Add structure align() attribute, fix empty string support in definition paths
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Fri, 13 May 2011 21:41:19 +0000 (17:41 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Fri, 13 May 2011 21:41:19 +0000 (17:41 -0400)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
13 files changed:
formats/ctf/ctf.c
formats/ctf/metadata/ctf-ast.h
formats/ctf/metadata/ctf-lexer.l
formats/ctf/metadata/ctf-parser.y
formats/ctf/metadata/ctf-test/succeed/ctf-embedded-1.txt
formats/ctf/metadata/ctf-test/succeed/ctf-test-align-attribute.txt [new file with mode: 0644]
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
include/babeltrace/types.h
types/struct.c
types/types.c

index f4432a89d167c0fe01e181232f246ad4cf5b73e0..bdebaeb306d8eba78b2c6187dd0c1dc93c93d78c 100644 (file)
@@ -693,8 +693,6 @@ int ctf_open_trace_read(struct ctf_trace *td, const char *path, int flags)
                goto error_dirfd;
        }
 
-       td->streams = g_ptr_array_new();
-
        /*
         * Keep the metadata file separate.
         */
index bf6ddb42db41fdc0c51290d31c0b043744586604..3d8d8b00d7a056a9797fbb807c5e0258d495453d 100644 (file)
@@ -245,6 +245,7 @@ struct ctf_node {
                        /* list of typedef, typealias and declarations */
                        struct cds_list_head declaration_list;
                        int has_body;
+                       struct cds_list_head min_align; /* align() attribute */
                } _struct;
        } u;
 };
index ff4f8a51ba9c17ed4ff65988e4159733d01d43ce..7e81add5a9a70d192328965be2bc92ecda88f864 100644 (file)
@@ -93,6 +93,7 @@ L\"                           BEGIN(string_lit); return STRING_LITERAL_START;
 "."                            return DOT;
 =                              return EQUAL;
 ","                            return COMMA;
+align                          setstring(yyextra, yylval, yytext); return TOK_ALIGN;
 const                          setstring(yyextra, yylval, yytext); return CONST;
 char                           setstring(yyextra, yylval, yytext); return CHAR;
 double                         setstring(yyextra, yylval, yytext); return DOUBLE;
index 8fc83dfad49c154f4ad756da4e7f73a3a72de60a..ed766952c175d32ad4412398d27e6431db14c4df 100644 (file)
@@ -304,6 +304,7 @@ static struct ctf_node *make_node(struct ctf_scanner *scanner,
                break;
        case NODE_STRUCT:
                CDS_INIT_LIST_HEAD(&node->u._struct.declaration_list);
+               CDS_INIT_LIST_HEAD(&node->u._struct.min_align);
                break;
 
        case NODE_UNKNOWN:
@@ -858,7 +859,7 @@ void ctf_scanner_free(struct ctf_scanner *scanner)
  */
 %expect 2
 %start file
-%token CHARACTER_CONSTANT_START SQUOTE STRING_LITERAL_START DQUOTE ESCSEQ CHAR_STRING_TOKEN LSBRAC RSBRAC LPAREN RPAREN LBRAC RBRAC RARROW STAR PLUS MINUS LT GT TYPEASSIGN COLON SEMICOLON DOTDOTDOT DOT EQUAL COMMA CONST CHAR DOUBLE ENUM EVENT FLOATING_POINT FLOAT INTEGER INT LONG SHORT SIGNED STREAM STRING STRUCT TRACE TYPEALIAS TYPEDEF UNSIGNED VARIANT VOID _BOOL _COMPLEX _IMAGINARY DECIMAL_CONSTANT OCTAL_CONSTANT HEXADECIMAL_CONSTANT
+%token CHARACTER_CONSTANT_START SQUOTE STRING_LITERAL_START DQUOTE ESCSEQ CHAR_STRING_TOKEN LSBRAC RSBRAC LPAREN RPAREN LBRAC RBRAC RARROW STAR PLUS MINUS LT GT TYPEASSIGN COLON SEMICOLON DOTDOTDOT DOT EQUAL COMMA CONST CHAR DOUBLE ENUM EVENT FLOATING_POINT FLOAT INTEGER INT LONG SHORT SIGNED STREAM STRING STRUCT TRACE TYPEALIAS TYPEDEF UNSIGNED VARIANT VOID _BOOL _COMPLEX _IMAGINARY DECIMAL_CONSTANT OCTAL_CONSTANT HEXADECIMAL_CONSTANT TOK_ALIGN
 %token <gs> IDENTIFIER ID_TYPE
 %token ERROR
 %union
@@ -971,6 +972,8 @@ keywords:
                {       $$ = yylval.gs;         }
        |       TRACE
                {       $$ = yylval.gs;         }
+       |       TOK_ALIGN
+               {       $$ = yylval.gs;         }
        ;
 
 /* 1.5 Constants */
@@ -1595,6 +1598,32 @@ struct_type_specifier:
                        $$->u._struct.has_body = 0;
                        $$->u._struct.name = $1->s;
                }
