+ if (event_name) {
+ g_free(event_name);
+ }
+
+ return ret;
+}
+
+static
+int auto_map_field_to_trace_clock_class(struct ctx *ctx,
+ struct ctf_field_class *fc)
+{
+ struct bt_private_clock_class *clock_class_to_map_to = NULL;
+ struct ctf_field_class_int *int_fc = (void *) fc;
+ int ret = 0;
+ uint64_t clock_class_count;
+
+ if (!fc) {
+ goto end;
+ }
+
+ if (fc->type != CTF_FIELD_CLASS_TYPE_INT &&
+ fc->type != CTF_FIELD_CLASS_TYPE_ENUM) {
+ goto end;
+ }
+
+ if (int_fc->mapped_clock_class) {
+ /* Already mapped */
+ goto end;
+ }
+
+ clock_class_count = ctx->ctf_tc->clock_classes->len;
+
+ switch (clock_class_count) {
+ case 0:
+ /*
+ * No clock class exists in the trace at this point. Create an
+ * implicit one at 1 GHz, named `default`, and use this clock
+ * class.
+ */
+ clock_class_to_map_to = bt_private_clock_class_create();
+ BT_ASSERT(clock_class_to_map_to);
+ bt_private_clock_class_set_frequency(clock_class_to_map_to,
+ UINT64_C(1000000000));
+ ret = bt_private_clock_class_set_name(clock_class_to_map_to,
+ "default");
+ BT_ASSERT(ret == 0);
+ g_ptr_array_add(ctx->ctf_tc->clock_classes,
+ clock_class_to_map_to);
+ bt_object_get_ref(clock_class_to_map_to);
+ break;
+ case 1:
+ /*
+ * Only one clock class exists in the trace at this point: use
+ * this one.
+ */
+ clock_class_to_map_to = ctx->ctf_tc->clock_classes->pdata[0];
+ bt_object_get_ref(clock_class_to_map_to);
+ break;
+ default:
+ /*
+ * Timestamp field not mapped to a clock class and there's more
+ * than one clock class in the trace: this is an error.
+ */
+ BT_LOGE_STR("Timestamp field found with no mapped clock class, "
+ "but there's more than one clock class in the trace at this point.");
+ ret = -1;
+ goto end;
+ }
+
+ BT_ASSERT(clock_class_to_map_to);
+ int_fc->mapped_clock_class = clock_class_to_map_to;
+ bt_object_get_ref(int_fc->mapped_clock_class);
+
+end:
+ bt_object_put_ref(clock_class_to_map_to);
+ return ret;
+}
+
+static
+int auto_map_fields_to_trace_clock_class(struct ctx *ctx,
+ struct ctf_field_class *root_fc, const char *field_name)
+{
+ int ret = 0;
+ uint64_t i, count;
+ struct ctf_field_class_struct *struct_fc = (void *) root_fc;
+ struct ctf_field_class_variant *var_fc = (void *) root_fc;
+
+ if (!root_fc) {
+ goto end;
+ }
+
+ if (root_fc->type != CTF_FIELD_CLASS_TYPE_STRUCT &&
+ root_fc->type != CTF_FIELD_CLASS_TYPE_VARIANT) {
+ goto end;
+ }
+
+ if (root_fc->type == CTF_FIELD_CLASS_TYPE_STRUCT) {
+ count = struct_fc->members->len;
+ } else {
+ count = var_fc->options->len;
+ }
+
+ for (i = 0; i < count; i++) {
+ struct ctf_named_field_class *named_fc = NULL;
+
+ if (root_fc->type == CTF_FIELD_CLASS_TYPE_STRUCT) {
+ named_fc = ctf_field_class_struct_borrow_member_by_index(
+ struct_fc, i);
+ } else if (root_fc->type == CTF_FIELD_CLASS_TYPE_VARIANT) {
+ named_fc = ctf_field_class_variant_borrow_option_by_index(
+ var_fc, i);
+ }
+
+ if (strcmp(named_fc->name->str, field_name) == 0) {
+ ret = auto_map_field_to_trace_clock_class(ctx,
+ named_fc->fc);
+ if (ret) {
+ BT_LOGE("Cannot automatically map field to trace's clock class: "
+ "field-name=\"%s\"", field_name);
+ goto end;
+ }
+ }
+
+ ret = auto_map_fields_to_trace_clock_class(ctx, named_fc->fc,
+ field_name);
+ if (ret) {
+ BT_LOGE("Cannot automatically map structure or variant field class's fields to trace's clock class: "
+ "field-name=\"%s\", root-field-name=\"%s\"",
+ field_name, named_fc->name->str);
+ goto end;
+ }
+ }
+
+end: