From e12863aae85dc131fcdd552edd6b32bd15702e12 Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Tue, 1 Jun 2004 03:02:26 +0000 Subject: 2004-05-31 Havoc Pennington * glib/dbus-gidl.c (method_info_add_arg): keep args sorted with "in" before "out" * glib/dbus-gobject.c (dbus_type_to_string): move to dbus-gutils.c * glib/dbus-glib-tool.c (main): set up to have a --self-test option that runs the tests, and start filling in some code including for starters just dumping the interfaces to stdout * glib/Makefile.am (INCLUDES): define DBUS_LOCALEDIR * test/data/valid-introspection-files/lots-of-types.xml: test of an example introspection file * glib/dbus-gparser.c (parser_check_doctype): doctype should be "node" (I think...) --- glib/Makefile.am | 9 +- glib/dbus-gidl.c | 25 +++++ glib/dbus-glib-tool.c | 280 +++++++++++++++++++++++++++++++++++++++++++++++--- glib/dbus-glib.h | 5 +- glib/dbus-gobject.c | 36 +------ glib/dbus-gparser.c | 4 +- glib/dbus-gutils.c | 34 ++++++ glib/dbus-gutils.h | 4 +- 8 files changed, 338 insertions(+), 59 deletions(-) (limited to 'glib') diff --git a/glib/Makefile.am b/glib/Makefile.am index c594ece1..5d2172e3 100644 --- a/glib/Makefile.am +++ b/glib/Makefile.am @@ -1,4 +1,4 @@ -INCLUDES=-I$(top_srcdir) $(DBUS_CLIENT_CFLAGS) $(DBUS_GLIB_CFLAGS) $(DBUS_GLIB_TOOL_CFLAGS) -DDBUS_COMPILATION=1 +INCLUDES=-I$(top_srcdir) $(DBUS_CLIENT_CFLAGS) $(DBUS_GLIB_CFLAGS) $(DBUS_GLIB_TOOL_CFLAGS) -DDBUS_COMPILATION=1 -DDBUS_LOCALEDIR=\"$(prefix)/@DATADIRNAME@/locale\" dbusincludedir=$(includedir)/dbus-1.0/dbus @@ -41,8 +41,7 @@ libdbus_gtool_la_LIBADD = libdbus-glib-1.la bin_PROGRAMS=dbus-glib-tool dbus_glib_tool_SOURCES = \ - dbus-glib-tool.c \ - dbus-gtool-test.h + dbus-glib-tool.c dbus_glib_tool_LDADD= $(DBUS_GLIB_TOOL_LIBS) libdbus-gtool.la @@ -58,7 +57,9 @@ noinst_PROGRAMS= $(TESTS) TESTS_ENVIRONMENT=DBUS_TEST_DATA=$(top_builddir)/test/data DBUS_TEST_HOMEDIR=$(top_builddir)/dbus TESTS=dbus-glib-test -dbus_glib_test_SOURCES= \ +## FIXME we aren't running dbus-glib-tool --self-test + +dbus_glib_test_SOURCES= \ dbus-gtest-main.c dbus_glib_test_LDADD= $(top_builddir)/glib/libdbus-glib-1.la diff --git a/glib/dbus-gidl.c b/glib/dbus-gidl.c index 2605df01..7db25c86 100644 --- a/glib/dbus-gidl.c +++ b/glib/dbus-gidl.c @@ -403,12 +403,33 @@ method_info_get_args (MethodInfo *info) return info->args; } +static int +args_sort_by_direction (const void *a, + const void *b) +{ + const ArgInfo *arg_a = a; + const ArgInfo *arg_b = b; + + if (arg_a->direction == arg_b->direction) + return 0; + else if (arg_a->direction == ARG_IN) + return -1; /* in is less than out */ + else + return 1; +} + void method_info_add_arg (MethodInfo *info, ArgInfo *arg) { arg_info_ref (arg); info->args = g_slist_append (info->args, arg); + + /* Keep "in" args sorted before "out" and otherwise maintain + * stable order (g_slist_sort is stable, at least in sufficiently + * new glib) + */ + info->args = g_slist_sort (info->args, args_sort_by_direction); } SignalInfo* @@ -459,8 +480,12 @@ void signal_info_add_arg (SignalInfo *info, ArgInfo *arg) { + g_assert (arg->direction == ARG_OUT); + arg_info_ref (arg); info->args = g_slist_append (info->args, arg); + + /* signal args don't need sorting since only "out" is allowed */ } ArgInfo* diff --git a/glib/dbus-glib-tool.c b/glib/dbus-glib-tool.c index 738f914d..d1195516 100644 --- a/glib/dbus-glib-tool.c +++ b/glib/dbus-glib-tool.c @@ -1,7 +1,7 @@ /* -*- mode: C; c-file-style: "gnu" -*- */ -/* dbus-compiler-main.c main() for GLib stubs/skels generator +/* dbus-glib-tool.c Tool used by apps using glib bindings * - * Copyright (C) 2003 Red Hat, Inc. + * Copyright (C) 2003, 2004 Red Hat, Inc. * * Licensed under the Academic Free License version 2.0 * @@ -21,21 +21,267 @@ * */ +#include #include "dbus-gidl.h" +#include "dbus-gparser.h" +#include "dbus-gutils.h" #include +#include +#define _(x) dgettext (GETTEXT_PACKAGE, x) +#define N_(x) x +#include +#include +#include #ifdef DBUS_BUILD_TESTS static void run_all_tests (const char *test_data_dir); #endif +static void +indent (int depth) +{ + depth *= 2; /* 2-space indent */ + + while (depth > 0) + { + putc (' ', stdout); + --depth; + } +} + +static void pretty_print (BaseInfo *base, + int depth); + +static void +pretty_print_list (GSList *list, + int depth) +{ + GSList *tmp; + + tmp = list; + while (tmp != NULL) + { + pretty_print (tmp->data, depth); + tmp = tmp->next; + } +} + +static void +pretty_print (BaseInfo *base, + int depth) +{ + InfoType t; + const char *name; + + t = base_info_get_type (base); + name = base_info_get_name (base); + + indent (depth); + + switch (t) + { + case INFO_TYPE_NODE: + { + NodeInfo *n = (NodeInfo*) base; + + if (name == NULL) + printf (_(" {\n")); + else + printf (_("node \"%s\" {\n"), name); + + pretty_print_list (node_info_get_interfaces (n), depth + 1); + pretty_print_list (node_info_get_nodes (n), depth + 1); + + indent (depth); + printf ("}\n"); + } + break; + case INFO_TYPE_INTERFACE: + { + InterfaceInfo *i = (InterfaceInfo*) base; + + g_assert (name != NULL); + + printf (_("interface \"%s\" {\n"), name); + + pretty_print_list (interface_info_get_methods (i), depth + 1); + pretty_print_list (interface_info_get_signals (i), depth + 1); + + indent (depth); + printf ("}\n"); + } + break; + case INFO_TYPE_METHOD: + { + MethodInfo *m = (MethodInfo*) base; + + g_assert (name != NULL); + + printf (_("method \"%s\" (\n"), name); + + pretty_print_list (method_info_get_args (m), depth + 1); + + indent (depth); + printf (")\n"); + } + break; + case INFO_TYPE_SIGNAL: + { + SignalInfo *s = (SignalInfo*) base; + + g_assert (name != NULL); + + printf (_("signal \"%s\" (\n"), name); + + pretty_print_list (signal_info_get_args (s), depth + 1); + + indent (depth); + printf (")\n"); + } + break; + case INFO_TYPE_ARG: + { + ArgInfo *a = (ArgInfo*) base; + int at = arg_info_get_type (a); + ArgDirection d = arg_info_get_direction (a); + + printf ("%s %s", + d == ARG_IN ? "in" : "out", + _dbus_gutils_type_to_string (at)); + if (name) + printf (" %s\n", name); + else + printf ("\n"); + } + break; + } +} + +static void +usage (int ecode) +{ + fprintf (stderr, "dbus-glib-tool [--version] [--help]\n"); + exit (ecode); +} + +static void +version (void) +{ + printf ("D-BUS GLib Tool %s\n" + "Copyright (C) 2003, 2004 Red Hat, Inc.\n" + "This is free software; see the source for copying conditions.\n" + "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n", + VERSION); + exit (0); +} + int main (int argc, char **argv) { - setlocale(LC_ALL, ""); + const char *prev_arg; + int i; + GSList *files; + gboolean end_of_args; + GSList *tmp; + gboolean just_pretty_print; + + setlocale (LC_ALL, ""); + bindtextdomain (GETTEXT_PACKAGE, DBUS_LOCALEDIR); + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); + textdomain (GETTEXT_PACKAGE); + + just_pretty_print = FALSE; + end_of_args = FALSE; + files = NULL; + prev_arg = NULL; + i = 1; + while (i < argc) + { + const char *arg = argv[i]; + + if (!end_of_args) + { + if (strcmp (arg, "--help") == 0 || + strcmp (arg, "-h") == 0 || + strcmp (arg, "-?") == 0) + usage (0); + else if (strcmp (arg, "--version") == 0) + version (); +#ifdef DBUS_BUILD_TESTS + else if (strcmp (arg, "--self-test") == 0) + run_all_tests (NULL); +#endif /* DBUS_BUILD_TESTS */ + else if (strcmp (arg, "--pretty-print") == 0) + just_pretty_print = TRUE; + else if (arg[0] == '-' && + arg[1] == '-' && + arg[2] == '\0') + end_of_args = TRUE; + else if (arg[0] == '-') + { + usage (1); + } + else + { + files = g_slist_prepend (files, (char*) arg); + } + } + else + files = g_slist_prepend (files, (char*) arg); + + prev_arg = arg; + + ++i; + } + + files = g_slist_reverse (files); + tmp = files; + while (tmp != NULL) + { + NodeInfo *node; + GError *error; + const char *filename; + + filename = tmp->data; + + error = NULL; + node = description_load_from_file (filename, + &error); + if (node == NULL) + { + g_assert (error != NULL); + fprintf (stderr, _("Unable to load \"%s\": %s\n"), + filename, error->message); + g_error_free (error); + exit (1); + } + else if (just_pretty_print) + { + pretty_print ((BaseInfo*) node, 0); + } + else + { + /* FIXME process the file to generate metadata variable + * definition rather than just printing it. + * i.e. we want to create DBusGObjectInfo. + * This probably requires extending the introspection XML format to + * allow a "native function name": + * + */ + pretty_print ((BaseInfo*) node, 0); + } + + if (node) + node_info_unref (node); + + tmp = tmp->next; + } + return 0; } + #ifdef DBUS_BUILD_TESTS static void test_die (const char *failure) @@ -44,11 +290,23 @@ test_die (const char *failure) exit (1); } +/** + * @ingroup DBusGTool + * Unit test for GLib utility tool + * @returns #TRUE on success. + */ +static dbus_bool_t +_dbus_gtool_test (const char *test_data_dir) +{ + + return TRUE; +} + static void run_all_tests (const char *test_data_dir) { if (test_data_dir == NULL) - test_data_dir = _dbus_getenv ("DBUS_TEST_DATA"); + test_data_dir = g_getenv ("DBUS_TEST_DATA"); if (test_data_dir != NULL) printf ("Test data in %s\n", test_data_dir); @@ -59,19 +317,7 @@ run_all_tests (const char *test_data_dir) if (!_dbus_gtool_test (test_data_dir)) test_die ("gtool"); - printf ("%s: completed successfully\n", "dbus-glib-test"); -} - -/** - * @ingroup DBusGTool - * Unit test for GLib utility tool - * @returns #TRUE on success. - */ -dbus_bool_t -_dbus_gtool_test (const char *test_data_dir) -{ - - return TRUE; + printf ("%s: completed successfully\n", "dbus-glib-tool"); } #endif /* DBUS_BUILD_TESTS */ diff --git a/glib/dbus-glib.h b/glib/dbus-glib.h index 64420e72..483a6e81 100644 --- a/glib/dbus-glib.h +++ b/glib/dbus-glib.h @@ -80,10 +80,11 @@ struct DBusGMethodInfo */ struct DBusGObjectInfo { + int format_version; /**< Allows us to change the rest of this struct + * by adding DBusGObjectInfo2, DBusGObjectInfo3, etc. + */ const DBusGMethodInfo *infos; /**< Array of method pointers */ const unsigned char *data; /**< Introspection data */ - void *dbus_internal_padding1; /**< Reserved for expansion */ - void *dbus_internal_padding2; /**< Reserved for expansion */ }; void dbus_g_object_class_install_info (GObjectClass *object_class, diff --git a/glib/dbus-gobject.c b/glib/dbus-gobject.c index 18e4cb5f..0168697e 100644 --- a/glib/dbus-gobject.c +++ b/glib/dbus-gobject.c @@ -149,36 +149,6 @@ gtype_to_dbus_type (GType type) } } -static const char * -dbus_type_to_string (int type) -{ - switch (type) - { - case DBUS_TYPE_INVALID: - return "invalid"; - case DBUS_TYPE_NIL: - return "nil"; - case DBUS_TYPE_BOOLEAN: - return "boolean"; - case DBUS_TYPE_INT32: - return "int32"; - case DBUS_TYPE_UINT32: - return "uint32"; - case DBUS_TYPE_DOUBLE: - return "double"; - case DBUS_TYPE_STRING: - return "string"; - case DBUS_TYPE_CUSTOM: - return "custom"; - case DBUS_TYPE_ARRAY: - return "array"; - case DBUS_TYPE_DICT: - return "dict"; - default: - return "unknown"; - } -} - static void introspect_properties (GObject *object, GString *xml) { @@ -234,7 +204,7 @@ introspect_properties (GObject *object, GString *xml) g_string_append (xml, "\">\n"); g_string_append (xml, " \n"); } @@ -245,7 +215,7 @@ introspect_properties (GObject *object, GString *xml) g_string_append (xml, "\">\n"); g_string_append (xml, " \n"); } @@ -292,7 +262,7 @@ introspect_signals (GType type, GString *xml) int dbus_type = gtype_to_dbus_type (query.param_types[arg]); g_string_append (xml, " \n"); } diff --git a/glib/dbus-gparser.c b/glib/dbus-gparser.c index 83aaf782..2cdca81f 100644 --- a/glib/dbus-gparser.c +++ b/glib/dbus-gparser.c @@ -212,12 +212,12 @@ parser_check_doctype (Parser *parser, { g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - if (strcmp (doctype, "dbus_description") != 0) + if (strcmp (doctype, "node") != 0) { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - "D-BUS description file has the wrong document type %s, use dbus_description", + "D-BUS description file has the wrong document type %s, use node or interface", doctype); return FALSE; } diff --git a/glib/dbus-gutils.c b/glib/dbus-gutils.c index eeaa7f94..8c4d3d09 100644 --- a/glib/dbus-gutils.c +++ b/glib/dbus-gutils.c @@ -77,6 +77,40 @@ _dbus_gutils_split_path (const char *path) return split; } +const char * +_dbus_gutils_type_to_string (int type) +{ + switch (type) + { + case DBUS_TYPE_INVALID: + return "invalid"; + case DBUS_TYPE_NIL: + return "nil"; + case DBUS_TYPE_BOOLEAN: + return "boolean"; + case DBUS_TYPE_INT32: + return "int32"; + case DBUS_TYPE_UINT32: + return "uint32"; + case DBUS_TYPE_DOUBLE: + return "double"; + case DBUS_TYPE_STRING: + return "string"; + case DBUS_TYPE_CUSTOM: + return "custom"; + case DBUS_TYPE_ARRAY: + return "array"; + case DBUS_TYPE_DICT: + return "dict"; + case DBUS_TYPE_INT64: + return "int64"; + case DBUS_TYPE_UINT64: + return "uint64"; + default: + return "unknown"; + } +} + #ifdef DBUS_BUILD_TESTS /** diff --git a/glib/dbus-gutils.h b/glib/dbus-gutils.h index 000cd3da..84041d04 100644 --- a/glib/dbus-gutils.h +++ b/glib/dbus-gutils.h @@ -31,7 +31,9 @@ G_BEGIN_DECLS -char** _dbus_gutils_split_path (const char *path); +char **_dbus_gutils_split_path (const char *path); +const char *_dbus_gutils_type_to_string (int type); + G_END_DECLS -- cgit