+       |       struct_declaration_begin struct_or_variant_declaration_list struct_declaration_end TOK_ALIGN LPAREN unary_expression RPAREN
+               {
+                       $$ = make_node(scanner, NODE_STRUCT);
+                       $$->u._struct.has_body = 1;
+                       cds_list_add_tail(&($6)->siblings, &$$->u._struct.min_align);
+                       if ($2 && set_parent_node($2, $$))
+                               reparent_error(scanner, "struct reparent error");
+               }
+       |       IDENTIFIER struct_declaration_begin struct_or_variant_declaration_list struct_declaration_end TOK_ALIGN LPAREN unary_expression RPAREN
+               {
+                       $$ = make_node(scanner, NODE_STRUCT);
+                       $$->u._struct.has_body = 1;
+                       $$->u._struct.name = $1->s;
+                       cds_list_add_tail(&($7)->siblings, &$$->u._struct.min_align);
+                       if ($3 && set_parent_node($3, $$))
+                               reparent_error(scanner, "struct reparent error");
+               }
+       |       ID_TYPE struct_declaration_begin struct_or_variant_declaration_list struct_declaration_end TOK_ALIGN LPAREN unary_expression RPAREN
+               {
+                       $$ = make_node(scanner, NODE_STRUCT);
+                       $$->u._struct.has_body = 1;
+                       $$->u._struct.name = $1->s;
+                       cds_list_add_tail(&($7)->siblings, &$$->u._struct.min_align);
+                       if ($3 && set_parent_node($3, $$))
+                               reparent_error(scanner, "struct reparent error");
+               }
        ;
 
 struct_declaration_begin:
index 4a97cdf7a9f6dfaf82697cdbc8197dd523b74cb5..1de8823229c4264542419ca0928daaeb39cc41c7 100644 (file)
@@ -21,7 +21,7 @@ stream {
                void *func_called;       * events in this stream.
                void *called_from;       */
                uint32_t event_count;   /* for debug */
-       };                      
+       };
 };
 
 /*
diff --git a/formats/ctf/metadata/ctf-test/succeed/ctf-test-align-attribute.txt b/formats/ctf/metadata/ctf-test/succeed/ctf-test-align-attribute.txt
new file mode 100644 (file)
index 0000000..f9eefe3
--- /dev/null
@@ -0,0 +1,48 @@
+/* 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; } := uint32_t;
+typealias integer { size = 32; align = 32; signed = false; } := 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 {
+               void *func_called;
+               void *called_from;
+       };
+};
+
+event {
+       name = func_exit;
+       id = 1;
+       stream_id = 0;
+};
index 37d17f5839e2ebb4047a4f338e6634be44c9b2e8..23734284678996cc0ee0ddd16e4b82df2dc042e2 100644 (file)
@@ -653,7 +653,8 @@ int ctf_variant_declaration_list_visit(FILE *fd, int depth,
 static
 struct declaration *ctf_declaration_struct_visit(FILE *fd,
        int depth, const char *name, struct cds_list_head *declaration_list,
-       int has_body, struct declaration_scope *declaration_scope,
+       int has_body, struct cds_list_head *min_align,
+       struct declaration_scope *declaration_scope,
        struct ctf_trace *trace)
 {
        struct declaration_struct *struct_declaration;
@@ -672,6 +673,8 @@ struct declaration *ctf_declaration_struct_visit(FILE *fd,
                                                  declaration_scope);
                return &struct_declaration->p;
        } else {
+               uint64_t min_align_value = 0;
+
                /* For unnamed struct, create type */
                /* For named struct (with body), create type and add to declaration scope */
                if (name) {
@@ -682,7 +685,16 @@ struct declaration *ctf_declaration_struct_visit(FILE *fd,
                                return NULL;
                        }
                }
