Bug 569633 – Typelib compiler fails with vararg callbacks
authorRober Carr <carrr@rpi.edu>
Tue, 10 Feb 2009 23:34:04 +0000 (23:34 +0000)
committerColin Walters <walters@src.gnome.org>
Tue, 10 Feb 2009 23:34:04 +0000 (23:34 +0000)
2009-02-10  Rober Carr <carrr@rpi.edu>

Bug 569633 – Typelib compiler fails with vararg callbacks

* girepository/girparser.c: Also filter out callback functions
which take vararg arguments.

svn path=/trunk/; revision=1095

ChangeLog
girepository/girparser.c
tests/scanner/foo-1.0-expected.gir
tests/scanner/foo.h

index 380b6b0..d12f5e6 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2009-02-10  Rober Carr <carrr@rpi.edu>
+
+       Bug 569633 – Typelib compiler fails with vararg callbacks
+
+       * girepository/girparser.c: Also filter out callback functions
+       which take vararg arguments.
+
 2009-02-10  Xan Lopez  <xan@gnome.org>
 
        Bug 570903 - Add information about -I flag to scanner manpage
index eb3c11d..b376234 100644 (file)
@@ -3040,18 +3040,20 @@ cleanup (GMarkupParseContext *context,
 }
 
 static GList *
-post_filter_varargs_functions (GList *list)
+post_filter_toplevel_varargs_functions (GList *list, 
+                                       GList **varargs_callbacks_out)
 {
   GList *iter;
-
+  GList *varargs_callbacks = *varargs_callbacks_out;
+  
   iter = list;
   while (iter)
     {
       GList *link = iter;
       GIrNode *node = iter->data;
-
+      
       iter = iter->next;
-
+      
       if (node->type == G_IR_NODE_FUNCTION)
        {
          if (((GIrNodeFunction*)node)->is_varargs)
@@ -3059,7 +3061,76 @@ post_filter_varargs_functions (GList *list)
              list = g_list_delete_link (list, link);
            }
        }
+      if (node->type == G_IR_NODE_CALLBACK)
+       {
+         if (((GIrNodeFunction*)node)->is_varargs)
+           {
+             varargs_callbacks = g_list_append (varargs_callbacks,
+                                                node);
+             list = g_list_delete_link (list, link);
+           }
+       }
+    }
+  
+  *varargs_callbacks_out = varargs_callbacks;
+  
+  return list;
+}
+
+static GList *
+post_filter_varargs_functions (GList *list, GList ** varargs_callbacks_out)
+{
+  GList *iter;
+  GList *varargs_callbacks;
+  
+  list = post_filter_toplevel_varargs_functions (list, varargs_callbacks_out);
+  
+  varargs_callbacks = *varargs_callbacks_out;
+
+  iter = list;
+  while (iter)
+    {
+      GList *link = iter;
+      GIrNode *node = iter->data;
+      
+      iter = iter->next;
+      
+      if (node->type == G_IR_NODE_FUNCTION)
+       {
+         GList *param;
+         gboolean function_done = FALSE;
+         
+         for (param = ((GIrNodeFunction *)node)->parameters;
+              param;
+              param = param->next)
+           {
+             GIrNodeParam *node = (GIrNodeParam *)param->data;
+             
+             if (function_done)
+               break;
+
+             if (node->type->is_interface)
+               {
+                 GList *callback;
+                 for (callback = varargs_callbacks;
+                      callback;
+                      callback = callback->next)
+                   {
+                     if (!strcmp (node->type->interface,
+                                  ((GIrNode *)varargs_callbacks->data)->name))
+                       {
+                         list = g_list_delete_link (list, link);
+                         function_done = TRUE;
+                         break;
+                       }
+                   }
+               }
+           }
+       }
     }
+  
+  *varargs_callbacks_out = varargs_callbacks;
+  
   return list;
 }
 
