Update gen io structs, basic implementation complete
[babeltrace.git] / formats / ctf / metadata / ctf-visitor-generate-io-struct.c
index fd6176fef4a1bef223cb3c0f3df0d34621d73d02..43763aab919131556d366c8bea8bcd3c78844093 100644 (file)
@@ -39,7 +39,8 @@
 static
 struct declaration *ctf_declaration_specifier_visit(FILE *fd,
                int depth, struct cds_list_head *head,
-               struct declaration_scope *declaration_scope);
+               struct declaration_scope *declaration_scope,
+               struct ctf_trace *trace);
 
 /*
  * String returned must be freed by the caller using g_free.
@@ -257,7 +258,8 @@ struct declaration *ctf_type_declarator_visit(int fd, int depth,
        GQuark *field_name,
        struct ctf_node *node_type_declarator,
        struct declaration_scope *declaration_scope,
-       struct declaration *nested_declaration)
+       struct declaration *nested_declaration,
+       struct ctf_trace *trace)
 {
        /*
         * Visit type declarator by first taking care of sequence/array
@@ -265,16 +267,18 @@ struct declaration *ctf_type_declarator_visit(int fd, int depth,
         * of pointers.
         */
 
-       assert(node_type_declarator->u.type_declarator.type != TYPEDEC_UNKNOWN);
+       if (node_type_declarator) {
+               assert(node_type_declarator->u.type_declarator.type != TYPEDEC_UNKNOWN);
 
-       /* TODO: gcc bitfields not supported yet. */
-       if (node_type_declarator->u.type_declarator.bitfield_len != NULL) {
-               fprintf(stderr, "[error] %s: gcc bitfields are not supported yet.\n", __func__);
-               return NULL;
+               /* TODO: gcc bitfields not supported yet. */
+               if (node_type_declarator->u.type_declarator.bitfield_len != NULL) {
+                       fprintf(stderr, "[error] %s: gcc bitfields are not supported yet.\n", __func__);
+                       return NULL;
+               }
        }
 
        if (!nested_declaration) {
-               if (!cds_list_empty(&node_type_declarator->u.type_declarator.pointers)) {
+               if (node_type_declarator && !cds_list_empty(&node_type_declarator->u.type_declarator.pointers)) {
                        GQuark alias_q;
 
                        /*
@@ -289,10 +293,14 @@ struct declaration *ctf_type_declarator_visit(int fd, int depth,
                                return NULL;
                        }
                } else {
-                       nested_declaration = /* parse declaration_specifier */;
+                       nested_declaration = ctf_declaration_specifier_visit(fd, depth,
+                               declaration_specifier, declaration_scope, trace);
                }
        }
 
+       if (!node_type_declarator)
+               return nested_declaration;
+
        if (node_type_declarator->u.type_declarator.type == TYPEDEC_ID) {
                if (node_type_declarator->u.type_declarator.u.id)
                        *field_name = g_quark_from_string(node_type_declarator->u.type_declarator.u.id);
@@ -310,15 +318,39 @@ struct declaration *ctf_type_declarator_visit(int fd, int depth,
                if (length) {
                        switch (length->type) {
                        case NODE_UNARY_EXPRESSION:
-                               /* Array */
-                               /* TODO */
-               .............
-                               declaration = /* create array */;
+                       {
+                               struct declaration_array *array_declaration;
+                               size_t len;
+
+                               if (length->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
+                                       fprintf(stderr, "[error] %s: array: unexpected unary expression.\n", __func__);
+                                       return NULL;
+                               }
+                               len = length->u.unary_expression.u.unsigned_constant;
+                               array_declaration = array_declaration_new(len, nested_declaration,
+                                                       declaration_scope);
+                               declaration = &array_declaration->p;
                                break;
+                       }
+                       case NODE_INTEGER:
                        case NODE_TYPE_SPECIFIER:
-                               /* Sequence */
-                               declaration = /* create sequence */;
+                       {
+                               struct declaration_sequence *sequence_declaration;
+                               struct declaration_integer *integer_declaration;
+                               GQuark dummy_id;
+
+                               declaration = ctf_type_declarator_visit(fd, depth,
+                                                       length,
+                                                       &dummy_id, NULL,
+                                                       declaration_scope,
+                                                       NULL, trace);
+                               assert(declaration->id == CTF_TYPE_INTEGER);
+                               integer_declaration = container_of(declaration, struct declaration_integer, p);
+                               declaration_sequence = sequence_declaration_new(integer_declaration,
+                                               nested_declaration, declaration_scope);
+                               declaration = &declaration_sequence->p;
                                break;
+                       }
                        default:
                                assert(0);
                        }
@@ -328,7 +360,7 @@ struct declaration *ctf_type_declarator_visit(int fd, int depth,
                declaration = ctf_type_declarator_visit(fd, depth,
                                declaration_specifier, field_name,
                                node_type_declarator->u.type_declarator.u.nested.type_declarator,
-                               declaration_scope, declaration);
+                               declaration_scope, declaration, trace);
                return declaration;
        }
 }
@@ -338,7 +370,8 @@ int ctf_struct_type_declarators_visit(int fd, int depth,
        struct declaration_struct *struct_declaration,
        struct cds_list_head *declaration_specifier,
        struct cds_list_head *type_declarators,
-       struct declaration_scope *declaration_scope)
+       struct declaration_scope *declaration_scope,
+       struct ctf_trace *trace)
 {
        struct ctf_node *iter;
        GQuark field_name;
@@ -350,7 +383,7 @@ int ctf_struct_type_declarators_visit(int fd, int depth,
                                                declaration_specifier,
                                                &field_name, iter,
                                                struct_declaration->scope,
-                                               NULL);
+                                               NULL, trace);
                struct_declaration_add_field(struct_declaration,
                                             g_quark_to_string(field_name),
                                             field_declaration);
@@ -363,7 +396,8 @@ int ctf_variant_type_declarators_visit(int fd, int depth,
        struct declaration_variant *variant_declaration,
        struct cds_list_head *declaration_specifier,
        struct cds_list_head *type_declarators,
-       struct declaration_scope *declaration_scope)
+       struct declaration_scope *declaration_scope,
+       struct ctf_trace *trace)
 {
        struct ctf_node *iter;
        GQuark field_name;
@@ -375,7 +409,7 @@ int ctf_variant_type_declarators_visit(int fd, int depth,
                                                declaration_specifier,
                                                &field_name, iter,
                                                variant_declaration->scope,
-                                               NULL);
+                                               NULL, trace);
                variant_declaration_add_field(variant_declaration,
                                              g_quark_to_string(field_name),
                                              field_declaration);
@@ -386,7 +420,8 @@ int ctf_variant_type_declarators_visit(int fd, int depth,
 static
 int ctf_typedef_visit(int fd, int depth, struct declaration_scope *scope,
                struct cds_list_head *declaration_specifier,
-               struct cds_list_head *type_declarators)
+               struct cds_list_head *type_declarators,
+               struct ctf_trace *trace)
 {
        struct ctf_node *iter;
        GQuark identifier;
@@ -398,7 +433,7 @@ int ctf_typedef_visit(int fd, int depth, struct declaration_scope *scope,
                type_declaration = ctf_type_declarator_visit(fd, depth,
                                        declaration_specifier,
                                        &identifier, iter,
-                                       scope, NULL);
+                                       scope, NULL, trace);
                ret = register_declaration(identifier, type_declaration, scope);
                if (ret) {
                        type_declaration->declaration_free(type_declaration);
@@ -410,7 +445,8 @@ int ctf_typedef_visit(int fd, int depth, struct declaration_scope *scope,
 
 static
 int ctf_typealias_visit(int fd, int depth, struct declaration_scope *scope,
-               struct ctf_node *target, struct ctf_node *alias)
+               struct ctf_node *target, struct ctf_node *alias,
+               struct ctf_trace *trace)
 {
        struct declaration *type_declaration;
        struct ctf_node *iter, *node;
@@ -426,7 +462,7 @@ int ctf_typealias_visit(int fd, int depth, struct declaration_scope *scope,
        type_declaration = ctf_type_declarator_visit(fd, depth,
                &target->u.typealias_target.declaration_specifier,
                &dummy_id, &target->u.typealias_target.type_declarators,
-               scope, NULL);
+               scope, NULL, trace);
        if (!type_declaration) {
                fprintf(stderr, "[error] %s: problem creating type declaration\n", __func__);
                err = -EINVAL;
@@ -461,7 +497,8 @@ error:
 
 static
 int ctf_struct_declaration_list_visit(int fd, int depth,
-       struct ctf_node *iter, struct declaration_struct *struct_declaration)
+       struct ctf_node *iter, struct declaration_struct *struct_declaration,
+       struct ctf_trace *trace)
 {
        struct declaration *declaration;
        int ret;
@@ -472,7 +509,7 @@ int ctf_struct_declaration_list_visit(int fd, int depth,
                ret = ctf_typedef_visit(fd, depth,
                        struct_declaration->scope,
                        &iter->u._typedef.declaration_specifier,
-                       &iter->u._typedef.type_declarators);
+                       &iter->u._typedef.type_declarators, trace);
                if (ret)
                        return ret;
                break;
@@ -481,7 +518,7 @@ int ctf_struct_declaration_list_visit(int fd, int depth,
                ret = ctf_typealias_visit(fd, depth,
                        struct_declaration->scope,
                        iter->u.typealias.target,
-                       iter->u.typealias.alias);
+                       iter->u.typealias.alias, trace);
                if (ret)
                        return ret;
                break;
@@ -490,7 +527,7 @@ int ctf_struct_declaration_list_visit(int fd, int depth,
                ret = ctf_struct_type_declarators_visit(fd, depth,
                                struct_declaration,
                                &iter->u.struct_or_variant_declaration.declaration_specifier,
-                               &iter->u.struct_or_variant_declaration.type_declarators);
+                               &iter->u.struct_or_variant_declaration.type_declarators, trace);
                if (ret)
                        return ret;
                break;
@@ -503,7 +540,8 @@ int ctf_struct_declaration_list_visit(int fd, int depth,
 
 static
 int ctf_variant_declaration_list_visit(int fd, int depth,
-       struct ctf_node *iter, struct declaration_variant *variant_declaration)
+       struct ctf_node *iter, struct declaration_variant *variant_declaration,
+       struct ctf_trace *trace)
 {
        struct declaration *declaration;
        int ret;
@@ -514,7 +552,7 @@ int ctf_variant_declaration_list_visit(int fd, int depth,
                ret = ctf_typedef_visit(fd, depth,
                        variant_declaration->scope,
                        &iter->u._typedef.declaration_specifier,
-                       &iter->u._typedef.type_declarators);
+                       &iter->u._typedef.type_declarators, trace);
                if (ret)
                        return ret;
                break;
@@ -523,7 +561,7 @@ int ctf_variant_declaration_list_visit(int fd, int depth,
                ret = ctf_typealias_visit(fd, depth,
                        variant_declaration->scope,
                        iter->u.typealias.target,
-                       iter->u.typealias.alias);
+                       iter->u.typealias.alias, trace);
                if (ret)
                        return ret;
                break;
@@ -532,7 +570,7 @@ int ctf_variant_declaration_list_visit(int fd, int depth,
                ret = ctf_variant_type_declarators_visit(fd, depth,
                                variant_declaration,
                                &iter->u.struct_or_variant_declaration.declaration_specifier,
-                               &iter->u.struct_or_variant_declaration.type_declarators);
+                               &iter->u.struct_or_variant_declaration.type_declarators, trace);
                if (ret)
                        return ret;
                break;
@@ -546,7 +584,8 @@ int ctf_variant_declaration_list_visit(int fd, int depth,
 static
 struct declaration_struct *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 declaration_scope *declaration_scope,
+       struct ctf_trace *trace)
 {
        struct declaration *declaration;
        struct declaration_struct *struct_declaration;
@@ -576,7 +615,8 @@ struct declaration_struct *ctf_declaration_struct_visit(FILE *fd,
                }
                struct_declaration = struct_declaration_new(name, declaration_scope);
                cds_list_for_each_entry(iter, declaration_list, siblings) {
-                       ret = ctf_struct_declaration_list_visit(fd, depth + 1, iter, struct_declaration);
+                       ret = ctf_struct_declaration_list_visit(fd, depth + 1, iter,
+                               struct_declaration, trace);
                        if (ret)
                                goto error;
                }
@@ -596,7 +636,8 @@ error:
 static
 struct declaration_variant *ctf_declaration_variant_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 declaration_scope *declaration_scope,
+       struct ctf_trace *trace)
 {
        struct declaration *declaration;
        struct declaration_variant *variant_declaration;
@@ -626,7 +667,8 @@ struct declaration_variant *ctf_declaration_variant_visit(FILE *fd,
                }
                variant_declaration = variant_declaration_new(name, declaration_scope);
                cds_list_for_each_entry(iter, declaration_list, siblings) {
-                       ret = ctf_variant_declaration_list_visit(fd, depth + 1, iter, variant_declaration);
+                       ret = ctf_variant_declaration_list_visit(fd, depth + 1, iter,
+                               variant_declaration, trace);
                        if (ret)
                                goto error;
                }
@@ -648,22 +690,98 @@ int ctf_enumerator_list_visit(int fd, int depth,
                struct ctf_node *enumerator,
                struct declaration_enum *enum_declaration)
 {
-       /* TODO */
-........
+       GQuark q;
+       struct ctf_node *iter;
+
+       q = g_quark_from_string(enumerator->u.enumerator.id);
+       if (enum_declaration->integer->signedness) {
+               int64_t start, end;
+               int nr_vals = 0;
+
+               cds_list_for_each_entry(iter, enumerator->u.enumerator.values, siblings) {
+                       int64_t *target;
+
+                       assert(iter->type == NODE_UNARY_EXPRESSION);
+                       if (nr_vals == 0)
+                               target = &start;
+                       else
+                               target = &end;
+
+                       switch (iter->u.unary_expression.type) {
+                       case UNARY_SIGNED_CONSTANT:
+                               *target = iter->u.unary_expression.u.signed_constant;
+                               break;
+                       case UNARY_UNSIGNED_CONSTANT:
+                               *target = iter->u.unary_expression.u.unsigned_constant;
+                               break;
+                       default:
+                               fprintf(stderr, "[error] %s: invalid enumerator\n", __func__);
+                               return -EINVAL;
+                       }
+                       if (nr_vals > 1) {
+                               fprintf(stderr, "[error] %s: invalid enumerator\n", __func__);
+                               return -EINVAL;
+                       }
+                       nr_vals++;
+               }
+               if (nr_vals == 1)
+                       end = start;
+               enum_signed_insert(enum_declaration, start, end, q);
+       } else
+               uint64_t start, end;
+               int nr_vals = 0;
+
+               cds_list_for_each_entry(iter, enumerator->u.enumerator.values, siblings) {
+                       int64_t *target;
+
+                       assert(iter->type == NODE_UNARY_EXPRESSION);
+                       if (nr_vals == 0)
+                               target = &start;
+                       else
+                               target = &end;
+
+                       switch (iter->u.unary_expression.type) {
+                       case UNARY_UNSIGNED_CONSTANT:
+                               *target = iter->u.unary_expression.u.unsigned_constant;
+                               break;
+                       case UNARY_SIGNED_CONSTANT:
+                               /*
+                                * We don't accept signed constants for enums with unsigned
+                                * container type.
+                                */
+                               fprintf(stderr, "[error] %s: invalid enumerator (signed constant encountered, but enum container type is unsigned)\n", __func__);
+                               return -EINVAL;
+                       default:
+                               fprintf(stderr, "[error] %s: invalid enumerator\n", __func__);
+                               return -EINVAL;
+                       }
+                       if (nr_vals > 1) {
+                               fprintf(stderr, "[error] %s: invalid enumerator\n", __func__);
+                               return -EINVAL;
+                       }
+                       nr_vals++;
+               }
+               if (nr_vals == 1)
+                       end = start;
+               enum_unsigned_insert(enum_declaration, start, end, q);
+       }
        return 0;
 }
 
 static
 struct declaration *ctf_declaration_enum_visit(int fd, int depth,
                        const char *name,
-                       struct ctf_node *container_type,
+                       struct cds_list_head *container_type,
                        struct cds_list_head *enumerator_list,
-                       int has_body)
+                       int has_body,
+                       struct declaration_scope *declaration_scope,
+                       struct ctf_trace *trace)
 {
        struct declaration *declaration;
        struct declaration_enum *enum_declaration;
        struct declaration_integer *integer_declaration;
-       struct ctf_node *iter;
+       struct ctf_node *iter, *first;
+       GQuark dummy_id;
 
        /*
         * For named enum (without body), lookup in
@@ -687,10 +805,27 @@ struct declaration *ctf_declaration_enum_visit(int fd, int depth,
                                return NULL;
                        }
                }
-
-               /* TODO CHECK Enumerations need to have their size/type specifier (< >). */
-               integer_declaration = integer_declaration_new(); /* TODO ... */
-               .....
+               if (cds_list_empty(container_type)) {
+                               fprintf(stderr, "[error] %s: missing container type for enumeration\n", __func__, name);
+                               return NULL;
+                       
+               }
+               first = _cds_list_first_entry(container_type, struct node, siblings);
+               switch (first->type) {
+               case NODE_INTEGER:
+               case NODE_TYPE_SPECIFIER:
+                       declaration = ctf_type_declarator_visit(fd, depth,
+                                               container_type,
+                                               &dummy_id, NULL,
+                                               declaration_scope,
+                                               NULL, trace);
+                       assert(declaration->id == CTF_TYPE_INTEGER);
+                       integer_declaration = container_of(declaration, struct declaration_integer, p);
+                       break;
+               }
+               default:
+                       assert(0);
+               }
                enum_declaration = enum_declaration_new(name, integer_declaration);
                declaration_unref(&integer_declaration->p);     /* leave ref to enum */
                cds_list_for_each_entry(iter, enumerator_list, siblings) {
@@ -731,12 +866,86 @@ struct declaration *ctf_declaration_type_specifier_visit(int fd, int depth,
        return declaration;
 }
 
+/*
+ * Returns 0/1 boolean, or < 0 on error.
+ */
+static
+int get_boolean(int fd, int depth, struct node *unary_expression)
+{
+       if (unary_expression->type != NODE_UNARY_EXPRESSION) {
+               fprintf(stderr, "[error] %s: expecting unary expression\n",
+                       __func__);
+               return -EINVAL;
+       }
+       switch (unary_expression->u.unary_expression.type) {
+       case UNARY_UNSIGNED_CONSTANT:
+               if (unary_expression->u.unary_expression.u.unsigned_constant == 0)
+                       return 0;
+               else
+                       return 1;
+       case UNARY_SIGNED_CONSTANT:
+               if (unary_expression->u.unary_expression.u.signed_constant == 0)
+                       return 0;
+               else
+                       return 1;
+       case UNARY_STRING:
+               if (!strcmp(unary_expression->u.unary_expression.u.string, "true"))
+                       return 1;
+               else if (!strcmp(unary_expression->u.unary_expression.u.string, "TRUE"))
+                       return 1;
+               else if (!strcmp(unary_expression->u.unary_expression.u.string, "false"))
+                       return 0;
+               else if (!strcmp(unary_expression->u.unary_expression.u.string, "FALSE"))
+                       return 0;
+               else {
+                       fprintf(stderr, "[error] %s: unexpected string \"%s\"\n",
+                               __func__, unary_expression->u.unary_expression.u.string);
+                       return -EINVAL;
+               }
+               break;
+       default:
+               fprintf(stderr, "[error] %s: unexpected unary expression type\n",
+                       __func__);
+               return -EINVAL;
+       } 
+
+}
+
+static
+int get_byte_order(int fd, int depth, struct node *unary_expression)
+{
+       int byte_order;
+
+       if (unary_expression->u.unary_expression.type != UNARY_STRING) {
+               fprintf(stderr, "[error] %s: byte_order: expecting string\n",
+                       __func__);
+               return -EINVAL;
+       }
+       if (!strcmp(unary_expression->u.unary_expression.u.string, "native"))
+               byte_order = trace->byte_order;
+       else if (!strcmp(unary_expression->u.unary_expression.u.string, "network"))
+               byte_order = BIG_ENDIAN;
+       else if (!strcmp(unary_expression->u.unary_expression.u.string, "be"))
+               byte_order = BIG_ENDIAN;
+       else if (!strcmp(unary_expression->u.unary_expression.u.string, "le"))
+               byte_order = LITTLE_ENDIAN;
+       else {
+               fprintf(stderr, "[error] %s: unexpected string \"%s\". Should be \"native\", \"network\", \"be\" or \"le\".\n",
+                       __func__, right->u.unary_expression.u.string);
+               return -EINVAL;
+       }
+       return byte_order;
+}
+
 static
 struct declaration *ctf_declaration_integer_visit(int fd, int depth,
-               struct cds_list_head *expressions)
+               struct cds_list_head *expressions,
+               struct ctf_trace *trace)
 {
        struct node *expression;
-       uint64_t alignment, size, byte_order = trace->native_bo, signedness = 0;
+       uint64_t alignment, size;
+       int byte_order = trace->byte_order;
+       int signedness = 0;
        int has_alignment = 0, has_size = 0;
        struct declaration_integer *integer_declaration;
 
@@ -747,13 +956,28 @@ struct declaration *ctf_declaration_integer_visit(int fd, int depth,
                right = expression->u.ctf_expression.right;
                assert(left->u.unary_expression.type == UNARY_STRING);
                if (!strcmp(left->u.unary_expression.u.string, "signed")) {
-                       /* TODO */
-       ...........
+                       signedness = get_boolean(fd, depth, right);
+                       if (signedness < 0)
+                               return NULL;
                } else if (!strcmp(left->u.unary_expression.u.string, "byte_order")) {
-
+                       byte_order = get_byte_order(fd, depth, right);
+                       if (byte_order < 0)
+                               return NULL;
                } else if (!strcmp(left->u.unary_expression.u.string, "size")) {
+                       if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
+                               fprintf(stderr, "[error] %s: size: expecting unsigned constant\n",
+                                       __func__);
+                               return NULL;
+                       }
+                       size = right->u.unary_expression.u.unsigned_constant;
                        has_size = 1;
                } else if (!strcmp(left->u.unary_expression.u.string, "align")) {
+                       if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
+                               fprintf(stderr, "[error] %s: align: expecting unsigned constant\n",
+                                       __func__);
+                               return NULL;
+                       }
+                       alignment = right->u.unary_expression.u.unsigned_constant;
                        has_alignment = 1;
                } else {
                        fprintf(stderr, "[error] %s: unknown attribute name %s\n",
@@ -761,26 +985,140 @@ struct declaration *ctf_declaration_integer_visit(int fd, int depth,
                        return NULL;
                }
        }
-       if (!has_alignment) {
-               fprintf(stderr, "[error] %s: missing alignment attribute\n", __func__);
-               return NULL;
-       }
        if (!has_size) {
                fprintf(stderr, "[error] %s: missing size attribute\n", __func__);
                return NULL;
        }
+       if (!has_alignment) {
+               if (size % CHAR_BIT) {
+                       /* bit-packed alignment */
+                       alignment = 1;
+               } else {
+                       /* byte-packed alignment */
+                       alignment = CHAR_BIT;
+               }
+       }
        integer_declaration = integer_declaration_new(size,
                                byte_order, signedness, alignment);
        return &integer_declaration->p;
 }
 
+static
+struct declaration *ctf_declaration_floating_point_visit(int fd, int depth,
+               struct cds_list_head *expressions,
+               struct ctf_trace *trace)
+{
+       struct node *expression;
+       uint64_t alignment, exp_dig, mant_dig, byte_order = trace->byte_order;
+       int has_alignment = 0, has_exp_dig = 0, has_mant_dig = 0;
+       struct declaration_float *float_declaration;
+
+       cds_list_for_each_entry(expression, expressions, siblings) {
+               struct node *left, *right;
+
+               left = expression->u.ctf_expression.left;
+               right = expression->u.ctf_expression.right;
+               assert(left->u.unary_expression.type == UNARY_STRING);
+               if (!strcmp(left->u.unary_expression.u.string, "byte_order")) {
+                       byte_order = get_byte_order(fd, depth, right);
+                       if (byte_order < 0)
+                               return NULL;
+               } else if (!strcmp(left->u.unary_expression.u.string, "exp_dig")) {
+                       if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
+                               fprintf(stderr, "[error] %s: exp_dig: expecting unsigned constant\n",
+                                       __func__);
+                               return NULL;
+                       }
+                       exp_dig = right->u.unary_expression.u.unsigned_constant;
+                       has_exp_dig = 1;
+               } else if (!strcmp(left->u.unary_expression.u.string, "mant_dig")) {
+                       if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
+                               fprintf(stderr, "[error] %s: mant_dig: expecting unsigned constant\n",
+                                       __func__);
+                               return NULL;
+                       }
+                       mant_dig = right->u.unary_expression.u.unsigned_constant;
+                       has_mant_dig = 1;
+               } else if (!strcmp(left->u.unary_expression.u.string, "align")) {
+                       if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
+                               fprintf(stderr, "[error] %s: align: expecting unsigned constant\n",
+                                       __func__);
+                               return NULL;
+                       }
+                       alignment = right->u.unary_expression.u.unsigned_constant;
+                       has_alignment = 1;
+               } else {
+                       fprintf(stderr, "[error] %s: unknown attribute name %s\n",
+                               __func__, left->u.unary_expression.u.string);
+                       return NULL;
+               }
+       }
+       if (!has_mant_dig) {
+               fprintf(stderr, "[error] %s: missing mant_dig attribute\n", __func__);
+               return NULL;
+       }
+       if (!has_exp_dig) {
+               fprintf(stderr, "[error] %s: missing exp_dig attribute\n", __func__);
+               return NULL;
+       }
+       if (!has_alignment) {
+               if ((mant_dig + exp_dig) % CHAR_BIT) {
+                       /* bit-packed alignment */
+                       alignment = 1;
+               } else {
+                       /* byte-packed alignment */
+                       alignment = CHAR_BIT;
+               }
+       }
+       float_declaration = float_declaration_new(mant_dig, exp_dig,
+                               byte_order, alignment);
+       return &float_declaration->p;
+}
+
+static
+struct declaration *ctf_declaration_string_visit(int fd, int depth,
+               struct cds_list_head *expressions,
+               struct ctf_trace *trace)
+{
+       struct node *expression;
+       const char *encoding_c = NULL;
+       enum ctf_string_encoding encoding = CTF_STRING_UTF8;
+       struct declaration_string *string_declaration;
+
+       cds_list_for_each_entry(expression, expressions, siblings) {
+               struct node *left, *right;
+
+               left = expression->u.ctf_expression.left;
+               right = expression->u.ctf_expression.right;
+               assert(left->u.unary_expression.type == UNARY_STRING);
+               if (!strcmp(left->u.unary_expression.u.string, "encoding")) {
+                       if (right->u.unary_expression.type != UNARY_UNSIGNED_STRING) {
+                               fprintf(stderr, "[error] %s: encoding: expecting string\n",
+                                       __func__);
+                               return NULL;
+                       }
+                       encoding_c = right->u.unary_expression.u.string;
+               } else {
+                       fprintf(stderr, "[error] %s: unknown attribute name %s\n",
+                               __func__, left->u.unary_expression.u.string);
+                       return NULL;
+               }
+       }
+       if (encoding_c && !strcmp(encoding_c, "ASCII"))
+               encoding = CTF_STRING_ASCII;
+       string_declaration = string_declaration_new(encoding);
+       return &string_declaration->p;
+}
+
+
 /*
  * Also add named variant, struct or enum to the current declaration scope.
  */
 static
 struct declaration *ctf_declaration_specifier_visit(FILE *fd,
                int depth, struct cds_list_head *head,
-               struct declaration_scope *declaration_scope)
+               struct declaration_scope *declaration_scope,
+               struct ctf_trace *trace)
 {
        struct declaration *declaration;
        struct node *first;
@@ -793,31 +1131,35 @@ struct declaration *ctf_declaration_specifier_visit(FILE *fd,
                        first->u._struct.name,
                        &first->u._struct.declaration_list,
                        first->u._struct.has_body,
-                       declaration_scope);
+                       declaration_scope,
+                       trace);
        case NODE_VARIANT:
                return ctf_declaration_variant_visit(fd, depth,
                        first->u.variant.name,
                        &first->u.variant.declaration_list,
                        first->u.variant.has_body,
-                       declaration_scope);
+                       declaration_scope,
+                       trace);
        case NODE_ENUM:
                return ctf_declaration_enum_visit(fd, depth,
                        first->u._enum.enum_id,
-                       first->u._enum.container_type,
+                       &first->u._enum.container_type,
                        &first->u._enum.enumerator_list,
-                       first->u._enum.has_body);
+                       first->u._enum.has_body,
+                       declaration_scope,
+                       trace);
        case NODE_INTEGER:
                return ctf_declaration_integer_visit(fd, depth,
-                       &first->u.integer.expressions);
-       case NODE_FLOATING_POINT:       /* TODO  */
+                       &first->u.integer.expressions, trace);
+       case NODE_FLOATING_POINT:
                return ctf_declaration_floating_point_visit(fd, depth,
-                       &first->u.floating_point.expressions);
-       case NODE_STRING:               /* TODO */
+                       &first->u.floating_point.expressions, trace);
+       case NODE_STRING:
                return ctf_declaration_string_visit(fd, depth,
-                       &first->u.string.expressions);
+                       &first->u.string.expressions, trace);
        case NODE_TYPE_SPECIFIER:
                return ctf_declaration_type_specifier_visit(fd, depth,
-                               head, declaration_scope);
+                               head, declaration_scope, trace);
        }
 }
 