-               struct_declaration = struct_declaration_new(declaration_scope);
+               if (!cds_list_empty(min_align)) {
+                       ret = get_unary_unsigned(min_align, &min_align_value);
+                       if (ret) {
+                               fprintf(fd, "[error] %s: unexpected unary expression for structure \"align\" attribute\n", __func__);
+                               ret = -EINVAL;
+                               goto error;
+                       }
+               }
+               struct_declaration = struct_declaration_new(declaration_scope,
+                                                           min_align_value);
                cds_list_for_each_entry(iter, declaration_list, siblings) {
                        ret = ctf_struct_declaration_list_visit(fd, depth + 1, iter,
                                struct_declaration, trace);
@@ -1265,6 +1277,7 @@ struct declaration *ctf_type_specifier_list_visit(FILE *fd,
                        node->u._struct.name,
                        &node->u._struct.declaration_list,
                        node->u._struct.has_body,
+                       &node->u._struct.min_align,
                        declaration_scope,
                        trace);
        case TYPESPEC_VARIANT:
@@ -1978,6 +1991,7 @@ int ctf_visitor_construct_metadata(FILE *fd, int depth, struct ctf_node *node,
 
        printf_verbose("CTF visitor: metadata construction... ");
        trace->root_declaration_scope = new_declaration_scope(NULL);
+       trace->streams = g_ptr_array_new();
        trace->byte_order = byte_order;
 
        switch (node->type) {
index 49d067c6640c66bc97c2ab2f5436dd9e2d170604..ce2fb0d9b19cd38c760b536529fa45d602111f7b 100644 (file)
@@ -401,6 +401,13 @@ int ctf_visitor_parent_links(FILE *fd, int depth, struct ctf_node *node)
                        if (ret)
                                return ret;
                }
+               cds_list_for_each_entry(iter, &node->u._struct.min_align,
+                                       siblings) {
+                       iter->parent = node;
+                       ret = ctf_visitor_parent_links(fd, depth + 1, iter);
+                       if (ret)
+                               return ret;
+               }
                break;
 
        case NODE_UNKNOWN:
index af55eb4861d7163463b2efb9af095506cc2dce10..be5ed8f440e1b51c5672962f0684bc46ebf875d1 100644 (file)
@@ -70,14 +70,27 @@ int ctf_visitor_unary_expression(FILE *fd, int depth, struct ctf_node *node)
                 * We are the length of a type declarator.
                 */
                switch (node->u.unary_expression.type) {
-               case UNARY_SIGNED_CONSTANT:
                case UNARY_UNSIGNED_CONSTANT:
                        break;
                default:
-                       fprintf(fd, "[error]: semantic error (children of type declarator and enum can only be numeric constants)\n");
+                       fprintf(fd, "[error]: semantic error (children of type declarator and enum can only be unsigned numeric constants)\n");
                        goto errperm;
                }
                break;                  /* OK */
+
+       case NODE_STRUCT:
+               /*
+                * We are the size of a struct align attribute.
+                */
+               switch (node->u.unary_expression.type) {
+               case UNARY_UNSIGNED_CONSTANT:
+                       break;
+               default:
+                       fprintf(fd, "[error]: semantic error (structure alignment attribute can only be unsigned numeric constants)\n");
+                       goto errperm;
+               }
+               break;
+
        case NODE_ENUMERATOR:
                /* The enumerator's parent has validated its validity already. */
                break;                  /* OK */
@@ -106,7 +119,6 @@ int ctf_visitor_unary_expression(FILE *fd, int depth, struct ctf_node *node)
        case NODE_ENUM:
        case NODE_STRUCT_OR_VARIANT_DECLARATION:
        case NODE_VARIANT:
-       case NODE_STRUCT:
        default:
                goto errinval;
        }
index f73c367193c4030d585b9d4fe16643f5687803a1..0236fbaedf1212cbdb20f4a1b78dfd691885386f 100644 (file)
@@ -677,6 +677,17 @@ int ctf_visitor_print_xml(FILE *fd, int depth, struct ctf_node *node)
                }
                print_tabs(fd, depth);
                fprintf(fd, "</struct>\n");
