X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=formats%2Fctf%2Fir%2Fevent-types.c;h=b336889b029efb208c525a17fb32e44b4301f048;hb=5cec03e402aaee5fe314e03f366363a617a7d0c8;hp=11ca0e9e0b44bf57e359c92d034a8a73aa66112a;hpb=d9b1ab6dad281d8ba70f6c8dd372ab489ea465c0;p=babeltrace.git diff --git a/formats/ctf/ir/event-types.c b/formats/ctf/ir/event-types.c index 11ca0e9e..b336889b 100644 --- a/formats/ctf/ir/event-types.c +++ b/formats/ctf/ir/event-types.c @@ -1172,11 +1172,6 @@ int bt_ctf_field_type_structure_add_field(struct bt_ctf_field_type *type, ret = -1; goto end; } - - if (type->declaration->alignment < field_type->declaration->alignment) { - type->declaration->alignment = - field_type->declaration->alignment; - } end: return ret; } @@ -1207,8 +1202,7 @@ int bt_ctf_field_type_structure_get_field(struct bt_ctf_field_type *type, struct structure_field *field; int ret = 0; - if (!type || index < 0 || !field_name || !field_type || - (type->declaration->id != CTF_TYPE_STRUCT)) { + if (!type || index < 0 || (type->declaration->id != CTF_TYPE_STRUCT)) { ret = -1; goto end; } @@ -1221,9 +1215,13 @@ int bt_ctf_field_type_structure_get_field(struct bt_ctf_field_type *type, } field = g_ptr_array_index(structure->fields, index); - *field_type = field->type; - bt_ctf_field_type_get(field->type); - *field_name = g_quark_to_string(field->name); + if (field_type) { + *field_type = field->type; + bt_ctf_field_type_get(field->type); + } + if (field_name) { + *field_name = g_quark_to_string(field->name); + } end: return ret; } @@ -1484,8 +1482,7 @@ int bt_ctf_field_type_variant_get_field(struct bt_ctf_field_type *type, struct structure_field *field; int ret = 0; - if (!type || index < 0 || !field_name || !field_type || - (type->declaration->id != CTF_TYPE_VARIANT)) { + if (!type || index < 0 || (type->declaration->id != CTF_TYPE_VARIANT)) { ret = -1; goto end; } @@ -1498,9 +1495,13 @@ int bt_ctf_field_type_variant_get_field(struct bt_ctf_field_type *type, } field = g_ptr_array_index(variant->fields, index); - *field_type = field->type; - bt_ctf_field_type_get(field->type); - *field_name = g_quark_to_string(field->name); + if (field_type) { + *field_type = field->type; + bt_ctf_field_type_get(field->type); + } + if (field_name) { + *field_name = g_quark_to_string(field->name); + } end: return ret; } @@ -1528,8 +1529,6 @@ struct bt_ctf_field_type *bt_ctf_field_type_array_create( array->element_type = element_type; array->length = length; bt_ctf_field_type_init(&array->parent); - array->parent.declaration->alignment = - element_type->declaration->alignment; return &array->parent; error: return NULL; @@ -1590,8 +1589,6 @@ struct bt_ctf_field_type *bt_ctf_field_type_sequence_create( sequence->element_type = element_type; sequence->length_field_name = g_string_new(length_field_name); bt_ctf_field_type_init(&sequence->parent); - sequence->parent.declaration->alignment = - element_type->declaration->alignment; return &sequence->parent; error: return NULL; @@ -1688,13 +1685,91 @@ end: int bt_ctf_field_type_get_alignment(struct bt_ctf_field_type *type) { int ret; + enum ctf_type_id type_id; if (!type) { ret = -1; goto end; } - ret = (int) type->declaration->alignment; + if (type->frozen) { + ret = (int) type->declaration->alignment; + goto end; + } + + type_id = bt_ctf_field_type_get_type_id(type); + switch (type_id) { + case CTF_TYPE_SEQUENCE: + { + struct bt_ctf_field_type *element = + bt_ctf_field_type_sequence_get_element_type(type); + + if (!element) { + ret = -1; + goto end; + } + + ret = bt_ctf_field_type_get_alignment(element); + bt_ctf_field_type_put(element); + break; + } + case CTF_TYPE_ARRAY: + { + struct bt_ctf_field_type *element = + bt_ctf_field_type_array_get_element_type(type); + + if (!element) { + ret = -1; + goto end; + } + + ret = bt_ctf_field_type_get_alignment(element); + bt_ctf_field_type_put(element); + break; + } + case CTF_TYPE_STRUCT: + { + int i, element_count; + + element_count = bt_ctf_field_type_structure_get_field_count( + type); + if (element_count < 0) { + ret = element_count; + goto end; + } + + for (i = 0; i < element_count; i++) { + struct bt_ctf_field_type *field; + int field_alignment; + + ret = bt_ctf_field_type_structure_get_field(type, NULL, + &field, i); + if (ret) { + goto end; + } + + assert(field); + field_alignment = bt_ctf_field_type_get_alignment( + field); + bt_ctf_field_type_put(field); + if (field_alignment < 0) { + ret = field_alignment; + goto end; + } + + type->declaration->alignment = MAX(field_alignment, + type->declaration->alignment); + } + ret = (int) type->declaration->alignment; + break; + } + case CTF_TYPE_UNKNOWN: + ret = -1; + break; + default: + ret = (int) type->declaration->alignment; + break; + } end: return ret; } @@ -1703,6 +1778,7 @@ int bt_ctf_field_type_set_alignment(struct bt_ctf_field_type *type, unsigned int alignment) { int ret = 0; + enum ctf_type_id type_id; /* Alignment must be bit-aligned (1) or byte aligned */ if (!type || type->frozen || (alignment != 1 && (alignment & 0x7))) { @@ -1710,12 +1786,25 @@ int bt_ctf_field_type_set_alignment(struct bt_ctf_field_type *type, goto end; } + type_id = bt_ctf_field_type_get_type_id(type); + if (type_id == CTF_TYPE_UNKNOWN) { + ret = -1; + goto end; + } + if (type->declaration->id == CTF_TYPE_STRING && alignment != CHAR_BIT) { ret = -1; goto end; } + if (type_id == CTF_TYPE_STRUCT || type_id == CTF_TYPE_VARIANT || + type_id == CTF_TYPE_SEQUENCE || type_id == CTF_TYPE_ARRAY) { + /* Setting an alignment on these types makes no sense */ + ret = -1; + goto end; + } + type->declaration->alignment = alignment; ret = 0; end: @@ -1955,6 +2044,251 @@ 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) +{ + int ret; + size_t index; + GQuark name_quark; + struct bt_ctf_field_type_structure *structure; + + if (!type || !name || + bt_ctf_field_type_get_type_id(type) != CTF_TYPE_STRUCT) { + ret = -1; + goto end; + } + + name_quark = g_quark_try_string(name); + if (!name_quark) { + ret = -1; + goto end; + } + + structure = container_of(type, struct bt_ctf_field_type_structure, + parent); + if (!g_hash_table_lookup_extended(structure->field_name_to_index, + GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) { + ret = -1; + goto end; + } + ret = (int) index; +end: + return ret; +} + +BT_HIDDEN +int bt_ctf_field_type_structure_set_field_index(struct bt_ctf_field_type *type, + struct bt_ctf_field_type *field, int index) +{ + int ret = 0; + struct bt_ctf_field_type_structure *structure; + + if (!type || !field || type->frozen || + bt_ctf_field_type_get_type_id(type) != CTF_TYPE_STRUCT) { + ret = -1; + goto end; + } + + structure = container_of(type, struct bt_ctf_field_type_structure, + parent); + if (index < 0 || index >= structure->fields->len) { + ret = -1; + goto end; + } + + bt_ctf_field_type_get(field); + bt_ctf_field_type_put(((struct structure_field *) + g_ptr_array_index(structure->fields, index))->type); + ((struct structure_field *) structure->fields->pdata[index])->type = + field; +end: + return ret; +} + +BT_HIDDEN +int bt_ctf_field_type_variant_get_field_name_index( + struct bt_ctf_field_type *type, const char *name) +{ + int ret; + size_t index; + GQuark name_quark; + struct bt_ctf_field_type_variant *variant; + + if (!type || !name || + bt_ctf_field_type_get_type_id(type) != CTF_TYPE_VARIANT) { + ret = -1; + goto end; + } + + name_quark = g_quark_try_string(name); + if (!name_quark) { + ret = -1; + goto end; + } + + variant = container_of(type, struct bt_ctf_field_type_variant, + parent); + if (!g_hash_table_lookup_extended(variant->field_name_to_index, + GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) { + ret = -1; + goto end; + } + ret = (int) index; +end: + return ret; +} + +BT_HIDDEN +int bt_ctf_field_type_sequence_set_length_field_path( + struct bt_ctf_field_type *type, + struct bt_ctf_field_path *path) +{ + int ret = 0; + struct bt_ctf_field_type_sequence *sequence; + + if (!type || bt_ctf_field_type_get_type_id(type) != CTF_TYPE_SEQUENCE) { + ret = -1; + goto end; + } + + 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; +end: + return ret; +} + +BT_HIDDEN +int bt_ctf_field_type_variant_set_tag_field_path(struct bt_ctf_field_type *type, + struct bt_ctf_field_path *path) +{ + int ret = 0; + struct bt_ctf_field_type_variant *variant; + + if (!type || bt_ctf_field_type_get_type_id(type) != CTF_TYPE_VARIANT) { + ret = -1; + goto end; + } + + 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; +end: + return ret; +} + +BT_HIDDEN +int bt_ctf_field_type_variant_set_tag(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) { + ret = -1; + goto end; + } + + variant = container_of(type, struct bt_ctf_field_type_variant, + parent); + bt_ctf_field_type_get(tag); + if (variant->tag) { + bt_ctf_field_type_put(&variant->tag->parent); + } + variant->tag = container_of(tag, struct bt_ctf_field_type_enumeration, + parent); +end: + return ret; +} + +BT_HIDDEN +int bt_ctf_field_type_variant_set_field_index(struct bt_ctf_field_type *type, + struct bt_ctf_field_type *field, int index) +{ + int ret = 0; + struct bt_ctf_field_type_variant *variant; + + if (!type || !field || type->frozen || + bt_ctf_field_type_get_type_id(type) != CTF_TYPE_VARIANT) { + ret = -1; + goto end; + } + + variant = container_of(type, struct bt_ctf_field_type_variant, + parent); + if (index < 0 || index >= variant->fields->len) { + ret = -1; + goto end; + } + + bt_ctf_field_type_get(field); + bt_ctf_field_type_put(((struct structure_field *) + g_ptr_array_index(variant->fields, index))->type); + ((struct structure_field *) variant->fields->pdata[index])->type = + field; +end: + return ret; +} + static void bt_ctf_field_type_integer_destroy(struct bt_ctf_ref *ref) { @@ -2038,6 +2372,7 @@ void bt_ctf_field_type_variant_destroy(struct bt_ctf_ref *ref) g_hash_table_destroy(variant->field_name_to_index); g_string_free(variant->tag_name, TRUE); bt_ctf_field_type_put(&variant->tag->parent); + bt_ctf_field_path_destroy(variant->tag_path); g_free(variant); } @@ -2071,6 +2406,7 @@ void bt_ctf_field_type_sequence_destroy(struct bt_ctf_ref *ref) struct bt_ctf_field_type_sequence, parent); bt_ctf_field_type_put(sequence->element_type); g_string_free(sequence->length_field_name, TRUE); + bt_ctf_field_path_destroy(sequence->length_field_path); g_free(sequence); } @@ -2117,9 +2453,11 @@ void bt_ctf_field_type_structure_freeze(struct bt_ctf_field_type *type) struct bt_ctf_field_type_structure *structure_type = container_of( type, struct bt_ctf_field_type_structure, parent); + /* Cache the alignment */ + type->declaration->alignment = bt_ctf_field_type_get_alignment(type); generic_field_type_freeze(type); - g_ptr_array_foreach(structure_type->fields, (GFunc)freeze_structure_field, - NULL); + g_ptr_array_foreach(structure_type->fields, + (GFunc) freeze_structure_field, NULL); } static @@ -2128,9 +2466,11 @@ void bt_ctf_field_type_variant_freeze(struct bt_ctf_field_type *type) struct bt_ctf_field_type_variant *variant_type = container_of( type, struct bt_ctf_field_type_variant, parent); + /* Cache the alignment */ + type->declaration->alignment = bt_ctf_field_type_get_alignment(type); generic_field_type_freeze(type); - g_ptr_array_foreach(variant_type->fields, (GFunc)freeze_structure_field, - NULL); + g_ptr_array_foreach(variant_type->fields, + (GFunc) freeze_structure_field, NULL); } static @@ -2139,6 +2479,8 @@ void bt_ctf_field_type_array_freeze(struct bt_ctf_field_type *type) struct bt_ctf_field_type_array *array_type = container_of( type, struct bt_ctf_field_type_array, parent); + /* Cache the alignment */ + type->declaration->alignment = bt_ctf_field_type_get_alignment(type); generic_field_type_freeze(type); bt_ctf_field_type_freeze(array_type->element_type); } @@ -2149,6 +2491,8 @@ void bt_ctf_field_type_sequence_freeze(struct bt_ctf_field_type *type) struct bt_ctf_field_type_sequence *sequence_type = container_of( type, struct bt_ctf_field_type_sequence, parent); + /* Cache the alignment */ + type->declaration->alignment = bt_ctf_field_type_get_alignment(type); generic_field_type_freeze(type); bt_ctf_field_type_freeze(sequence_type->element_type); } @@ -2854,6 +3198,13 @@ 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) { + goto error; + } + } end: if (copy_tag) { bt_ctf_field_type_put(copy_tag); @@ -2923,12 +3274,25 @@ struct bt_ctf_field_type *bt_ctf_field_type_sequence_copy( copy_sequence = container_of(copy, struct bt_ctf_field_type_sequence, parent); copy_sequence->declaration = sequence->declaration; + if (sequence->length_field_path) { + copy_sequence->length_field_path = bt_ctf_field_path_copy( + sequence->length_field_path); + if (!copy_sequence->length_field_path) { + goto error; + } + } end: if (copy_element) { bt_ctf_field_type_put(copy_element); } return copy; +error: + if (copy) { + bt_ctf_field_type_put(copy); + copy = NULL; + } + goto end; } static