[1/3] widl: Allow is_string_type to work for typedef'd types.

Dan Hipschman dsh at linux.ucla.edu
Thu Feb 21 17:46:51 CST 2008


This fixes a couple WIDL bugs to get the next BITS test to work.  Specifically,
is_string_type should check the attributes on the type as well as the ones
passed in from the var to handle typedef'd types.  Also, it turns out that
WIDL does not handle writing the types of returned values to the type format
string (it only works if they are already written which happens to be the case
if the type is used on, say, an argument or struct field).  This bug appears in
the get_filename test with the above fix to is_string_type, but fixing it on
its own will also break the test since then the wrong offset is cached when it
is written to the format string.  Hence these two fixes need to go in together.
This complication arises from the optimization of NdrPointerFoo to
NdrConformantStringFoo.

Includes two new tests (one for each fix) that pass on Wine and Windows.

---
 dlls/rpcrt4/tests/server.c   |   22 ++++++++++++++++++++++
 dlls/rpcrt4/tests/server.idl |   13 +++++++++++++
 tools/widl/header.h          |    3 ++-
 tools/widl/typegen.c         |    9 ++++++++-
 4 files changed, 45 insertions(+), 2 deletions(-)

diff --git a/dlls/rpcrt4/tests/server.c b/dlls/rpcrt4/tests/server.c
index 43c3ec2..e06e57a 100644
--- a/dlls/rpcrt4/tests/server.c
+++ b/dlls/rpcrt4/tests/server.c
@@ -93,6 +93,12 @@ s_str_length(const char *s)
 }
 
 int
+s_str_t_length(str_t s)
+{
+  return strlen(s);
+}
+
+int
 s_cstr_length(const char *s, int n)
 {
   int len = 0;
@@ -497,6 +503,16 @@ s_sum_L1_norms(int n, vector_t *vs)
   return sum;
 }
 
+s123_t *
+s_get_s123(void)
+{
+  s123_t *s = MIDL_user_allocate(sizeof *s);
+  s->f1 = 1;
+  s->f2 = 2;
+  s->f3 = 3;
+  return s;
+}
+
 str_t
 s_get_filename(void)
 {
@@ -693,6 +709,7 @@ basic_tests(void)
   ok(x == 25, "RPC square_ref\n");
 
   ok(str_length(string) == strlen(string), "RPC str_length\n");
+  ok(str_t_length(string) == strlen(string), "RPC str_length\n");
   ok(dot_self(&a) == 59, "RPC dot_self\n");
 
   ok(str_struct_len(&ss) == lstrlenA(string), "RPC str_struct_len\n");
@@ -959,6 +976,7 @@ pointer_tests(void)
   name_t name;
   void *buffer;
   int *pa2;
+  s123_t *s123;
 
   ok(test_list_length(list) == 3, "RPC test_list_length\n");
   ok(square_puint(p1) == 121, "RPC square_puint\n");
@@ -1012,6 +1030,10 @@ pointer_tests(void)
 
   pa2 = a;
   ok(sum_pcarr2(4, &pa2) == 10, "RPC sum_pcarr2\n");
+
+  s123 = get_s123();
+  ok(s123->f1 == 1 && s123->f2 == 2 && s123->f3 == 3, "RPC get_s123\n");
+  MIDL_user_free(s123);
 }
 
 static int
diff --git a/dlls/rpcrt4/tests/server.idl b/dlls/rpcrt4/tests/server.idl
index ec51757..7736e14 100644
--- a/dlls/rpcrt4/tests/server.idl
+++ b/dlls/rpcrt4/tests/server.idl
@@ -82,6 +82,7 @@ cpp_quote("#endif")
   void square_out(int x, [out] int *y);
   void square_ref([in, out] int *x);
   int str_length([string] const char *s);
+  int str_t_length(str_t 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);
@@ -300,6 +301,18 @@ cpp_quote("#endif")
   int sum_pcarr2(int n, [size_is(, n)] int **pa);
   int sum_L1_norms(int n, [size_is(n)] vector_t *vs);
 
+  /* Don't use this except in the get_s123 test.  */
+  typedef struct
+  {
+    int f1;
+    int f2;
+    int f3;
+  } s123_t;
+
+  /* Make sure WIDL generates a type format string for a previously unseen
+     type as a return value.  */
+  s123_t *get_s123(void);
+
   void get_5numbers([in] int count, [out, length_is(count)] pints_t pn[5]);
   void get_numbers([in] int length, [in] int size, [out, length_is(length), size_is(size)] pints_t pn[]);
   str_t get_filename(void);
diff --git a/tools/widl/header.h b/tools/widl/header.h
index 41784a0..656d4b2 100644
--- a/tools/widl/header.h
+++ b/tools/widl/header.h
@@ -78,7 +78,8 @@ static inline int last_array(const type_t *type)
 
 static inline int is_string_type(const attr_list_t *attrs, const type_t *type)
 {
-    return is_attr(attrs, ATTR_STRING) && (last_ptr(type) || last_array(type));
+    return ((is_attr(attrs, ATTR_STRING) || is_attr(type->attrs, ATTR_STRING))
+            && (last_ptr(type) || last_array(type)));
 }
 
 static inline int is_context_handle(const type_t *type)
diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c
index f3af935..ae23f94 100644
--- a/tools/widl/typegen.c
+++ b/tools/widl/typegen.c
@@ -2355,6 +2355,13 @@ static size_t process_tfs(FILE *file, const ifref_list_t *ifaces, type_pred_t pr
             {
                 if (is_local(func->def->attrs)) continue;
 
+                if (!is_void(func->def->type))
+                    update_tfsoff(func->def->type,
+                                  write_typeformatstring_var(
+                                      file, 2, NULL, func->def->type,
+                                      func->def, &typeformat_offset),
+                                  file);
+
                 current_func = func;
                 if (func->args)
                     LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry )
@@ -2821,7 +2828,7 @@ static void write_remoting_arg(FILE *file, int indent, const func_t *func,
                 fprintf(file, ";\n");
             }
 
-            if ((phase == PHASE_FREE) || (pointer_type == RPC_FC_UP))
+            if (phase == PHASE_FREE || pass == PASS_RETURN || pointer_type == RPC_FC_UP)
                 print_phase_function(file, indent, "Pointer", phase, var,
                                      start_offset - (type->size_is ? 4 : 2));
             else



More information about the wine-patches mailing list