STATE_BOXED,
STATE_STRUCT,
STATE_SIGNAL,
- STATE_ERRORDOMAIN
+ STATE_ERRORDOMAIN,
+ STATE_UNION
} ParseState;
typedef struct _ParseContext ParseContext;
((ctx->state == STATE_OBJECT ||
ctx->state == STATE_INTERFACE ||
ctx->state == STATE_BOXED ||
- ctx->state == STATE_STRUCT) &&
+ ctx->state == STATE_STRUCT ||
+ ctx->state == STATE_UNION) &&
strcmp (element_name, "method") == 0) ||
((ctx->state == STATE_OBJECT ||
ctx->state == STATE_BOXED) &&
struct_ = (GIdlNodeStruct *)ctx->current_node;
struct_->members = g_list_append (struct_->members, function); }
break;
+ case G_IDL_NODE_UNION:
+ {
+ GIdlNodeUnion *union_;
+
+ union_ = (GIdlNodeUnion *)ctx->current_node;
+ union_->members = g_list_append (union_->members, function);
+ }
+ break;
}
ctx->current_node = (GIdlNode *)function;
if (strcmp (element_name, "field") == 0 &&
(ctx->state == STATE_OBJECT ||
ctx->state == STATE_BOXED ||
- ctx->state == STATE_STRUCT))
+ ctx->state == STATE_STRUCT ||
+ ctx->state == STATE_UNION))
{
const gchar *name;
const gchar *type;
const gchar *readable;
const gchar *writable;
const gchar *bits;
+ const gchar *branch;
name = find_attribute ("name", attribute_names, attribute_values);
type = find_attribute ("type", attribute_names, attribute_values);
readable = find_attribute ("readable", attribute_names, attribute_values);
writable = find_attribute ("writable", attribute_names, attribute_values);
bits = find_attribute ("bits", attribute_names, attribute_values);
+ branch = find_attribute ("branch", attribute_names, attribute_values);
if (name == NULL)
MISSING_ATTRIBUTE (error, element_name, "name");
struct_->members = g_list_append (struct_->members, field);
}
break;
+ case G_IDL_NODE_UNION:
+ {
+ GIdlNodeUnion *union_;
+
+ union_ = (GIdlNodeUnion *)ctx->current_node;
+ union_->members = g_list_append (union_->members, field);
+ if (branch)
+ {
+ GIdlNodeConstant *constant;
+
+ constant = (GIdlNodeConstant *) g_idl_node_new (G_IDL_NODE_CONSTANT);
+ ((GIdlNode *)constant)->name = g_strdup (name);
+ constant->value = g_strdup (branch);
+ constant->type = union_->discriminator_type;
+ constant->deprecated = FALSE;
+
+ union_->discriminators = g_list_append (union_->discriminators, constant);
+ }
+ }
+ break;
}
}
return TRUE;
return FALSE;
}
+
+static gboolean
+start_union (GMarkupParseContext *context,
+ const gchar *element_name,
+ const gchar **attribute_names,
+ const gchar **attribute_values,
+ ParseContext *ctx,
+ GError **error)
+{
+ if (strcmp (element_name, "union") == 0 &&
+ ctx->state == STATE_NAMESPACE)
+ {
+ const gchar *name;
+ const gchar *deprecated;
+ const gchar *typename;
+ const gchar *typeinit;
+
+ name = find_attribute ("name", attribute_names, attribute_values);
+ deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
+ typename = find_attribute ("type-name", attribute_names, attribute_values);
+ typeinit = find_attribute ("get-type", attribute_names, attribute_values);
+
+ if (name == NULL)
+ MISSING_ATTRIBUTE (error, element_name, "name");
+ else
+ {
+ GIdlNodeUnion *union_;
+
+ union_ = (GIdlNodeUnion *) g_idl_node_new (G_IDL_NODE_UNION);
+
+ ((GIdlNode *)union_)->name = g_strdup (name);
+ union_->gtype_name = g_strdup (typename);
+ union_->gtype_init = g_strdup (typeinit);
+ if (deprecated && strcmp (deprecated, "1") == 0)
+ union_->deprecated = TRUE;
+ else
+ union_->deprecated = FALSE;
+
+ ctx->current_node = (GIdlNode *)union_;
+ ctx->current_module->entries =
+ g_list_append (ctx->current_module->entries, union_);
+
+ ctx->state = STATE_UNION;
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static gboolean
+start_discriminator (GMarkupParseContext *context,
+ const gchar *element_name,
+ const gchar **attribute_names,
+ const gchar **attribute_values,
+ ParseContext *ctx,
+ GError **error)
+{
+ if (strcmp (element_name, "discriminator") == 0 &&
+ ctx->state == STATE_UNION)
+ {
+ const gchar *type;
+ const gchar *offset;
+
+ type = find_attribute ("type", attribute_names, attribute_values);
+ offset = find_attribute ("offset", attribute_names, attribute_values);
+ if (type == NULL)
+ MISSING_ATTRIBUTE (error, element_name, "type");
+ else if (offset == NULL)
+ MISSING_ATTRIBUTE (error, element_name, "offset");
+ {
+ ((GIdlNodeUnion *)ctx->current_node)->discriminator_type
+ = parse_type (type);
+ ((GIdlNodeUnion *)ctx->current_node)->discriminator_offset
+ = atoi (offset);
+ }
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
static void
start_element_handler (GMarkupParseContext *context,
const gchar *element_name,
goto out;
break;
+ case 'd':
+ if (start_discriminator (context, element_name,
+ attribute_names, attribute_values,
+ ctx, error))
+ goto out;
+ break;
+
case 'e':
if (start_enum (context, element_name,
attribute_names, attribute_values,
break;
+ case 'u':
+ if (start_union (context, element_name,
+ attribute_names, attribute_values,
+ ctx, error))
+ goto out;
+ break;
+
case 'v':
if (start_vfunc (context, element_name,
attribute_names, attribute_values,
ctx->state = STATE_BOXED;
else if (ctx->current_node->type == G_IDL_NODE_STRUCT)
ctx->state = STATE_STRUCT;
+ else if (ctx->current_node->type == G_IDL_NODE_UNION)
+ ctx->state = STATE_UNION;
}
break;
ctx->state = STATE_NAMESPACE;
}
break;
+ case STATE_UNION:
+ if (strcmp (element_name, "union") == 0)
+ {
+ ctx->current_node = NULL;
+ ctx->state = STATE_NAMESPACE;
+ }
+ break;
+
case STATE_IMPLEMENTS:
ctx->state = STATE_OBJECT;
break;