+               if (!cds_list_empty(&node->u._struct.min_align)) {
+                       print_tabs(fd, depth);
+                       fprintf(fd, "<align>\n");
+                       cds_list_for_each_entry(iter, &node->u._struct.min_align, siblings) {
+                               ret = ctf_visitor_print_xml(fd, depth + 1, iter);
+                               if (ret)
+                                       return ret;
+                       }
+                       print_tabs(fd, depth);
+                       fprintf(fd, "</align>\n");
+               }
                break;
 
        case NODE_UNKNOWN:
index 2c7650e620779ae2e8c202c38b26f07d7f87b00b..a4dcdee933be4f19dc9fda9d684534ca85f556c3 100644 (file)
@@ -427,7 +427,8 @@ struct declaration_string *
        string_declaration_new(enum ctf_string_encoding encoding);
 
 struct declaration_struct *
-       struct_declaration_new(struct declaration_scope *parent_scope);
+       struct_declaration_new(struct declaration_scope *parent_scope,
+                              uint64_t min_align);
 void struct_declaration_add_field(struct declaration_struct *struct_declaration,
                                  const char *field_name,
                                  struct declaration *field_declaration);
index ba312111cd3d65c3f25a5bf8cc3ecc71af7dd14d..a6b7e3b98da185eaabbb251eab029fdd79c24d45 100644 (file)
@@ -68,7 +68,8 @@ void _struct_declaration_free(struct declaration *declaration)
 }
 
 struct declaration_struct *
-       struct_declaration_new(struct declaration_scope *parent_scope)
+       struct_declaration_new(struct declaration_scope *parent_scope,
+                              uint64_t min_align)
 {
        struct declaration_struct *struct_declaration;
        struct declaration *declaration;
@@ -82,7 +83,7 @@ struct declaration_struct *
                                                DEFAULT_NR_STRUCT_FIELDS);
        struct_declaration->scope = new_declaration_scope(parent_scope);
        declaration->id = CTF_TYPE_STRUCT;
-       declaration->alignment = 1;
+       declaration->alignment = max(1, min_align);
        declaration->declaration_free = _struct_declaration_free;
        declaration->definition_new = _struct_definition_new;
        declaration->definition_free = _struct_definition_free;
index 7369f30d09ffb5a272c3d54f14e5466ac3b005b2..e63394692410ea3f6a885263c5969411caad321d 100644 (file)
@@ -481,13 +481,17 @@ GQuark new_definition_path(struct definition_scope *parent_scope, GQuark field_n
                for (i = 0; i < parent_scope->scope_path->len; i++) {
                        GQuark q = g_array_index(parent_scope->scope_path,
                                                 GQuark, i);
-
+                       if (!q)
+                               continue;
                        g_string_append(str, g_quark_to_string(q));
                        g_string_append(str, ".");
                }
        }
-       g_string_append(str, g_quark_to_string(field_name));
+       if (field_name)
+               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);
        g_free(c_str);
        return path;
This page took 0.033355 seconds and 4 git commands to generate.