#include <babeltrace/ctf-ir/field-path-internal.h>
#include <babeltrace/ctf-ir/utils.h>
#include <babeltrace/ref.h>
-#include <babeltrace/ctf-ir/clock.h>
-#include <babeltrace/ctf-ir/clock-internal.h>
+#include <babeltrace/ctf-ir/clock-class.h>
+#include <babeltrace/ctf-ir/clock-class-internal.h>
#include <babeltrace/ctf-writer/writer-internal.h>
#include <babeltrace/object-internal.h>
#include <babeltrace/ref.h>
[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
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,
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;
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)
{
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_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);
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;
}
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;
}
-struct bt_ctf_field_type *bt_ctf_field_type_enumeration_create(
- struct bt_ctf_field_type *integer_container_type)
+static
+void bt_ctf_field_type_enum_iter_destroy(struct bt_object *obj)
{
- struct bt_ctf_field_type_enumeration *enumeration = NULL;
+ struct bt_ctf_field_type_enumeration_mapping_iterator *iter =
+ container_of(obj,
+ struct bt_ctf_field_type_enumeration_mapping_iterator,
+ base);
- if (!integer_container_type) {
+ 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;
}
- if (integer_container_type->declaration->id != BT_CTF_TYPE_ID_INTEGER) {
+ iter->u.name_quark = g_quark_try_string(name);
+ if (!iter->u.name_quark) {
goto error;
}
- enumeration = g_new0(struct bt_ctf_field_type_enumeration, 1);
- if (!enumeration) {
+ /* 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;
}
- enumeration->parent.declaration = &enumeration->declaration.p;
- enumeration->parent.declaration->id = BT_CTF_TYPE_ID_ENUM;
- bt_get(integer_container_type);
- enumeration->container = integer_container_type;
- enumeration->entries = g_ptr_array_new_with_free_func(
- (GDestroyNotify)destroy_enumeration_mapping);
- bt_ctf_field_type_init(&enumeration->parent, FALSE);
- return &enumeration->parent;
+ return iter;
error:
- g_free(enumeration);
+ bt_put(iter);
return NULL;
}
-struct bt_ctf_field_type *bt_ctf_field_type_enumeration_get_container_type(
- struct bt_ctf_field_type *type)
+int bt_ctf_field_type_enumeration_mapping_iterator_next(
+ struct bt_ctf_field_type_enumeration_mapping_iterator *iter)
{
- struct bt_ctf_field_type *container_type = NULL;
- struct bt_ctf_field_type_enumeration *enumeration_type;
+ struct bt_ctf_field_type_enumeration *enumeration;
+ struct bt_ctf_field_type *type;
+ int i, ret = 0, len;
- if (!type) {
- goto end;
- }
+ 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);
- if (type->declaration->id != BT_CTF_TYPE_ID_ENUM) {
- goto end;
+ 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();
+ }
}
- enumeration_type = container_of(type,
- struct bt_ctf_field_type_enumeration, parent);
- container_type = enumeration_type->container;
- bt_get(container_type);
+ ret = -1;
end:
- return container_type;
+ return ret;
}
-int bt_ctf_field_type_enumeration_add_mapping(
- struct bt_ctf_field_type *type, const char *string,
- int64_t range_start, int64_t range_end)
+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)
{
- int ret = 0;
- GQuark mapping_name;
- struct enumeration_mapping *mapping;
- struct bt_ctf_field_type_enumeration *enumeration;
- struct range_overlap_query query;
- char *escaped_string;
+ struct bt_ctf_field_type_enumeration_mapping_iterator *iter;
- if (!type || (type->declaration->id != BT_CTF_TYPE_ID_ENUM) ||
- type->frozen ||
- (range_end < range_start)) {
- ret = -1;
- goto end;
+ iter = bt_ctf_field_type_enumeration_find_mappings_type(
+ type, ITERATOR_BY_SIGNED_VALUE);
+ if (!iter) {
+ goto error;
}
- if (!string || strlen(string) == 0) {
- ret = -1;
- goto end;
+ if (bt_ctf_field_type_integer_get_signed(
+ iter->enumeration_type->container) != 1) {
+ goto error;
}
+ iter->u.signed_value = value;
- escaped_string = g_strescape(string, NULL);
- if (!escaped_string) {
- ret = -1;
- goto end;
+ /* 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;
}
- 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);
+ return iter;
+error:
+ bt_put(iter);
+ return NULL;
+}
- /* 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;
+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;
}
- mapping = g_new(struct enumeration_mapping, 1);
- if (!mapping) {
- ret = -1;
- goto error_free;
+ if (bt_ctf_field_type_integer_get_signed(
+ iter->enumeration_type->container) != 0) {
+ goto error;
}
+ iter->u.unsigned_value = value;
- *mapping = (struct enumeration_mapping) {
- .range_start._signed = range_start,
- .range_end._signed = range_end, .string = mapping_name};
- g_ptr_array_add(enumeration->entries, mapping);
- g_ptr_array_sort(enumeration->entries,
- (GCompareFunc)compare_enumeration_mappings_signed);
-error_free:
- free(escaped_string);
-end:
- return ret;
+ /* 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_add_mapping_unsigned(
- struct bt_ctf_field_type *type, const char *string,
- uint64_t range_start, uint64_t range_end)
+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;
- 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) ||
- type->frozen ||
- (range_end < range_start)) {
- ret = -1;
- goto end;
- }
- if (!string || strlen(string) == 0) {
+ if (!enum_field_type || index < 0) {
ret = -1;
goto end;
}
- escaped_string = g_strescape(string, NULL);
- if (!escaped_string) {
+ mapping = get_enumeration_mapping(enum_field_type, index);
+ if (!mapping) {
ret = -1;
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;
+ if (mapping_name) {
+ *mapping_name = g_quark_to_string(mapping->string);
}
-
- *mapping = (struct enumeration_mapping) {
- .range_start._unsigned = range_start,
- .range_end._unsigned = range_end, .string = mapping_name};
- g_ptr_array_add(enumeration->entries, mapping);
- g_ptr_array_sort(enumeration->entries,
- (GCompareFunc)compare_enumeration_mappings_unsigned);
-error_free:
- free(escaped_string);
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)
+int bt_ctf_field_type_enumeration_mapping_iterator_get_name(
+ struct bt_ctf_field_type_enumeration_mapping_iterator *iter,
+ const char **mapping_name)
{
- const char *name = NULL;
- struct range_overlap_query query =
- (struct range_overlap_query) {
- .range_start._unsigned = value,
- .range_end._unsigned = value,
- .overlaps = 0 };
+ int ret = 0;
- g_ptr_array_foreach(enumeration_type->entries,
- check_ranges_overlap_unsigned,
- &query);
- if (!query.overlaps) {
+ if (!iter) {
+ ret = -1;
goto end;
}
- name = g_quark_to_string(query.mapping_name);
+ ret = bt_ctf_field_type_enumeration_get_mapping_name(
+ &iter->enumeration_type->parent, iter->index,
+ mapping_name);
end:
- return name;
+ return ret;
}
-const char *bt_ctf_field_type_enumeration_get_mapping_name_signed(
- struct bt_ctf_field_type_enumeration *enumeration_type,
- int64_t value)
+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)
{
- const char *name = NULL;
- struct range_overlap_query query =
- (struct range_overlap_query) {
- .range_start._signed = value,
- .range_end._signed = value,
- .overlaps = 0 };
+ int ret = 0;
- g_ptr_array_foreach(enumeration_type->entries, check_ranges_overlap,
- &query);
- if (!query.overlaps) {
+ if (!iter) {
+ ret = -1;
goto end;
}
- name = g_quark_to_string(query.mapping_name);
+ ret = bt_ctf_field_type_enumeration_get_mapping_signed(
+ &iter->enumeration_type->parent, iter->index,
+ mapping_name, range_begin, range_end);
end:
- return name;
+ return ret;
}
-int bt_ctf_field_type_enumeration_get_mapping_count(
- struct bt_ctf_field_type *type)
+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;
- struct bt_ctf_field_type_enumeration *enumeration;
- if (!type || (type->declaration->id != BT_CTF_TYPE_ID_ENUM)) {
+ if (!iter) {
ret = -1;
goto end;
}
- enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
- parent);
- ret = (int) enumeration->entries->len;
+ ret = bt_ctf_field_type_enumeration_get_mapping_unsigned(
+ &iter->enumeration_type->parent, iter->index,
+ mapping_name, range_begin, range_end);
end:
return ret;
}
-static inline
-struct enumeration_mapping *get_enumeration_mapping(
- struct bt_ctf_field_type *type, int index)
+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)
{
- struct enumeration_mapping *mapping = NULL;
- struct bt_ctf_field_type_enumeration *enumeration;
+ int ret = 0;
+ struct enumeration_mapping *mapping;
- enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
- parent);
- if (index >= enumeration->entries->len) {
+ if (!enum_field_type || index < 0) {
+ ret = -1;
goto end;
}
- mapping = g_ptr_array_index(enumeration->entries, index);
+ 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 mapping;
+ return ret;
}
-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)
+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)
{
- struct enumeration_mapping *mapping;
int ret = 0;
+ struct enumeration_mapping *mapping;
- if (!type || index < 0 || !string || !range_start || !range_end ||
- (type->declaration->id != BT_CTF_TYPE_ID_ENUM)) {
+ if (!enum_field_type || index < 0) {
ret = -1;
goto end;
}
- mapping = get_enumeration_mapping(type, index);
+ mapping = get_enumeration_mapping(enum_field_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;
+ 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;
}
-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 bt_ctf_field_type *bt_ctf_field_type_enumeration_create(
+ struct bt_ctf_field_type *integer_container_type)
{
- struct enumeration_mapping *mapping;
- int ret = 0;
+ struct bt_ctf_field_type_enumeration *enumeration = NULL;
- if (!type || index < 0 || !string || !range_start || !range_end ||
- (type->declaration->id != BT_CTF_TYPE_ID_ENUM)) {
- ret = -1;
+ if (!integer_container_type) {
+ goto error;
+ }
+
+ if (integer_container_type->declaration->id != BT_CTF_TYPE_ID_INTEGER) {
+ goto error;
+ }
+
+ enumeration = g_new0(struct bt_ctf_field_type_enumeration, 1);
+ if (!enumeration) {
+ goto error;
+ }
+
+ enumeration->parent.declaration = &enumeration->declaration.p;
+ enumeration->parent.declaration->id = BT_CTF_TYPE_ID_ENUM;
+ bt_get(integer_container_type);
+ enumeration->container = integer_container_type;
+ enumeration->entries = g_ptr_array_new_with_free_func(
+ (GDestroyNotify)destroy_enumeration_mapping);
+ bt_ctf_field_type_init(&enumeration->parent, FALSE);
+ return &enumeration->parent;
+error:
+ g_free(enumeration);
+ return NULL;
+}
+
+struct bt_ctf_field_type *bt_ctf_field_type_enumeration_get_container_type(
+ struct bt_ctf_field_type *type)
+{
+ struct bt_ctf_field_type *container_type = NULL;
+ struct bt_ctf_field_type_enumeration *enumeration_type;
+
+ if (!type) {
goto end;
}
- mapping = get_enumeration_mapping(type, index);
- if (!mapping) {
- ret = -1;
+ if (type->declaration->id != BT_CTF_TYPE_ID_ENUM) {
goto end;
}
- *string = g_quark_to_string(mapping->string);
- *range_start = mapping->range_start._unsigned;
- *range_end = mapping->range_end._unsigned;
+ enumeration_type = container_of(type,
+ struct bt_ctf_field_type_enumeration, parent);
+ container_type = enumeration_type->container;
+ bt_get(container_type);
end:
- return ret;
+ return container_type;
}
-int bt_ctf_field_type_enumeration_get_mapping_index_by_name(
- struct bt_ctf_field_type *type, const char *name)
+int bt_ctf_field_type_enumeration_add_mapping(
+ struct bt_ctf_field_type *type, const char *string,
+ int64_t range_start, int64_t range_end)
{
- GQuark name_quark;
+ int ret = 0;
+ GQuark mapping_name;
+ struct enumeration_mapping *mapping;
struct bt_ctf_field_type_enumeration *enumeration;
- int i, ret = 0;
+ char *escaped_string;
- if (!type || !name ||
- (type->declaration->id != BT_CTF_TYPE_ID_ENUM)) {
+ if (!type || (type->declaration->id != BT_CTF_TYPE_ID_ENUM) ||
+ type->frozen ||
+ (range_end < range_start)) {
ret = -1;
goto end;
}
- name_quark = g_quark_try_string(name);
- if (!name_quark) {
+ if (!string || strlen(string) == 0) {
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;
- }
+ escaped_string = g_strescape(string, NULL);
+ if (!escaped_string) {
+ ret = -1;
+ goto end;
}
- ret = -1;
+ 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,
+ };
+ 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);
+error_free:
+ free(escaped_string);
end:
return ret;
}
-int bt_ctf_field_type_enumeration_get_mapping_index_by_value(
- struct bt_ctf_field_type *type, int64_t value)
+int bt_ctf_field_type_enumeration_add_mapping_unsigned(
+ struct bt_ctf_field_type *type, const char *string,
+ uint64_t range_start, uint64_t range_end)
{
+ int ret = 0;
+ GQuark mapping_name;
+ struct enumeration_mapping *mapping;
struct bt_ctf_field_type_enumeration *enumeration;
- int i, ret = 0;
+ char *escaped_string;
- if (!type || (type->declaration->id != BT_CTF_TYPE_ID_ENUM)) {
+ if (!type || (type->declaration->id != BT_CTF_TYPE_ID_ENUM) ||
+ type->frozen ||
+ (range_end < range_start)) {
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 (!string || strlen(string) == 0) {
+ ret = -1;
+ goto end;
+ }
- if (value >= mapping->range_start._signed &&
- value <= mapping->range_end._signed) {
- ret = i;
- goto end;
- }
+ escaped_string = g_strescape(string, NULL);
+ if (!escaped_string) {
+ ret = -1;
+ goto end;
}
- ret = -1;
+ 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,
+ };
+ 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);
+error_free:
+ free(escaped_string);
end:
return ret;
}
-int bt_ctf_field_type_enumeration_get_mapping_index_by_unsigned_value(
- struct bt_ctf_field_type *type, uint64_t value)
+int bt_ctf_field_type_enumeration_get_mapping_count(
+ struct bt_ctf_field_type *type)
{
+ int ret = 0;
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;
+ enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
+ parent);
+ ret = (int) enumeration->entries->len;
end:
return ret;
}
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;
}
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;
}
goto end;
}
- enum_value = bt_ctf_field_enumeration_get_mapping_name(tag);
+ enum_value = bt_ctf_field_enumeration_get_single_mapping_name(tag);
if (!enum_value) {
goto end;
}
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 =
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);
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,
}
}
-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;
type, struct bt_ctf_field_type_integer, parent);
if (integer_type->mapped_clock) {
- bt_ctf_clock_freeze(integer_type->mapped_clock);
+ bt_ctf_clock_class_freeze(integer_type->mapped_clock);
}
generic_field_type_freeze(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);
}
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) {
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) {
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;
default:
break;
}
-
+end:
return field;
}