* unary expression (value) or
* type_specifier_list.
*/
- struct ctf_node *length;
+ struct cds_list_head length;
/* for abstract type declarator */
unsigned int abstract_array;
} nested;
case NODE_TYPEALIAS_ALIAS:
parent->u.typealias_alias.type_specifier_list = node;
break;
- case NODE_TYPE_DECLARATOR:
- parent->u.type_declarator.type = TYPEDEC_NESTED;
- parent->u.type_declarator.u.nested.length = node;
- break;
case NODE_ENUM:
parent->u._enum.container_type = node;
break;
case NODE_STRUCT_OR_VARIANT_DECLARATION:
parent->u.struct_or_variant_declaration.type_specifier_list = node;
break;
+ case NODE_TYPE_DECLARATOR:
case NODE_TYPE_SPECIFIER:
case NODE_TYPEALIAS:
case NODE_FLOATING_POINT:
%type <n> type_specifier
%type <n> struct_type_specifier
%type <n> variant_type_specifier
-%type <n> declaration_specifiers_or_integer_constant
%type <n> enum_type_specifier
%type <n> struct_or_variant_declaration_list
%type <n> struct_or_variant_declaration
{ pop_scope(scanner); }
;
-declaration_specifiers_or_integer_constant:
- declaration_specifiers
- { $$ = $1; }
- | DECIMAL_CONSTANT
- {
- $$ = make_node(scanner, NODE_UNARY_EXPRESSION);
- $$->u.unary_expression.type = UNARY_UNSIGNED_CONSTANT;
- sscanf(yylval.gs->s, "%" PRIu64,
- &$$->u.unary_expression.u.unsigned_constant);
- }
- | OCTAL_CONSTANT
- {
- $$ = make_node(scanner, NODE_UNARY_EXPRESSION);
- $$->u.unary_expression.type = UNARY_UNSIGNED_CONSTANT;
- sscanf(yylval.gs->s, "0%" PRIo64,
- &$$->u.unary_expression.u.unsigned_constant);
- }
- | HEXADECIMAL_CONSTANT
- {
- $$ = make_node(scanner, NODE_UNARY_EXPRESSION);
- $$->u.unary_expression.type = UNARY_UNSIGNED_CONSTANT;
- sscanf(yylval.gs->s, "0x%" PRIx64,
- &$$->u.unary_expression.u.unsigned_constant);
- }
- ;
-
enum_type_specifier:
LBRAC enumerator_list RBRAC
{
$$->u.type_declarator.type = TYPEDEC_NESTED;
$$->u.type_declarator.u.nested.type_declarator = $2;
}
- | direct_abstract_declarator LSBRAC declaration_specifiers_or_integer_constant RSBRAC
+ | direct_abstract_declarator LSBRAC unary_expression RSBRAC
{
$$ = make_node(scanner, NODE_TYPE_DECLARATOR);
$$->u.type_declarator.type = TYPEDEC_NESTED;
$$->u.type_declarator.u.nested.type_declarator = $1;
- ($$)->u.type_declarator.u.nested.length = $3;
+ CDS_INIT_LIST_HEAD(&($$)->u.type_declarator.u.nested.length);
+ _cds_list_splice_tail(&($3)->tmp_head, &($$)->u.type_declarator.u.nested.length);
}
| direct_abstract_declarator LSBRAC RSBRAC
{
$$->u.type_declarator.type = TYPEDEC_NESTED;
$$->u.type_declarator.u.nested.type_declarator = $2;
}
- | direct_alias_abstract_declarator LSBRAC declaration_specifiers_or_integer_constant RSBRAC
+ | direct_alias_abstract_declarator LSBRAC unary_expression RSBRAC
{
$$ = make_node(scanner, NODE_TYPE_DECLARATOR);
$$->u.type_declarator.type = TYPEDEC_NESTED;
$$->u.type_declarator.u.nested.type_declarator = $1;
- ($$)->u.type_declarator.u.nested.length = $3;
+ CDS_INIT_LIST_HEAD(&($$)->u.type_declarator.u.nested.length);
+ _cds_list_splice_tail(&($3)->tmp_head, &($$)->u.type_declarator.u.nested.length);
}
| direct_alias_abstract_declarator LSBRAC RSBRAC
{
$$->u.type_declarator.type = TYPEDEC_NESTED;
$$->u.type_declarator.u.nested.type_declarator = $2;
}
- | direct_declarator LSBRAC declaration_specifiers_or_integer_constant RSBRAC
+ | direct_declarator LSBRAC unary_expression RSBRAC
{
$$ = make_node(scanner, NODE_TYPE_DECLARATOR);
$$->u.type_declarator.type = TYPEDEC_NESTED;
$$->u.type_declarator.u.nested.type_declarator = $1;
- ($$)->u.type_declarator.u.nested.length = $3;
+ CDS_INIT_LIST_HEAD(&($$)->u.type_declarator.u.nested.length);
+ _cds_list_splice_tail(&($3)->tmp_head, &($$)->u.type_declarator.u.nested.length);
}
;
$$->u.type_declarator.type = TYPEDEC_NESTED;
$$->u.type_declarator.u.nested.type_declarator = $2;
}
- | direct_type_declarator LSBRAC declaration_specifiers_or_integer_constant RSBRAC
+ | direct_type_declarator LSBRAC unary_expression RSBRAC
{
$$ = make_node(scanner, NODE_TYPE_DECLARATOR);
$$->u.type_declarator.type = TYPEDEC_NESTED;
$$->u.type_declarator.u.nested.type_declarator = $1;
- ($$)->u.type_declarator.u.nested.length = $3;
+ CDS_INIT_LIST_HEAD(&($$)->u.type_declarator.u.nested.length);
+ _cds_list_splice_tail(&($3)->tmp_head, &($$)->u.type_declarator.u.nested.length);
}
;
--- /dev/null
+/* Architecture with 32-bit pointers, 32-bit integers, 32-bit longs */
+
+typealias integer { size = 1; align = 1; signed = false; } := uint1_t;
+typealias integer { size = 8; align = 8; signed = false; } := uint8_t;
+typealias integer { size = 63; align = 1; signed = false; } := timestamp_t;
+
+typealias integer { size = 32; align = 32; signed = false; base = dec; } := uint32_t;
+typealias integer { size = 32; align = 32; signed = false; base = hex;} := void *;
+
+trace {
+ major = 0;
+ minor = 1;
+ uuid = "2a6422d0-6cee-11e0-8c08-cb07d7b3a564";
+ byte_order = be;
+ packet.header := struct {
+ uint32_t magic;
+ uint8_t trace_uuid[16];
+ uint32_t stream_id;
+ };
+};
+
+stream {
+ id = 0;
+ event.header := struct {
+ uint1_t id;
+ timestamp_t timestamp;
+ } align(8);
+ event.context := struct {
+ uint32_t thread_id;
+ uint32_t event_count;
+ };
+};
+
+event {
+ name = func_enter;
+ id = 0;
+ stream_id = 0;
+ fields := struct {
+ uint8_t len;
+ uint32_t myseq[len];
+ };
+};
trace {
major = 66;
minor = 2;
+ byte_order = le;
uuid = "1123fcea-706e-11e0-a38b-f3c28a683a3d";
packet.header := struct event_packet_header;
};
id = 0;
stream_id = 5;
context := struct {};
- payload := struct {};
+ fields := struct {};
};
typealias integer { size = 32; align = 32; signed = false; } := unsigned long long *;
};
event {
+ typealias integer { size = 8; align = 8; signed = true; } := char;
+ typealias integer { size = 32; align = 32; signed = false; } := unsigned int;
+
name = test_event2;
id = 1;
stream_id = 5;
- payload := struct {
+ fields := struct {
enum : char { a = 0, b = 1, } tag;
variant vardecl <tag> myvariant;
+ unsigned int seqlen;
+ int myseq[seqlen];
};
};
typedef int myarray[10];
-typedef int myseq[uint];
return nested_declaration;
} else {
struct declaration *declaration;
- struct ctf_node *length;
+ struct ctf_node *first;
/* TYPEDEC_NESTED */
/* create array/sequence, pass nested_declaration as child. */
- length = node_type_declarator->u.type_declarator.u.nested.length;
- if (!length) {
- fprintf(fd, "[error] %s: expecting length type or value.\n", __func__);
+ if (cds_list_empty(&node_type_declarator->u.type_declarator.u.nested.length)) {
+ fprintf(fd, "[error] %s: expecting length field reference or value.\n", __func__);
return NULL;
}
- switch (length->type) {
- case NODE_UNARY_EXPRESSION:
+ first = _cds_list_first_entry(&node_type_declarator->u.type_declarator.u.nested.length,
+ struct ctf_node, siblings);
+ assert(first->type == NODE_UNARY_EXPRESSION);
+
+ switch (first->u.unary_expression.type) {
+ case UNARY_UNSIGNED_CONSTANT:
{
struct declaration_array *array_declaration;
size_t len;
- if (length->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
- fprintf(fd, "[error] %s: array: unexpected unary expression.\n", __func__);
- return NULL;
- }
- len = length->u.unary_expression.u.unsigned_constant;
+ len = first->u.unary_expression.u.unsigned_constant;
array_declaration = array_declaration_new(len, nested_declaration,
declaration_scope);
+
+ if (!array_declaration) {
+ fprintf(fd, "[error] %s: cannot create array declaration.\n", __func__);
+ return NULL;
+ }
declaration = &array_declaration->p;
break;
}
- case NODE_TYPE_SPECIFIER_LIST:
+ case UNARY_STRING:
{
+ /* Lookup unsigned integer definition, create sequence */
+ char *length_name = concatenate_unary_strings(&node_type_declarator->u.type_declarator.u.nested.length);
struct declaration_sequence *sequence_declaration;
- struct declaration_integer *integer_declaration;
- declaration = ctf_type_specifier_list_visit(fd, depth,
- length, declaration_scope, trace);
- if (!declaration) {
- fprintf(fd, "[error] %s: unable to find declaration type for sequence length\n", __func__);
- return NULL;
- }
- if (declaration->id != CTF_TYPE_INTEGER) {
- fprintf(fd, "[error] %s: length type for sequence is expected to be an integer (unsigned).\n", __func__);
- declaration_unref(declaration);
+ sequence_declaration = sequence_declaration_new(length_name, nested_declaration, declaration_scope);
+ if (!sequence_declaration) {
+ fprintf(fd, "[error] %s: cannot create sequence declaration.\n", __func__);
return NULL;
}
- integer_declaration = container_of(declaration, struct declaration_integer, p);
- if (integer_declaration->signedness != false) {
- fprintf(fd, "[error] %s: length type for sequence should always be an unsigned integer.\n", __func__);
- declaration_unref(declaration);
- return NULL;
- }
-
- sequence_declaration = sequence_declaration_new(integer_declaration,
- nested_declaration, declaration_scope);
declaration = &sequence_declaration->p;
break;
}
goto error;
}
event->fields_decl = container_of(declaration, struct declaration_struct, p);
+ } else {
+ fprintf(fd, "[error] %s: attribute \"%s\" is unknown in event declaration.\n", __func__, left);
+ ret = -EINVAL;
+ goto error;
}
error:
g_free(left);
&event->id);
parent_def_scope = event->stream->definition_scope;
if (event->context_decl) {
- event->context =
- container_of(
+ struct definition *definition =
event->context_decl->p.definition_new(&event->context_decl->p,
- parent_def_scope, 0, 0),
- struct definition_struct, p);
- set_dynamic_definition_scope(&event->context->p,
- event->context->scope,
- "event.context");
+ parent_def_scope, 0, 0, "event.context");
+ if (!definition) {
+ ret = -EINVAL;
+ goto error;
+ }
+ event->context = container_of(definition,
+ struct definition_struct, p);
parent_def_scope = event->context->scope;
- declaration_unref(&event->context_decl->p);
}
if (event->fields_decl) {
- event->fields =
- container_of(
+ struct definition *definition =
event->fields_decl->p.definition_new(&event->fields_decl->p,
- parent_def_scope, 0, 0),
- struct definition_struct, p);
- set_dynamic_definition_scope(&event->fields->p,
- event->fields->scope,
- "event.fields");
+ parent_def_scope, 0, 0, "event.fields");
+ if (!definition) {
+ ret = -EINVAL;
+ goto error;
+ }
+ event->fields = container_of(definition,
+ struct definition_struct, p);
parent_def_scope = event->fields->scope;
- declaration_unref(&event->fields_decl->p);
}
return 0;
error:
- declaration_unref(&event->fields_decl->p);
- declaration_unref(&event->context_decl->p);
+ if (event->context)
+ definition_unref(&event->context->p);
+ if (event->fields)
+ definition_unref(&event->fields->p);
+ if (event->fields_decl)
+ declaration_unref(&event->fields_decl->p);
+ if (event->context_decl)
+ declaration_unref(&event->context_decl->p);
free_declaration_scope(event->declaration_scope);
g_free(event);
return ret;
goto error;
}
stream->packet_context_decl = container_of(declaration, struct declaration_struct, p);
+ } else {
+ fprintf(fd, "[error] %s: attribute \"%s\" is unknown in stream declaration.\n", __func__, left);
+ ret = -EINVAL;
+ goto error;
}
+
error:
g_free(left);
break;
parent_def_scope = trace->definition_scope;
if (stream->packet_context_decl) {
- stream->packet_context =
- container_of(
+ struct definition *definition =
stream->packet_context_decl->p.definition_new(&stream->packet_context_decl->p,
- parent_def_scope, 0, 0),
- struct definition_struct, p);
- set_dynamic_definition_scope(&stream->packet_context->p,
- stream->packet_context->scope,
- "stream.packet.context");
+ parent_def_scope, 0, 0, "stream.packet.context");
+ if (!definition) {
+ ret = -EINVAL;
+ goto error;
+ }
+ stream->packet_context = container_of(definition,
+ struct definition_struct, p);
parent_def_scope = stream->packet_context->scope;
- declaration_unref(&stream->packet_context_decl->p);
}
if (stream->event_header_decl) {
- stream->event_header =
- container_of(
+ struct definition *definition =
stream->event_header_decl->p.definition_new(&stream->event_header_decl->p,
- parent_def_scope, 0, 0),
- struct definition_struct, p);
- set_dynamic_definition_scope(&stream->event_header->p,
- stream->event_header->scope,
- "stream.event.header");
+ parent_def_scope, 0, 0, "stream.event.header");
+ if (!definition) {
+ ret = -EINVAL;
+ goto error;
+ }
+ stream->event_header =
+ container_of(definition, struct definition_struct, p);
parent_def_scope = stream->event_header->scope;
- declaration_unref(&stream->event_header_decl->p);
}
if (stream->event_context_decl) {
- stream->event_context =
- container_of(
+ struct definition *definition =
stream->event_context_decl->p.definition_new(&stream->event_context_decl->p,
- parent_def_scope, 0, 0),
- struct definition_struct, p);
- set_dynamic_definition_scope(&stream->event_context->p,
- stream->event_context->scope,
- "stream.event.context");
+ parent_def_scope, 0, 0, "stream.event.context");
+ if (!definition) {
+ ret = -EINVAL;
+ goto error;
+ }
+ stream->event_context =
+ container_of(definition, struct definition_struct, p);
parent_def_scope = stream->event_context->scope;
- declaration_unref(&stream->event_context_decl->p);
}
stream->definition_scope = parent_def_scope;
return 0;
error:
- declaration_unref(&stream->event_header_decl->p);
- declaration_unref(&stream->event_context_decl->p);
- declaration_unref(&stream->packet_context_decl->p);
+ if (stream->event_context)
+ definition_unref(&stream->event_context->p);
+ if (stream->event_header)
+ definition_unref(&stream->event_header->p);
+ if (stream->packet_context)
+ definition_unref(&stream->packet_context->p);
+ if (stream->event_header_decl)
+ declaration_unref(&stream->event_header_decl->p);
+ if (stream->event_context_decl)
+ declaration_unref(&stream->event_context_decl->p);
+ if (stream->packet_context_decl)
+ declaration_unref(&stream->packet_context_decl->p);
g_ptr_array_free(stream->files, TRUE);
g_ptr_array_free(stream->events_by_id, TRUE);
g_hash_table_destroy(stream->event_quark_to_id);
goto error;
}
trace->packet_header_decl = container_of(declaration, struct declaration_struct, p);
+ } else {
+ fprintf(fd, "[error] %s: attribute \"%s\" is unknown in trace declaration.\n", __func__, left);
+ ret = -EINVAL;
+ goto error;
}
+
error:
g_free(left);
break;
parent_def_scope = NULL;
if (trace->packet_header_decl) {
- trace->packet_header =
- container_of(
+ struct definition *definition =
trace->packet_header_decl->p.definition_new(&trace->packet_header_decl->p,
- parent_def_scope, 0, 0),
- struct definition_struct, p);
- set_dynamic_definition_scope(&trace->packet_header->p,
- trace->packet_header->scope,
- "trace.packet.header");
+ parent_def_scope, 0, 0, "trace.packet.header");
+ if (!definition) {
+ ret = -EINVAL;
+ goto error;
+ }
+ trace->packet_header =
+ container_of(definition, struct definition_struct, p);
parent_def_scope = trace->packet_header->scope;
- declaration_unref(&trace->packet_header_decl->p);
}
trace->definition_scope = parent_def_scope;
|| struct_declaration_lookup_field_index(trace->packet_header_decl, g_quark_from_static_string("magic")) < 0) {
ret = -EPERM;
fprintf(fd, "[error] %s: missing both byte_order and packet header magic number in trace declaration\n", __func__);
- goto error_free_def;
+ goto error;
}
}
return 0;
-error_free_def:
- definition_unref(&trace->packet_header->p);
error:
+ if (trace->packet_header)
+ definition_unref(&trace->packet_header->p);
+ if (trace->packet_header_decl)
+ declaration_unref(&trace->packet_header_decl->p);
g_ptr_array_free(trace->streams, TRUE);
free_declaration_scope(trace->declaration_scope);
return ret;
depth++;
- if (!cds_list_empty(&node->u.type_declarator.pointers)) {
- cds_list_for_each_entry(iter, &node->u.type_declarator.pointers,
- siblings) {
- iter->parent = node;
- ret = ctf_visitor_parent_links(fd, depth + 1, iter);
- if (ret)
- return ret;
- }
+ cds_list_for_each_entry(iter, &node->u.type_declarator.pointers,
+ siblings) {
+ iter->parent = node;
+ ret = ctf_visitor_parent_links(fd, depth + 1, iter);
+ if (ret)
+ return ret;
}
switch (node->u.type_declarator.type) {
if (ret)
return ret;
}
- if (node->u.type_declarator.u.nested.length) {
- node->u.type_declarator.u.nested.length->parent = node;
- ret = ctf_visitor_parent_links(fd, depth + 1, node->u.type_declarator.u.nested.length);
+ cds_list_for_each_entry(iter, &node->u.type_declarator.u.nested.length,
+ siblings) {
+ iter->parent = node;
+ ret = ctf_visitor_parent_links(fd, depth + 1, iter);
if (ret)
return ret;
}
*/
switch (node->u.unary_expression.type) {
case UNARY_UNSIGNED_CONSTANT:
+ case UNARY_STRING:
break;
default:
- fprintf(fd, "[error]: semantic error (children of type declarator and enum can only be unsigned numeric constants)\n");
+ fprintf(fd, "[error]: semantic error (children of type declarator and enum can only be unsigned numeric constants or references to fields (a.b.c))\n");
goto errperm;
}
break; /* OK */
goto errinval;
}
- if (!cds_list_empty(&node->u.type_declarator.pointers)) {
- cds_list_for_each_entry(iter, &node->u.type_declarator.pointers,
- siblings) {
- ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
- if (ret)
- return ret;
- }
+ cds_list_for_each_entry(iter, &node->u.type_declarator.pointers,
+ siblings) {
+ ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
+ if (ret)
+ return ret;
}
switch (node->u.type_declarator.type) {
if (ret)
return ret;
}
- ret = _ctf_visitor_semantic_check(fd, depth + 1,
- node->u.type_declarator.u.nested.length);
- if (ret)
- return ret;
+ cds_list_for_each_entry(iter, &node->u.type_declarator.u.nested.length,
+ siblings) {
+ if (iter->type != NODE_UNARY_EXPRESSION) {
+ fprintf(fd, "[error] %s: expecting unary expression as length\n", __func__);
+ return -EINVAL;
+ }
+ ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
+ if (ret)
+ return ret;
+ }
if (node->u.type_declarator.bitfield_len) {
ret = _ctf_visitor_semantic_check(fd, depth + 1,
node->u.type_declarator.bitfield_len);
print_tabs(fd, depth);
fprintf(fd, "</type_declarator>\n");
}
- if (node->u.type_declarator.u.nested.length) {
+ if (!cds_list_empty(&node->u.type_declarator.u.nested.length)) {
print_tabs(fd, depth);
fprintf(fd, "<length>\n");
- ret = ctf_visitor_print_xml(fd, depth + 1, node->u.type_declarator.u.nested.length);
- if (ret)
- return ret;
+ cds_list_for_each_entry(iter, &node->u.type_declarator.u.nested.length,
+ siblings) {
+ ret = ctf_visitor_print_xml(fd, depth + 1, iter);
+ if (ret)
+ return ret;
+ }
print_tabs(fd, depth);
fprintf(fd, "</length>\n");
}
union ldoubleIEEE754 u;
struct definition *tmpdef =
static_ldouble_declaration->p.definition_new(&static_ldouble_declaration->p,
- NULL, 0, 0);
+ NULL, 0, 0, NULL);
struct definition_float *tmpfloat =
container_of(tmpdef, struct definition_float, p);
struct ctf_stream_pos destp;
union ldoubleIEEE754 u;
struct definition *tmpdef =
static_ldouble_declaration->p.definition_new(&static_ldouble_declaration->p,
- NULL, 0, 0);
+ NULL, 0, 0, NULL);
struct definition_float *tmpfloat =
container_of(tmpdef, struct definition_float, p);
struct ctf_stream_pos srcp;
struct definition *
(*definition_new)(struct declaration *declaration,
struct definition_scope *parent_scope,
- GQuark field_name, int index);
+ GQuark field_name, int index,
+ const char *root_name);
/*
* definition_free called with definition ref is decremented to 0.
*/
struct definition_integer *sign;
struct definition_integer *mantissa;
struct definition_integer *exp;
+ struct definition_scope *scope;
/* Last values read */
long double value;
};
struct definition p;
struct definition_integer *integer;
struct declaration_enum *declaration;
+ struct definition_scope *scope;
/* Last GQuark values read. Keeping a reference on the GQuark array. */
GArray *value;
};
struct declaration_sequence {
struct declaration p;
- struct declaration_integer *len_declaration;
+ GArray *length_name; /* Array of GQuark */
struct declaration *elem;
struct declaration_scope *scope;
};
struct definition p;
struct declaration_sequence *declaration;
struct definition_scope *scope;
- struct definition_integer *len;
+ struct definition_integer *length;
GPtrArray *elems; /* Array of pointers to struct definition */
};
struct definition_scope *scope);
struct definition_scope *
new_definition_scope(struct definition_scope *parent_scope,
- GQuark field_name);
-void set_dynamic_definition_scope(struct definition *definition,
- struct definition_scope *scope,
- const char *root_name);
+ GQuark field_name, const char *root_name);
void free_definition_scope(struct definition_scope *scope);
-GQuark new_definition_path(struct definition_scope *parent_scope, GQuark field_name);
+GQuark new_definition_path(struct definition_scope *parent_scope,
+ GQuark field_name, const char *root_name);
static inline
int compare_definition_path(struct definition *definition, GQuark path)
* to the sequence. No need to free them explicitly.
*/
struct declaration_sequence *
- sequence_declaration_new(struct declaration_integer *len_declaration,
+ sequence_declaration_new(const char *length_name,
struct declaration *elem_declaration,
struct declaration_scope *parent_scope);
uint64_t sequence_len(struct definition_sequence *sequence);
static
struct definition *_array_definition_new(struct declaration *declaration,
struct definition_scope *parent_scope,
- GQuark field_name, int index);
+ GQuark field_name, int index, const char *root_name);
static
void _array_definition_free(struct definition *definition);
struct definition *
_array_definition_new(struct declaration *declaration,
struct definition_scope *parent_scope,
- GQuark field_name, int index)
+ GQuark field_name, int index, const char *root_name)
{
struct declaration_array *array_declaration =
container_of(declaration, struct declaration_array, p);
struct definition_array *array;
- uint64_t i;
+ int ret;
+ int i;
array = g_new(struct definition_array, 1);
declaration_ref(&array_declaration->p);
array->p.declaration = declaration;
array->declaration = array_declaration;
array->p.ref = 1;
- array->p.index = index;
+ /*
+ * Use INT_MAX order to ensure that all fields of the parent
+ * scope are seen as being prior to this scope.
+ */
+ array->p.index = root_name ? INT_MAX : index;
array->p.name = field_name;
- array->p.path = new_definition_path(parent_scope, field_name);
- array->scope = new_definition_scope(parent_scope, field_name);
+ array->p.path = new_definition_path(parent_scope, field_name, root_name);
+ array->scope = new_definition_scope(parent_scope, field_name, root_name);
+ ret = register_field_definition(field_name, &array->p,
+ parent_scope);
+ assert(!ret);
array->elems = g_ptr_array_sized_new(array_declaration->len);
g_ptr_array_set_size(array->elems, array_declaration->len);
for (i = 0; i < array_declaration->len; i++) {
GQuark name;
str = g_string_new("");
- g_string_printf(str, "[%" PRIu64 "]", i);
+ g_string_printf(str, "[%u]", (unsigned int) i);
name = g_quark_from_string(str->str);
(void) g_string_free(str, TRUE);
field = (struct definition **) &g_ptr_array_index(array->elems, i);
*field = array_declaration->elem->definition_new(array_declaration->elem,
array->scope,
- name, i);
+ name, i, NULL);
+ if (!*field)
+ goto error;
}
return &array->p;
+
+error:
+ for (i--; i >= 0; i--) {
+ struct definition *field;
+
+ field = g_ptr_array_index(array->elems, i);
+ field->declaration->definition_free(field);
+ }
+ (void) g_ptr_array_free(array->elems, TRUE);
+ free_definition_scope(array->scope);
+ declaration_unref(array->p.declaration);
+ g_free(array);
+ return NULL;
}
static
static
struct definition *_enum_definition_new(struct declaration *declaration,
struct definition_scope *parent_scope,
- GQuark field_name, int index);
+ GQuark field_name, int index,
+ const char *root_name);
static
void _enum_definition_free(struct definition *definition);
struct definition *
_enum_definition_new(struct declaration *declaration,
struct definition_scope *parent_scope,
- GQuark field_name, int index)
+ GQuark field_name, int index,
+ const char *root_name)
{
struct declaration_enum *enum_declaration =
container_of(declaration, struct declaration_enum, p);
struct definition_enum *_enum;
struct definition *definition_integer_parent;
+ int ret;
_enum = g_new(struct definition_enum, 1);
declaration_ref(&enum_declaration->p);
_enum->p.declaration = declaration;
_enum->declaration = enum_declaration;
_enum->p.ref = 1;
- _enum->p.index = index;
+ /*
+ * Use INT_MAX order to ensure that all fields of the parent
+ * scope are seen as being prior to this scope.
+ */
+ _enum->p.index = root_name ? INT_MAX : index;
_enum->p.name = field_name;
- _enum->p.path = new_definition_path(parent_scope, field_name);
+ _enum->p.path = new_definition_path(parent_scope, field_name, root_name);
+ _enum->scope = new_definition_scope(parent_scope, field_name, root_name);
_enum->value = NULL;
+ ret = register_field_definition(field_name, &_enum->p,
+ parent_scope);
+ assert(!ret);
definition_integer_parent =
enum_declaration->integer_declaration->p.definition_new(&enum_declaration->integer_declaration->p,
- parent_scope,
- g_quark_from_static_string("container"), 0);
+ _enum->scope,
+ g_quark_from_static_string("container"), 0, NULL);
_enum->integer = container_of(definition_integer_parent,
struct definition_integer, p);
return &_enum->p;
static
struct definition *_float_definition_new(struct declaration *declaration,
struct definition_scope *parent_scope,
- GQuark field_name, int index);
+ GQuark field_name, int index,
+ const char *root_name);
static
void _float_definition_free(struct definition *definition);
struct definition *
_float_definition_new(struct declaration *declaration,
struct definition_scope *parent_scope,
- GQuark field_name, int index)
+ GQuark field_name, int index,
+ const char *root_name)
{
struct declaration_float *float_declaration =
container_of(declaration, struct declaration_float, p);
struct definition_float *_float;
struct definition *tmp;
+ int ret;
_float = g_new(struct definition_float, 1);
declaration_ref(&float_declaration->p);
_float->p.declaration = declaration;
_float->declaration = float_declaration;
+ _float->scope = new_definition_scope(parent_scope, field_name, root_name);
+ _float->p.path = new_definition_path(parent_scope, field_name, root_name);
if (float_declaration->byte_order == LITTLE_ENDIAN) {
tmp = float_declaration->mantissa->p.definition_new(&float_declaration->mantissa->p,
- parent_scope, g_quark_from_static_string("mantissa"), 0);
+ _float->scope, g_quark_from_static_string("mantissa"), 0, NULL);
_float->mantissa = container_of(tmp, struct definition_integer, p);
tmp = float_declaration->exp->p.definition_new(&float_declaration->exp->p,
- parent_scope, g_quark_from_static_string("exp"), 1);
+ _float->scope, g_quark_from_static_string("exp"), 1, NULL);
_float->exp = container_of(tmp, struct definition_integer, p);
tmp = float_declaration->sign->p.definition_new(&float_declaration->sign->p,
- parent_scope, g_quark_from_static_string("sign"), 2);
+ _float->scope, g_quark_from_static_string("sign"), 2, NULL);
_float->sign = container_of(tmp, struct definition_integer, p);
} else {
tmp = float_declaration->sign->p.definition_new(&float_declaration->sign->p,
- parent_scope, g_quark_from_static_string("sign"), 0);
+ _float->scope, g_quark_from_static_string("sign"), 0, NULL);
_float->sign = container_of(tmp, struct definition_integer, p);
tmp = float_declaration->exp->p.definition_new(&float_declaration->exp->p,
- parent_scope, g_quark_from_static_string("exp"), 1);
+ _float->scope, g_quark_from_static_string("exp"), 1, NULL);
_float->exp = container_of(tmp, struct definition_integer, p);
tmp = float_declaration->mantissa->p.definition_new(&float_declaration->mantissa->p,
- parent_scope, g_quark_from_static_string("mantissa"), 2);
+ _float->scope, g_quark_from_static_string("mantissa"), 2, NULL);
_float->mantissa = container_of(tmp, struct definition_integer, p);
}
_float->p.ref = 1;
- _float->p.index = index;
+ /*
+ * Use INT_MAX order to ensure that all fields of the parent
+ * scope are seen as being prior to this scope.
+ */
+ _float->p.index = root_name ? INT_MAX : index;
_float->p.name = field_name;
- _float->p.path = new_definition_path(parent_scope, field_name);
_float->value = 0.0;
+ ret = register_field_definition(field_name, &_float->p,
+ parent_scope);
+ assert(!ret);
return &_float->p;
}
static
struct definition *_integer_definition_new(struct declaration *declaration,
struct definition_scope *parent_scope,
- GQuark field_name, int index);
+ GQuark field_name, int index,
+ const char *root_name);
static
void _integer_definition_free(struct definition *definition);
struct definition *
_integer_definition_new(struct declaration *declaration,
struct definition_scope *parent_scope,
- GQuark field_name, int index)
+ GQuark field_name, int index,
+ const char *root_name)
{
struct declaration_integer *integer_declaration =
container_of(declaration, struct declaration_integer, p);
struct definition_integer *integer;
+ int ret;
integer = g_new(struct definition_integer, 1);
declaration_ref(&integer_declaration->p);
integer->p.declaration = declaration;
integer->declaration = integer_declaration;
integer->p.ref = 1;
- integer->p.index = index;
+ /*
+ * Use INT_MAX order to ensure that all fields of the parent
+ * scope are seen as being prior to this scope.
+ */
+ integer->p.index = root_name ? INT_MAX : index;
integer->p.name = field_name;
- integer->p.path = new_definition_path(parent_scope, field_name);
+ integer->p.path = new_definition_path(parent_scope, field_name,
+ root_name);
integer->value._unsigned = 0;
+ ret = register_field_definition(field_name, &integer->p,
+ parent_scope);
+ assert(!ret);
return &integer->p;
}
#include <babeltrace/format.h>
#include <inttypes.h>
-#ifndef max
-#define max(a, b) ((a) < (b) ? (b) : (a))
-#endif
-
static
struct definition *_sequence_definition_new(struct declaration *declaration,
struct definition_scope *parent_scope,
- GQuark field_name, int index);
+ GQuark field_name, int index,
+ const char *root_name);
static
void _sequence_definition_free(struct definition *definition);
uint64_t len, oldlen, i;
int ret;
- ret = generic_rw(pos, &sequence_definition->len->p);
- if (ret)
- return ret;
- len = sequence_definition->len->value._unsigned;
+ len = sequence_definition->length->value._unsigned;
/*
* Yes, large sequences could be _painfully slow_ to parse due
* to memory allocation for each event read. At least, never
field = (struct definition **) &g_ptr_array_index(sequence_definition->elems, i);
*field = sequence_declaration->elem->definition_new(sequence_declaration->elem,
sequence_definition->scope,
- name, i);
+ name, i, NULL);
ret = generic_rw(pos, *field);
if (ret)
return ret;
container_of(declaration, struct declaration_sequence, p);
free_declaration_scope(sequence_declaration->scope);
- declaration_unref(&sequence_declaration->len_declaration->p);
+ g_array_free(sequence_declaration->length_name, TRUE);
declaration_unref(sequence_declaration->elem);
g_free(sequence_declaration);
}
struct declaration_sequence *
- sequence_declaration_new(struct declaration_integer *len_declaration,
+ sequence_declaration_new(const char *length,
struct declaration *elem_declaration,
struct declaration_scope *parent_scope)
{
sequence_declaration = g_new(struct declaration_sequence, 1);
declaration = &sequence_declaration->p;
- assert(!len_declaration->signedness);
- declaration_ref(&len_declaration->p);
- sequence_declaration->len_declaration = len_declaration;
+
+ sequence_declaration->length_name = g_array_new(FALSE, TRUE, sizeof(GQuark));
+ append_scope_path(length, sequence_declaration->length_name);
+
declaration_ref(elem_declaration);
sequence_declaration->elem = elem_declaration;
sequence_declaration->scope = new_declaration_scope(parent_scope);
declaration->id = CTF_TYPE_SEQUENCE;
- declaration->alignment = max(len_declaration->p.alignment, elem_declaration->alignment);
+ declaration->alignment = elem_declaration->alignment;
declaration->declaration_free = _sequence_declaration_free;
declaration->definition_new = _sequence_definition_new;
declaration->definition_free = _sequence_definition_free;
static
struct definition *_sequence_definition_new(struct declaration *declaration,
struct definition_scope *parent_scope,
- GQuark field_name, int index)
+ GQuark field_name, int index,
+ const char *root_name)
{
struct declaration_sequence *sequence_declaration =
container_of(declaration, struct declaration_sequence, p);
struct definition_sequence *sequence;
struct definition *len_parent;
+ int ret;
sequence = g_new(struct definition_sequence, 1);
declaration_ref(&sequence_declaration->p);
sequence->p.declaration = declaration;
sequence->declaration = sequence_declaration;
sequence->p.ref = 1;
- sequence->p.index = index;
+ /*
+ * Use INT_MAX order to ensure that all fields of the parent
+ * scope are seen as being prior to this scope.
+ */
+ sequence->p.index = root_name ? INT_MAX : index;
sequence->p.name = field_name;
- sequence->p.path = new_definition_path(parent_scope, field_name);
- sequence->scope = new_definition_scope(parent_scope, field_name);
- len_parent = sequence_declaration->len_declaration->p.definition_new(&sequence_declaration->len_declaration->p,
- sequence->scope,
- g_quark_from_static_string("length"), 0);
- sequence->len =
+ sequence->p.path = new_definition_path(parent_scope, field_name, root_name);
+ sequence->scope = new_definition_scope(parent_scope, field_name, root_name);
+ ret = register_field_definition(field_name, &sequence->p,
+ parent_scope);
+ assert(!ret);
+ len_parent = lookup_definition(sequence->scope->scope_path,
+ sequence_declaration->length_name,
+ parent_scope);
+ if (!len_parent) {
+ printf("[error] Lookup for sequence length field failed.\n");
+ goto error;
+ }
+ sequence->length =
container_of(len_parent, struct definition_integer, p);
+ if (sequence->length->declaration->signedness) {
+ printf("[error] Sequence length field should be unsigned.\n");
+ goto error;
+ }
+ definition_ref(len_parent);
sequence->elems = g_ptr_array_new();
return &sequence->p;
+
+error:
+ free_definition_scope(sequence->scope);
+ declaration_unref(&sequence_declaration->p);
+ g_free(sequence);
+ return NULL;
}
static
{
struct definition_sequence *sequence =
container_of(definition, struct definition_sequence, p);
- struct definition *len_definition = &sequence->len->p;
+ struct definition *len_definition = &sequence->length->p;
uint64_t i;
for (i = 0; i < sequence->elems->len; i++) {
field->declaration->definition_free(field);
}
(void) g_ptr_array_free(sequence->elems, TRUE);
- len_definition->declaration->definition_free(len_definition);
+ definition_unref(len_definition);
free_definition_scope(sequence->scope);
declaration_unref(sequence->p.declaration);
g_free(sequence);
uint64_t sequence_len(struct definition_sequence *sequence)
{
- return sequence->len->value._unsigned;
+ return sequence->length->value._unsigned;
}
struct definition *sequence_index(struct definition_sequence *sequence, uint64_t i)
{
- if (i >= sequence->len->value._unsigned)
+ if (i >= sequence->length->value._unsigned)
return NULL;
assert(i < sequence->elems->len);
return g_ptr_array_index(sequence->elems, i);
static
struct definition *_string_definition_new(struct declaration *declaration,
struct definition_scope *parent_scope,
- GQuark field_name, int index);
+ GQuark field_name, int index,
+ const char *root_name);
static
void _string_definition_free(struct definition *definition);
struct definition *
_string_definition_new(struct declaration *declaration,
struct definition_scope *parent_scope,
- GQuark field_name, int index)
+ GQuark field_name, int index,
+ const char *root_name)
{
struct declaration_string *string_declaration =
container_of(declaration, struct declaration_string, p);
struct definition_string *string;
+ int ret;
string = g_new(struct definition_string, 1);
declaration_ref(&string_declaration->p);
string->p.declaration = declaration;
string->declaration = string_declaration;
string->p.ref = 1;
- string->p.index = index;
+ /*
+ * Use INT_MAX order to ensure that all fields of the parent
+ * scope are seen as being prior to this scope.
+ */
+ string->p.index = root_name ? INT_MAX : index;
string->p.name = field_name;
- string->p.path = new_definition_path(parent_scope, field_name);
+ string->p.path = new_definition_path(parent_scope, field_name,
+ root_name);
string->value = NULL;
string->len = 0;
string->alloc_len = 0;
+ ret = register_field_definition(field_name, &string->p,
+ parent_scope);
+ assert(!ret);
return &string->p;
}
#include <babeltrace/compiler.h>
#include <babeltrace/format.h>
+#include <errno.h>
#ifndef max
#define max(a, b) ((a) < (b) ? (b) : (a))
static
struct definition *_struct_definition_new(struct declaration *declaration,
struct definition_scope *parent_scope,
- GQuark field_name, int index);
+ GQuark field_name, int index,
+ const char *root_name);
static
void _struct_definition_free(struct definition *definition);
struct definition *
_struct_definition_new(struct declaration *declaration,
struct definition_scope *parent_scope,
- GQuark field_name, int index)
+ GQuark field_name, int index,
+ const char *root_name)
{
struct declaration_struct *struct_declaration =
container_of(declaration, struct declaration_struct, p);
struct definition_struct *_struct;
- unsigned long i;
+ int i;
int ret;
_struct = g_new(struct definition_struct, 1);
_struct->p.declaration = declaration;
_struct->declaration = struct_declaration;
_struct->p.ref = 1;
- _struct->p.index = index;
+ /*
+ * Use INT_MAX order to ensure that all fields of the parent
+ * scope are seen as being prior to this scope.
+ */
+ _struct->p.index = root_name ? INT_MAX : index;
_struct->p.name = field_name;
- _struct->p.path = new_definition_path(parent_scope, field_name);
- _struct->scope = new_definition_scope(parent_scope, field_name);
+ _struct->p.path = new_definition_path(parent_scope, field_name, root_name);
+ _struct->scope = new_definition_scope(parent_scope, field_name, root_name);
+
+ ret = register_field_definition(field_name, &_struct->p,
+ parent_scope);
+ assert(!ret || ret == -EPERM);
+
_struct->fields = g_ptr_array_sized_new(DEFAULT_NR_STRUCT_FIELDS);
g_ptr_array_set_size(_struct->fields, struct_declaration->fields->len);
for (i = 0; i < struct_declaration->fields->len; i++) {
*field = declaration_field->declaration->definition_new(declaration_field->declaration,
_struct->scope,
- declaration_field->name, i);
- ret = register_field_definition(declaration_field->name,
- *field,
- _struct->scope);
- assert(!ret);
+ declaration_field->name, i, NULL);
+ if (!*field)
+ goto error;
}
return &_struct->p;
+
+error:
+ for (i--; i >= 0; i--) {
+ struct definition *field = g_ptr_array_index(_struct->fields, i);
+ definition_unref(field);
+ }
+ free_definition_scope(_struct->scope);
+ declaration_unref(&struct_declaration->p);
+ g_free(_struct);
+ return NULL;
}
static
*/
#include <babeltrace/format.h>
+#include <babeltrace/babeltrace.h>
#include <limits.h>
#include <glib.h>
#include <errno.h>
static int is_path_child_of(GArray *path, GArray *maybe_parent)
{
- if (path->len <= maybe_parent->len)
- return 0;
+ int i, ret;
+
+ if (babeltrace_debug) {
+ int need_dot = 0;
+
+ printf_debug("Is path \"");
+ for (i = 0; i < path->len; need_dot = 1, i++)
+ printf("%s%s", need_dot ? "." : "",
+ g_quark_to_string(g_array_index(path, GQuark, i)));
+ need_dot = 0;
+ printf("\" child of \"");
+ for (i = 0; i < maybe_parent->len; need_dot = 1, i++)
+ printf("%s%s", need_dot ? "." : "",
+ g_quark_to_string(g_array_index(maybe_parent, GQuark, i)));
+ printf("\" ? ");
+ }
+
+ if (path->len <= maybe_parent->len) {
+ ret = 0;
+ goto end;
+ }
if (compare_paths(path, maybe_parent, maybe_parent->len)
== maybe_parent->len)
- return 1;
+ ret = 1;
else
- return 0;
+ ret = 0;
+end:
+ if (babeltrace_debug)
+ printf("%s\n", ret ? "Yes" : "No");
+ return ret;
}
static struct definition_scope *
GQuark last;
int index;
- while (scope) {
- /* going up in the hierarchy. Check where we come from. */
- assert(is_path_child_of(cur_path, scope->scope_path));
- assert(cur_path->len - scope->scope_path->len == 1);
+ /* Going up in the hierarchy. Check where we come from. */
+ assert(is_path_child_of(cur_path, scope->scope_path));
+ assert(cur_path->len - scope->scope_path->len == 1);
+
+ /*
+ * First, check if the target name is size one, present in
+ * our parent path, located prior to us.
+ */
+ if (lookup_path->len == 1) {
+ last = g_array_index(lookup_path, GQuark, 0);
+ lookup_definition = lookup_field_definition_scope(last, scope);
last = g_array_index(cur_path, GQuark, cur_path->len - 1);
definition = lookup_field_definition_scope(last, scope);
assert(definition);
- index = definition->index;
+ if (lookup_definition && lookup_definition->index < definition->index)
+ return lookup_definition;
+ else
+ return NULL;
+ }
+
+ while (scope) {
+ if (is_path_child_of(cur_path, scope->scope_path) &&
+ cur_path->len - scope->scope_path->len == 1) {
+ last = g_array_index(cur_path, GQuark, cur_path->len - 1);
+ definition = lookup_field_definition_scope(last, scope);
+ assert(definition);
+ index = definition->index;
+ } else {
+ /*
+ * Getting to a dynamic scope parent. We are
+ * guaranteed that the parent is entirely
+ * located before the child.
+ */
+ index = -1;
+ }
lookup:
if (is_path_child_of(lookup_path, scope->scope_path)) {
/* Means we can lookup the field in this scope */
goto lookup;
}
} else {
- assert(index != -1);
/* lookup_path is within an upper scope */
cur_path = scope->scope_path;
scope = scope->parent_scope;
int register_field_definition(GQuark field_name, struct definition *definition,
struct definition_scope *scope)
{
- if (!field_name)
+ if (!scope || !field_name)
return -EPERM;
/* Only lookup in local scope */
g_hash_table_insert(scope->definitions,
(gpointer) (unsigned long) field_name,
definition);
- definition_ref(definition);
+ /* Don't keep reference on definition */
return 0;
}
{
struct definition_scope *scope = g_new(struct definition_scope, 1);
- scope->definitions = g_hash_table_new_full(g_direct_hash,
- g_direct_equal, NULL,
- (GDestroyNotify) definition_unref);
+ scope->definitions = g_hash_table_new(g_direct_hash,
+ g_direct_equal);
scope->parent_scope = parent_scope;
scope->scope_path = g_array_sized_new(FALSE, TRUE, sizeof(GQuark),
scope_path_len);
return scope;
}
-GQuark new_definition_path(struct definition_scope *parent_scope, GQuark field_name)
+GQuark new_definition_path(struct definition_scope *parent_scope,
+ GQuark field_name, const char *root_name)
{
GQuark path;
GString *str;
gchar *c_str;
int i;
+ int need_dot = 0;
str = g_string_new("");
- if (parent_scope) {
+ if (root_name) {
+ g_string_append(str, root_name);
+ need_dot = 1;
+ } else if (parent_scope) {
for (i = 0; i < parent_scope->scope_path->len; i++) {
GQuark q = g_array_index(parent_scope->scope_path,
GQuark, i);
if (!q)
continue;
+ if (need_dot)
+ g_string_append(str, ".");
g_string_append(str, g_quark_to_string(q));
- g_string_append(str, ".");
+ need_dot = 1;
}
}
- if (field_name)
+ if (field_name) {
+ if (need_dot)
+ g_string_append(str, ".");
g_string_append(str, g_quark_to_string(field_name));
+ }
c_str = g_string_free(str, FALSE);
if (c_str[0] == '\0')
return 0;
path = g_quark_from_string(c_str);
+ printf_debug("new definition path: %s\n", c_str);
g_free(c_str);
return path;
}
struct definition_scope *
new_definition_scope(struct definition_scope *parent_scope,
- GQuark field_name)
+ GQuark field_name, const char *root_name)
{
struct definition_scope *scope;
- int scope_path_len = 1;
- if (parent_scope)
+ if (root_name) {
+ scope = _new_definition_scope(parent_scope, 0);
+ append_scope_path(root_name, scope->scope_path);
+ } else {
+ int scope_path_len = 1;
+
+ assert(parent_scope);
scope_path_len += parent_scope->scope_path->len;
- scope = _new_definition_scope(parent_scope, scope_path_len);
- if (parent_scope)
- memcpy(scope->scope_path, parent_scope->scope_path,
+ scope = _new_definition_scope(parent_scope, scope_path_len);
+ memcpy(scope->scope_path->data, parent_scope->scope_path->data,
sizeof(GQuark) * (scope_path_len - 1));
- g_array_index(scope->scope_path, GQuark, scope_path_len - 1) =
- field_name;
+ g_array_index(scope->scope_path, GQuark, scope_path_len - 1) =
+ field_name;
+ }
+ if (babeltrace_debug) {
+ int i, need_dot = 0;
+
+ printf_debug("new definition scope: ");
+ for (i = 0; i < scope->scope_path->len; need_dot = 1, i++)
+ printf("%s%s", need_dot ? "." : "",
+ g_quark_to_string(g_array_index(scope->scope_path, GQuark, i)));
+ printf("\n");
+ }
return scope;
}
}
}
-void set_dynamic_definition_scope(struct definition *definition,
- struct definition_scope *scope,
- const char *root_name)
-{
- g_array_set_size(scope->scope_path, 0);
- append_scope_path(root_name, scope->scope_path);
- /*
- * Use INT_MAX order to ensure that all fields of the parent
- * scope are seen as being prior to this scope.
- */
- definition->index = INT_MAX;
-}
-
void free_definition_scope(struct definition_scope *scope)
{
g_array_free(scope->scope_path, TRUE);
static
struct definition *_variant_definition_new(struct declaration *declaration,
struct definition_scope *parent_scope,
- GQuark field_name, int index);
+ GQuark field_name, int index,
+ const char *root_name);
static
void _variant_definition_free(struct definition *definition);
struct definition *
_variant_definition_new(struct declaration *declaration,
struct definition_scope *parent_scope,
- GQuark field_name, int index)
+ GQuark field_name, int index,
+ const char *root_name)
{
struct declaration_variant *variant_declaration =
container_of(declaration, struct declaration_variant, p);
struct definition_variant *variant;
unsigned long i;
+ int ret;
variant = g_new(struct definition_variant, 1);
declaration_ref(&variant_declaration->p);
variant->p.declaration = declaration;
variant->declaration = variant_declaration;
variant->p.ref = 1;
- variant->p.index = index;
+ /*
+ * Use INT_MAX order to ensure that all fields of the parent
+ * scope are seen as being prior to this scope.
+ */
+ variant->p.index = root_name ? INT_MAX : index;
variant->p.name = field_name;
- variant->p.path = new_definition_path(parent_scope, field_name);
- variant->scope = new_definition_scope(parent_scope, field_name);
+ variant->p.path = new_definition_path(parent_scope, field_name, root_name);
+ variant->scope = new_definition_scope(parent_scope, field_name, root_name);
+
+ ret = register_field_definition(field_name, &variant->p,
+ parent_scope);
+ assert(!ret);
+
variant->enum_tag = lookup_definition(variant->scope->scope_path,
variant_declaration->tag_name,
parent_scope);
*/
*field = declaration_field->declaration->definition_new(declaration_field->declaration,
variant->scope,
- declaration_field->name, 0);
+ declaration_field->name, 0, NULL);
+ if (!*field)
+ goto error;
}
variant->current_field = NULL;
return &variant->p;