#include <babeltrace/ctf-writer/event-types.h>
#include <babeltrace/ctf-ir/event-types-internal.h>
+#include <babeltrace/ctf-ir/utils.h>
+#include <babeltrace/ctf-ir/clock.h>
#include <babeltrace/ctf-writer/writer-internal.h>
#include <babeltrace/compiler.h>
#include <babeltrace/endian.h>
static
void bt_ctf_field_type_integer_set_byte_order(struct bt_ctf_field_type *,
- int byte_order);
+ int byte_order, int set_native);
+static
+void bt_ctf_field_type_enumeration_set_byte_order(struct bt_ctf_field_type *,
+ int byte_order, int set_native);
static
void bt_ctf_field_type_floating_point_set_byte_order(
- struct bt_ctf_field_type *, int byte_order);
+ struct bt_ctf_field_type *, int byte_order, int set_native);
+static
+void bt_ctf_field_type_structure_set_byte_order(struct bt_ctf_field_type *,
+ int byte_order, int set_native);
+static
+void bt_ctf_field_type_variant_set_byte_order(struct bt_ctf_field_type *,
+ int byte_order, int set_native);
+static
+void bt_ctf_field_type_array_set_byte_order(struct bt_ctf_field_type *,
+ int byte_order, int set_native);
+static
+void bt_ctf_field_type_sequence_set_byte_order(struct bt_ctf_field_type *,
+ int byte_order, int set_native);
+/* The set_native flag only set the byte order if it is set to native */
static
void (* const set_byte_order_funcs[])(struct bt_ctf_field_type *,
- int) = {
- [CTF_TYPE_INTEGER] =
- bt_ctf_field_type_integer_set_byte_order,
+ int byte_order, int set_native) = {
+ [CTF_TYPE_INTEGER] = bt_ctf_field_type_integer_set_byte_order,
+ [CTF_TYPE_ENUM] =
+ bt_ctf_field_type_enumeration_set_byte_order,
[CTF_TYPE_FLOAT] =
bt_ctf_field_type_floating_point_set_byte_order,
- [CTF_TYPE_ENUM ... CTF_TYPE_SEQUENCE] = NULL,
+ [CTF_TYPE_STRUCT] =
+ bt_ctf_field_type_structure_set_byte_order,
+ [CTF_TYPE_VARIANT] = bt_ctf_field_type_variant_set_byte_order,
+ [CTF_TYPE_ARRAY] = bt_ctf_field_type_array_set_byte_order,
+ [CTF_TYPE_SEQUENCE] = bt_ctf_field_type_sequence_set_byte_order,
+ [CTF_TYPE_STRING] = NULL,
};
static
(gpointer) (unsigned long) name_quark,
(gpointer) (unsigned long) fields->len);
g_ptr_array_add(fields, field);
- bt_ctf_field_type_freeze(field_type);
end:
return ret;
}
goto end;
}
- if (type->declaration->id == CTF_TYPE_ENUM) {
+ switch (type->declaration->id) {
+ case CTF_TYPE_ENUM:
+ {
struct bt_ctf_field_type_enumeration *enumeration =
container_of(type, struct bt_ctf_field_type_enumeration,
parent);
+ /* Ensure enum has entries */
ret = enumeration->entries->len ? 0 : -1;
+ break;
+ }
+ default:
+ break;
}
end:
return ret;
struct bt_ctf_field_type_integer *integer =
g_new0(struct bt_ctf_field_type_integer, 1);
- if (!integer || size > 64) {
+ if (!integer || size == 0 || size > 64) {
return NULL;
}
}
integer = container_of(type, struct bt_ctf_field_type_integer, parent);
- if (is_signed && integer->declaration.len <= 1) {
- ret = -1;
- goto end;
- }
-
integer->declaration.signedness = !!is_signed;
end:
return ret;
return ret;
}
+struct bt_ctf_clock *bt_ctf_field_type_integer_get_mapped_clock(
+ struct bt_ctf_field_type *type)
+{
+ struct bt_ctf_field_type_integer *integer;
+ struct bt_ctf_clock *clock = NULL;
+
+ if (!type) {
+ goto end;
+ }
+
+ integer = container_of(type, struct bt_ctf_field_type_integer, parent);
+ clock = integer->mapped_clock;
+ if (clock) {
+ bt_ctf_clock_get(clock);
+ }
+end:
+ return clock;
+}
+
+int bt_ctf_field_type_integer_set_mapped_clock(
+ struct bt_ctf_field_type *type,
+ struct bt_ctf_clock *clock)
+{
+ struct bt_ctf_field_type_integer *integer;
+ int ret = 0;
+
+ if (!type || type->frozen) {
+ ret = -1;
+ goto end;
+ }
+
+ integer = container_of(type, struct bt_ctf_field_type_integer, parent);
+ if (integer->mapped_clock) {
+ bt_ctf_clock_put(integer->mapped_clock);
+ }
+
+ if (clock) {
+ bt_ctf_clock_get(clock);
+ }
+
+ integer->mapped_clock = clock;
+end:
+ return ret;
+}
+
struct bt_ctf_field_type *bt_ctf_field_type_enumeration_create(
struct bt_ctf_field_type *integer_container_type)
{
structure->parent.declaration = &structure->declaration.p;
structure->parent.declaration->id = CTF_TYPE_STRUCT;
- bt_ctf_field_type_init(&structure->parent);
structure->fields = g_ptr_array_new_with_free_func(
(GDestroyNotify)destroy_structure_field);
structure->field_name_to_index = g_hash_table_new(NULL, NULL);
+ bt_ctf_field_type_init(&structure->parent);
return &structure->parent;
error:
return NULL;
struct bt_ctf_field_type_structure *structure;
if (!type || !field_type || type->frozen ||
- validate_identifier(field_name) ||
+ bt_ctf_validate_identifier(field_name) ||
(type->declaration->id != CTF_TYPE_STRUCT) ||
bt_ctf_field_type_validate(field_type)) {
ret = -1;
{
struct bt_ctf_field_type_variant *variant = NULL;
- if (!enum_tag || validate_identifier(tag_name) ||
+ if (!enum_tag || bt_ctf_validate_identifier(tag_name) ||
(enum_tag->declaration->id != CTF_TYPE_ENUM)) {
goto error;
}
variant->parent.declaration = &variant->declaration.p;
variant->parent.declaration->id = CTF_TYPE_VARIANT;
variant->tag_name = g_string_new(tag_name);
- bt_ctf_field_type_init(&variant->parent);
variant->field_name_to_index = g_hash_table_new(NULL, NULL);
variant->fields = g_ptr_array_new_with_free_func(
(GDestroyNotify)destroy_structure_field);
bt_ctf_field_type_get(enum_tag);
variant->tag = container_of(enum_tag,
struct bt_ctf_field_type_enumeration, parent);
+ bt_ctf_field_type_init(&variant->parent);
return &variant->parent;
error:
return NULL;
GQuark field_name_quark = g_quark_from_string(field_name);
if (!type || !field_type || type->frozen ||
- validate_identifier(field_name) ||
+ bt_ctf_validate_identifier(field_name) ||
(type->declaration->id != CTF_TYPE_VARIANT) ||
bt_ctf_field_type_validate(field_type)) {
ret = -1;
array->parent.declaration = &array->declaration.p;
array->parent.declaration->id = CTF_TYPE_ARRAY;
- bt_ctf_field_type_init(&array->parent);
+
bt_ctf_field_type_get(element_type);
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;
{
struct bt_ctf_field_type_sequence *sequence = NULL;
- if (!element_type || validate_identifier(length_field_name) ||
+ if (!element_type || bt_ctf_validate_identifier(length_field_name) ||
bt_ctf_field_type_validate(element_type)) {
goto error;
}
sequence->parent.declaration = &sequence->declaration.p;
sequence->parent.declaration->id = CTF_TYPE_SEQUENCE;
- bt_ctf_field_type_init(&sequence->parent);
bt_ctf_field_type_get(element_type);
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;
struct bt_ctf_field_type *type)
{
enum bt_ctf_byte_order ret = BT_CTF_BYTE_ORDER_UNKNOWN;
+ int internal_byte_order = -1;
if (!type) {
goto end;
{
struct bt_ctf_field_type_integer *integer = container_of(
type, struct bt_ctf_field_type_integer, parent);
- ret = integer->declaration.byte_order == LITTLE_ENDIAN ?
- BT_CTF_BYTE_ORDER_LITTLE_ENDIAN :
- BT_CTF_BYTE_ORDER_BIG_ENDIAN;
+ internal_byte_order = integer->declaration.byte_order;
break;
}
case CTF_TYPE_FLOAT:
container_of(type,
struct bt_ctf_field_type_floating_point,
parent);
- ret = floating_point->declaration.byte_order == LITTLE_ENDIAN ?
- BT_CTF_BYTE_ORDER_LITTLE_ENDIAN :
- BT_CTF_BYTE_ORDER_BIG_ENDIAN;
+ internal_byte_order = floating_point->declaration.byte_order;
break;
}
default:
+ goto end;
+ }
+
+ switch (internal_byte_order) {
+ case LITTLE_ENDIAN:
+ ret = BT_CTF_BYTE_ORDER_LITTLE_ENDIAN;
+ break;
+ case BIG_ENDIAN:
+ ret = BT_CTF_BYTE_ORDER_BIG_ENDIAN;
break;
+ case 0:
+ ret = BT_CTF_BYTE_ORDER_NATIVE;
+ break;
+ default:
+ ret = BT_CTF_BYTE_ORDER_UNKNOWN;
}
end:
return ret;
type_id = type->declaration->id;
switch (byte_order) {
case BT_CTF_BYTE_ORDER_NATIVE:
- internal_byte_order = (G_BYTE_ORDER == G_LITTLE_ENDIAN ?
- LITTLE_ENDIAN : BIG_ENDIAN);
+ /* Leave unset. Will be initialized by parent. */
+ internal_byte_order = 0;
break;
case BT_CTF_BYTE_ORDER_LITTLE_ENDIAN:
internal_byte_order = LITTLE_ENDIAN;
}
if (set_byte_order_funcs[type_id]) {
- set_byte_order_funcs[type_id](type, internal_byte_order);
+ set_byte_order_funcs[type_id](type, internal_byte_order, 0);
}
end:
return ret;
return ret;
}
+BT_HIDDEN
+void bt_ctf_field_type_set_native_byte_order(struct bt_ctf_field_type *type,
+ int byte_order)
+{
+ if (!type) {
+ return;
+ }
+
+ assert(byte_order == LITTLE_ENDIAN || byte_order == BIG_ENDIAN);
+ if (set_byte_order_funcs[type->declaration->id]) {
+ set_byte_order_funcs[type->declaration->id](type,
+ byte_order, 1);
+ }
+}
+
static
void bt_ctf_field_type_integer_destroy(struct bt_ctf_ref *ref)
{
integer = container_of(
container_of(ref, struct bt_ctf_field_type, ref_count),
struct bt_ctf_field_type_integer, parent);
+ if (integer->mapped_clock) {
+ bt_ctf_clock_put(integer->mapped_clock);
+ }
g_free(integer);
}
{
struct bt_ctf_field_type_integer *integer = container_of(type,
struct bt_ctf_field_type_integer, parent);
+ int ret = 0;
g_string_append_printf(context->string,
- "integer { size = %zu; align = %zu; signed = %s; encoding = %s; base = %s; byte_order = %s; }",
+ "integer { size = %zu; align = %zu; signed = %s; encoding = %s; base = %s; byte_order = %s",
integer->declaration.len, type->declaration->alignment,
(integer->declaration.signedness ? "true" : "false"),
get_encoding_string(integer->declaration.encoding),
get_integer_base_string(integer->declaration.base),
get_byte_order_string(integer->declaration.byte_order));
- return 0;
+ if (integer->mapped_clock) {
+ const char *clock_name = bt_ctf_clock_get_name(
+ integer->mapped_clock);
+
+ if (!clock_name) {
+ ret = -1;
+ goto end;
+ }
+
+ g_string_append_printf(context->string,
+ "; map = clock.%s.value", clock_name);
+ }
+
+ g_string_append(context->string, "; }");
+end:
+ return ret;
}
static
static
void bt_ctf_field_type_integer_set_byte_order(struct bt_ctf_field_type *type,
- int byte_order)
+ int byte_order, int set_native)
{
struct bt_ctf_field_type_integer *integer_type = container_of(type,
struct bt_ctf_field_type_integer, parent);
- integer_type->declaration.byte_order = byte_order;
+ if (set_native) {
+ integer_type->declaration.byte_order =
+ integer_type->declaration.byte_order == 0 ?
+ byte_order : integer_type->declaration.byte_order;
+ } else {
+ integer_type->declaration.byte_order = byte_order;
+ }
+}
+
+static
+void bt_ctf_field_type_enumeration_set_byte_order(
+ struct bt_ctf_field_type *type, int byte_order, int set_native)
+{
+ struct bt_ctf_field_type_enumeration *enum_type = container_of(type,
+ struct bt_ctf_field_type_enumeration, parent);
+
+ /* Safe to assume that container is an integer */
+ bt_ctf_field_type_integer_set_byte_order(enum_type->container,
+ byte_order, set_native);
}
static
void bt_ctf_field_type_floating_point_set_byte_order(
- struct bt_ctf_field_type *type, int byte_order)
+ struct bt_ctf_field_type *type, int byte_order, int set_native)
{
struct bt_ctf_field_type_floating_point *floating_point_type =
container_of(type, struct bt_ctf_field_type_floating_point,
parent);
- floating_point_type->declaration.byte_order = byte_order;
- floating_point_type->sign.byte_order = byte_order;
- floating_point_type->mantissa.byte_order = byte_order;
- floating_point_type->exp.byte_order = byte_order;
+ if (set_native) {
+ floating_point_type->declaration.byte_order =
+ floating_point_type->declaration.byte_order == 0 ?
+ byte_order :
+ floating_point_type->declaration.byte_order;
+ floating_point_type->sign.byte_order =
+ floating_point_type->sign.byte_order == 0 ?
+ byte_order : floating_point_type->sign.byte_order;
+ floating_point_type->mantissa.byte_order =
+ floating_point_type->mantissa.byte_order == 0 ?
+ byte_order : floating_point_type->mantissa.byte_order;
+ floating_point_type->exp.byte_order =
+ floating_point_type->exp.byte_order == 0 ?
+ byte_order : floating_point_type->exp.byte_order;
+ } else {
+ floating_point_type->declaration.byte_order = byte_order;
+ floating_point_type->sign.byte_order = byte_order;
+ floating_point_type->mantissa.byte_order = byte_order;
+ floating_point_type->exp.byte_order = byte_order;
+ }
+}
+
+static
+void bt_ctf_field_type_structure_set_byte_order(struct bt_ctf_field_type *type,
+ int byte_order, int set_native)
+{
+ int i;
+ struct bt_ctf_field_type_structure *structure_type =
+ container_of(type, struct bt_ctf_field_type_structure,
+ parent);
+
+ for (i = 0; i < structure_type->fields->len; i++) {
+ struct structure_field *field = g_ptr_array_index(
+ structure_type->fields, i);
+ struct bt_ctf_field_type *field_type = field->type;
+
+ if (set_byte_order_funcs[field_type->declaration->id]) {
+ set_byte_order_funcs[field_type->declaration->id](
+ field_type, byte_order, set_native);
+ }
+ }
+}
+
+static
+void bt_ctf_field_type_variant_set_byte_order(struct bt_ctf_field_type *type,
+ int byte_order, int set_native)
+{
+ int i;
+ struct bt_ctf_field_type_variant *variant_type =
+ container_of(type, struct bt_ctf_field_type_variant,
+ parent);
+
+ for (i = 0; i < variant_type->fields->len; i++) {
+ struct structure_field *field = g_ptr_array_index(
+ variant_type->fields, i);
+ struct bt_ctf_field_type *field_type = field->type;
+
+ if (set_byte_order_funcs[field_type->declaration->id]) {
+ set_byte_order_funcs[field_type->declaration->id](
+ field_type, byte_order, set_native);
+ }
+ }
+}
+
+static
+void bt_ctf_field_type_array_set_byte_order(struct bt_ctf_field_type *type,
+ int byte_order, int set_native)
+{
+ struct bt_ctf_field_type_array *array_type =
+ container_of(type, struct bt_ctf_field_type_array,
+ parent);
+
+ if (set_byte_order_funcs[array_type->element_type->declaration->id]) {
+ set_byte_order_funcs[array_type->element_type->declaration->id](
+ array_type->element_type, byte_order, set_native);
+ }
+}
+
+static
+void bt_ctf_field_type_sequence_set_byte_order(struct bt_ctf_field_type *type,
+ int byte_order, int set_native)
+{
+ struct bt_ctf_field_type_sequence *sequence_type =
+ container_of(type, struct bt_ctf_field_type_sequence,
+ parent);
+
+ if (set_byte_order_funcs[
+ sequence_type->element_type->declaration->id]) {
+ set_byte_order_funcs[
+ sequence_type->element_type->declaration->id](
+ sequence_type->element_type, byte_order, set_native);
+ }
}