Improve enum member parsing and introspection
authorJohan Dahlin <jdahlin@async.com.br>
Tue, 3 Jun 2008 23:32:04 +0000 (23:32 +0000)
committerJohan Dahlin <johan@src.gnome.org>
Tue, 3 Jun 2008 23:32:04 +0000 (23:32 +0000)
2008-06-03  Johan Dahlin  <jdahlin@async.com.br>

    * giscanner/Makefile.am:
    * giscanner/ast.py:
    * giscanner/girwriter.py:
    * giscanner/glibast.py:
    * giscanner/glibtransformer.py:
    * giscanner/transformer.py:
    * giscanner/utils.py:
    * tests/parser/Foo-expected.gir:
    Improve enum member parsing and introspection

svn path=/trunk/; revision=283

ChangeLog
giscanner/Makefile.am
giscanner/ast.py
giscanner/girwriter.py
giscanner/glibast.py
giscanner/glibtransformer.py
giscanner/transformer.py
giscanner/utils.py [new file with mode: 0644]
tests/parser/Foo-expected.gir

index c6b4190..b15378e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2008-06-03  Johan Dahlin  <jdahlin@async.com.br>
+
+       * giscanner/Makefile.am:
+       * giscanner/ast.py:
+       * giscanner/girwriter.py:
+       * giscanner/glibast.py:
+       * giscanner/glibtransformer.py:
+       * giscanner/transformer.py:
+       * giscanner/utils.py:
+       * tests/parser/Foo-expected.gir:
+       Improve enum member parsing and introspection
+
 2008-05-31  Johan Dahlin  <jdahlin@async.com.br>
 
        * giscanner/scannerparser.y:
index 931d490..0da9b59 100644 (file)
@@ -38,6 +38,7 @@ pkgpyexec_PYTHON =            \
        odict.py                \
        sourcescanner.py        \
        transformer.py          \
+       utils.py                \
        xmlwriter.py
 
 _giscanner_la_CFLAGS = \
index ff1fa84..be3962d 100644 (file)
@@ -135,9 +135,10 @@ class Enum(Node):
 
 
 class Member(Node):
-    def __init__(self, name, value):
+    def __init__(self, name, value, symbol):
         Node.__init__(self, name)
         self.value = value
+        self.symbol = symbol
 
     def __repr__(self):
         return 'Member(%r, %r)' % (self.name, self.value)
index 8d17fad..f26373b 100644 (file)
@@ -147,7 +147,8 @@ class GIRWriter(XMLWriter):
 
     def _write_member(self, member):
         attrs = [('name', member.name),
-                 ('value', str(member.value))]
+                 ('value', str(member.value)),
+                 ('c:identifier', member.symbol)]
         if isinstance(member, GLibEnumMember):
             attrs.append(('glib:nick', member.nick))
         self.write_tag('member', attrs)
index d50c503..50d51c3 100644 (file)
@@ -41,8 +41,8 @@ class GLibFlags(GLibEnum):
 
 
 class GLibEnumMember(Member):
-    def __init__(self, name, value, nick):
-        Member.__init__(self, name, value)
+    def __init__(self, name, value, symbol, nick):
+        Member.__init__(self, name, value, symbol)
         self.nick = nick
 
 
index 782ec16..5099ac2 100644 (file)
@@ -19,7 +19,6 @@
 #
 
 import ctypes
-import re
 import os
 
 from . import cgobject
@@ -28,30 +27,7 @@ from .ast import (Callback, Enum, Function, Member, Namespace, Parameter,
                   Property, Return, Sequence, Struct, Type)
 from .glibast import (GLibBoxed, GLibEnum, GLibEnumMember, GLibFlags,
                       GLibInterface, GLibObject, GLibSignal)
-
-
-# Copied from h2defs.py
-_upperstr_pat1 = re.compile(r'([^A-Z])([A-Z])')
-_upperstr_pat2 = re.compile(r'([A-Z][A-Z])([A-Z][0-9a-z])')
-_upperstr_pat3 = re.compile(r'^([A-Z])([A-Z])')
-
-def to_underscores(name):
-    """Converts a typename to the equivalent underscores name.
-    This is used to form the type conversion macros and enum/flag
-    name variables"""
-    name = _upperstr_pat1.sub(r'\1_\2', name)
-    name = _upperstr_pat2.sub(r'\1_\2', name)
-    name = _upperstr_pat3.sub(r'\1_\2', name, count=1)
-    return name
-
-_libtool_pat = re.compile("dlname='([A-z0-9\.\-\+]+)'\n")
-
-def resolve_libtool(libname):
-    data = open(libname).read()
-    filename = _libtool_pat.search(data).groups()[0]
-    libname = os.path.join(os.path.dirname(libname),
-                           '.libs', filename)
-    return libname
+from .utils import resolve_libtool, to_underscores
 
 
 class GLibTransformer(object):
@@ -169,6 +145,7 @@ class GLibTransformer(object):
         except AttributeError:
             print 'Warning: could not find symbol: %s' % symbol
             return False
+
         func.restype = cgobject.GType
         func.argtypes = []
         type_id = func()
@@ -275,8 +252,9 @@ class GLibTransformer(object):
 
         members = []
         for enum_value in type_class.get_values():
