summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorC. Scott Ananian <cscott@litl.com>2009-05-19 20:17:08 -0400
committerColin Walters <walters@verbum.org>2009-05-20 12:13:15 -0400
commitaa94335b84d17512281ab3ed4cd20fb1fad9dcd8 (patch)
tree026c1f2e46d42743e211b4374ddfe12d529e400d
parent50dd263dbe16ecf8e81c3f674d23cb086f79ca7e (diff)
downloadgobject-introspection-aa94335b84d17512281ab3ed4cd20fb1fad9dcd8.tar.gz
Better handle classes with non-standard to_underscore names.
Previously we tried to guess what the "underscore version" of a class name would be, but for classes like NMSetting8021x we'd guess "nm_setting8021x" instead of "nm_setting_802_1x". All such guesses are subject to error: instead let's try to use the prefix of the _get_type() method instead, and only guess if that doesn't work. We do this for both class names and when detecting methods. An additional type with a "non-standard" underscored version (TestWi8021x) added to the everything.[ch] test suite to test proper conversion. GdkWindow and GObject have unusual get_type methods; add special quirks to handle these (at least until the methods are renamed upstream). (Slightly modified for PEP8 compliance by Colin Walters) Signed-off-by: Colin Walters <walters@verbum.org>
-rw-r--r--giscanner/glibtransformer.py29
-rw-r--r--tests/everything/everything.c106
-rw-r--r--tests/everything/everything.h24
3 files changed, 157 insertions, 2 deletions
diff --git a/giscanner/glibtransformer.py b/giscanner/glibtransformer.py
index 0f5b0c92..6a0dee06 100644
--- a/giscanner/glibtransformer.py
+++ b/giscanner/glibtransformer.py
@@ -60,6 +60,18 @@ SYMBOL_BLACKLIST = [
SYMBOL_BLACKLIST_RE = [re.compile(x) for x in \
[r'\w+_marshal_[A-Z]+__', ]]
+GET_TYPE_OVERRIDES = {
+ # this is a special case, from glibtransforer.py:create_gobject
+ 'intern': 'g_object_get_type',
+ # this is presumably a typo, should be fixed upstream
+ 'g_gstring_get_type': 'g_string_get_type',
+ # this is historical cruft: there's a deprecated
+ # #define gdk_window_get_type gdk_window_get_window_type
+ # upstream; this method can be renamed properly upstream once
+ # that deprecated alias is removed (in some future release)
+ 'gdk_window_object_get_type': 'gdk_window_get_type',
+}
+
class IntrospectionBinary(object):
@@ -213,6 +225,10 @@ class GLibTransformer(object):
def _register_internal_type(self, type_name, node):
self._names.type_names[type_name] = (None, node)
uscored = to_underscores(type_name).lower()
+ # prefer the prefix of the get_type method, if there is one
+ if hasattr(node, 'get_type'):
+ uscored = GET_TYPE_OVERRIDES.get(node.get_type, node.get_type)
+ uscored = uscored[:-len('_get_type')]
self._uscore_type_names[uscored] = node
# Besides the straight underscore conversion, we also try
# removing the underscores from the namespace as a possible C
@@ -220,7 +236,9 @@ class GLibTransformer(object):
suffix = self._transformer.remove_prefix(type_name)
prefix = type_name[:-len(suffix)]
no_uscore_prefixed = (prefix + '_' + to_underscores(suffix)).lower()
- self._uscore_type_names[no_uscore_prefixed] = node
+ # since this is a guess, don't overwrite any 'real' prefix
+ if no_uscore_prefixed not in self._uscore_type_names:
+ self._uscore_type_names[no_uscore_prefixed] = node
def _resolve_quarks(self):
for node in self._error_quark_functions:
@@ -401,7 +419,7 @@ class GLibTransformer(object):
target_klass = None
prefix_components = None
methname = None
- for i in xrange(1, len(components)-1):
+ for i in xrange(1, len(components)):
prefix_components = '_'.join(components[0:-i])
methname = '_'.join(components[-i:])
target_klass = self._uscore_type_names.get(prefix_components)
@@ -446,6 +464,13 @@ class GLibTransformer(object):
argtype = target_arg.type.ctype.replace('*', '')
name = self._transformer.remove_prefix(argtype)
name_uscore = to_underscores_noprefix(name).lower()
+ # prefer the prefix of the _get_type method, if there is one
+ if argtype in self._names.type_names:
+ node = self._names.type_names[argtype][1]
+ if hasattr(node, 'get_type'):
+ name_uscore = GET_TYPE_OVERRIDES.get(node.get_type,
+ node.get_type)
+ name_uscore = name_uscore[:-len('_get_type')]
name_offset = func.symbol.find(name_uscore)
if name_offset < 0:
return None
diff --git a/tests/everything/everything.c b/tests/everything/everything.c
index 7c9e4e5d..52dec4ba 100644
--- a/tests/everything/everything.c
+++ b/tests/everything/everything.c
@@ -1345,3 +1345,109 @@ test_interface_get_type(void)
return type;
}
+/* gobject with non-standard prefix */
+G_DEFINE_TYPE(TestWi8021x, test_wi_802_1x, G_TYPE_OBJECT);
+
+enum
+{
+ PROP_TEST_WI_802_1X_TESTBOOL = 1
+};
+
+static void
+test_wi_802_1x_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ TestWi8021x *self = TEST_WI_802_1X (object);
+
+ switch (property_id)
+ {
+ case PROP_TEST_WI_802_1X_TESTBOOL:
+ test_wi_802_1x_set_testbool (self, g_value_get_boolean (value));
+ break;
+
+ default:
+ /* We don't have any other property... */
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+test_wi_802_1x_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ TestWi8021x *self = TEST_WI_802_1X (object);
+
+ switch (property_id)
+ {
+ case PROP_TEST_WI_802_1X_TESTBOOL:
+ g_value_set_boolean (value, test_wi_802_1x_get_testbool (self));
+ break;
+
+ default:
+ /* We don't have any other property... */
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+test_wi_802_1x_dispose (GObject *gobject)
+{
+ /* Chain up to the parent class */
+ G_OBJECT_CLASS (test_wi_802_1x_parent_class)->dispose (gobject);
+}
+
+static void
+test_wi_802_1x_class_init (TestWi8021xClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GParamSpec *pspec;
+
+ gobject_class->set_property = test_wi_802_1x_set_property;
+ gobject_class->get_property = test_wi_802_1x_get_property;
+ gobject_class->dispose = test_wi_802_1x_dispose;
+
+ pspec = g_param_spec_boolean ("testbool",
+ "Nick for testbool",
+ "Blurb for testbool",
+ TRUE,
+ G_PARAM_READWRITE);
+ g_object_class_install_property (gobject_class,
+ PROP_TEST_WI_802_1X_TESTBOOL,
+ pspec);
+}
+
+static void
+test_wi_802_1x_init (TestWi8021x *obj)
+{
+ obj->testbool = TRUE;
+}
+
+TestWi8021x *
+test_wi_802_1x_new (void)
+{
+ return g_object_new (TEST_TYPE_WI_802_1X, NULL);
+}
+
+void
+test_wi_802_1x_set_testbool (TestWi8021x *obj, gboolean val)
+{
+ obj->testbool = val;
+}
+
+gboolean
+test_wi_802_1x_get_testbool (TestWi8021x *obj)
+{
+ return obj->testbool;
+}
+
+int
+test_wi_802_1x_static_method (int x)
+{
+ return 2*x;
+}
diff --git a/tests/everything/everything.h b/tests/everything/everything.h
index 9f4c7d7a..2a7e3cdd 100644
--- a/tests/everything/everything.h
+++ b/tests/everything/everything.h
@@ -258,4 +258,28 @@ struct _TestInterfaceIface {
GType test_interface_get_type (void) G_GNUC_CONST;
+/* gobject with non-standard prefix */
+#define TEST_TYPE_WI_802_1X (test_wi_802_1x_get_type ())
+#define TEST_WI_802_1X(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), TEST_TYPE_WI_802_1X, TestWi8021x))
+#define TEST_IS_WI_802_1X(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), TEST_TYPE_WI_802_1X))
+#define TEST_WI_802_1X_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TEST_TYPE_WI_802_1X, TestWi8021xClass))
+
+typedef struct
+{
+ GObject parent_instance;
+
+ gboolean testbool;
+} TestWi8021x;
+
+typedef struct
+{
+ GObjectClass parent_class;
+} TestWi8021xClass;
+
+GType test_wi_802_1x_get_type (void);
+TestWi8021x* test_wi_802_1x_new (void);
+gboolean test_wi_802_1x_get_testbool (TestWi8021x *obj);
+void test_wi_802_1x_set_testbool (TestWi8021x *obj, gboolean v);
+int test_wi_802_1x_static_method (int x);
+
#endif /* __GITESTTYPES_H__ */