Update sequence (type specifier -> field ref), fix definition lookup
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Mon, 16 May 2011 21:10:48 +0000 (17:10 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Mon, 16 May 2011 21:10:48 +0000 (17:10 -0400)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
19 files changed:
formats/ctf/metadata/ctf-ast.h
formats/ctf/metadata/ctf-parser.y
formats/ctf/metadata/ctf-test/succeed/ctf-test-seq.txt [new file with mode: 0644]
formats/ctf/metadata/ctf-test/succeed/ctf-test.txt
formats/ctf/metadata/ctf-visitor-generate-io-struct.c
formats/ctf/metadata/ctf-visitor-parent-links.c
formats/ctf/metadata/ctf-visitor-semantic-validator.c
formats/ctf/metadata/ctf-visitor-xml.c
formats/ctf/types/float.c
include/babeltrace/types.h
types/array.c
types/enum.c
types/float.c
types/integer.c
types/sequence.c
types/string.c
types/struct.c
types/types.c
types/variant.c

index 3d8d8b00d7a056a9797fbb807c5e0258d495453d..f21dda01143be72f5381f7881676f5c92d934907 100644 (file)
@@ -192,7 +192,7 @@ struct ctf_node {
                                         * 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;
index ed766952c175d32ad4412398d27e6431db14c4df..697f942c7cb4f3d2a937e0d7a6effbb22ae49812 100644 (file)
@@ -535,16 +535,13 @@ static int reparent_type_specifier_list(struct ctf_node *node,
        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:
@@ -888,7 +885,6 @@ void ctf_scanner_free(struct ctf_scanner *scanner)
 %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
@@ -1752,32 +1748,6 @@ variant_declaration_end:
                {       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
                {
@@ -2142,12 +2112,13 @@ direct_abstract_declarator:
                        $$->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
                {
@@ -2191,12 +2162,13 @@ direct_alias_abstract_declarator:
                        $$->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
                {
@@ -2230,12 +2202,13 @@ direct_declarator:
                        $$->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);
                }
        ;
 
@@ -2263,12 +2236,13 @@ direct_type_declarator:
                        $$->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);
                }
        ;
 
diff --git a/formats/ctf/metadata/ctf-test/succeed/ctf-test-seq.txt b/formats/ctf/metadata/ctf-test/succeed/ctf-test-seq.txt
new file mode 100644 (file)
index 0000000..763a776
--- /dev/null
@@ -0,0 +1,42 @@
+/* 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];
+       };
+};
index 260ac024bab30ab19497c3e9436fe7dff03a34e9..c261a9a5da428a5d1823b50db6ec39c857008c01 100644 (file)
@@ -51,6 +51,7 @@ struct event_packet_header {
 trace {
        major = 66;
        minor = 2;
+       byte_order = le;
        uuid = "1123fcea-706e-11e0-a38b-f3c28a683a3d";
        packet.header := struct event_packet_header;
 };
@@ -175,7 +176,7 @@ event {
        id = 0;
        stream_id = 5;
        context := struct {};
-       payload := struct {};
+       fields := struct {};
 };
 
 typealias integer { size = 32; align = 32; signed = false; } := unsigned long long *;
@@ -186,14 +187,18 @@ variant vardecl {
 };
 
 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];
index 507233c97cdf3b4fbdf4ce8e24548be2a8fb6967..ecd9ffd9217b88873e6523ebd4b8027e4d47a5cb 100644 (file)
@@ -346,57 +346,47 @@ struct declaration *ctf_type_declarator_visit(FILE *fd, int depth,
                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;
                }
@@ -1505,6 +1495,10 @@ int ctf_event_declaration_visit(FILE *fd, int depth, struct ctf_node *node, stru
                                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);
@@ -1572,34 +1566,40 @@ int ctf_event_visit(FILE *fd, int depth, struct ctf_node *node,
                            &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;
@@ -1710,7 +1710,12 @@ int ctf_stream_declaration_visit(FILE *fd, int depth, struct ctf_node *node, str
                                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;
@@ -1767,49 +1772,58 @@ int ctf_stream_visit(FILE *fd, int depth, struct ctf_node *node,
 
        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);
@@ -1921,7 +1935,12 @@ int ctf_trace_declaration_visit(FILE *fd, int depth, struct ctf_node *node, stru
                                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;
@@ -1973,16 +1992,16 @@ int ctf_trace_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace
 
        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;
 
@@ -1992,14 +2011,16 @@ int ctf_trace_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace
                    || 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;
index ce2fb0d9b19cd38c760b536529fa45d602111f7b..a4476b22e648029ff5f8d92a193b5f9672fefed9 100644 (file)
@@ -128,14 +128,12 @@ int ctf_visitor_type_declarator(FILE *fd, int depth, struct ctf_node *node)
 
        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) {
@@ -149,9 +147,10 @@ int ctf_visitor_type_declarator(FILE *fd, int depth, struct ctf_node *node)
                        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;
                }
index be5ed8f440e1b51c5672962f0684bc46ebf875d1..0883bc79c1058036ad8dd64f17bbedc8d18f042a 100644 (file)
@@ -71,9 +71,10 @@ int ctf_visitor_unary_expression(FILE *fd, int depth, struct ctf_node *node)
                 */
                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 */
@@ -341,13 +342,11 @@ int ctf_visitor_type_declarator(FILE *fd, int depth, struct ctf_node *node)
                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) {
@@ -361,10 +360,16 @@ int ctf_visitor_type_declarator(FILE *fd, int depth, struct ctf_node *node)
                        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);
index 0236fbaedf1212cbdb20f4a1b78dfd691885386f..7115126f980d6a6b0a8021e203fd4d1b4fa0228d 100644 (file)
@@ -309,12 +309,15 @@ int ctf_visitor_print_type_declarator(FILE *fd, int depth, struct ctf_node *node
                        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");
                }
index ebd7b7ae166c91a3be761b2ea9da6198e3cf9277..8ba8a69d51d83d45b1c43a05074f959c22554f70 100644 (file)
@@ -142,7 +142,7 @@ int ctf_float_read(struct stream_pos *ppos, struct definition *definition)
        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;
@@ -168,7 +168,7 @@ int ctf_float_write(struct stream_pos *ppos, struct definition *definition)
        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;
index 33311a683dae1056ff48928b4f4f0e3f83a788a4..2aa45b8a0cdfbe6f33f0cd290bf50064ecaeae88 100644 (file)
@@ -91,7 +91,8 @@ struct declaration {
        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.
         */
@@ -166,6 +167,7 @@ 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;
 };
@@ -218,6 +220,7 @@ 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;
 };
@@ -298,7 +301,7 @@ struct definition_array {
 
 struct declaration_sequence {
        struct declaration p;
-       struct declaration_integer *len_declaration;
+       GArray *length_name;            /* Array of GQuark */
        struct declaration *elem;
        struct declaration_scope *scope;
 };
@@ -307,7 +310,7 @@ struct definition_sequence {
        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 */
 };
 
@@ -358,13 +361,11 @@ int register_field_definition(GQuark field_name,
                              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)
@@ -497,7 +498,7 @@ int array_rw(struct stream_pos *pos, struct definition *definition);
  * 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);
index 0bb141ce33e14cf3ba2ca12858e734535f3856a4..0be26476df8605945713bb74927a0848cfd9ed85 100644 (file)
@@ -23,7 +23,7 @@
 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);
 
