- Support multiple interfaces per idl file.
- Support explicit binding handles.
Modified: trunk/reactos/tools/widl/ChangeLog
Modified: trunk/reactos/tools/widl/client.c
Modified: trunk/reactos/tools/widl/header.c
Modified: trunk/reactos/tools/widl/header.h
Modified: trunk/reactos/tools/widl/server.c

Modified: trunk/reactos/tools/widl/ChangeLog
--- trunk/reactos/tools/widl/ChangeLog	2005-02-25 05:28:54 UTC (rev 13739)
+++ trunk/reactos/tools/widl/ChangeLog	2005-02-25 12:20:36 UTC (rev 13740)
@@ -1,5 +1,15 @@
 ChangeLog
 
+2005-02-25 ekohl
+  tools/widl/client.c
+  tools/widl/header.c
+  tools/widl/header.h
+  tools/widl/server.c
+
+Support multiple interfaces per idl file.
+Support explicit binding handles.
+
+
 2005-02-24 ekohl
   include/wine/rpcfc.h
   tools/widl/client.c

Modified: trunk/reactos/tools/widl/client.c
--- trunk/reactos/tools/widl/client.c	2005-02-25 05:28:54 UTC (rev 13739)
+++ trunk/reactos/tools/widl/client.c	2005-02-25 12:20:36 UTC (rev 13740)
@@ -225,8 +225,8 @@
 static void print_message_buffer_size(func_t *func)
 {
     unsigned int alignment;
-    unsigned int size;
-    unsigned int last_size = 0;
+    int size;
+    int last_size = -1;
     var_t *var;
 
     if (!func->args)
@@ -253,7 +253,7 @@
         case RPC_FC_USHORT:
         case RPC_FC_SHORT:
             size = 2;
-            if (last_size != 0 && last_size < 2)
+            if (last_size != -1 && last_size < 2)
                 alignment += (2 - last_size);
             break;
 
@@ -261,14 +261,14 @@
         case RPC_FC_LONG:
         case RPC_FC_FLOAT:
             size = 4;
-            if (last_size != 0 && last_size < 4)
+            if (last_size != -1 && last_size < 4)
                 alignment += (4 - last_size);
             break;
 
         case RPC_FC_HYPER:
         case RPC_FC_DOUBLE:
             size = 8;
-            if (last_size != 0 && last_size < 4)
+            if (last_size != -1 && last_size < 4)
                 alignment += (4 - last_size);
             break;
 
@@ -280,21 +280,11 @@
             error("Unknown/unsupported type!");
         }
 
-        if (size == 0)
-        {
-            if (last_size != 0)
-                fprintf(client, " +");
-            fprintf(client, " 0U");
-        }
-        else
-        {
-            if (last_size != 0)
-                fprintf(client, " +");
-            fprintf(client, " %uU", size + alignment);
+        if (last_size != -1)
+            fprintf(client, " +");
+        fprintf(client, " %dU", (size == 0) ? 0 : size + alignment);
 
-            last_size = size;
-        }
-        
+        last_size = size;
 
         var = PREV_LINK(var);
     }
@@ -379,9 +369,10 @@
 static void write_function_stubs(type_t *iface)
 {
     char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE);
-    int explitit_handle = is_attr(iface->attrs, ATTR_IMPLICIT_HANDLE);
+    int explicit_handle = is_attr(iface->attrs, ATTR_EXPLICIT_HANDLE);
     func_t *func = iface->funcs;
     var_t* var;
+    var_t* explicit_handle_var;
     int method_count = 0;
     unsigned int proc_offset = 0;
 
@@ -390,6 +381,25 @@
     {
         var_t *def = func->def;
 
+        /* check for a defined binding handle */
+        explicit_handle_var = get_explicit_handle_var(func);
+        if (explicit_handle)
+        {
+            if (!explicit_handle_var)
+            {
+                error("%s() does not define an explicit binding handle!\n", def->name);
+                return;
+            }
+        }
+        else
+        {
+            if (explicit_handle_var)
+            {
+                error("%s() must not define a binding handle!\n", def->name);
+                return;
+            }
+        }
+
         write_type(client, def->type, def, def->tname);
         fprintf(client, " ");
         write_name(client, def);
@@ -411,7 +421,7 @@
             fprintf(client, " _RetVal;\n");
         }
 
-        if (implicit_handle)
+        if (implicit_handle || explicit_handle)
             print_client("RPC_BINDING_HANDLE _Handle = 0;\n");
         print_client("RPC_MESSAGE _RpcMessage;\n");
         print_client("MIDL_STUB_MESSAGE _StubMsg;\n");