@@ -3067,37 +3138,44 @@ static void
 post_filter (GIrModule *module)
 {
   GList *iter;
-
-  module->entries = post_filter_varargs_functions (module->entries);
+  GList *varargs_callbacks = NULL;
+  
+  module->entries = post_filter_varargs_functions (module->entries,
+                                                  &varargs_callbacks);
   iter = module->entries;
   while (iter)
     {
       GIrNode *node = iter->data;
-
+      
       iter = iter->next;
       
       if (node->type == G_IR_NODE_OBJECT || 
          node->type == G_IR_NODE_INTERFACE) 
        {
          GIrNodeInterface *iface = (GIrNodeInterface*)node;
-         iface->members = post_filter_varargs_functions (iface->members);
+         iface->members = post_filter_varargs_functions (iface->members,
+                                                         &varargs_callbacks);
        }
       else if (node->type == G_IR_NODE_BOXED)
        {
          GIrNodeBoxed *boxed = (GIrNodeBoxed*)node;
-         boxed->members = post_filter_varargs_functions (boxed->members);
+         boxed->members = post_filter_varargs_functions (boxed->members,
+                                                         &varargs_callbacks);
        }
       else if (node->type == G_IR_NODE_STRUCT)
        {
          GIrNodeStruct *iface = (GIrNodeStruct*)node;
-         iface->members = post_filter_varargs_functions (iface->members);
+         iface->members = post_filter_varargs_functions (iface->members,
+                                                         &varargs_callbacks);
        }
       else if (node->type == G_IR_NODE_UNION)
        {
          GIrNodeUnion *iface = (GIrNodeUnion*)node;
-         iface->members = post_filter_varargs_functions (iface->members);
+         iface->members = post_filter_varargs_functions (iface->members,
+                                                         &varargs_callbacks);
        }
     }
+  g_list_free (varargs_callbacks);
 }
 
 /**
index 7bc2009..a76fa4e 100644 (file)
@@ -640,6 +640,59 @@ and/or use gtk-doc annotations.  -->
         </parameter>
       </parameters>
     </function>
+    <callback name="VarargsCallback" c:type="FooVarargsCallback">
+      <return-value transfer-ownership="none">
+        <type name="none" c:type="void"/>
+      </return-value>
+      <parameters>
+        <parameter name="param" transfer-ownership="none">
+          <type name="utf8" c:type="char*"/>
+        </parameter>
+        <parameter transfer-ownership="none">
+          <varargs>
+          </varargs>
+        </parameter>
+      </parameters>
+    </callback>
+    <function name="test_varargs_callback"
+              c:identifier="foo_test_varargs_callback">
+      <return-value transfer-ownership="none">
+        <type name="none" c:type="void"/>
+      </return-value>
+      <parameters>
+        <parameter name="i" transfer-ownership="none">
+          <type name="int" c:type="gint"/>
+        </parameter>
+        <parameter name="callback" transfer-ownership="none">
+          <type name="VarargsCallback" c:type="FooVarargsCallback"/>
+        </parameter>
+      </parameters>
+    </function>
+    <function name="test_varargs_callback2"
+              c:identifier="foo_test_varargs_callback2">
+      <return-value transfer-ownership="none">
+        <type name="none" c:type="void"/>
+      </return-value>
+      <parameters>
+        <parameter name="callback" transfer-ownership="none">
+          <type name="VarargsCallback" c:type="FooVarargsCallback"/>
+        </parameter>
+      </parameters>
+    </function>
+    <function name="test_varargs_callback3"
+              c:identifier="foo_test_varargs_callback3">
+      <return-value transfer-ownership="none">
+        <type name="none" c:type="void"/>
+      </return-value>
+      <parameters>
+        <parameter name="callback" transfer-ownership="none">
+          <type name="VarargsCallback" c:type="FooVarargsCallback"/>
+        </parameter>
+        <parameter name="callback2" transfer-ownership="none">
+          <type name="VarargsCallback" c:type="FooVarargsCallback"/>
+        </parameter>
+      </parameters>
+    </function>
     <enumeration name="Error"
                  glib:type-name="FooError"
                  glib:get-type="foo_error_get_type"
index e866bbe..060b5d5 100644 (file)
@@ -303,6 +303,12 @@ const FooStruct * foo_test_const_struct_retval (void);
 void foo_test_const_char_param (const char * param);
 void foo_test_const_struct_param (const FooStruct * param);
 
+typedef void (*FooVarargsCallback) (const char * param, ...);
+void foo_test_varargs_callback (gint i, FooVarargsCallback callback);
+void foo_test_varargs_callback2 (FooVarargsCallback callback);
+void foo_test_varargs_callback3 (FooVarargsCallback callback,
+                                FooVarargsCallback callback2);
+
 typedef enum {
   FOO_ERROR_GOOD,
   FOO_ERROR_BAD,