#include "scanner.h"
#include "parser.h"
#include "ast.h"
+#include "decoder.h"
/* Bit value (left shift) */
#define _BV(_val) (1 << (_val))
/* 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;
* int64_t -> struct bt_ctf_stream_class *
*/
GHashTable *stream_classes;
+
+ /* Config passed by the user */
+ struct ctf_metadata_decoder_config decoder_config;
};
/*
*/
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.");
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:
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)
_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.");
}
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);
_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.");
}
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);
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;
+ }
}
}
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) {
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:
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;
}
/* 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;