From e8b29ce05be743bb695959fc7f5fa6ccbc69fbe9 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Tue, 3 Jun 2008 23:32:04 +0000 Subject: Improve enum member parsing and introspection 2008-06-03 Johan Dahlin * 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 | 12 ++++++++++ giscanner/Makefile.am | 1 + giscanner/ast.py | 3 ++- giscanner/girwriter.py | 3 ++- giscanner/glibast.py | 4 ++-- giscanner/glibtransformer.py | 30 ++++-------------------- giscanner/transformer.py | 17 +++++++++----- giscanner/utils.py | 53 +++++++++++++++++++++++++++++++++++++++++++ tests/parser/Foo-expected.gir | 36 +++++++++++++++++++++-------- 9 files changed, 114 insertions(+), 45 deletions(-) create mode 100644 giscanner/utils.py diff --git a/ChangeLog b/ChangeLog index c6b41900..b15378e4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2008-06-03 Johan Dahlin + + * 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 * giscanner/scannerparser.y: diff --git a/giscanner/Makefile.am b/giscanner/Makefile.am index 931d4907..0da9b597 100644 --- a/giscanner/Makefile.am +++ b/giscanner/Makefile.am @@ -38,6 +38,7 @@ pkgpyexec_PYTHON = \ odict.py \ sourcescanner.py \ transformer.py \ + utils.py \ xmlwriter.py _giscanner_la_CFLAGS = \ diff --git a/giscanner/ast.py b/giscanner/ast.py index ff1fa84d..be3962d8 100644 --- a/giscanner/ast.py +++ b/giscanner/ast.py @@ -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) diff --git a/giscanner/girwriter.py b/giscanner/girwriter.py index 8d17fade..f26373b3 100644 --- a/giscanner/girwriter.py +++ b/giscanner/girwriter.py @@ -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) diff --git a/giscanner/glibast.py b/giscanner/glibast.py index d50c503c..50d51c34 100644 --- a/giscanner/glibast.py +++ b/giscanner/glibast.py @@ -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 diff --git a/giscanner/glibtransformer.py b/giscanner/glibtransformer.py index 782ec163..5099ac2e 100644 --- a/giscanner/glibtransformer.py +++ b/giscanner/glibtransformer.py @@ -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) diff --git a/giscanner/transformer.py b/giscanner/transformer.py index f322635a..3047d528 100644 --- a/giscanner/transformer.py +++ b/giscanner/transformer.py @@ -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 index 00000000..488baadd --- /dev/null +++ b/giscanner/utils.py @@ -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:] + diff --git a/tests/parser/Foo-expected.gir b/tests/parser/Foo-expected.gir index e4561c83..5dfd41f2 100644 --- a/tests/parser/Foo-expected.gir +++ b/tests/parser/Foo-expected.gir @@ -216,9 +216,18 @@ c:type="FooEnumType" glib:type-name="FooEnumType" glib:get-type="foo_enum_type_get_type"> - - - + + + @@ -234,14 +243,23 @@ c:type="FooFlagsType" glib:type-name="FooFlagsType" glib:get-type="foo_flags_type_get_type"> - - - + + + - - - + + +