@@ -434,6 +444,11 @@
             print_client("_Handle = %s;\n", implicit_handle);
             fprintf(client, "\n");
         }
+        else if (explicit_handle)
+        {
+            print_client("_Handle = %s;\n", explicit_handle_var->name);
+            fprintf(client, "\n");
+        }
 
         /* emit the message buffer size */
         print_client("_StubMsg.BufferLength =");
@@ -445,7 +460,7 @@
         indent++;
         print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");
         print_client("_StubMsg.BufferLength,\n");
-        if (implicit_handle)
+        if (implicit_handle || explicit_handle)
             print_client("%_Handle);\n");
         else
             print_client("%s__MIDL_AutoBindHandle);\n", iface->name);
@@ -691,39 +706,47 @@
 
 void write_client(ifref_t *ifaces)
 {
-    ifref_t *lcur = ifaces;
-    char *file_id = client_token;
-    int c;
+    ifref_t *iface = ifaces;
 
     if (!do_client)
         return;
-    if (!lcur)
+    if (!iface)
         return;
-    END_OF_LIST(lcur);
+    END_OF_LIST(iface);
 
     init_client();
     if (!client)
         return;
 
-    write_formatstringsdecl(lcur->iface);
-    write_implicithandledecl(lcur->iface);
+    while (iface)
+    {
+        fprintf(client, "/*****************************************************************************\n");
+        fprintf(client, " * %s interface\n", iface->iface->name);
+        fprintf(client, " */\n");
+        fprintf(client, "\n");
 
-    write_clientinterfacedecl(lcur->iface);
-    write_stubdescdecl(lcur->iface);
-    write_bindinghandledecl(lcur->iface);
+        write_formatstringsdecl(iface->iface);
+        write_implicithandledecl(iface->iface);
 
-    write_function_stubs(lcur->iface);
-    write_stubdescriptor(lcur->iface);
+        write_clientinterfacedecl(iface->iface);
+        write_stubdescdecl(iface->iface);
+        write_bindinghandledecl(iface->iface);
 
-    print_client("#if !defined(__RPC_WIN32__)\n");
-    print_client("#error  Invalid build platform for this stub.\n");
-    print_client("#endif\n");
-    fprintf(client, "\n");
+        write_function_stubs(iface->iface);
+        write_stubdescriptor(iface->iface);
 
-    write_procformatstring(lcur->iface);
-    write_typeformatstring();
+        print_client("#if !defined(__RPC_WIN32__)\n");
+        print_client("#error  Invalid build platform for this stub.\n");
+        print_client("#endif\n");
+        fprintf(client, "\n");
 
-    fprintf(client, "\n");
+        write_procformatstring(iface->iface);
+        write_typeformatstring();
 
+        fprintf(client, "\n");
+
+        iface = PREV_LINK(iface);
+    }
+
     fclose(client);
 }

Modified: trunk/reactos/tools/widl/header.c
--- trunk/reactos/tools/widl/header.c	2005-02-25 05:28:54 UTC (rev 13739)
+++ trunk/reactos/tools/widl/header.c	2005-02-25 12:20:36 UTC (rev 13740)
@@ -427,6 +427,28 @@
   fprintf(header, ";\n\n");
 }
 
+
+var_t* get_explicit_handle_var(func_t* func)
+{
+    var_t* var;
+
+    if (!func->args)
+        return NULL;
+
+    var = func->args;
+    while (NEXT_LINK(var)) var = NEXT_LINK(var);
+    while (var)
+    {
+        if (var->type->type == RPC_FC_IGNORE)
+            return var;
+
+        var = PREV_LINK(var);
+    }
+
+    return NULL;
+}
+
+
 /********** INTERFACES **********/
 
 int is_object(attr_t *a)
