widl [1/6]: Generate names for tagless structs, unions and enums

Dan Hipschman dsh at linux.ucla.edu
Mon Aug 28 20:29:24 CDT 2006


This is so tagless structs, unions and enums are given automatically
generated names when they are typedef'd.  For example,

typedef struct { int x; } foo_t;

would be output as

typedef struct __WIDL_<file>_generated_name_<N> { int x; } foo_t;

It matches the behavior of MIDL, but not the naming scheme.  MIDL's naming
scheme uses the containing interface's name, or if the declaration is at
the top level it generates an interface name using the file name.  I haven't
completely figured it out yet, but using only the file name works now for
Wine.  This also lets us add tagless structs, etc., to typelibs in a fashion
consistent with MIDL (without this patch, Widl just crashes).

ChangeLog:
* Generate names for tagless structs, unions and enums being typedef'd.
---
 tools/widl/parser.y |   23 +++++++++++++++++++++++
 tools/widl/widl.c   |    3 +++
 tools/widl/widl.h   |    1 +
 3 files changed, 27 insertions(+), 0 deletions(-)

diff --git a/tools/widl/parser.y b/tools/widl/parser.y
index ead02cb..a9d0c80 100644
--- a/tools/widl/parser.y
+++ b/tools/widl/parser.y
@@ -104,6 +104,7 @@ static void write_diid(type_t *iface);
 static void write_iid(type_t *iface);
 
 static int compute_method_indexes(type_t *iface);
+static char *gen_name(void);
 
 #define tsENUM   1
 #define tsSTRUCT 2
@@ -824,9 +825,19 @@ type:	  tVOID					{ $$ = make_tref(NULL,
 	;
 
 typedef: tTYPEDEF m_attributes type pident_list	{ typeref_t *tref = uniq_tref($3);
+						  type_t *t;
 						  $4->tname = tref->name;
 						  tref->name = NULL;
 						  $$ = type_ref(tref);
+						  t = $$->ref;
+						  if ((t->kind == TKIND_ENUM || t->kind == TKIND_RECORD
+						       || t->kind == TKIND_UNION) && ! t->name && ! parse_only)
+						  {
+						    attr_t *a = make_attr(ATTR_PUBLIC);
+						    LINK(a, $2);
+						    $2 = a;
+						    t->name = gen_name();
+						  }
 						  $$->attrs = $2;
 						  if (!parse_only && do_header)
 						    write_typedef($$, $4);
@@ -1614,3 +1625,15 @@ static int compute_method_indexes(type_t
 
   return idx;
 }
+
+static char *gen_name(void)
+{
+  static const char format[] = "__WIDL_%s_generated_name_%08lX";
+  static unsigned long n = 0;
+
+  size_t size = sizeof format - 7 + strlen(input_base) + 8;
+  char *name = xmalloc(size);
+
+  sprintf(name, format, input_base, n++);
+  return name;
+}
diff --git a/tools/widl/widl.c b/tools/widl/widl.c
index c2456f1..9463f74 100644
--- a/tools/widl/widl.c
+++ b/tools/widl/widl.c
@@ -99,6 +99,7 @@ int no_preprocess = 0;
 int old_names = 0;
 
 char *input_name;
+char *input_base;
 char *header_name;
 char *header_token;
 char *typelib_name;
@@ -278,6 +279,8 @@ #endif
                  (debuglevel & DEBUGLEVEL_PPTRACE) != 0,
                  (debuglevel & DEBUGLEVEL_PPMSG) != 0 );
 
+  input_base = dup_basename(input_name, ".idl");
+
   if (!header_name) {
     header_name = dup_basename(input_name, ".idl");
     strcat(header_name, ".h");
diff --git a/tools/widl/widl.h b/tools/widl/widl.h
index e84a5ad..0732a29 100644
--- a/tools/widl/widl.h
+++ b/tools/widl/widl.h
@@ -45,6 +45,7 @@ extern int do_idfile;
 extern int old_names;
 
 extern char *input_name;
+extern char *input_base;
 extern char *header_name;
 extern char *typelib_name;
 extern char *proxy_name;



More information about the wine-patches mailing list