summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohan Dahlin <jdahlin@async.com.br>2009-01-12 23:24:01 +0000
committerJohan Dahlin <johan@src.gnome.org>2009-01-12 23:24:01 +0000
commit9256e916164ec557ed66f92a0d6d95bb286cdf8b (patch)
treee481541d55ca9eafb63684f2ee41d48096b8eac5
parente81c4681cc88a00fcd841c5a68d860d3714b55d7 (diff)
downloadgobject-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
-rw-r--r--ChangeLog20
-rw-r--r--giscanner/ast.py11
-rw-r--r--giscanner/girwriter.py29
-rw-r--r--giscanner/giscannermodule.c8
-rw-r--r--giscanner/glibast.py23
-rw-r--r--giscanner/glibtransformer.py9
-rw-r--r--giscanner/scannerparser.y20
-rw-r--r--giscanner/sourcescanner.c1
-rw-r--r--giscanner/sourcescanner.h1
-rw-r--r--giscanner/sourcescanner.py6
-rw-r--r--giscanner/transformer.py12
-rw-r--r--tests/scanner/foo-1.0-expected.gir5
-rw-r--r--tests/scanner/foo-1.0-expected.tgir5
-rw-r--r--tests/scanner/foo.h9
14 files changed, 133 insertions, 26 deletions
diff --git a/ChangeLog b/ChangeLog
index d94ffd69..7e4c22b9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+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.
+
2009-01-12 Havoc Pennington <hp@pobox.com>
Bug 563386 – scanner ignores "const" on boxed return values
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,
diff --git a/tests/scanner/foo-1.0-expected.gir b/tests/scanner/foo-1.0-expected.gir
index 84a5cc3a..17fd5200 100644
--- a/tests/scanner/foo-1.0-expected.gir
+++ b/tests/scanner/foo-1.0-expected.gir
@@ -301,6 +301,11 @@
<member name="trois" value="3" c:identifier="FOO_ENUM_TROIS"/>
<member name="neuf" value="9" c:identifier="FOO_ENUM_NEUF"/>
</enumeration>
+ <bitfield name="FlagsNoType" c:type="FooFlagsNoType">
+ <member name="ett" value="1" c:identifier="FOO_FLAGS_ETT"/>
+ <member name="tva" value="2" c:identifier="FOO_FLAGS_TVA"/>
+ <member name="fyra" value="4" c:identifier="FOO_FLAGS_FYRA"/>
+ </bitfield>
<enumeration name="EnumFullname" c:type="FooEnumFullname">
<member name="one" value="1" c:identifier="FOO_ENUM_FULLNAME_ONE"/>
<member name="two" value="2" c:identifier="FOO_ENUM_FULLNAME_TWO"/>
diff --git a/tests/scanner/foo-1.0-expected.tgir b/tests/scanner/foo-1.0-expected.tgir
index 8c205a9c..2cb29d39 100644
--- a/tests/scanner/foo-1.0-expected.tgir
+++ b/tests/scanner/foo-1.0-expected.tgir
@@ -193,6 +193,11 @@
<member name="trois" value="3"/>
<member name="neuf" value="9"/>
</enumeration>
+ <bitfield name="FlagsNoType">
+ <member name="ett" value="1"/>
+ <member name="tva" value="2"/>
+ <member name="fyra" value="4"/>
+ </bitfield>
<enumeration name="EnumFullname">
<member name="one" value="1"/>
<member name="two" value="2"/>
diff --git a/tests/scanner/foo.h b/tests/scanner/foo.h
index dbef015b..f08fc3c7 100644
--- a/tests/scanner/foo.h
+++ b/tests/scanner/foo.h
@@ -128,6 +128,8 @@ typedef enum
FOO_FLAGS_THIRD = 1 << 2
} FooFlagsType;
+GType foo_flags_type_get_type (void);
+
typedef enum
{
FOO_ENUM_UN = 1,
@@ -136,7 +138,12 @@ typedef enum
FOO_ENUM_NEUF = 9
} FooEnumNoType;
-GType foo_flags_type_get_type (void);
+typedef enum
+{
+ FOO_FLAGS_ETT = 1 << 0,
+ FOO_FLAGS_TVA = 1 << 1,
+ FOO_FLAGS_FYRA = 1 << 2
+} FooFlagsNoType;
typedef enum
{