@@ -890,7 +1232,7 @@ int ctf_event_declaration_visit(FILE *fd, int depth, struct ctf_node *node, stru
                                return -EPERM;
                        declaration = ctf_declaration_specifier_visit(fd, depth,
                                        &node->u.ctf_expression.right,
-                                       event->declaration_scope);
+                                       event->declaration_scope, trace);
                        if (!declaration)
                                return -EPERM;
                        if (declaration->type->id != CTF_TYPE_STRUCT)
@@ -903,7 +1245,7 @@ int ctf_event_declaration_visit(FILE *fd, int depth, struct ctf_node *node, stru
                                return -EPERM;
                        declaration = ctf_declaration_specifier_visit(fd, depth,
                                        &node->u.ctf_expression.right,
-                                       event->declaration_scope);
+                                       event->declaration_scope, trace);
                        if (!declaration)
                                return -EPERM;
                        if (declaration->type->id != CTF_TYPE_STRUCT)
@@ -1028,7 +1370,7 @@ int ctf_stream_declaration_visit(FILE *fd, int depth, struct ctf_node *node, str
 
                        declaration = ctf_declaration_specifier_visit(fd, depth,
                                        &node->u.ctf_expression.right,
-                                       stream->declaration_scope, stream->definition_scope);
+                                       stream->declaration_scope, stream->definition_scope, trace);
                        if (!declaration)
                                return -EPERM;
                        if (declaration->type->id != CTF_TYPE_STRUCT)
