2004-05-31 Havoc Pennington <hp@redhat.com>
authorHavoc Pennington <hp@redhat.com>
Tue, 1 Jun 2004 03:02:26 +0000 (03:02 +0000)
committerHavoc Pennington <hp@redhat.com>
Tue, 1 Jun 2004 03:02:26 +0000 (03:02 +0000)
* 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...)

ChangeLog
glib/Makefile.am
glib/dbus-gidl.c
glib/dbus-glib-tool.c
glib/dbus-glib.h
glib/dbus-gobject.c
glib/dbus-gparser.c
glib/dbus-gutils.c
glib/dbus-gutils.h
test/data/valid-introspection-files/lots-of-types.xml [new file with mode: 0644]

index ef2b505..e798965 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@
+2004-05-31  Havoc Pennington  <hp@redhat.com>
+
+       * 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...)
+
 2004-05-31  Seth Nickell  <seth@gnome.org>
 
        * python/dbus_bindings.pyx.in:
index c594ece..5d2172e 100644 (file)
@@ -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
index 2605df0..7db25c8 100644 (file)
@@ -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*
index 738f914..d119551 100644 (file)
@@ -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
  *
  *
  */
 
+#include <config.h>
 #include "dbus-gidl.h"
+#include "dbus-gparser.h"
+#include "dbus-gutils.h"
 #include <locale.h>
+#include <libintl.h>
+#define _(x) dgettext (GETTEXT_PACKAGE, x)
+#define N_(x) x
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 
 #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 (_("<anonymous node> {\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":
+           *  <method name="Frobate" native="my_object_frobate">
+           */
+          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 */
index 64420e7..483a6e8 100644 (file)
@@ -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,
index 18e4cb5..0168697 100644 (file)
@@ -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, "      <arg type=\"");
-          g_string_append (xml, dbus_type_to_string (dbus_type));
+          g_string_append (xml, _dbus_gutils_type_to_string (dbus_type));
           g_string_append (xml, "\"/>\n");
         }
 
@@ -245,7 +215,7 @@ introspect_properties (GObject *object, GString *xml)
           g_string_append (xml, "\">\n");
           
           g_string_append (xml, "      <arg type=\"");
-          g_string_append (xml, dbus_type_to_string (dbus_type));
+          g_string_append (xml, _dbus_gutils_type_to_string (dbus_type));
           g_string_append (xml, "\" direction=\"out\"/>\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, "      <arg type=\"");
-          g_string_append (xml, dbus_type_to_string (dbus_type));
+          g_string_append (xml, _dbus_gutils_type_to_string (dbus_type));
           g_string_append (xml, "\"/>\n");
        }
 
index 83aaf78..2cdca81 100644 (file)
@@ -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;
     }
index eeaa7f9..8c4d3d0 100644 (file)
@@ -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
 
 /**
index 000cd3d..84041d0 100644 (file)
@@ -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
 
diff --git a/test/data/valid-introspection-files/lots-of-types.xml b/test/data/valid-introspection-files/lots-of-types.xml
new file mode 100644 (file)
index 0000000..8e0e605
--- /dev/null
@@ -0,0 +1,93 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Introspection 0.1//EN"
+ "http://www.freedesktop.org/software/dbus/introspection.dtd">
+<node>
+
+  <interface name="org.freedesktop.LotsOfTypesInterface">
+
+    <method name="SetInt32Value">
+      <arg name="theInt32" type="int32"/>
+    </method>
+    <method name="GetInt32Value">
+      <arg name="theInt32" type="int32" direction="out"/>
+    </method>
+    <signal name="Int32ValueChanged">
+      <arg name="newInt32Value" type="int32"/>
+    </signal>
+
+    <method name="SetUint32Value">
+      <arg name="theUint32" type="uint32"/>
+    </method>
+    <method name="GetUint32Value">
+      <arg name="theUint32" type="uint32" direction="out"/>
+    </method>
+    <signal name="Uint32ValueChanged">
+      <arg name="newUint32Value" type="uint32"/>
+    </signal>
+
+    <method name="SetInt64Value">
+      <arg name="theInt64" type="int64"/>
+    </method>
+    <method name="GetInt64Value">
+      <arg name="theInt64" type="int64" direction="out"/>
+    </method>
+    <signal name="Int64ValueChanged">
+      <arg name="newInt64Value" type="int64"/>
+    </signal>
+
+    <method name="SetUint64Value">
+      <arg name="theUint64" type="uint64"/>
+    </method>
+    <method name="GetUint64Value">
+      <arg name="theUint64" type="uint64" direction="out"/>
+    </method>
+    <signal name="Uint64ValueChanged">
+      <arg name="newUint64Value" type="uint64"/>
+    </signal>
+
+    <method name="SetBooleanValue">
+      <arg name="theBoolean" type="boolean"/>
+    </method>
+    <method name="GetBooleanValue">
+      <arg name="theBoolean" type="boolean" direction="out"/>
+    </method>
+    <signal name="BooleanValueChanged">
+      <arg name="newBooleanValue" type="boolean"/>
+    </signal>
+
+    <method name="SetStringValue">
+      <arg name="theString" type="string"/>
+    </method>
+    <method name="GetStringValue">
+      <arg name="theString" type="string" direction="out"/>
+    </method>
+    <signal name="StringValueChanged">
+      <arg name="newStringValue" type="string"/>
+    </signal>
+
+    <method name="SetDoubleValue">
+      <arg name="theDouble" type="double"/>
+    </method>
+    <method name="GetDoubleValue">
+      <arg name="theDouble" type="double" direction="out"/>
+    </method>
+    <signal name="DoubleValueChanged">
+      <arg name="newDoubleValue" type="double"/>
+    </signal>
+
+  </interface>
+
+  <interface name="org.freedesktop.ASecondInterface">
+    <method name="RandomFrobate">
+      <arg type="boolean" direction="in"/>
+      <arg type="string" direction="out"/>
+      <arg type="string" direction="out"/>
+      <arg type="int64"/> <!-- direction defaults to "in" -->
+      <arg type="string" direction="out"/>
+      <arg type="string" direction="out"/>
+      <arg type="int32" direction="in"/>
+    </method>
+  </interface>
+
+</node>
+