visitor-generate-ir.c: automatically map specific fields to trace's clock class
[deliverable/babeltrace.git] / plugins / ctf / common / metadata / visitor-generate-ir.c
index 19a67896bfe936b850d7b41d75c66cf2f71c6cc0..4188d45bdc6fcedc85acac5b6db4030287ecffad 100644 (file)
@@ -54,6 +54,7 @@
 #include "scanner.h"
 #include "parser.h"
 #include "ast.h"
+#include "decoder.h"
 
 /* Bit value (left shift) */
 #define _BV(_val)              (1 << (_val))
@@ -200,9 +201,6 @@ struct ctx {
        /* 1 if this is an LTTng trace */
        bool is_lttng;
 
-       /* Offset (ns) to apply to clock classes on creation */
-       int64_t clock_class_offset_ns;
-
        /* Eventual name suffix of the trace to set */
        char *trace_name_suffix;
 
@@ -218,6 +216,9 @@ struct ctx {
         * int64_t -> struct bt_ctf_stream_class *
         */
        GHashTable *stream_classes;
+
+       /* Config passed by the user */
+       struct ctf_metadata_decoder_config decoder_config;
 };
 
 /*
@@ -601,11 +602,14 @@ end:
  */
 static
 struct ctx *ctx_create(struct bt_ctf_trace *trace,
-               int64_t clock_class_offset_ns, const char *trace_name_suffix)
+               const struct ctf_metadata_decoder_config *decoder_config,
+               const char *trace_name_suffix)
 {
        struct ctx *ctx = NULL;
        struct ctx_decl_scope *scope = NULL;
 
+       assert(decoder_config);
+
        ctx = g_new0(struct ctx, 1);
        if (!ctx) {
                BT_LOGE_STR("Failed to allocate one visitor context.");
@@ -638,7 +642,7 @@ struct ctx *ctx_create(struct bt_ctf_trace *trace,
        ctx->current_scope = scope;
        scope = NULL;
        ctx->trace_bo = BT_CTF_BYTE_ORDER_NATIVE;
-       ctx->clock_class_offset_ns = clock_class_offset_ns;
+       ctx->decoder_config = *decoder_config;
        return ctx;
 
 error:
@@ -3757,6 +3761,67 @@ end:
        return ret;
 }
 
+static
+int auto_map_fields_to_trace_clock_class(struct ctx *ctx,
+               struct bt_ctf_field_type *packet_context_field_type,
+               const char **field_names)
+{
+       _BT_CTF_FIELD_TYPE_INIT(ft);
+       struct bt_ctf_clock_class *clock_class = NULL;
+       struct bt_ctf_clock_class *mapped_clock_class = NULL;
+       int ret = 0;
+       const char **field_name;
+
+       if (ctx->decoder_config.strict) {
+               goto end;
+       }
+
+       if (!packet_context_field_type) {
+               goto end;
+       }
+
+       if (!bt_ctf_field_type_is_structure(packet_context_field_type)) {
+               goto end;
+       }
+
+       if (bt_ctf_trace_get_clock_class_count(ctx->trace) != 1) {
+               goto end;
+       }
+
+       clock_class = bt_ctf_trace_get_clock_class_by_index(ctx->trace, 0);
+       assert(clock_class);
+
+       for (field_name = field_names; *field_name; field_name++) {
+               ft = bt_ctf_field_type_structure_get_field_type_by_name(
+                       packet_context_field_type, *field_name);
+
+               if (ft && bt_ctf_field_type_is_integer(ft)) {
+                       mapped_clock_class =
+                               bt_ctf_field_type_integer_get_mapped_clock_class(ft);
+
+                       if (!mapped_clock_class) {
+                               ret = bt_ctf_field_type_integer_set_mapped_clock_class(
+                                       ft, clock_class);
+                               if (ret) {
+                                       BT_LOGE("Cannot map field type's field to trace's clock class: "
+                                               "field-name=\"%s\", ret=%d",
+                                               *field_name, ret);
+                                       goto end;
+                               }
+                       }
+               }
+
+               BT_PUT(mapped_clock_class);
+               BT_PUT(ft);
+       }
+
+end:
+       bt_put(mapped_clock_class);
+       bt_put(clock_class);
+       bt_put(ft);
+       return ret;
+}
+
 static
 int visit_stream_decl_entry(struct ctx *ctx, struct ctf_node *node,
        struct bt_ctf_stream_class *stream_class, int *set)
@@ -3834,6 +3899,12 @@ int visit_stream_decl_entry(struct ctx *ctx, struct ctf_node *node,
 
                        _SET(set, _STREAM_ID_SET);
                } else if (!strcmp(left, "event.header")) {
+                       const char *field_names[] = {
+                               "timestamp",
+                               "ts",
+                               NULL,
+                       };
+
                        if (_IS_SET(set, _STREAM_EVENT_HEADER_SET)) {
                                _BT_LOGE_NODE(node,
                                        "Duplicate `event.header` entry in stream class.");
@@ -3853,6 +3924,13 @@ int visit_stream_decl_entry(struct ctx *ctx, struct ctf_node *node,
                        }
 
                        assert(decl);
+                       ret = auto_map_fields_to_trace_clock_class(ctx,
+                               decl, field_names);
+                       if (ret) {
+                               _BT_LOGE_NODE(node,
+                                       "Cannot automatically map specific event header field type fields to trace's clock class.");
+                               goto error;
+                       }
 
                        ret = bt_ctf_stream_class_set_event_header_type(
                                stream_class, decl);
@@ -3896,6 +3974,12 @@ int visit_stream_decl_entry(struct ctx *ctx, struct ctf_node *node,
 
                        _SET(set, _STREAM_EVENT_CONTEXT_SET);
                } else if (!strcmp(left, "packet.context")) {
+                       const char *field_names[] = {
+                               "timestamp_begin",
+                               "timestamp_end",
+                               NULL,
+                       };
+
                        if (_IS_SET(set, _STREAM_PACKET_CONTEXT_SET)) {
                                _BT_LOGE_NODE(node,
                                        "Duplicate `packet.context` entry in stream class.");
@@ -3915,6 +3999,13 @@ int visit_stream_decl_entry(struct ctx *ctx, struct ctf_node *node,
                        }
 
                        assert(decl);
+                       ret = auto_map_fields_to_trace_clock_class(ctx,
+                               decl, field_names);
+                       if (ret) {
+                               _BT_LOGE_NODE(node,
+                                       "Cannot automatically map specific packet context field type fields to trace's clock class.");
+                               goto error;
+                       }
 
                        ret = bt_ctf_stream_class_set_packet_context_type(
                                stream_class, decl);
@@ -4348,12 +4439,14 @@ int visit_env(struct ctx *ctx, struct ctf_node *node)
                                goto error;
                        }
 
-                       if (strcmp(left, "tracer_name") == 0) {
-                               if (strncmp(right, "lttng", 5) == 0) {
-                                       BT_LOGI("Detected LTTng trace from `%s` environment value: "
-                                               "tracer-name=\"%s\"",
-                                               left, right);
-                                       ctx->is_lttng = 1;
+                       if (!ctx->decoder_config.strict) {
+                               if (strcmp(left, "tracer_name") == 0) {
+                                       if (strncmp(right, "lttng", 5) == 0) {
+                                               BT_LOGI("Non-strict mode: detected LTTng trace from `%s` environment value: "
+                                                       "tracer-name=\"%s\"",
+                                                       left, right);
+                                               ctx->is_lttng = 1;
+                                       }
                                }
                        }
 
@@ -4770,6 +4863,7 @@ int apply_clock_class_offset(struct ctx *ctx, struct bt_ctf_clock_class *clock)
        int ret;
        uint64_t freq;
        int64_t offset_cycles;
+       int64_t offset_to_apply;
 
        freq = bt_ctf_clock_class_get_frequency(clock);
        if (freq == -1ULL) {
@@ -4785,7 +4879,10 @@ int apply_clock_class_offset(struct ctx *ctx, struct bt_ctf_clock_class *clock)
                goto end;
        }
 
-       offset_cycles += cycles_from_ns(freq, ctx->clock_class_offset_ns);
+       offset_to_apply =
+               ctx->decoder_config.clock_class_offset_s * 1000000000LL +
+               ctx->decoder_config.clock_class_offset_ns;
+       offset_cycles += cycles_from_ns(freq, offset_to_apply);
        ret = bt_ctf_clock_class_set_offset_cycles(clock, offset_cycles);
 
 end:
@@ -5033,7 +5130,8 @@ end:
 
 BT_HIDDEN
 struct ctf_visitor_generate_ir *ctf_visitor_generate_ir_create(
-               int64_t clock_class_offset_ns, const char *name)
+               const struct ctf_metadata_decoder_config *decoder_config,
+               const char *name)
 {
        int ret;
        struct ctx *ctx = NULL;
@@ -5053,7 +5151,7 @@ struct ctf_visitor_generate_ir *ctf_visitor_generate_ir_create(
        }
 
        /* Create visitor's context */
-       ctx = ctx_create(trace, clock_class_offset_ns, name);
+       ctx = ctx_create(trace, decoder_config, name);
        if (!ctx) {
                BT_LOGE_STR("Cannot create visitor's context.");
                goto error;
This page took 0.028664 seconds and 5 git commands to generate.