X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=formats%2Fctf%2Fir%2Fevent-types.c;h=40c26da01d47cbed5966f1318712dc2529007d8e;hb=6a43d7325c8e5271a0fecc0b8bd2c557d98beaf9;hp=9b78c0dbfd5b43f02b0ad9184c5b7337ba26897e;hpb=736133f1ae231a5bf12d45be43066d6825450efe;p=babeltrace.git diff --git a/formats/ctf/ir/event-types.c b/formats/ctf/ir/event-types.c index 9b78c0db..40c26da0 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,56 @@ 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( @@ -2021,6 +2160,77 @@ int bt_ctf_field_type_variant_get_field_name_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; +} + static void bt_ctf_field_type_integer_destroy(struct bt_ctf_ref *ref) { @@ -2104,6 +2314,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); } @@ -2137,6 +2348,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); } @@ -2183,9 +2395,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 @@ -2194,9 +2408,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 @@ -2205,6 +2421,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); } @@ -2215,6 +2433,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); } @@ -2920,6 +3140,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); @@ -2989,12 +3216,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