@@ -663,10 +685,28 @@
 
 static void write_function_proto(type_t *iface)
 {
+  int explicit_handle = is_attr(iface->attrs, ATTR_EXPLICIT_HANDLE);
+  var_t* explicit_handle_var;
+
   func_t *cur = iface->funcs;
   while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);
   while (cur) {
     var_t *def = cur->def;
+
+    /* check for a defined binding handle */
+    explicit_handle_var = get_explicit_handle_var(cur);
+    if (explicit_handle) {
+      if (!explicit_handle_var) {
+        error("%s() does not define an explicit binding handle!\n", def->name);
+        return;
+      }
+    } else {
+      if (explicit_handle_var) {
+        error("%s() must not define a binding handle!\n", def->name);
+        return;
+      }
+    }
+
     /* FIXME: do we need to handle call_as? */
     write_type(header, def->type, def, def->tname);
     fprintf(header, " ");

Modified: trunk/reactos/tools/widl/header.h
--- trunk/reactos/tools/widl/header.h	2005-02-25 05:28:54 UTC (rev 13739)
+++ trunk/reactos/tools/widl/header.h	2005-02-25 12:20:36 UTC (rev 13740)
@@ -40,5 +40,5 @@
 extern void write_expr(FILE *h, expr_t *e);
 extern void write_constdef(var_t *v);
 extern void write_externdef(var_t *v);
-
+extern var_t* get_explicit_handle_var(func_t* func);
 #endif

Modified: trunk/reactos/tools/widl/server.c
--- trunk/reactos/tools/widl/server.c	2005-02-25 05:28:54 UTC (rev 13739)
+++ trunk/reactos/tools/widl/server.c	2005-02-25 12:20:36 UTC (rev 13740)
@@ -336,8 +336,10 @@
 
 static void write_function_stubs(type_t *iface)
 {
+    int explicit_handle = is_attr(iface->attrs, ATTR_EXPLICIT_HANDLE);
     func_t *func = iface->funcs;
     var_t *var;
+    var_t* explicit_handle_var;
     unsigned int proc_offset = 0;
 
     while (NEXT_LINK(func)) func = NEXT_LINK(func);
@@ -345,6 +347,25 @@
     {
         var_t *def = func->def;
 
+        /* check for a defined binding handle */
+        explicit_handle_var = get_explicit_handle_var(func);
+        if (explicit_handle)
+        {
+            if (!explicit_handle_var)
+            {
+                error("%s() does not define an explicit binding handle!\n", def->name);
+                return;
+            }
+        }
+        else
+        {
+            if (explicit_handle_var)
+            {
+                error("%s() must not define a binding handle!\n", def->name);
+                return;
+            }
+        }
+
         write_type(server, def->type, def, def->tname);
         fprintf(server, " __RPC_STUB\n");
         fprintf(server, "%s_", iface->name);
@@ -397,6 +418,12 @@
         indent--;
         fprintf(server, "\n");
 
+        if (explicit_handle)
+        {
+            print_server("%s = _pRpcMessage->Handle;\n", explicit_handle_var->name);
+            fprintf(server, "\n");
+        }
+
         print_server("RpcTryFinally\n");
         print_server("{\n");
         indent++;
@@ -698,38 +725,46 @@
 
 void write_server(ifref_t *ifaces)
 {
-    ifref_t *lcur = ifaces;
-    char *file_id = server_token;
-    int c;
+    ifref_t *iface = ifaces;
 
     if (!do_server)
         return;
-    if (!lcur)
+    if (!iface)
         return;
-    END_OF_LIST(lcur);
+    END_OF_LIST(iface);
 
     init_server();
     if (!server)
         return;
 
-    write_formatstringsdecl(lcur->iface);
-    write_serverinterfacedecl(lcur->iface);
-    write_stubdescdecl(lcur->iface);
+    while (iface)
+    {
+        fprintf(server, "/*****************************************************************************\n");
+        fprintf(server, " * %s interface\n", iface->iface->name);
+        fprintf(server, " */\n");
+        fprintf(server, "\n");
 
-    write_function_stubs(lcur->iface);
+        write_formatstringsdecl(iface->iface);
+        write_serverinterfacedecl(iface->iface);
+        write_stubdescdecl(iface->iface);
 
-    write_stubdescriptor(lcur->iface);
-    write_dispatchtable(lcur->iface);
+        write_function_stubs(iface->iface);
 
-    print_server("#if !defined(__RPC_WIN32__)\n");
-    print_server("#error  Invalid build platform for this stub.\n");
-    print_server("#endif\n");
-    fprintf(server, "\n");
+        write_stubdescriptor(iface->iface);
+        write_dispatchtable(iface->iface);
 
-    write_procformatstring(lcur->iface);
-    write_typeformatstring();
+        print_server("#if !defined(__RPC_WIN32__)\n");
+        print_server("#error  Invalid build platform for this stub.\n");
+        print_server("#endif\n");
+        fprintf(server, "\n");
 
-    fprintf(server, "\n");
+        write_procformatstring(iface->iface);
+        write_typeformatstring();
 
+        fprintf(server, "\n");
+
+        iface = PREV_LINK(iface);
+    }
+
     fclose(server);
 }