X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;ds=sidebyside;f=formats%2Fctf%2Fir%2Ffield-types.c;h=02a47b366d900cb0d5e1aa29019ab5a00558d480;hb=f3985ab106d89d8e764c1a8dd0c8bda09b755d10;hp=1613dd19178ea2f9e7e19d4085982b2a3d62753d;hpb=2e33ac5abec88a4be03907091474324dfcc42e23;p=babeltrace.git diff --git a/formats/ctf/ir/field-types.c b/formats/ctf/ir/field-types.c index 1613dd19..02a47b36 100644 --- a/formats/ctf/ir/field-types.c +++ b/formats/ctf/ir/field-types.c @@ -30,7 +30,8 @@ #include #include #include -#include +#include +#include #include #include #include @@ -90,6 +91,8 @@ void (* const type_destroy_funcs[])(struct bt_ctf_field_type *) = { static void generic_field_type_freeze(struct bt_ctf_field_type *); static +void bt_ctf_field_type_integer_freeze(struct bt_ctf_field_type *); +static void bt_ctf_field_type_enumeration_freeze(struct bt_ctf_field_type *); static void bt_ctf_field_type_structure_freeze(struct bt_ctf_field_type *); @@ -102,7 +105,7 @@ void bt_ctf_field_type_sequence_freeze(struct bt_ctf_field_type *); static type_freeze_func const type_freeze_funcs[] = { - [BT_CTF_TYPE_ID_INTEGER] = generic_field_type_freeze, + [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_type_integer_freeze, [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_type_enumeration_freeze, [BT_CTF_TYPE_ID_FLOAT] = generic_field_type_freeze, [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_type_structure_freeze, @@ -267,6 +270,8 @@ int (* const type_compare_funcs[])(struct bt_ctf_field_type *, [BT_CTF_TYPE_ID_STRING] = bt_ctf_field_type_string_compare, }; +static +int bt_ctf_field_type_integer_validate(struct bt_ctf_field_type *); static int bt_ctf_field_type_enumeration_validate(struct bt_ctf_field_type *); static @@ -280,7 +285,7 @@ int bt_ctf_field_type_sequence_validate(struct bt_ctf_field_type *); static int (* const type_validate_funcs[])(struct bt_ctf_field_type *) = { - [BT_CTF_TYPE_ID_INTEGER] = NULL, + [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_type_integer_validate, [BT_CTF_TYPE_ID_FLOAT] = NULL, [BT_CTF_TYPE_ID_STRING] = NULL, [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_type_enumeration_validate, @@ -399,8 +404,8 @@ int add_structure_field(GPtrArray *fields, field->name = name_quark; field->type = field_type; g_hash_table_insert(field_name_to_index, - (gpointer) (unsigned long) name_quark, - (gpointer) (unsigned long) fields->len); + GUINT_TO_POINTER(name_quark), + GUINT_TO_POINTER(fields->len)); g_ptr_array_add(fields, field); end: return ret; @@ -422,6 +427,89 @@ void bt_ctf_field_type_destroy(struct bt_object *obj) type_destroy_funcs[type_id](type); } +static +int bt_ctf_field_type_integer_validate(struct bt_ctf_field_type *type) +{ + int ret = 0; + + struct bt_ctf_field_type_integer *integer = + container_of(type, struct bt_ctf_field_type_integer, + parent); + + if (integer->mapped_clock && integer->declaration.signedness) { + ret = -1; + goto end; + } + +end: + return ret; +} + +static +struct enumeration_mapping *get_enumeration_mapping( + struct bt_ctf_field_type *type, int index) +{ + struct enumeration_mapping *mapping = NULL; + struct bt_ctf_field_type_enumeration *enumeration; + + enumeration = container_of(type, struct bt_ctf_field_type_enumeration, + parent); + if (index >= enumeration->entries->len) { + goto end; + } + + mapping = g_ptr_array_index(enumeration->entries, index); +end: + return mapping; +} + +/* + * Note: This algorithm is O(n^2) vs number of enumeration mappings. + * Only used when freezing an enumeration. + */ +static +void set_enumeration_range_overlap( + struct bt_ctf_field_type *type) +{ + int i, j, len; + struct bt_ctf_field_type *container_type; + struct bt_ctf_field_type_enumeration *enumeration_type; + int is_signed; + + enumeration_type = container_of(type, + struct bt_ctf_field_type_enumeration, parent); + + len = enumeration_type->entries->len; + container_type = enumeration_type->container; + is_signed = bt_ctf_field_type_integer_get_signed(container_type); + + for (i = 0; i < len; i++) { + for (j = i + 1; j < len; j++) { + struct enumeration_mapping *mapping[2]; + + mapping[0] = get_enumeration_mapping(type, i); + mapping[1] = get_enumeration_mapping(type, j); + if (is_signed) { + if (mapping[0]->range_start._signed + <= mapping[1]->range_end._signed + && mapping[0]->range_end._signed + >= mapping[1]->range_start._signed) { + enumeration_type->has_overlapping_ranges = true; + return; + } + } else { + if (mapping[0]->range_start._unsigned + <= mapping[1]->range_end._unsigned + && mapping[0]->range_end._unsigned + >= mapping[1]->range_start._unsigned) { + enumeration_type->has_overlapping_ranges = true; + return; + } + } + } + } +} + static int bt_ctf_field_type_enumeration_validate(struct bt_ctf_field_type *type) { @@ -534,6 +622,43 @@ end: return ret; } +static +bool bt_ctf_field_type_enumeration_has_overlapping_ranges( + struct bt_ctf_field_type_enumeration *enumeration_type) +{ + if (!enumeration_type->parent.frozen) { + set_enumeration_range_overlap(&enumeration_type->parent); + } + return enumeration_type->has_overlapping_ranges; +} + +static +int bt_ctf_field_type_enumeration_get_mapping_name( + struct bt_ctf_field_type *enum_field_type, + int index, + const char **mapping_name) +{ + int ret = 0; + struct enumeration_mapping *mapping; + + if (!enum_field_type || index < 0) { + ret = -1; + goto end; + } + + mapping = get_enumeration_mapping(enum_field_type, index); + if (!mapping) { + ret = -1; + goto end; + } + + if (mapping_name) { + *mapping_name = g_quark_to_string(mapping->string); + } +end: + return ret; +} + static int bt_ctf_field_type_variant_validate(struct bt_ctf_field_type *type) { @@ -551,6 +676,12 @@ int bt_ctf_field_type_variant_validate(struct bt_ctf_field_type *type) goto end; } + if (bt_ctf_field_type_enumeration_has_overlapping_ranges( + variant->tag)) { + ret = -1; + goto end; + } + tag_mappings_count = bt_ctf_field_type_enumeration_get_mapping_count( (struct bt_ctf_field_type *) variant->tag); @@ -562,12 +693,11 @@ int bt_ctf_field_type_variant_validate(struct bt_ctf_field_type *type) 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( + ret = bt_ctf_field_type_enumeration_get_mapping_name( (struct bt_ctf_field_type *) variant->tag, - i, &label, &range_start, &range_end); + i, &label); if (ret) { goto end; } @@ -797,39 +927,329 @@ end: return ret; } -struct bt_ctf_clock *bt_ctf_field_type_integer_get_mapped_clock( +struct bt_ctf_clock_class *bt_ctf_field_type_integer_get_mapped_clock_class( struct bt_ctf_field_type *type) { struct bt_ctf_field_type_integer *integer; - struct bt_ctf_clock *clock = NULL; + struct bt_ctf_clock_class *clock_class = NULL; if (!type) { goto end; } integer = container_of(type, struct bt_ctf_field_type_integer, parent); - clock = integer->mapped_clock; - bt_get(clock); + clock_class = integer->mapped_clock; + bt_get(clock_class); end: - return clock; + return clock_class; } -int bt_ctf_field_type_integer_set_mapped_clock( +int bt_ctf_field_type_integer_set_mapped_clock_class( struct bt_ctf_field_type *type, - struct bt_ctf_clock *clock) + struct bt_ctf_clock_class *clock_class) { struct bt_ctf_field_type_integer *integer; int ret = 0; - if (!type || type->frozen) { + if (!type || type->frozen || !bt_ctf_clock_class_is_valid(clock_class)) { ret = -1; goto end; } integer = container_of(type, struct bt_ctf_field_type_integer, parent); bt_put(integer->mapped_clock); - bt_get(clock); - integer->mapped_clock = clock; + integer->mapped_clock = bt_get(clock_class); +end: + return ret; +} + +static +void bt_ctf_field_type_enum_iter_destroy(struct bt_object *obj) +{ + struct bt_ctf_field_type_enumeration_mapping_iterator *iter = + container_of(obj, + struct bt_ctf_field_type_enumeration_mapping_iterator, + base); + + bt_put(&iter->enumeration_type->parent); + g_free(iter); +} + +static +struct bt_ctf_field_type_enumeration_mapping_iterator * +bt_ctf_field_type_enumeration_find_mappings_type( + struct bt_ctf_field_type *type, + enum bt_ctf_field_type_enumeration_mapping_iterator_type iterator_type) +{ + struct bt_ctf_field_type_enumeration *enumeration_type; + struct bt_ctf_field_type_enumeration_mapping_iterator *iter = NULL; + + if (!type || (type->declaration->id != BT_CTF_TYPE_ID_ENUM)) { + goto end; + } + + enumeration_type = container_of(type, + struct bt_ctf_field_type_enumeration, parent); + iter = g_new0(struct bt_ctf_field_type_enumeration_mapping_iterator, 1); + if (!iter) { + goto end; + } + + bt_object_init(&iter->base, bt_ctf_field_type_enum_iter_destroy); + bt_get(type); + iter->enumeration_type = enumeration_type; + iter->index = -1; + iter->type = iterator_type; +end: + return iter; +} + +struct bt_ctf_field_type_enumeration_mapping_iterator * +bt_ctf_field_type_enumeration_find_mappings_by_name( + struct bt_ctf_field_type *type, const char *name) +{ + struct bt_ctf_field_type_enumeration_mapping_iterator *iter; + + iter = bt_ctf_field_type_enumeration_find_mappings_type( + type, ITERATOR_BY_NAME); + if (!iter) { + goto error; + } + + iter->u.name_quark = g_quark_try_string(name); + if (!iter->u.name_quark) { + goto error; + } + + /* Advance iterator to first entry, or leave index at -1. */ + if (bt_ctf_field_type_enumeration_mapping_iterator_next(iter)) { + /* No entry found. */ + goto error; + } + + return iter; +error: + bt_put(iter); + return NULL; +} + +int bt_ctf_field_type_enumeration_mapping_iterator_next( + struct bt_ctf_field_type_enumeration_mapping_iterator *iter) +{ + struct bt_ctf_field_type_enumeration *enumeration; + struct bt_ctf_field_type *type; + int i, ret = 0, len; + + enumeration = iter->enumeration_type; + type = &enumeration->parent; + len = enumeration->entries->len; + for (i = iter->index + 1; i < len; i++) { + struct enumeration_mapping *mapping = + get_enumeration_mapping(type, i); + + switch (iter->type) { + case ITERATOR_BY_NAME: + if (mapping->string == iter->u.name_quark) { + iter->index = i; + goto end; + } + break; + case ITERATOR_BY_SIGNED_VALUE: + { + int64_t value = iter->u.signed_value; + + if (value >= mapping->range_start._signed && + value <= mapping->range_end._signed) { + iter->index = i; + goto end; + } + break; + } + case ITERATOR_BY_UNSIGNED_VALUE: + { + uint64_t value = iter->u.unsigned_value; + + if (value >= mapping->range_start._unsigned && + value <= mapping->range_end._unsigned) { + iter->index = i; + goto end; + } + break; + } + default: + abort(); + } + } + + ret = -1; +end: + return ret; +} + +struct bt_ctf_field_type_enumeration_mapping_iterator * +bt_ctf_field_type_enumeration_find_mappings_by_signed_value( + struct bt_ctf_field_type *type, int64_t value) +{ + struct bt_ctf_field_type_enumeration_mapping_iterator *iter; + + iter = bt_ctf_field_type_enumeration_find_mappings_type( + type, ITERATOR_BY_SIGNED_VALUE); + if (!iter) { + goto error; + } + + if (bt_ctf_field_type_integer_get_signed( + iter->enumeration_type->container) != 1) { + goto error; + } + iter->u.signed_value = value; + + /* Advance iterator to first entry, or leave index at -1. */ + if (bt_ctf_field_type_enumeration_mapping_iterator_next(iter)) { + /* No entry found. */ + goto error; + } + + return iter; +error: + bt_put(iter); + return NULL; +} + +struct bt_ctf_field_type_enumeration_mapping_iterator * +bt_ctf_field_type_enumeration_find_mappings_by_unsigned_value( + struct bt_ctf_field_type *type, uint64_t value) +{ + struct bt_ctf_field_type_enumeration_mapping_iterator *iter; + + iter = bt_ctf_field_type_enumeration_find_mappings_type( + type, ITERATOR_BY_UNSIGNED_VALUE); + if (!iter) { + goto error; + } + + if (bt_ctf_field_type_integer_get_signed( + iter->enumeration_type->container) != 0) { + goto error; + } + iter->u.unsigned_value = value; + + /* Advance iterator to first entry, or leave index at -1. */ + if (bt_ctf_field_type_enumeration_mapping_iterator_next(iter)) { + /* No entry found. */ + goto error; + } + + return iter; +error: + bt_put(iter); + return NULL; +} + +int bt_ctf_field_type_enumeration_mapping_iterator_get_signed( + struct bt_ctf_field_type_enumeration_mapping_iterator *iter, + const char **mapping_name, int64_t *range_begin, + int64_t *range_end) +{ + int ret = 0; + + if (!iter) { + ret = -1; + goto end; + } + + ret = bt_ctf_field_type_enumeration_get_mapping_signed( + &iter->enumeration_type->parent, iter->index, + mapping_name, range_begin, range_end); +end: + return ret; +} + +int bt_ctf_field_type_enumeration_mapping_iterator_get_unsigned( + struct bt_ctf_field_type_enumeration_mapping_iterator *iter, + const char **mapping_name, uint64_t *range_begin, + uint64_t *range_end) +{ + int ret = 0; + + if (!iter) { + ret = -1; + goto end; + } + + ret = bt_ctf_field_type_enumeration_get_mapping_unsigned( + &iter->enumeration_type->parent, iter->index, + mapping_name, range_begin, range_end); +end: + return ret; +} + +int bt_ctf_field_type_enumeration_get_mapping_signed( + struct bt_ctf_field_type *enum_field_type, + int index, + const char **mapping_name, int64_t *range_begin, + int64_t *range_end) +{ + int ret = 0; + struct enumeration_mapping *mapping; + + if (!enum_field_type || index < 0) { + ret = -1; + goto end; + } + + mapping = get_enumeration_mapping(enum_field_type, index); + if (!mapping) { + ret = -1; + goto end; + } + + if (mapping_name) { + *mapping_name = g_quark_to_string(mapping->string); + } + + if (range_begin) { + *range_begin = mapping->range_start._signed; + } + + if (range_end) { + *range_end = mapping->range_end._signed; + } +end: + return ret; +} + +int bt_ctf_field_type_enumeration_get_mapping_unsigned( + struct bt_ctf_field_type *enum_field_type, + int index, + const char **mapping_name, uint64_t *range_begin, + uint64_t *range_end) +{ + int ret = 0; + struct enumeration_mapping *mapping; + + if (!enum_field_type || index < 0) { + ret = -1; + goto end; + } + + mapping = get_enumeration_mapping(enum_field_type, index); + if (!mapping) { + ret = -1; + goto end; + } + + if (mapping_name) { + *mapping_name = g_quark_to_string(mapping->string); + } + + if (range_begin) { + *range_begin = mapping->range_start._unsigned; + } + + if (range_end) { + *range_end = mapping->range_end._unsigned; + } end: return ret; } @@ -895,7 +1315,6 @@ int bt_ctf_field_type_enumeration_add_mapping( GQuark mapping_name; struct enumeration_mapping *mapping; struct bt_ctf_field_type_enumeration *enumeration; - struct range_overlap_query query; char *escaped_string; if (!type || (type->declaration->id != BT_CTF_TYPE_ID_ENUM) || @@ -916,31 +1335,19 @@ int bt_ctf_field_type_enumeration_add_mapping( goto end; } - mapping_name = g_quark_from_string(escaped_string); - query = (struct range_overlap_query) { - .range_start._signed = range_start, - .range_end._signed = range_end, - .mapping_name = mapping_name, - .overlaps = 0 }; - enumeration = container_of(type, struct bt_ctf_field_type_enumeration, - parent); - - /* Check that the range does not overlap with one already present */ - g_ptr_array_foreach(enumeration->entries, check_ranges_overlap, &query); - if (query.overlaps) { - ret = -1; - goto error_free; - } - mapping = g_new(struct enumeration_mapping, 1); if (!mapping) { ret = -1; goto error_free; } - + mapping_name = g_quark_from_string(escaped_string); *mapping = (struct enumeration_mapping) { .range_start._signed = range_start, - .range_end._signed = range_end, .string = mapping_name}; + .range_end._signed = range_end, + .string = mapping_name, + }; + enumeration = container_of(type, struct bt_ctf_field_type_enumeration, + parent); g_ptr_array_add(enumeration->entries, mapping); g_ptr_array_sort(enumeration->entries, (GCompareFunc)compare_enumeration_mappings_signed); @@ -958,7 +1365,6 @@ int bt_ctf_field_type_enumeration_add_mapping_unsigned( GQuark mapping_name; struct enumeration_mapping *mapping; struct bt_ctf_field_type_enumeration *enumeration; - struct range_overlap_query query; char *escaped_string; if (!type || (type->declaration->id != BT_CTF_TYPE_ID_ENUM) || @@ -979,32 +1385,19 @@ int bt_ctf_field_type_enumeration_add_mapping_unsigned( goto end; } - mapping_name = g_quark_from_string(escaped_string); - query = (struct range_overlap_query) { - .range_start._unsigned = range_start, - .range_end._unsigned = range_end, - .mapping_name = mapping_name, - .overlaps = 0 }; - enumeration = container_of(type, struct bt_ctf_field_type_enumeration, - parent); - - /* Check that the range does not overlap with one already present */ - g_ptr_array_foreach(enumeration->entries, check_ranges_overlap_unsigned, - &query); - if (query.overlaps) { - ret = -1; - goto error_free; - } - mapping = g_new(struct enumeration_mapping, 1); if (!mapping) { ret = -1; goto error_free; } - + mapping_name = g_quark_from_string(escaped_string); *mapping = (struct enumeration_mapping) { .range_start._unsigned = range_start, - .range_end._unsigned = range_end, .string = mapping_name}; + .range_end._unsigned = range_end, + .string = mapping_name, + }; + enumeration = container_of(type, struct bt_ctf_field_type_enumeration, + parent); g_ptr_array_add(enumeration->entries, mapping); g_ptr_array_sort(enumeration->entries, (GCompareFunc)compare_enumeration_mappings_unsigned); @@ -1014,51 +1407,6 @@ end: return ret; } -const char *bt_ctf_field_type_enumeration_get_mapping_name_unsigned( - struct bt_ctf_field_type_enumeration *enumeration_type, - uint64_t value) -{ - const char *name = NULL; - struct range_overlap_query query = - (struct range_overlap_query) { - .range_start._unsigned = value, - .range_end._unsigned = value, - .overlaps = 0 }; - - g_ptr_array_foreach(enumeration_type->entries, - check_ranges_overlap_unsigned, - &query); - if (!query.overlaps) { - goto end; - } - - name = g_quark_to_string(query.mapping_name); -end: - return name; -} - -const char *bt_ctf_field_type_enumeration_get_mapping_name_signed( - struct bt_ctf_field_type_enumeration *enumeration_type, - int64_t value) -{ - const char *name = NULL; - struct range_overlap_query query = - (struct range_overlap_query) { - .range_start._signed = value, - .range_end._signed = value, - .overlaps = 0 }; - - g_ptr_array_foreach(enumeration_type->entries, check_ranges_overlap, - &query); - if (!query.overlaps) { - goto end; - } - - name = g_quark_to_string(query.mapping_name); -end: - return name; -} - int bt_ctf_field_type_enumeration_get_mapping_count( struct bt_ctf_field_type *type) { @@ -1077,170 +1425,6 @@ end: return ret; } -static inline -struct enumeration_mapping *get_enumeration_mapping( - struct bt_ctf_field_type *type, int index) -{ - struct enumeration_mapping *mapping = NULL; - struct bt_ctf_field_type_enumeration *enumeration; - - enumeration = container_of(type, struct bt_ctf_field_type_enumeration, - parent); - if (index >= enumeration->entries->len) { - goto end; - } - - mapping = g_ptr_array_index(enumeration->entries, index); -end: - return mapping; -} - -int bt_ctf_field_type_enumeration_get_mapping( - struct bt_ctf_field_type *type, int index, - const char **string, int64_t *range_start, int64_t *range_end) -{ - struct enumeration_mapping *mapping; - int ret = 0; - - if (!type || index < 0 || !string || !range_start || !range_end || - (type->declaration->id != BT_CTF_TYPE_ID_ENUM)) { - ret = -1; - goto end; - } - - mapping = get_enumeration_mapping(type, index); - if (!mapping) { - ret = -1; - goto end; - } - - *string = g_quark_to_string(mapping->string); - *range_start = mapping->range_start._signed; - *range_end = mapping->range_end._signed; -end: - return ret; -} - -int bt_ctf_field_type_enumeration_get_mapping_unsigned( - struct bt_ctf_field_type *type, int index, - const char **string, uint64_t *range_start, uint64_t *range_end) -{ - struct enumeration_mapping *mapping; - int ret = 0; - - if (!type || index < 0 || !string || !range_start || !range_end || - (type->declaration->id != BT_CTF_TYPE_ID_ENUM)) { - ret = -1; - goto end; - } - - mapping = get_enumeration_mapping(type, index); - if (!mapping) { - ret = -1; - goto end; - } - - *string = g_quark_to_string(mapping->string); - *range_start = mapping->range_start._unsigned; - *range_end = mapping->range_end._unsigned; -end: - return ret; -} - -int bt_ctf_field_type_enumeration_get_mapping_index_by_name( - struct bt_ctf_field_type *type, const char *name) -{ - GQuark name_quark; - struct bt_ctf_field_type_enumeration *enumeration; - int i, ret = 0; - - if (!type || !name || - (type->declaration->id != BT_CTF_TYPE_ID_ENUM)) { - ret = -1; - goto end; - } - - name_quark = g_quark_try_string(name); - if (!name_quark) { - ret = -1; - goto end; - } - - enumeration = container_of(type, - struct bt_ctf_field_type_enumeration, parent); - for (i = 0; i < enumeration->entries->len; i++) { - struct enumeration_mapping *mapping = - get_enumeration_mapping(type, i); - - if (mapping->string == name_quark) { - ret = i; - goto end; - } - } - - ret = -1; -end: - return ret; -} - -int bt_ctf_field_type_enumeration_get_mapping_index_by_value( - struct bt_ctf_field_type *type, int64_t value) -{ - struct bt_ctf_field_type_enumeration *enumeration; - int i, ret = 0; - - if (!type || (type->declaration->id != BT_CTF_TYPE_ID_ENUM)) { - ret = -1; - goto end; - } - - enumeration = container_of(type, - struct bt_ctf_field_type_enumeration, parent); - for (i = 0; i < enumeration->entries->len; i++) { - struct enumeration_mapping *mapping = - get_enumeration_mapping(type, i); - - if (value >= mapping->range_start._signed && - value <= mapping->range_end._signed) { - ret = i; - goto end; - } - } - - ret = -1; -end: - return ret; -} - -int bt_ctf_field_type_enumeration_get_mapping_index_by_unsigned_value( - struct bt_ctf_field_type *type, uint64_t value) -{ - struct bt_ctf_field_type_enumeration *enumeration; - int i, ret = 0; - - if (!type || (type->declaration->id != BT_CTF_TYPE_ID_ENUM)) { - ret = -1; - goto end; - } - - enumeration = container_of(type, - struct bt_ctf_field_type_enumeration, parent); - for (i = 0; i < enumeration->entries->len; i++) { - struct enumeration_mapping *mapping = - get_enumeration_mapping(type, i); - - if (value >= mapping->range_start._unsigned && - value <= mapping->range_end._unsigned) { - ret = i; - goto end; - } - } - - ret = -1; -end: - return ret; -} - struct bt_ctf_field_type *bt_ctf_field_type_floating_point_create(void) { struct bt_ctf_field_type_floating_point *floating_point = @@ -1387,9 +1571,14 @@ int bt_ctf_field_type_structure_add_field(struct bt_ctf_field_type *type, int ret = 0; struct bt_ctf_field_type_structure *structure; + /* + * TODO: check that `field_type` does not contain `type`, + * recursively. + */ if (!type || !field_type || type->frozen || bt_ctf_validate_identifier(field_name) || - (type->declaration->id != BT_CTF_TYPE_ID_STRUCT)) { + (type->declaration->id != BT_CTF_TYPE_ID_STRUCT) || + type == field_type) { ret = -1; goto end; } @@ -1592,9 +1781,14 @@ int bt_ctf_field_type_variant_add_field(struct bt_ctf_field_type *type, struct bt_ctf_field_type_variant *variant; GQuark field_name_quark = g_quark_from_string(field_name); + /* + * TODO: check that `field_type` does not contain `type`, + * recursively. + */ if (!type || !field_type || type->frozen || bt_ctf_validate_identifier(field_name) || - (type->declaration->id != BT_CTF_TYPE_ID_VARIANT)) { + (type->declaration->id != BT_CTF_TYPE_ID_VARIANT) || + type == field_type) { ret = -1; goto end; } @@ -1668,22 +1862,30 @@ struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_from_tag( struct bt_ctf_field_type *type, struct bt_ctf_field *tag) { + int ret; const char *enum_value; struct bt_ctf_field_type *field_type = NULL; + struct bt_ctf_field_type_enumeration_mapping_iterator *iter = NULL; if (!type || !tag || type->declaration->id != BT_CTF_TYPE_ID_VARIANT) { goto end; } - enum_value = bt_ctf_field_enumeration_get_mapping_name(tag); - if (!enum_value) { + iter = bt_ctf_field_enumeration_get_mappings(tag); + if (!iter) { + goto end; + } + + ret = bt_ctf_field_type_enumeration_mapping_iterator_get_signed(iter, + &enum_value, NULL, NULL); + if (ret) { goto end; } - /* Already increments field_type's reference count */ field_type = bt_ctf_field_type_variant_get_field_type_by_name( type, enum_value); end: + bt_put(iter); return field_type; } @@ -2117,6 +2319,13 @@ enum bt_ctf_byte_order bt_ctf_field_type_get_byte_order( ret = integer->user_byte_order; break; } + case BT_CTF_TYPE_ID_ENUM: + { + struct bt_ctf_field_type_enumeration *enum_ft = container_of( + type, struct bt_ctf_field_type_enumeration, parent); + ret = bt_ctf_field_type_get_byte_order(enum_ft->container); + break; + } case BT_CTF_TYPE_ID_FLOAT: { struct bt_ctf_field_type_floating_point *floating_point = @@ -2258,7 +2467,9 @@ struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_signed( struct range_overlap_query query = { .range_start._signed = tag_value, .range_end._signed = tag_value, - .mapping_name = 0, .overlaps = 0}; + .mapping_name = 0, + .overlaps = 0, + }; g_ptr_array_foreach(variant->tag->entries, check_ranges_overlap, &query); @@ -2290,7 +2501,9 @@ struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_unsigned( struct range_overlap_query query = { .range_start._unsigned = tag_value, .range_end._unsigned = tag_value, - .mapping_name = 0, .overlaps = 0}; + .mapping_name = 0, + .overlaps = 0, + }; g_ptr_array_foreach(variant->tag->entries, check_ranges_overlap_unsigned, @@ -2349,7 +2562,6 @@ void bt_ctf_field_type_set_native_byte_order(struct bt_ctf_field_type *type, } } -BT_HIDDEN struct bt_ctf_field_type *bt_ctf_field_type_copy(struct bt_ctf_field_type *type) { struct bt_ctf_field_type *copy = NULL; @@ -2680,12 +2892,27 @@ void generic_field_type_freeze(struct bt_ctf_field_type *type) type->frozen = 1; } +static +void bt_ctf_field_type_integer_freeze(struct bt_ctf_field_type *type) +{ + struct bt_ctf_field_type_integer *integer_type = container_of( + type, struct bt_ctf_field_type_integer, parent); + + if (integer_type->mapped_clock) { + bt_ctf_clock_class_freeze(integer_type->mapped_clock); + } + + generic_field_type_freeze(type); +} + static void bt_ctf_field_type_enumeration_freeze(struct bt_ctf_field_type *type) { struct bt_ctf_field_type_enumeration *enumeration_type = container_of( type, struct bt_ctf_field_type_enumeration, parent); + set_enumeration_range_overlap(type); + generic_field_type_freeze(type); bt_ctf_field_type_freeze(enumeration_type->container); } @@ -2809,7 +3036,7 @@ int bt_ctf_field_type_integer_serialize(struct bt_ctf_field_type *type, get_integer_base_string(integer->declaration.base), get_byte_order_string(integer->declaration.byte_order)); if (integer->mapped_clock) { - const char *clock_name = bt_ctf_clock_get_name( + const char *clock_name = bt_ctf_clock_class_get_name( integer->mapped_clock); if (!clock_name) { @@ -3319,7 +3546,7 @@ struct bt_ctf_field_type *bt_ctf_field_type_enumeration_copy( for (i = 0; i < enumeration->entries->len; i++) { struct enumeration_mapping *mapping = g_ptr_array_index( enumeration->entries, i); - struct enumeration_mapping* copy_mapping = g_new0( + struct enumeration_mapping *copy_mapping = g_new0( struct enumeration_mapping, 1); if (!copy_mapping) { @@ -4027,9 +4254,15 @@ struct bt_ctf_field_type *bt_ctf_field_type_get_field_at_index( index); break; case CTF_TYPE_VARIANT: - bt_ctf_field_type_variant_get_field(field_type, NULL, + { + int ret = bt_ctf_field_type_variant_get_field(field_type, NULL, &field, index); + if (ret) { + field = NULL; + goto end; + } break; + } case CTF_TYPE_ARRAY: field = bt_ctf_field_type_array_get_element_type(field_type); break; @@ -4039,7 +4272,7 @@ struct bt_ctf_field_type *bt_ctf_field_type_get_field_at_index( default: break; } - +end: return field; }