@@ -1039,7 +1381,7 @@ int ctf_stream_declaration_visit(FILE *fd, int depth, struct ctf_node *node, str
 
                        declaration = ctf_declaration_specifier_visit(fd, depth,
                                        &node->u.ctf_expression.right,
-                                       stream->declaration_scope);
+                                       stream->declaration_scope, trace);
                        if (!declaration)
                                return -EPERM;
                        if (declaration->type->id != CTF_TYPE_STRUCT)
@@ -1050,7 +1392,7 @@ int ctf_stream_declaration_visit(FILE *fd, int depth, struct ctf_node *node, str
 
                        declaration = ctf_declaration_specifier_visit(fd, depth,
                                        &node->u.ctf_expression.right,
-                                       stream->declaration_scope);
+                                       stream->declaration_scope, trace);
                        if (!declaration)
                                return -EPERM;
                        if (declaration->type->id != CTF_TYPE_STRUCT)
@@ -1256,11 +1598,14 @@ error:
        return ret;
 }
 
-int _ctf_visitor(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
+int ctf_visitor_construct_metadata(FILE *fd, int depth, struct ctf_node *node,
+               struct ctf_trace *trace, int byte_order)
 {
        int ret = 0;
        struct ctf_node *iter;
 
+       trace->byte_order = byte_order;
+
        switch (node->type) {
        case NODE_ROOT:
                cds_list_for_each_entry(iter, &node->u.root._typedef,
@@ -1282,7 +1627,7 @@ int _ctf_visitor(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *t
                }
                cds_list_for_each_entry(iter, &node->u.root.declaration_specifier, siblings) {
                        ret = ctf_declaration_specifier_visit(fd, depth, iter,
-                                       trace->root_declaration_scope);
+                                       trace->root_declaration_scope, trace);
                        if (ret)
                                return ret;
                }
This page took 0.043785 seconds and 4 git commands to generate.