Blob Blame History Raw
From 3d69cfeab177e79b4ecfe1b4284a5bd840fd11e7 Mon Sep 17 00:00:00 2001
From: Colin Walters <walters@verbum.org>
Date: Thu, 2 Apr 2009 14:01:05 +0100
Subject: [PATCH] Fix hyphenated error codes correctly

The error code names generated my glib-mkenums separate the words by
hyphens which are invalid D-BUS error names. This patch converts them
back to wincaps, but we can't uppercase the first letter.

Based on an original patch from Neil Roberts <neil@linux.intel.com>
---
 dbus/dbus-gobject.c             |   21 ++++++++++++++++++---
 test/core/my-object.c           |   13 +++++++++++++
 test/core/my-object.h           |    4 +++-
 test/core/test-dbus-glib.c      |    7 +++++++
 test/core/test-service-glib.xml |    3 +++
 5 files changed, 44 insertions(+), 4 deletions(-)

diff --git a/dbus/dbus-gobject.c b/dbus/dbus-gobject.c
index f75a3b1..e294c35 100644
--- a/dbus/dbus-gobject.c
+++ b/dbus/dbus-gobject.c
@@ -46,13 +46,14 @@ static GHashTable *marshal_table = NULL;
 static GData *error_metadata = NULL;
 
 static char*
-uscore_to_wincaps (const char *uscore)
+uscore_to_wincaps_full (const char *uscore,
+                        gboolean    uppercase_first)
 {
   const char *p;
   GString *str;
   gboolean last_was_uscore;
 
-  last_was_uscore = TRUE;
+  last_was_uscore = uppercase_first;
   
   str = g_string_new (NULL);
   p = uscore;
@@ -78,6 +79,12 @@ uscore_to_wincaps (const char *uscore)
   return g_string_free (str, FALSE);
 }
 
+static char *
+uscore_to_wincaps (const char *uscore)
+{
+  return uscore_to_wincaps_full (uscore, TRUE);
+}
+
 static const char *
 string_table_next (const char *table)
 {
@@ -1065,6 +1072,7 @@ gerror_domaincode_to_dbus_error_name (const DBusGObjectInfo *object_info,
 	{
 	  GEnumValue *value;
 	  GEnumClass *klass;
+          const char *p;
 
 	  klass = g_type_class_ref (info->code_enum);
 	  value = g_enum_get_value (klass, code);
@@ -1093,9 +1101,16 @@ gerror_domaincode_to_dbus_error_name (const DBusGObjectInfo *object_info,
     }
   else
     {
+      gchar *code_str_wincaps;
       dbus_error_name = g_string_new (domain_str);
       g_string_append_c (dbus_error_name, '.');
-      g_string_append (dbus_error_name, code_str);
+      /* We can't uppercase here for backwards compatibility
+       * reasons; if someone had a lowercase enumeration value,
+       * previously we'd just send it across unaltered.
+       */
+      code_str_wincaps = uscore_to_wincaps_full (code_str, FALSE);
+      g_string_append (dbus_error_name, code_str_wincaps);
+      g_free (code_str_wincaps);
     }
 
   return g_string_free (dbus_error_name, FALSE);
diff --git a/test/core/my-object.c b/test/core/my-object.c
index 6059724..886943e 100644
--- a/test/core/my-object.c
+++ b/test/core/my-object.c
@@ -169,6 +169,7 @@ my_object_error_get_type (void)
 
 			ENUM_ENTRY (MY_OBJECT_ERROR_FOO, "Foo"),
 			ENUM_ENTRY (MY_OBJECT_ERROR_BAR, "Bar"),
+			ENUM_ENTRY (MY_OBJECT_ERROR_MULTI_WORD, "Multi-word"),
 			{ 0, 0, 0 }
 		};
 
@@ -235,6 +236,18 @@ my_object_throw_not_supported (MyObject *obj, GError **error)
 }
 
 gboolean
+my_object_throw_error_multi_word (MyObject *obj, GError **error)
+{
+  g_set_error (error,
+	       MY_OBJECT_ERROR,
+	       MY_OBJECT_ERROR_MULTI_WORD,
+	       "%s",
+	       "this method's error has a hyphen");    
+  return FALSE;
+}
+
+
+gboolean
 my_object_uppercase (MyObject *obj, const char *str, char **ret, GError **error)
 {
   *ret = g_ascii_strup (str, -1);
diff --git a/test/core/my-object.h b/test/core/my-object.h
index 7fe449d..1d3c869 100644
--- a/test/core/my-object.h
+++ b/test/core/my-object.h
@@ -31,7 +31,8 @@ struct MyObjectClass
 typedef enum
 {
   MY_OBJECT_ERROR_FOO,
-  MY_OBJECT_ERROR_BAR
+  MY_OBJECT_ERROR_BAR,
+  MY_OBJECT_ERROR_MULTI_WORD
 } MyObjectError;
 
 #define MY_OBJECT_ERROR (my_object_error_quark ())
@@ -50,6 +51,7 @@ gint32   my_object_increment_retval_error (MyObject *obj, gint32 x, GError **err
 
 gboolean my_object_throw_error (MyObject *obj, GError **error);
 gboolean my_object_throw_not_supported (MyObject *obj, GError **error);
+gboolean my_object_throw_error_multi_word (MyObject *obj, GError **error);
 
 gboolean my_object_uppercase (MyObject *obj, const char *str, char **ret, GError **error);
 
diff --git a/test/core/test-dbus-glib.c b/test/core/test-dbus-glib.c
index 0e3c12f..6de156c 100644
--- a/test/core/test-dbus-glib.c
+++ b/test/core/test-dbus-glib.c
@@ -870,6 +870,13 @@ main (int argc, char **argv)
 
   g_print ("(wrapped) ThrowError failed (as expected) returned error: %s\n", error->message);
   g_clear_error (&error);
+  
+  g_print ("Calling (wrapped) throw_error_multi_word\n");
+  if (org_freedesktop_DBus_GLib_Tests_MyObject_throw_error_multi_word (proxy, &error) != FALSE)
+    lose ("(wrapped) ThrowErrorMultiWord call unexpectedly succeeded!");
+
+  g_print ("(wrapped) ThrowErrorMultiWord failed (as expected) returned error: %s\n", error->message);
+  g_clear_error (&error);
 
   if (org_freedesktop_DBus_GLib_Tests_MyObject_async_throw_error (proxy, &error) != FALSE)
     lose ("(wrapped) AsyncThrowError call unexpectedly succeeded!");
diff --git a/test/core/test-service-glib.xml b/test/core/test-service-glib.xml
index 86152c7..5bc94a6 100644
--- a/test/core/test-service-glib.xml
+++ b/test/core/test-service-glib.xml
@@ -31,6 +31,9 @@
 
     <method name="ThrowNotSupported">
     </method>
+    
+    <method name="ThrowErrorMultiWord">
+    </method>
 
     <method name="Uppercase">
       <arg type="s" direction="in" />
-- 
1.6.6.1