X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=formats%2Fctf%2Fir%2Fevent-types.c;h=91ab78c86bc05a8196daab4ec2f95f34e9d21c8e;hb=46caf2cb05e3c88e0c42a8507aeb524b8d2fc6df;hp=316efa78fa086b95915eec7c382a139801d17769;hpb=4a1e8671a35f5881e7226c03c1ef2dbe1b2370f5;p=babeltrace.git diff --git a/formats/ctf/ir/event-types.c b/formats/ctf/ir/event-types.c index 316efa78..91ab78c8 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; } @@ -1288,6 +1286,8 @@ struct bt_ctf_field_type *bt_ctf_field_type_variant_create( } bt_ctf_field_type_init(&variant->parent); + /* A variant's alignment is undefined */ + variant->parent.declaration->alignment = 0; return &variant->parent; error: return NULL; @@ -1484,8 +1484,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 +1497,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 +1531,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 +1591,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 +1687,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 +1780,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 +1788,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: @@ -2039,6 +2130,35 @@ 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) @@ -2116,6 +2236,61 @@ int bt_ctf_field_type_variant_set_tag_field_path(struct bt_ctf_field_type *type, 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) { @@ -2280,9 +2455,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 @@ -2291,9 +2468,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 @@ -2302,6 +2481,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); } @@ -2312,6 +2493,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); }