@@ -86,22 +86,30 @@ 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)
 {
        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++) {
@@ -110,16 +118,31 @@ struct definition *
                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
index 068651c74eecb780acec420939888a10f3f4f049..b60c9c56ce239a08dcaa23ffbbf4fb4ca70ee1af 100644 (file)
@@ -24,7 +24,8 @@
 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);
 
@@ -396,26 +397,36 @@ 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)
 {
        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;
index 2306d94f1b17cecd48df03b89343efe507fe8256..5ae831ce2a745e3beaeff5973f59ac051ffd7ec7 100644 (file)
@@ -23,7 +23,8 @@
 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);
 
@@ -69,43 +70,53 @@ 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)
 {
        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;
 }
 
index 059c6d898b7951e31951e35b3bd7e5d3be9eac05..940963a51ec5a2fea08cb0cd197a21573303d8c8 100644 (file)
@@ -24,7 +24,8 @@
 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);
 
@@ -60,21 +61,31 @@ 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)
 {
        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;
 }
 
index f4262cdb99b595a8119dccd2c59bab379c1d57dd..119522d7de7a084f42345aef5a73b999755ebf7e 100644 (file)
 #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);
 
@@ -40,10 +37,7 @@ int sequence_rw(struct stream_pos *pos, 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
@@ -69,7 +63,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,
-                                         name, i);
+                                         name, i, NULL);
                ret = generic_rw(pos, *field);
                if (ret)
                        return ret;
