widl: Allow size_is on strings

Dan Hipschman dsh at linux.ucla.edu
Tue Sep 4 17:46:30 CDT 2007


This patch fixes the problem reported here:
http://www.winehq.org/pipermail/wine-devel/2007-August/058495.html

---
 dlls/rpcrt4/tests/server.c   |   12 +++++++++
 dlls/rpcrt4/tests/server.idl |    1 +
 tools/widl/typegen.c         |   53 +++++++++++++++++++-----------------------
 3 files changed, 37 insertions(+), 29 deletions(-)

diff --git a/dlls/rpcrt4/tests/server.c b/dlls/rpcrt4/tests/server.c
index b6b2565..cd21468 100644
--- a/dlls/rpcrt4/tests/server.c
+++ b/dlls/rpcrt4/tests/server.c
@@ -85,6 +85,15 @@ s_str_length(const char *s)
 }
 
 int
+s_cstr_length(const char *s, int n)
+{
+  int len = 0;
+  while (0 < n-- && *s++)
+    ++len;
+  return len;
+}
+
+int
 s_dot_self(vector_t *v)
 {
   return s_square(v->x) + s_square(v->y) + s_square(v->z);
@@ -616,6 +625,7 @@ pointer_tests(void)
 static void
 array_tests(void)
 {
+  static const char str1[25] = "Hello";
   static int m[2][3][4] =
   {
     {{1, 2, 3, 4}, {-1, -3, -5, -7}, {0, 2, 4, 6}},
@@ -628,6 +638,8 @@ array_tests(void)
   cs_t *cs;
   int n;
 
+  ok(cstr_length(str1, sizeof str1) == strlen(str1), "RPC cstr_length\n");
+
   ok(sum_fixed_int_3d(m) == 4116, "RPC sum_fixed_int_3d\n");
 
   ok(sum_conf_array(c, 10) == 45, "RPC sum_conf_array\n");
diff --git a/dlls/rpcrt4/tests/server.idl b/dlls/rpcrt4/tests/server.idl
index 0a8c0d3..3ee40ae 100644
--- a/dlls/rpcrt4/tests/server.idl
+++ b/dlls/rpcrt4/tests/server.idl
@@ -73,6 +73,7 @@ interface IServer
   void square_out(int x, [out] int *y);
   void square_ref([in, out] int *x);
   int str_length([string] const char *s);
+  int cstr_length([string, size_is(n)] const char *s, int n);
   int dot_self(vector_t *v);
   double square_half(double x, [out] double *y);
   float square_half_float(float x, [out] float *y);
diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c
index 0ec03d9..7d7c134 100644
--- a/tools/widl/typegen.c
+++ b/tools/widl/typegen.c
@@ -1312,30 +1312,37 @@ static void write_pointer_description(FILE *file, type_t *type,
             &offset_in_memory, &offset_in_buffer, typestring_offset);
 }
 
+static int is_declptr(const type_t *t)
+{
+  return is_ptr(t) || (is_conformant_array(t) && !t->declarray);
+}
+
 static size_t write_string_tfs(FILE *file, const attr_list_t *attrs,
                                const type_t *type,
                                const char *name, unsigned int *typestring_offset)
 {
     size_t start_offset = *typestring_offset;
-    unsigned char flags = 0;
-    int pointer_type;
     unsigned char rtype;
 
-    if (is_ptr(type))
+    if (is_declptr(type))
     {
-        pointer_type = type->type;
-        type = type->ref;
+        unsigned char flag = is_conformant_array(type) ? 0 : RPC_FC_P_SIMPLEPOINTER;
+        int pointer_type = is_ptr(type) ? type->type : get_attrv(attrs, ATTR_POINTERTYPE);
+        if (!pointer_type)
+            pointer_type = RPC_FC_RP;
+        print_file(file, 2,"0x%x, 0x%x,\t/* %s%s */\n",
+                   pointer_type, flag, string_of_type(pointer_type),
+                   flag ? " [simple_pointer]" : "");
+        *typestring_offset += 2;
+        if (!flag)
+        {
+            print_file(file, 2, "NdrFcShort(0x2),\n");
+            *typestring_offset += 2;
+        }
+        rtype = type->ref->type;
     }
     else
-        pointer_type = get_attrv(attrs, ATTR_POINTERTYPE);
-
-    if (!pointer_type)
-        pointer_type = RPC_FC_RP;
-
-    if (!get_attrp(attrs, ATTR_SIZEIS))
-        flags |= RPC_FC_P_SIMPLEPOINTER;
-
-    rtype = type->type;
+        rtype = type->type;
 
     if ((rtype != RPC_FC_BYTE) && (rtype != RPC_FC_CHAR) && (rtype != RPC_FC_WCHAR))
     {
@@ -1343,18 +1350,6 @@ static size_t write_string_tfs(FILE *file, const attr_list_t *attrs,
         return start_offset;
     }
 
-    print_file(file, 2,"0x%x, 0x%x,    /* %s%s */\n",
-               pointer_type, flags,
-               pointer_type == RPC_FC_FP ? "FC_FP" : (pointer_type == RPC_FC_UP ? "FC_UP" : "FC_RP"),
-               (flags & RPC_FC_P_SIMPLEPOINTER) ? " [simple_pointer]" : "");
-    *typestring_offset += 2;
-
-    if (!(flags & RPC_FC_P_SIMPLEPOINTER))
-    {
-        print_file(file, 2, "NdrFcShort(0x2),\n");
-        *typestring_offset += 2;
-    }
-
     if (type->declarray && !is_conformant_array(type))
     {
         /* FIXME: multi-dimensional array */
@@ -1396,10 +1391,10 @@ static size_t write_string_tfs(FILE *file, const attr_list_t *attrs,
     }
     else
     {
-        if (rtype == RPC_FC_CHAR)
-            WRITE_FCTYPE(file, FC_C_CSTRING, *typestring_offset);
-        else
+        if (rtype == RPC_FC_WCHAR)
             WRITE_FCTYPE(file, FC_C_WSTRING, *typestring_offset);
+        else
+            WRITE_FCTYPE(file, FC_C_CSTRING, *typestring_offset);
         print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD);
         *typestring_offset += 2;
 



More information about the wine-patches mailing list