From faa3c319ba4021372a3bcc1829f357007419124e Mon Sep 17 00:00:00 2001 From: Will Thompson Date: Wed, 5 Dec 2018 21:32:05 +0000 Subject: [PATCH 1/4] gdbus-codegen: make --interface-info-{header,body} not crash Since 1217b1bc4f242c14d6eabbee0c688c320eab2e4d, LICENSE_STR has taken two parameters, not one. Without this change, running either mode fails with a traceback like: Traceback (most recent call last): File "../gdbus-codegen", line 55, in sys.exit(codegen_main.codegen_main()) File ".../codegen_main.py", line 294, in codegen_main gen.generate() File ".../codegen.py", line 896, in generate self.generate_body_preamble() File ".../codegen.py", line 682, in generate_body_preamble self.outfile.write(LICENSE_STR.format(config.VERSION)) IndexError: tuple index out of range 8916874ee6f3ff0f887dbe1eda55c23c2c0097ee, which introduced these flags, was actually merged after that commit, but I assume it was written beforehand. --- gio/gdbus-2.0/codegen/codegen.py | 12 ++++++++---- gio/gdbus-2.0/codegen/codegen_main.py | 2 ++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/gio/gdbus-2.0/codegen/codegen.py b/gio/gdbus-2.0/codegen/codegen.py index 9d2b904c7..9220176a8 100644 --- a/gio/gdbus-2.0/codegen/codegen.py +++ b/gio/gdbus-2.0/codegen/codegen.py @@ -619,17 +619,19 @@ class HeaderCodeGenerator: # ---------------------------------------------------------------------------------------------------- class InterfaceInfoHeaderCodeGenerator: - def __init__(self, ifaces, namespace, header_name, use_pragma, outfile): + def __init__(self, ifaces, namespace, header_name, input_files_basenames, use_pragma, outfile): self.ifaces = ifaces self.namespace, self.ns_upper, self.ns_lower = generate_namespace(namespace) self.header_guard = header_name.upper().replace('.', '_').replace('-', '_').replace('/', '_').replace(':', '_') + self.input_files_basenames = input_files_basenames self.use_pragma = use_pragma self.outfile = outfile # ---------------------------------------------------------------------------------------------------- def generate_header_preamble(self): - self.outfile.write(LICENSE_STR.format(config.VERSION)) + basenames = ', '.join(self.input_files_basenames) + self.outfile.write(LICENSE_STR.format(config.VERSION, basenames)) self.outfile.write('\n') if self.use_pragma: @@ -670,16 +672,18 @@ class InterfaceInfoHeaderCodeGenerator: # ---------------------------------------------------------------------------------------------------- class InterfaceInfoBodyCodeGenerator: - def __init__(self, ifaces, namespace, header_name, outfile): + def __init__(self, ifaces, namespace, header_name, input_files_basenames, outfile): self.ifaces = ifaces self.namespace, self.ns_upper, self.ns_lower = generate_namespace(namespace) self.header_name = header_name + self.input_files_basenames = input_files_basenames self.outfile = outfile # ---------------------------------------------------------------------------------------------------- def generate_body_preamble(self): - self.outfile.write(LICENSE_STR.format(config.VERSION)) + basenames = ', '.join(self.input_files_basenames) + self.outfile.write(LICENSE_STR.format(config.VERSION, basenames)) self.outfile.write('\n') self.outfile.write('#ifdef HAVE_CONFIG_H\n' '# include "config.h"\n' diff --git a/gio/gdbus-2.0/codegen/codegen_main.py b/gio/gdbus-2.0/codegen/codegen_main.py index 03de1d107..880ff3932 100644 --- a/gio/gdbus-2.0/codegen/codegen_main.py +++ b/gio/gdbus-2.0/codegen/codegen_main.py @@ -281,6 +281,7 @@ def codegen_main(): gen = codegen.InterfaceInfoHeaderCodeGenerator(all_ifaces, args.c_namespace, header_name, + input_files_basenames, args.pragma_once, outfile) gen.generate() @@ -290,6 +291,7 @@ def codegen_main(): gen = codegen.InterfaceInfoBodyCodeGenerator(all_ifaces, args.c_namespace, header_name, + input_files_basenames, outfile) gen.generate() From deafd7256ed67826147ba00466be63dff96d1da3 Mon Sep 17 00:00:00 2001 From: Will Thompson Date: Thu, 6 Dec 2018 17:28:09 +0000 Subject: [PATCH 2/4] gdbus-codegen: don't sort args in --interface-info-body Previously, method and signal arguments were sorted by name, which (assuming you don't happen to give your arguments lexicographically-ordered names) means the generated signatures were incorrect when there is more than 1 argument. While sorting the methods and signals themselves (and properties, and annotations on all these) is fine, it's easiest to not sort anything. --- gio/gdbus-2.0/codegen/codegen.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gio/gdbus-2.0/codegen/codegen.py b/gio/gdbus-2.0/codegen/codegen.py index 9220176a8..daf55bfbe 100644 --- a/gio/gdbus-2.0/codegen/codegen.py +++ b/gio/gdbus-2.0/codegen/codegen.py @@ -700,7 +700,7 @@ class InterfaceInfoBodyCodeGenerator: def generate_array(self, array_name_lower, element_type, elements): self.outfile.write('const %s * const %s[] =\n' % (element_type, array_name_lower)) self.outfile.write('{\n') - for (_, name) in sorted(elements, key=utils.version_cmp_key): + for (_, name) in elements: self.outfile.write(' &%s,\n' % name) self.outfile.write(' NULL,\n') self.outfile.write('};\n') From d946bff4800c919d50a70e1770066aa42bc38e36 Mon Sep 17 00:00:00 2001 From: Will Thompson Date: Mon, 10 Dec 2018 13:40:11 +0000 Subject: [PATCH 3/4] gdbus-codegen: sort input files This means the output (including lists of filenames) does not depend on the order of the input files, which may matter if this tool is invoked with a glob or some other mechanism that doesn't guarantee an order. --- gio/gdbus-2.0/codegen/codegen_main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gio/gdbus-2.0/codegen/codegen_main.py b/gio/gdbus-2.0/codegen/codegen_main.py index 880ff3932..7683f0af5 100644 --- a/gio/gdbus-2.0/codegen/codegen_main.py +++ b/gio/gdbus-2.0/codegen/codegen_main.py @@ -235,7 +235,7 @@ def codegen_main(): all_ifaces = [] input_files_basenames = [] - for fname in args.files + args.xml_files: + for fname in sorted(args.files + args.xml_files): with open(fname, 'rb') as f: xml_data = f.read() parsed_ifaces = parser.parse_dbus_xml(xml_data) From 335a01ebe4c4dda550af8ef578c0b2e9fdd35e3c Mon Sep 17 00:00:00 2001 From: Will Thompson Date: Thu, 6 Dec 2018 21:38:39 +0000 Subject: [PATCH 4/4] gdbus-codegen: test --interface-info-{header,body} This test is rudimentary but better than nothing. --- gio/tests/Makefile.am | 42 +++++++++++-- gio/tests/gdbus-test-codegen.c | 106 +++++++++++++++++++++++++++++++++ gio/tests/meson.build | 44 ++++++++++---- 3 files changed, 177 insertions(+), 15 deletions(-) diff --git a/gio/tests/Makefile.am b/gio/tests/Makefile.am index 8efb1eaa0..21850974f 100644 --- a/gio/tests/Makefile.am +++ b/gio/tests/Makefile.am @@ -487,16 +487,16 @@ gdbus_proxy_threads_SOURCES = $(gdbus_sessionbus_sources) gdbus-pro gdbus_proxy_unique_name_SOURCES = $(gdbus_sessionbus_sources) gdbus-proxy-unique-name.c gdbus_proxy_well_known_name_SOURCES = $(gdbus_sessionbus_sources) gdbus-proxy-well-known-name.c gdbus_test_codegen_SOURCES = $(gdbus_sessionbus_sources) gdbus-test-codegen.c -nodist_gdbus_test_codegen_SOURCES = gdbus-test-codegen-generated.c gdbus-test-codegen-generated.h +nodist_gdbus_test_codegen_SOURCES = gdbus-test-codegen-generated.c gdbus-test-codegen-generated.h gdbus-test-codegen-generated-interface-info.c gdbus-test-codegen-generated-interface-info.h gdbus_test_codegen_old_SOURCES = $(gdbus_sessionbus_sources) gdbus-test-codegen.c -nodist_gdbus_test_codegen_old_SOURCES = gdbus-test-codegen-generated.c gdbus-test-codegen-generated.h +nodist_gdbus_test_codegen_old_SOURCES = gdbus-test-codegen-generated.c gdbus-test-codegen-generated.h gdbus-test-codegen-generated-interface-info.c gdbus-test-codegen-generated-interface-info.h gdbus_test_codegen_old_CPPFLAGS = $(AM_CPPFLAGS) -DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_36 -DGLIB_VERSION_MAX_ALLOWED=GLIB_VERSION_2_36 gdbus_threading_SOURCES = $(gdbus_sessionbus_sources) gdbus-threading.c gmenumodel_SOURCES = $(gdbus_sessionbus_sources) gmenumodel.c gnotification_SOURCES = $(gdbus_sessionbus_sources) gnotification.c gnotification-server.h gnotification-server.c -BUILT_SOURCES += gdbus-test-codegen-generated.c gdbus-test-codegen-generated.h -gdbus-test-codegen.o: gdbus-test-codegen-generated.h +BUILT_SOURCES += gdbus-test-codegen-generated.c gdbus-test-codegen-generated.h gdbus-test-codegen-generated-interface-info.c gdbus-test-codegen-generated-interface-info.h +gdbus-test-codegen.o: gdbus-test-codegen-generated.h gdbus-test-codegen-generated-interface-info.h gdbus-test-codegen-generated.h: test-codegen.xml Makefile $(top_builddir)/gio/gdbus-2.0/codegen/gdbus-codegen $(AM_V_GEN) UNINSTALLED_GLIB_SRCDIR=$(top_srcdir) \ UNINSTALLED_GLIB_BUILDDIR=$(top_builddir) \ @@ -519,9 +519,41 @@ gdbus-test-codegen-generated.h: test-codegen.xml Makefile $(top_builddir)/gio/gd $(NULL) gdbus-test-codegen-generated.c: gdbus-test-codegen-generated.h @: # Generated as side-effect of .h +gdbus-test-codegen-generated-interface-info.h: test-codegen.xml Makefile $(top_builddir)/gio/gdbus-2.0/codegen/gdbus-codegen + $(AM_V_GEN) UNINSTALLED_GLIB_SRCDIR=$(top_srcdir) \ + UNINSTALLED_GLIB_BUILDDIR=$(top_builddir) \ + $(PYTHON) $(top_builddir)/gio/gdbus-2.0/codegen/gdbus-codegen \ + --interface-info-header \ + --annotate "org.project.Bar" Key1 Value1 \ + --annotate "org.project.Bar" org.gtk.GDBus.Internal Value2 \ + --annotate "org.project.Bar.HelloWorld()" Key3 Value3 \ + --annotate "org.project.Bar::TestSignal" Key4 Value4 \ + --annotate "org.project.Bar:ay" Key5 Value5 \ + --annotate "org.project.Bar.TestPrimitiveTypes()[val_int32]" Key6 Value6 \ + --annotate "org.project.Bar.TestPrimitiveTypes()[ret_uint32]" Key7 Value7 \ + --annotate "org.project.Bar::TestSignal[array_of_strings]" Key8 Value8 \ + --output $@ \ + $(srcdir)/test-codegen.xml \ + $(NULL) +gdbus-test-codegen-generated-interface-info.c: test-codegen.xml Makefile $(top_builddir)/gio/gdbus-2.0/codegen/gdbus-codegen + $(AM_V_GEN) UNINSTALLED_GLIB_SRCDIR=$(top_srcdir) \ + UNINSTALLED_GLIB_BUILDDIR=$(top_builddir) \ + $(PYTHON) $(top_builddir)/gio/gdbus-2.0/codegen/gdbus-codegen \ + --interface-info-body \ + --annotate "org.project.Bar" Key1 Value1 \ + --annotate "org.project.Bar" org.gtk.GDBus.Internal Value2 \ + --annotate "org.project.Bar.HelloWorld()" Key3 Value3 \ + --annotate "org.project.Bar::TestSignal" Key4 Value4 \ + --annotate "org.project.Bar:ay" Key5 Value5 \ + --annotate "org.project.Bar.TestPrimitiveTypes()[val_int32]" Key6 Value6 \ + --annotate "org.project.Bar.TestPrimitiveTypes()[ret_uint32]" Key7 Value7 \ + --annotate "org.project.Bar::TestSignal[array_of_strings]" Key8 Value8 \ + --output $@ \ + $(srcdir)/test-codegen.xml \ + $(NULL) EXTRA_DIST += test-codegen.xml -CLEANFILES += gdbus-test-codegen-generated.[ch] gdbus-test-codegen-generated-doc-*.xml +CLEANFILES += gdbus-test-codegen-generated.[ch] gdbus-test-codegen-generated-doc-*.xml gdbus-test-codegen-generated-interface-info.[ch] endif # OS_UNIX endif # HAVE_DBUS_DAEMON diff --git a/gio/tests/gdbus-test-codegen.c b/gio/tests/gdbus-test-codegen.c index 653004ad6..dfc40ad32 100644 --- a/gio/tests/gdbus-test-codegen.c +++ b/gio/tests/gdbus-test-codegen.c @@ -26,6 +26,7 @@ #include "gdbus-tests.h" #include "gdbus-test-codegen-generated.h" +#include "gdbus-test-codegen-generated-interface-info.h" /* ---------------------------------------------------------------------------------------------------- */ @@ -2463,6 +2464,110 @@ test_deprecations (void) /* ---------------------------------------------------------------------------------------------------- */ +static void +assert_arg_infos_equal (GDBusArgInfo **a, + GDBusArgInfo **b) +{ + if (a == NULL) + { + g_assert_null (b); + return; + } + + g_assert_nonnull (b); + + for (; *a != NULL && *b != NULL; a++, b++) + { + g_assert_cmpstr ((*a)->name, ==, (*b)->name); + g_assert_cmpstr ((*a)->signature, ==, (*b)->signature); + } + + g_assert_null (*a); + g_assert_null (*b); +} + +static void +assert_annotations_equal (GDBusAnnotationInfo **a, + GDBusAnnotationInfo **b) +{ + guint a_len = count_annotations (a); + guint b_len = count_annotations (b); + + g_assert_cmpuint (a_len, ==, b_len); + + if (a == NULL || b == NULL) + return; + + for (; *a != NULL && *b != NULL; a++, b++) + { + g_assert_cmpstr ((*a)->key, ==, (*b)->key); + g_assert_cmpstr ((*a)->value, ==, (*b)->value); + assert_annotations_equal ((*a)->annotations, (*b)->annotations); + } + + g_assert_null (*a); + g_assert_null (*b); +} + +/* Test that the GDBusInterfaceInfo structure generated by gdbus-codegen + * --interface-info-body matches that generated by the other mode. + */ +static void +test_standalone_interface_info (void) +{ + GDBusInterfaceSkeleton *skel = G_DBUS_INTERFACE_SKELETON (foo_igen_bar_skeleton_new ()); + GDBusInterfaceInfo *skel_info = g_dbus_interface_skeleton_get_info (skel); + const GDBusInterfaceInfo *slim_info = &org_project_bar_interface; + gsize i; + + g_assert_cmpstr (skel_info->name, ==, slim_info->name); + + for (i = 0; skel_info->methods[i] != NULL; i++) + { + GDBusMethodInfo *skel_method = skel_info->methods[i]; + GDBusMethodInfo *slim_method = slim_info->methods[i]; + + g_assert_nonnull (slim_method); + g_assert_cmpstr (skel_method->name, ==, slim_method->name); + assert_arg_infos_equal (skel_method->in_args, slim_method->in_args); + assert_arg_infos_equal (skel_method->out_args, slim_method->out_args); + assert_annotations_equal (skel_method->annotations, slim_method->annotations); + } + g_assert_null (slim_info->methods[i]); + + for (i = 0; skel_info->signals[i] != NULL; i++) + { + GDBusSignalInfo *skel_signal = skel_info->signals[i]; + GDBusSignalInfo *slim_signal = slim_info->signals[i]; + + g_assert_nonnull (slim_signal); + g_assert_cmpstr (skel_signal->name, ==, slim_signal->name); + assert_arg_infos_equal (skel_signal->args, slim_signal->args); + assert_annotations_equal (skel_signal->annotations, slim_signal->annotations); + } + g_assert_null (slim_info->signals[i]); + + for (i = 0; skel_info->properties[i] != NULL; i++) + { + GDBusPropertyInfo *skel_prop = skel_info->properties[i]; + GDBusPropertyInfo *slim_prop = slim_info->properties[i]; + + g_assert_nonnull (slim_prop); + + g_assert_cmpstr (skel_prop->name, ==, slim_prop->name); + g_assert_cmpstr (skel_prop->signature, ==, slim_prop->signature); + g_assert_cmpuint (skel_prop->flags, ==, slim_prop->flags); + assert_annotations_equal (skel_prop->annotations, slim_prop->annotations); + } + g_assert_null (slim_info->properties[i]); + + assert_annotations_equal (skel_info->annotations, slim_info->annotations); + + g_clear_object (&skel); +} + +/* ---------------------------------------------------------------------------------------------------- */ + int main (int argc, char *argv[]) @@ -2475,6 +2580,7 @@ main (int argc, g_test_add_func ("/gdbus/codegen/property-naming", test_property_naming); g_test_add_func ("/gdbus/codegen/autocleanups", test_autocleanups); g_test_add_func ("/gdbus/codegen/deprecations", test_deprecations); + g_test_add_func ("/gdbus/codegen/standalone-interface-info", test_standalone_interface_info); return session_bus_run (); } diff --git a/gio/tests/meson.build b/gio/tests/meson.build index a81715c11..2bec83285 100644 --- a/gio/tests/meson.build +++ b/gio/tests/meson.build @@ -171,6 +171,16 @@ if host_machine.system() != 'windows' # Test programs that need to bring up a session bus (requires dbus-daemon) have_dbus_daemon = find_program('dbus-daemon', required : false).found() if have_dbus_daemon + annotate_args = [ + '--annotate', 'org.project.Bar', 'Key1', 'Value1', + '--annotate', 'org.project.Bar', 'org.gtk.GDBus.Internal', 'Value2', + '--annotate', 'org.project.Bar.HelloWorld()', 'Key3', 'Value3', + '--annotate', 'org.project.Bar::TestSignal', 'Key4', 'Value4', + '--annotate', 'org.project.Bar:ay', 'Key5', 'Value5', + '--annotate', 'org.project.Bar.TestPrimitiveTypes()[val_int32]', 'Key6', 'Value6', + '--annotate', 'org.project.Bar.TestPrimitiveTypes()[ret_uint32]', 'Key7', 'Value7', + '--annotate', 'org.project.Bar::TestSignal[array_of_strings]', 'Key8', 'Value8', + ] # Generate gdbus-test-codegen-generated.{c,h} gdbus_test_codegen_generated = custom_target('gdbus-test-codegen-generated', input : ['test-codegen.xml'], @@ -185,16 +195,30 @@ if host_machine.system() != 'windows' '--c-generate-autocleanup', 'all', '--c-namespace', 'Foo_iGen', '--generate-docbook', 'gdbus-test-codegen-generated-doc', - '--annotate', 'org.project.Bar', 'Key1', 'Value1', - '--annotate', 'org.project.Bar', 'org.gtk.GDBus.Internal', 'Value2', - '--annotate', 'org.project.Bar.HelloWorld()', 'Key3', 'Value3', - '--annotate', 'org.project.Bar::TestSignal', 'Key4', 'Value4', - '--annotate', 'org.project.Bar:ay', 'Key5', 'Value5', - '--annotate', 'org.project.Bar.TestPrimitiveTypes()[val_int32]', 'Key6', 'Value6', - '--annotate', 'org.project.Bar.TestPrimitiveTypes()[ret_uint32]', 'Key7', 'Value7', - '--annotate', 'org.project.Bar::TestSignal[array_of_strings]', 'Key8', 'Value8', + annotate_args, '@INPUT@']) + gdbus_test_codegen_generated_interface_info = [ + custom_target('gdbus-test-codegen-generated-interface-info-h', + input : ['test-codegen.xml'], + output : ['gdbus-test-codegen-generated-interface-info.h'], + depend_files : gdbus_codegen_built_files, + command : [python, gdbus_codegen, + '--interface-info-header', + annotate_args, + '--output', '@OUTPUT@', + '@INPUT@']), + custom_target('gdbus-test-codegen-generated-interface-info-c', + input : ['test-codegen.xml'], + output : ['gdbus-test-codegen-generated-interface-info.c'], + depend_files : gdbus_codegen_built_files, + command : [python, gdbus_codegen, + '--interface-info-body', + annotate_args, + '--output', '@OUTPUT@', + '@INPUT@']), + ] + extra_sources = ['gdbus-sessionbus.c', 'gdbus-tests.c'] gio_tests += { @@ -224,7 +248,7 @@ if host_machine.system() != 'windows' 'gdbus-proxy-unique-name' : {'extra_sources' : extra_sources}, 'gdbus-proxy-well-known-name' : {'extra_sources' : extra_sources}, 'gdbus-test-codegen' : { - 'extra_sources' : [extra_sources, gdbus_test_codegen_generated], + 'extra_sources' : [extra_sources, gdbus_test_codegen_generated, gdbus_test_codegen_generated_interface_info], }, 'gdbus-threading' : { 'extra_sources' : extra_sources, @@ -239,7 +263,7 @@ if host_machine.system() != 'windows' }, 'gdbus-test-codegen-old' : { 'source' : 'gdbus-test-codegen.c', - 'extra_sources' : [extra_sources, gdbus_test_codegen_generated], + 'extra_sources' : [extra_sources, gdbus_test_codegen_generated, gdbus_test_codegen_generated_interface_info], 'c_args' : ['-DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_36', '-DGLIB_VERSION_MAX_ALLOWED=GLIB_VERSION_2_36'], },