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)
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)
{
struct bt_ctf_field_type *get_type_field(struct bt_ctf_field_type *type, int i)
{
struct bt_ctf_field_type *field = NULL;
- const char *unused_name;
enum ctf_type_id type_id = bt_ctf_field_type_get_type_id(type);
if (type_id == CTF_TYPE_STRUCT) {
- bt_ctf_field_type_structure_get_field(type, &unused_name,
+ bt_ctf_field_type_structure_get_field(type, NULL,
&field, i);
} else if (type_id == CTF_TYPE_VARIANT) {
bt_ctf_field_type_variant_get_field(type,
- &unused_name, &field, i);
+ NULL, &field, i);
}
return field;
}
+static inline
+int set_type_field(struct bt_ctf_field_type *type,
+ struct bt_ctf_field_type *field, int i)
+{
+ int ret = -1;
+ enum ctf_type_id type_id = bt_ctf_field_type_get_type_id(type);
+
+ if (type_id == CTF_TYPE_STRUCT) {
+ ret = bt_ctf_field_type_structure_set_field_index(
+ type, field, i);
+ } else if (type_id == CTF_TYPE_VARIANT) {
+ ret = bt_ctf_field_type_variant_set_field_index(
+ type, field, i);
+ }
+
+ return ret;
+}
+
static inline
int get_type_field_index(struct bt_ctf_field_type *type, const char *name)
{
const char *field_name = NULL;
struct bt_ctf_field_path *field_path = NULL;
struct bt_ctf_field_type *resolved_type = NULL;
+ struct bt_ctf_field_type *type_copy = NULL;
+ struct ctf_type_stack_frame *frame;
if (type_id != CTF_TYPE_SEQUENCE &&
type_id != CTF_TYPE_VARIANT) {
/* Print path if in verbose mode */
print_path(field_name, resolved_type, field_path);
- /* Set type's path */
+ /*
+ * Set field type's path.
+ *
+ * The original field is copied since it may have been reused
+ * in multiple structures which would cause a conflict.
+ */
+ type_copy = bt_ctf_field_type_copy(type);
+ if (!type_copy) {
+ ret = -1;
+ goto end;
+ }
+
if (type_id == CTF_TYPE_VARIANT) {
if (bt_ctf_field_type_get_type_id(resolved_type) !=
CTF_TYPE_ENUM) {
ret = -1;
goto end;
}
- ret = bt_ctf_field_type_variant_set_tag(type, resolved_type);
+ ret = bt_ctf_field_type_variant_set_tag(
+ type_copy, resolved_type);
if (ret) {
goto end;
}
- ret = bt_ctf_field_type_variant_set_tag_field_path(type,
+ ret = bt_ctf_field_type_variant_set_tag_field_path(type_copy,
field_path);
if (ret) {
goto end;
goto end;
}
- ret = bt_ctf_field_type_sequence_set_length_field_path(type,
- field_path);
+ ret = bt_ctf_field_type_sequence_set_length_field_path(
+ type_copy, field_path);
if (ret) {
goto end;
}
}
+
+ /* Replace the original field */
+ frame = ctf_type_stack_peek(context->stack);
+ ret = set_type_field(frame->type, type_copy, frame->index);
+ bt_ctf_field_type_put(type_copy);
end:
return ret;
}
int bt_ctf_field_type_structure_get_field_name_index(
struct bt_ctf_field_type *structure, const char *name);
+/* Replace an existing field's type in a structure */
+BT_HIDDEN
+int bt_ctf_field_type_structure_set_field_index(
+ struct bt_ctf_field_type *structure,
+ struct bt_ctf_field_type *field, int index);
+
BT_HIDDEN
int bt_ctf_field_type_variant_get_field_name_index(
struct bt_ctf_field_type *variant, const char *name);
int bt_ctf_field_type_variant_set_tag(struct bt_ctf_field_type *type,
struct bt_ctf_field_type *tag);
+/* Replace an existing field's type in a variant */
+BT_HIDDEN
+int bt_ctf_field_type_variant_set_field_index(
+ struct bt_ctf_field_type *variant,
+ struct bt_ctf_field_type *field, int index);
+
#endif /* BABELTRACE_CTF_IR_EVENT_TYPES_INTERNAL_H */