diff options
author | Johan Dahlin <jdahlin@async.com.br> | 2009-01-12 23:24:01 +0000 |
---|---|---|
committer | Johan Dahlin <johan@src.gnome.org> | 2009-01-12 23:24:01 +0000 |
commit | 9256e916164ec557ed66f92a0d6d95bb286cdf8b (patch) | |
tree | e481541d55ca9eafb63684f2ee41d48096b8eac5 /giscanner | |
parent | e81c4681cc88a00fcd841c5a68d860d3714b55d7 (diff) | |
download | gobject-introspection-9256e916164ec557ed66f92a0d6d95bb286cdf8b.tar.gz |
Bug 563591 – Flags not recognized when there is no introspection data
2009-01-12 Johan Dahlin <jdahlin@async.com.br>
Bug 563591 – Flags not recognized when there is no introspection data
* giscanner/ast.py:
* giscanner/girwriter.py:
* giscanner/giscannermodule.c (type_get_is_bitfield):
* giscanner/glibast.py:
* giscanner/glibtransformer.py:
* giscanner/scannerparser.y:
* giscanner/sourcescanner.c (gi_source_type_copy):
* giscanner/sourcescanner.h:
* giscanner/sourcescanner.py:
* giscanner/transformer.py:
* tests/scanner/foo-1.0-expected.gir:
* tests/scanner/foo-1.0-expected.tgir:
* tests/scanner/foo.h:
Large parts of this patch was done by Jürg Billeter.
svn path=/trunk/; revision=1025
Diffstat (limited to 'giscanner')
-rw-r--r-- | giscanner/ast.py | 11 | ||||
-rw-r--r-- | giscanner/girwriter.py | 29 | ||||
-rw-r--r-- | giscanner/giscannermodule.c | 8 | ||||
-rw-r--r-- | giscanner/glibast.py | 23 | ||||
-rw-r--r-- | giscanner/glibtransformer.py | 9 | ||||
-rw-r--r-- | giscanner/scannerparser.y | 20 | ||||
-rw-r--r-- | giscanner/sourcescanner.c | 1 | ||||
-rw-r--r-- | giscanner/sourcescanner.h | 1 | ||||
-rw-r--r-- | giscanner/sourcescanner.py | 6 | ||||
-rw-r--r-- | giscanner/transformer.py | 12 |
10 files changed, 95 insertions, 25 deletions
diff --git a/giscanner/ast.py b/giscanner/ast.py index c5dc436c..b141691d 100644 --- a/giscanner/ast.py +++ b/giscanner/ast.py @@ -328,6 +328,17 @@ class Enum(Node): return 'Enum(%r, %r)' % (self.name, self.members) +class Bitfield(Node): + + def __init__(self, name, symbol, members): + Node.__init__(self, name) + self.symbol = symbol + self.members = members + + def __repr__(self): + return 'Bitfield(%r, %r)' % (self.name, self.members) + + class Member(Node): def __init__(self, name, value, symbol): diff --git a/giscanner/girwriter.py b/giscanner/girwriter.py index f82a73e5..e72b0289 100644 --- a/giscanner/girwriter.py +++ b/giscanner/girwriter.py @@ -23,8 +23,9 @@ from __future__ import with_statement import os from ctypes.util import find_library -from .ast import (Callback, Class, Constant, Enum, Function, Interface, Member, - Array, Struct, Alias, Union, List, Map, Varargs) +from .ast import (Alias, Array, Bitfield, Callback, Class, Constant, Enum, + Function, Interface, List, Map, Member, Struct, Union, + Varargs) from .glibast import (GLibBoxed, GLibEnum, GLibEnumMember, GLibFlags, GLibObject, GLibInterface) from .xmlwriter import XMLWriter @@ -72,6 +73,8 @@ class GIRWriter(XMLWriter): self._write_function(node) elif isinstance(node, Enum): self._write_enum(node) + elif isinstance(node, Bitfield): + self._write_bitfield(node) elif isinstance(node, (Class, Interface)): self._write_class(node) elif isinstance(node, Callback): @@ -221,20 +224,30 @@ class GIRWriter(XMLWriter): attrs = [('name', enum.name)] self._append_version(enum, attrs) self._append_deprecated(enum, attrs) - if isinstance(enum, GLibFlags): - tag_name = 'bitfield' - else: - tag_name = 'enumeration' - if isinstance(enum, GLibEnum) or isinstance(enum, GLibFlags): + if isinstance(enum, GLibEnum): attrs.extend([('glib:type-name', enum.type_name), ('glib:get-type', enum.get_type), ('c:type', enum.ctype)]) else: attrs.append(('c:type', enum.symbol)) - with self.tagcontext(tag_name, attrs): + with self.tagcontext('enumeration', attrs): for member in enum.members: self._write_member(member) + def _write_bitfield(self, bitfield): + attrs = [('name', bitfield.name)] + self._append_version(bitfield, attrs) + self._append_deprecated(bitfield, attrs) + if isinstance(bitfield, GLibFlags): + attrs.extend([('glib:type-name', bitfield.type_name), + ('glib:get-type', bitfield.get_type), + ('c:type', bitfield.ctype)]) + else: + attrs.append(('c:type', bitfield.symbol)) + with self.tagcontext('bitfield', attrs): + for member in bitfield.members: + self._write_member(member) + def _write_member(self, member): attrs = [('name', member.name), ('value', str(member.value)), diff --git a/giscanner/giscannermodule.c b/giscanner/giscannermodule.c index afa4c29c..7d75f55b 100644 --- a/giscanner/giscannermodule.c +++ b/giscanner/giscannermodule.c @@ -256,6 +256,13 @@ type_get_child_list (PyGISourceType *self, return list; } +static PyObject * +type_get_is_bitfield (PyGISourceType *self, + void *context) +{ + return PyInt_FromLong (self->type->is_bitfield); +} + static const PyGetSetDef _PyGISourceType_getsets[] = { { "type", (getter)type_get_type, NULL, NULL}, { "storage_class_specifier", (getter)type_get_storage_class_specifier, NULL, NULL}, @@ -264,6 +271,7 @@ static const PyGetSetDef _PyGISourceType_getsets[] = { { "name", (getter)type_get_name, NULL, NULL}, { "base_type", (getter)type_get_base_type, NULL, NULL}, { "child_list", (getter)type_get_child_list, NULL, NULL}, + { "is_bitfield", (getter)type_get_is_bitfield, NULL, NULL}, { 0 } }; diff --git a/giscanner/glibast.py b/giscanner/glibast.py index 637dc633..a804f620 100644 --- a/giscanner/glibast.py +++ b/giscanner/glibast.py @@ -18,7 +18,8 @@ # Boston, MA 02111-1307, USA. # -from .ast import Class, Enum, Interface, Member, Node, Property, Struct, Union +from .ast import (Bitfield, Class, Enum, Interface, Member, Node, + Property, Struct, Union) from .ast import ( type_names, default_array_types, TYPE_STRING, TYPE_INT8, TYPE_UINT8, TYPE_INT16, TYPE_UINT16, @@ -71,15 +72,21 @@ class GLibEnum(Enum): self.get_type = get_type def __repr__(self): - return '%s(%r, %r, %r)' % ( - self.__class__.__name__, - self.name, - self.members, - self.get_type) + return 'GlibEnum(%r, %r, %r)' % (self.name, self.members, + self.get_type) -class GLibFlags(GLibEnum): - pass +class GLibFlags(Bitfield): + + def __init__(self, name, type_name, members, get_type): + Bitfield.__init__(self, name, type_name, members) + self.ctype = type_name + self.type_name = type_name + self.get_type = get_type + + def __repr__(self): + return 'GlibFlags(%r, %r, %r)' % (self.name, self.members, + self.get_type) class GLibEnumMember(Member): diff --git a/giscanner/glibtransformer.py b/giscanner/glibtransformer.py index ee39862e..d46c3c0f 100644 --- a/giscanner/glibtransformer.py +++ b/giscanner/glibtransformer.py @@ -25,8 +25,8 @@ import tempfile import shutil import subprocess -from .ast import (Callback, Constant, Enum, Function, Member, Namespace, - Parameter, Property, Return, Struct, Type, Alias, +from .ast import (Alias, Bitfield, Callback, Constant, Enum, Function, Member, + Namespace, Parameter, Property, Return, Struct, Type, Union, Field, type_name_from_ctype, default_array_types, TYPE_UINT8, PARAM_TRANSFER_FULL) from .transformer import Names @@ -259,6 +259,8 @@ class GLibTransformer(object): def _parse_node(self, node): if isinstance(node, Enum): self._parse_enum(node) + elif isinstance(node, Bitfield): + self._parse_bitfield(node) elif isinstance(node, Function): self._parse_function(node) elif isinstance(node, Struct): @@ -283,6 +285,9 @@ class GLibTransformer(object): def _parse_enum(self, enum): self._add_attribute(enum) + def _parse_bitfield(self, enum): + self._add_attribute(enum) + def _parse_constant(self, constant): self._add_attribute(constant) diff --git a/giscanner/scannerparser.y b/giscanner/scannerparser.y index 64cf11b3..dffe90e2 100644 --- a/giscanner/scannerparser.y +++ b/giscanner/scannerparser.y @@ -46,6 +46,7 @@ static void yyerror (GISourceScanner *scanner, const char *str); extern void ctype_free (GISourceType * type); static int last_enum_value = -1; +static gboolean is_bitfield; static GHashTable *const_table = NULL; %} @@ -381,6 +382,12 @@ shift_expression $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST); $$->const_int_set = TRUE; $$->const_int = $1->const_int << $3->const_int; + + /* assume this is a bitfield/flags declaration + * if a left shift operator is sued in an enum value + * This mimics the glib-mkenum behavior. + */ + is_bitfield = TRUE; } | shift_expression SR additive_expression { @@ -818,24 +825,28 @@ enum_specifier { $$ = gi_source_enum_new ($2); $$->child_list = $4; + $$->is_bitfield = is_bitfield; last_enum_value = -1; } | ENUM '{' enumerator_list '}' { $$ = gi_source_enum_new (NULL); $$->child_list = $3; + $$->is_bitfield = is_bitfield; last_enum_value = -1; } | ENUM identifier_or_typedef_name '{' enumerator_list ',' '}' { $$ = gi_source_enum_new ($2); $$->child_list = $4; + $$->is_bitfield = is_bitfield; last_enum_value = -1; } | ENUM '{' enumerator_list ',' '}' { $$ = gi_source_enum_new (NULL); $$->child_list = $3; + $$->is_bitfield = is_bitfield; last_enum_value = -1; } | ENUM identifier_or_typedef_name @@ -845,9 +856,14 @@ enum_specifier ; enumerator_list - : enumerator + : { - $$ = g_list_append (NULL, $1); + /* reset flag before the first enum value */ + is_bitfield = FALSE; + } + enumerator + { + $$ = g_list_append (NULL, $2); } | enumerator_list ',' enumerator { diff --git a/giscanner/sourcescanner.c b/giscanner/sourcescanner.c index cf412362..1a2508d9 100644 --- a/giscanner/sourcescanner.c +++ b/giscanner/sourcescanner.c @@ -108,6 +108,7 @@ gi_source_type_copy (GISourceType * type) result->base_type = gi_source_type_copy (type->base_type); for (l = type->child_list; l; l = l->next) result->child_list = g_list_append (result->child_list, gi_source_symbol_ref (l->data)); + result->is_bitfield = type->is_bitfield; return result; } diff --git a/giscanner/sourcescanner.h b/giscanner/sourcescanner.h index 69417d11..f36a8084 100644 --- a/giscanner/sourcescanner.h +++ b/giscanner/sourcescanner.h @@ -127,6 +127,7 @@ struct _GISourceType char *name; GISourceType *base_type; GList *child_list; /* list of GISourceSymbol */ + gboolean is_bitfield; }; GISourceScanner * gi_source_scanner_new (void); diff --git a/giscanner/sourcescanner.py b/giscanner/sourcescanner.py index 5018bf43..56aac93e 100644 --- a/giscanner/sourcescanner.py +++ b/giscanner/sourcescanner.py @@ -104,7 +104,7 @@ def ctype_name(ctype): class SourceType(object): __members__ = ['type', 'base_type', 'name', 'type_qualifier', - 'child_list'] + 'child_list', 'is_bitfield'] def __init__(self, scanner, stype): self._scanner = scanner @@ -140,6 +140,10 @@ class SourceType(object): continue yield SourceSymbol(self._scanner, symbol) + @property + def is_bitfield(self): + return self._stype.is_bitfield + class SourceSymbol(object): __members__ = ['const_int', 'const_string', 'ident', 'type', 'base_type'] diff --git a/giscanner/transformer.py b/giscanner/transformer.py index 8e335ff6..b7e8c5df 100644 --- a/giscanner/transformer.py +++ b/giscanner/transformer.py @@ -20,7 +20,7 @@ import os -from .ast import (Callback, Enum, Function, Namespace, Member, +from .ast import (Bitfield, Callback, Enum, Function, Namespace, Member, Parameter, Return, Struct, Field, Type, Array, Alias, Interface, Class, Node, Union, Varargs, Constant, type_name_from_ctype, @@ -210,9 +210,13 @@ class Transformer(object): child.ident)) enum_name = self.remove_prefix(symbol.ident) - enum = Enum(enum_name, symbol.ident, members) - self._names.type_names[symbol.ident] = (None, enum) - return enum + if symbol.base_type.is_bitfield: + klass = Bitfield + else: + klass = Enum + node = klass(enum_name, symbol.ident, members) + self._names.type_names[symbol.ident] = (None, node) + return node def _create_object(self, symbol): return Member(symbol.ident, symbol.base_type.name, |