X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=formats%2Fctf%2Fir%2Fevent-types.c;h=f4ac0ecfd0b774925960fb0da06f0e7f41b6f083;hb=b011f6b0d77e0a93fffa1b47ee32e1b07dd16a8a;hp=c750d2187a12a5534579d6f4d29a27b48f9f7651;hpb=265e809cb65022c2d9f15c0ddc0d607445621b76;p=babeltrace.git diff --git a/formats/ctf/ir/event-types.c b/formats/ctf/ir/event-types.c index c750d218..f4ac0ecf 100644 --- a/formats/ctf/ir/event-types.c +++ b/formats/ctf/ir/event-types.c @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -267,6 +268,29 @@ int (* const type_compare_funcs[])(struct bt_ctf_field_type *, [CTF_TYPE_STRING] = bt_ctf_field_type_string_compare, }; +static +int bt_ctf_field_type_enumeration_validate(struct bt_ctf_field_type *); +static +int bt_ctf_field_type_structure_validate(struct bt_ctf_field_type *); +static +int bt_ctf_field_type_variant_validate(struct bt_ctf_field_type *); +static +int bt_ctf_field_type_array_validate(struct bt_ctf_field_type *); +static +int bt_ctf_field_type_sequence_validate(struct bt_ctf_field_type *); + +static +int (* const type_validate_funcs[])(struct bt_ctf_field_type *) = { + [CTF_TYPE_INTEGER] = NULL, + [CTF_TYPE_FLOAT] = NULL, + [CTF_TYPE_STRING] = NULL, + [CTF_TYPE_ENUM] = bt_ctf_field_type_enumeration_validate, + [CTF_TYPE_STRUCT] = bt_ctf_field_type_structure_validate, + [CTF_TYPE_VARIANT] = bt_ctf_field_type_variant_validate, + [CTF_TYPE_ARRAY] = bt_ctf_field_type_array_validate, + [CTF_TYPE_SEQUENCE] = bt_ctf_field_type_sequence_validate, +}; + static void destroy_enumeration_mapping(struct enumeration_mapping *mapping) { @@ -399,51 +423,228 @@ void bt_ctf_field_type_destroy(struct bt_object *obj) type_destroy_funcs[type_id](type); } -BT_HIDDEN -int bt_ctf_field_type_validate(struct bt_ctf_field_type *type) +static +int bt_ctf_field_type_enumeration_validate(struct bt_ctf_field_type *type) { int ret = 0; - if (!type) { + struct bt_ctf_field_type_enumeration *enumeration = + container_of(type, struct bt_ctf_field_type_enumeration, + parent); + struct bt_ctf_field_type *container_type = + bt_ctf_field_type_enumeration_get_container_type(type); + + if (!container_type) { ret = -1; goto end; } - switch (type->declaration->id) { - case CTF_TYPE_ENUM: - { - struct bt_ctf_field_type_enumeration *enumeration = - container_of(type, struct bt_ctf_field_type_enumeration, - parent); + ret = bt_ctf_field_type_validate(container_type); + if (ret) { + goto end; + } - /* Ensure enum has entries */ - ret = enumeration->entries->len ? 0 : -1; - break; + /* Ensure enum has entries */ + ret = enumeration->entries->len ? 0 : -1; + +end: + BT_PUT(container_type); + return ret; +} + +static +int bt_ctf_field_type_sequence_validate(struct bt_ctf_field_type *type) +{ + int ret = 0; + struct bt_ctf_field_type *element_type = NULL; + struct bt_ctf_field_type_sequence *sequence = + container_of(type, struct bt_ctf_field_type_sequence, + parent); + + /* Length field name should be set at this point */ + if (sequence->length_field_name->len == 0) { + ret = -1; + goto end; } - case CTF_TYPE_SEQUENCE: - { - struct bt_ctf_field_type_sequence *sequence = - container_of(type, struct bt_ctf_field_type_sequence, + + element_type = bt_ctf_field_type_sequence_get_element_type(type); + if (!element_type) { + ret = -1; + goto end; + } + + ret = bt_ctf_field_type_validate(element_type); + +end: + BT_PUT(element_type); + + return ret; +} + +static +int bt_ctf_field_type_array_validate(struct bt_ctf_field_type *type) +{ + int ret = 0; + struct bt_ctf_field_type *element_type = NULL; + + element_type = bt_ctf_field_type_array_get_element_type(type); + if (!element_type) { + ret = -1; + goto end; + } + + ret = bt_ctf_field_type_validate(element_type); + +end: + BT_PUT(element_type); + + return ret; +} + +static +int bt_ctf_field_type_structure_validate(struct bt_ctf_field_type *type) +{ + int ret = 0; + struct bt_ctf_field_type *child_type = NULL; + int field_count = bt_ctf_field_type_structure_get_field_count(type); + int i; + + if (field_count < 0) { + ret = -1; + goto end; + } + + for (i = 0; i < field_count; ++i) { + ret = bt_ctf_field_type_structure_get_field(type, + NULL, &child_type, i); + if (ret) { + goto end; + } + + ret = bt_ctf_field_type_validate(child_type); + if (ret) { + goto end; + } + + BT_PUT(child_type); + } + +end: + BT_PUT(child_type); + + return ret; +} + +static +int bt_ctf_field_type_variant_validate(struct bt_ctf_field_type *type) +{ + int ret = 0; + int field_count; + struct bt_ctf_field_type *child_type = NULL; + struct bt_ctf_field_type_variant *variant = + container_of(type, struct bt_ctf_field_type_variant, parent); + int i; + int tag_mappings_count; - /* length field name should be set at this point */ - ret = sequence->length_field_name->len ? 0 : -1; - break; + if (variant->tag_name->len == 0 || !variant->tag) { + ret = -1; + goto end; + } + + tag_mappings_count = + bt_ctf_field_type_enumeration_get_mapping_count( + (struct bt_ctf_field_type *) variant->tag); + + if (tag_mappings_count != variant->fields->len) { + ret = -1; + goto end; } - case CTF_TYPE_VARIANT: - { - struct bt_ctf_field_type_variant *variant = - container_of(type, struct bt_ctf_field_type_variant, - parent); - if (variant->tag_name->len == 0 || !variant->tag) { + for (i = 0; i < tag_mappings_count; ++i) { + const char *label; + int64_t range_start, range_end; + struct bt_ctf_field_type *ft; + + ret = bt_ctf_field_type_enumeration_get_mapping( + (struct bt_ctf_field_type *) variant->tag, + i, &label, &range_start, &range_end); + if (ret) { + goto end; + } + if (!label) { ret = -1; + goto end; } - break; + + ft = bt_ctf_field_type_variant_get_field_type_by_name( + type, label); + if (!ft) { + ret = -1; + goto end; + } + + BT_PUT(ft); } - default: - break; + + field_count = bt_ctf_field_type_variant_get_field_count(type); + if (field_count < 0) { + ret = -1; + goto end; + } + + for (i = 0; i < field_count; ++i) { + ret = bt_ctf_field_type_variant_get_field(type, + NULL, &child_type, i); + if (ret) { + goto end; + } + + ret = bt_ctf_field_type_validate(child_type); + if (ret) { + goto end; + } + + BT_PUT(child_type); + } + +end: + BT_PUT(child_type); + + return ret; +} + +/* + * This function validates a given field type without considering + * where this field type is located. It only validates the properties + * of the given field type and the properties of its children if + * applicable. + */ +BT_HIDDEN +int bt_ctf_field_type_validate(struct bt_ctf_field_type *type) +{ + int ret = 0; + enum ctf_type_id id = bt_ctf_field_type_get_type_id(type); + + if (!type) { + ret = -1; + goto end; + } + + if (type->valid) { + /* Already marked as valid */ + goto end; + } + + if (type_validate_funcs[id]) { + ret = type_validate_funcs[id](type); + } + + if (!ret && type->frozen) { + /* Field type is valid */ + type->valid = 1; } + end: return ret; } @@ -1189,8 +1390,7 @@ int bt_ctf_field_type_structure_add_field(struct bt_ctf_field_type *type, if (!type || !field_type || type->frozen || bt_ctf_validate_identifier(field_name) || - (type->declaration->id != CTF_TYPE_STRUCT) || - bt_ctf_field_type_validate(field_type)) { + (type->declaration->id != CTF_TYPE_STRUCT)) { ret = -1; goto end; } @@ -1394,8 +1594,7 @@ int bt_ctf_field_type_variant_add_field(struct bt_ctf_field_type *type, if (!type || !field_type || type->frozen || bt_ctf_validate_identifier(field_name) || - (type->declaration->id != CTF_TYPE_VARIANT) || - bt_ctf_field_type_validate(field_type)) { + (type->declaration->id != CTF_TYPE_VARIANT)) { ret = -1; goto end; } @@ -1544,8 +1743,7 @@ struct bt_ctf_field_type *bt_ctf_field_type_array_create( { struct bt_ctf_field_type_array *array = NULL; - if (!element_type || length == 0 || - bt_ctf_field_type_validate(element_type)) { + if (!element_type || length == 0) { goto error; } @@ -1631,8 +1829,7 @@ struct bt_ctf_field_type *bt_ctf_field_type_sequence_create( { struct bt_ctf_field_type_sequence *sequence = NULL; - if (!element_type || bt_ctf_validate_identifier(length_field_name) || - bt_ctf_field_type_validate(element_type)) { + if (!element_type || bt_ctf_validate_identifier(length_field_name)) { goto error; } @@ -2123,6 +2320,13 @@ int bt_ctf_field_type_serialize(struct bt_ctf_field_type *type, goto end; } + /* Make sure field type is valid before serializing it */ + ret = bt_ctf_field_type_validate(type); + + if (ret) { + goto end; + } + ret = type->serialize(type, context); end: return ret; @@ -2157,57 +2361,6 @@ end: return copy; } -BT_HIDDEN -struct bt_ctf_field_path *bt_ctf_field_path_create(void) -{ - struct bt_ctf_field_path *field_path = NULL; - - field_path = g_new0(struct bt_ctf_field_path, 1); - if (!field_path) { - goto end; - } - - field_path->root = CTF_NODE_UNKNOWN; - field_path->path_indexes = g_array_new(TRUE, FALSE, sizeof(int)); - if (!field_path->path_indexes) { - bt_ctf_field_path_destroy(field_path); - field_path = NULL; - } -end: - return field_path; -} - - -BT_HIDDEN -struct bt_ctf_field_path *bt_ctf_field_path_copy( - struct bt_ctf_field_path *path) -{ - struct bt_ctf_field_path *new_path = bt_ctf_field_path_create(); - - if (!new_path) { - goto end; - } - - new_path->root = path->root; - g_array_insert_vals(new_path->path_indexes, 0, - path->path_indexes->data, path->path_indexes->len); -end: - return new_path; -} - -BT_HIDDEN -void bt_ctf_field_path_destroy(struct bt_ctf_field_path *path) -{ - if (!path) { - return; - } - - if (path->path_indexes) { - g_array_free(path->path_indexes, TRUE); - } - g_free(path); -} - BT_HIDDEN int bt_ctf_field_type_structure_get_field_name_index( struct bt_ctf_field_type *type, const char *name) @@ -2318,26 +2471,12 @@ int bt_ctf_field_type_sequence_set_length_field_path( sequence = container_of(type, struct bt_ctf_field_type_sequence, parent); - if (sequence->length_field_path) { - bt_ctf_field_path_destroy(sequence->length_field_path); - } - sequence->length_field_path = path; + bt_get(path); + BT_MOVE(sequence->length_field_path, path); end: return ret; } -BT_HIDDEN -struct bt_ctf_field_path *bt_ctf_field_type_sequence_get_length_field_path( - struct bt_ctf_field_type *type) -{ - struct bt_ctf_field_type_sequence *sequence; - - sequence = container_of(type, struct bt_ctf_field_type_sequence, - parent); - - return sequence->length_field_path; -} - BT_HIDDEN int bt_ctf_field_type_variant_set_tag_field_path(struct bt_ctf_field_type *type, struct bt_ctf_field_path *path) @@ -2352,35 +2491,21 @@ int bt_ctf_field_type_variant_set_tag_field_path(struct bt_ctf_field_type *type, variant = container_of(type, struct bt_ctf_field_type_variant, parent); - if (variant->tag_path) { - bt_ctf_field_path_destroy(variant->tag_path); - } - variant->tag_path = path; + bt_get(path); + BT_MOVE(variant->tag_field_path, path); end: return ret; } BT_HIDDEN -struct bt_ctf_field_path *bt_ctf_field_type_variant_get_tag_field_path( - struct bt_ctf_field_type *type) -{ - struct bt_ctf_field_type_variant *variant; - - variant = container_of(type, struct bt_ctf_field_type_variant, - parent); - - return variant->tag_path; -} - -BT_HIDDEN -int bt_ctf_field_type_variant_set_tag(struct bt_ctf_field_type *type, +int bt_ctf_field_type_variant_set_tag_field_type(struct bt_ctf_field_type *type, struct bt_ctf_field_type *tag) { int ret = 0; struct bt_ctf_field_type_variant *variant; - if (!type || !tag || type->frozen || - bt_ctf_field_type_get_type_id(tag) != CTF_TYPE_ENUM) { + if (!type || !tag || + bt_ctf_field_type_get_type_id(tag) != CTF_TYPE_ENUM) { ret = -1; goto end; } @@ -2497,7 +2622,7 @@ void bt_ctf_field_type_variant_destroy(struct bt_ctf_field_type *type) g_hash_table_destroy(variant->field_name_to_index); g_string_free(variant->tag_name, TRUE); bt_put(&variant->tag->parent); - bt_ctf_field_path_destroy(variant->tag_path); + BT_PUT(variant->tag_field_path); g_free(variant); } @@ -2527,7 +2652,7 @@ void bt_ctf_field_type_sequence_destroy(struct bt_ctf_field_type *type) bt_put(sequence->element_type); g_string_free(sequence->length_field_name, TRUE); - bt_ctf_field_path_destroy(sequence->length_field_path); + BT_PUT(sequence->length_field_path); g_free(sequence); } @@ -2707,11 +2832,6 @@ int bt_ctf_field_type_enumeration_serialize(struct bt_ctf_field_type *type, struct bt_ctf_field_type *container_type; int container_signed; - ret = bt_ctf_field_type_validate(type); - if (ret) { - goto end; - } - container_type = bt_ctf_field_type_enumeration_get_container_type(type); if (!container_type) { ret = -1; @@ -3236,6 +3356,9 @@ struct bt_ctf_field_type *bt_ctf_field_type_floating_point_copy( copy_float->mantissa = floating_point->mantissa; copy_float->exp = floating_point->exp; copy_float->user_byte_order = floating_point->user_byte_order; + copy_float->declaration.sign = ©_float->sign; + copy_float->declaration.mantissa = ©_float->mantissa; + copy_float->declaration.exp = ©_float->exp; end: return copy; } @@ -3353,10 +3476,10 @@ struct bt_ctf_field_type *bt_ctf_field_type_variant_copy( } copy_variant->declaration = variant->declaration; - if (variant->tag_path) { - copy_variant->tag_path = bt_ctf_field_path_copy( - variant->tag_path); - if (!copy_variant->tag_path) { + if (variant->tag_field_path) { + copy_variant->tag_field_path = bt_ctf_field_path_copy( + variant->tag_field_path); + if (!copy_variant->tag_field_path) { goto error; } } @@ -3709,8 +3832,6 @@ int bt_ctf_field_type_structure_compare(struct bt_ctf_field_type *type_a, if (ret) { goto end; } - - ret = 1; } /* Equal */ @@ -3764,8 +3885,6 @@ int bt_ctf_field_type_variant_compare(struct bt_ctf_field_type *type_a, if (ret) { goto end; } - - ret = 1; } /* Equal */ @@ -3859,3 +3978,119 @@ int bt_ctf_field_type_compare(struct bt_ctf_field_type *type_a, end: return ret; } + +BT_HIDDEN +int bt_ctf_field_type_get_field_count(struct bt_ctf_field_type *field_type) +{ + int field_count = -1; + enum ctf_type_id type_id = bt_ctf_field_type_get_type_id(field_type); + + switch (type_id) { + case CTF_TYPE_STRUCT: + field_count = + bt_ctf_field_type_structure_get_field_count(field_type); + break; + case CTF_TYPE_VARIANT: + field_count = + bt_ctf_field_type_variant_get_field_count(field_type); + break; + case CTF_TYPE_ARRAY: + case CTF_TYPE_SEQUENCE: + /* + * Array and sequence types always contain a single member + * (the element type). + */ + field_count = 1; + break; + default: + break; + } + + return field_count; +} + +BT_HIDDEN +struct bt_ctf_field_type *bt_ctf_field_type_get_field_at_index( + struct bt_ctf_field_type *field_type, int index) +{ + struct bt_ctf_field_type *field = NULL; + enum ctf_type_id type_id = bt_ctf_field_type_get_type_id(field_type); + + switch (type_id) { + case CTF_TYPE_STRUCT: + bt_ctf_field_type_structure_get_field(field_type, NULL, &field, + index); + break; + case CTF_TYPE_VARIANT: + bt_ctf_field_type_variant_get_field(field_type, NULL, + &field, index); + break; + case CTF_TYPE_ARRAY: + field = bt_ctf_field_type_array_get_element_type(field_type); + break; + case CTF_TYPE_SEQUENCE: + field = bt_ctf_field_type_sequence_get_element_type(field_type); + break; + default: + break; + } + + return field; +} + +BT_HIDDEN +int bt_ctf_field_type_get_field_index(struct bt_ctf_field_type *field_type, + const char *name) +{ + int field_index = -1; + enum ctf_type_id type_id = bt_ctf_field_type_get_type_id(field_type); + + switch (type_id) { + case CTF_TYPE_STRUCT: + field_index = bt_ctf_field_type_structure_get_field_name_index( + field_type, name); + break; + case CTF_TYPE_VARIANT: + field_index = bt_ctf_field_type_variant_get_field_name_index( + field_type, name); + break; + default: + break; + } + + return field_index; +} + +struct bt_ctf_field_path *bt_ctf_field_type_variant_get_tag_field_path( + struct bt_ctf_field_type *type) +{ + struct bt_ctf_field_path *field_path = NULL; + struct bt_ctf_field_type_variant *variant; + + if (!type || !bt_ctf_field_type_is_variant(type)) { + goto end; + } + + variant = container_of(type, struct bt_ctf_field_type_variant, + parent); + field_path = bt_get(variant->tag_field_path); +end: + return field_path; +} + +struct bt_ctf_field_path *bt_ctf_field_type_sequence_get_length_field_path( + struct bt_ctf_field_type *type) +{ + struct bt_ctf_field_path *field_path = NULL; + struct bt_ctf_field_type_sequence *sequence; + + if (!type || !bt_ctf_field_type_is_sequence(type)) { + goto end; + } + + sequence = container_of(type, struct bt_ctf_field_type_sequence, + parent); + field_path = bt_get(sequence->length_field_path); +end: + return field_path; +}