Bug 575613 - Enum stripping with common prefix, also use "_" consistently
authorColin Walters <walters@verbum.org>
Mon, 16 Mar 2009 22:25:19 +0000 (18:25 -0400)
committerColin Walters <walters@verbum.org>
Tue, 17 Mar 2009 15:10:04 +0000 (11:10 -0400)
Some enums have members which have a common prefix which doesn't
match that of the enum name, but it also longer than the global
namespace prefix.  Instead, try stripping the common prefix first,
and only if that fails fall back to the global strip.

Also, for glib-registered enums we were using the nick, which
typically has "-" as a separator.  Replace that with "_" for
consistency between unregistered enums and registered.

utils.py:strip_common_prefix is now unused, delete.

giscanner/glibtransformer.py
giscanner/transformer.py
giscanner/utils.py
tests/scanner/foo-1.0-expected.gir
tests/scanner/foo-1.0-expected.tgir
tests/scanner/foo.h

index 61d4cef..0f5b0c9 100644 (file)
@@ -640,7 +640,10 @@ class GLibTransformer(object):
     def _introspect_enum(self, node):
         members = []
         for member in node.findall('member'):
-            members.append(GLibEnumMember(member.attrib['nick'],
+            # Keep the name closer to what we'd take from C by default;
+            # see http://bugzilla.gnome.org/show_bug.cgi?id=575613
+            name = member.attrib['nick'].replace('-', '_')
+            members.append(GLibEnumMember(name,
                                           member.attrib['value'],
                                           member.attrib['name'],
                                           member.attrib['nick']))
index 9aebbd8..2746b6e 100644 (file)
@@ -37,7 +37,7 @@ from .sourcescanner import (
     CSYMBOL_TYPE_ENUM, CSYMBOL_TYPE_UNION, CSYMBOL_TYPE_OBJECT,
     CSYMBOL_TYPE_MEMBER, CSYMBOL_TYPE_ELLIPSIS, CSYMBOL_TYPE_CONST,
     TYPE_QUALIFIER_CONST)
-from .utils import strip_common_prefix, to_underscores
+from .utils import to_underscores
 
 _xdg_data_dirs = [x for x in os.environ.get('XDG_DATA_DIRS', '').split(':') \
                       + [DATADIR, '/usr/share'] if x]
@@ -208,11 +208,46 @@ class Transformer(object):
             raise NotImplementedError(
                 'Transformer: unhandled symbol: %r' % (symbol, ))
 
+    def _enum_common_prefix(self, symbol):
+        def common_prefix(a, b):
+            alen = len(a)
+            blen = len(b)
+            l = min(alen, blen)
+            for i in xrange(l):
+                if a[i] != b[i]:
+                    return a[:i]
+            if alen > blen:
+                return b
+            return a
+        # Nothing less than 2 has a common prefix
+        if len(list(symbol.base_type.child_list)) < 2:
+            return None
+        prefix = None
+        for child in symbol.base_type.child_list:
+            if prefix is None:
+                prefix = child.ident
+            else:
+                prefix = common_prefix(prefix, child.ident)
+                if prefix == '':
+                    return None
+        return prefix
+
     def _create_enum(self, symbol):
+        prefix = self._enum_common_prefix(symbol)
+        if prefix:
+            prefixlen = len(prefix)
+        else:
+            prefixlen = 0
         members = []
         for child in symbol.base_type.child_list:
-            name = strip_common_prefix(symbol.ident, child.ident).lower()
-            members.append(Member(name,
+            if prefixlen > 0:
+                name = child.ident[prefixlen:]
+            else:
+                # Ok, the enum members don't have a consistent prefix
+                # among them, so let's just remove the global namespace
+                # prefix.
+                name = self.remove_prefix(child.ident)
+            members.append(Member(name.lower(),
                                   child.const_int,
                                   child.ident))
 
index 021ffea..d2752e7 100644 (file)
@@ -57,14 +57,3 @@ def extract_libtool(libname):
     #        and pre-2.2. Johan 2008-10-21
     libname = libname.replace('.libs/.libs', '.libs')
     return libname
-
-
-def strip_common_prefix(first, second):
-    max_index = second.rfind('_')
-    second_len = len(second)
-    second = second.replace('_', '')
-    max_index -= second_len - len(second) - 1
-    for i, c in enumerate(first.upper()):
-        if i >= len(second) or c != second[i] or i == max_index:
-            return second[i:]
-    return second[i + 1:]
index 59efffd..b28d861 100644 (file)
@@ -15,6 +15,11 @@ and/or use gtk-doc annotations.  -->
     <alias name="List" target="GLib.SList" c:type="FooList"/>
     <alias name="ObjectCookie" target="any" c:type="FooObjectCookie"/>
     <alias name="XEvent" target="none" c:type="FooXEvent"/>
+    <enumeration name="ASingle" c:type="FooASingle">
+      <member name="some_single_enum"
+              value="0"
+              c:identifier="FOO_SOME_SINGLE_ENUM"/>
+    </enumeration>
     <record name="BRect"
             c:type="FooBRect"
             glib:type-name="FooBRect"
@@ -536,6 +541,21 @@ uses a C sugar return type.">
     <constant name="SUCCESS_INT" value="4408">
       <type name="int"/>
     </constant>
+    <enumeration name="StackLayer" c:type="FooStackLayer">
+      <member name="desktop" value="0" c:identifier="FOO_LAYER_DESKTOP"/>
+      <member name="bottom" value="1" c:identifier="FOO_LAYER_BOTTOM"/>
+      <member name="normal" value="2" c:identifier="FOO_LAYER_NORMAL"/>
+      <member name="top" value="4" c:identifier="FOO_LAYER_TOP"/>
+      <member name="dock" value="4" c:identifier="FOO_LAYER_DOCK"/>
+      <member name="fullscreen" value="5" c:identifier="FOO_LAYER_FULLSCREEN"/>
+      <member name="focused_window"
+              value="6"
+              c:identifier="FOO_LAYER_FOCUSED_WINDOW"/>
+      <member name="override_redirect"
+              value="7"
+              c:identifier="FOO_LAYER_OVERRIDE_REDIRECT"/>
+      <member name="last" value="8" c:identifier="FOO_LAYER_LAST"/>
+    </enumeration>
     <record name="Struct" c:type="FooStruct">
       <field name="priv" writable="1">
         <type name="StructPrivate" c:type="FooStructPrivate*"/>
index e834876..bd94ed3 100644 (file)
@@ -7,6 +7,9 @@
   <include name="GObject" version="2.0"/>
   <include name="GLib" version="2.0"/>
   <namespace name="foo" version="1.0" shared-library="foo">
+    <enumeration name="ASingle">
+      <member name="some_single_enum" value="0"/>
+    </enumeration>
     <record name="BRect" glib:type-name="FooBRect" glib:get-type="foo_brect_get_type">
       <field name="x" writable="1">
         <type name="double"/>
     <constant name="SUCCESS_INT" value="4408">
       <type name="int"/>
     </constant>
+    <enumeration name="StackLayer">
+      <member name="desktop" value="0"/>
+      <member name="bottom" value="1"/>
+      <member name="normal" value="2"/>
+      <member name="top" value="4"/>
+      <member name="dock" value="4"/>
+      <member name="fullscreen" value="5"/>
+      <member name="focused_window" value="6"/>
+      <member name="override_redirect" value="7"/>
+      <member name="last" value="8"/>
+    </enumeration>
     <record name="Struct">
       <field name="priv" writable="1">
         <type name="StructPrivate"/>
index e9d00dd..8097cfc 100644 (file)
@@ -341,6 +341,24 @@ GType foo_error_get_type (void);
 
 GQuark foo_error_quark (void);
 
+typedef enum
+{
+  FOO_LAYER_DESKTOP        = 0,
+  FOO_LAYER_BOTTOM        = 1,
+  FOO_LAYER_NORMAL        = 2,
+  FOO_LAYER_TOP        = 4, /* Same as DOCK; see EWMH and bug 330717 */
+  FOO_LAYER_DOCK        = 4,
+  FOO_LAYER_FULLSCREEN        = 5,
+  FOO_LAYER_FOCUSED_WINDOW    = 6,
+  FOO_LAYER_OVERRIDE_REDIRECT = 7,
+  FOO_LAYER_LAST        = 8
+} FooStackLayer;
+
+typedef enum
+{
+  FOO_SOME_SINGLE_ENUM
+} FooASingle;
+
 /* Should be skipped */
 void foo_some_variant (guint x, va_list args);
 void foo_some_variant_ptr (guint x, va_list *args);