https://git.reactos.org/?p=reactos.git;a=commitdiff;h=891d81e058237344de3fe4e183f6b1933d1f2bbc

commit 891d81e058237344de3fe4e183f6b1933d1f2bbc
Author: Amine Khaldi <amine.kha...@reactos.org>
AuthorDate: Sun Oct 8 10:52:42 2017 +0100

    [WIDL] Sync with Wine Staging 2.16. CORE-13762
    
    b42a155 widl: Handle C++ aggregate returns in a MSVC compatible way.
    084fa63 widl: Only generate Proxy Stubs when functions have the call_as 
attribute.
    fbdf119 widl: Try to find imported typelib using .tlb extension if it 
wasn't specified.
---
 media/doc/README.WINE    |  2 +-
 sdk/tools/widl/header.c  | 53 ++++++++++++++++++++++++++++++++++++++++++++++--
 sdk/tools/widl/typelib.c | 36 ++++++++++++++++++++++++--------
 3 files changed, 80 insertions(+), 11 deletions(-)

diff --git a/media/doc/README.WINE b/media/doc/README.WINE
index 1a7c651da6..8dcdd23aa5 100644
--- a/media/doc/README.WINE
+++ b/media/doc/README.WINE
@@ -16,7 +16,7 @@ wine-patc...@winehq.com and ros-...@reactos.org
 The following build tools are shared with Wine.
 
 reactos/sdk/tools/unicode               # Synced to WineStaging-2.9
-reactos/sdk/tools/widl                  # Synced to WineStaging-2.9
+reactos/sdk/tools/widl                  # Synced to WineStaging-2.16
 reactos/sdk/tools/wpp                   # Synced to WineStaging-2.9
 
 The following libraries are shared with Wine.
diff --git a/sdk/tools/widl/header.c b/sdk/tools/widl/header.c
index a5dadbaf68..27bca0ed0d 100644
--- a/sdk/tools/widl/header.c
+++ b/sdk/tools/widl/header.c
@@ -1043,13 +1043,62 @@ static void write_cpp_method_def(FILE *header, const 
type_t *iface)
     const var_t *func = stmt->u.var;
     if (!is_callas(func->attrs)) {
       const char *callconv = get_attrp(func->type->attrs, ATTR_CALLCONV);
+      const var_list_t *args = type_get_function_args(func->type);
+      const var_t *arg;
+
       if (!callconv) callconv = "STDMETHODCALLTYPE";
+
+      if (is_aggregate_return(func)) {
+        fprintf(header, "#ifdef WIDL_EXPLICIT_AGGREGATE_RETURNS\n");
+
+        indent(header, 0);
+        fprintf(header, "virtual ");
+        write_type_decl_left(header, type_function_get_rettype(func->type));
+        fprintf(header, "* %s %s(\n", callconv, get_name(func));
+        ++indentation;
+        indent(header, 0);
+        write_type_decl_left(header, type_function_get_rettype(func->type));
+        fprintf(header, " *__ret");
+        --indentation;
+        if (args) {
+          fprintf(header, ",\n");
+          write_args(header, args, iface->name, 2, TRUE);
+        }
+        fprintf(header, ") = 0;\n");
+
+        indent(header, 0);
+        write_type_decl_left(header, type_function_get_rettype(func->type));
+        fprintf(header, " %s %s(\n", callconv, get_name(func));
+        write_args(header, args, iface->name, 2, TRUE);
+        fprintf(header, ")\n");
+        indent(header, 0);
+        fprintf(header, "{\n");
+        ++indentation;
+        indent(header, 0);
+        write_type_decl_left(header, type_function_get_rettype(func->type));
+        fprintf(header, " __ret;\n");
+        indent(header, 0);
+        fprintf(header, "return *%s(&__ret", get_name(func));
+        if (args)
+            LIST_FOR_EACH_ENTRY(arg, args, const var_t, entry)
+                fprintf(header, ", %s", arg->name);
+        fprintf(header, ");\n");
+        --indentation;
+        indent(header, 0);
+        fprintf(header, "}\n");
+
+        fprintf(header, "#else\n");
+      }
+
       indent(header, 0);
       fprintf(header, "virtual ");
       write_type_decl_left(header, type_function_get_rettype(func->type));
       fprintf(header, " %s %s(\n", callconv, get_name(func));
-      write_args(header, type_get_function_args(func->type), iface->name, 2, 
TRUE);
+      write_args(header, args, iface->name, 2, TRUE);
       fprintf(header, ") = 0;\n");
+
+      if (is_aggregate_return(func))
+        fprintf(header, "#endif\n");
       fprintf(header, "\n");
     }
   }
@@ -1181,7 +1230,7 @@ static void write_method_proto(FILE *header, const type_t 
*iface)
   {
     const var_t *func = stmt->u.var;
 
-    if (!is_local(func->attrs)) {
+    if (is_callas(func->attrs)) {
       const char *callconv = get_attrp(func->type->attrs, ATTR_CALLCONV);
       if (!callconv) callconv = "STDMETHODCALLTYPE";
       /* proxy prototype */
diff --git a/sdk/tools/widl/typelib.c b/sdk/tools/widl/typelib.c
index f8f92e2062..ba71de71ab 100644
--- a/sdk/tools/widl/typelib.c
+++ b/sdk/tools/widl/typelib.c
@@ -327,22 +327,42 @@ static void read_msft_importlib(importlib_t *importlib, 
int fd)
     free(typeinfo_offs);
 }
 
+static int open_typelib(const char *name)
+{
+    char *file_name;
+    int fd;
+
+    file_name = wpp_find_include(name, NULL);
+    if(!file_name)
+        return open(name, O_RDONLY | O_BINARY );
+
+    fd = open(file_name, O_RDONLY | O_BINARY );
+    free(file_name);
+    return fd;
+}
+
 static void read_importlib(importlib_t *importlib)
 {
     int fd;
     INT magic;
-    char *file_name;
 
-    file_name = wpp_find_include(importlib->name, NULL);
-    if(file_name) {
-        fd = open(file_name, O_RDONLY | O_BINARY );
-        free(file_name);
-    }else {
-        fd = open(importlib->name, O_RDONLY | O_BINARY );
+    fd = open_typelib(importlib->name);
+
+    /* widl extension: if importlib name has no .tlb extension, try using .tlb 
*/
+    if(fd < 0) {
+        const char *p = strrchr(importlib->name, '.');
+        size_t len = p ? p - importlib->name : strlen(importlib->name);
+        if(strcmp(importlib->name + len, ".tlb")) {
+            char *tlb_name = xmalloc(len + 5);
+            memcpy(tlb_name, importlib->name, len);
+            strcpy(tlb_name + len, ".tlb");
+            fd = open_typelib(tlb_name);
+            free(tlb_name);
+        }
     }
 
     if(fd < 0)
-        error("Could not open importlib %s.\n", importlib->name);
+        error("Could not find importlib %s.\n", importlib->name);
 
     tlb_read(fd, &magic, sizeof(magic));
 

Reply via email to