Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/girepository
diff options
context:
space:
mode:
authorColin Walters <walters@src.gnome.org>2009-02-04 00:48:24 (GMT)
committer Colin Walters <walters@src.gnome.org>2009-02-04 00:48:24 (GMT)
commite3e84400529899854fe06f7d110685f50be26a18 (patch)
tree6d7ab0ca6fb6b44969063070024628cddc2cfb6e /girepository
parentab991adecd8659a8b2843f4191ca4aa16aa4e121 (diff)
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. svn path=/trunk/; revision=1082
Diffstat (limited to 'girepository')
-rw-r--r--girepository/girparser.c73
1 files changed, 57 insertions, 16 deletions
diff --git a/girepository/girparser.c b/girepository/girparser.c
index 46c16e5..3e1f9df 100644
--- a/girepository/girparser.c
+++ b/girepository/girparser.c
@@ -2112,7 +2112,10 @@ start_struct (GMarkupParseContext *context,
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 @@ start_struct (GMarkupParseContext *context,
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 @@ start_struct (GMarkupParseContext *context,
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 @@ start_struct (GMarkupParseContext *context,
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 @@ start_union (GMarkupParseContext *context,
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 @@ start_union (GMarkupParseContext *context,
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 @@ start_union (GMarkupParseContext *context,
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 @@ start_union (GMarkupParseContext *context,
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 @@ require_one_of_end_elements (GMarkupParseContext *context,
}
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 @@ end_element_handler (GMarkupParseContext *context,
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 @@ end_element_handler (GMarkupParseContext *context,
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: