diff options
author | Rober Carr <carrr@rpi.edu> | 2009-02-10 23:34:04 +0000 |
---|---|---|
committer | Colin Walters <walters@src.gnome.org> | 2009-02-10 23:34:04 +0000 |
commit | 049dc259e7f2c5f71eec63fb42a5cd5ec70d7be3 (patch) | |
tree | cc9141b7375d869497ad7e8e0e3c007d54ae8844 | |
parent | 328524ab5212d0632a8b3405d6e4375db6aba086 (diff) | |
download | gobject-introspection-049dc259e7f2c5f71eec63fb42a5cd5ec70d7be3.tar.gz |
Bug 569633 – Typelib compiler fails with vararg callbacks
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
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | girepository/girparser.c | 100 | ||||
-rw-r--r-- | tests/scanner/foo-1.0-expected.gir | 53 | ||||
-rw-r--r-- | tests/scanner/foo.h | 6 |
4 files changed, 155 insertions, 11 deletions
@@ -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 diff --git a/girepository/girparser.c b/girepository/girparser.c index eb3c11d3..b376234d 100644 --- a/girepository/girparser.c +++ b/girepository/girparser.c @@ -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); } /** diff --git a/tests/scanner/foo-1.0-expected.gir b/tests/scanner/foo-1.0-expected.gir index 7bc20095..a76fa4ee 100644 --- a/tests/scanner/foo-1.0-expected.gir +++ b/tests/scanner/foo-1.0-expected.gir @@ -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" diff --git a/tests/scanner/foo.h b/tests/scanner/foo.h index e866bbea..060b5d55 100644 --- a/tests/scanner/foo.h +++ b/tests/scanner/foo.h @@ -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, |