-            members.append(GLibEnumMember(enum_value.value_name,
+            members.append(GLibEnumMember(enum_value.value_nick,
                                           enum_value.value,
+                                          enum_value.value_name,
                                           enum_value.value_nick))
 
         klass = (GLibFlags if ftype_id == cgobject.TYPE_FLAGS else GLibEnum)
index f322635..3047d52 100644 (file)
@@ -27,6 +27,7 @@ from giscanner.sourcescanner import (
     CTYPE_FUNCTION, CTYPE_STRUCT, CSYMBOL_TYPE_FUNCTION,
     CSYMBOL_TYPE_TYPEDEF, CSYMBOL_TYPE_STRUCT, CSYMBOL_TYPE_ENUM,
     CSYMBOL_TYPE_UNION, CSYMBOL_TYPE_OBJECT, CSYMBOL_TYPE_MEMBER)
+from .utils import strip_common_prefix
 
 
 class Transformer(object):
@@ -125,14 +126,17 @@ class Transformer(object):
     def _create_enum(self, symbol):
         members = []
         for child in symbol.base_type.child_list:
-            members.append(Member(child.ident,
-                                  child.const_int))
+            name = strip_common_prefix(symbol.ident, child.ident).lower()
+            members.append(Member(name,
+                                  child.const_int,
+                                  child.ident))
 
-        name = self.strip_namespace_object(symbol.ident)
-        return Enum(name, symbol.ident, members)
+        enum_name = self.strip_namespace_object(symbol.ident)
+        return Enum(enum_name, symbol.ident, members)
 
     def _create_object(self, symbol):
-        return Member(symbol.ident, symbol.base_type.name)
+        return Member(symbol.ident, symbol.base_type.name,
+                      symbol.ident)
 
     def _create_function(self, symbol):
         directives = symbol.directives()
@@ -175,7 +179,8 @@ class Transformer(object):
             symbol.base_type.base_type.type == CTYPE_FUNCTION):
             node = self._create_callback(symbol)
         else:
-            node = Member(symbol.ident, self._create_source_type(symbol))
+            node = Member(symbol.ident, self._create_source_type(symbol),
+                          symbol.ident)
         return node
     
     def _create_typedef(self, symbol):
diff --git a/giscanner/utils.py b/giscanner/utils.py
new file mode 100644 (file)
index 0000000..488baad
--- /dev/null
@@ -0,0 +1,53 @@
+# -*- Mode: Python -*-
+# GObject-Introspection - a framework for introspecting GObject libraries
+# Copyright (C) 2008  Johan Dahlin
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+
+import re
+import os
+
+# Copied from h2defs.py
+_upperstr_pat1 = re.compile(r'([^A-Z])([A-Z])')
+_upperstr_pat2 = re.compile(r'([A-Z][A-Z])([A-Z][0-9a-z])')
+_upperstr_pat3 = re.compile(r'^([A-Z])([A-Z])')
+
+def to_underscores(name):
+    """Converts a typename to the equivalent underscores name.
+    This is used to form the type conversion macros and enum/flag
+    name variables"""
+    name = _upperstr_pat1.sub(r'\1_\2', name)
+    name = _upperstr_pat2.sub(r'\1_\2', name)
+    name = _upperstr_pat3.sub(r'\1_\2', name, count=1)
+    return name
+
+_libtool_pat = re.compile("dlname='([A-z0-9\.\-\+]+)'\n")
+
+def resolve_libtool(libname):
+    data = open(libname).read()
+    filename = _libtool_pat.search(data).groups()[0]
+    libname = os.path.join(os.path.dirname(libname),
+                           '.libs', filename)
+    return libname
+
+def strip_common_prefix(first, second):
+    first_underscore = to_underscores(first)
+    for i, c in enumerate(first_underscore.upper()):
+        if c != second[i]:
+            break
+    return second[i:]
+    
index e4561c8..5dfd41f 100644 (file)
                  c:type="FooEnumType"
                  glib:type-name="FooEnumType"
                  glib:get-type="foo_enum_type_get_type">
-      <member name="FOO_ENUM_ALPHA" value="0" glib:nick="alpha"/>
-      <member name="FOO_ENUM_BETA" value="1" glib:nick="beta"/>
-      <member name="FOO_ENUM_DELTA" value="2" glib:nick="delta"/>
+      <member name="alpha"
+                value="0"
+                c:identifier="FOO_ENUM_ALPHA"
+                glib:nick="alpha"/>
+      <member name="beta"
+                value="1"
+                c:identifier="FOO_ENUM_BETA"
+                glib:nick="beta"/>
+      <member name="delta"
+                value="2"
+                c:identifier="FOO_ENUM_DELTA"
+                glib:nick="delta"/>
     </enumeration>
     <function name="enum_type_method" c:identifier="foo_enum_type_method">
       <return-value>
               c:type="FooFlagsType"
               glib:type-name="FooFlagsType"
               glib:get-type="foo_flags_type_get_type">
-      <member name="FOO_FLAGS_FIRST" value="1" glib:nick="first"/>
-      <member name="FOO_FLAGS_SECOND" value="2" glib:nick="second"/>
-      <member name="FOO_FLAGS_THIRD" value="4" glib:nick="third"/>
+      <member name="first"
+                value="1"
+                c:identifier="FOO_FLAGS_FIRST"
+                glib:nick="first"/>
+      <member name="second"
+                value="2"
+                c:identifier="FOO_FLAGS_SECOND"
+                glib:nick="second"/>
+      <member name="third"
+                value="4"
+                c:identifier="FOO_FLAGS_THIRD"
+                glib:nick="third"/>
     </bitfield>
     <enumeration name="EnumNoType" c:type="FooEnumNoType">
-      <member name="FOO_ENUM_UN" value="1"/>
-      <member name="FOO_ENUM_DEUX" value="2"/>
-      <member name="FOO_ENUM_TROIS" value="3"/>
+      <member name="un" value="1" c:identifier="FOO_ENUM_UN"/>
+      <member name="deux" value="2" c:identifier="FOO_ENUM_DEUX"/>
+      <member name="trois" value="3" c:identifier="FOO_ENUM_TROIS"/>
     </enumeration>
     <glib:boxed c:type="Boxed"
                 glib:name="Boxed"