gobject-introspection r1082 - in trunk: . girepository giscanner tests/repository tests/scanner
- From: walters svn gnome org
- To: svn-commits-list gnome org
- Subject: gobject-introspection r1082 - in trunk: . girepository giscanner tests/repository tests/scanner
- Date: Wed, 4 Feb 2009 00:48:24 +0000 (UTC)
Author: walters
Date: Wed Feb 4 00:48:24 2009
New Revision: 1082
URL: http://svn.gnome.org/viewvc/gobject-introspection?rev=1082&view=rev
Log:
Bug 555960 - Nested structs and unions (generation portion)
Patch from Andreas Rottmann <a rottmann gmx at>.
* tests/scanner/utility.h (UtilityTaggedValue): Make the union
member anonymous.
(UtilityByte): New union typedef with an unnamed struct in it.
* giscanner/transformer.py (Transformer._create_struct): Create
unnamed structs for symbols with a None ident.
(Transformer._create_union): Likewise.
* giscanner/girwriter.py (GIRWriter._write_record): Allow name
being None.
(GIRWriter._write_union): Likewise.
* girepository/girparser.c (start_struct): Allow a NULL name for
non-toplevel structs.
(start_union): Likewise.
* tests/scanner/utility.h (UtilityTaggedValue): New struct
typedef, which has a nested union member.
* tests/scanner/utility-expected.gir: Adapted.
* giscanner/transformer.py (Transformer._create_member): Create
struct/union members if appropriate.
(Transformer._create_struct, Transformer._create_union): Allow for
structs/unions without a C type.
* giscanner/glibtransformer.py (GLibTransformer._resolve_field):
We don't need to resolve non-typef'd
(GLibTransformer._resolve_field): Add cases for non-typedef'd
struct/union "fields".
* giscanner/girwriter.py (GIRWriter._write_record): Allow for
records without a C type.
(GIRWriter._write_field): structs and unions may appear in places
where fields do.
Modified:
trunk/ChangeLog
trunk/girepository/girparser.c
trunk/giscanner/girwriter.py
trunk/giscanner/glibtransformer.py
trunk/giscanner/transformer.py
trunk/tests/repository/Makefile.am
trunk/tests/scanner/utility-1.0-expected.gir
trunk/tests/scanner/utility-1.0-expected.tgir
trunk/tests/scanner/utility.h
Modified: trunk/girepository/girparser.c
==============================================================================
--- trunk/girepository/girparser.c (original)
+++ trunk/girepository/girparser.c Wed Feb 4 00:48:24 2009
@@ -2112,7 +2112,10 @@
GError **error)
{
if (strcmp (element_name, "record") == 0 &&
- ctx->state == STATE_NAMESPACE)
+ (ctx->state == STATE_NAMESPACE ||
+ ctx->state == STATE_UNION ||
+ ctx->state == STATE_STRUCT ||
+ ctx->state == STATE_CLASS))
{
const gchar *name;
const gchar *deprecated;
@@ -2127,7 +2130,7 @@
gtype_name = find_attribute ("glib:type-name", attribute_names, attribute_values);
gtype_init = find_attribute ("glib:get-type", attribute_names, attribute_values);
- if (name == NULL)
+ if (name == NULL && ctx->node_stack == NULL)
{
MISSING_ATTRIBUTE (context, error, element_name, "name");
return FALSE;
@@ -2145,7 +2148,7 @@
struct_ = (GIrNodeStruct *) g_ir_node_new (G_IR_NODE_STRUCT);
- ((GIrNode *)struct_)->name = g_strdup (name);
+ ((GIrNode *)struct_)->name = g_strdup (name ? name : "");
if (deprecated)
struct_->deprecated = TRUE;
else
@@ -2156,9 +2159,10 @@
struct_->gtype_name = g_strdup (gtype_name);
struct_->gtype_init = g_strdup (gtype_init);
-
- ctx->current_module->entries =
- g_list_append (ctx->current_module->entries, struct_);
+
+ if (ctx->node_stack == NULL)
+ ctx->current_module->entries =
+ g_list_append (ctx->current_module->entries, struct_);
push_node (ctx, (GIrNode *)struct_);
state_switch (ctx, STATE_STRUCT);
@@ -2176,8 +2180,11 @@
ParseContext *ctx,
GError **error)
{
- if (strcmp (element_name, "union") == 0 &&
- ctx->state == STATE_NAMESPACE)
+ if (strcmp (element_name, "union") == 0 &&
+ (ctx->state == STATE_NAMESPACE ||
+ ctx->state == STATE_UNION ||
+ ctx->state == STATE_STRUCT ||
+ ctx->state == STATE_CLASS))
{
const gchar *name;
const gchar *deprecated;
@@ -2189,7 +2196,7 @@
typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
- if (name == NULL)
+ if (name == NULL && ctx->node_stack == NULL)
MISSING_ATTRIBUTE (context, error, element_name, "name");
else
{
@@ -2197,7 +2204,7 @@
union_ = (GIrNodeUnion *) g_ir_node_new (G_IR_NODE_UNION);
- ((GIrNode *)union_)->name = g_strdup (name);
+ ((GIrNode *)union_)->name = g_strdup (name ? name : "");
union_->gtype_name = g_strdup (typename);
union_->gtype_init = g_strdup (typeinit);
if (deprecated)
@@ -2205,8 +2212,9 @@
else
union_->deprecated = FALSE;
- ctx->current_module->entries =
- g_list_append (ctx->current_module->entries, union_);
+ if (ctx->node_stack == NULL)
+ ctx->current_module->entries =
+ g_list_append (ctx->current_module->entries, union_);
push_node (ctx, (GIrNode *)union_);
state_switch (ctx, STATE_UNION);
@@ -2685,6 +2693,41 @@
}
static gboolean
+state_switch_end_struct_or_union (GMarkupParseContext *context,
+ ParseContext *ctx,
+ const gchar *element_name,
+ GError **error)
+{
+ pop_node (ctx);
+ if (ctx->node_stack == NULL)
+ {
+ state_switch (ctx, STATE_NAMESPACE);
+ }
+ else
+ {
+ if (CURRENT_NODE (ctx)->type == G_IR_NODE_STRUCT)
+ state_switch (ctx, STATE_STRUCT);
+ else if (CURRENT_NODE (ctx)->type == G_IR_NODE_UNION)
+ state_switch (ctx, STATE_UNION);
+ else if (CURRENT_NODE (ctx)->type == G_IR_NODE_OBJECT)
+ state_switch (ctx, STATE_CLASS);
+ else
+ {
+ int line_number, char_number;
+ g_markup_parse_context_get_position (context, &line_number, &char_number);
+ g_set_error (error,
+ G_MARKUP_ERROR,
+ G_MARKUP_ERROR_INVALID_CONTENT,
+ "Unexpected end tag '%s' on line %d char %d",
+ element_name,
+ line_number, char_number);
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+static gboolean
require_end_element (GMarkupParseContext *context,
ParseContext *ctx,
const char *expected_name,
@@ -2897,8 +2940,7 @@
case STATE_STRUCT:
if (require_end_element (context, ctx, "record", element_name, error))
{
- pop_node (ctx);
- state_switch (ctx, STATE_NAMESPACE);
+ state_switch_end_struct_or_union (context, ctx, element_name, error);
}
break;
@@ -2914,8 +2956,7 @@
case STATE_UNION:
if (require_end_element (context, ctx, "union", element_name, error))
{
- pop_node (ctx);
- state_switch (ctx, STATE_NAMESPACE);
+ state_switch_end_struct_or_union (context, ctx, element_name, error);
}
break;
case STATE_IMPLEMENTS:
Modified: trunk/giscanner/girwriter.py
==============================================================================
--- trunk/giscanner/girwriter.py (original)
+++ trunk/giscanner/girwriter.py Wed Feb 4 00:48:24 2009
@@ -366,8 +366,11 @@
('glib:get-type', boxed.get_type)]
def _write_record(self, record):
- attrs = [('name', record.name),
- ('c:type', record.symbol)]
+ attrs = []
+ if record.name is not None:
+ attrs.append(('name', record.name))
+ if record.symbol is not None: # the record might be anonymous
+ attrs.append(('c:type', record.symbol))
if record.disguised:
attrs.append(('disguised', '1'))
if record.doc:
@@ -386,8 +389,11 @@
self._write_method(method)
def _write_union(self, union):
- attrs = [('name', union.name),
- ('c:type', union.symbol)]
+ attrs = []
+ if union.name is not None:
+ attrs.append(('name', union.name))
+ if union.symbol is not None: # the union might be anonymous
+ attrs.append(('c:type', union.symbol))
if union.doc:
attrs.append(('doc', union.doc))
self._append_version(union, attrs)
@@ -410,19 +416,22 @@
if isinstance(field, Callback):
self._write_callback(field)
- return
-
- attrs = [('name', field.name)]
- # Fields are assumed to be read-only
- # (see also girparser.c and generate.c)
- if not field.readable:
- attrs.append(('readable', '0'))
- if field.writable:
- attrs.append(('writable', '1'))
- if field.bits:
- attrs.append(('bits', str(field.bits)))
- with self.tagcontext('field', attrs):
- self._write_type(field.type)
+ elif isinstance(field, Struct):
+ self._write_record(field)
+ elif isinstance(field, Union):
+ self._write_union(field)
+ else:
+ attrs = [('name', field.name)]
+ # Fields are assumed to be read-only
+ # (see also girparser.c and generate.c)
+ if not field.readable:
+ attrs.append(('readable', '0'))
+ if field.writable:
+ attrs.append(('writable', '1'))
+ if field.bits:
+ attrs.append(('bits', str(field.bits)))
+ with self.tagcontext('field', attrs):
+ self._write_type(field.type)
def _write_signal(self, signal):
attrs = [('name', signal.name)]
Modified: trunk/giscanner/glibtransformer.py
==============================================================================
--- trunk/giscanner/glibtransformer.py (original)
+++ trunk/giscanner/glibtransformer.py Wed Feb 4 00:48:24 2009
@@ -870,8 +870,12 @@
def _resolve_field(self, field):
if isinstance(field, Callback):
self._resolve_function(field)
- return
- field.type = self._resolve_param_type(field.type)
+ elif isinstance(field, Record): # non-typedef'd struct
+ self._resolve_record(field)
+ elif isinstance(field, Union): # non-typedef'd union
+ self._resolve_union(field)
+ else:
+ field.type = self._resolve_param_type(field.type)
def _resolve_alias(self, alias):
alias.target = self._resolve_type_name(alias.target, alias.target)
Modified: trunk/giscanner/transformer.py
==============================================================================
--- trunk/giscanner/transformer.py (original)
+++ trunk/giscanner/transformer.py Wed Feb 4 00:48:24 2009
@@ -307,6 +307,10 @@
if (source_type.type == CTYPE_POINTER and
symbol.base_type.base_type.type == CTYPE_FUNCTION):
node = self._create_callback(symbol)
+ elif source_type.type == CTYPE_STRUCT and source_type.name is None:
+ node = self._create_struct(symbol, anonymous=True)
+ elif source_type.type == CTYPE_UNION and source_type.name is None:
+ node = self._create_union(symbol, anonymous=True)
else:
# Special handling for fields; we don't have annotations on them
# to apply later, yet.
@@ -478,8 +482,14 @@
self._typedefs_ns[callback.name] = callback
return callback
- def _create_compound(self, klass, symbol):
- compound = self._typedefs_ns.get(symbol.ident, None)
+ def _create_compound(self, klass, symbol, anonymous):
+ if symbol.ident is None:
+ # the compound is an anonymous member of another union or a struct
+ assert anonymous
+ compound = klass(None, None)
+ else:
+ compound = self._typedefs_ns.get(symbol.ident, None)
+
if compound is None:
# This is a bit of a hack; really we should try
# to resolve through the typedefs to find the real
@@ -500,11 +510,11 @@
return compound
- def _create_struct(self, symbol):
- return self._create_compound(Struct, symbol)
+ def _create_struct(self, symbol, anonymous=False):
+ return self._create_compound(Struct, symbol, anonymous)
- def _create_union(self, symbol):
- return self._create_compound(Union, symbol)
+ def _create_union(self, symbol, anonymous=False):
+ return self._create_compound(Union, symbol, anonymous)
def _create_callback(self, symbol):
parameters = self._create_parameters(symbol.base_type.base_type)
Modified: trunk/tests/repository/Makefile.am
==============================================================================
--- trunk/tests/repository/Makefile.am (original)
+++ trunk/tests/repository/Makefile.am Wed Feb 4 00:48:24 2009
@@ -13,4 +13,5 @@
gitestthrows_LDADD = $(top_builddir)/girepository/libgirepository-1.0.la $(GIREPO_LIBS)
TESTS = gitestrepo gitestthrows
-TESTS_ENVIRONMENT=env top_builddir="$(top_builddir)" $(DEBUG)
+TESTS_ENVIRONMENT=env top_builddir="$(top_builddir)" $(DEBUG) \
+ XDG_DATA_DIRS="$(top_srcdir)/gir:$(XDG_DATA_DIRS)"
Modified: trunk/tests/scanner/utility-1.0-expected.gir
==============================================================================
--- trunk/tests/scanner/utility-1.0-expected.gir (original)
+++ trunk/tests/scanner/utility-1.0-expected.gir Wed Feb 4 00:48:24 2009
@@ -46,6 +46,35 @@
<type name="GObject.ObjectClass" c:type="GObjectClass"/>
</field>
</record>
+ <record name="TaggedValue" c:type="UtilityTaggedValue">
+ <field name="tag" writable="1">
+ <type name="int" c:type="int"/>
+ </field>
+ <union>
+ <field name="v_pointer" writable="1">
+ <type name="any" c:type="gpointer"/>
+ </field>
+ <field name="v_real" writable="1">
+ <type name="double" c:type="double"/>
+ </field>
+ <field name="v_integer" writable="1">
+ <type name="long" c:type="long"/>
+ </field>
+ </union>
+ </record>
+ <union name="Byte" c:type="UtilityByte">
+ <field name="value" writable="1">
+ <type name="uint8" c:type="guint8"/>
+ </field>
+ <record>
+ <field name="first_nibble" writable="1" bits="4">
+ <type name="uint8" c:type="guint8"/>
+ </field>
+ <field name="second_nibble" writable="1" bits="4">
+ <type name="uint8" c:type="guint8"/>
+ </field>
+ </record>
+ </union>
<callback name="FileFunc" c:type="UtilityFileFunc">
<return-value transfer-ownership="none">
<type name="none" c:type="void"/>
Modified: trunk/tests/scanner/utility-1.0-expected.tgir
==============================================================================
--- trunk/tests/scanner/utility-1.0-expected.tgir (original)
+++ trunk/tests/scanner/utility-1.0-expected.tgir Wed Feb 4 00:48:24 2009
@@ -35,6 +35,18 @@
<type name="GObject.ObjectClass"/>
</field>
</record>
+ <record name="TaggedValue">
+ <field name="tag" writable="1">
+ <type name="int"/>
+ </field>
+ <!-- FIXME: anonymous union member missing -->
+ </record>
+ <union name="Byte">
+ <field name="value" writable="1">
+ <type name="uint8"/>
+ </field>
+ <!-- FIXME: anonymous struct member missing -->
+ </union>
<callback name="FileFunc">
<return-value transfer-ownership="none">
<type name="none"/>
Modified: trunk/tests/scanner/utility.h
==============================================================================
--- trunk/tests/scanner/utility.h (original)
+++ trunk/tests/scanner/utility.h Wed Feb 4 00:48:24 2009
@@ -23,6 +23,27 @@
/* This one is similar to Pango.Glyph */
typedef guint32 UtilityGlyph;
+typedef struct
+{
+ int tag;
+ union
+ {
+ gpointer v_pointer;
+ double v_real;
+ long v_integer;
+ };
+} UtilityTaggedValue;
+
+typedef union
+{
+ guint8 value;
+ struct
+ {
+ guint8 first_nibble : 4;
+ guint8 second_nibble : 4;
+ };
+} UtilityByte;
+
typedef void (*UtilityFileFunc)(const char *path, gpointer user_data);
GType utility_object_get_type (void) G_GNUC_CONST;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]