Dan Hipschman : widl: Implement complex arrays.

Alexandre Julliard julliard at winehq.org
Wed Sep 19 08:16:14 CDT 2007


Module: wine
Branch: master
Commit: 132f06cd48c7ebd176649a5e00795e7a7fc67adb
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=132f06cd48c7ebd176649a5e00795e7a7fc67adb

Author: Dan Hipschman <dsh at linux.ucla.edu>
Date:   Tue Sep 18 15:29:59 2007 -0700

widl: Implement complex arrays.

---

 dlls/rpcrt4/tests/server.c   |   12 ++++++++++++
 dlls/rpcrt4/tests/server.idl |    1 +
 tools/widl/parser.y          |   25 ++++++++++++++++++++++---
 tools/widl/typegen.c         |   25 +++++++++++++++++++------
 tools/widl/typegen.h         |    1 +
 5 files changed, 55 insertions(+), 9 deletions(-)

diff --git a/dlls/rpcrt4/tests/server.c b/dlls/rpcrt4/tests/server.c
index 2ed6de7..40f9a81 100644
--- a/dlls/rpcrt4/tests/server.c
+++ b/dlls/rpcrt4/tests/server.c
@@ -351,6 +351,12 @@ s_sum_padded(padded_t *p)
 }
 
 int
+s_sum_padded2(padded_t ps[2])
+{
+  return s_sum_padded(&ps[0]) + s_sum_padded(&ps[1]);
+}
+
+int
 s_sum_bogus(bogus_t *b)
 {
   return *b->h.p1 + *b->p2 + *b->p3 + b->c;
@@ -405,6 +411,7 @@ basic_tests(void)
   pints_t pints;
   ptypes_t ptypes;
   padded_t padded;
+  padded_t padded2[2];
   bogus_t bogus;
   int i1, i2, i3, *pi2, *pi3, **ppi3;
   double u, v;
@@ -483,6 +490,11 @@ basic_tests(void)
   padded.i = -3;
   padded.c = 8;
   ok(sum_padded(&padded) == 5, "RPC sum_padded\n");
+  padded2[0].i = -5;
+  padded2[0].c = 1;
+  padded2[1].i = 3;
+  padded2[1].c = 7;
+  ok(sum_padded2(padded2) == 6, "RPC sum_padded2\n");
 
   i1 = 14;
   i2 = -7;
diff --git a/dlls/rpcrt4/tests/server.idl b/dlls/rpcrt4/tests/server.idl
index 44bb945..23ca779 100644
--- a/dlls/rpcrt4/tests/server.idl
+++ b/dlls/rpcrt4/tests/server.idl
@@ -207,6 +207,7 @@ interface IServer
   } padded_t;
 
   int sum_padded(padded_t *p);
+  int sum_padded2(padded_t ps[2]);
 
   typedef struct
   {
diff --git a/tools/widl/parser.y b/tools/widl/parser.y
index fbaf9a7..46fb439 100644
--- a/tools/widl/parser.y
+++ b/tools/widl/parser.y
@@ -1365,9 +1365,28 @@ static void set_type(var_t *v, type_t *type, int ptr_level, array_dims_t *arr)
     }
   }
 
-  /* if the structure is complex, then so must be the encompassing array */
-  if (is_array(v->type) && (v->type->ref->type == RPC_FC_BOGUS_STRUCT))
-    v->type->type = RPC_FC_BOGUS_ARRAY;
+  if (is_array(v->type))
+  {
+    const type_t *rt = v->type->ref;
+    switch (rt->type)
+    {
+    case RPC_FC_BOGUS_STRUCT:
+    case RPC_FC_NON_ENCAPSULATED_UNION:
+    case RPC_FC_ENCAPSULATED_UNION:
+    case RPC_FC_ENUM16:
+      v->type->type = RPC_FC_BOGUS_ARRAY;
+      break;
+    /* FC_RP should be above, but widl overuses these, and will break things.  */
+    case RPC_FC_UP:
+    case RPC_FC_RP:
+      if (rt->ref->type == RPC_FC_IP)
+        v->type->type = RPC_FC_BOGUS_ARRAY;
+      break;
+    default:
+      if (is_user_type(rt))
+        v->type->type = RPC_FC_BOGUS_ARRAY;
+    }
+  }
 }
 
 static ifref_list_t *append_ifref(ifref_list_t *list, ifref_t *iface)
diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c
index d821065..6625bda 100644
--- a/tools/widl/typegen.c
+++ b/tools/widl/typegen.c
@@ -200,7 +200,7 @@ static type_t *get_user_type(const type_t *t, const char **pname)
     }
 }
 
-static int is_user_type(const type_t *t)
+int is_user_type(const type_t *t)
 {
     return get_user_type(t, NULL) != NULL;
 }
@@ -1448,6 +1448,11 @@ static size_t write_array_tfs(FILE *file, const attr_list_t *attrs, type_t *type
     size_t start_offset;
     int has_pointer;
     int pointer_type = get_attrv(attrs, ATTR_POINTERTYPE);
+    unsigned int baseoff
+        = type->declarray && current_structure
+        ? type_memsize(current_structure, &align)
+        : 0;
+
     if (!pointer_type)
         pointer_type = RPC_FC_RP;
 
@@ -1470,10 +1475,6 @@ static size_t write_array_tfs(FILE *file, const attr_list_t *attrs, type_t *type
     if (type->type != RPC_FC_BOGUS_ARRAY)
     {
         unsigned char tc = type->type;
-        unsigned int baseoff
-            = type->declarray && current_structure
-            ? type_memsize(current_structure, &align)
-            : 0;
 
         if (tc == RPC_FC_LGFARRAY || tc == RPC_FC_LGVARRAY)
         {
@@ -1530,7 +1531,19 @@ static size_t write_array_tfs(FILE *file, const attr_list_t *attrs, type_t *type
         write_end(file, typestring_offset);
     }
     else
-        error("%s: complex arrays unimplemented\n", name);
+    {
+        unsigned int dim = size_is ? 0 : type->dim;
+        print_file(file, 2, "NdrFcShort(0x%x),\t/* %u */\n", dim, dim);
+        *typestring_offset += 2;
+        *typestring_offset
+            += write_conf_or_var_desc(file, current_structure, baseoff,
+                                      size_is);
+        *typestring_offset
+            += write_conf_or_var_desc(file, current_structure, baseoff,
+                                      length_is);
+        write_member_type(file, type, NULL, type->ref, NULL, typestring_offset);
+        write_end(file, typestring_offset);
+    }
 
     return start_offset;
 }
diff --git a/tools/widl/typegen.h b/tools/widl/typegen.h
index 448e503..fc17c19 100644
--- a/tools/widl/typegen.h
+++ b/tools/widl/typegen.h
@@ -56,3 +56,4 @@ int decl_indirect(const type_t *t);
 void write_parameters_init(FILE *file, int indent, const func_t *func);
 void print(FILE *file, int indent, const char *format, va_list ap);
 int get_padding(const var_list_t *fields);
+int is_user_type(const type_t *t);




More information about the wine-cvs mailing list