From: Mathieu Desnoyers Date: Wed, 18 May 2011 21:47:56 +0000 (-0400) Subject: CTF: Add support for event headers using variants X-Git-Tag: v0.1~42 X-Git-Url: http://git.efficios.com/?p=babeltrace.git;a=commitdiff_plain;h=a35173fe7e72fe456cbd19db34a5ff7a09a0c7ff CTF: Add support for event headers using variants Signed-off-by: Mathieu Desnoyers --- diff --git a/formats/ctf/ctf.c b/formats/ctf/ctf.c index 1ba00a67..13232692 100644 --- a/formats/ctf/ctf.c +++ b/formats/ctf/ctf.c @@ -93,7 +93,6 @@ int ctf_read_event(struct stream_pos *ppos, struct ctf_stream *stream) struct ctf_stream_class *stream_class = stream->stream_class; struct ctf_event *event_class; uint64_t id = 0; - int len_index; int ret; if (pos->offset == EOF) @@ -101,38 +100,43 @@ int ctf_read_event(struct stream_pos *ppos, struct ctf_stream *stream) /* Read event header */ if (stream_class->event_header) { + struct definition_integer *integer_definition; + ret = generic_rw(ppos, &stream_class->event_header->p); if (ret) goto error; /* lookup event id */ - len_index = struct_declaration_lookup_field_index(stream_class->event_header_decl, - g_quark_from_static_string("id")); - if (len_index >= 0) { - struct definition_integer *defint; - struct definition *field; + integer_definition = lookup_integer(&stream_class->event_header->p, "id", FALSE); + if (integer_definition) { + id = integer_definition->value._unsigned; + } else { + struct definition_enum *enum_definition; - field = struct_definition_get_field_from_index(stream_class->event_header, len_index); - assert(field->declaration->id == CTF_TYPE_INTEGER); - defint = container_of(field, struct definition_integer, p); - assert(defint->declaration->signedness == FALSE); - id = defint->value._unsigned; /* set id */ + enum_definition = lookup_enum(&stream_class->event_header->p, "id", FALSE); + if (enum_definition) { + id = enum_definition->integer->value._unsigned; + } } /* lookup timestamp */ - len_index = struct_declaration_lookup_field_index(stream_class->event_header_decl, - g_quark_from_static_string("timestamp")); - if (len_index >= 0) { - struct definition_integer *defint; - struct definition *field; + integer_definition = lookup_integer(&stream_class->event_header->p, "timestamp", FALSE); + if (integer_definition) { + stream->timestamp = integer_definition->value._unsigned; + } else { + struct definition *definition; - field = struct_definition_get_field_from_index(stream_class->event_header, len_index); - assert(field->declaration->id == CTF_TYPE_INTEGER); - defint = container_of(field, struct definition_integer, p); - assert(defint->declaration->signedness == FALSE); - /* update timestamp */ - stream->timestamp = defint->value._unsigned; + definition = lookup_variant(&stream_class->event_header->p, "v"); + if (definition) { + integer_definition = lookup_integer(definition, "id", FALSE); + if (integer_definition) { + id = integer_definition->value._unsigned; + } + integer_definition = lookup_integer(definition, "timestamp", FALSE); + if (integer_definition) { + stream->timestamp = integer_definition->value._unsigned; + } + } } - } /* Read stream-declared event context */ diff --git a/formats/ctf/metadata/ctf-visitor-generate-io-struct.c b/formats/ctf/metadata/ctf-visitor-generate-io-struct.c index 29068563..09ce1847 100644 --- a/formats/ctf/metadata/ctf-visitor-generate-io-struct.c +++ b/formats/ctf/metadata/ctf-visitor-generate-io-struct.c @@ -1605,7 +1605,7 @@ int ctf_event_visit(FILE *fd, int depth, struct ctf_node *node, } event->context = container_of(definition, struct definition_struct, p); - parent_def_scope = event->context->scope; + parent_def_scope = event->context->p.scope; } if (event->fields_decl) { struct definition *definition = @@ -1617,7 +1617,7 @@ int ctf_event_visit(FILE *fd, int depth, struct ctf_node *node, } event->fields = container_of(definition, struct definition_struct, p); - parent_def_scope = event->fields->scope; + parent_def_scope = event->fields->p.scope; } return 0; @@ -1811,7 +1811,7 @@ int ctf_stream_visit(FILE *fd, int depth, struct ctf_node *node, } stream->packet_context = container_of(definition, struct definition_struct, p); - parent_def_scope = stream->packet_context->scope; + parent_def_scope = stream->packet_context->p.scope; } if (stream->event_header_decl) { struct definition *definition = @@ -1823,7 +1823,7 @@ int ctf_stream_visit(FILE *fd, int depth, struct ctf_node *node, } stream->event_header = container_of(definition, struct definition_struct, p); - parent_def_scope = stream->event_header->scope; + parent_def_scope = stream->event_header->p.scope; } if (stream->event_context_decl) { struct definition *definition = @@ -1835,7 +1835,7 @@ int ctf_stream_visit(FILE *fd, int depth, struct ctf_node *node, } stream->event_context = container_of(definition, struct definition_struct, p); - parent_def_scope = stream->event_context->scope; + parent_def_scope = stream->event_context->p.scope; } stream->definition_scope = parent_def_scope; @@ -2039,7 +2039,7 @@ int ctf_trace_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace } trace->packet_header = container_of(definition, struct definition_struct, p); - parent_def_scope = trace->packet_header->scope; + parent_def_scope = trace->packet_header->p.scope; } trace->definition_scope = parent_def_scope; diff --git a/include/babeltrace/types.h b/include/babeltrace/types.h index da9ca5c5..cd31a9ef 100644 --- a/include/babeltrace/types.h +++ b/include/babeltrace/types.h @@ -105,6 +105,7 @@ struct definition { GQuark name; /* Field name in its container (or 0 if unset) */ int ref; /* number of references to the definition */ GQuark path; + struct definition_scope *scope; }; typedef int (*rw_dispatch)(struct stream_pos *pos, @@ -175,7 +176,6 @@ struct definition_float { struct definition_integer *sign; struct definition_integer *mantissa; struct definition_integer *exp; - struct definition_scope *scope; /* Last values read */ long double value; }; @@ -228,7 +228,6 @@ struct definition_enum { 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; }; @@ -260,7 +259,6 @@ struct declaration_struct { struct definition_struct { struct definition p; struct declaration_struct *declaration; - struct definition_scope *scope; GPtrArray *fields; /* Array of pointers to struct definition */ }; @@ -281,7 +279,6 @@ struct declaration_variant { struct definition_variant { struct definition p; struct declaration_variant *declaration; - struct definition_scope *scope; struct definition *enum_tag; GPtrArray *fields; /* Array of pointers to struct definition */ struct definition *current_field; /* Last field read */ @@ -297,7 +294,6 @@ struct declaration_array { struct definition_array { struct definition p; struct declaration_array *declaration; - struct definition_scope *scope; GPtrArray *elems; /* Array of pointers to struct definition */ GString *string; /* String for encoded integer children */ }; @@ -312,7 +308,6 @@ struct declaration_sequence { struct definition_sequence { struct definition p; struct declaration_sequence *declaration; - struct definition_scope *scope; struct definition_integer *length; GPtrArray *elems; /* Array of pointers to struct definition */ GString *string; /* String for encoded integer children */ @@ -357,9 +352,9 @@ void free_declaration_scope(struct declaration_scope *scope); * definition scopes. */ struct definition * - lookup_definition(GArray *cur_path, /* array of GQuark */ - GArray *lookup_path, /* array of GQuark */ - struct definition_scope *scope); + lookup_path_definition(GArray *cur_path, /* array of GQuark */ + GArray *lookup_path, /* array of GQuark */ + struct definition_scope *scope); int register_field_definition(GQuark field_name, struct definition *definition, struct definition_scope *scope); @@ -514,4 +509,16 @@ int sequence_rw(struct stream_pos *pos, struct definition *definition); */ void append_scope_path(const char *path, GArray *q); +/* + * Lookup helpers. + */ +struct definition_integer *lookup_integer(struct definition *definition, + const char *field_name, + int signedness); +struct definition_enum *lookup_enum(struct definition *definition, + const char *field_name, + int signedness); +struct definition *lookup_variant(struct definition *definition, + const char *field_name); + #endif /* _BABELTRACE_TYPES_H */ diff --git a/types/array.c b/types/array.c index 6c17299a..4cc1fbaa 100644 --- a/types/array.c +++ b/types/array.c @@ -106,7 +106,7 @@ struct definition * array->p.index = root_name ? INT_MAX : index; array->p.name = 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); + array->p.scope = new_definition_scope(parent_scope, field_name, root_name); ret = register_field_definition(field_name, &array->p, parent_scope); assert(!ret); @@ -143,7 +143,7 @@ struct definition * field = (struct definition **) &g_ptr_array_index(array->elems, i); *field = array_declaration->elem->definition_new(array_declaration->elem, - array->scope, + array->p.scope, name, i, NULL); if (!*field) goto error; @@ -159,7 +159,7 @@ error: field->declaration->definition_free(field); } (void) g_ptr_array_free(array->elems, TRUE); - free_definition_scope(array->scope); + free_definition_scope(array->p.scope); declaration_unref(array->p.declaration); g_free(array); return NULL; @@ -183,7 +183,7 @@ void _array_definition_free(struct definition *definition) } (void) g_ptr_array_free(array->elems, TRUE); } - free_definition_scope(array->scope); + free_definition_scope(array->p.scope); declaration_unref(array->p.declaration); g_free(array); } diff --git a/types/enum.c b/types/enum.c index b60c9c56..1c71f9e6 100644 --- a/types/enum.c +++ b/types/enum.c @@ -418,14 +418,14 @@ struct definition * _enum->p.index = root_name ? INT_MAX : index; _enum->p.name = 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->p.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, - _enum->scope, + _enum->p.scope, g_quark_from_static_string("container"), 0, NULL); _enum->integer = container_of(definition_integer_parent, struct definition_integer, p); @@ -439,6 +439,7 @@ void _enum_definition_free(struct definition *definition) container_of(definition, struct definition_enum, p); definition_unref(&_enum->integer->p); + free_definition_scope(_enum->p.scope); declaration_unref(_enum->p.declaration); if (_enum->value) g_array_unref(_enum->value); diff --git a/types/float.c b/types/float.c index dab8d0da..78270e22 100644 --- a/types/float.c +++ b/types/float.c @@ -86,27 +86,27 @@ struct definition * 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.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, - _float->scope, g_quark_from_static_string("mantissa"), 0, NULL); + _float->p.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, - _float->scope, g_quark_from_static_string("exp"), 1, NULL); + _float->p.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, - _float->scope, g_quark_from_static_string("sign"), 2, NULL); + _float->p.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, - _float->scope, g_quark_from_static_string("sign"), 0, NULL); + _float->p.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, - _float->scope, g_quark_from_static_string("exp"), 1, NULL); + _float->p.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, - _float->scope, g_quark_from_static_string("mantissa"), 2, NULL); + _float->p.scope, g_quark_from_static_string("mantissa"), 2, NULL); _float->mantissa = container_of(tmp, struct definition_integer, p); } _float->p.ref = 1; @@ -132,6 +132,7 @@ void _float_definition_free(struct definition *definition) definition_unref(&_float->sign->p); definition_unref(&_float->exp->p); definition_unref(&_float->mantissa->p); + free_definition_scope(_float->p.scope); declaration_unref(_float->p.declaration); g_free(_float); } diff --git a/types/integer.c b/types/integer.c index 6a95b939..5f9989b2 100644 --- a/types/integer.c +++ b/types/integer.c @@ -84,6 +84,7 @@ struct definition * integer->p.name = field_name; integer->p.path = new_definition_path(parent_scope, field_name, root_name); + integer->p.scope = NULL; integer->value._unsigned = 0; ret = register_field_definition(field_name, &integer->p, parent_scope); diff --git a/types/sequence.c b/types/sequence.c index 676d9ef6..1066bc71 100644 --- a/types/sequence.c +++ b/types/sequence.c @@ -62,7 +62,7 @@ int sequence_rw(struct stream_pos *pos, struct definition *definition) field = (struct definition **) &g_ptr_array_index(sequence_definition->elems, i); *field = sequence_declaration->elem->definition_new(sequence_declaration->elem, - sequence_definition->scope, + sequence_definition->p.scope, name, i, NULL); ret = generic_rw(pos, *field); if (ret) @@ -133,13 +133,13 @@ struct definition *_sequence_definition_new(struct declaration *declaration, sequence->p.index = root_name ? INT_MAX : index; sequence->p.name = field_name; sequence->p.path = new_definition_path(parent_scope, field_name, root_name); - sequence->scope = new_definition_scope(parent_scope, field_name, root_name); + sequence->p.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); + len_parent = lookup_path_definition(sequence->p.scope->scope_path, + sequence_declaration->length_name, + parent_scope); if (!len_parent) { printf("[error] Lookup for sequence length field failed.\n"); goto error; @@ -175,7 +175,7 @@ struct definition *_sequence_definition_new(struct declaration *declaration, return &sequence->p; error: - free_definition_scope(sequence->scope); + free_definition_scope(sequence->p.scope); declaration_unref(&sequence_declaration->p); g_free(sequence); return NULL; @@ -201,7 +201,7 @@ void _sequence_definition_free(struct definition *definition) } (void) g_ptr_array_free(sequence->elems, TRUE); definition_unref(len_definition); - free_definition_scope(sequence->scope); + free_definition_scope(sequence->p.scope); declaration_unref(sequence->p.declaration); g_free(sequence); } diff --git a/types/string.c b/types/string.c index 47e0970e..1999cffd 100644 --- a/types/string.c +++ b/types/string.c @@ -77,6 +77,7 @@ struct definition * string->p.name = field_name; string->p.path = new_definition_path(parent_scope, field_name, root_name); + string->p.scope = NULL; string->value = NULL; string->len = 0; string->alloc_len = 0; diff --git a/types/struct.c b/types/struct.c index a9703b28..3961afc5 100644 --- a/types/struct.c +++ b/types/struct.c @@ -118,7 +118,7 @@ struct definition * _struct->p.index = root_name ? INT_MAX : index; _struct->p.name = 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); + _struct->p.scope = new_definition_scope(parent_scope, field_name, root_name); ret = register_field_definition(field_name, &_struct->p, parent_scope); @@ -134,7 +134,7 @@ struct definition * (struct definition **) &g_ptr_array_index(_struct->fields, i); *field = declaration_field->declaration->definition_new(declaration_field->declaration, - _struct->scope, + _struct->p.scope, declaration_field->name, i, NULL); if (!*field) goto error; @@ -146,7 +146,7 @@ error: struct definition *field = g_ptr_array_index(_struct->fields, i); definition_unref(field); } - free_definition_scope(_struct->scope); + free_definition_scope(_struct->p.scope); declaration_unref(&struct_declaration->p); g_free(_struct); return NULL; @@ -164,7 +164,7 @@ void _struct_definition_free(struct definition *definition) struct definition *field = g_ptr_array_index(_struct->fields, i); definition_unref(field); } - free_definition_scope(_struct->scope); + free_definition_scope(_struct->p.scope); declaration_unref(_struct->p.declaration); g_free(_struct); } diff --git a/types/types.c b/types/types.c index 17dcffb9..b9576ea3 100644 --- a/types/types.c +++ b/types/types.c @@ -146,40 +146,7 @@ end: static struct definition_scope * get_definition_scope(struct definition *definition) { - switch (definition->declaration->id) { - case CTF_TYPE_STRUCT: - { - struct definition_struct *def = - container_of(definition, struct definition_struct, p); - return def->scope; - } - case CTF_TYPE_VARIANT: - { - struct definition_variant *def = - container_of(definition, struct definition_variant, p); - return def->scope; - } - case CTF_TYPE_ARRAY: - { - struct definition_array *def = - container_of(definition, struct definition_array, p); - return def->scope; - } - case CTF_TYPE_SEQUENCE: - { - struct definition_sequence *def = - container_of(definition, struct definition_sequence, p); - return def->scope; - } - - case CTF_TYPE_INTEGER: - case CTF_TYPE_FLOAT: - case CTF_TYPE_ENUM: - case CTF_TYPE_STRING: - case CTF_TYPE_UNKNOWN: - default: - return NULL; - } + return definition->scope; } /* @@ -203,9 +170,9 @@ static struct definition_scope * * scope: the definition scope containing the variant definition. */ struct definition * - lookup_definition(GArray *cur_path, - GArray *lookup_path, - struct definition_scope *scope) + lookup_path_definition(GArray *cur_path, + GArray *lookup_path, + struct definition_scope *scope) { struct definition *definition, *lookup_definition; GQuark last; @@ -629,3 +596,69 @@ void free_definition_scope(struct definition_scope *scope) g_hash_table_destroy(scope->definitions); g_free(scope); } + +static +struct definition *lookup_definition(struct definition *definition, + const char *field_name) +{ + struct definition_scope *scope = get_definition_scope(definition); + + if (!scope) + return NULL; + + return lookup_field_definition_scope(g_quark_from_string(field_name), + scope); +} + +struct definition_integer *lookup_integer(struct definition *definition, + const char *field_name, + int signedness) +{ + struct definition *lookup; + struct definition_integer *lookup_integer; + + lookup = lookup_definition(definition, field_name); + if (!lookup) + return NULL; + if (lookup->declaration->id != CTF_TYPE_INTEGER) + return NULL; + lookup_integer = container_of(lookup, struct definition_integer, p); + if (lookup_integer->declaration->signedness != signedness) + return NULL; + return lookup_integer; +} + +struct definition_enum *lookup_enum(struct definition *definition, + const char *field_name, + int signedness) +{ + struct definition *lookup; + struct definition_enum *lookup_enum; + + lookup = lookup_definition(definition, field_name); + if (!lookup) + return NULL; + if (lookup->declaration->id != CTF_TYPE_ENUM) + return NULL; + lookup_enum = container_of(lookup, struct definition_enum, p); + if (lookup_enum->integer->declaration->signedness != signedness) + return NULL; + return lookup_enum; +} + +struct definition *lookup_variant(struct definition *definition, + const char *field_name) +{ + struct definition *lookup; + struct definition_variant *lookup_variant; + + lookup = lookup_definition(definition, field_name); + if (!lookup) + return NULL; + if (lookup->declaration->id != CTF_TYPE_VARIANT) + return NULL; + lookup_variant = container_of(lookup, struct definition_variant, p); + lookup = variant_get_current_field(lookup_variant); + assert(lookup); + return lookup; +} diff --git a/types/variant.c b/types/variant.c index 96b66508..35e00c19 100644 --- a/types/variant.c +++ b/types/variant.c @@ -183,15 +183,15 @@ struct definition * variant->p.index = root_name ? INT_MAX : index; variant->p.name = 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); + variant->p.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); + variant->enum_tag = lookup_path_definition(variant->p.scope->scope_path, + variant_declaration->tag_name, + parent_scope); if (!variant->enum_tag || check_enum_tag(variant, variant->enum_tag) < 0) @@ -211,7 +211,7 @@ struct definition * * various choices of the same field. */ *field = declaration_field->declaration->definition_new(declaration_field->declaration, - variant->scope, + variant->p.scope, declaration_field->name, 0, NULL); if (!*field) goto error; @@ -219,7 +219,7 @@ struct definition * variant->current_field = NULL; return &variant->p; error: - free_definition_scope(variant->scope); + free_definition_scope(variant->p.scope); declaration_unref(&variant_declaration->p); g_free(variant); return NULL; @@ -238,7 +238,7 @@ void _variant_definition_free(struct definition *definition) definition_unref(field); } definition_unref(variant->enum_tag); - free_definition_scope(variant->scope); + free_definition_scope(variant->p.scope); declaration_unref(variant->p.declaration); g_free(variant); }