@@ -84,13 +78,13 @@ void _sequence_declaration_free(struct declaration *declaration)
                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)
 {
@@ -99,14 +93,15 @@ struct declaration_sequence *
 
        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;
@@ -117,29 +112,53 @@ struct declaration_sequence *
 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
@@ -147,7 +166,7 @@ void _sequence_definition_free(struct definition *definition)
 {
        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++) {
@@ -157,7 +176,7 @@ void _sequence_definition_free(struct definition *definition)
                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);
@@ -165,12 +184,12 @@ void _sequence_definition_free(struct definition *definition)
 
 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);
index 0f261f418b1bd2a766dcba83bd2bd0e8d8ce1f4a..47e0970e890280b159d52d385a15cc0e60eed63b 100644 (file)
@@ -23,7 +23,8 @@
 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);
 
@@ -55,23 +56,33 @@ 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)
 {
        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;
 }
 
index a6b7e3b98da185eaabbb251eab029fdd79c24d45..a9703b28e4859a00f59f59894c2a0a37762c0305 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <babeltrace/compiler.h>
 #include <babeltrace/format.h>
+#include <errno.h>
 
 #ifndef max
 #define max(a, b)      ((a) < (b) ? (b) : (a))
@@ -26,7 +27,8 @@
 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);
 
@@ -95,12 +97,13 @@ 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)
 {
        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);
@@ -108,10 +111,19 @@ struct definition *
        _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++) {
@@ -123,13 +135,21 @@ struct definition *
 
                *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
index e63394692410ea3f6a885263c5969411caad321d..17dcffb92576f868e3a212c05d235aed24617bc7 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include <babeltrace/format.h>
+#include <babeltrace/babeltrace.h>
 #include <limits.h>
 #include <glib.h>
 #include <errno.h>
@@ -110,13 +111,36 @@ static int compare_paths(GArray *a, GArray *b, int len)
 
 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 *
@@ -187,14 +211,41 @@ struct definition *
        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 */
@@ -222,7 +273,6 @@ lookup:
                                goto lookup;
                        }
                } else {
-                       assert(index != -1);
                        /* lookup_path is within an upper scope */
                        cur_path = scope->scope_path;
                        scope = scope->parent_scope;
@@ -234,7 +284,7 @@ lookup:
 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 */
@@ -244,7 +294,7 @@ int register_field_definition(GQuark field_name, struct definition *definition,
        g_hash_table_insert(scope->definitions,
                            (gpointer) (unsigned long) field_name,
                            definition);
-       definition_ref(definition);
+       /* Don't keep reference on definition */
        return 0;
 }
 
@@ -459,9 +509,8 @@ static struct definition_scope *
 {
        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);
@@ -469,49 +518,74 @@ static struct definition_scope *
        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;
 }
 
@@ -549,19 +623,6 @@ void append_scope_path(const char *path, GArray *q)
        }
 }
 
-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);
index 8a781f67c0df03af2a114b7fdddbd2d5b6ae509f..96b665082442fcef2c4acfd0f145315e431c1ff3 100644 (file)
@@ -23,7 +23,8 @@
 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);
 
@@ -161,22 +162,33 @@ 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)
 {
        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);
@@ -200,7 +212,9 @@ struct definition *
                 */
                *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;
This page took 0.084311 seconds and 4 git commands to generate.