widl [3/3]: Keep track of every allocated type_t to simplify set_all_tfswrite

Dan Hipschman dsh at linux.ucla.edu
Mon Oct 8 18:47:28 CDT 2007


This patch adds code to widl so that it keeps track of every type allocated in
a big list.  The reason this is useful is that if we want to set a field of
every type (tfswrite in this case), or more generally just do any operation on
every type node, this makes it very simple.  Without this, we need some thirty
or so ugly lines of code, which are hard to verify as correct.  Now it takes
three very clear lines to do the same thing.  I will miss that three-deep stack
of 'if's and 'LIST_FOR_EACH_ENTRY's, though.

---
 tools/widl/parser.y    |   23 +++++++++++++++++++++-
 tools/widl/typegen.c   |   49 +----------------------------------------------
 tools/widl/typelib.c   |    2 +-
 tools/widl/widltypes.h |    2 +
 4 files changed, 27 insertions(+), 49 deletions(-)

diff --git a/tools/widl/parser.y b/tools/widl/parser.y
index 68ef0cb..06f1f77 100644
--- a/tools/widl/parser.y
+++ b/tools/widl/parser.y
@@ -1249,9 +1249,30 @@ static array_dims_t *append_array(array_dims_t *list, expr_t *expr)
     return list;
 }
 
+static struct list type_pool = LIST_INIT(type_pool);
+typedef struct
+{
+  type_t data;
+  struct list link;
+} type_pool_node_t;
+
+type_t *alloc_type(void)
+{
+  type_pool_node_t *node = xmalloc(sizeof *node);
+  list_add_tail(&type_pool, &node->link);
+  return &node->data;
+}
+
+void set_all_tfswrite(int val)
+{
+  type_pool_node_t *node;
+  LIST_FOR_EACH_ENTRY(node, &type_pool, type_pool_node_t, link)
+    node->data.tfswrite = val;
+}
+
 static type_t *make_type(unsigned char type, type_t *ref)
 {
-  type_t *t = xmalloc(sizeof(type_t));
+  type_t *t = alloc_type();
   t->name = NULL;
   t->kind = TKIND_PRIMITIVE;
   t->type = type;
diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c
index ba2c983..f3ca74f 100644
--- a/tools/widl/typegen.c
+++ b/tools/widl/typegen.c
@@ -2095,36 +2095,6 @@ static size_t write_typeformatstring_var(FILE *file, int indent, const func_t *f
                            offset, typeformat_offset);
 }
 
-static void set_tfswrite(type_t *type, int val)
-{
-    while (type->tfswrite != val)
-    {
-        type_t *utype = get_user_type(type, NULL);
-
-        type->tfswrite = val;
-
-        if (utype)
-            set_tfswrite(utype, val);
-
-        if (type->kind == TKIND_ALIAS)
-            type = type->orig;
-        else if (is_ptr(type) || is_array(type))
-            type = type->ref;
-        else
-        {
-            if (type->fields)
-            {
-                var_t *v;
-                LIST_FOR_EACH_ENTRY( v, type->fields, var_t, entry )
-                    if (v->type)
-                        set_tfswrite(v->type, val);
-            }
-
-            return;
-        }
-    }
-}
-
 static int write_embedded_types(FILE *file, const attr_list_t *attrs, type_t *type,
                                 const char *name, int write_ptr, unsigned int *tfsoff)
 {
@@ -2180,21 +2150,6 @@ static int write_embedded_types(FILE *file, const attr_list_t *attrs, type_t *ty
     return retmask;
 }
 
-static void set_all_tfswrite(const ifref_list_t *ifaces, int val)
-{
-    const ifref_t * iface;
-    const func_t *func;
-    const var_t *var;
-
-    if (ifaces)
-        LIST_FOR_EACH_ENTRY( iface, ifaces, const ifref_t, entry )
-            if (iface->iface->funcs)
-                LIST_FOR_EACH_ENTRY( func, iface->iface->funcs, const func_t, entry )
-                    if (func->args)
-                        LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry )
-                            set_tfswrite(var->type, val);
-}
-
 static size_t process_tfs(FILE *file, const ifref_list_t *ifaces, int for_objects)
 {
     const var_t *var;
@@ -2242,7 +2197,7 @@ void write_typeformatstring(FILE *file, const ifref_list_t *ifaces, int for_obje
     indent++;
     print_file(file, indent, "NdrFcShort(0x0),\n");
 
-    set_all_tfswrite(ifaces, TRUE);
+    set_all_tfswrite(TRUE);
     process_tfs(file, ifaces, for_objects);
 
     print_file(file, indent, "0x0\n");
@@ -2859,7 +2814,7 @@ size_t get_size_procformatstring(const ifref_list_t *ifaces, int for_objects)
 
 size_t get_size_typeformatstring(const ifref_list_t *ifaces, int for_objects)
 {
-    set_all_tfswrite(ifaces, FALSE);
+    set_all_tfswrite(FALSE);
     return process_tfs(NULL, ifaces, for_objects);
 }
 
diff --git a/tools/widl/typelib.c b/tools/widl/typelib.c
index 5341720..7130e50 100644
--- a/tools/widl/typelib.c
+++ b/tools/widl/typelib.c
@@ -52,7 +52,7 @@ static typelib_t *typelib;
 
 type_t *duptype(type_t *t, int dupname)
 {
-  type_t *d = xmalloc(sizeof *d);
+  type_t *d = alloc_type();
 
   *d = *t;
   if (dupname && t->name)
diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h
index a7e8d59..4145be2 100644
--- a/tools/widl/widltypes.h
+++ b/tools/widl/widltypes.h
@@ -313,6 +313,8 @@ extern user_type_list_t user_type_list;
 void check_for_user_types_and_context_handles(const var_list_t *list);
 
 void init_types(void);
+type_t *alloc_type(void);
+void set_all_tfswrite(int val);
 
 type_t *duptype(type_t *t, int dupname);
 type_t *alias(type_t *t, const char *name);



More information about the wine-patches mailing list