From 4164020e790fa6c0700715936b40a3fa46df479e Mon Sep 17 00:00:00 2001 From: Simon Marchi Date: Fri, 21 Jan 2022 21:11:21 -0500 Subject: [PATCH] Re-format new C++ files Run tools/format-cpp to format the C++ files introduced in the previous commit. Then, run: sed -ri 's|^\t \*| *|' $(find . -name '*.cpp' -o -name '*.hpp') sed -ri 's|^\t\t \*| *|' $(find . -name '*.cpp' -o -name '*.hpp') sed -ri 's|^\t\t\t \*| *|' $(find . -name '*.cpp' -o -name '*.hpp') sed -ri 's|^\t\t\t\t \*| *|' $(find . -name '*.cpp' -o -name '*.hpp') sed -ri 's|^\t\t\t\t\t \*| *|' $(find . -name '*.cpp' -o -name '*.hpp') to fix up the multi-line comments which didn't get un-indented by clang-format. Change-Id: Iaf22f898ea5d0839b55d9f1bf09eb3754dc56cf2 Signed-off-by: Simon Marchi Reviewed-on: https://review.lttng.org/c/babeltrace/+/7105 Reviewed-by: Philippe Proulx --- src/cpp-tester/Makefile.am | 9 + src/cpp-tester/cpp-tester.cpp | 13 + src/plugins/ctf/common/bfcr/bfcr.cpp | 2171 ++--- src/plugins/ctf/common/bfcr/bfcr.hpp | 430 +- src/plugins/ctf/common/metadata/ast.hpp | 741 +- .../metadata/ctf-meta-configure-ir-trace.cpp | 69 +- .../metadata/ctf-meta-configure-ir-trace.hpp | 3 +- .../ctf/common/metadata/ctf-meta-resolve.cpp | 2021 ++-- .../common/metadata/ctf-meta-translate.cpp | 1120 +-- .../metadata/ctf-meta-update-alignments.cpp | 289 +- .../ctf-meta-update-default-clock-classes.cpp | 319 +- .../common/metadata/ctf-meta-update-in-ir.cpp | 469 +- .../metadata/ctf-meta-update-meanings.cpp | 367 +- .../ctf-meta-update-stream-class-config.cpp | 79 +- .../ctf-meta-update-text-array-sequence.cpp | 264 +- .../ctf-meta-update-value-storing-indexes.cpp | 269 +- .../ctf/common/metadata/ctf-meta-validate.cpp | 618 +- .../ctf/common/metadata/ctf-meta-visitors.hpp | 19 +- ...tf-meta-warn-meaningless-header-fields.cpp | 206 +- src/plugins/ctf/common/metadata/ctf-meta.hpp | 2612 +++-- .../decoder-packetized-file-stream-to-buf.cpp | 447 +- .../decoder-packetized-file-stream-to-buf.hpp | 10 +- src/plugins/ctf/common/metadata/decoder.cpp | 743 +- src/plugins/ctf/common/metadata/decoder.hpp | 101 +- src/plugins/ctf/common/metadata/logging.hpp | 56 +- src/plugins/ctf/common/metadata/objstack.cpp | 169 +- .../ctf/common/metadata/parser-wrap.hpp | 6 +- .../ctf/common/metadata/scanner-symbols.hpp | 54 +- src/plugins/ctf/common/metadata/scanner.hpp | 29 +- .../common/metadata/visitor-generate-ir.cpp | 8560 ++++++++--------- .../common/metadata/visitor-parent-links.cpp | 839 +- .../metadata/visitor-semantic-validator.cpp | 1925 ++-- src/plugins/ctf/common/msg-iter/msg-iter.cpp | 5541 ++++++----- src/plugins/ctf/common/msg-iter/msg-iter.hpp | 449 +- src/plugins/ctf/common/print.hpp | 42 +- src/plugins/ctf/fs-sink/fs-sink-ctf-meta.hpp | 1390 ++- src/plugins/ctf/fs-sink/fs-sink-stream.cpp | 1139 ++- src/plugins/ctf/fs-sink/fs-sink-stream.hpp | 291 +- src/plugins/ctf/fs-sink/fs-sink-trace.cpp | 934 +- src/plugins/ctf/fs-sink/fs-sink-trace.hpp | 72 +- src/plugins/ctf/fs-sink/fs-sink.cpp | 1969 ++-- src/plugins/ctf/fs-sink/fs-sink.hpp | 73 +- .../ctf/fs-sink/translate-ctf-ir-to-tsdl.cpp | 1678 ++-- .../ctf/fs-sink/translate-ctf-ir-to-tsdl.hpp | 3 +- .../fs-sink/translate-trace-ir-to-ctf-ir.cpp | 2915 +++--- .../fs-sink/translate-trace-ir-to-ctf-ir.hpp | 22 +- src/plugins/ctf/fs-src/data-stream-file.cpp | 1589 ++- src/plugins/ctf/fs-src/data-stream-file.hpp | 93 +- src/plugins/ctf/fs-src/file.cpp | 134 +- src/plugins/ctf/fs-src/file.hpp | 3 +- src/plugins/ctf/fs-src/fs.cpp | 3904 ++++---- src/plugins/ctf/fs-src/fs.hpp | 316 +- src/plugins/ctf/fs-src/lttng-index.hpp | 42 +- src/plugins/ctf/fs-src/metadata.cpp | 167 +- src/plugins/ctf/fs-src/metadata.hpp | 16 +- src/plugins/ctf/fs-src/query.cpp | 856 +- src/plugins/ctf/fs-src/query.hpp | 22 +- src/plugins/ctf/lttng-live/data-stream.cpp | 466 +- src/plugins/ctf/lttng-live/data-stream.hpp | 20 +- src/plugins/ctf/lttng-live/lttng-live.cpp | 3853 ++++---- src/plugins/ctf/lttng-live/lttng-live.hpp | 484 +- .../ctf/lttng-live/lttng-viewer-abi.hpp | 315 +- src/plugins/ctf/lttng-live/metadata.cpp | 588 +- src/plugins/ctf/lttng-live/metadata.hpp | 8 +- .../ctf/lttng-live/viewer-connection.cpp | 3321 +++---- .../ctf/lttng-live/viewer-connection.hpp | 135 +- src/plugins/ctf/plugin.cpp | 50 +- 67 files changed, 27991 insertions(+), 29936 deletions(-) create mode 100644 src/cpp-tester/Makefile.am create mode 100644 src/cpp-tester/cpp-tester.cpp diff --git a/src/cpp-tester/Makefile.am b/src/cpp-tester/Makefile.am new file mode 100644 index 00000000..18a254d8 --- /dev/null +++ b/src/cpp-tester/Makefile.am @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: MIT + +noinst_PROGRAMS = cpp-tester + +cpp_tester_SOURCES = cpp-tester.cpp +cpp_tester_LDADD = \ + $(top_builddir)/src/lib/libbabeltrace2.la \ + $(top_builddir)/src/common/libbabeltrace2-common.la \ + $(top_builddir)/src/logging/libbabeltrace2-logging.la diff --git a/src/cpp-tester/cpp-tester.cpp b/src/cpp-tester/cpp-tester.cpp new file mode 100644 index 00000000..8e46fe4c --- /dev/null +++ b/src/cpp-tester/cpp-tester.cpp @@ -0,0 +1,13 @@ +#include +#include + +#include "cpp-common/bt2/value.hpp" + +void f(bt2::BoolValue::Shared lel) +{ +} + +int main() +{ + f(bt2::NullValue {}.shared()); +} diff --git a/src/plugins/ctf/common/bfcr/bfcr.cpp b/src/plugins/ctf/common/bfcr/bfcr.cpp index b745dd05..d1495a61 100644 --- a/src/plugins/ctf/common/bfcr/bfcr.cpp +++ b/src/plugins/ctf/common/bfcr/bfcr.cpp @@ -8,8 +8,8 @@ */ #define BT_COMP_LOG_SELF_COMP (bfcr->self_comp) -#define BT_LOG_OUTPUT_LEVEL (bfcr->log_level) -#define BT_LOG_TAG "PLUGIN/CTF/BFCR" +#define BT_LOG_OUTPUT_LEVEL (bfcr->log_level) +#define BT_LOG_TAG "PLUGIN/CTF/BFCR" #include "logging/comp-logging.h" #include @@ -29,1323 +29,1244 @@ #include "bfcr.hpp" #include "../metadata/ctf-meta.hpp" -#define DIV8(_x) ((_x) >> 3) -#define BYTES_TO_BITS(_x) ((_x) * 8) -#define BITS_TO_BYTES_FLOOR(_x) DIV8(_x) -#define BITS_TO_BYTES_CEIL(_x) DIV8((_x) + 7) -#define IN_BYTE_OFFSET(_at) ((_at) & 7) +#define DIV8(_x) ((_x) >> 3) +#define BYTES_TO_BITS(_x) ((_x) *8) +#define BITS_TO_BYTES_FLOOR(_x) DIV8(_x) +#define BITS_TO_BYTES_CEIL(_x) DIV8((_x) + 7) +#define IN_BYTE_OFFSET(_at) ((_at) &7) /* A visit stack entry */ -struct stack_entry { - /* - * Current class of base field, one of: - * - * * Structure - * * Array - * * Sequence - * * Variant - */ - struct ctf_field_class *base_class; - - /* Length of base field (always 1 for a variant class) */ - int64_t base_len; - - /* Index of next field to read */ - int64_t index; +struct stack_entry +{ + /* + * Current class of base field, one of: + * + * * Structure + * * Array + * * Sequence + * * Variant + */ + struct ctf_field_class *base_class; + + /* Length of base field (always 1 for a variant class) */ + int64_t base_len; + + /* Index of next field to read */ + int64_t index; }; struct bt_bfcr; /* Visit stack */ -struct stack { - struct bt_bfcr *bfcr; +struct stack +{ + struct bt_bfcr *bfcr; - /* Entries (struct stack_entry) */ - GArray *entries; + /* Entries (struct stack_entry) */ + GArray *entries; - /* Number of active entries */ - size_t size; + /* Number of active entries */ + size_t size; }; /* Reading states */ -enum bfcr_state { - BFCR_STATE_NEXT_FIELD, - BFCR_STATE_ALIGN_BASIC, - BFCR_STATE_ALIGN_COMPOUND, - BFCR_STATE_READ_BASIC_BEGIN, - BFCR_STATE_READ_BASIC_CONTINUE, - BFCR_STATE_DONE, +enum bfcr_state +{ + BFCR_STATE_NEXT_FIELD, + BFCR_STATE_ALIGN_BASIC, + BFCR_STATE_ALIGN_COMPOUND, + BFCR_STATE_READ_BASIC_BEGIN, + BFCR_STATE_READ_BASIC_CONTINUE, + BFCR_STATE_DONE, }; /* Binary class reader */ -struct bt_bfcr { - bt_logging_level log_level; - - /* Weak */ - bt_self_component *self_comp; - - /* BFCR stack */ - struct stack *stack; - - /* Current basic field class */ - struct ctf_field_class *cur_basic_field_class; - - /* Current state */ - enum bfcr_state state; - - /* - * Last basic field class's byte order. - * - * This is used to detect errors since two contiguous basic - * classes for which the common boundary is not the boundary of - * a byte cannot have different byte orders. - * - * This is set to CTF_BYTE_ORDER_UNKNOWN on reset and when the last - * basic field class was a string class. - */ - enum ctf_byte_order last_bo; - - /* Current byte order (copied to last_bo after a successful read) */ - enum ctf_byte_order cur_bo; - - /* Stitch buffer infos */ - struct { - /* Stitch buffer */ - uint8_t buf[16]; - - /* Offset, within stitch buffer, of first bit */ - size_t offset; - - /* Length (bits) of data in stitch buffer from offset */ - size_t at; - } stitch; - - /* User buffer infos */ - struct { - /* Address */ - const uint8_t *addr; - - /* Offset of data from address (bits) */ - size_t offset; - - /* Current position from offset (bits) */ - size_t at; - - /* Offset of offset within whole packet (bits) */ - size_t packet_offset; - - /* Data size in buffer (bits) */ - size_t sz; - - /* Buffer size (bytes) */ - size_t buf_sz; - } buf; - - /* User stuff */ - struct { - /* Callback functions */ - struct bt_bfcr_cbs cbs; - - /* Private data */ - void *data; - } user; +struct bt_bfcr +{ + bt_logging_level log_level; + + /* Weak */ + bt_self_component *self_comp; + + /* BFCR stack */ + struct stack *stack; + + /* Current basic field class */ + struct ctf_field_class *cur_basic_field_class; + + /* Current state */ + enum bfcr_state state; + + /* + * Last basic field class's byte order. + * + * This is used to detect errors since two contiguous basic + * classes for which the common boundary is not the boundary of + * a byte cannot have different byte orders. + * + * This is set to CTF_BYTE_ORDER_UNKNOWN on reset and when the last + * basic field class was a string class. + */ + enum ctf_byte_order last_bo; + + /* Current byte order (copied to last_bo after a successful read) */ + enum ctf_byte_order cur_bo; + + /* Stitch buffer infos */ + struct + { + /* Stitch buffer */ + uint8_t buf[16]; + + /* Offset, within stitch buffer, of first bit */ + size_t offset; + + /* Length (bits) of data in stitch buffer from offset */ + size_t at; + } stitch; + + /* User buffer infos */ + struct + { + /* Address */ + const uint8_t *addr; + + /* Offset of data from address (bits) */ + size_t offset; + + /* Current position from offset (bits) */ + size_t at; + + /* Offset of offset within whole packet (bits) */ + size_t packet_offset; + + /* Data size in buffer (bits) */ + size_t sz; + + /* Buffer size (bytes) */ + size_t buf_sz; + } buf; + + /* User stuff */ + struct + { + /* Callback functions */ + struct bt_bfcr_cbs cbs; + + /* Private data */ + void *data; + } user; }; -static inline -const char *bfcr_state_string(enum bfcr_state state) +static inline const char *bfcr_state_string(enum bfcr_state state) { - switch (state) { - case BFCR_STATE_NEXT_FIELD: - return "NEXT_FIELD"; - case BFCR_STATE_ALIGN_BASIC: - return "ALIGN_BASIC"; - case BFCR_STATE_ALIGN_COMPOUND: - return "ALIGN_COMPOUND"; - case BFCR_STATE_READ_BASIC_BEGIN: - return "READ_BASIC_BEGIN"; - case BFCR_STATE_READ_BASIC_CONTINUE: - return "READ_BASIC_CONTINUE"; - case BFCR_STATE_DONE: - return "DONE"; - } - - bt_common_abort(); + switch (state) { + case BFCR_STATE_NEXT_FIELD: + return "NEXT_FIELD"; + case BFCR_STATE_ALIGN_BASIC: + return "ALIGN_BASIC"; + case BFCR_STATE_ALIGN_COMPOUND: + return "ALIGN_COMPOUND"; + case BFCR_STATE_READ_BASIC_BEGIN: + return "READ_BASIC_BEGIN"; + case BFCR_STATE_READ_BASIC_CONTINUE: + return "READ_BASIC_CONTINUE"; + case BFCR_STATE_DONE: + return "DONE"; + } + + bt_common_abort(); } -static -struct stack *stack_new(struct bt_bfcr *bfcr) +static struct stack *stack_new(struct bt_bfcr *bfcr) { - struct stack *stack = NULL; + struct stack *stack = NULL; - stack = g_new0(struct stack, 1); - if (!stack) { - BT_COMP_LOGE_STR("Failed to allocate one stack."); - goto error; - } + stack = g_new0(struct stack, 1); + if (!stack) { + BT_COMP_LOGE_STR("Failed to allocate one stack."); + goto error; + } - stack->bfcr = bfcr; - stack->entries = g_array_new(FALSE, TRUE, sizeof(struct stack_entry)); - if (!stack->entries) { - BT_COMP_LOGE_STR("Failed to allocate a GArray."); - goto error; - } + stack->bfcr = bfcr; + stack->entries = g_array_new(FALSE, TRUE, sizeof(struct stack_entry)); + if (!stack->entries) { + BT_COMP_LOGE_STR("Failed to allocate a GArray."); + goto error; + } - BT_COMP_LOGD("Created stack: addr=%p", stack); - return stack; + BT_COMP_LOGD("Created stack: addr=%p", stack); + return stack; error: - g_free(stack); - return NULL; + g_free(stack); + return NULL; } -static -void stack_destroy(struct stack *stack) +static void stack_destroy(struct stack *stack) { - struct bt_bfcr *bfcr; + struct bt_bfcr *bfcr; - if (!stack) { - return; - } + if (!stack) { + return; + } - bfcr = stack->bfcr; - BT_COMP_LOGD("Destroying stack: addr=%p", stack); + bfcr = stack->bfcr; + BT_COMP_LOGD("Destroying stack: addr=%p", stack); - if (stack->entries) { - g_array_free(stack->entries, TRUE); - } + if (stack->entries) { + g_array_free(stack->entries, TRUE); + } - g_free(stack); + g_free(stack); } -static -int stack_push(struct stack *stack, struct ctf_field_class *base_class, - size_t base_len) +static int stack_push(struct stack *stack, struct ctf_field_class *base_class, size_t base_len) { - struct stack_entry *entry; - struct bt_bfcr *bfcr; - - BT_ASSERT_DBG(stack); - BT_ASSERT_DBG(base_class); - bfcr = stack->bfcr; - BT_COMP_LOGT("Pushing field class on stack: stack-addr=%p, " - "fc-addr=%p, fc-type=%d, base-length=%zu, " - "stack-size-before=%zu, stack-size-after=%zu", - stack, base_class, base_class->type, - base_len, stack->size, stack->size + 1); - - if (stack->entries->len == stack->size) { - g_array_set_size(stack->entries, stack->size + 1); - } - - entry = &g_array_index(stack->entries, struct stack_entry, stack->size); - entry->base_class = base_class; - entry->base_len = base_len; - entry->index = 0; - stack->size++; - return 0; + struct stack_entry *entry; + struct bt_bfcr *bfcr; + + BT_ASSERT_DBG(stack); + BT_ASSERT_DBG(base_class); + bfcr = stack->bfcr; + BT_COMP_LOGT("Pushing field class on stack: stack-addr=%p, " + "fc-addr=%p, fc-type=%d, base-length=%zu, " + "stack-size-before=%zu, stack-size-after=%zu", + stack, base_class, base_class->type, base_len, stack->size, stack->size + 1); + + if (stack->entries->len == stack->size) { + g_array_set_size(stack->entries, stack->size + 1); + } + + entry = &g_array_index(stack->entries, struct stack_entry, stack->size); + entry->base_class = base_class; + entry->base_len = base_len; + entry->index = 0; + stack->size++; + return 0; } -static inline -int64_t get_compound_field_class_length(struct bt_bfcr *bfcr, - struct ctf_field_class *fc) +static inline int64_t get_compound_field_class_length(struct bt_bfcr *bfcr, + struct ctf_field_class *fc) { - int64_t length; - - switch (fc->type) { - case CTF_FIELD_CLASS_TYPE_STRUCT: - { - ctf_field_class_struct *struct_fc = ctf_field_class_as_struct(fc); - - length = (int64_t) struct_fc->members->len; - break; - } - case CTF_FIELD_CLASS_TYPE_VARIANT: - { - /* Variant field classes always "contain" a single class */ - length = 1; - break; - } - case CTF_FIELD_CLASS_TYPE_ARRAY: - { - struct ctf_field_class_array *array_fc = ctf_field_class_as_array(fc); - - length = (int64_t) array_fc->length; - break; - } - case CTF_FIELD_CLASS_TYPE_SEQUENCE: - length = bfcr->user.cbs.query.get_sequence_length(fc, - bfcr->user.data); - break; - default: - bt_common_abort(); - } - - return length; + int64_t length; + + switch (fc->type) { + case CTF_FIELD_CLASS_TYPE_STRUCT: + { + ctf_field_class_struct *struct_fc = ctf_field_class_as_struct(fc); + + length = (int64_t) struct_fc->members->len; + break; + } + case CTF_FIELD_CLASS_TYPE_VARIANT: + { + /* Variant field classes always "contain" a single class */ + length = 1; + break; + } + case CTF_FIELD_CLASS_TYPE_ARRAY: + { + struct ctf_field_class_array *array_fc = ctf_field_class_as_array(fc); + + length = (int64_t) array_fc->length; + break; + } + case CTF_FIELD_CLASS_TYPE_SEQUENCE: + length = bfcr->user.cbs.query.get_sequence_length(fc, bfcr->user.data); + break; + default: + bt_common_abort(); + } + + return length; } -static -int stack_push_with_len(struct bt_bfcr *bfcr, struct ctf_field_class *base_class) +static int stack_push_with_len(struct bt_bfcr *bfcr, struct ctf_field_class *base_class) { - int ret; - int64_t length = get_compound_field_class_length(bfcr, base_class); + int ret; + int64_t length = get_compound_field_class_length(bfcr, base_class); - if (length < 0) { - BT_COMP_LOGW("Cannot get compound field class's field count: " - "bfcr-addr=%p, fc-addr=%p, fc-type=%d", - bfcr, base_class, base_class->type); - ret = BT_BFCR_STATUS_ERROR; - goto end; - } + if (length < 0) { + BT_COMP_LOGW("Cannot get compound field class's field count: " + "bfcr-addr=%p, fc-addr=%p, fc-type=%d", + bfcr, base_class, base_class->type); + ret = BT_BFCR_STATUS_ERROR; + goto end; + } - ret = stack_push(bfcr->stack, base_class, (size_t) length); + ret = stack_push(bfcr->stack, base_class, (size_t) length); end: - return ret; + return ret; } -static inline -unsigned int stack_size(struct stack *stack) +static inline unsigned int stack_size(struct stack *stack) { - BT_ASSERT_DBG(stack); - return stack->size; + BT_ASSERT_DBG(stack); + return stack->size; } -static -void stack_pop(struct stack *stack) +static void stack_pop(struct stack *stack) { - struct bt_bfcr *bfcr; - - BT_ASSERT_DBG(stack); - BT_ASSERT_DBG(stack_size(stack)); - bfcr = stack->bfcr; - BT_COMP_LOGT("Popping from stack: " - "stack-addr=%p, stack-size-before=%u, stack-size-after=%u", - stack, stack->entries->len, stack->entries->len - 1); - stack->size--; + struct bt_bfcr *bfcr; + + BT_ASSERT_DBG(stack); + BT_ASSERT_DBG(stack_size(stack)); + bfcr = stack->bfcr; + BT_COMP_LOGT("Popping from stack: " + "stack-addr=%p, stack-size-before=%u, stack-size-after=%u", + stack, stack->entries->len, stack->entries->len - 1); + stack->size--; } -static inline -bool stack_empty(struct stack *stack) +static inline bool stack_empty(struct stack *stack) { - return stack_size(stack) == 0; + return stack_size(stack) == 0; } -static -void stack_clear(struct stack *stack) +static void stack_clear(struct stack *stack) { - BT_ASSERT_DBG(stack); - stack->size = 0; + BT_ASSERT_DBG(stack); + stack->size = 0; } -static inline -struct stack_entry *stack_top(struct stack *stack) +static inline struct stack_entry *stack_top(struct stack *stack) { - BT_ASSERT_DBG(stack); - BT_ASSERT_DBG(stack_size(stack)); - return &g_array_index(stack->entries, struct stack_entry, - stack->size - 1); + BT_ASSERT_DBG(stack); + BT_ASSERT_DBG(stack_size(stack)); + return &g_array_index(stack->entries, struct stack_entry, stack->size - 1); } -static inline -size_t available_bits(struct bt_bfcr *bfcr) +static inline size_t available_bits(struct bt_bfcr *bfcr) { - return bfcr->buf.sz - bfcr->buf.at; + return bfcr->buf.sz - bfcr->buf.at; } -static inline -void consume_bits(struct bt_bfcr *bfcr, size_t incr) +static inline void consume_bits(struct bt_bfcr *bfcr, size_t incr) { - BT_COMP_LOGT("Advancing cursor: bfcr-addr=%p, cur-before=%zu, cur-after=%zu", - bfcr, bfcr->buf.at, bfcr->buf.at + incr); - bfcr->buf.at += incr; + BT_COMP_LOGT("Advancing cursor: bfcr-addr=%p, cur-before=%zu, cur-after=%zu", bfcr, + bfcr->buf.at, bfcr->buf.at + incr); + bfcr->buf.at += incr; } -static inline -bool has_enough_bits(struct bt_bfcr *bfcr, size_t sz) +static inline bool has_enough_bits(struct bt_bfcr *bfcr, size_t sz) { - return available_bits(bfcr) >= sz; + return available_bits(bfcr) >= sz; } -static inline -bool at_least_one_bit_left(struct bt_bfcr *bfcr) +static inline bool at_least_one_bit_left(struct bt_bfcr *bfcr) { - return has_enough_bits(bfcr, 1); + return has_enough_bits(bfcr, 1); } -static inline -size_t packet_at(struct bt_bfcr *bfcr) +static inline size_t packet_at(struct bt_bfcr *bfcr) { - return bfcr->buf.packet_offset + bfcr->buf.at; + return bfcr->buf.packet_offset + bfcr->buf.at; } -static inline -size_t buf_at_from_addr(struct bt_bfcr *bfcr) +static inline size_t buf_at_from_addr(struct bt_bfcr *bfcr) { - /* - * Considering this: - * - * ====== offset ===== (17) - * - * xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx - * ^ - * addr (0) ==== at ==== (12) - * - * We want this: - * - * =============================== (29) - */ - return bfcr->buf.offset + bfcr->buf.at; + /* + * Considering this: + * + * ====== offset ===== (17) + * + * xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx + * ^ + * addr (0) ==== at ==== (12) + * + * We want this: + * + * =============================== (29) + */ + return bfcr->buf.offset + bfcr->buf.at; } -static -void stitch_reset(struct bt_bfcr *bfcr) +static void stitch_reset(struct bt_bfcr *bfcr) { - bfcr->stitch.offset = 0; - bfcr->stitch.at = 0; + bfcr->stitch.offset = 0; + bfcr->stitch.at = 0; } -static inline -size_t stitch_at_from_addr(struct bt_bfcr *bfcr) +static inline size_t stitch_at_from_addr(struct bt_bfcr *bfcr) { - return bfcr->stitch.offset + bfcr->stitch.at; + return bfcr->stitch.offset + bfcr->stitch.at; } -static -void stitch_append_from_buf(struct bt_bfcr *bfcr, size_t sz) +static void stitch_append_from_buf(struct bt_bfcr *bfcr, size_t sz) { - size_t stitch_byte_at; - size_t buf_byte_at; - size_t nb_bytes; - - if (sz == 0) { - return; - } - - stitch_byte_at = - BITS_TO_BYTES_FLOOR(stitch_at_from_addr(bfcr)); - buf_byte_at = BITS_TO_BYTES_FLOOR(buf_at_from_addr(bfcr)); - nb_bytes = BITS_TO_BYTES_CEIL(sz); - BT_ASSERT(nb_bytes > 0); - BT_ASSERT(bfcr->buf.addr); - memcpy(&bfcr->stitch.buf[stitch_byte_at], &bfcr->buf.addr[buf_byte_at], - nb_bytes); - bfcr->stitch.at += sz; - consume_bits(bfcr, sz); + size_t stitch_byte_at; + size_t buf_byte_at; + size_t nb_bytes; + + if (sz == 0) { + return; + } + + stitch_byte_at = BITS_TO_BYTES_FLOOR(stitch_at_from_addr(bfcr)); + buf_byte_at = BITS_TO_BYTES_FLOOR(buf_at_from_addr(bfcr)); + nb_bytes = BITS_TO_BYTES_CEIL(sz); + BT_ASSERT(nb_bytes > 0); + BT_ASSERT(bfcr->buf.addr); + memcpy(&bfcr->stitch.buf[stitch_byte_at], &bfcr->buf.addr[buf_byte_at], nb_bytes); + bfcr->stitch.at += sz; + consume_bits(bfcr, sz); } -static -void stitch_append_from_remaining_buf(struct bt_bfcr *bfcr) +static void stitch_append_from_remaining_buf(struct bt_bfcr *bfcr) { - stitch_append_from_buf(bfcr, available_bits(bfcr)); + stitch_append_from_buf(bfcr, available_bits(bfcr)); } -static -void stitch_set_from_remaining_buf(struct bt_bfcr *bfcr) +static void stitch_set_from_remaining_buf(struct bt_bfcr *bfcr) { - stitch_reset(bfcr); - bfcr->stitch.offset = IN_BYTE_OFFSET(buf_at_from_addr(bfcr)); - stitch_append_from_remaining_buf(bfcr); + stitch_reset(bfcr); + bfcr->stitch.offset = IN_BYTE_OFFSET(buf_at_from_addr(bfcr)); + stitch_append_from_remaining_buf(bfcr); } -static inline -void read_unsigned_bitfield(struct bt_bfcr *bfcr, const uint8_t *buf, size_t at, - unsigned int field_size, enum ctf_byte_order bo, - uint64_t *v) +static inline void read_unsigned_bitfield(struct bt_bfcr *bfcr, const uint8_t *buf, size_t at, + unsigned int field_size, enum ctf_byte_order bo, + uint64_t *v) { - switch (bo) { - case CTF_BYTE_ORDER_BIG: - bt_bitfield_read_be(buf, uint8_t, at, field_size, v); - break; - case CTF_BYTE_ORDER_LITTLE: - bt_bitfield_read_le(buf, uint8_t, at, field_size, v); - break; - default: - bt_common_abort(); - } - - BT_COMP_LOGT("Read unsigned bit array: cur=%zu, size=%u, " - "bo=%d, val=%" PRIu64, at, field_size, bo, *v); + switch (bo) { + case CTF_BYTE_ORDER_BIG: + bt_bitfield_read_be(buf, uint8_t, at, field_size, v); + break; + case CTF_BYTE_ORDER_LITTLE: + bt_bitfield_read_le(buf, uint8_t, at, field_size, v); + break; + default: + bt_common_abort(); + } + + BT_COMP_LOGT("Read unsigned bit array: cur=%zu, size=%u, " + "bo=%d, val=%" PRIu64, + at, field_size, bo, *v); } -static inline -void read_signed_bitfield(struct bt_bfcr *bfcr, const uint8_t *buf, size_t at, - unsigned int field_size, enum ctf_byte_order bo, int64_t *v) +static inline void read_signed_bitfield(struct bt_bfcr *bfcr, const uint8_t *buf, size_t at, + unsigned int field_size, enum ctf_byte_order bo, int64_t *v) { - switch (bo) { - case CTF_BYTE_ORDER_BIG: - bt_bitfield_read_be(buf, uint8_t, at, field_size, v); - break; - case CTF_BYTE_ORDER_LITTLE: - bt_bitfield_read_le(buf, uint8_t, at, field_size, v); - break; - default: - bt_common_abort(); - } - - BT_COMP_LOGT("Read signed bit array: cur=%zu, size=%u, " - "bo=%d, val=%" PRId64, at, field_size, bo, *v); + switch (bo) { + case CTF_BYTE_ORDER_BIG: + bt_bitfield_read_be(buf, uint8_t, at, field_size, v); + break; + case CTF_BYTE_ORDER_LITTLE: + bt_bitfield_read_le(buf, uint8_t, at, field_size, v); + break; + default: + bt_common_abort(); + } + + BT_COMP_LOGT("Read signed bit array: cur=%zu, size=%u, " + "bo=%d, val=%" PRId64, + at, field_size, bo, *v); } -typedef enum bt_bfcr_status (* read_basic_and_call_cb_t)(struct bt_bfcr *, - const uint8_t *, size_t); +typedef enum bt_bfcr_status (*read_basic_and_call_cb_t)(struct bt_bfcr *, const uint8_t *, size_t); -static inline -enum bt_bfcr_status validate_contiguous_bo(struct bt_bfcr *bfcr, - enum ctf_byte_order next_bo) +static inline enum bt_bfcr_status validate_contiguous_bo(struct bt_bfcr *bfcr, + enum ctf_byte_order next_bo) { - enum bt_bfcr_status status = BT_BFCR_STATUS_OK; - - /* Always valid when at a byte boundary */ - if (packet_at(bfcr) % 8 == 0) { - goto end; - } - - /* Always valid if last byte order is unknown */ - if (bfcr->last_bo == CTF_BYTE_ORDER_UNKNOWN) { - goto end; - } - - /* Always valid if next byte order is unknown */ - if (next_bo == CTF_BYTE_ORDER_UNKNOWN) { - goto end; - } - - /* Make sure last byte order is compatible with the next byte order */ - switch (bfcr->last_bo) { - case CTF_BYTE_ORDER_BIG: - if (next_bo != CTF_BYTE_ORDER_BIG) { - status = BT_BFCR_STATUS_ERROR; - } - break; - case CTF_BYTE_ORDER_LITTLE: - if (next_bo != CTF_BYTE_ORDER_LITTLE) { - status = BT_BFCR_STATUS_ERROR; - } - break; - default: - status = BT_BFCR_STATUS_ERROR; - } + enum bt_bfcr_status status = BT_BFCR_STATUS_OK; + + /* Always valid when at a byte boundary */ + if (packet_at(bfcr) % 8 == 0) { + goto end; + } + + /* Always valid if last byte order is unknown */ + if (bfcr->last_bo == CTF_BYTE_ORDER_UNKNOWN) { + goto end; + } + + /* Always valid if next byte order is unknown */ + if (next_bo == CTF_BYTE_ORDER_UNKNOWN) { + goto end; + } + + /* Make sure last byte order is compatible with the next byte order */ + switch (bfcr->last_bo) { + case CTF_BYTE_ORDER_BIG: + if (next_bo != CTF_BYTE_ORDER_BIG) { + status = BT_BFCR_STATUS_ERROR; + } + break; + case CTF_BYTE_ORDER_LITTLE: + if (next_bo != CTF_BYTE_ORDER_LITTLE) { + status = BT_BFCR_STATUS_ERROR; + } + break; + default: + status = BT_BFCR_STATUS_ERROR; + } end: - if (status < 0) { - BT_COMP_LOGW("Cannot read bit array: two different byte orders not at a byte boundary: " - "bfcr-addr=%p, last-bo=%d, next-bo=%d", - bfcr, bfcr->last_bo, next_bo); - } + if (status < 0) { + BT_COMP_LOGW("Cannot read bit array: two different byte orders not at a byte boundary: " + "bfcr-addr=%p, last-bo=%d, next-bo=%d", + bfcr, bfcr->last_bo, next_bo); + } - return status; + return status; } -static -enum bt_bfcr_status read_basic_float_and_call_cb(struct bt_bfcr *bfcr, - const uint8_t *buf, size_t at) +static enum bt_bfcr_status read_basic_float_and_call_cb(struct bt_bfcr *bfcr, const uint8_t *buf, + size_t at) { - double dblval; - unsigned int field_size; - enum ctf_byte_order bo; - enum bt_bfcr_status status = BT_BFCR_STATUS_OK; - ctf_field_class_float *fc = ctf_field_class_as_float(bfcr->cur_basic_field_class); - - BT_ASSERT_DBG(fc); - field_size = fc->base.size; - bo = fc->base.byte_order; - bfcr->cur_bo = bo; - - switch (field_size) { - case 32: - { - uint64_t v; - union { - uint32_t u; - float f; - } f32; - - read_unsigned_bitfield(bfcr, buf, at, field_size, bo, &v); - f32.u = (uint32_t) v; - dblval = (double) f32.f; - break; - } - case 64: - { - union { - uint64_t u; - double d; - } f64; - - read_unsigned_bitfield(bfcr, buf, at, field_size, bo, &f64.u); - dblval = f64.d; - break; - } - default: - /* Only 32-bit and 64-bit fields are supported currently */ - bt_common_abort(); - } - - BT_COMP_LOGT("Read floating point number value: bfcr=%p, cur=%zu, val=%f", - bfcr, at, dblval); - - if (bfcr->user.cbs.classes.floating_point) { - BT_COMP_LOGT("Calling user function (floating point number)."); - status = bfcr->user.cbs.classes.floating_point(dblval, - bfcr->cur_basic_field_class, bfcr->user.data); - BT_COMP_LOGT("User function returned: status=%s", - bt_bfcr_status_string(status)); - if (status != BT_BFCR_STATUS_OK) { - BT_COMP_LOGW("User function failed: bfcr-addr=%p, status=%s", - bfcr, bt_bfcr_status_string(status)); - } - } - - return status; + double dblval; + unsigned int field_size; + enum ctf_byte_order bo; + enum bt_bfcr_status status = BT_BFCR_STATUS_OK; + ctf_field_class_float *fc = ctf_field_class_as_float(bfcr->cur_basic_field_class); + + BT_ASSERT_DBG(fc); + field_size = fc->base.size; + bo = fc->base.byte_order; + bfcr->cur_bo = bo; + + switch (field_size) { + case 32: + { + uint64_t v; + union + { + uint32_t u; + float f; + } f32; + + read_unsigned_bitfield(bfcr, buf, at, field_size, bo, &v); + f32.u = (uint32_t) v; + dblval = (double) f32.f; + break; + } + case 64: + { + union + { + uint64_t u; + double d; + } f64; + + read_unsigned_bitfield(bfcr, buf, at, field_size, bo, &f64.u); + dblval = f64.d; + break; + } + default: + /* Only 32-bit and 64-bit fields are supported currently */ + bt_common_abort(); + } + + BT_COMP_LOGT("Read floating point number value: bfcr=%p, cur=%zu, val=%f", bfcr, at, dblval); + + if (bfcr->user.cbs.classes.floating_point) { + BT_COMP_LOGT("Calling user function (floating point number)."); + status = bfcr->user.cbs.classes.floating_point(dblval, bfcr->cur_basic_field_class, + bfcr->user.data); + BT_COMP_LOGT("User function returned: status=%s", bt_bfcr_status_string(status)); + if (status != BT_BFCR_STATUS_OK) { + BT_COMP_LOGW("User function failed: bfcr-addr=%p, status=%s", bfcr, + bt_bfcr_status_string(status)); + } + } + + return status; } -static inline -enum bt_bfcr_status read_basic_int_and_call_cb(struct bt_bfcr *bfcr, - const uint8_t *buf, size_t at) +static inline enum bt_bfcr_status read_basic_int_and_call_cb(struct bt_bfcr *bfcr, + const uint8_t *buf, size_t at) { - unsigned int field_size; - enum ctf_byte_order bo; - enum bt_bfcr_status status = BT_BFCR_STATUS_OK; - ctf_field_class_int *fc = ctf_field_class_as_int(bfcr->cur_basic_field_class); - - field_size = fc->base.size; - bo = fc->base.byte_order; - - /* - * Update current byte order now because we could be reading - * the integer value of an enumeration class, and thus we know - * here the actual supporting integer class's byte order. - */ - bfcr->cur_bo = bo; - - if (fc->is_signed) { - int64_t v; - - read_signed_bitfield(bfcr, buf, at, field_size, bo, &v); - - if (bfcr->user.cbs.classes.signed_int) { - BT_COMP_LOGT("Calling user function (signed integer)."); - status = bfcr->user.cbs.classes.signed_int(v, - bfcr->cur_basic_field_class, bfcr->user.data); - BT_COMP_LOGT("User function returned: status=%s", - bt_bfcr_status_string(status)); - if (status != BT_BFCR_STATUS_OK) { - BT_COMP_LOGW("User function failed: " - "bfcr-addr=%p, status=%s", - bfcr, bt_bfcr_status_string(status)); - } - } - } else { - uint64_t v; - - read_unsigned_bitfield(bfcr, buf, at, field_size, bo, &v); - - if (bfcr->user.cbs.classes.unsigned_int) { - BT_COMP_LOGT("Calling user function (unsigned integer)."); - status = bfcr->user.cbs.classes.unsigned_int(v, - bfcr->cur_basic_field_class, bfcr->user.data); - BT_COMP_LOGT("User function returned: status=%s", - bt_bfcr_status_string(status)); - if (status != BT_BFCR_STATUS_OK) { - BT_COMP_LOGW("User function failed: " - "bfcr-addr=%p, status=%s", - bfcr, bt_bfcr_status_string(status)); - } - } - } - - return status; + unsigned int field_size; + enum ctf_byte_order bo; + enum bt_bfcr_status status = BT_BFCR_STATUS_OK; + ctf_field_class_int *fc = ctf_field_class_as_int(bfcr->cur_basic_field_class); + + field_size = fc->base.size; + bo = fc->base.byte_order; + + /* + * Update current byte order now because we could be reading + * the integer value of an enumeration class, and thus we know + * here the actual supporting integer class's byte order. + */ + bfcr->cur_bo = bo; + + if (fc->is_signed) { + int64_t v; + + read_signed_bitfield(bfcr, buf, at, field_size, bo, &v); + + if (bfcr->user.cbs.classes.signed_int) { + BT_COMP_LOGT("Calling user function (signed integer)."); + status = + bfcr->user.cbs.classes.signed_int(v, bfcr->cur_basic_field_class, bfcr->user.data); + BT_COMP_LOGT("User function returned: status=%s", bt_bfcr_status_string(status)); + if (status != BT_BFCR_STATUS_OK) { + BT_COMP_LOGW("User function failed: " + "bfcr-addr=%p, status=%s", + bfcr, bt_bfcr_status_string(status)); + } + } + } else { + uint64_t v; + + read_unsigned_bitfield(bfcr, buf, at, field_size, bo, &v); + + if (bfcr->user.cbs.classes.unsigned_int) { + BT_COMP_LOGT("Calling user function (unsigned integer)."); + status = bfcr->user.cbs.classes.unsigned_int(v, bfcr->cur_basic_field_class, + bfcr->user.data); + BT_COMP_LOGT("User function returned: status=%s", bt_bfcr_status_string(status)); + if (status != BT_BFCR_STATUS_OK) { + BT_COMP_LOGW("User function failed: " + "bfcr-addr=%p, status=%s", + bfcr, bt_bfcr_status_string(status)); + } + } + } + + return status; } -static inline -enum bt_bfcr_status read_bit_array_class_and_call_continue(struct bt_bfcr *bfcr, - read_basic_and_call_cb_t read_basic_and_call_cb) +static inline enum bt_bfcr_status +read_bit_array_class_and_call_continue(struct bt_bfcr *bfcr, + read_basic_and_call_cb_t read_basic_and_call_cb) { - size_t available; - size_t needed_bits; - enum bt_bfcr_status status = BT_BFCR_STATUS_OK; - ctf_field_class_bit_array *fc = ctf_field_class_as_bit_array(bfcr->cur_basic_field_class); - - if (!at_least_one_bit_left(bfcr)) { - BT_COMP_LOGT("Reached end of data: bfcr-addr=%p", bfcr); - status = BT_BFCR_STATUS_EOF; - goto end; - } - - available = available_bits(bfcr); - needed_bits = fc->size - bfcr->stitch.at; - BT_COMP_LOGT("Continuing basic field decoding: " - "bfcr-addr=%p, field-size=%u, needed-size=%zu, " - "available-size=%zu", - bfcr, fc->size, needed_bits, available); - if (needed_bits <= available) { - /* We have all the bits; append to stitch, then decode */ - stitch_append_from_buf(bfcr, needed_bits); - status = read_basic_and_call_cb(bfcr, bfcr->stitch.buf, - bfcr->stitch.offset); - if (status != BT_BFCR_STATUS_OK) { - BT_COMP_LOGW("Cannot read basic field: " - "bfcr-addr=%p, fc-addr=%p, status=%s", - bfcr, bfcr->cur_basic_field_class, - bt_bfcr_status_string(status)); - goto end; - } - - if (stack_empty(bfcr->stack)) { - /* Root is a basic class */ - bfcr->state = BFCR_STATE_DONE; - } else { - /* Go to next field */ - stack_top(bfcr->stack)->index++; - bfcr->state = BFCR_STATE_NEXT_FIELD; - bfcr->last_bo = bfcr->cur_bo; - } - goto end; - } - - /* We are here; it means we don't have enough data to decode this */ - BT_COMP_LOGT_STR("Not enough data to read the next basic field: appending to stitch buffer."); - stitch_append_from_remaining_buf(bfcr); - status = BT_BFCR_STATUS_EOF; + size_t available; + size_t needed_bits; + enum bt_bfcr_status status = BT_BFCR_STATUS_OK; + ctf_field_class_bit_array *fc = ctf_field_class_as_bit_array(bfcr->cur_basic_field_class); + + if (!at_least_one_bit_left(bfcr)) { + BT_COMP_LOGT("Reached end of data: bfcr-addr=%p", bfcr); + status = BT_BFCR_STATUS_EOF; + goto end; + } + + available = available_bits(bfcr); + needed_bits = fc->size - bfcr->stitch.at; + BT_COMP_LOGT("Continuing basic field decoding: " + "bfcr-addr=%p, field-size=%u, needed-size=%zu, " + "available-size=%zu", + bfcr, fc->size, needed_bits, available); + if (needed_bits <= available) { + /* We have all the bits; append to stitch, then decode */ + stitch_append_from_buf(bfcr, needed_bits); + status = read_basic_and_call_cb(bfcr, bfcr->stitch.buf, bfcr->stitch.offset); + if (status != BT_BFCR_STATUS_OK) { + BT_COMP_LOGW("Cannot read basic field: " + "bfcr-addr=%p, fc-addr=%p, status=%s", + bfcr, bfcr->cur_basic_field_class, bt_bfcr_status_string(status)); + goto end; + } + + if (stack_empty(bfcr->stack)) { + /* Root is a basic class */ + bfcr->state = BFCR_STATE_DONE; + } else { + /* Go to next field */ + stack_top(bfcr->stack)->index++; + bfcr->state = BFCR_STATE_NEXT_FIELD; + bfcr->last_bo = bfcr->cur_bo; + } + goto end; + } + + /* We are here; it means we don't have enough data to decode this */ + BT_COMP_LOGT_STR("Not enough data to read the next basic field: appending to stitch buffer."); + stitch_append_from_remaining_buf(bfcr); + status = BT_BFCR_STATUS_EOF; end: - return status; + return status; } -static inline -enum bt_bfcr_status read_bit_array_class_and_call_begin(struct bt_bfcr *bfcr, - read_basic_and_call_cb_t read_basic_and_call_cb) +static inline enum bt_bfcr_status +read_bit_array_class_and_call_begin(struct bt_bfcr *bfcr, + read_basic_and_call_cb_t read_basic_and_call_cb) { - size_t available; - enum bt_bfcr_status status = BT_BFCR_STATUS_OK; - ctf_field_class_bit_array *fc = ctf_field_class_as_bit_array(bfcr->cur_basic_field_class); - - if (!at_least_one_bit_left(bfcr)) { - BT_COMP_LOGT("Reached end of data: bfcr-addr=%p", bfcr); - status = BT_BFCR_STATUS_EOF; - goto end; - } - - status = validate_contiguous_bo(bfcr, fc->byte_order); - if (status != BT_BFCR_STATUS_OK) { - /* validate_contiguous_bo() logs errors */ - goto end; - } - - available = available_bits(bfcr); - - if (fc->size <= available) { - /* We have all the bits; decode and set now */ - BT_ASSERT_DBG(bfcr->buf.addr); - status = read_basic_and_call_cb(bfcr, bfcr->buf.addr, - buf_at_from_addr(bfcr)); - if (status != BT_BFCR_STATUS_OK) { - BT_COMP_LOGW("Cannot read basic field: " - "bfcr-addr=%p, fc-addr=%p, status=%s", - bfcr, bfcr->cur_basic_field_class, - bt_bfcr_status_string(status)); - goto end; - } - - consume_bits(bfcr, fc->size); - - if (stack_empty(bfcr->stack)) { - /* Root is a basic class */ - bfcr->state = BFCR_STATE_DONE; - } else { - /* Go to next field */ - stack_top(bfcr->stack)->index++; - bfcr->state = BFCR_STATE_NEXT_FIELD; - bfcr->last_bo = bfcr->cur_bo; - } - - goto end; - } - - /* We are here; it means we don't have enough data to decode this */ - BT_COMP_LOGT_STR("Not enough data to read the next basic field: setting stitch buffer."); - stitch_set_from_remaining_buf(bfcr); - bfcr->state = BFCR_STATE_READ_BASIC_CONTINUE; - status = BT_BFCR_STATUS_EOF; + size_t available; + enum bt_bfcr_status status = BT_BFCR_STATUS_OK; + ctf_field_class_bit_array *fc = ctf_field_class_as_bit_array(bfcr->cur_basic_field_class); + + if (!at_least_one_bit_left(bfcr)) { + BT_COMP_LOGT("Reached end of data: bfcr-addr=%p", bfcr); + status = BT_BFCR_STATUS_EOF; + goto end; + } + + status = validate_contiguous_bo(bfcr, fc->byte_order); + if (status != BT_BFCR_STATUS_OK) { + /* validate_contiguous_bo() logs errors */ + goto end; + } + + available = available_bits(bfcr); + + if (fc->size <= available) { + /* We have all the bits; decode and set now */ + BT_ASSERT_DBG(bfcr->buf.addr); + status = read_basic_and_call_cb(bfcr, bfcr->buf.addr, buf_at_from_addr(bfcr)); + if (status != BT_BFCR_STATUS_OK) { + BT_COMP_LOGW("Cannot read basic field: " + "bfcr-addr=%p, fc-addr=%p, status=%s", + bfcr, bfcr->cur_basic_field_class, bt_bfcr_status_string(status)); + goto end; + } + + consume_bits(bfcr, fc->size); + + if (stack_empty(bfcr->stack)) { + /* Root is a basic class */ + bfcr->state = BFCR_STATE_DONE; + } else { + /* Go to next field */ + stack_top(bfcr->stack)->index++; + bfcr->state = BFCR_STATE_NEXT_FIELD; + bfcr->last_bo = bfcr->cur_bo; + } + + goto end; + } + + /* We are here; it means we don't have enough data to decode this */ + BT_COMP_LOGT_STR("Not enough data to read the next basic field: setting stitch buffer."); + stitch_set_from_remaining_buf(bfcr); + bfcr->state = BFCR_STATE_READ_BASIC_CONTINUE; + status = BT_BFCR_STATUS_EOF; end: - return status; + return status; } -static inline -enum bt_bfcr_status read_basic_int_class_and_call_begin( - struct bt_bfcr *bfcr) +static inline enum bt_bfcr_status read_basic_int_class_and_call_begin(struct bt_bfcr *bfcr) { - return read_bit_array_class_and_call_begin(bfcr, read_basic_int_and_call_cb); + return read_bit_array_class_and_call_begin(bfcr, read_basic_int_and_call_cb); } -static inline -enum bt_bfcr_status read_basic_int_class_and_call_continue( - struct bt_bfcr *bfcr) +static inline enum bt_bfcr_status read_basic_int_class_and_call_continue(struct bt_bfcr *bfcr) { - return read_bit_array_class_and_call_continue(bfcr, - read_basic_int_and_call_cb); + return read_bit_array_class_and_call_continue(bfcr, read_basic_int_and_call_cb); } -static inline -enum bt_bfcr_status read_basic_float_class_and_call_begin( - struct bt_bfcr *bfcr) +static inline enum bt_bfcr_status read_basic_float_class_and_call_begin(struct bt_bfcr *bfcr) { - return read_bit_array_class_and_call_begin(bfcr, - read_basic_float_and_call_cb); + return read_bit_array_class_and_call_begin(bfcr, read_basic_float_and_call_cb); } -static inline -enum bt_bfcr_status read_basic_float_class_and_call_continue( - struct bt_bfcr *bfcr) +static inline enum bt_bfcr_status read_basic_float_class_and_call_continue(struct bt_bfcr *bfcr) { - return read_bit_array_class_and_call_continue(bfcr, - read_basic_float_and_call_cb); + return read_bit_array_class_and_call_continue(bfcr, read_basic_float_and_call_cb); } -static inline -enum bt_bfcr_status read_basic_string_class_and_call( - struct bt_bfcr *bfcr, bool begin) +static inline enum bt_bfcr_status read_basic_string_class_and_call(struct bt_bfcr *bfcr, bool begin) { - size_t buf_at_bytes; - const uint8_t *result; - size_t available_bytes; - const uint8_t *first_chr; - enum bt_bfcr_status status = BT_BFCR_STATUS_OK; - - if (!at_least_one_bit_left(bfcr)) { - BT_COMP_LOGT("Reached end of data: bfcr-addr=%p", bfcr); - status = BT_BFCR_STATUS_EOF; - goto end; - } - - BT_ASSERT_DBG(buf_at_from_addr(bfcr) % 8 == 0); - available_bytes = BITS_TO_BYTES_FLOOR(available_bits(bfcr)); - buf_at_bytes = BITS_TO_BYTES_FLOOR(buf_at_from_addr(bfcr)); - BT_ASSERT_DBG(bfcr->buf.addr); - first_chr = &bfcr->buf.addr[buf_at_bytes]; - result = (const uint8_t *) memchr(first_chr, '\0', available_bytes); - - if (begin && bfcr->user.cbs.classes.string_begin) { - BT_COMP_LOGT("Calling user function (string, beginning)."); - status = bfcr->user.cbs.classes.string_begin( - bfcr->cur_basic_field_class, bfcr->user.data); - BT_COMP_LOGT("User function returned: status=%s", - bt_bfcr_status_string(status)); - if (status != BT_BFCR_STATUS_OK) { - BT_COMP_LOGW("User function failed: bfcr-addr=%p, status=%s", - bfcr, bt_bfcr_status_string(status)); - goto end; - } - } - - if (!result) { - /* No null character yet */ - if (bfcr->user.cbs.classes.string) { - BT_COMP_LOGT("Calling user function (substring)."); - status = bfcr->user.cbs.classes.string( - (const char *) first_chr, - available_bytes, bfcr->cur_basic_field_class, - bfcr->user.data); - BT_COMP_LOGT("User function returned: status=%s", - bt_bfcr_status_string(status)); - if (status != BT_BFCR_STATUS_OK) { - BT_COMP_LOGW("User function failed: " - "bfcr-addr=%p, status=%s", - bfcr, bt_bfcr_status_string(status)); - goto end; - } - } - - consume_bits(bfcr, BYTES_TO_BITS(available_bytes)); - bfcr->state = BFCR_STATE_READ_BASIC_CONTINUE; - status = BT_BFCR_STATUS_EOF; - } else { - /* Found the null character */ - size_t result_len = (size_t) (result - first_chr); - - if (bfcr->user.cbs.classes.string && result_len) { - BT_COMP_LOGT("Calling user function (substring)."); - status = bfcr->user.cbs.classes.string( - (const char *) first_chr, - result_len, bfcr->cur_basic_field_class, - bfcr->user.data); - BT_COMP_LOGT("User function returned: status=%s", - bt_bfcr_status_string(status)); - if (status != BT_BFCR_STATUS_OK) { - BT_COMP_LOGW("User function failed: " - "bfcr-addr=%p, status=%s", - bfcr, bt_bfcr_status_string(status)); - goto end; - } - } - - if (bfcr->user.cbs.classes.string_end) { - BT_COMP_LOGT("Calling user function (string, end)."); - status = bfcr->user.cbs.classes.string_end( - bfcr->cur_basic_field_class, bfcr->user.data); - BT_COMP_LOGT("User function returned: status=%s", - bt_bfcr_status_string(status)); - if (status != BT_BFCR_STATUS_OK) { - BT_COMP_LOGW("User function failed: " - "bfcr-addr=%p, status=%s", - bfcr, bt_bfcr_status_string(status)); - goto end; - } - } - - consume_bits(bfcr, BYTES_TO_BITS(result_len + 1)); - - if (stack_empty(bfcr->stack)) { - /* Root is a basic class */ - bfcr->state = BFCR_STATE_DONE; - } else { - /* Go to next field */ - stack_top(bfcr->stack)->index++; - bfcr->state = BFCR_STATE_NEXT_FIELD; - bfcr->last_bo = bfcr->cur_bo; - } - } + size_t buf_at_bytes; + const uint8_t *result; + size_t available_bytes; + const uint8_t *first_chr; + enum bt_bfcr_status status = BT_BFCR_STATUS_OK; + + if (!at_least_one_bit_left(bfcr)) { + BT_COMP_LOGT("Reached end of data: bfcr-addr=%p", bfcr); + status = BT_BFCR_STATUS_EOF; + goto end; + } + + BT_ASSERT_DBG(buf_at_from_addr(bfcr) % 8 == 0); + available_bytes = BITS_TO_BYTES_FLOOR(available_bits(bfcr)); + buf_at_bytes = BITS_TO_BYTES_FLOOR(buf_at_from_addr(bfcr)); + BT_ASSERT_DBG(bfcr->buf.addr); + first_chr = &bfcr->buf.addr[buf_at_bytes]; + result = (const uint8_t *) memchr(first_chr, '\0', available_bytes); + + if (begin && bfcr->user.cbs.classes.string_begin) { + BT_COMP_LOGT("Calling user function (string, beginning)."); + status = bfcr->user.cbs.classes.string_begin(bfcr->cur_basic_field_class, bfcr->user.data); + BT_COMP_LOGT("User function returned: status=%s", bt_bfcr_status_string(status)); + if (status != BT_BFCR_STATUS_OK) { + BT_COMP_LOGW("User function failed: bfcr-addr=%p, status=%s", bfcr, + bt_bfcr_status_string(status)); + goto end; + } + } + + if (!result) { + /* No null character yet */ + if (bfcr->user.cbs.classes.string) { + BT_COMP_LOGT("Calling user function (substring)."); + status = bfcr->user.cbs.classes.string((const char *) first_chr, available_bytes, + bfcr->cur_basic_field_class, bfcr->user.data); + BT_COMP_LOGT("User function returned: status=%s", bt_bfcr_status_string(status)); + if (status != BT_BFCR_STATUS_OK) { + BT_COMP_LOGW("User function failed: " + "bfcr-addr=%p, status=%s", + bfcr, bt_bfcr_status_string(status)); + goto end; + } + } + + consume_bits(bfcr, BYTES_TO_BITS(available_bytes)); + bfcr->state = BFCR_STATE_READ_BASIC_CONTINUE; + status = BT_BFCR_STATUS_EOF; + } else { + /* Found the null character */ + size_t result_len = (size_t) (result - first_chr); + + if (bfcr->user.cbs.classes.string && result_len) { + BT_COMP_LOGT("Calling user function (substring)."); + status = bfcr->user.cbs.classes.string((const char *) first_chr, result_len, + bfcr->cur_basic_field_class, bfcr->user.data); + BT_COMP_LOGT("User function returned: status=%s", bt_bfcr_status_string(status)); + if (status != BT_BFCR_STATUS_OK) { + BT_COMP_LOGW("User function failed: " + "bfcr-addr=%p, status=%s", + bfcr, bt_bfcr_status_string(status)); + goto end; + } + } + + if (bfcr->user.cbs.classes.string_end) { + BT_COMP_LOGT("Calling user function (string, end)."); + status = + bfcr->user.cbs.classes.string_end(bfcr->cur_basic_field_class, bfcr->user.data); + BT_COMP_LOGT("User function returned: status=%s", bt_bfcr_status_string(status)); + if (status != BT_BFCR_STATUS_OK) { + BT_COMP_LOGW("User function failed: " + "bfcr-addr=%p, status=%s", + bfcr, bt_bfcr_status_string(status)); + goto end; + } + } + + consume_bits(bfcr, BYTES_TO_BITS(result_len + 1)); + + if (stack_empty(bfcr->stack)) { + /* Root is a basic class */ + bfcr->state = BFCR_STATE_DONE; + } else { + /* Go to next field */ + stack_top(bfcr->stack)->index++; + bfcr->state = BFCR_STATE_NEXT_FIELD; + bfcr->last_bo = bfcr->cur_bo; + } + } end: - return status; + return status; } -static inline -enum bt_bfcr_status read_basic_begin_state(struct bt_bfcr *bfcr) +static inline enum bt_bfcr_status read_basic_begin_state(struct bt_bfcr *bfcr) { - enum bt_bfcr_status status; - - BT_ASSERT_DBG(bfcr->cur_basic_field_class); - - switch (bfcr->cur_basic_field_class->type) { - case CTF_FIELD_CLASS_TYPE_INT: - case CTF_FIELD_CLASS_TYPE_ENUM: - status = read_basic_int_class_and_call_begin(bfcr); - break; - case CTF_FIELD_CLASS_TYPE_FLOAT: - status = read_basic_float_class_and_call_begin(bfcr); - break; - case CTF_FIELD_CLASS_TYPE_STRING: - status = read_basic_string_class_and_call(bfcr, true); - break; - default: - bt_common_abort(); - } - - return status; + enum bt_bfcr_status status; + + BT_ASSERT_DBG(bfcr->cur_basic_field_class); + + switch (bfcr->cur_basic_field_class->type) { + case CTF_FIELD_CLASS_TYPE_INT: + case CTF_FIELD_CLASS_TYPE_ENUM: + status = read_basic_int_class_and_call_begin(bfcr); + break; + case CTF_FIELD_CLASS_TYPE_FLOAT: + status = read_basic_float_class_and_call_begin(bfcr); + break; + case CTF_FIELD_CLASS_TYPE_STRING: + status = read_basic_string_class_and_call(bfcr, true); + break; + default: + bt_common_abort(); + } + + return status; } -static inline -enum bt_bfcr_status read_basic_continue_state(struct bt_bfcr *bfcr) +static inline enum bt_bfcr_status read_basic_continue_state(struct bt_bfcr *bfcr) { - enum bt_bfcr_status status; - - BT_ASSERT_DBG(bfcr->cur_basic_field_class); - - switch (bfcr->cur_basic_field_class->type) { - case CTF_FIELD_CLASS_TYPE_INT: - case CTF_FIELD_CLASS_TYPE_ENUM: - status = read_basic_int_class_and_call_continue(bfcr); - break; - case CTF_FIELD_CLASS_TYPE_FLOAT: - status = read_basic_float_class_and_call_continue(bfcr); - break; - case CTF_FIELD_CLASS_TYPE_STRING: - status = read_basic_string_class_and_call(bfcr, false); - break; - default: - bt_common_abort(); - } - - return status; + enum bt_bfcr_status status; + + BT_ASSERT_DBG(bfcr->cur_basic_field_class); + + switch (bfcr->cur_basic_field_class->type) { + case CTF_FIELD_CLASS_TYPE_INT: + case CTF_FIELD_CLASS_TYPE_ENUM: + status = read_basic_int_class_and_call_continue(bfcr); + break; + case CTF_FIELD_CLASS_TYPE_FLOAT: + status = read_basic_float_class_and_call_continue(bfcr); + break; + case CTF_FIELD_CLASS_TYPE_STRING: + status = read_basic_string_class_and_call(bfcr, false); + break; + default: + bt_common_abort(); + } + + return status; } -static inline -size_t bits_to_skip_to_align_to(struct bt_bfcr *bfcr, size_t align) +static inline size_t bits_to_skip_to_align_to(struct bt_bfcr *bfcr, size_t align) { - size_t aligned_packet_at; + size_t aligned_packet_at; - aligned_packet_at = BT_ALIGN(packet_at(bfcr), align); - return aligned_packet_at - packet_at(bfcr); + aligned_packet_at = BT_ALIGN(packet_at(bfcr), align); + return aligned_packet_at - packet_at(bfcr); } -static inline -enum bt_bfcr_status align_class_state(struct bt_bfcr *bfcr, - struct ctf_field_class *field_class, enum bfcr_state next_state) +static inline enum bt_bfcr_status align_class_state(struct bt_bfcr *bfcr, + struct ctf_field_class *field_class, + enum bfcr_state next_state) { - unsigned int field_alignment; - size_t skip_bits; - enum bt_bfcr_status status = BT_BFCR_STATUS_OK; - - /* Get field's alignment */ - field_alignment = field_class->alignment; - - /* - * 0 means "undefined" for variants; what we really want is 1 - * (always aligned) - */ - BT_ASSERT_DBG(field_alignment >= 1); - - /* Compute how many bits we need to skip */ - skip_bits = bits_to_skip_to_align_to(bfcr, (size_t) field_alignment); - - /* Nothing to skip? aligned */ - if (skip_bits == 0) { - bfcr->state = next_state; - goto end; - } - - /* Make sure there's at least one bit left */ - if (!at_least_one_bit_left(bfcr)) { - status = BT_BFCR_STATUS_EOF; - goto end; - } - - /* Consume as many bits as possible in what's left */ - consume_bits(bfcr, MIN(available_bits(bfcr), skip_bits)); - - /* Are we done now? */ - skip_bits = bits_to_skip_to_align_to(bfcr, field_alignment); - if (skip_bits == 0) { - /* Yes: go to next state */ - bfcr->state = next_state; - goto end; - } else { - /* No: need more data */ - BT_COMP_LOGT("Reached end of data when aligning: bfcr-addr=%p", bfcr); - status = BT_BFCR_STATUS_EOF; - } + unsigned int field_alignment; + size_t skip_bits; + enum bt_bfcr_status status = BT_BFCR_STATUS_OK; + + /* Get field's alignment */ + field_alignment = field_class->alignment; + + /* + * 0 means "undefined" for variants; what we really want is 1 + * (always aligned) + */ + BT_ASSERT_DBG(field_alignment >= 1); + + /* Compute how many bits we need to skip */ + skip_bits = bits_to_skip_to_align_to(bfcr, (size_t) field_alignment); + + /* Nothing to skip? aligned */ + if (skip_bits == 0) { + bfcr->state = next_state; + goto end; + } + + /* Make sure there's at least one bit left */ + if (!at_least_one_bit_left(bfcr)) { + status = BT_BFCR_STATUS_EOF; + goto end; + } + + /* Consume as many bits as possible in what's left */ + consume_bits(bfcr, MIN(available_bits(bfcr), skip_bits)); + + /* Are we done now? */ + skip_bits = bits_to_skip_to_align_to(bfcr, field_alignment); + if (skip_bits == 0) { + /* Yes: go to next state */ + bfcr->state = next_state; + goto end; + } else { + /* No: need more data */ + BT_COMP_LOGT("Reached end of data when aligning: bfcr-addr=%p", bfcr); + status = BT_BFCR_STATUS_EOF; + } end: - return status; + return status; } -static inline -enum bt_bfcr_status next_field_state(struct bt_bfcr *bfcr) +static inline enum bt_bfcr_status next_field_state(struct bt_bfcr *bfcr) { - int ret; - struct stack_entry *top; - struct ctf_field_class *next_field_class = NULL; - enum bt_bfcr_status status = BT_BFCR_STATUS_OK; - - if (stack_empty(bfcr->stack)) { - goto end; - } - - top = stack_top(bfcr->stack); - - /* Are we done with this base class? */ - while (top->index == top->base_len) { - if (bfcr->user.cbs.classes.compound_end) { - BT_COMP_LOGT("Calling user function (compound, end)."); - status = bfcr->user.cbs.classes.compound_end( - top->base_class, bfcr->user.data); - BT_COMP_LOGT("User function returned: status=%s", - bt_bfcr_status_string(status)); - if (status != BT_BFCR_STATUS_OK) { - BT_COMP_LOGW("User function failed: bfcr-addr=%p, status=%s", - bfcr, bt_bfcr_status_string(status)); - goto end; - } - } - - stack_pop(bfcr->stack); - - /* Are we done with the root class? */ - if (stack_empty(bfcr->stack)) { - bfcr->state = BFCR_STATE_DONE; - goto end; - } - - top = stack_top(bfcr->stack); - top->index++; - } - - /* Get next field's class */ - switch (top->base_class->type) { - case CTF_FIELD_CLASS_TYPE_STRUCT: - next_field_class = ctf_field_class_struct_borrow_member_by_index( - ctf_field_class_as_struct(top->base_class), (uint64_t) top->index)->fc; - break; - case CTF_FIELD_CLASS_TYPE_ARRAY: - case CTF_FIELD_CLASS_TYPE_SEQUENCE: - { - ctf_field_class_array_base *array_fc = - ctf_field_class_as_array_base(top->base_class); - - next_field_class = array_fc->elem_fc; - break; - } - case CTF_FIELD_CLASS_TYPE_VARIANT: - /* Variant classes are dynamic: the user should know! */ - next_field_class = - bfcr->user.cbs.query.borrow_variant_selected_field_class( - top->base_class, bfcr->user.data); - break; - default: - break; - } - - if (!next_field_class) { - BT_COMP_LOGW("Cannot get the field class of the next field: " - "bfcr-addr=%p, base-fc-addr=%p, base-fc-type=%d, " - "index=%" PRId64, - bfcr, top->base_class, top->base_class->type, - top->index); - status = BT_BFCR_STATUS_ERROR; - goto end; - } - - if (next_field_class->is_compound) { - if (bfcr->user.cbs.classes.compound_begin) { - BT_COMP_LOGT("Calling user function (compound, begin)."); - status = bfcr->user.cbs.classes.compound_begin( - next_field_class, bfcr->user.data); - BT_COMP_LOGT("User function returned: status=%s", - bt_bfcr_status_string(status)); - if (status != BT_BFCR_STATUS_OK) { - BT_COMP_LOGW("User function failed: bfcr-addr=%p, status=%s", - bfcr, bt_bfcr_status_string(status)); - goto end; - } - } - - ret = stack_push_with_len(bfcr, next_field_class); - if (ret) { - /* stack_push_with_len() logs errors */ - status = BT_BFCR_STATUS_ERROR; - goto end; - } - - /* Next state: align a compound class */ - bfcr->state = BFCR_STATE_ALIGN_COMPOUND; - } else { - /* Replace current basic field class */ - BT_COMP_LOGT("Replacing current basic field class: " - "bfcr-addr=%p, cur-basic-fc-addr=%p, " - "next-basic-fc-addr=%p", - bfcr, bfcr->cur_basic_field_class, next_field_class); - bfcr->cur_basic_field_class = next_field_class; - - /* Next state: align a basic class */ - bfcr->state = BFCR_STATE_ALIGN_BASIC; - } + int ret; + struct stack_entry *top; + struct ctf_field_class *next_field_class = NULL; + enum bt_bfcr_status status = BT_BFCR_STATUS_OK; + + if (stack_empty(bfcr->stack)) { + goto end; + } + + top = stack_top(bfcr->stack); + + /* Are we done with this base class? */ + while (top->index == top->base_len) { + if (bfcr->user.cbs.classes.compound_end) { + BT_COMP_LOGT("Calling user function (compound, end)."); + status = bfcr->user.cbs.classes.compound_end(top->base_class, bfcr->user.data); + BT_COMP_LOGT("User function returned: status=%s", bt_bfcr_status_string(status)); + if (status != BT_BFCR_STATUS_OK) { + BT_COMP_LOGW("User function failed: bfcr-addr=%p, status=%s", bfcr, + bt_bfcr_status_string(status)); + goto end; + } + } + + stack_pop(bfcr->stack); + + /* Are we done with the root class? */ + if (stack_empty(bfcr->stack)) { + bfcr->state = BFCR_STATE_DONE; + goto end; + } + + top = stack_top(bfcr->stack); + top->index++; + } + + /* Get next field's class */ + switch (top->base_class->type) { + case CTF_FIELD_CLASS_TYPE_STRUCT: + next_field_class = ctf_field_class_struct_borrow_member_by_index( + ctf_field_class_as_struct(top->base_class), (uint64_t) top->index) + ->fc; + break; + case CTF_FIELD_CLASS_TYPE_ARRAY: + case CTF_FIELD_CLASS_TYPE_SEQUENCE: + { + ctf_field_class_array_base *array_fc = ctf_field_class_as_array_base(top->base_class); + + next_field_class = array_fc->elem_fc; + break; + } + case CTF_FIELD_CLASS_TYPE_VARIANT: + /* Variant classes are dynamic: the user should know! */ + next_field_class = bfcr->user.cbs.query.borrow_variant_selected_field_class( + top->base_class, bfcr->user.data); + break; + default: + break; + } + + if (!next_field_class) { + BT_COMP_LOGW("Cannot get the field class of the next field: " + "bfcr-addr=%p, base-fc-addr=%p, base-fc-type=%d, " + "index=%" PRId64, + bfcr, top->base_class, top->base_class->type, top->index); + status = BT_BFCR_STATUS_ERROR; + goto end; + } + + if (next_field_class->is_compound) { + if (bfcr->user.cbs.classes.compound_begin) { + BT_COMP_LOGT("Calling user function (compound, begin)."); + status = bfcr->user.cbs.classes.compound_begin(next_field_class, bfcr->user.data); + BT_COMP_LOGT("User function returned: status=%s", bt_bfcr_status_string(status)); + if (status != BT_BFCR_STATUS_OK) { + BT_COMP_LOGW("User function failed: bfcr-addr=%p, status=%s", bfcr, + bt_bfcr_status_string(status)); + goto end; + } + } + + ret = stack_push_with_len(bfcr, next_field_class); + if (ret) { + /* stack_push_with_len() logs errors */ + status = BT_BFCR_STATUS_ERROR; + goto end; + } + + /* Next state: align a compound class */ + bfcr->state = BFCR_STATE_ALIGN_COMPOUND; + } else { + /* Replace current basic field class */ + BT_COMP_LOGT("Replacing current basic field class: " + "bfcr-addr=%p, cur-basic-fc-addr=%p, " + "next-basic-fc-addr=%p", + bfcr, bfcr->cur_basic_field_class, next_field_class); + bfcr->cur_basic_field_class = next_field_class; + + /* Next state: align a basic class */ + bfcr->state = BFCR_STATE_ALIGN_BASIC; + } end: - return status; + return status; } -static inline -enum bt_bfcr_status handle_state(struct bt_bfcr *bfcr) +static inline enum bt_bfcr_status handle_state(struct bt_bfcr *bfcr) { - enum bt_bfcr_status status = BT_BFCR_STATUS_OK; - - BT_COMP_LOGT("Handling state: bfcr-addr=%p, state=%s", - bfcr, bfcr_state_string(bfcr->state)); - - switch (bfcr->state) { - case BFCR_STATE_NEXT_FIELD: - status = next_field_state(bfcr); - break; - case BFCR_STATE_ALIGN_BASIC: - status = align_class_state(bfcr, bfcr->cur_basic_field_class, - BFCR_STATE_READ_BASIC_BEGIN); - break; - case BFCR_STATE_ALIGN_COMPOUND: - status = align_class_state(bfcr, stack_top(bfcr->stack)->base_class, - BFCR_STATE_NEXT_FIELD); - break; - case BFCR_STATE_READ_BASIC_BEGIN: - status = read_basic_begin_state(bfcr); - break; - case BFCR_STATE_READ_BASIC_CONTINUE: - status = read_basic_continue_state(bfcr); - break; - case BFCR_STATE_DONE: - break; - } - - BT_COMP_LOGT("Handled state: bfcr-addr=%p, status=%s", - bfcr, bt_bfcr_status_string(status)); - return status; + enum bt_bfcr_status status = BT_BFCR_STATUS_OK; + + BT_COMP_LOGT("Handling state: bfcr-addr=%p, state=%s", bfcr, bfcr_state_string(bfcr->state)); + + switch (bfcr->state) { + case BFCR_STATE_NEXT_FIELD: + status = next_field_state(bfcr); + break; + case BFCR_STATE_ALIGN_BASIC: + status = align_class_state(bfcr, bfcr->cur_basic_field_class, BFCR_STATE_READ_BASIC_BEGIN); + break; + case BFCR_STATE_ALIGN_COMPOUND: + status = align_class_state(bfcr, stack_top(bfcr->stack)->base_class, BFCR_STATE_NEXT_FIELD); + break; + case BFCR_STATE_READ_BASIC_BEGIN: + status = read_basic_begin_state(bfcr); + break; + case BFCR_STATE_READ_BASIC_CONTINUE: + status = read_basic_continue_state(bfcr); + break; + case BFCR_STATE_DONE: + break; + } + + BT_COMP_LOGT("Handled state: bfcr-addr=%p, status=%s", bfcr, bt_bfcr_status_string(status)); + return status; } BT_HIDDEN -struct bt_bfcr *bt_bfcr_create(struct bt_bfcr_cbs cbs, void *data, - bt_logging_level log_level, bt_self_component *self_comp) +struct bt_bfcr *bt_bfcr_create(struct bt_bfcr_cbs cbs, void *data, bt_logging_level log_level, + bt_self_component *self_comp) { - struct bt_bfcr *bfcr; - - BT_COMP_LOG_CUR_LVL(BT_LOG_DEBUG, log_level, self_comp, - "Creating binary field class reader (BFCR)."); - bfcr = g_new0(struct bt_bfcr, 1); - if (!bfcr) { - BT_COMP_LOG_CUR_LVL(BT_LOG_ERROR, log_level, self_comp, - "Failed to allocate one binary class reader."); - goto end; - } - - bfcr->log_level = log_level; - bfcr->self_comp = self_comp; - bfcr->stack = stack_new(bfcr); - if (!bfcr->stack) { - BT_COMP_LOGE_STR("Cannot create BFCR's stack."); - bt_bfcr_destroy(bfcr); - bfcr = NULL; - goto end; - } - - bfcr->state = BFCR_STATE_NEXT_FIELD; - bfcr->user.cbs = cbs; - bfcr->user.data = data; - BT_COMP_LOGD("Created BFCR: addr=%p", bfcr); + struct bt_bfcr *bfcr; + + BT_COMP_LOG_CUR_LVL(BT_LOG_DEBUG, log_level, self_comp, + "Creating binary field class reader (BFCR)."); + bfcr = g_new0(struct bt_bfcr, 1); + if (!bfcr) { + BT_COMP_LOG_CUR_LVL(BT_LOG_ERROR, log_level, self_comp, + "Failed to allocate one binary class reader."); + goto end; + } + + bfcr->log_level = log_level; + bfcr->self_comp = self_comp; + bfcr->stack = stack_new(bfcr); + if (!bfcr->stack) { + BT_COMP_LOGE_STR("Cannot create BFCR's stack."); + bt_bfcr_destroy(bfcr); + bfcr = NULL; + goto end; + } + + bfcr->state = BFCR_STATE_NEXT_FIELD; + bfcr->user.cbs = cbs; + bfcr->user.data = data; + BT_COMP_LOGD("Created BFCR: addr=%p", bfcr); end: - return bfcr; + return bfcr; } BT_HIDDEN void bt_bfcr_destroy(struct bt_bfcr *bfcr) { - if (bfcr->stack) { - stack_destroy(bfcr->stack); - } + if (bfcr->stack) { + stack_destroy(bfcr->stack); + } - BT_COMP_LOGD("Destroying BFCR: addr=%p", bfcr); - g_free(bfcr); + BT_COMP_LOGD("Destroying BFCR: addr=%p", bfcr); + g_free(bfcr); } -static -void reset(struct bt_bfcr *bfcr) +static void reset(struct bt_bfcr *bfcr) { - BT_COMP_LOGD("Resetting BFCR: addr=%p", bfcr); - stack_clear(bfcr->stack); - stitch_reset(bfcr); - bfcr->buf.addr = NULL; - bfcr->last_bo = CTF_BYTE_ORDER_UNKNOWN; + BT_COMP_LOGD("Resetting BFCR: addr=%p", bfcr); + stack_clear(bfcr->stack); + stitch_reset(bfcr); + bfcr->buf.addr = NULL; + bfcr->last_bo = CTF_BYTE_ORDER_UNKNOWN; } -static -void update_packet_offset(struct bt_bfcr *bfcr) +static void update_packet_offset(struct bt_bfcr *bfcr) { - BT_COMP_LOGT("Updating packet offset for next call: " - "bfcr-addr=%p, cur-packet-offset=%zu, next-packet-offset=%zu", - bfcr, bfcr->buf.packet_offset, - bfcr->buf.packet_offset + bfcr->buf.at); - bfcr->buf.packet_offset += bfcr->buf.at; + BT_COMP_LOGT("Updating packet offset for next call: " + "bfcr-addr=%p, cur-packet-offset=%zu, next-packet-offset=%zu", + bfcr, bfcr->buf.packet_offset, bfcr->buf.packet_offset + bfcr->buf.at); + bfcr->buf.packet_offset += bfcr->buf.at; } BT_HIDDEN -size_t bt_bfcr_start(struct bt_bfcr *bfcr, - struct ctf_field_class *cls, const uint8_t *buf, - size_t offset, size_t packet_offset, size_t sz, - enum bt_bfcr_status *status) +size_t bt_bfcr_start(struct bt_bfcr *bfcr, struct ctf_field_class *cls, const uint8_t *buf, + size_t offset, size_t packet_offset, size_t sz, enum bt_bfcr_status *status) { - BT_ASSERT_DBG(bfcr); - BT_ASSERT_DBG(BYTES_TO_BITS(sz) >= offset); - reset(bfcr); - bfcr->buf.addr = buf; - bfcr->buf.offset = offset; - bfcr->buf.at = 0; - bfcr->buf.packet_offset = packet_offset; - bfcr->buf.buf_sz = sz; - bfcr->buf.sz = BYTES_TO_BITS(sz) - offset; - *status = BT_BFCR_STATUS_OK; - - BT_COMP_LOGT("Starting decoding: bfcr-addr=%p, fc-addr=%p, " - "buf-addr=%p, buf-size=%zu, offset=%zu, " - "packet-offset=%zu", - bfcr, cls, buf, sz, offset, packet_offset); - - /* Set root class */ - if (cls->is_compound) { - /* Compound class: push on visit stack */ - int stack_ret; - - if (bfcr->user.cbs.classes.compound_begin) { - BT_COMP_LOGT("Calling user function (compound, begin)."); - *status = bfcr->user.cbs.classes.compound_begin( - cls, bfcr->user.data); - BT_COMP_LOGT("User function returned: status=%s", - bt_bfcr_status_string(*status)); - if (*status != BT_BFCR_STATUS_OK) { - BT_COMP_LOGW("User function failed: bfcr-addr=%p, status=%s", - bfcr, bt_bfcr_status_string(*status)); - goto end; - } - } - - stack_ret = stack_push_with_len(bfcr, cls); - if (stack_ret) { - /* stack_push_with_len() logs errors */ - *status = BT_BFCR_STATUS_ERROR; - goto end; - } - - bfcr->state = BFCR_STATE_ALIGN_COMPOUND; - } else { - /* Basic class: set as current basic class */ - bfcr->cur_basic_field_class = cls; - bfcr->state = BFCR_STATE_ALIGN_BASIC; - } - - /* Run the machine! */ - BT_COMP_LOGT_STR("Running the state machine."); - - while (true) { - *status = handle_state(bfcr); - if (*status != BT_BFCR_STATUS_OK || - bfcr->state == BFCR_STATE_DONE) { - break; - } - } - - /* Update packet offset for next time */ - update_packet_offset(bfcr); + BT_ASSERT_DBG(bfcr); + BT_ASSERT_DBG(BYTES_TO_BITS(sz) >= offset); + reset(bfcr); + bfcr->buf.addr = buf; + bfcr->buf.offset = offset; + bfcr->buf.at = 0; + bfcr->buf.packet_offset = packet_offset; + bfcr->buf.buf_sz = sz; + bfcr->buf.sz = BYTES_TO_BITS(sz) - offset; + *status = BT_BFCR_STATUS_OK; + + BT_COMP_LOGT("Starting decoding: bfcr-addr=%p, fc-addr=%p, " + "buf-addr=%p, buf-size=%zu, offset=%zu, " + "packet-offset=%zu", + bfcr, cls, buf, sz, offset, packet_offset); + + /* Set root class */ + if (cls->is_compound) { + /* Compound class: push on visit stack */ + int stack_ret; + + if (bfcr->user.cbs.classes.compound_begin) { + BT_COMP_LOGT("Calling user function (compound, begin)."); + *status = bfcr->user.cbs.classes.compound_begin(cls, bfcr->user.data); + BT_COMP_LOGT("User function returned: status=%s", bt_bfcr_status_string(*status)); + if (*status != BT_BFCR_STATUS_OK) { + BT_COMP_LOGW("User function failed: bfcr-addr=%p, status=%s", bfcr, + bt_bfcr_status_string(*status)); + goto end; + } + } + + stack_ret = stack_push_with_len(bfcr, cls); + if (stack_ret) { + /* stack_push_with_len() logs errors */ + *status = BT_BFCR_STATUS_ERROR; + goto end; + } + + bfcr->state = BFCR_STATE_ALIGN_COMPOUND; + } else { + /* Basic class: set as current basic class */ + bfcr->cur_basic_field_class = cls; + bfcr->state = BFCR_STATE_ALIGN_BASIC; + } + + /* Run the machine! */ + BT_COMP_LOGT_STR("Running the state machine."); + + while (true) { + *status = handle_state(bfcr); + if (*status != BT_BFCR_STATUS_OK || bfcr->state == BFCR_STATE_DONE) { + break; + } + } + + /* Update packet offset for next time */ + update_packet_offset(bfcr); end: - return bfcr->buf.at; + return bfcr->buf.at; } BT_HIDDEN size_t bt_bfcr_continue(struct bt_bfcr *bfcr, const uint8_t *buf, size_t sz, - enum bt_bfcr_status *status) + enum bt_bfcr_status *status) { - BT_ASSERT_DBG(bfcr); - BT_ASSERT_DBG(buf); - BT_ASSERT_DBG(sz > 0); - bfcr->buf.addr = buf; - bfcr->buf.offset = 0; - bfcr->buf.at = 0; - bfcr->buf.buf_sz = sz; - bfcr->buf.sz = BYTES_TO_BITS(sz); - *status = BT_BFCR_STATUS_OK; - - BT_COMP_LOGT("Continuing decoding: bfcr-addr=%p, buf-addr=%p, buf-size=%zu", - bfcr, buf, sz); - - /* Continue running the machine */ - BT_COMP_LOGT_STR("Running the state machine."); - - while (true) { - *status = handle_state(bfcr); - if (*status != BT_BFCR_STATUS_OK || - bfcr->state == BFCR_STATE_DONE) { - break; - } - } - - /* Update packet offset for next time */ - update_packet_offset(bfcr); - return bfcr->buf.at; + BT_ASSERT_DBG(bfcr); + BT_ASSERT_DBG(buf); + BT_ASSERT_DBG(sz > 0); + bfcr->buf.addr = buf; + bfcr->buf.offset = 0; + bfcr->buf.at = 0; + bfcr->buf.buf_sz = sz; + bfcr->buf.sz = BYTES_TO_BITS(sz); + *status = BT_BFCR_STATUS_OK; + + BT_COMP_LOGT("Continuing decoding: bfcr-addr=%p, buf-addr=%p, buf-size=%zu", bfcr, buf, sz); + + /* Continue running the machine */ + BT_COMP_LOGT_STR("Running the state machine."); + + while (true) { + *status = handle_state(bfcr); + if (*status != BT_BFCR_STATUS_OK || bfcr->state == BFCR_STATE_DONE) { + break; + } + } + + /* Update packet offset for next time */ + update_packet_offset(bfcr); + return bfcr->buf.at; } BT_HIDDEN -void bt_bfcr_set_unsigned_int_cb(struct bt_bfcr *bfcr, - bt_bfcr_unsigned_int_cb_func cb) +void bt_bfcr_set_unsigned_int_cb(struct bt_bfcr *bfcr, bt_bfcr_unsigned_int_cb_func cb) { - BT_ASSERT_DBG(bfcr); - BT_ASSERT_DBG(cb); - bfcr->user.cbs.classes.unsigned_int = cb; + BT_ASSERT_DBG(bfcr); + BT_ASSERT_DBG(cb); + bfcr->user.cbs.classes.unsigned_int = cb; } diff --git a/src/plugins/ctf/common/bfcr/bfcr.hpp b/src/plugins/ctf/common/bfcr/bfcr.hpp index e94c05b4..b67d6bd3 100644 --- a/src/plugins/ctf/common/bfcr/bfcr.hpp +++ b/src/plugins/ctf/common/bfcr/bfcr.hpp @@ -37,220 +37,217 @@ /** * Binary class reader API status codes. */ -enum bt_bfcr_status { - /** Out of memory. */ - BT_BFCR_STATUS_ENOMEM = -5, - /** - * The binary stream reader reached the end of the user-provided - * buffer, but data is still needed to finish decoding the - * requested class. - * - * The user needs to call bt_bfcr_continue() as long as - * #BT_BFCR_STATUS_EOF is returned to complete the decoding - * process of a given class. - */ - BT_BFCR_STATUS_EOF = 1, +enum bt_bfcr_status +{ + /** Out of memory. */ + BT_BFCR_STATUS_ENOMEM = -5, + /** + * The binary stream reader reached the end of the user-provided + * buffer, but data is still needed to finish decoding the + * requested class. + * + * The user needs to call bt_bfcr_continue() as long as + * #BT_BFCR_STATUS_EOF is returned to complete the decoding + * process of a given class. + */ + BT_BFCR_STATUS_EOF = 1, - /** Invalid argument. */ - BT_BFCR_STATUS_INVAL = -3, + /** Invalid argument. */ + BT_BFCR_STATUS_INVAL = -3, - /** General error. */ - BT_BFCR_STATUS_ERROR = -1, + /** General error. */ + BT_BFCR_STATUS_ERROR = -1, - /** Everything okay. */ - BT_BFCR_STATUS_OK = 0, + /** Everything okay. */ + BT_BFCR_STATUS_OK = 0, }; /** Field class reader. */ struct bt_bfcr; -typedef enum bt_bfcr_status (* bt_bfcr_unsigned_int_cb_func)(uint64_t, - struct ctf_field_class *, void *); +typedef enum bt_bfcr_status (*bt_bfcr_unsigned_int_cb_func)(uint64_t, struct ctf_field_class *, + void *); /* * Field class reader user callback functions. */ -struct bt_bfcr_cbs { - /** - * Field class callback functions. - * - * This CTF binary class reader is event-driven. The following - * functions are called during the decoding process, either when - * a compound class begins/ends, or when a basic class is - * completely decoded (along with its value). - * - * Each function also receives the CTF field class associated - * with the call, and user data (registered to the class reader - * calling them). - * - * Actual trace IR fields are \em not created here; this would - * be the responsibility of a class reader's user (the provider - * of those callback functions). - * - * All the class callback functions return one of the following - * values: - * - * - #BT_BFCR_STATUS_OK: Everything is okay; - * continue the decoding process. - * - #BT_BFCR_STATUS_ERROR: General error (reported - * to class reader's user). - * - * Any member of this structure may be set to \c NULL, should - * a specific message be not needed. - */ - struct { - /** - * Called when a signed integer class is completely - * decoded. This could also be the supporting signed - * integer class of an enumeration class (\p class will - * indicate this). - * - * @param value Signed integer value - * @param class Integer or enumeration class - * @param data User data - * @returns #BT_BFCR_STATUS_OK or - * #BT_BFCR_STATUS_ERROR - */ - enum bt_bfcr_status (* signed_int)(int64_t value, - struct ctf_field_class *cls, void *data); +struct bt_bfcr_cbs +{ + /** + * Field class callback functions. + * + * This CTF binary class reader is event-driven. The following + * functions are called during the decoding process, either when + * a compound class begins/ends, or when a basic class is + * completely decoded (along with its value). + * + * Each function also receives the CTF field class associated + * with the call, and user data (registered to the class reader + * calling them). + * + * Actual trace IR fields are \em not created here; this would + * be the responsibility of a class reader's user (the provider + * of those callback functions). + * + * All the class callback functions return one of the following + * values: + * + * - #BT_BFCR_STATUS_OK: Everything is okay; + * continue the decoding process. + * - #BT_BFCR_STATUS_ERROR: General error (reported + * to class reader's user). + * + * Any member of this structure may be set to \c NULL, should + * a specific message be not needed. + */ + struct + { + /** + * Called when a signed integer class is completely + * decoded. This could also be the supporting signed + * integer class of an enumeration class (\p class will + * indicate this). + * + * @param value Signed integer value + * @param class Integer or enumeration class + * @param data User data + * @returns #BT_BFCR_STATUS_OK or + * #BT_BFCR_STATUS_ERROR + */ + enum bt_bfcr_status (*signed_int)(int64_t value, struct ctf_field_class *cls, void *data); - /** - * Called when an unsigned integer class is completely - * decoded. This could also be the supporting signed - * integer class of an enumeration class (\p class will - * indicate this). - * - * @param value Unsigned integer value - * @param class Integer or enumeration class - * @param data User data - * @returns #BT_BFCR_STATUS_OK or - * #BT_BFCR_STATUS_ERROR - */ - bt_bfcr_unsigned_int_cb_func unsigned_int; + /** + * Called when an unsigned integer class is completely + * decoded. This could also be the supporting signed + * integer class of an enumeration class (\p class will + * indicate this). + * + * @param value Unsigned integer value + * @param class Integer or enumeration class + * @param data User data + * @returns #BT_BFCR_STATUS_OK or + * #BT_BFCR_STATUS_ERROR + */ + bt_bfcr_unsigned_int_cb_func unsigned_int; - /** - * Called when a floating point number class is - * completely decoded. - * - * @param value Floating point number value - * @param class Floating point number class - * @param data User data - * @returns #BT_BFCR_STATUS_OK or - * #BT_BFCR_STATUS_ERROR - */ - enum bt_bfcr_status (* floating_point)(double value, - struct ctf_field_class *cls, void *data); + /** + * Called when a floating point number class is + * completely decoded. + * + * @param value Floating point number value + * @param class Floating point number class + * @param data User data + * @returns #BT_BFCR_STATUS_OK or + * #BT_BFCR_STATUS_ERROR + */ + enum bt_bfcr_status (*floating_point)(double value, struct ctf_field_class *cls, + void *data); - /** - * Called when a string class begins. - * - * All the following user callback function calls will - * be made to bt_bfcr_cbs::classes::string(), each of - * them providing one substring of the complete string - * class's value. - * - * @param class Beginning string class - * @param data User data - * @returns #BT_BFCR_STATUS_OK or - * #BT_BFCR_STATUS_ERROR - */ - enum bt_bfcr_status (* string_begin)( - struct ctf_field_class *cls, void *data); + /** + * Called when a string class begins. + * + * All the following user callback function calls will + * be made to bt_bfcr_cbs::classes::string(), each of + * them providing one substring of the complete string + * class's value. + * + * @param class Beginning string class + * @param data User data + * @returns #BT_BFCR_STATUS_OK or + * #BT_BFCR_STATUS_ERROR + */ + enum bt_bfcr_status (*string_begin)(struct ctf_field_class *cls, void *data); - /** - * Called when a string class's substring is decoded - * (between a call to bt_bfcr_cbs::classes::string_begin() - * and a call to bt_bfcr_cbs::classes::string_end()). - * - * @param value String value (\em not null-terminated) - * @param len String value length - * @param class String class - * @param data User data - * @returns #BT_BFCR_STATUS_OK or - * #BT_BFCR_STATUS_ERROR - */ - enum bt_bfcr_status (* string)(const char *value, - size_t len, struct ctf_field_class *cls, - void *data); + /** + * Called when a string class's substring is decoded + * (between a call to bt_bfcr_cbs::classes::string_begin() + * and a call to bt_bfcr_cbs::classes::string_end()). + * + * @param value String value (\em not null-terminated) + * @param len String value length + * @param class String class + * @param data User data + * @returns #BT_BFCR_STATUS_OK or + * #BT_BFCR_STATUS_ERROR + */ + enum bt_bfcr_status (*string)(const char *value, size_t len, struct ctf_field_class *cls, + void *data); - /** - * Called when a string class ends. - * - * @param class Ending string class - * @param data User data - * @returns #BT_BFCR_STATUS_OK or - * #BT_BFCR_STATUS_ERROR - */ - enum bt_bfcr_status (* string_end)( - struct ctf_field_class *cls, void *data); + /** + * Called when a string class ends. + * + * @param class Ending string class + * @param data User data + * @returns #BT_BFCR_STATUS_OK or + * #BT_BFCR_STATUS_ERROR + */ + enum bt_bfcr_status (*string_end)(struct ctf_field_class *cls, void *data); - /** - * Called when a compound class begins. - * - * All the following class callback function calls will - * signal sequential elements of this compound class, - * until the next corresponding - * bt_bfcr_cbs::classes::compound_end() is called. - * - * If \p class is a variant class, then only one class - * callback function call will follow before the call to - * bt_bfcr_cbs::classes::compound_end(). This single - * call indicates the selected class of this variant - * class. - * - * @param class Beginning compound class - * @param data User data - * @returns #BT_BFCR_STATUS_OK or - * #BT_BFCR_STATUS_ERROR - */ - enum bt_bfcr_status (* compound_begin)( - struct ctf_field_class *cls, void *data); + /** + * Called when a compound class begins. + * + * All the following class callback function calls will + * signal sequential elements of this compound class, + * until the next corresponding + * bt_bfcr_cbs::classes::compound_end() is called. + * + * If \p class is a variant class, then only one class + * callback function call will follow before the call to + * bt_bfcr_cbs::classes::compound_end(). This single + * call indicates the selected class of this variant + * class. + * + * @param class Beginning compound class + * @param data User data + * @returns #BT_BFCR_STATUS_OK or + * #BT_BFCR_STATUS_ERROR + */ + enum bt_bfcr_status (*compound_begin)(struct ctf_field_class *cls, void *data); - /** - * Called when a compound class ends. - * - * @param class Ending compound class - * @param data User data - * @returns #BT_BFCR_STATUS_OK or - * #BT_BFCR_STATUS_ERROR - */ - enum bt_bfcr_status (* compound_end)( - struct ctf_field_class *cls, void *data); - } classes; + /** + * Called when a compound class ends. + * + * @param class Ending compound class + * @param data User data + * @returns #BT_BFCR_STATUS_OK or + * #BT_BFCR_STATUS_ERROR + */ + enum bt_bfcr_status (*compound_end)(struct ctf_field_class *cls, void *data); + } classes; - /** - * Query callback functions are used when the class reader needs - * dynamic information, i.e. a sequence class's current length - * or a variant class's current selected class. - * - * Both functions need to be set unless it is known that no - * sequences or variants will have to be decoded. - */ - struct { - /** - * Called to query the current length of a given sequence - * class. - * - * @param class Sequence class - * @param data User data - * @returns Sequence length or - * #BT_BFCR_STATUS_ERROR on error - */ - int64_t (* get_sequence_length)(struct ctf_field_class *cls, - void *data); + /** + * Query callback functions are used when the class reader needs + * dynamic information, i.e. a sequence class's current length + * or a variant class's current selected class. + * + * Both functions need to be set unless it is known that no + * sequences or variants will have to be decoded. + */ + struct + { + /** + * Called to query the current length of a given sequence + * class. + * + * @param class Sequence class + * @param data User data + * @returns Sequence length or + * #BT_BFCR_STATUS_ERROR on error + */ + int64_t (*get_sequence_length)(struct ctf_field_class *cls, void *data); - /** - * Called to query the current selected class of a given - * variant class. - * - * @param class Variant class - * @param data User data - * @returns Current selected class (owned by - * this) or \c NULL on error - */ - struct ctf_field_class * (* borrow_variant_selected_field_class)( - struct ctf_field_class *cls, void *data); - } query; + /** + * Called to query the current selected class of a given + * variant class. + * + * @param class Variant class + * @param data User data + * @returns Current selected class (owned by + * this) or \c NULL on error + */ + struct ctf_field_class *(*borrow_variant_selected_field_class)(struct ctf_field_class *cls, + void *data); + } query; }; /** @@ -261,8 +258,8 @@ struct bt_bfcr_cbs { * @returns New binary class reader on success, or \c NULL on error */ BT_HIDDEN -struct bt_bfcr *bt_bfcr_create(struct bt_bfcr_cbs cbs, void *data, - bt_logging_level log_level, bt_self_component *self_comp); +struct bt_bfcr *bt_bfcr_create(struct bt_bfcr_cbs cbs, void *data, bt_logging_level log_level, + bt_self_component *self_comp); /** * Destroys a CTF binary class reader, freeing all internal resources. @@ -304,10 +301,8 @@ void bt_bfcr_destroy(struct bt_bfcr *bfcr); * @returns Number of consumed bits */ BT_HIDDEN -size_t bt_bfcr_start(struct bt_bfcr *bfcr, - struct ctf_field_class *cls, const uint8_t *buf, - size_t offset, size_t packet_offset, size_t sz, - enum bt_bfcr_status *status); +size_t bt_bfcr_start(struct bt_bfcr *bfcr, struct ctf_field_class *cls, const uint8_t *buf, + size_t offset, size_t packet_offset, size_t sz, enum bt_bfcr_status *status); /** * Continues the decoding process a given CTF class. @@ -333,31 +328,28 @@ size_t bt_bfcr_start(struct bt_bfcr *bfcr, * @returns Number of consumed bits */ BT_HIDDEN -size_t bt_bfcr_continue(struct bt_bfcr *bfcr, - const uint8_t *buf, size_t sz, - enum bt_bfcr_status *status); +size_t bt_bfcr_continue(struct bt_bfcr *bfcr, const uint8_t *buf, size_t sz, + enum bt_bfcr_status *status); BT_HIDDEN -void bt_bfcr_set_unsigned_int_cb(struct bt_bfcr *bfcr, - bt_bfcr_unsigned_int_cb_func cb); +void bt_bfcr_set_unsigned_int_cb(struct bt_bfcr *bfcr, bt_bfcr_unsigned_int_cb_func cb); -static inline -const char *bt_bfcr_status_string(enum bt_bfcr_status status) +static inline const char *bt_bfcr_status_string(enum bt_bfcr_status status) { - switch (status) { - case BT_BFCR_STATUS_ENOMEM: - return "ENOMEM"; - case BT_BFCR_STATUS_EOF: - return "EOF"; - case BT_BFCR_STATUS_INVAL: - return "INVAL"; - case BT_BFCR_STATUS_ERROR: - return "ERROR"; - case BT_BFCR_STATUS_OK: - return "OK"; - } + switch (status) { + case BT_BFCR_STATUS_ENOMEM: + return "ENOMEM"; + case BT_BFCR_STATUS_EOF: + return "EOF"; + case BT_BFCR_STATUS_INVAL: + return "INVAL"; + case BT_BFCR_STATUS_ERROR: + return "ERROR"; + case BT_BFCR_STATUS_OK: + return "OK"; + } - bt_common_abort(); + bt_common_abort(); } #endif /* CTF_BFCR_H */ diff --git a/src/plugins/ctf/common/metadata/ast.hpp b/src/plugins/ctf/common/metadata/ast.hpp index 490e4d29..1a70b566 100644 --- a/src/plugins/ctf/common/metadata/ast.hpp +++ b/src/plugins/ctf/common/metadata/ast.hpp @@ -26,290 +26,327 @@ struct ctf_node; struct ctf_parser; struct ctf_visitor_generate_ir; -#define EINCOMPLETE 1000 - -#define FOREACH_CTF_NODES(F) \ - F(NODE_UNKNOWN) \ - F(NODE_ROOT) \ - F(NODE_ERROR) \ - F(NODE_EVENT) \ - F(NODE_STREAM) \ - F(NODE_ENV) \ - F(NODE_TRACE) \ - F(NODE_CLOCK) \ - F(NODE_CALLSITE) \ - F(NODE_CTF_EXPRESSION) \ - F(NODE_UNARY_EXPRESSION) \ - F(NODE_TYPEDEF) \ - F(NODE_TYPEALIAS_TARGET) \ - F(NODE_TYPEALIAS_ALIAS) \ - F(NODE_TYPEALIAS) \ - F(NODE_TYPE_SPECIFIER) \ - F(NODE_TYPE_SPECIFIER_LIST) \ - F(NODE_POINTER) \ - F(NODE_TYPE_DECLARATOR) \ - F(NODE_FLOATING_POINT) \ - F(NODE_INTEGER) \ - F(NODE_STRING) \ - F(NODE_ENUMERATOR) \ - F(NODE_ENUM) \ - F(NODE_STRUCT_OR_VARIANT_DECLARATION) \ - F(NODE_VARIANT) \ - F(NODE_STRUCT) - -enum node_type { -#define ENTRY(S) S, - FOREACH_CTF_NODES(ENTRY) +#define EINCOMPLETE 1000 + +#define FOREACH_CTF_NODES(F) \ + F(NODE_UNKNOWN) \ + F(NODE_ROOT) \ + F(NODE_ERROR) \ + F(NODE_EVENT) \ + F(NODE_STREAM) \ + F(NODE_ENV) \ + F(NODE_TRACE) \ + F(NODE_CLOCK) \ + F(NODE_CALLSITE) \ + F(NODE_CTF_EXPRESSION) \ + F(NODE_UNARY_EXPRESSION) \ + F(NODE_TYPEDEF) \ + F(NODE_TYPEALIAS_TARGET) \ + F(NODE_TYPEALIAS_ALIAS) \ + F(NODE_TYPEALIAS) \ + F(NODE_TYPE_SPECIFIER) \ + F(NODE_TYPE_SPECIFIER_LIST) \ + F(NODE_POINTER) \ + F(NODE_TYPE_DECLARATOR) \ + F(NODE_FLOATING_POINT) \ + F(NODE_INTEGER) \ + F(NODE_STRING) \ + F(NODE_ENUMERATOR) \ + F(NODE_ENUM) \ + F(NODE_STRUCT_OR_VARIANT_DECLARATION) \ + F(NODE_VARIANT) \ + F(NODE_STRUCT) + +enum node_type +{ +#define ENTRY(S) S, + FOREACH_CTF_NODES(ENTRY) #undef ENTRY }; -enum ctf_unary { - UNARY_UNKNOWN = 0, - UNARY_STRING, - UNARY_SIGNED_CONSTANT, - UNARY_UNSIGNED_CONSTANT, - UNARY_SBRAC, +enum ctf_unary +{ + UNARY_UNKNOWN = 0, + UNARY_STRING, + UNARY_SIGNED_CONSTANT, + UNARY_UNSIGNED_CONSTANT, + UNARY_SBRAC, }; -enum ctf_unary_link { - UNARY_LINK_UNKNOWN = 0, - UNARY_DOTLINK, - UNARY_ARROWLINK, - UNARY_DOTDOTDOT, +enum ctf_unary_link +{ + UNARY_LINK_UNKNOWN = 0, + UNARY_DOTLINK, + UNARY_ARROWLINK, + UNARY_DOTDOTDOT, }; -enum ctf_typedec { - TYPEDEC_UNKNOWN = 0, - TYPEDEC_ID, /* identifier */ - TYPEDEC_NESTED, /* (), array or sequence */ +enum ctf_typedec +{ + TYPEDEC_UNKNOWN = 0, + TYPEDEC_ID, /* identifier */ + TYPEDEC_NESTED, /* (), array or sequence */ }; -enum ctf_typespec { - TYPESPEC_UNKNOWN = 0, - TYPESPEC_VOID, - TYPESPEC_CHAR, - TYPESPEC_SHORT, - TYPESPEC_INT, - TYPESPEC_LONG, - TYPESPEC_FLOAT, - TYPESPEC_DOUBLE, - TYPESPEC_SIGNED, - TYPESPEC_UNSIGNED, - TYPESPEC_BOOL, - TYPESPEC_COMPLEX, - TYPESPEC_IMAGINARY, - TYPESPEC_CONST, - TYPESPEC_ID_TYPE, - TYPESPEC_FLOATING_POINT, - TYPESPEC_INTEGER, - TYPESPEC_STRING, - TYPESPEC_STRUCT, - TYPESPEC_VARIANT, - TYPESPEC_ENUM, +enum ctf_typespec +{ + TYPESPEC_UNKNOWN = 0, + TYPESPEC_VOID, + TYPESPEC_CHAR, + TYPESPEC_SHORT, + TYPESPEC_INT, + TYPESPEC_LONG, + TYPESPEC_FLOAT, + TYPESPEC_DOUBLE, + TYPESPEC_SIGNED, + TYPESPEC_UNSIGNED, + TYPESPEC_BOOL, + TYPESPEC_COMPLEX, + TYPESPEC_IMAGINARY, + TYPESPEC_CONST, + TYPESPEC_ID_TYPE, + TYPESPEC_FLOATING_POINT, + TYPESPEC_INTEGER, + TYPESPEC_STRING, + TYPESPEC_STRUCT, + TYPESPEC_VARIANT, + TYPESPEC_ENUM, }; -struct ctf_node { - /* - * Parent node is only set on demand by specific visitor. - */ - struct ctf_node *parent; - struct bt_list_head siblings; - struct bt_list_head tmp_head; - unsigned int lineno; - /* - * We mark nodes visited in the generate-ir phase (last - * phase). We only mark the 1-depth level nodes as visited - * (never the root node, and not their sub-nodes). This allows - * skipping already visited nodes when doing incremental - * metadata append. - */ - int visited; - - enum node_type type; - union { - struct { - } unknown; - struct { - /* - * Children nodes are ctf_expression, field_class_def, - * field_class_alias and field_class_specifier_list. - */ - struct bt_list_head declaration_list; - struct bt_list_head trace; - struct bt_list_head env; - struct bt_list_head stream; - struct bt_list_head event; - struct bt_list_head clock; - struct bt_list_head callsite; - } root; - struct { - /* - * Children nodes are ctf_expression, field_class_def, - * field_class_alias and field_class_specifier_list. - */ - struct bt_list_head declaration_list; - } event; - struct { - /* - * Children nodes are ctf_expression, field_class_def, - * field_class_alias and field_class_specifier_list. - */ - struct bt_list_head declaration_list; - } stream; - struct { - /* - * Children nodes are ctf_expression, field_class_def, - * field_class_alias and field_class_specifier_list. - */ - struct bt_list_head declaration_list; - } env; - struct { - /* - * Children nodes are ctf_expression, field_class_def, - * field_class_alias and field_class_specifier_list. - */ - struct bt_list_head declaration_list; - } trace; - struct { - /* - * Children nodes are ctf_expression, field_class_def, - * field_class_alias and field_class_specifier_list. - */ - struct bt_list_head declaration_list; - } clock; - struct { - /* - * Children nodes are ctf_expression, field_class_def, - * field_class_alias and field_class_specifier_list. - */ - struct bt_list_head declaration_list; - } callsite; - struct { - struct bt_list_head left; /* Should be string */ - struct bt_list_head right; /* Unary exp. or type */ - } ctf_expression; - struct { - ctf_unary type; - union { - /* - * string for identifier, id_type, keywords, - * string literals and character constants. - */ - char *string; - int64_t signed_constant; - uint64_t unsigned_constant; - struct ctf_node *sbrac_exp; - } u; - ctf_unary_link link; - } unary_expression; - struct { - struct ctf_node *field_class_specifier_list; - struct bt_list_head field_class_declarators; - } field_class_def; - /* new type is "alias", existing type "target" */ - struct { - struct ctf_node *field_class_specifier_list; - struct bt_list_head field_class_declarators; - } field_class_alias_target; - struct { - struct ctf_node *field_class_specifier_list; - struct bt_list_head field_class_declarators; - } field_class_alias_name; - struct { - struct ctf_node *target; - struct ctf_node *alias; - } field_class_alias; - struct { - ctf_typespec type; - /* For struct, variant and enum */ - struct ctf_node *node; - const char *id_type; - } field_class_specifier; - struct { - /* list of field_class_specifier */ - struct bt_list_head head; - } field_class_specifier_list; - struct { - unsigned int const_qualifier; - } pointer; - struct { - struct bt_list_head pointers; - ctf_typedec type; - union { - char *id; - struct { - /* typedec has no pointer list */ - struct ctf_node *field_class_declarator; - /* - * unary expression (value) or - * field_class_specifier_list. - */ - struct bt_list_head length; - /* for abstract type declarator */ - unsigned int abstract_array; - } nested; - } u; - struct ctf_node *bitfield_len; - } field_class_declarator; - struct { - /* Children nodes are ctf_expression. */ - struct bt_list_head expressions; - } floating_point; - struct { - /* Children nodes are ctf_expression. */ - struct bt_list_head expressions; - } integer; - struct { - /* Children nodes are ctf_expression. */ - struct bt_list_head expressions; - } string; - struct { - char *id; - /* - * Range list or single value node. Contains unary - * expressions. - */ - struct bt_list_head values; - } enumerator; - struct { - char *enum_id; - /* - * Either NULL, or points to unary expression or - * field_class_specifier_list. - */ - struct ctf_node *container_field_class; - struct bt_list_head enumerator_list; - int has_body; - } _enum; - struct { - struct ctf_node *field_class_specifier_list; - struct bt_list_head field_class_declarators; - } struct_or_variant_declaration; - struct { - char *name; - char *choice; - /* - * list of field_class_def, field_class_alias and - * declarations - */ - struct bt_list_head declaration_list; - int has_body; - } variant; - struct { - char *name; - /* - * list of field_class_def, field_class_alias and - * declarations - */ - struct bt_list_head declaration_list; - int has_body; - struct bt_list_head min_align; /* align() attribute */ - } _struct; - } u; +struct ctf_node +{ + /* + * Parent node is only set on demand by specific visitor. + */ + struct ctf_node *parent; + struct bt_list_head siblings; + struct bt_list_head tmp_head; + unsigned int lineno; + /* + * We mark nodes visited in the generate-ir phase (last + * phase). We only mark the 1-depth level nodes as visited + * (never the root node, and not their sub-nodes). This allows + * skipping already visited nodes when doing incremental + * metadata append. + */ + int visited; + + enum node_type type; + union + { + struct + { + } unknown; + struct + { + /* + * Children nodes are ctf_expression, field_class_def, + * field_class_alias and field_class_specifier_list. + */ + struct bt_list_head declaration_list; + struct bt_list_head trace; + struct bt_list_head env; + struct bt_list_head stream; + struct bt_list_head event; + struct bt_list_head clock; + struct bt_list_head callsite; + } root; + struct + { + /* + * Children nodes are ctf_expression, field_class_def, + * field_class_alias and field_class_specifier_list. + */ + struct bt_list_head declaration_list; + } event; + struct + { + /* + * Children nodes are ctf_expression, field_class_def, + * field_class_alias and field_class_specifier_list. + */ + struct bt_list_head declaration_list; + } stream; + struct + { + /* + * Children nodes are ctf_expression, field_class_def, + * field_class_alias and field_class_specifier_list. + */ + struct bt_list_head declaration_list; + } env; + struct + { + /* + * Children nodes are ctf_expression, field_class_def, + * field_class_alias and field_class_specifier_list. + */ + struct bt_list_head declaration_list; + } trace; + struct + { + /* + * Children nodes are ctf_expression, field_class_def, + * field_class_alias and field_class_specifier_list. + */ + struct bt_list_head declaration_list; + } clock; + struct + { + /* + * Children nodes are ctf_expression, field_class_def, + * field_class_alias and field_class_specifier_list. + */ + struct bt_list_head declaration_list; + } callsite; + struct + { + struct bt_list_head left; /* Should be string */ + struct bt_list_head right; /* Unary exp. or type */ + } ctf_expression; + struct + { + ctf_unary type; + union + { + /* + * string for identifier, id_type, keywords, + * string literals and character constants. + */ + char *string; + int64_t signed_constant; + uint64_t unsigned_constant; + struct ctf_node *sbrac_exp; + } u; + ctf_unary_link link; + } unary_expression; + struct + { + struct ctf_node *field_class_specifier_list; + struct bt_list_head field_class_declarators; + } field_class_def; + /* new type is "alias", existing type "target" */ + struct + { + struct ctf_node *field_class_specifier_list; + struct bt_list_head field_class_declarators; + } field_class_alias_target; + struct + { + struct ctf_node *field_class_specifier_list; + struct bt_list_head field_class_declarators; + } field_class_alias_name; + struct + { + struct ctf_node *target; + struct ctf_node *alias; + } field_class_alias; + struct + { + ctf_typespec type; + /* For struct, variant and enum */ + struct ctf_node *node; + const char *id_type; + } field_class_specifier; + struct + { + /* list of field_class_specifier */ + struct bt_list_head head; + } field_class_specifier_list; + struct + { + unsigned int const_qualifier; + } pointer; + struct + { + struct bt_list_head pointers; + ctf_typedec type; + union + { + char *id; + struct + { + /* typedec has no pointer list */ + struct ctf_node *field_class_declarator; + /* + * unary expression (value) or + * field_class_specifier_list. + */ + struct bt_list_head length; + /* for abstract type declarator */ + unsigned int abstract_array; + } nested; + } u; + struct ctf_node *bitfield_len; + } field_class_declarator; + struct + { + /* Children nodes are ctf_expression. */ + struct bt_list_head expressions; + } floating_point; + struct + { + /* Children nodes are ctf_expression. */ + struct bt_list_head expressions; + } integer; + struct + { + /* Children nodes are ctf_expression. */ + struct bt_list_head expressions; + } string; + struct + { + char *id; + /* + * Range list or single value node. Contains unary + * expressions. + */ + struct bt_list_head values; + } enumerator; + struct + { + char *enum_id; + /* + * Either NULL, or points to unary expression or + * field_class_specifier_list. + */ + struct ctf_node *container_field_class; + struct bt_list_head enumerator_list; + int has_body; + } _enum; + struct + { + struct ctf_node *field_class_specifier_list; + struct bt_list_head field_class_declarators; + } struct_or_variant_declaration; + struct + { + char *name; + char *choice; + /* + * list of field_class_def, field_class_alias and + * declarations + */ + struct bt_list_head declaration_list; + int has_body; + } variant; + struct + { + char *name; + /* + * list of field_class_def, field_class_alias and + * declarations + */ + struct bt_list_head declaration_list; + int has_body; + struct bt_list_head min_align; /* align() attribute */ + } _struct; + } u; }; -struct ctf_ast { - struct ctf_node root; +struct ctf_ast +{ + struct ctf_node root; }; const char *node_type(struct ctf_node *node); @@ -317,119 +354,103 @@ const char *node_type(struct ctf_node *node); struct meta_log_config; BT_HIDDEN -struct ctf_visitor_generate_ir *ctf_visitor_generate_ir_create( - const struct ctf_metadata_decoder_config *config); +struct ctf_visitor_generate_ir * +ctf_visitor_generate_ir_create(const struct ctf_metadata_decoder_config *config); void ctf_visitor_generate_ir_destroy(struct ctf_visitor_generate_ir *visitor); BT_HIDDEN -bt_trace_class *ctf_visitor_generate_ir_get_ir_trace_class( - struct ctf_visitor_generate_ir *visitor); +bt_trace_class *ctf_visitor_generate_ir_get_ir_trace_class(struct ctf_visitor_generate_ir *visitor); BT_HIDDEN -struct ctf_trace_class *ctf_visitor_generate_ir_borrow_ctf_trace_class( - struct ctf_visitor_generate_ir *visitor); +struct ctf_trace_class * +ctf_visitor_generate_ir_borrow_ctf_trace_class(struct ctf_visitor_generate_ir *visitor); BT_HIDDEN int ctf_visitor_generate_ir_visit_node(struct ctf_visitor_generate_ir *visitor, - struct ctf_node *node); + struct ctf_node *node); BT_HIDDEN -int ctf_visitor_semantic_check(int depth, struct ctf_node *node, - struct meta_log_config *log_cfg); +int ctf_visitor_semantic_check(int depth, struct ctf_node *node, struct meta_log_config *log_cfg); BT_HIDDEN -int ctf_visitor_parent_links(int depth, struct ctf_node *node, - struct meta_log_config *log_cfg); +int ctf_visitor_parent_links(int depth, struct ctf_node *node, struct meta_log_config *log_cfg); -static inline -char *ctf_ast_concatenate_unary_strings(struct bt_list_head *head) +static inline char *ctf_ast_concatenate_unary_strings(struct bt_list_head *head) { - int i = 0; - GString *str; - struct ctf_node *node; - - str = g_string_new(NULL); - BT_ASSERT(str); - - bt_list_for_each_entry(node, head, siblings) { - char *src_string; - - if ( - node->type != NODE_UNARY_EXPRESSION || - node->u.unary_expression.type != UNARY_STRING || - !( - ( - node->u.unary_expression.link != - UNARY_LINK_UNKNOWN - ) ^ (i == 0) - ) - ) { - goto error; - } - - switch (node->u.unary_expression.link) { - case UNARY_DOTLINK: - g_string_append(str, "."); - break; - case UNARY_ARROWLINK: - g_string_append(str, "->"); - break; - case UNARY_DOTDOTDOT: - g_string_append(str, "..."); - break; - default: - break; - } - - src_string = node->u.unary_expression.u.string; - g_string_append(str, src_string); - i++; - } - - /* Destroys the container, returns the underlying string */ - return g_string_free(str, FALSE); + int i = 0; + GString *str; + struct ctf_node *node; + + str = g_string_new(NULL); + BT_ASSERT(str); + + bt_list_for_each_entry (node, head, siblings) { + char *src_string; + + if (node->type != NODE_UNARY_EXPRESSION || node->u.unary_expression.type != UNARY_STRING || + !((node->u.unary_expression.link != UNARY_LINK_UNKNOWN) ^ (i == 0))) { + goto error; + } + + switch (node->u.unary_expression.link) { + case UNARY_DOTLINK: + g_string_append(str, "."); + break; + case UNARY_ARROWLINK: + g_string_append(str, "->"); + break; + case UNARY_DOTDOTDOT: + g_string_append(str, "..."); + break; + default: + break; + } + + src_string = node->u.unary_expression.u.string; + g_string_append(str, src_string); + i++; + } + + /* Destroys the container, returns the underlying string */ + return g_string_free(str, FALSE); error: - /* This always returns NULL */ - return g_string_free(str, TRUE); + /* This always returns NULL */ + return g_string_free(str, TRUE); } -static inline -int ctf_ast_get_unary_uuid(struct bt_list_head *head, - bt_uuid_t uuid, int log_level, bt_self_component *self_comp) +static inline int ctf_ast_get_unary_uuid(struct bt_list_head *head, bt_uuid_t uuid, int log_level, + bt_self_component *self_comp) { - int i = 0; - int ret = 0; - struct ctf_node *node; - - bt_list_for_each_entry(node, head, siblings) { - int uexpr_type = node->u.unary_expression.type; - int uexpr_link = node->u.unary_expression.link; - const char *src_string; - - if (node->type != NODE_UNARY_EXPRESSION || - uexpr_type != UNARY_STRING || - uexpr_link != UNARY_LINK_UNKNOWN || - i != 0) { - ret = -EINVAL; - goto end; - } - - src_string = node->u.unary_expression.u.string; - ret = bt_uuid_from_str(src_string, uuid); - if (ret) { + int i = 0; + int ret = 0; + struct ctf_node *node; + + bt_list_for_each_entry (node, head, siblings) { + int uexpr_type = node->u.unary_expression.type; + int uexpr_link = node->u.unary_expression.link; + const char *src_string; + + if (node->type != NODE_UNARY_EXPRESSION || uexpr_type != UNARY_STRING || + uexpr_link != UNARY_LINK_UNKNOWN || i != 0) { + ret = -EINVAL; + goto end; + } + + src_string = node->u.unary_expression.u.string; + ret = bt_uuid_from_str(src_string, uuid); + if (ret) { #ifdef BT_COMP_LOG_CUR_LVL - BT_COMP_LOG_CUR_LVL(BT_LOG_ERROR, log_level, - self_comp, - "Cannot parse UUID: uuid=\"%s\"", src_string); + BT_COMP_LOG_CUR_LVL(BT_LOG_ERROR, log_level, self_comp, + "Cannot parse UUID: uuid=\"%s\"", src_string); #endif - goto end; - } - } + goto end; + } + } end: - return ret; + return ret; } #endif /* _CTF_AST_H */ diff --git a/src/plugins/ctf/common/metadata/ctf-meta-configure-ir-trace.cpp b/src/plugins/ctf/common/metadata/ctf-meta-configure-ir-trace.cpp index e8023161..fbda3d73 100644 --- a/src/plugins/ctf/common/metadata/ctf-meta-configure-ir-trace.cpp +++ b/src/plugins/ctf/common/metadata/ctf-meta-configure-ir-trace.cpp @@ -9,43 +9,40 @@ #include "ctf-meta-configure-ir-trace.hpp" BT_HIDDEN -int ctf_trace_class_configure_ir_trace(struct ctf_trace_class *tc, - bt_trace *ir_trace) +int ctf_trace_class_configure_ir_trace(struct ctf_trace_class *tc, bt_trace *ir_trace) { - int ret = 0; - uint64_t i; - - BT_ASSERT(tc); - BT_ASSERT(ir_trace); - - if (tc->is_uuid_set) { - bt_trace_set_uuid(ir_trace, tc->uuid); - } - - for (i = 0; i < tc->env_entries->len; i++) { - struct ctf_trace_class_env_entry *env_entry = - ctf_trace_class_borrow_env_entry_by_index(tc, i); - - switch (env_entry->type) { - case CTF_TRACE_CLASS_ENV_ENTRY_TYPE_INT: - ret = bt_trace_set_environment_entry_integer( - ir_trace, env_entry->name->str, - env_entry->value.i); - break; - case CTF_TRACE_CLASS_ENV_ENTRY_TYPE_STR: - ret = bt_trace_set_environment_entry_string( - ir_trace, env_entry->name->str, - env_entry->value.str->str); - break; - default: - bt_common_abort(); - } - - if (ret) { - goto end; - } - } + int ret = 0; + uint64_t i; + + BT_ASSERT(tc); + BT_ASSERT(ir_trace); + + if (tc->is_uuid_set) { + bt_trace_set_uuid(ir_trace, tc->uuid); + } + + for (i = 0; i < tc->env_entries->len; i++) { + struct ctf_trace_class_env_entry *env_entry = + ctf_trace_class_borrow_env_entry_by_index(tc, i); + + switch (env_entry->type) { + case CTF_TRACE_CLASS_ENV_ENTRY_TYPE_INT: + ret = bt_trace_set_environment_entry_integer(ir_trace, env_entry->name->str, + env_entry->value.i); + break; + case CTF_TRACE_CLASS_ENV_ENTRY_TYPE_STR: + ret = bt_trace_set_environment_entry_string(ir_trace, env_entry->name->str, + env_entry->value.str->str); + break; + default: + bt_common_abort(); + } + + if (ret) { + goto end; + } + } end: - return ret; + return ret; } diff --git a/src/plugins/ctf/common/metadata/ctf-meta-configure-ir-trace.hpp b/src/plugins/ctf/common/metadata/ctf-meta-configure-ir-trace.hpp index 09d5ade1..af84fc8a 100644 --- a/src/plugins/ctf/common/metadata/ctf-meta-configure-ir-trace.hpp +++ b/src/plugins/ctf/common/metadata/ctf-meta-configure-ir-trace.hpp @@ -12,7 +12,6 @@ #include "ctf-meta.hpp" BT_HIDDEN -int ctf_trace_class_configure_ir_trace(struct ctf_trace_class *tc, - bt_trace *ir_trace); +int ctf_trace_class_configure_ir_trace(struct ctf_trace_class *tc, bt_trace *ir_trace); #endif /* _CTF_META_CONFIGURE_IR_TRACE_H */ diff --git a/src/plugins/ctf/common/metadata/ctf-meta-resolve.cpp b/src/plugins/ctf/common/metadata/ctf-meta-resolve.cpp index 972ea701..06fa55f5 100644 --- a/src/plugins/ctf/common/metadata/ctf-meta-resolve.cpp +++ b/src/plugins/ctf/common/metadata/ctf-meta-resolve.cpp @@ -5,10 +5,10 @@ * Copyright 2015 Jérémie Galarneau */ -#define BT_COMP_LOG_SELF_COMP (ctx->self_comp) +#define BT_COMP_LOG_SELF_COMP (ctx->self_comp) #define BT_COMP_LOG_SELF_COMP_CLASS (ctx->self_comp_class) -#define BT_LOG_OUTPUT_LEVEL (ctx->log_level) -#define BT_LOG_TAG "PLUGIN/CTF/META/RESOLVE" +#define BT_LOG_OUTPUT_LEVEL (ctx->log_level) +#define BT_LOG_TAG "PLUGIN/CTF/META/RESOLVE" #include "logging/comp-logging.h" #include @@ -27,7 +27,7 @@ #include "ctf-meta-visitors.hpp" #include "logging.hpp" -using field_class_stack_t = GPtrArray ; +using field_class_stack_t = GPtrArray; /* * A stack frame. @@ -38,286 +38,272 @@ using field_class_stack_t = GPtrArray ; * indicates the name of the field class in the upper frame (empty * string for array and sequence field classes). */ -struct field_class_stack_frame { - struct ctf_field_class *fc; - int64_t index; +struct field_class_stack_frame +{ + struct ctf_field_class *fc; + int64_t index; }; /* * The current context of the resolving engine. */ -struct resolve_context { - bt_logging_level log_level; - - /* Weak, exactly one of these must be set */ - bt_self_component *self_comp; - bt_self_component_class *self_comp_class; - - struct ctf_trace_class *tc; - struct ctf_stream_class *sc; - struct ctf_event_class *ec; - - struct { - struct ctf_field_class *packet_header; - struct ctf_field_class *packet_context; - struct ctf_field_class *event_header; - struct ctf_field_class *event_common_context; - struct ctf_field_class *event_spec_context; - struct ctf_field_class *event_payload; - } scopes; - - /* Root scope being visited */ - enum ctf_scope root_scope; - field_class_stack_t *field_class_stack; - struct ctf_field_class *cur_fc; +struct resolve_context +{ + bt_logging_level log_level; + + /* Weak, exactly one of these must be set */ + bt_self_component *self_comp; + bt_self_component_class *self_comp_class; + + struct ctf_trace_class *tc; + struct ctf_stream_class *sc; + struct ctf_event_class *ec; + + struct + { + struct ctf_field_class *packet_header; + struct ctf_field_class *packet_context; + struct ctf_field_class *event_header; + struct ctf_field_class *event_common_context; + struct ctf_field_class *event_spec_context; + struct ctf_field_class *event_payload; + } scopes; + + /* Root scope being visited */ + enum ctf_scope root_scope; + field_class_stack_t *field_class_stack; + struct ctf_field_class *cur_fc; }; /* TSDL dynamic scope prefixes as defined in CTF Section 7.3.2 */ static const char * const absolute_path_prefixes[] = { - /* CTF_SCOPE_PACKET_HEADER */ "trace.packet.header.", - /* CTF_SCOPE_PACKET_CONTEXT */ "stream.packet.context.", - /* CTF_SCOPE_EVENT_HEADER */ "stream.event.header.", - /* CTF_SCOPE_EVENT_COMMON_CONTEXT */ "stream.event.context.", - /* CTF_SCOPE_EVENT_SPECIFIC_CONTEXT */ "event.context.", - /* CTF_SCOPE_EVENT_PAYLOAD */ "event.fields.", + /* CTF_SCOPE_PACKET_HEADER */ "trace.packet.header.", + /* CTF_SCOPE_PACKET_CONTEXT */ "stream.packet.context.", + /* CTF_SCOPE_EVENT_HEADER */ "stream.event.header.", + /* CTF_SCOPE_EVENT_COMMON_CONTEXT */ "stream.event.context.", + /* CTF_SCOPE_EVENT_SPECIFIC_CONTEXT */ "event.context.", + /* CTF_SCOPE_EVENT_PAYLOAD */ "event.fields.", }; /* Number of path tokens used for the absolute prefixes */ static const uint64_t absolute_path_prefix_ptoken_counts[] = { - /* CTF_SCOPE_PACKET_HEADER */ 3, - /* CTF_SCOPE_PACKET_CONTEXT */ 3, - /* CTF_SCOPE_EVENT_HEADER */ 3, - /* CTF_SCOPE_EVENT_COMMON_CONTEXT */ 3, - /* CTF_SCOPE_EVENT_SPECIFIC_CONTEXT */ 2, - /* CTF_SCOPE_EVENT_PAYLOAD */ 2, + /* CTF_SCOPE_PACKET_HEADER */ 3, + /* CTF_SCOPE_PACKET_CONTEXT */ 3, + /* CTF_SCOPE_EVENT_HEADER */ 3, + /* CTF_SCOPE_EVENT_COMMON_CONTEXT */ 3, + /* CTF_SCOPE_EVENT_SPECIFIC_CONTEXT */ 2, + /* CTF_SCOPE_EVENT_PAYLOAD */ 2, }; -static -void destroy_field_class_stack_frame(struct field_class_stack_frame *frame) +static void destroy_field_class_stack_frame(struct field_class_stack_frame *frame) { - if (!frame) { - return; - } + if (!frame) { + return; + } - g_free(frame); + g_free(frame); } /* * Creates a class stack. */ -static -field_class_stack_t *field_class_stack_create(void) +static field_class_stack_t *field_class_stack_create(void) { - return g_ptr_array_new_with_free_func( - (GDestroyNotify) destroy_field_class_stack_frame); + return g_ptr_array_new_with_free_func((GDestroyNotify) destroy_field_class_stack_frame); } /* * Destroys a class stack. */ -static -void field_class_stack_destroy(field_class_stack_t *stack) +static void field_class_stack_destroy(field_class_stack_t *stack) { - if (stack) { - g_ptr_array_free(stack, TRUE); - } + if (stack) { + g_ptr_array_free(stack, TRUE); + } } /* * Pushes a field class onto a class stack. */ -static -int field_class_stack_push(field_class_stack_t *stack, struct ctf_field_class *fc, - struct resolve_context *ctx) +static int field_class_stack_push(field_class_stack_t *stack, struct ctf_field_class *fc, + struct resolve_context *ctx) { - int ret = 0; - struct field_class_stack_frame *frame = NULL; - - if (!stack || !fc) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid parameter: stack or field class is `NULL`."); - ret = -1; - goto end; - } - - frame = g_new0(struct field_class_stack_frame, 1); - if (!frame) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Failed to allocate one field class stack frame."); - ret = -1; - goto end; - } - - BT_COMP_LOGD("Pushing field class on context's stack: " - "fc-addr=%p, stack-size-before=%u", fc, stack->len); - frame->fc = fc; - g_ptr_array_add(stack, frame); + int ret = 0; + struct field_class_stack_frame *frame = NULL; + + if (!stack || !fc) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Invalid parameter: stack or field class is `NULL`."); + ret = -1; + goto end; + } + + frame = g_new0(struct field_class_stack_frame, 1); + if (!frame) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Failed to allocate one field class stack frame."); + ret = -1; + goto end; + } + + BT_COMP_LOGD("Pushing field class on context's stack: " + "fc-addr=%p, stack-size-before=%u", + fc, stack->len); + frame->fc = fc; + g_ptr_array_add(stack, frame); end: - return ret; + return ret; } /* * Checks whether or not `stack` is empty. */ -static -bool field_class_stack_empty(field_class_stack_t *stack) +static bool field_class_stack_empty(field_class_stack_t *stack) { - return stack->len == 0; + return stack->len == 0; } /* * Returns the number of frames in `stack`. */ -static -size_t field_class_stack_size(field_class_stack_t *stack) +static size_t field_class_stack_size(field_class_stack_t *stack) { - return stack->len; + return stack->len; } /* * Returns the top frame of `stack`. */ -static -struct field_class_stack_frame *field_class_stack_peek(field_class_stack_t *stack) +static struct field_class_stack_frame *field_class_stack_peek(field_class_stack_t *stack) { - BT_ASSERT(stack); - BT_ASSERT(!field_class_stack_empty(stack)); + BT_ASSERT(stack); + BT_ASSERT(!field_class_stack_empty(stack)); - return (field_class_stack_frame *) g_ptr_array_index(stack, stack->len - 1); + return (field_class_stack_frame *) g_ptr_array_index(stack, stack->len - 1); } /* * Returns the frame at index `index` in `stack`. */ -static -struct field_class_stack_frame *field_class_stack_at(field_class_stack_t *stack, - size_t index) +static struct field_class_stack_frame *field_class_stack_at(field_class_stack_t *stack, + size_t index) { - BT_ASSERT(stack); - BT_ASSERT(index < stack->len); + BT_ASSERT(stack); + BT_ASSERT(index < stack->len); - return (field_class_stack_frame *) g_ptr_array_index(stack, index); + return (field_class_stack_frame *) g_ptr_array_index(stack, index); } /* * Removes the top frame of `stack`. */ -static -void field_class_stack_pop(field_class_stack_t *stack, - struct resolve_context *ctx) +static void field_class_stack_pop(field_class_stack_t *stack, struct resolve_context *ctx) { - if (!field_class_stack_empty(stack)) { - /* - * This will call the frame's destructor and free it, as - * well as put its contained field class. - */ - BT_COMP_LOGD("Popping context's stack: stack-size-before=%u", - stack->len); - g_ptr_array_set_size(stack, stack->len - 1); - } + if (!field_class_stack_empty(stack)) { + /* + * This will call the frame's destructor and free it, as + * well as put its contained field class. + */ + BT_COMP_LOGD("Popping context's stack: stack-size-before=%u", stack->len); + g_ptr_array_set_size(stack, stack->len - 1); + } } /* * Returns the scope field class of `scope` in the context `ctx`. */ -static -struct ctf_field_class *borrow_class_from_ctx(struct resolve_context *ctx, - enum ctf_scope scope) +static struct ctf_field_class *borrow_class_from_ctx(struct resolve_context *ctx, + enum ctf_scope scope) { - switch (scope) { - case CTF_SCOPE_PACKET_HEADER: - return ctx->scopes.packet_header; - case CTF_SCOPE_PACKET_CONTEXT: - return ctx->scopes.packet_context; - case CTF_SCOPE_EVENT_HEADER: - return ctx->scopes.event_header; - case CTF_SCOPE_EVENT_COMMON_CONTEXT: - return ctx->scopes.event_common_context; - case CTF_SCOPE_EVENT_SPECIFIC_CONTEXT: - return ctx->scopes.event_spec_context; - case CTF_SCOPE_EVENT_PAYLOAD: - return ctx->scopes.event_payload; - default: - bt_common_abort(); - } - - return NULL; + switch (scope) { + case CTF_SCOPE_PACKET_HEADER: + return ctx->scopes.packet_header; + case CTF_SCOPE_PACKET_CONTEXT: + return ctx->scopes.packet_context; + case CTF_SCOPE_EVENT_HEADER: + return ctx->scopes.event_header; + case CTF_SCOPE_EVENT_COMMON_CONTEXT: + return ctx->scopes.event_common_context; + case CTF_SCOPE_EVENT_SPECIFIC_CONTEXT: + return ctx->scopes.event_spec_context; + case CTF_SCOPE_EVENT_PAYLOAD: + return ctx->scopes.event_payload; + default: + bt_common_abort(); + } + + return NULL; } /* * Returns the CTF scope from a path string. May return -1 if the path * is found to be relative. */ -static -enum ctf_scope get_root_scope_from_absolute_pathstr(const char *pathstr, - struct resolve_context *ctx) +static enum ctf_scope get_root_scope_from_absolute_pathstr(const char *pathstr, + struct resolve_context *ctx) { - enum ctf_scope scope; - enum ctf_scope ret = CTF_SCOPE_PACKET_UNKNOWN; - const size_t prefixes_count = sizeof(absolute_path_prefixes) / - sizeof(*absolute_path_prefixes); - - for (scope = CTF_SCOPE_PACKET_HEADER; scope < CTF_SCOPE_PACKET_HEADER + - prefixes_count; scope = (ctf_scope) (scope + 1)) { - /* - * Check if path string starts with a known absolute - * path prefix. - * - * Refer to CTF 7.3.2 STATIC AND DYNAMIC SCOPES. - */ - if (strncmp(pathstr, absolute_path_prefixes[scope], - strlen(absolute_path_prefixes[scope]))) { - /* Prefix does not match: try the next one */ - BT_COMP_LOGD("Prefix does not match: trying the next one: " - "path=\"%s\", path-prefix=\"%s\", scope=%s", - pathstr, absolute_path_prefixes[scope], - ctf_scope_string(scope)); - continue; - } - - /* Found it! */ - ret = scope; - BT_COMP_LOGD("Found root scope from absolute path: " - "path=\"%s\", scope=%s", pathstr, - ctf_scope_string(scope)); - goto end; - } + enum ctf_scope scope; + enum ctf_scope ret = CTF_SCOPE_PACKET_UNKNOWN; + const size_t prefixes_count = sizeof(absolute_path_prefixes) / sizeof(*absolute_path_prefixes); + + for (scope = CTF_SCOPE_PACKET_HEADER; scope < CTF_SCOPE_PACKET_HEADER + prefixes_count; + scope = (ctf_scope) (scope + 1)) { + /* + * Check if path string starts with a known absolute + * path prefix. + * + * Refer to CTF 7.3.2 STATIC AND DYNAMIC SCOPES. + */ + if (strncmp(pathstr, absolute_path_prefixes[scope], + strlen(absolute_path_prefixes[scope]))) { + /* Prefix does not match: try the next one */ + BT_COMP_LOGD("Prefix does not match: trying the next one: " + "path=\"%s\", path-prefix=\"%s\", scope=%s", + pathstr, absolute_path_prefixes[scope], ctf_scope_string(scope)); + continue; + } + + /* Found it! */ + ret = scope; + BT_COMP_LOGD("Found root scope from absolute path: " + "path=\"%s\", scope=%s", + pathstr, ctf_scope_string(scope)); + goto end; + } end: - return ret; + return ret; } /* * Destroys a path token. */ -static -void ptokens_destroy_func(gpointer ptoken, gpointer data) +static void ptokens_destroy_func(gpointer ptoken, gpointer data) { - g_string_free((GString *) ptoken, TRUE); + g_string_free((GString *) ptoken, TRUE); } /* * Destroys a path token list. */ -static -void ptokens_destroy(GList *ptokens) +static void ptokens_destroy(GList *ptokens) { - if (!ptokens) { - return; - } + if (!ptokens) { + return; + } - g_list_foreach(ptokens, ptokens_destroy_func, NULL); - g_list_free(ptokens); + g_list_foreach(ptokens, ptokens_destroy_func, NULL); + g_list_free(ptokens); } /* * Returns the string contained in a path token. */ -static -const char *ptoken_get_string(GList *ptoken) +static const char *ptoken_get_string(GList *ptoken) { - GString *tokenstr = (GString *) ptoken->data; + GString *tokenstr = (GString *) ptoken->data; - return tokenstr->str; + return tokenstr->str; } /* @@ -325,42 +311,41 @@ const char *ptoken_get_string(GList *ptoken) * individual words of a path string into a list of individual * strings. */ -static -GList *pathstr_to_ptokens(const char *pathstr, struct resolve_context *ctx) +static GList *pathstr_to_ptokens(const char *pathstr, struct resolve_context *ctx) { - const char *at = pathstr; - const char *last = at; - GList *ptokens = NULL; + const char *at = pathstr; + const char *last = at; + GList *ptokens = NULL; - for (;;) { - if (*at == '.' || *at == '\0') { - GString *tokenstr; + for (;;) { + if (*at == '.' || *at == '\0') { + GString *tokenstr; - if (at == last) { - /* Error: empty token */ - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Empty path token: path=\"%s\", pos=%u", - pathstr, (unsigned int) (at - pathstr)); - goto error; - } + if (at == last) { + /* Error: empty token */ + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Empty path token: path=\"%s\", pos=%u", + pathstr, (unsigned int) (at - pathstr)); + goto error; + } - tokenstr = g_string_new(NULL); - g_string_append_len(tokenstr, last, at - last); - ptokens = g_list_append(ptokens, tokenstr); - last = at + 1; - } + tokenstr = g_string_new(NULL); + g_string_append_len(tokenstr, last, at - last); + ptokens = g_list_append(ptokens, tokenstr); + last = at + 1; + } - if (*at == '\0') { - break; - } + if (*at == '\0') { + break; + } - at++; - } + at++; + } - return ptokens; + return ptokens; error: - ptokens_destroy(ptokens); - return NULL; + ptokens_destroy(ptokens); + return NULL; } /* @@ -372,77 +357,70 @@ error: * `field_path` is an output parameter owned by the caller that must be * filled here. */ -static -int ptokens_to_field_path(GList *ptokens, struct ctf_field_path *field_path, - struct ctf_field_class *fc, int64_t src_index, - struct resolve_context *ctx) +static int ptokens_to_field_path(GList *ptokens, struct ctf_field_path *field_path, + struct ctf_field_class *fc, int64_t src_index, + struct resolve_context *ctx) { - int ret = 0; - GList *cur_ptoken = ptokens; - bool first_level_done = false; - - /* Locate target */ - while (cur_ptoken) { - int64_t child_index; - struct ctf_field_class *child_fc; - const char *ft_name = ptoken_get_string(cur_ptoken); - - BT_COMP_LOGD("Current path token: token=\"%s\"", ft_name); - - /* Find to which index corresponds the current path token */ - if (fc->type == CTF_FIELD_CLASS_TYPE_ARRAY || - fc->type == CTF_FIELD_CLASS_TYPE_SEQUENCE) { - child_index = -1; - } else { - child_index = - ctf_field_class_compound_get_field_class_index_from_orig_name( - fc, ft_name); - if (child_index < 0) { - /* - * Error: field name does not exist or - * wrong current class. - */ - BT_COMP_LOGD("Cannot get index of field class: " - "field-name=\"%s\", " - "src-index=%" PRId64 ", " - "child-index=%" PRId64 ", " - "first-level-done=%d", - ft_name, src_index, child_index, - first_level_done); - ret = -1; - goto end; - } else if (child_index > src_index && - !first_level_done) { - BT_COMP_LOGD("Child field class is located after source field class: " - "field-name=\"%s\", " - "src-index=%" PRId64 ", " - "child-index=%" PRId64 ", " - "first-level-done=%d", - ft_name, src_index, child_index, - first_level_done); - ret = -1; - goto end; - } - - /* Next path token */ - cur_ptoken = g_list_next(cur_ptoken); - first_level_done = true; - } - - /* Create new field path entry */ - ctf_field_path_append_index(field_path, child_index); - - /* Get child field class */ - child_fc = ctf_field_class_compound_borrow_field_class_by_index( - fc, child_index); - BT_ASSERT(child_fc); - - /* Move child class to current class */ - fc = child_fc; - } + int ret = 0; + GList *cur_ptoken = ptokens; + bool first_level_done = false; + + /* Locate target */ + while (cur_ptoken) { + int64_t child_index; + struct ctf_field_class *child_fc; + const char *ft_name = ptoken_get_string(cur_ptoken); + + BT_COMP_LOGD("Current path token: token=\"%s\"", ft_name); + + /* Find to which index corresponds the current path token */ + if (fc->type == CTF_FIELD_CLASS_TYPE_ARRAY || fc->type == CTF_FIELD_CLASS_TYPE_SEQUENCE) { + child_index = -1; + } else { + child_index = + ctf_field_class_compound_get_field_class_index_from_orig_name(fc, ft_name); + if (child_index < 0) { + /* + * Error: field name does not exist or + * wrong current class. + */ + BT_COMP_LOGD("Cannot get index of field class: " + "field-name=\"%s\", " + "src-index=%" PRId64 ", " + "child-index=%" PRId64 ", " + "first-level-done=%d", + ft_name, src_index, child_index, first_level_done); + ret = -1; + goto end; + } else if (child_index > src_index && !first_level_done) { + BT_COMP_LOGD("Child field class is located after source field class: " + "field-name=\"%s\", " + "src-index=%" PRId64 ", " + "child-index=%" PRId64 ", " + "first-level-done=%d", + ft_name, src_index, child_index, first_level_done); + ret = -1; + goto end; + } + + /* Next path token */ + cur_ptoken = g_list_next(cur_ptoken); + first_level_done = true; + } + + /* Create new field path entry */ + ctf_field_path_append_index(field_path, child_index); + + /* Get child field class */ + child_fc = ctf_field_class_compound_borrow_field_class_by_index(fc, child_index); + BT_ASSERT(child_fc); + + /* Move child class to current class */ + fc = child_fc; + } end: - return ret; + return ret; } /* @@ -452,94 +430,91 @@ end: * `field_path` is an output parameter owned by the caller that must be * filled here. */ -static -int absolute_ptokens_to_field_path(GList *ptokens, - struct ctf_field_path *field_path, - struct resolve_context *ctx) +static int absolute_ptokens_to_field_path(GList *ptokens, struct ctf_field_path *field_path, + struct resolve_context *ctx) { - int ret = 0; - GList *cur_ptoken; - struct ctf_field_class *fc; - - /* - * Make sure we're not referring to a scope within a translated - * object. - */ - switch (field_path->root) { - case CTF_SCOPE_PACKET_HEADER: - if (ctx->tc->is_translated) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Trace class is already translated: " - "root-scope=%s", - ctf_scope_string(field_path->root)); - ret = -1; - goto end; - } - - break; - case CTF_SCOPE_PACKET_CONTEXT: - case CTF_SCOPE_EVENT_HEADER: - case CTF_SCOPE_EVENT_COMMON_CONTEXT: - if (!ctx->sc) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("No current stream class: " - "root-scope=%s", - ctf_scope_string(field_path->root)); - ret = -1; - goto end; - } - - if (ctx->sc->is_translated) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Stream class is already translated: " - "root-scope=%s", - ctf_scope_string(field_path->root)); - ret = -1; - goto end; - } - - break; - case CTF_SCOPE_EVENT_SPECIFIC_CONTEXT: - case CTF_SCOPE_EVENT_PAYLOAD: - if (!ctx->ec) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("No current event class: " - "root-scope=%s", - ctf_scope_string(field_path->root)); - ret = -1; - goto end; - } - - if (ctx->ec->is_translated) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Event class is already translated: " - "root-scope=%s", - ctf_scope_string(field_path->root)); - ret = -1; - goto end; - } - - break; - - default: - bt_common_abort(); - } - - /* Skip absolute path tokens */ - cur_ptoken = g_list_nth(ptokens, - absolute_path_prefix_ptoken_counts[field_path->root]); - - /* Start with root class */ - fc = borrow_class_from_ctx(ctx, field_path->root); - if (!fc) { - /* Error: root class is not available */ - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Root field class is not available: " - "root-scope=%s", - ctf_scope_string(field_path->root)); - ret = -1; - goto end; - } - - /* Locate target */ - ret = ptokens_to_field_path(cur_ptoken, field_path, fc, INT64_MAX, ctx); + int ret = 0; + GList *cur_ptoken; + struct ctf_field_class *fc; + + /* + * Make sure we're not referring to a scope within a translated + * object. + */ + switch (field_path->root) { + case CTF_SCOPE_PACKET_HEADER: + if (ctx->tc->is_translated) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Trace class is already translated: " + "root-scope=%s", + ctf_scope_string(field_path->root)); + ret = -1; + goto end; + } + + break; + case CTF_SCOPE_PACKET_CONTEXT: + case CTF_SCOPE_EVENT_HEADER: + case CTF_SCOPE_EVENT_COMMON_CONTEXT: + if (!ctx->sc) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("No current stream class: " + "root-scope=%s", + ctf_scope_string(field_path->root)); + ret = -1; + goto end; + } + + if (ctx->sc->is_translated) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Stream class is already translated: " + "root-scope=%s", + ctf_scope_string(field_path->root)); + ret = -1; + goto end; + } + + break; + case CTF_SCOPE_EVENT_SPECIFIC_CONTEXT: + case CTF_SCOPE_EVENT_PAYLOAD: + if (!ctx->ec) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("No current event class: " + "root-scope=%s", + ctf_scope_string(field_path->root)); + ret = -1; + goto end; + } + + if (ctx->ec->is_translated) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Event class is already translated: " + "root-scope=%s", + ctf_scope_string(field_path->root)); + ret = -1; + goto end; + } + + break; + + default: + bt_common_abort(); + } + + /* Skip absolute path tokens */ + cur_ptoken = g_list_nth(ptokens, absolute_path_prefix_ptoken_counts[field_path->root]); + + /* Start with root class */ + fc = borrow_class_from_ctx(ctx, field_path->root); + if (!fc) { + /* Error: root class is not available */ + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Root field class is not available: " + "root-scope=%s", + ctf_scope_string(field_path->root)); + ret = -1; + goto end; + } + + /* Locate target */ + ret = ptokens_to_field_path(cur_ptoken, field_path, fc, INT64_MAX, ctx); end: - return ret; + return ret; } /* @@ -549,762 +524,740 @@ end: * `field_path` is an output parameter owned by the caller that must be * filled here. */ -static -int relative_ptokens_to_field_path(GList *ptokens, - struct ctf_field_path *field_path, struct resolve_context *ctx) +static int relative_ptokens_to_field_path(GList *ptokens, struct ctf_field_path *field_path, + struct resolve_context *ctx) { - int ret = 0; - int64_t parent_pos_in_stack; - struct ctf_field_path tail_field_path; - - ctf_field_path_init(&tail_field_path); - parent_pos_in_stack = field_class_stack_size(ctx->field_class_stack) - 1; - - while (parent_pos_in_stack >= 0) { - struct ctf_field_class *parent_class = - field_class_stack_at(ctx->field_class_stack, - parent_pos_in_stack)->fc; - int64_t cur_index = field_class_stack_at(ctx->field_class_stack, - parent_pos_in_stack)->index; - - BT_COMP_LOGD("Locating target field class from current parent field class: " - "parent-pos=%" PRId64 ", parent-fc-addr=%p, " - "cur-index=%" PRId64, - parent_pos_in_stack, parent_class, cur_index); - - /* Locate target from current parent class */ - ret = ptokens_to_field_path(ptokens, &tail_field_path, - parent_class, cur_index, ctx); - if (ret) { - /* Not found... yet */ - BT_COMP_LOGD_STR("Not found at this point."); - ctf_field_path_clear(&tail_field_path); - } else { - /* Found: stitch tail field path to head field path */ - uint64_t i = 0; - size_t tail_field_path_len = - tail_field_path.path->len; - - while (BT_TRUE) { - struct ctf_field_class *cur_class = - field_class_stack_at( - ctx->field_class_stack, i)->fc; - int64_t index = field_class_stack_at( - ctx->field_class_stack, i)->index; - - if (cur_class == parent_class) { - break; - } - - ctf_field_path_append_index(field_path, - index); - i++; - } - - for (i = 0; i < tail_field_path_len; i++) { - int64_t index = - ctf_field_path_borrow_index_by_index( - &tail_field_path, i); - - ctf_field_path_append_index(field_path, - (int64_t) index); - } - break; - } - - parent_pos_in_stack--; - } - - if (parent_pos_in_stack < 0) { - /* Not found */ - ret = -1; - } - - ctf_field_path_fini(&tail_field_path); - return ret; + int ret = 0; + int64_t parent_pos_in_stack; + struct ctf_field_path tail_field_path; + + ctf_field_path_init(&tail_field_path); + parent_pos_in_stack = field_class_stack_size(ctx->field_class_stack) - 1; + + while (parent_pos_in_stack >= 0) { + struct ctf_field_class *parent_class = + field_class_stack_at(ctx->field_class_stack, parent_pos_in_stack)->fc; + int64_t cur_index = + field_class_stack_at(ctx->field_class_stack, parent_pos_in_stack)->index; + + BT_COMP_LOGD("Locating target field class from current parent field class: " + "parent-pos=%" PRId64 ", parent-fc-addr=%p, " + "cur-index=%" PRId64, + parent_pos_in_stack, parent_class, cur_index); + + /* Locate target from current parent class */ + ret = ptokens_to_field_path(ptokens, &tail_field_path, parent_class, cur_index, ctx); + if (ret) { + /* Not found... yet */ + BT_COMP_LOGD_STR("Not found at this point."); + ctf_field_path_clear(&tail_field_path); + } else { + /* Found: stitch tail field path to head field path */ + uint64_t i = 0; + size_t tail_field_path_len = tail_field_path.path->len; + + while (BT_TRUE) { + struct ctf_field_class *cur_class = + field_class_stack_at(ctx->field_class_stack, i)->fc; + int64_t index = field_class_stack_at(ctx->field_class_stack, i)->index; + + if (cur_class == parent_class) { + break; + } + + ctf_field_path_append_index(field_path, index); + i++; + } + + for (i = 0; i < tail_field_path_len; i++) { + int64_t index = ctf_field_path_borrow_index_by_index(&tail_field_path, i); + + ctf_field_path_append_index(field_path, (int64_t) index); + } + break; + } + + parent_pos_in_stack--; + } + + if (parent_pos_in_stack < 0) { + /* Not found */ + ret = -1; + } + + ctf_field_path_fini(&tail_field_path); + return ret; } /* * Converts a path string to a field path object within the resolving * context `ctx`. */ -static -int pathstr_to_field_path(const char *pathstr, - struct ctf_field_path *field_path, struct resolve_context *ctx) +static int pathstr_to_field_path(const char *pathstr, struct ctf_field_path *field_path, + struct resolve_context *ctx) { - int ret = 0; - enum ctf_scope root_scope; - GList *ptokens = NULL; - - /* Convert path string to path tokens */ - ptokens = pathstr_to_ptokens(pathstr, ctx); - if (!ptokens) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot convert path string to path tokens: " - "path=\"%s\"", pathstr); - ret = -1; - goto end; - } - - /* Absolute or relative path? */ - root_scope = get_root_scope_from_absolute_pathstr(pathstr, ctx); - - if (root_scope == CTF_SCOPE_PACKET_UNKNOWN) { - /* Relative path: start with current root scope */ - field_path->root = ctx->root_scope; - BT_COMP_LOGD("Detected relative path: starting with current root scope: " - "scope=%s", ctf_scope_string(field_path->root)); - ret = relative_ptokens_to_field_path(ptokens, field_path, ctx); - if (ret) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot get relative field path of path string: " - "path=\"%s\", start-scope=%s, end-scope=%s", - pathstr, ctf_scope_string(ctx->root_scope), - ctf_scope_string(field_path->root)); - goto end; - } - } else { - /* Absolute path: use found root scope */ - field_path->root = root_scope; - BT_COMP_LOGD("Detected absolute path: using root scope: " - "scope=%s", ctf_scope_string(field_path->root)); - ret = absolute_ptokens_to_field_path(ptokens, field_path, ctx); - if (ret) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot get absolute field path of path string: " - "path=\"%s\", root-scope=%s", - pathstr, ctf_scope_string(root_scope)); - goto end; - } - } - - if (BT_LOG_ON_TRACE && ret == 0) { - GString *field_path_pretty = ctf_field_path_string(field_path); - const char *field_path_pretty_str = - field_path_pretty ? field_path_pretty->str : NULL; - - BT_COMP_LOGD("Found field path: path=\"%s\", field-path=\"%s\"", - pathstr, field_path_pretty_str); - - if (field_path_pretty) { - g_string_free(field_path_pretty, TRUE); - } - } + int ret = 0; + enum ctf_scope root_scope; + GList *ptokens = NULL; + + /* Convert path string to path tokens */ + ptokens = pathstr_to_ptokens(pathstr, ctx); + if (!ptokens) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot convert path string to path tokens: " + "path=\"%s\"", + pathstr); + ret = -1; + goto end; + } + + /* Absolute or relative path? */ + root_scope = get_root_scope_from_absolute_pathstr(pathstr, ctx); + + if (root_scope == CTF_SCOPE_PACKET_UNKNOWN) { + /* Relative path: start with current root scope */ + field_path->root = ctx->root_scope; + BT_COMP_LOGD("Detected relative path: starting with current root scope: " + "scope=%s", + ctf_scope_string(field_path->root)); + ret = relative_ptokens_to_field_path(ptokens, field_path, ctx); + if (ret) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Cannot get relative field path of path string: " + "path=\"%s\", start-scope=%s, end-scope=%s", + pathstr, ctf_scope_string(ctx->root_scope), ctf_scope_string(field_path->root)); + goto end; + } + } else { + /* Absolute path: use found root scope */ + field_path->root = root_scope; + BT_COMP_LOGD("Detected absolute path: using root scope: " + "scope=%s", + ctf_scope_string(field_path->root)); + ret = absolute_ptokens_to_field_path(ptokens, field_path, ctx); + if (ret) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Cannot get absolute field path of path string: " + "path=\"%s\", root-scope=%s", + pathstr, ctf_scope_string(root_scope)); + goto end; + } + } + + if (BT_LOG_ON_TRACE && ret == 0) { + GString *field_path_pretty = ctf_field_path_string(field_path); + const char *field_path_pretty_str = field_path_pretty ? field_path_pretty->str : NULL; + + BT_COMP_LOGD("Found field path: path=\"%s\", field-path=\"%s\"", pathstr, + field_path_pretty_str); + + if (field_path_pretty) { + g_string_free(field_path_pretty, TRUE); + } + } end: - ptokens_destroy(ptokens); - return ret; + ptokens_destroy(ptokens); + return ret; } /* * Retrieves a field class by following the field path `field_path` in * the resolving context `ctx`. */ -static -struct ctf_field_class *field_path_to_field_class( - struct ctf_field_path *field_path, struct resolve_context *ctx) +static struct ctf_field_class *field_path_to_field_class(struct ctf_field_path *field_path, + struct resolve_context *ctx) { - uint64_t i; - struct ctf_field_class *fc; - - /* Start with root class */ - fc = borrow_class_from_ctx(ctx, field_path->root); - if (!fc) { - /* Error: root class is not available */ - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Root field class is not available: root-scope=%s", - ctf_scope_string(field_path->root)); - goto end; - } - - /* Locate target */ - for (i = 0; i < field_path->path->len; i++) { - struct ctf_field_class *child_fc; - int64_t child_index = - ctf_field_path_borrow_index_by_index(field_path, i); - - /* Get child field class */ - child_fc = ctf_field_class_compound_borrow_field_class_by_index( - fc, child_index); - BT_ASSERT(child_fc); - - /* Move child class to current class */ - fc = child_fc; - } + uint64_t i; + struct ctf_field_class *fc; + + /* Start with root class */ + fc = borrow_class_from_ctx(ctx, field_path->root); + if (!fc) { + /* Error: root class is not available */ + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Root field class is not available: root-scope=%s", + ctf_scope_string(field_path->root)); + goto end; + } + + /* Locate target */ + for (i = 0; i < field_path->path->len; i++) { + struct ctf_field_class *child_fc; + int64_t child_index = ctf_field_path_borrow_index_by_index(field_path, i); + + /* Get child field class */ + child_fc = ctf_field_class_compound_borrow_field_class_by_index(fc, child_index); + BT_ASSERT(child_fc); + + /* Move child class to current class */ + fc = child_fc; + } end: - return fc; + return fc; } /* * Fills the equivalent field path object of the context class stack. */ -static -void get_ctx_stack_field_path(struct resolve_context *ctx, - struct ctf_field_path *field_path) +static void get_ctx_stack_field_path(struct resolve_context *ctx, struct ctf_field_path *field_path) { - uint64_t i; + uint64_t i; - BT_ASSERT(field_path); - field_path->root = ctx->root_scope; - ctf_field_path_clear(field_path); + BT_ASSERT(field_path); + field_path->root = ctx->root_scope; + ctf_field_path_clear(field_path); - for (i = 0; i < field_class_stack_size(ctx->field_class_stack); i++) { - struct field_class_stack_frame *frame = - field_class_stack_at(ctx->field_class_stack, i); + for (i = 0; i < field_class_stack_size(ctx->field_class_stack); i++) { + struct field_class_stack_frame *frame = field_class_stack_at(ctx->field_class_stack, i); - ctf_field_path_append_index(field_path, frame->index); - } + ctf_field_path_append_index(field_path, frame->index); + } } /* * Returns the index of the lowest common ancestor of two field path * objects having the same root scope. */ -static -int64_t get_field_paths_lca_index(struct ctf_field_path *field_path1, - struct ctf_field_path *field_path2, - struct resolve_context *ctx) +static int64_t get_field_paths_lca_index(struct ctf_field_path *field_path1, + struct ctf_field_path *field_path2, + struct resolve_context *ctx) { - int64_t lca_index = 0; - uint64_t field_path1_len, field_path2_len; - - if (BT_LOG_ON_TRACE) { - GString *field_path1_pretty = - ctf_field_path_string(field_path1); - GString *field_path2_pretty = - ctf_field_path_string(field_path2); - const char *field_path1_pretty_str = - field_path1_pretty ? field_path1_pretty->str : NULL; - const char *field_path2_pretty_str = - field_path2_pretty ? field_path2_pretty->str : NULL; - - BT_COMP_LOGD("Finding lowest common ancestor (LCA) between two field paths: " - "field-path-1=\"%s\", field-path-2=\"%s\"", - field_path1_pretty_str, field_path2_pretty_str); - - if (field_path1_pretty) { - g_string_free(field_path1_pretty, TRUE); - } - - if (field_path2_pretty) { - g_string_free(field_path2_pretty, TRUE); - } - } - - /* - * Start from both roots and find the first mismatch. - */ - BT_ASSERT(field_path1->root == field_path2->root); - field_path1_len = field_path1->path->len; - field_path2_len = field_path2->path->len; - - while (true) { - int64_t target_index, ctx_index; - - if (lca_index == (int64_t) field_path2_len || - lca_index == (int64_t) field_path1_len) { - /* - * This means that both field paths never split. - * This is invalid because the target cannot be - * an ancestor of the source. - */ - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Source field class is an ancestor of target field class or vice versa: " - "lca-index=%" PRId64 ", " - "field-path-1-len=%" PRIu64 ", " - "field-path-2-len=%" PRIu64, - lca_index, field_path1_len, field_path2_len); - lca_index = -1; - break; - } - - target_index = ctf_field_path_borrow_index_by_index(field_path1, - lca_index); - ctx_index = ctf_field_path_borrow_index_by_index(field_path2, - lca_index); - - if (target_index != ctx_index) { - /* LCA index is the previous */ - break; - } - - lca_index++; - } - - BT_COMP_LOGD("Found LCA: lca-index=%" PRId64, lca_index); - return lca_index; + int64_t lca_index = 0; + uint64_t field_path1_len, field_path2_len; + + if (BT_LOG_ON_TRACE) { + GString *field_path1_pretty = ctf_field_path_string(field_path1); + GString *field_path2_pretty = ctf_field_path_string(field_path2); + const char *field_path1_pretty_str = field_path1_pretty ? field_path1_pretty->str : NULL; + const char *field_path2_pretty_str = field_path2_pretty ? field_path2_pretty->str : NULL; + + BT_COMP_LOGD("Finding lowest common ancestor (LCA) between two field paths: " + "field-path-1=\"%s\", field-path-2=\"%s\"", + field_path1_pretty_str, field_path2_pretty_str); + + if (field_path1_pretty) { + g_string_free(field_path1_pretty, TRUE); + } + + if (field_path2_pretty) { + g_string_free(field_path2_pretty, TRUE); + } + } + + /* + * Start from both roots and find the first mismatch. + */ + BT_ASSERT(field_path1->root == field_path2->root); + field_path1_len = field_path1->path->len; + field_path2_len = field_path2->path->len; + + while (true) { + int64_t target_index, ctx_index; + + if (lca_index == (int64_t) field_path2_len || lca_index == (int64_t) field_path1_len) { + /* + * This means that both field paths never split. + * This is invalid because the target cannot be + * an ancestor of the source. + */ + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Source field class is an ancestor of target field class or vice versa: " + "lca-index=%" PRId64 ", " + "field-path-1-len=%" PRIu64 ", " + "field-path-2-len=%" PRIu64, + lca_index, field_path1_len, field_path2_len); + lca_index = -1; + break; + } + + target_index = ctf_field_path_borrow_index_by_index(field_path1, lca_index); + ctx_index = ctf_field_path_borrow_index_by_index(field_path2, lca_index); + + if (target_index != ctx_index) { + /* LCA index is the previous */ + break; + } + + lca_index++; + } + + BT_COMP_LOGD("Found LCA: lca-index=%" PRId64, lca_index); + return lca_index; } /* * Validates a target field path. */ -static -int validate_target_field_path(struct ctf_field_path *target_field_path, - struct ctf_field_class *target_fc, - struct resolve_context *ctx) +static int validate_target_field_path(struct ctf_field_path *target_field_path, + struct ctf_field_class *target_fc, + struct resolve_context *ctx) { - int ret = 0; - struct ctf_field_path ctx_field_path; - uint64_t target_field_path_len = target_field_path->path->len; - int64_t lca_index; - - /* Get context field path */ - ctf_field_path_init(&ctx_field_path); - get_ctx_stack_field_path(ctx, &ctx_field_path); - - /* - * Make sure the target is not a root. - */ - if (target_field_path_len == 0) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Target field path's length is 0 (targeting the root)."); - ret = -1; - goto end; - } - - /* - * Make sure the root of the target field path is not located - * after the context field path's root. - */ - if (target_field_path->root > ctx_field_path.root) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Target field class is located after source field class: " - "target-root=%s, source-root=%s", - ctf_scope_string(target_field_path->root), - ctf_scope_string(ctx_field_path.root)); - ret = -1; - goto end; - } - - if (target_field_path->root == ctx_field_path.root) { - int64_t target_index, ctx_index; - - /* - * Find the index of the lowest common ancestor of both field - * paths. - */ - lca_index = get_field_paths_lca_index(target_field_path, - &ctx_field_path, ctx); - if (lca_index < 0) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot get least common ancestor."); - ret = -1; - goto end; - } - - /* - * Make sure the target field path is located before the - * context field path. - */ - target_index = ctf_field_path_borrow_index_by_index( - target_field_path, (uint64_t) lca_index); - ctx_index = ctf_field_path_borrow_index_by_index( - &ctx_field_path, (uint64_t) lca_index); - - if (target_index >= ctx_index) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Target field class's index is greater than or equal to source field class's index in LCA: " - "lca-index=%" PRId64 ", " - "target-index=%" PRId64 ", " - "source-index=%" PRId64, - lca_index, target_index, ctx_index); - ret = -1; - goto end; - } - } - - /* - * Make sure the target class has the right class and properties. - */ - switch (ctx->cur_fc->type) { - case CTF_FIELD_CLASS_TYPE_VARIANT: - if (target_fc->type != CTF_FIELD_CLASS_TYPE_ENUM) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Variant field class's tag field class is not an enumeration field class: " - "tag-fc-addr=%p, tag-fc-id=%d", - target_fc, target_fc->type); - ret = -1; - goto end; - } - break; - case CTF_FIELD_CLASS_TYPE_SEQUENCE: - { - struct ctf_field_class_int *int_fc = ctf_field_class_as_int(target_fc); - - if (target_fc->type != CTF_FIELD_CLASS_TYPE_INT && - target_fc->type != CTF_FIELD_CLASS_TYPE_ENUM) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Sequence field class's length field class is not an unsigned integer field class: " - "length-fc-addr=%p, length-fc-id=%d", - target_fc, target_fc->type); - ret = -1; - goto end; - } - - if (int_fc->is_signed) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Sequence field class's length field class is not an unsigned integer field class: " - "length-fc-addr=%p, length-fc-id=%d", - target_fc, target_fc->type); - ret = -1; - goto end; - } - break; - } - default: - bt_common_abort(); - } + int ret = 0; + struct ctf_field_path ctx_field_path; + uint64_t target_field_path_len = target_field_path->path->len; + int64_t lca_index; + + /* Get context field path */ + ctf_field_path_init(&ctx_field_path); + get_ctx_stack_field_path(ctx, &ctx_field_path); + + /* + * Make sure the target is not a root. + */ + if (target_field_path_len == 0) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Target field path's length is 0 (targeting the root)."); + ret = -1; + goto end; + } + + /* + * Make sure the root of the target field path is not located + * after the context field path's root. + */ + if (target_field_path->root > ctx_field_path.root) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Target field class is located after source field class: " + "target-root=%s, source-root=%s", + ctf_scope_string(target_field_path->root), ctf_scope_string(ctx_field_path.root)); + ret = -1; + goto end; + } + + if (target_field_path->root == ctx_field_path.root) { + int64_t target_index, ctx_index; + + /* + * Find the index of the lowest common ancestor of both field + * paths. + */ + lca_index = get_field_paths_lca_index(target_field_path, &ctx_field_path, ctx); + if (lca_index < 0) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot get least common ancestor."); + ret = -1; + goto end; + } + + /* + * Make sure the target field path is located before the + * context field path. + */ + target_index = + ctf_field_path_borrow_index_by_index(target_field_path, (uint64_t) lca_index); + ctx_index = ctf_field_path_borrow_index_by_index(&ctx_field_path, (uint64_t) lca_index); + + if (target_index >= ctx_index) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Target field class's index is greater than or equal to source field class's index in LCA: " + "lca-index=%" PRId64 ", " + "target-index=%" PRId64 ", " + "source-index=%" PRId64, + lca_index, target_index, ctx_index); + ret = -1; + goto end; + } + } + + /* + * Make sure the target class has the right class and properties. + */ + switch (ctx->cur_fc->type) { + case CTF_FIELD_CLASS_TYPE_VARIANT: + if (target_fc->type != CTF_FIELD_CLASS_TYPE_ENUM) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Variant field class's tag field class is not an enumeration field class: " + "tag-fc-addr=%p, tag-fc-id=%d", + target_fc, target_fc->type); + ret = -1; + goto end; + } + break; + case CTF_FIELD_CLASS_TYPE_SEQUENCE: + { + struct ctf_field_class_int *int_fc = ctf_field_class_as_int(target_fc); + + if (target_fc->type != CTF_FIELD_CLASS_TYPE_INT && + target_fc->type != CTF_FIELD_CLASS_TYPE_ENUM) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Sequence field class's length field class is not an unsigned integer field class: " + "length-fc-addr=%p, length-fc-id=%d", + target_fc, target_fc->type); + ret = -1; + goto end; + } + + if (int_fc->is_signed) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Sequence field class's length field class is not an unsigned integer field class: " + "length-fc-addr=%p, length-fc-id=%d", + target_fc, target_fc->type); + ret = -1; + goto end; + } + break; + } + default: + bt_common_abort(); + } end: - ctf_field_path_fini(&ctx_field_path); - return ret; + ctf_field_path_fini(&ctx_field_path); + return ret; } /* * Resolves a variant or sequence field class `fc`. */ -static -int resolve_sequence_or_variant_field_class(struct ctf_field_class *fc, - struct resolve_context *ctx) +static int resolve_sequence_or_variant_field_class(struct ctf_field_class *fc, + struct resolve_context *ctx) { - int ret = 0; - const char *pathstr; - struct ctf_field_path target_field_path; - struct ctf_field_class *target_fc = NULL; - GString *target_field_path_pretty = NULL; - const char *target_field_path_pretty_str; - - ctf_field_path_init(&target_field_path); - - /* Get path string */ - switch (fc->type) { - case CTF_FIELD_CLASS_TYPE_SEQUENCE: - { - struct ctf_field_class_sequence *seq_fc = ctf_field_class_as_sequence(fc); - pathstr = seq_fc->length_ref->str; - break; - } - case CTF_FIELD_CLASS_TYPE_VARIANT: - { - struct ctf_field_class_variant *var_fc = ctf_field_class_as_variant(fc); - pathstr = var_fc->tag_ref->str; - break; - } - default: - bt_common_abort(); - } - - if (!pathstr) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot get path string."); - ret = -1; - goto end; - } - - /* Get target field path out of path string */ - ret = pathstr_to_field_path(pathstr, &target_field_path, ctx); - if (ret) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot get target field path for path string: " - "path=\"%s\"", pathstr); - goto end; - } - - target_field_path_pretty = ctf_field_path_string( - &target_field_path); - target_field_path_pretty_str = - target_field_path_pretty ? target_field_path_pretty->str : NULL; - - /* Get target field class */ - target_fc = field_path_to_field_class(&target_field_path, ctx); - if (!target_fc) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot get target field class for path string: " - "path=\"%s\", target-field-path=\"%s\"", - pathstr, target_field_path_pretty_str); - ret = -1; - goto end; - } - - ret = validate_target_field_path(&target_field_path, - target_fc, ctx); - if (ret) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid target field path for path string: " - "path=\"%s\", target-field-path=\"%s\"", - pathstr, target_field_path_pretty_str); - goto end; - } - - /* Set target field path and target field class */ - switch (fc->type) { - case CTF_FIELD_CLASS_TYPE_SEQUENCE: - { - ctf_field_class_sequence *seq_fc = ctf_field_class_as_sequence(fc); - - ctf_field_path_copy_content(&seq_fc->length_path, - &target_field_path); - seq_fc->length_fc = ctf_field_class_as_int(target_fc); - break; - } - case CTF_FIELD_CLASS_TYPE_VARIANT: - { - ctf_field_class_variant *var_fc = ctf_field_class_as_variant(fc); - - ctf_field_path_copy_content(&var_fc->tag_path, - &target_field_path); - ctf_field_class_variant_set_tag_field_class(var_fc, - ctf_field_class_as_enum(target_fc)); - break; - } - default: - bt_common_abort(); - } + int ret = 0; + const char *pathstr; + struct ctf_field_path target_field_path; + struct ctf_field_class *target_fc = NULL; + GString *target_field_path_pretty = NULL; + const char *target_field_path_pretty_str; + + ctf_field_path_init(&target_field_path); + + /* Get path string */ + switch (fc->type) { + case CTF_FIELD_CLASS_TYPE_SEQUENCE: + { + struct ctf_field_class_sequence *seq_fc = ctf_field_class_as_sequence(fc); + pathstr = seq_fc->length_ref->str; + break; + } + case CTF_FIELD_CLASS_TYPE_VARIANT: + { + struct ctf_field_class_variant *var_fc = ctf_field_class_as_variant(fc); + pathstr = var_fc->tag_ref->str; + break; + } + default: + bt_common_abort(); + } + + if (!pathstr) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot get path string."); + ret = -1; + goto end; + } + + /* Get target field path out of path string */ + ret = pathstr_to_field_path(pathstr, &target_field_path, ctx); + if (ret) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot get target field path for path string: " + "path=\"%s\"", + pathstr); + goto end; + } + + target_field_path_pretty = ctf_field_path_string(&target_field_path); + target_field_path_pretty_str = target_field_path_pretty ? target_field_path_pretty->str : NULL; + + /* Get target field class */ + target_fc = field_path_to_field_class(&target_field_path, ctx); + if (!target_fc) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot get target field class for path string: " + "path=\"%s\", target-field-path=\"%s\"", + pathstr, target_field_path_pretty_str); + ret = -1; + goto end; + } + + ret = validate_target_field_path(&target_field_path, target_fc, ctx); + if (ret) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid target field path for path string: " + "path=\"%s\", target-field-path=\"%s\"", + pathstr, target_field_path_pretty_str); + goto end; + } + + /* Set target field path and target field class */ + switch (fc->type) { + case CTF_FIELD_CLASS_TYPE_SEQUENCE: + { + ctf_field_class_sequence *seq_fc = ctf_field_class_as_sequence(fc); + + ctf_field_path_copy_content(&seq_fc->length_path, &target_field_path); + seq_fc->length_fc = ctf_field_class_as_int(target_fc); + break; + } + case CTF_FIELD_CLASS_TYPE_VARIANT: + { + ctf_field_class_variant *var_fc = ctf_field_class_as_variant(fc); + + ctf_field_path_copy_content(&var_fc->tag_path, &target_field_path); + ctf_field_class_variant_set_tag_field_class(var_fc, ctf_field_class_as_enum(target_fc)); + break; + } + default: + bt_common_abort(); + } end: - if (target_field_path_pretty) { - g_string_free(target_field_path_pretty, TRUE); - } + if (target_field_path_pretty) { + g_string_free(target_field_path_pretty, TRUE); + } - ctf_field_path_fini(&target_field_path); - return ret; + ctf_field_path_fini(&target_field_path); + return ret; } /* * Resolves a field class `fc`. */ -static -int resolve_field_class(struct ctf_field_class *fc, struct resolve_context *ctx) +static int resolve_field_class(struct ctf_field_class *fc, struct resolve_context *ctx) { - int ret = 0; - - if (!fc) { - /* Field class is not available; still valid */ - goto end; - } - - ctx->cur_fc = fc; - - /* Resolve sequence/variant field class */ - switch (fc->type) { - case CTF_FIELD_CLASS_TYPE_SEQUENCE: - case CTF_FIELD_CLASS_TYPE_VARIANT: - ret = resolve_sequence_or_variant_field_class(fc, ctx); - if (ret) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot resolve sequence field class's length or variant field class's tag: " - "ret=%d, fc-addr=%p", ret, fc); - goto end; - } - - break; - default: - break; - } - - /* Recurse into compound classes */ - switch (fc->type) { - case CTF_FIELD_CLASS_TYPE_STRUCT: - case CTF_FIELD_CLASS_TYPE_VARIANT: - case CTF_FIELD_CLASS_TYPE_SEQUENCE: - case CTF_FIELD_CLASS_TYPE_ARRAY: - { - uint64_t i; - uint64_t field_count = - ctf_field_class_compound_get_field_class_count(fc); - - ret = field_class_stack_push(ctx->field_class_stack, fc, ctx); - if (ret) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot push field class on context's stack: " - "fc-addr=%p", fc); - goto end; - } - - for (i = 0; i < field_count; i++) { - struct ctf_field_class *child_fc = - ctf_field_class_compound_borrow_field_class_by_index( - fc, i); - - BT_ASSERT(child_fc); - - if (fc->type == CTF_FIELD_CLASS_TYPE_ARRAY|| - fc->type == CTF_FIELD_CLASS_TYPE_SEQUENCE) { - field_class_stack_peek( - ctx->field_class_stack)->index = -1; - } else { - field_class_stack_peek( - ctx->field_class_stack)->index = - (int64_t) i; - } - - BT_COMP_LOGD("Resolving field class's child field class: " - "parent-fc-addr=%p, child-fc-addr=%p, " - "index=%" PRIu64 ", count=%" PRIu64, - fc, child_fc, i, field_count); - ret = resolve_field_class(child_fc, ctx); - if (ret) { - goto end; - } - } - - field_class_stack_pop(ctx->field_class_stack, ctx); - break; - } - default: - break; - } + int ret = 0; + + if (!fc) { + /* Field class is not available; still valid */ + goto end; + } + + ctx->cur_fc = fc; + + /* Resolve sequence/variant field class */ + switch (fc->type) { + case CTF_FIELD_CLASS_TYPE_SEQUENCE: + case CTF_FIELD_CLASS_TYPE_VARIANT: + ret = resolve_sequence_or_variant_field_class(fc, ctx); + if (ret) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Cannot resolve sequence field class's length or variant field class's tag: " + "ret=%d, fc-addr=%p", + ret, fc); + goto end; + } + + break; + default: + break; + } + + /* Recurse into compound classes */ + switch (fc->type) { + case CTF_FIELD_CLASS_TYPE_STRUCT: + case CTF_FIELD_CLASS_TYPE_VARIANT: + case CTF_FIELD_CLASS_TYPE_SEQUENCE: + case CTF_FIELD_CLASS_TYPE_ARRAY: + { + uint64_t i; + uint64_t field_count = ctf_field_class_compound_get_field_class_count(fc); + + ret = field_class_stack_push(ctx->field_class_stack, fc, ctx); + if (ret) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot push field class on context's stack: " + "fc-addr=%p", + fc); + goto end; + } + + for (i = 0; i < field_count; i++) { + struct ctf_field_class *child_fc = + ctf_field_class_compound_borrow_field_class_by_index(fc, i); + + BT_ASSERT(child_fc); + + if (fc->type == CTF_FIELD_CLASS_TYPE_ARRAY || + fc->type == CTF_FIELD_CLASS_TYPE_SEQUENCE) { + field_class_stack_peek(ctx->field_class_stack)->index = -1; + } else { + field_class_stack_peek(ctx->field_class_stack)->index = (int64_t) i; + } + + BT_COMP_LOGD("Resolving field class's child field class: " + "parent-fc-addr=%p, child-fc-addr=%p, " + "index=%" PRIu64 ", count=%" PRIu64, + fc, child_fc, i, field_count); + ret = resolve_field_class(child_fc, ctx); + if (ret) { + goto end; + } + } + + field_class_stack_pop(ctx->field_class_stack, ctx); + break; + } + default: + break; + } end: - return ret; + return ret; } /* * Resolves the root field class corresponding to the scope `root_scope`. */ -static -int resolve_root_class(enum ctf_scope root_scope, struct resolve_context *ctx) +static int resolve_root_class(enum ctf_scope root_scope, struct resolve_context *ctx) { - int ret; + int ret; - BT_ASSERT(field_class_stack_size(ctx->field_class_stack) == 0); - ctx->root_scope = root_scope; - ret = resolve_field_class(borrow_class_from_ctx(ctx, root_scope), ctx); - ctx->root_scope = CTF_SCOPE_PACKET_UNKNOWN; - return ret; + BT_ASSERT(field_class_stack_size(ctx->field_class_stack) == 0); + ctx->root_scope = root_scope; + ret = resolve_field_class(borrow_class_from_ctx(ctx, root_scope), ctx); + ctx->root_scope = CTF_SCOPE_PACKET_UNKNOWN; + return ret; } -static -int resolve_event_class_field_classes(struct resolve_context *ctx, - struct ctf_event_class *ec) +static int resolve_event_class_field_classes(struct resolve_context *ctx, + struct ctf_event_class *ec) { - int ret = 0; - - BT_ASSERT(!ctx->scopes.event_spec_context); - BT_ASSERT(!ctx->scopes.event_payload); - - if (ec->is_translated) { - goto end; - } - - ctx->ec = ec; - ctx->scopes.event_spec_context = ec->spec_context_fc; - ret = resolve_root_class(CTF_SCOPE_EVENT_COMMON_CONTEXT, ctx); - if (ret) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot resolve event specific context field class: " - "ret=%d", ret); - goto end; - } - - ctx->scopes.event_payload = ec->payload_fc; - ret = resolve_root_class(CTF_SCOPE_EVENT_PAYLOAD, ctx); - if (ret) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot resolve event payload field class: " - "ret=%d", ret); - goto end; - } + int ret = 0; + + BT_ASSERT(!ctx->scopes.event_spec_context); + BT_ASSERT(!ctx->scopes.event_payload); + + if (ec->is_translated) { + goto end; + } + + ctx->ec = ec; + ctx->scopes.event_spec_context = ec->spec_context_fc; + ret = resolve_root_class(CTF_SCOPE_EVENT_COMMON_CONTEXT, ctx); + if (ret) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Cannot resolve event specific context field class: " + "ret=%d", + ret); + goto end; + } + + ctx->scopes.event_payload = ec->payload_fc; + ret = resolve_root_class(CTF_SCOPE_EVENT_PAYLOAD, ctx); + if (ret) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot resolve event payload field class: " + "ret=%d", + ret); + goto end; + } end: - ctx->scopes.event_spec_context = NULL; - ctx->scopes.event_payload = NULL; - ctx->ec = NULL; - return ret; + ctx->scopes.event_spec_context = NULL; + ctx->scopes.event_payload = NULL; + ctx->ec = NULL; + return ret; } -static -int resolve_stream_class_field_classes(struct resolve_context *ctx, - struct ctf_stream_class *sc) +static int resolve_stream_class_field_classes(struct resolve_context *ctx, + struct ctf_stream_class *sc) { - int ret = 0; - uint64_t i; - - BT_ASSERT(!ctx->scopes.packet_context); - BT_ASSERT(!ctx->scopes.event_header); - BT_ASSERT(!ctx->scopes.event_common_context); - ctx->sc = sc; - - if (!sc->is_translated) { - ctx->scopes.packet_context = sc->packet_context_fc; - ret = resolve_root_class(CTF_SCOPE_PACKET_CONTEXT, ctx); - if (ret) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot resolve packet context field class: " - "ret=%d", ret); - goto end; - } - - ctx->scopes.event_header = sc->event_header_fc; - ret = resolve_root_class(CTF_SCOPE_EVENT_HEADER, ctx); - if (ret) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot resolve event header field class: " - "ret=%d", ret); - goto end; - } - - ctx->scopes.event_common_context = sc->event_common_context_fc; - ret = resolve_root_class(CTF_SCOPE_EVENT_COMMON_CONTEXT, ctx); - if (ret) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot resolve event common context field class: " - "ret=%d", ret); - goto end; - } - } - - ctx->scopes.packet_context = sc->packet_context_fc; - ctx->scopes.event_header = sc->event_header_fc; - ctx->scopes.event_common_context = sc->event_common_context_fc; - - for (i = 0; i < sc->event_classes->len; i++) { - ctf_event_class *ec = (ctf_event_class *) sc->event_classes->pdata[i]; - - ret = resolve_event_class_field_classes(ctx, ec); - if (ret) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot resolve event class's field classes: " - "ec-id=%" PRIu64 ", ec-name=\"%s\"", - ec->id, ec->name->str); - goto end; - } - } + int ret = 0; + uint64_t i; + + BT_ASSERT(!ctx->scopes.packet_context); + BT_ASSERT(!ctx->scopes.event_header); + BT_ASSERT(!ctx->scopes.event_common_context); + ctx->sc = sc; + + if (!sc->is_translated) { + ctx->scopes.packet_context = sc->packet_context_fc; + ret = resolve_root_class(CTF_SCOPE_PACKET_CONTEXT, ctx); + if (ret) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot resolve packet context field class: " + "ret=%d", + ret); + goto end; + } + + ctx->scopes.event_header = sc->event_header_fc; + ret = resolve_root_class(CTF_SCOPE_EVENT_HEADER, ctx); + if (ret) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot resolve event header field class: " + "ret=%d", + ret); + goto end; + } + + ctx->scopes.event_common_context = sc->event_common_context_fc; + ret = resolve_root_class(CTF_SCOPE_EVENT_COMMON_CONTEXT, ctx); + if (ret) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Cannot resolve event common context field class: " + "ret=%d", + ret); + goto end; + } + } + + ctx->scopes.packet_context = sc->packet_context_fc; + ctx->scopes.event_header = sc->event_header_fc; + ctx->scopes.event_common_context = sc->event_common_context_fc; + + for (i = 0; i < sc->event_classes->len; i++) { + ctf_event_class *ec = (ctf_event_class *) sc->event_classes->pdata[i]; + + ret = resolve_event_class_field_classes(ctx, ec); + if (ret) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot resolve event class's field classes: " + "ec-id=%" PRIu64 ", ec-name=\"%s\"", + ec->id, ec->name->str); + goto end; + } + } end: - ctx->scopes.packet_context = NULL; - ctx->scopes.event_header = NULL; - ctx->scopes.event_common_context = NULL; - ctx->sc = NULL; - return ret; + ctx->scopes.packet_context = NULL; + ctx->scopes.event_header = NULL; + ctx->scopes.event_common_context = NULL; + ctx->sc = NULL; + return ret; } BT_HIDDEN int ctf_trace_class_resolve_field_classes(struct ctf_trace_class *tc, - struct meta_log_config *log_cfg) + struct meta_log_config *log_cfg) { - int ret = 0; - uint64_t i; - - resolve_context local_ctx{}; - local_ctx.log_level = log_cfg->log_level; - local_ctx.self_comp = log_cfg->self_comp; - local_ctx.self_comp_class = log_cfg->self_comp_class; - local_ctx.tc = tc; - local_ctx.scopes.packet_header = tc->packet_header_fc; - local_ctx.root_scope = CTF_SCOPE_PACKET_HEADER; - - struct resolve_context *ctx = &local_ctx; - - /* Initialize class stack */ - ctx->field_class_stack = field_class_stack_create(); - if (!ctx->field_class_stack) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot create field class stack."); - ret = -1; - goto end; - } - - if (!tc->is_translated) { - ctx->scopes.packet_header = tc->packet_header_fc; - ret = resolve_root_class(CTF_SCOPE_PACKET_HEADER, ctx); - if (ret) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot resolve packet header field class: " - "ret=%d", ret); - goto end; - } - } - - ctx->scopes.packet_header = tc->packet_header_fc; - - for (i = 0; i < tc->stream_classes->len; i++) { - ctf_stream_class *sc = (ctf_stream_class *) tc->stream_classes->pdata[i]; - - ret = resolve_stream_class_field_classes(ctx, sc); - if (ret) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot resolve stream class's field classes: " - "sc-id=%" PRIu64, sc->id); - goto end; - } - } + int ret = 0; + uint64_t i; + + resolve_context local_ctx {}; + local_ctx.log_level = log_cfg->log_level; + local_ctx.self_comp = log_cfg->self_comp; + local_ctx.self_comp_class = log_cfg->self_comp_class; + local_ctx.tc = tc; + local_ctx.scopes.packet_header = tc->packet_header_fc; + local_ctx.root_scope = CTF_SCOPE_PACKET_HEADER; + + struct resolve_context *ctx = &local_ctx; + + /* Initialize class stack */ + ctx->field_class_stack = field_class_stack_create(); + if (!ctx->field_class_stack) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot create field class stack."); + ret = -1; + goto end; + } + + if (!tc->is_translated) { + ctx->scopes.packet_header = tc->packet_header_fc; + ret = resolve_root_class(CTF_SCOPE_PACKET_HEADER, ctx); + if (ret) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot resolve packet header field class: " + "ret=%d", + ret); + goto end; + } + } + + ctx->scopes.packet_header = tc->packet_header_fc; + + for (i = 0; i < tc->stream_classes->len; i++) { + ctf_stream_class *sc = (ctf_stream_class *) tc->stream_classes->pdata[i]; + + ret = resolve_stream_class_field_classes(ctx, sc); + if (ret) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot resolve stream class's field classes: " + "sc-id=%" PRIu64, + sc->id); + goto end; + } + } end: - field_class_stack_destroy(ctx->field_class_stack); - return ret; + field_class_stack_destroy(ctx->field_class_stack); + return ret; } diff --git a/src/plugins/ctf/common/metadata/ctf-meta-translate.cpp b/src/plugins/ctf/common/metadata/ctf-meta-translate.cpp index 0d66dace..c39948ee 100644 --- a/src/plugins/ctf/common/metadata/ctf-meta-translate.cpp +++ b/src/plugins/ctf/common/metadata/ctf-meta-translate.cpp @@ -15,693 +15,641 @@ #include "ctf-meta-visitors.hpp" -struct ctx { - bt_self_component *self_comp; - bt_trace_class *ir_tc; - bt_stream_class *ir_sc; - struct ctf_trace_class *tc; - struct ctf_stream_class *sc; - struct ctf_event_class *ec; - enum ctf_scope scope; +struct ctx +{ + bt_self_component *self_comp; + bt_trace_class *ir_tc; + bt_stream_class *ir_sc; + struct ctf_trace_class *tc; + struct ctf_stream_class *sc; + struct ctf_event_class *ec; + enum ctf_scope scope; }; -static inline -bt_field_class *ctf_field_class_to_ir(struct ctx *ctx, - struct ctf_field_class *fc); +static inline bt_field_class *ctf_field_class_to_ir(struct ctx *ctx, struct ctf_field_class *fc); -static inline -void ctf_field_class_int_set_props(struct ctf_field_class_int *fc, - bt_field_class *ir_fc) +static inline void ctf_field_class_int_set_props(struct ctf_field_class_int *fc, + bt_field_class *ir_fc) { - bt_field_class_integer_set_field_value_range(ir_fc, - fc->base.size); - bt_field_class_integer_set_preferred_display_base(ir_fc, - fc->disp_base); + bt_field_class_integer_set_field_value_range(ir_fc, fc->base.size); + bt_field_class_integer_set_preferred_display_base(ir_fc, fc->disp_base); } -static inline -bt_field_class *ctf_field_class_int_to_ir(struct ctx *ctx, - struct ctf_field_class_int *fc) +static inline bt_field_class *ctf_field_class_int_to_ir(struct ctx *ctx, + struct ctf_field_class_int *fc) { - bt_field_class *ir_fc; + bt_field_class *ir_fc; - if (fc->is_signed) { - ir_fc = bt_field_class_integer_signed_create(ctx->ir_tc); - } else { - ir_fc = bt_field_class_integer_unsigned_create(ctx->ir_tc); - } + if (fc->is_signed) { + ir_fc = bt_field_class_integer_signed_create(ctx->ir_tc); + } else { + ir_fc = bt_field_class_integer_unsigned_create(ctx->ir_tc); + } - BT_ASSERT(ir_fc); - ctf_field_class_int_set_props(fc, ir_fc); - return ir_fc; + BT_ASSERT(ir_fc); + ctf_field_class_int_set_props(fc, ir_fc); + return ir_fc; } -static inline -bt_field_class *ctf_field_class_enum_to_ir(struct ctx *ctx, - struct ctf_field_class_enum *fc) +static inline bt_field_class *ctf_field_class_enum_to_ir(struct ctx *ctx, + struct ctf_field_class_enum *fc) { - int ret; - bt_field_class *ir_fc; - uint64_t i; - - if (fc->base.is_signed) { - ir_fc = bt_field_class_enumeration_signed_create(ctx->ir_tc); - } else { - ir_fc = bt_field_class_enumeration_unsigned_create(ctx->ir_tc); - } - - BT_ASSERT(ir_fc); - ctf_field_class_int_set_props(&fc->base, ir_fc); - - for (i = 0; i < fc->mappings->len; i++) { - struct ctf_field_class_enum_mapping *mapping = - ctf_field_class_enum_borrow_mapping_by_index(fc, i); - bt_integer_range_set_signed *range_set_signed = NULL; - bt_integer_range_set_unsigned *range_set_unsigned = NULL; - uint64_t range_i; - - if (fc->base.is_signed) { - range_set_signed = bt_integer_range_set_signed_create(); - BT_ASSERT(range_set_signed); - } else { - range_set_unsigned = bt_integer_range_set_unsigned_create(); - BT_ASSERT(range_set_unsigned); - } - - for (range_i = 0; range_i < mapping->ranges->len; range_i++) { - struct ctf_range *range = - ctf_field_class_enum_mapping_borrow_range_by_index( - mapping, range_i); - - if (fc->base.is_signed) { - ret = bt_integer_range_set_signed_add_range( - range_set_signed, range->lower.i, - range->upper.i); - } else { - ret = bt_integer_range_set_unsigned_add_range( - range_set_unsigned, range->lower.u, - range->upper.u); - } - - BT_ASSERT(ret == 0); - } - - if (fc->base.is_signed) { - ret = bt_field_class_enumeration_signed_add_mapping( - ir_fc, mapping->label->str, range_set_signed); - BT_INTEGER_RANGE_SET_SIGNED_PUT_REF_AND_RESET(range_set_signed); - } else { - ret = bt_field_class_enumeration_unsigned_add_mapping( - ir_fc, mapping->label->str, range_set_unsigned); - BT_INTEGER_RANGE_SET_UNSIGNED_PUT_REF_AND_RESET(range_set_unsigned); - } - - BT_ASSERT(ret == 0); - } - - return ir_fc; + int ret; + bt_field_class *ir_fc; + uint64_t i; + + if (fc->base.is_signed) { + ir_fc = bt_field_class_enumeration_signed_create(ctx->ir_tc); + } else { + ir_fc = bt_field_class_enumeration_unsigned_create(ctx->ir_tc); + } + + BT_ASSERT(ir_fc); + ctf_field_class_int_set_props(&fc->base, ir_fc); + + for (i = 0; i < fc->mappings->len; i++) { + struct ctf_field_class_enum_mapping *mapping = + ctf_field_class_enum_borrow_mapping_by_index(fc, i); + bt_integer_range_set_signed *range_set_signed = NULL; + bt_integer_range_set_unsigned *range_set_unsigned = NULL; + uint64_t range_i; + + if (fc->base.is_signed) { + range_set_signed = bt_integer_range_set_signed_create(); + BT_ASSERT(range_set_signed); + } else { + range_set_unsigned = bt_integer_range_set_unsigned_create(); + BT_ASSERT(range_set_unsigned); + } + + for (range_i = 0; range_i < mapping->ranges->len; range_i++) { + struct ctf_range *range = + ctf_field_class_enum_mapping_borrow_range_by_index(mapping, range_i); + + if (fc->base.is_signed) { + ret = bt_integer_range_set_signed_add_range(range_set_signed, range->lower.i, + range->upper.i); + } else { + ret = bt_integer_range_set_unsigned_add_range(range_set_unsigned, range->lower.u, + range->upper.u); + } + + BT_ASSERT(ret == 0); + } + + if (fc->base.is_signed) { + ret = bt_field_class_enumeration_signed_add_mapping(ir_fc, mapping->label->str, + range_set_signed); + BT_INTEGER_RANGE_SET_SIGNED_PUT_REF_AND_RESET(range_set_signed); + } else { + ret = bt_field_class_enumeration_unsigned_add_mapping(ir_fc, mapping->label->str, + range_set_unsigned); + BT_INTEGER_RANGE_SET_UNSIGNED_PUT_REF_AND_RESET(range_set_unsigned); + } + + BT_ASSERT(ret == 0); + } + + return ir_fc; } -static inline -bt_field_class *ctf_field_class_float_to_ir(struct ctx *ctx, - struct ctf_field_class_float *fc) +static inline bt_field_class *ctf_field_class_float_to_ir(struct ctx *ctx, + struct ctf_field_class_float *fc) { - bt_field_class *ir_fc; + bt_field_class *ir_fc; - if (fc->base.size == 32) { - ir_fc = bt_field_class_real_single_precision_create(ctx->ir_tc); - } else { - ir_fc = bt_field_class_real_double_precision_create(ctx->ir_tc); - } - BT_ASSERT(ir_fc); + if (fc->base.size == 32) { + ir_fc = bt_field_class_real_single_precision_create(ctx->ir_tc); + } else { + ir_fc = bt_field_class_real_double_precision_create(ctx->ir_tc); + } + BT_ASSERT(ir_fc); - return ir_fc; + return ir_fc; } -static inline -bt_field_class *ctf_field_class_string_to_ir(struct ctx *ctx, - struct ctf_field_class_string *fc) +static inline bt_field_class *ctf_field_class_string_to_ir(struct ctx *ctx, + struct ctf_field_class_string *fc) { - bt_field_class *ir_fc = bt_field_class_string_create(ctx->ir_tc); + bt_field_class *ir_fc = bt_field_class_string_create(ctx->ir_tc); - BT_ASSERT(ir_fc); - return ir_fc; + BT_ASSERT(ir_fc); + return ir_fc; } -static inline -void translate_struct_field_class_members(struct ctx *ctx, - struct ctf_field_class_struct *fc, bt_field_class *ir_fc, - bool with_header_prefix, - struct ctf_field_class_struct *context_fc) +static inline void translate_struct_field_class_members(struct ctx *ctx, + struct ctf_field_class_struct *fc, + bt_field_class *ir_fc, + bool with_header_prefix, + struct ctf_field_class_struct *context_fc) { - uint64_t i; - int ret; - - for (i = 0; i < fc->members->len; i++) { - struct ctf_named_field_class *named_fc = - ctf_field_class_struct_borrow_member_by_index(fc, i); - bt_field_class *member_ir_fc; - const char *name = named_fc->name->str; - - if (!named_fc->fc->in_ir) { - continue; - } - - member_ir_fc = ctf_field_class_to_ir(ctx, named_fc->fc); - BT_ASSERT(member_ir_fc); - ret = bt_field_class_structure_append_member(ir_fc, name, - member_ir_fc); - BT_ASSERT(ret == 0); - bt_field_class_put_ref(member_ir_fc); - } + uint64_t i; + int ret; + + for (i = 0; i < fc->members->len; i++) { + struct ctf_named_field_class *named_fc = + ctf_field_class_struct_borrow_member_by_index(fc, i); + bt_field_class *member_ir_fc; + const char *name = named_fc->name->str; + + if (!named_fc->fc->in_ir) { + continue; + } + + member_ir_fc = ctf_field_class_to_ir(ctx, named_fc->fc); + BT_ASSERT(member_ir_fc); + ret = bt_field_class_structure_append_member(ir_fc, name, member_ir_fc); + BT_ASSERT(ret == 0); + bt_field_class_put_ref(member_ir_fc); + } } -static inline -bt_field_class *ctf_field_class_struct_to_ir(struct ctx *ctx, - struct ctf_field_class_struct *fc) +static inline bt_field_class *ctf_field_class_struct_to_ir(struct ctx *ctx, + struct ctf_field_class_struct *fc) { - bt_field_class *ir_fc = bt_field_class_structure_create(ctx->ir_tc); + bt_field_class *ir_fc = bt_field_class_structure_create(ctx->ir_tc); - BT_ASSERT(ir_fc); - translate_struct_field_class_members(ctx, fc, ir_fc, false, NULL); - return ir_fc; + BT_ASSERT(ir_fc); + translate_struct_field_class_members(ctx, fc, ir_fc, false, NULL); + return ir_fc; } -static inline -bt_field_class *borrow_ir_fc_from_field_path(struct ctx *ctx, - struct ctf_field_path *field_path) +static inline bt_field_class *borrow_ir_fc_from_field_path(struct ctx *ctx, + struct ctf_field_path *field_path) { - bt_field_class *ir_fc = NULL; - struct ctf_field_class *fc = ctf_field_path_borrow_field_class( - field_path, ctx->tc, ctx->sc, ctx->ec); + bt_field_class *ir_fc = NULL; + struct ctf_field_class *fc = + ctf_field_path_borrow_field_class(field_path, ctx->tc, ctx->sc, ctx->ec); - BT_ASSERT(fc); + BT_ASSERT(fc); - if (fc->in_ir) { - ir_fc = fc->ir_fc; - } + if (fc->in_ir) { + ir_fc = fc->ir_fc; + } - return ir_fc; + return ir_fc; } -static inline -const bt_field_class_enumeration_mapping *find_ir_enum_field_class_mapping_by_label( - const bt_field_class *fc, const char *label, bool is_signed) +static inline const bt_field_class_enumeration_mapping * +find_ir_enum_field_class_mapping_by_label(const bt_field_class *fc, const char *label, + bool is_signed) { - const bt_field_class_enumeration_mapping *mapping = NULL; - uint64_t i; - - for (i = 0; i < bt_field_class_enumeration_get_mapping_count(fc); i++) { - const bt_field_class_enumeration_mapping *this_mapping; - const bt_field_class_enumeration_signed_mapping *signed_this_mapping = NULL; - const bt_field_class_enumeration_unsigned_mapping *unsigned_this_mapping = NULL; - - if (is_signed) { - signed_this_mapping = - bt_field_class_enumeration_signed_borrow_mapping_by_index_const( - fc, i); - BT_ASSERT(signed_this_mapping); - this_mapping = - bt_field_class_enumeration_signed_mapping_as_mapping_const( - signed_this_mapping); - } else { - unsigned_this_mapping = - bt_field_class_enumeration_unsigned_borrow_mapping_by_index_const( - fc, i); - BT_ASSERT(unsigned_this_mapping); - this_mapping = - bt_field_class_enumeration_unsigned_mapping_as_mapping_const( - unsigned_this_mapping); - } - - BT_ASSERT(this_mapping); - - if (strcmp(bt_field_class_enumeration_mapping_get_label( - this_mapping), label) == 0) { - mapping = this_mapping; - goto end; - } - } + const bt_field_class_enumeration_mapping *mapping = NULL; + uint64_t i; + + for (i = 0; i < bt_field_class_enumeration_get_mapping_count(fc); i++) { + const bt_field_class_enumeration_mapping *this_mapping; + const bt_field_class_enumeration_signed_mapping *signed_this_mapping = NULL; + const bt_field_class_enumeration_unsigned_mapping *unsigned_this_mapping = NULL; + + if (is_signed) { + signed_this_mapping = + bt_field_class_enumeration_signed_borrow_mapping_by_index_const(fc, i); + BT_ASSERT(signed_this_mapping); + this_mapping = + bt_field_class_enumeration_signed_mapping_as_mapping_const(signed_this_mapping); + } else { + unsigned_this_mapping = + bt_field_class_enumeration_unsigned_borrow_mapping_by_index_const(fc, i); + BT_ASSERT(unsigned_this_mapping); + this_mapping = + bt_field_class_enumeration_unsigned_mapping_as_mapping_const(unsigned_this_mapping); + } + + BT_ASSERT(this_mapping); + + if (strcmp(bt_field_class_enumeration_mapping_get_label(this_mapping), label) == 0) { + mapping = this_mapping; + goto end; + } + } end: - return mapping; + return mapping; } -static inline -bt_field_class *ctf_field_class_variant_to_ir(struct ctx *ctx, - struct ctf_field_class_variant *fc) +static inline bt_field_class *ctf_field_class_variant_to_ir(struct ctx *ctx, + struct ctf_field_class_variant *fc) { - int ret; - bt_field_class *ir_fc; - uint64_t i; - bt_field_class *ir_tag_fc = NULL; - - if (fc->tag_path.root != CTF_SCOPE_PACKET_HEADER && - fc->tag_path.root != CTF_SCOPE_EVENT_HEADER) { - ir_tag_fc = borrow_ir_fc_from_field_path(ctx, &fc->tag_path); - BT_ASSERT(ir_tag_fc); - } - - ir_fc = bt_field_class_variant_create(ctx->ir_tc, ir_tag_fc); - BT_ASSERT(ir_fc); - - for (i = 0; i < fc->options->len; i++) { - struct ctf_named_field_class *named_fc = - ctf_field_class_variant_borrow_option_by_index(fc, i); - bt_field_class *option_ir_fc; - - BT_ASSERT(named_fc->fc->in_ir); - option_ir_fc = ctf_field_class_to_ir(ctx, named_fc->fc); - BT_ASSERT(option_ir_fc); - - if (ir_tag_fc) { - /* - * At this point the trace IR selector - * (enumeration) field class already exists if - * the variant is tagged (`ir_tag_fc`). This one - * already contains range sets for its mappings, - * so we just reuse the same, finding them by - * matching a variant field class's option's - * _original_ name (with a leading underscore, - * possibly) with a selector field class's - * mapping name. - */ - if (fc->tag_fc->base.is_signed) { - const bt_field_class_enumeration_signed_mapping *mapping = - (bt_field_class_enumeration_signed_mapping *) - find_ir_enum_field_class_mapping_by_label( - ir_tag_fc, - named_fc->orig_name->str, true); - const bt_integer_range_set_signed *range_set; - - BT_ASSERT(mapping); - range_set = - bt_field_class_enumeration_signed_mapping_borrow_ranges_const( - mapping); - BT_ASSERT(range_set); - ret = bt_field_class_variant_with_selector_field_integer_signed_append_option( - ir_fc, named_fc->name->str, - option_ir_fc, range_set); - } else { - const bt_field_class_enumeration_unsigned_mapping *mapping = - (bt_field_class_enumeration_unsigned_mapping *) - find_ir_enum_field_class_mapping_by_label( - ir_tag_fc, - named_fc->orig_name->str, - false); - const bt_integer_range_set_unsigned *range_set; - - BT_ASSERT(mapping); - range_set = - bt_field_class_enumeration_unsigned_mapping_borrow_ranges_const( - mapping); - BT_ASSERT(range_set); - ret = bt_field_class_variant_with_selector_field_integer_unsigned_append_option( - ir_fc, named_fc->name->str, - option_ir_fc, range_set); - } - } else { - ret = bt_field_class_variant_without_selector_append_option( - ir_fc, named_fc->name->str, option_ir_fc); - } - - BT_ASSERT(ret == 0); - bt_field_class_put_ref(option_ir_fc); - } - - return ir_fc; + int ret; + bt_field_class *ir_fc; + uint64_t i; + bt_field_class *ir_tag_fc = NULL; + + if (fc->tag_path.root != CTF_SCOPE_PACKET_HEADER && + fc->tag_path.root != CTF_SCOPE_EVENT_HEADER) { + ir_tag_fc = borrow_ir_fc_from_field_path(ctx, &fc->tag_path); + BT_ASSERT(ir_tag_fc); + } + + ir_fc = bt_field_class_variant_create(ctx->ir_tc, ir_tag_fc); + BT_ASSERT(ir_fc); + + for (i = 0; i < fc->options->len; i++) { + struct ctf_named_field_class *named_fc = + ctf_field_class_variant_borrow_option_by_index(fc, i); + bt_field_class *option_ir_fc; + + BT_ASSERT(named_fc->fc->in_ir); + option_ir_fc = ctf_field_class_to_ir(ctx, named_fc->fc); + BT_ASSERT(option_ir_fc); + + if (ir_tag_fc) { + /* + * At this point the trace IR selector + * (enumeration) field class already exists if + * the variant is tagged (`ir_tag_fc`). This one + * already contains range sets for its mappings, + * so we just reuse the same, finding them by + * matching a variant field class's option's + * _original_ name (with a leading underscore, + * possibly) with a selector field class's + * mapping name. + */ + if (fc->tag_fc->base.is_signed) { + const bt_field_class_enumeration_signed_mapping *mapping = + (bt_field_class_enumeration_signed_mapping *) + find_ir_enum_field_class_mapping_by_label(ir_tag_fc, + named_fc->orig_name->str, true); + const bt_integer_range_set_signed *range_set; + + BT_ASSERT(mapping); + range_set = bt_field_class_enumeration_signed_mapping_borrow_ranges_const(mapping); + BT_ASSERT(range_set); + ret = bt_field_class_variant_with_selector_field_integer_signed_append_option( + ir_fc, named_fc->name->str, option_ir_fc, range_set); + } else { + const bt_field_class_enumeration_unsigned_mapping *mapping = + (bt_field_class_enumeration_unsigned_mapping *) + find_ir_enum_field_class_mapping_by_label(ir_tag_fc, + named_fc->orig_name->str, false); + const bt_integer_range_set_unsigned *range_set; + + BT_ASSERT(mapping); + range_set = + bt_field_class_enumeration_unsigned_mapping_borrow_ranges_const(mapping); + BT_ASSERT(range_set); + ret = bt_field_class_variant_with_selector_field_integer_unsigned_append_option( + ir_fc, named_fc->name->str, option_ir_fc, range_set); + } + } else { + ret = bt_field_class_variant_without_selector_append_option(ir_fc, named_fc->name->str, + option_ir_fc); + } + + BT_ASSERT(ret == 0); + bt_field_class_put_ref(option_ir_fc); + } + + return ir_fc; } -static inline -bt_field_class *ctf_field_class_array_to_ir(struct ctx *ctx, - struct ctf_field_class_array *fc) +static inline bt_field_class *ctf_field_class_array_to_ir(struct ctx *ctx, + struct ctf_field_class_array *fc) { - bt_field_class *ir_fc; - bt_field_class *elem_ir_fc; - - if (fc->base.is_text) { - ir_fc = bt_field_class_string_create(ctx->ir_tc); - BT_ASSERT(ir_fc); - goto end; - } - - elem_ir_fc = ctf_field_class_to_ir(ctx, fc->base.elem_fc); - BT_ASSERT(elem_ir_fc); - ir_fc = bt_field_class_array_static_create(ctx->ir_tc, elem_ir_fc, - fc->length); - BT_ASSERT(ir_fc); - bt_field_class_put_ref(elem_ir_fc); + bt_field_class *ir_fc; + bt_field_class *elem_ir_fc; + + if (fc->base.is_text) { + ir_fc = bt_field_class_string_create(ctx->ir_tc); + BT_ASSERT(ir_fc); + goto end; + } + + elem_ir_fc = ctf_field_class_to_ir(ctx, fc->base.elem_fc); + BT_ASSERT(elem_ir_fc); + ir_fc = bt_field_class_array_static_create(ctx->ir_tc, elem_ir_fc, fc->length); + BT_ASSERT(ir_fc); + bt_field_class_put_ref(elem_ir_fc); end: - return ir_fc; + return ir_fc; } -static inline -bt_field_class *ctf_field_class_sequence_to_ir(struct ctx *ctx, - struct ctf_field_class_sequence *fc) +static inline bt_field_class *ctf_field_class_sequence_to_ir(struct ctx *ctx, + struct ctf_field_class_sequence *fc) { - bt_field_class *ir_fc; - bt_field_class *elem_ir_fc; - bt_field_class *length_fc = NULL; - - if (fc->base.is_text) { - ir_fc = bt_field_class_string_create(ctx->ir_tc); - BT_ASSERT(ir_fc); - goto end; - } - - elem_ir_fc = ctf_field_class_to_ir(ctx, fc->base.elem_fc); - BT_ASSERT(elem_ir_fc); - - if (fc->length_path.root != CTF_SCOPE_PACKET_HEADER && - fc->length_path.root != CTF_SCOPE_EVENT_HEADER) { - length_fc = borrow_ir_fc_from_field_path(ctx, &fc->length_path); - BT_ASSERT(length_fc); - } - - ir_fc = bt_field_class_array_dynamic_create(ctx->ir_tc, elem_ir_fc, - length_fc); - BT_ASSERT(ir_fc); - bt_field_class_put_ref(elem_ir_fc); - BT_ASSERT(ir_fc); + bt_field_class *ir_fc; + bt_field_class *elem_ir_fc; + bt_field_class *length_fc = NULL; + + if (fc->base.is_text) { + ir_fc = bt_field_class_string_create(ctx->ir_tc); + BT_ASSERT(ir_fc); + goto end; + } + + elem_ir_fc = ctf_field_class_to_ir(ctx, fc->base.elem_fc); + BT_ASSERT(elem_ir_fc); + + if (fc->length_path.root != CTF_SCOPE_PACKET_HEADER && + fc->length_path.root != CTF_SCOPE_EVENT_HEADER) { + length_fc = borrow_ir_fc_from_field_path(ctx, &fc->length_path); + BT_ASSERT(length_fc); + } + + ir_fc = bt_field_class_array_dynamic_create(ctx->ir_tc, elem_ir_fc, length_fc); + BT_ASSERT(ir_fc); + bt_field_class_put_ref(elem_ir_fc); + BT_ASSERT(ir_fc); end: - return ir_fc; + return ir_fc; } -static inline -bt_field_class *ctf_field_class_to_ir(struct ctx *ctx, - struct ctf_field_class *fc) +static inline bt_field_class *ctf_field_class_to_ir(struct ctx *ctx, struct ctf_field_class *fc) { - bt_field_class *ir_fc = NULL; - - BT_ASSERT(fc); - BT_ASSERT(fc->in_ir); - - switch (fc->type) { - case CTF_FIELD_CLASS_TYPE_INT: - ir_fc = ctf_field_class_int_to_ir(ctx, ctf_field_class_as_int(fc)); - break; - case CTF_FIELD_CLASS_TYPE_ENUM: - ir_fc = ctf_field_class_enum_to_ir(ctx, ctf_field_class_as_enum(fc)); - break; - case CTF_FIELD_CLASS_TYPE_FLOAT: - ir_fc = ctf_field_class_float_to_ir(ctx, ctf_field_class_as_float(fc)); - break; - case CTF_FIELD_CLASS_TYPE_STRING: - ir_fc = ctf_field_class_string_to_ir(ctx, ctf_field_class_as_string(fc)); - break; - case CTF_FIELD_CLASS_TYPE_STRUCT: - ir_fc = ctf_field_class_struct_to_ir(ctx, ctf_field_class_as_struct(fc)); - break; - case CTF_FIELD_CLASS_TYPE_ARRAY: - ir_fc = ctf_field_class_array_to_ir(ctx, ctf_field_class_as_array(fc)); - break; - case CTF_FIELD_CLASS_TYPE_SEQUENCE: - ir_fc = ctf_field_class_sequence_to_ir(ctx, ctf_field_class_as_sequence(fc)); - break; - case CTF_FIELD_CLASS_TYPE_VARIANT: - ir_fc = ctf_field_class_variant_to_ir(ctx, ctf_field_class_as_variant(fc)); - break; - default: - bt_common_abort(); - } - - fc->ir_fc = ir_fc; - return ir_fc; + bt_field_class *ir_fc = NULL; + + BT_ASSERT(fc); + BT_ASSERT(fc->in_ir); + + switch (fc->type) { + case CTF_FIELD_CLASS_TYPE_INT: + ir_fc = ctf_field_class_int_to_ir(ctx, ctf_field_class_as_int(fc)); + break; + case CTF_FIELD_CLASS_TYPE_ENUM: + ir_fc = ctf_field_class_enum_to_ir(ctx, ctf_field_class_as_enum(fc)); + break; + case CTF_FIELD_CLASS_TYPE_FLOAT: + ir_fc = ctf_field_class_float_to_ir(ctx, ctf_field_class_as_float(fc)); + break; + case CTF_FIELD_CLASS_TYPE_STRING: + ir_fc = ctf_field_class_string_to_ir(ctx, ctf_field_class_as_string(fc)); + break; + case CTF_FIELD_CLASS_TYPE_STRUCT: + ir_fc = ctf_field_class_struct_to_ir(ctx, ctf_field_class_as_struct(fc)); + break; + case CTF_FIELD_CLASS_TYPE_ARRAY: + ir_fc = ctf_field_class_array_to_ir(ctx, ctf_field_class_as_array(fc)); + break; + case CTF_FIELD_CLASS_TYPE_SEQUENCE: + ir_fc = ctf_field_class_sequence_to_ir(ctx, ctf_field_class_as_sequence(fc)); + break; + case CTF_FIELD_CLASS_TYPE_VARIANT: + ir_fc = ctf_field_class_variant_to_ir(ctx, ctf_field_class_as_variant(fc)); + break; + default: + bt_common_abort(); + } + + fc->ir_fc = ir_fc; + return ir_fc; } -static inline -bool ctf_field_class_struct_has_immediate_member_in_ir( - struct ctf_field_class_struct *fc) +static inline bool +ctf_field_class_struct_has_immediate_member_in_ir(struct ctf_field_class_struct *fc) { - uint64_t i; - bool has_immediate_member_in_ir = false; - - /* - * If the structure field class has no members at all, then it - * was an empty structure in the beginning, so leave it existing - * and empty. - */ - if (fc->members->len == 0) { - has_immediate_member_in_ir = true; - goto end; - } - - for (i = 0; i < fc->members->len; i++) { - struct ctf_named_field_class *named_fc = - ctf_field_class_struct_borrow_member_by_index(fc, i); - - if (named_fc->fc->in_ir) { - has_immediate_member_in_ir = true; - goto end; - } - } + uint64_t i; + bool has_immediate_member_in_ir = false; + + /* + * If the structure field class has no members at all, then it + * was an empty structure in the beginning, so leave it existing + * and empty. + */ + if (fc->members->len == 0) { + has_immediate_member_in_ir = true; + goto end; + } + + for (i = 0; i < fc->members->len; i++) { + struct ctf_named_field_class *named_fc = + ctf_field_class_struct_borrow_member_by_index(fc, i); + + if (named_fc->fc->in_ir) { + has_immediate_member_in_ir = true; + goto end; + } + } end: - return has_immediate_member_in_ir; + return has_immediate_member_in_ir; } -static inline -bt_field_class *scope_ctf_field_class_to_ir(struct ctx *ctx) +static inline bt_field_class *scope_ctf_field_class_to_ir(struct ctx *ctx) { - bt_field_class *ir_fc = NULL; - struct ctf_field_class *fc = NULL; - - switch (ctx->scope) { - case CTF_SCOPE_PACKET_CONTEXT: - fc = ctx->sc->packet_context_fc; - break; - case CTF_SCOPE_EVENT_COMMON_CONTEXT: - fc = ctx->sc->event_common_context_fc; - break; - case CTF_SCOPE_EVENT_SPECIFIC_CONTEXT: - fc = ctx->ec->spec_context_fc; - break; - case CTF_SCOPE_EVENT_PAYLOAD: - fc = ctx->ec->payload_fc; - break; - default: - bt_common_abort(); - } - - if (fc && ctf_field_class_struct_has_immediate_member_in_ir( - ctf_field_class_as_struct(fc))) { - ir_fc = ctf_field_class_to_ir(ctx, fc); - } - - return ir_fc; + bt_field_class *ir_fc = NULL; + struct ctf_field_class *fc = NULL; + + switch (ctx->scope) { + case CTF_SCOPE_PACKET_CONTEXT: + fc = ctx->sc->packet_context_fc; + break; + case CTF_SCOPE_EVENT_COMMON_CONTEXT: + fc = ctx->sc->event_common_context_fc; + break; + case CTF_SCOPE_EVENT_SPECIFIC_CONTEXT: + fc = ctx->ec->spec_context_fc; + break; + case CTF_SCOPE_EVENT_PAYLOAD: + fc = ctx->ec->payload_fc; + break; + default: + bt_common_abort(); + } + + if (fc && ctf_field_class_struct_has_immediate_member_in_ir(ctf_field_class_as_struct(fc))) { + ir_fc = ctf_field_class_to_ir(ctx, fc); + } + + return ir_fc; } -static inline -void ctf_event_class_to_ir(struct ctx *ctx) +static inline void ctf_event_class_to_ir(struct ctx *ctx) { - int ret; - bt_event_class *ir_ec = NULL; - bt_field_class *ir_fc; - - BT_ASSERT(ctx->ec); - - if (ctx->ec->is_translated) { - ir_ec = bt_stream_class_borrow_event_class_by_id( - ctx->ir_sc, ctx->ec->id); - BT_ASSERT(ir_ec); - goto end; - } - - ir_ec = bt_event_class_create_with_id(ctx->ir_sc, ctx->ec->id); - BT_ASSERT(ir_ec); - bt_event_class_put_ref(ir_ec); - ctx->scope = CTF_SCOPE_EVENT_SPECIFIC_CONTEXT; - ir_fc = scope_ctf_field_class_to_ir(ctx); - if (ir_fc) { - ret = bt_event_class_set_specific_context_field_class( - ir_ec, ir_fc); - BT_ASSERT(ret == 0); - bt_field_class_put_ref(ir_fc); - } - - ctx->scope = CTF_SCOPE_EVENT_PAYLOAD; - ir_fc = scope_ctf_field_class_to_ir(ctx); - if (ir_fc) { - ret = bt_event_class_set_payload_field_class(ir_ec, - ir_fc); - BT_ASSERT(ret == 0); - bt_field_class_put_ref(ir_fc); - } - - if (ctx->ec->name->len > 0) { - ret = bt_event_class_set_name(ir_ec, ctx->ec->name->str); - BT_ASSERT(ret == 0); - } - - if (ctx->ec->emf_uri->len > 0) { - ret = bt_event_class_set_emf_uri(ir_ec, ctx->ec->emf_uri->str); - BT_ASSERT(ret == 0); - } - - if (ctx->ec->is_log_level_set) { - bt_event_class_set_log_level(ir_ec, ctx->ec->log_level); - } - - ctx->ec->is_translated = true; - ctx->ec->ir_ec = ir_ec; + int ret; + bt_event_class *ir_ec = NULL; + bt_field_class *ir_fc; + + BT_ASSERT(ctx->ec); + + if (ctx->ec->is_translated) { + ir_ec = bt_stream_class_borrow_event_class_by_id(ctx->ir_sc, ctx->ec->id); + BT_ASSERT(ir_ec); + goto end; + } + + ir_ec = bt_event_class_create_with_id(ctx->ir_sc, ctx->ec->id); + BT_ASSERT(ir_ec); + bt_event_class_put_ref(ir_ec); + ctx->scope = CTF_SCOPE_EVENT_SPECIFIC_CONTEXT; + ir_fc = scope_ctf_field_class_to_ir(ctx); + if (ir_fc) { + ret = bt_event_class_set_specific_context_field_class(ir_ec, ir_fc); + BT_ASSERT(ret == 0); + bt_field_class_put_ref(ir_fc); + } + + ctx->scope = CTF_SCOPE_EVENT_PAYLOAD; + ir_fc = scope_ctf_field_class_to_ir(ctx); + if (ir_fc) { + ret = bt_event_class_set_payload_field_class(ir_ec, ir_fc); + BT_ASSERT(ret == 0); + bt_field_class_put_ref(ir_fc); + } + + if (ctx->ec->name->len > 0) { + ret = bt_event_class_set_name(ir_ec, ctx->ec->name->str); + BT_ASSERT(ret == 0); + } + + if (ctx->ec->emf_uri->len > 0) { + ret = bt_event_class_set_emf_uri(ir_ec, ctx->ec->emf_uri->str); + BT_ASSERT(ret == 0); + } + + if (ctx->ec->is_log_level_set) { + bt_event_class_set_log_level(ir_ec, ctx->ec->log_level); + } + + ctx->ec->is_translated = true; + ctx->ec->ir_ec = ir_ec; end: - return; + return; } - -static inline -void ctf_stream_class_to_ir(struct ctx *ctx) +static inline void ctf_stream_class_to_ir(struct ctx *ctx) { - int ret; - bt_field_class *ir_fc; - - BT_ASSERT(ctx->sc); - - if (ctx->sc->is_translated) { - ctx->ir_sc = bt_trace_class_borrow_stream_class_by_id( - ctx->ir_tc, ctx->sc->id); - BT_ASSERT(ctx->ir_sc); - goto end; - } - - ctx->ir_sc = bt_stream_class_create_with_id(ctx->ir_tc, ctx->sc->id); - BT_ASSERT(ctx->ir_sc); - bt_stream_class_put_ref(ctx->ir_sc); - - if (ctx->sc->default_clock_class) { - BT_ASSERT(ctx->sc->default_clock_class->ir_cc); - ret = bt_stream_class_set_default_clock_class(ctx->ir_sc, - ctx->sc->default_clock_class->ir_cc); - BT_ASSERT(ret == 0); - } - - bt_stream_class_set_supports_packets(ctx->ir_sc, BT_TRUE, - ctx->sc->packets_have_ts_begin, ctx->sc->packets_have_ts_end); - bt_stream_class_set_supports_discarded_events(ctx->ir_sc, - ctx->sc->has_discarded_events, - ctx->sc->discarded_events_have_default_cs); - bt_stream_class_set_supports_discarded_packets(ctx->ir_sc, - ctx->sc->has_discarded_packets, - ctx->sc->discarded_packets_have_default_cs); - ctx->scope = CTF_SCOPE_PACKET_CONTEXT; - ir_fc = scope_ctf_field_class_to_ir(ctx); - if (ir_fc) { - ret = bt_stream_class_set_packet_context_field_class( - ctx->ir_sc, ir_fc); - BT_ASSERT(ret == 0); - bt_field_class_put_ref(ir_fc); - } - - ctx->scope = CTF_SCOPE_EVENT_COMMON_CONTEXT; - ir_fc = scope_ctf_field_class_to_ir(ctx); - if (ir_fc) { - ret = bt_stream_class_set_event_common_context_field_class( - ctx->ir_sc, ir_fc); - BT_ASSERT(ret == 0); - bt_field_class_put_ref(ir_fc); - } - - bt_stream_class_set_assigns_automatic_event_class_id(ctx->ir_sc, - BT_FALSE); - bt_stream_class_set_assigns_automatic_stream_id(ctx->ir_sc, BT_FALSE); - - ctx->sc->is_translated = true; - ctx->sc->ir_sc = ctx->ir_sc; + int ret; + bt_field_class *ir_fc; + + BT_ASSERT(ctx->sc); + + if (ctx->sc->is_translated) { + ctx->ir_sc = bt_trace_class_borrow_stream_class_by_id(ctx->ir_tc, ctx->sc->id); + BT_ASSERT(ctx->ir_sc); + goto end; + } + + ctx->ir_sc = bt_stream_class_create_with_id(ctx->ir_tc, ctx->sc->id); + BT_ASSERT(ctx->ir_sc); + bt_stream_class_put_ref(ctx->ir_sc); + + if (ctx->sc->default_clock_class) { + BT_ASSERT(ctx->sc->default_clock_class->ir_cc); + ret = bt_stream_class_set_default_clock_class(ctx->ir_sc, + ctx->sc->default_clock_class->ir_cc); + BT_ASSERT(ret == 0); + } + + bt_stream_class_set_supports_packets(ctx->ir_sc, BT_TRUE, ctx->sc->packets_have_ts_begin, + ctx->sc->packets_have_ts_end); + bt_stream_class_set_supports_discarded_events(ctx->ir_sc, ctx->sc->has_discarded_events, + ctx->sc->discarded_events_have_default_cs); + bt_stream_class_set_supports_discarded_packets(ctx->ir_sc, ctx->sc->has_discarded_packets, + ctx->sc->discarded_packets_have_default_cs); + ctx->scope = CTF_SCOPE_PACKET_CONTEXT; + ir_fc = scope_ctf_field_class_to_ir(ctx); + if (ir_fc) { + ret = bt_stream_class_set_packet_context_field_class(ctx->ir_sc, ir_fc); + BT_ASSERT(ret == 0); + bt_field_class_put_ref(ir_fc); + } + + ctx->scope = CTF_SCOPE_EVENT_COMMON_CONTEXT; + ir_fc = scope_ctf_field_class_to_ir(ctx); + if (ir_fc) { + ret = bt_stream_class_set_event_common_context_field_class(ctx->ir_sc, ir_fc); + BT_ASSERT(ret == 0); + bt_field_class_put_ref(ir_fc); + } + + bt_stream_class_set_assigns_automatic_event_class_id(ctx->ir_sc, BT_FALSE); + bt_stream_class_set_assigns_automatic_stream_id(ctx->ir_sc, BT_FALSE); + + ctx->sc->is_translated = true; + ctx->sc->ir_sc = ctx->ir_sc; end: - return; + return; } -static inline -void ctf_clock_class_to_ir(bt_clock_class *ir_cc, struct ctf_clock_class *cc) +static inline void ctf_clock_class_to_ir(bt_clock_class *ir_cc, struct ctf_clock_class *cc) { - int ret; + int ret; - if (strlen(cc->name->str) > 0) { - ret = bt_clock_class_set_name(ir_cc, cc->name->str); - BT_ASSERT(ret == 0); - } + if (strlen(cc->name->str) > 0) { + ret = bt_clock_class_set_name(ir_cc, cc->name->str); + BT_ASSERT(ret == 0); + } - if (strlen(cc->description->str) > 0) { - ret = bt_clock_class_set_description(ir_cc, cc->description->str); - BT_ASSERT(ret == 0); - } + if (strlen(cc->description->str) > 0) { + ret = bt_clock_class_set_description(ir_cc, cc->description->str); + BT_ASSERT(ret == 0); + } - bt_clock_class_set_frequency(ir_cc, cc->frequency); - bt_clock_class_set_precision(ir_cc, cc->precision); - bt_clock_class_set_offset(ir_cc, cc->offset_seconds, cc->offset_cycles); + bt_clock_class_set_frequency(ir_cc, cc->frequency); + bt_clock_class_set_precision(ir_cc, cc->precision); + bt_clock_class_set_offset(ir_cc, cc->offset_seconds, cc->offset_cycles); - if (cc->has_uuid) { - bt_clock_class_set_uuid(ir_cc, cc->uuid); - } + if (cc->has_uuid) { + bt_clock_class_set_uuid(ir_cc, cc->uuid); + } - bt_clock_class_set_origin_is_unix_epoch(ir_cc, cc->is_absolute); + bt_clock_class_set_origin_is_unix_epoch(ir_cc, cc->is_absolute); } -static inline -int ctf_trace_class_to_ir(struct ctx *ctx) +static inline int ctf_trace_class_to_ir(struct ctx *ctx) { - int ret = 0; - uint64_t i; + int ret = 0; + uint64_t i; - BT_ASSERT(ctx->tc); - BT_ASSERT(ctx->ir_tc); + BT_ASSERT(ctx->tc); + BT_ASSERT(ctx->ir_tc); - if (ctx->tc->is_translated) { - goto end; - } + if (ctx->tc->is_translated) { + goto end; + } - for (i = 0; i < ctx->tc->clock_classes->len; i++) { - ctf_clock_class *cc = (ctf_clock_class *) ctx->tc->clock_classes->pdata[i]; + for (i = 0; i < ctx->tc->clock_classes->len; i++) { + ctf_clock_class *cc = (ctf_clock_class *) ctx->tc->clock_classes->pdata[i]; - cc->ir_cc = bt_clock_class_create(ctx->self_comp); - ctf_clock_class_to_ir(cc->ir_cc, cc); - } + cc->ir_cc = bt_clock_class_create(ctx->self_comp); + ctf_clock_class_to_ir(cc->ir_cc, cc); + } - bt_trace_class_set_assigns_automatic_stream_class_id(ctx->ir_tc, - BT_FALSE); - ctx->tc->is_translated = true; - ctx->tc->ir_tc = ctx->ir_tc; + bt_trace_class_set_assigns_automatic_stream_class_id(ctx->ir_tc, BT_FALSE); + ctx->tc->is_translated = true; + ctx->tc->ir_tc = ctx->ir_tc; end: - return ret; + return ret; } BT_HIDDEN -int ctf_trace_class_translate(bt_self_component *self_comp, - bt_trace_class *ir_tc, struct ctf_trace_class *tc) +int ctf_trace_class_translate(bt_self_component *self_comp, bt_trace_class *ir_tc, + struct ctf_trace_class *tc) { - int ret = 0; - uint64_t i; - struct ctx ctx = { 0 }; + int ret = 0; + uint64_t i; + struct ctx ctx = {0}; - ctx.self_comp = self_comp; - ctx.tc = tc; - ctx.ir_tc = ir_tc; - ret = ctf_trace_class_to_ir(&ctx); - if (ret) { - goto end; - } + ctx.self_comp = self_comp; + ctx.tc = tc; + ctx.ir_tc = ir_tc; + ret = ctf_trace_class_to_ir(&ctx); + if (ret) { + goto end; + } - for (i = 0; i < tc->stream_classes->len; i++) { - uint64_t j; - ctx.sc = (ctf_stream_class *) tc->stream_classes->pdata[i]; + for (i = 0; i < tc->stream_classes->len; i++) { + uint64_t j; + ctx.sc = (ctf_stream_class *) tc->stream_classes->pdata[i]; - ctf_stream_class_to_ir(&ctx); + ctf_stream_class_to_ir(&ctx); - for (j = 0; j < ctx.sc->event_classes->len; j++) { - ctx.ec = (ctf_event_class *) ctx.sc->event_classes->pdata[j]; + for (j = 0; j < ctx.sc->event_classes->len; j++) { + ctx.ec = (ctf_event_class *) ctx.sc->event_classes->pdata[j]; - ctf_event_class_to_ir(&ctx); - ctx.ec = NULL; - } + ctf_event_class_to_ir(&ctx); + ctx.ec = NULL; + } - ctx.sc = NULL; - } + ctx.sc = NULL; + } end: - return ret; + return ret; } diff --git a/src/plugins/ctf/common/metadata/ctf-meta-update-alignments.cpp b/src/plugins/ctf/common/metadata/ctf-meta-update-alignments.cpp index 6e93b671..b4c9a266 100644 --- a/src/plugins/ctf/common/metadata/ctf-meta-update-alignments.cpp +++ b/src/plugins/ctf/common/metadata/ctf-meta-update-alignments.cpp @@ -14,160 +14,155 @@ #include "ctf-meta-visitors.hpp" -static inline -int set_alignments(struct ctf_field_class *fc) +static inline int set_alignments(struct ctf_field_class *fc) { - int ret = 0; - uint64_t i; - - if (!fc) { - goto end; - } - - switch (fc->type) { - case CTF_FIELD_CLASS_TYPE_STRUCT: - { - struct ctf_field_class_struct *struct_fc = ctf_field_class_as_struct(fc); - - for (i = 0; i < struct_fc->members->len; i++) { - struct ctf_named_field_class *named_fc = - ctf_field_class_struct_borrow_member_by_index( - struct_fc, i); - - ret = set_alignments(named_fc->fc); - if (ret) { - goto end; - } - - if (named_fc->fc->alignment > fc->alignment) { - fc->alignment = named_fc->fc->alignment; - } - } - - break; - } - case CTF_FIELD_CLASS_TYPE_VARIANT: - { - struct ctf_field_class_variant *var_fc = ctf_field_class_as_variant(fc); - - for (i = 0; i < var_fc->options->len; i++) { - struct ctf_named_field_class *named_fc = - ctf_field_class_variant_borrow_option_by_index( - var_fc, i); - - ret = set_alignments(named_fc->fc); - if (ret) { - goto end; - } - } - - break; - } - case CTF_FIELD_CLASS_TYPE_ARRAY: - case CTF_FIELD_CLASS_TYPE_SEQUENCE: - { - struct ctf_field_class_array_base *array_fc = ctf_field_class_as_array_base(fc); - - ret = set_alignments(array_fc->elem_fc); - if (ret) { - goto end; - } - - /* - * Use the alignment of the array/sequence field class's - * element FC as its own alignment. - * - * This is especially important when the array/sequence - * field's effective length is zero: as per CTF 1.8, the - * stream data decoding process still needs to align the - * cursor using the element's alignment [1]: - * - * > Arrays are always aligned on their element - * > alignment requirement. - * - * For example: - * - * struct { - * integer { size = 8; } a; - * integer { size = 8; align = 16; } b[0]; - * integer { size = 8; } c; - * }; - * - * When using this to decode the bytes 1, 2, and 3, then - * the decoded values are: - * - * `a`: 1 - * `b`: [] - * `c`: 3 - * - * [1]: https://diamon.org/ctf/#spec4.2.3 - */ - array_fc->base.alignment = array_fc->elem_fc->alignment; - break; - } - default: - break; - } + int ret = 0; + uint64_t i; + + if (!fc) { + goto end; + } + + switch (fc->type) { + case CTF_FIELD_CLASS_TYPE_STRUCT: + { + struct ctf_field_class_struct *struct_fc = ctf_field_class_as_struct(fc); + + for (i = 0; i < struct_fc->members->len; i++) { + struct ctf_named_field_class *named_fc = + ctf_field_class_struct_borrow_member_by_index(struct_fc, i); + + ret = set_alignments(named_fc->fc); + if (ret) { + goto end; + } + + if (named_fc->fc->alignment > fc->alignment) { + fc->alignment = named_fc->fc->alignment; + } + } + + break; + } + case CTF_FIELD_CLASS_TYPE_VARIANT: + { + struct ctf_field_class_variant *var_fc = ctf_field_class_as_variant(fc); + + for (i = 0; i < var_fc->options->len; i++) { + struct ctf_named_field_class *named_fc = + ctf_field_class_variant_borrow_option_by_index(var_fc, i); + + ret = set_alignments(named_fc->fc); + if (ret) { + goto end; + } + } + + break; + } + case CTF_FIELD_CLASS_TYPE_ARRAY: + case CTF_FIELD_CLASS_TYPE_SEQUENCE: + { + struct ctf_field_class_array_base *array_fc = ctf_field_class_as_array_base(fc); + + ret = set_alignments(array_fc->elem_fc); + if (ret) { + goto end; + } + + /* + * Use the alignment of the array/sequence field class's + * element FC as its own alignment. + * + * This is especially important when the array/sequence + * field's effective length is zero: as per CTF 1.8, the + * stream data decoding process still needs to align the + * cursor using the element's alignment [1]: + * + * > Arrays are always aligned on their element + * > alignment requirement. + * + * For example: + * + * struct { + * integer { size = 8; } a; + * integer { size = 8; align = 16; } b[0]; + * integer { size = 8; } c; + * }; + * + * When using this to decode the bytes 1, 2, and 3, then + * the decoded values are: + * + * `a`: 1 + * `b`: [] + * `c`: 3 + * + * [1]: https://diamon.org/ctf/#spec4.2.3 + */ + array_fc->base.alignment = array_fc->elem_fc->alignment; + break; + } + default: + break; + } end: - return ret; + return ret; } BT_HIDDEN -int ctf_trace_class_update_alignments( - struct ctf_trace_class *ctf_tc) +int ctf_trace_class_update_alignments(struct ctf_trace_class *ctf_tc) { - int ret = 0; - uint64_t i; - - if (!ctf_tc->is_translated) { - ret = set_alignments(ctf_tc->packet_header_fc); - if (ret) { - goto end; - } - } - - for (i = 0; i < ctf_tc->stream_classes->len; i++) { - ctf_stream_class *sc = (ctf_stream_class *) ctf_tc->stream_classes->pdata[i]; - uint64_t j; - - if (!sc->is_translated) { - ret = set_alignments(sc->packet_context_fc); - if (ret) { - goto end; - } - - ret = set_alignments(sc->event_header_fc); - if (ret) { - goto end; - } - - ret = set_alignments(sc->event_common_context_fc); - if (ret) { - goto end; - } - } - - for (j = 0; j < sc->event_classes->len; j++) { - struct ctf_event_class *ec = - (ctf_event_class *) sc->event_classes->pdata[j]; - - if (ec->is_translated) { - continue; - } - - ret = set_alignments(ec->spec_context_fc); - if (ret) { - goto end; - } - - ret = set_alignments(ec->payload_fc); - if (ret) { - goto end; - } - } - } + int ret = 0; + uint64_t i; + + if (!ctf_tc->is_translated) { + ret = set_alignments(ctf_tc->packet_header_fc); + if (ret) { + goto end; + } + } + + for (i = 0; i < ctf_tc->stream_classes->len; i++) { + ctf_stream_class *sc = (ctf_stream_class *) ctf_tc->stream_classes->pdata[i]; + uint64_t j; + + if (!sc->is_translated) { + ret = set_alignments(sc->packet_context_fc); + if (ret) { + goto end; + } + + ret = set_alignments(sc->event_header_fc); + if (ret) { + goto end; + } + + ret = set_alignments(sc->event_common_context_fc); + if (ret) { + goto end; + } + } + + for (j = 0; j < sc->event_classes->len; j++) { + struct ctf_event_class *ec = (ctf_event_class *) sc->event_classes->pdata[j]; + + if (ec->is_translated) { + continue; + } + + ret = set_alignments(ec->spec_context_fc); + if (ret) { + goto end; + } + + ret = set_alignments(ec->payload_fc); + if (ret) { + goto end; + } + } + } end: - return ret; + return ret; } diff --git a/src/plugins/ctf/common/metadata/ctf-meta-update-default-clock-classes.cpp b/src/plugins/ctf/common/metadata/ctf-meta-update-default-clock-classes.cpp index d40adda3..a1e1ecfc 100644 --- a/src/plugins/ctf/common/metadata/ctf-meta-update-default-clock-classes.cpp +++ b/src/plugins/ctf/common/metadata/ctf-meta-update-default-clock-classes.cpp @@ -4,10 +4,10 @@ * Copyright 2018 Philippe Proulx */ -#define BT_COMP_LOG_SELF_COMP (log_cfg->self_comp) +#define BT_COMP_LOG_SELF_COMP (log_cfg->self_comp) #define BT_COMP_LOG_SELF_COMP_CLASS (log_cfg->self_comp_class) -#define BT_LOG_OUTPUT_LEVEL (log_cfg->log_level) -#define BT_LOG_TAG "PLUGIN/CTF/META/UPDATE-DEF-CC" +#define BT_LOG_OUTPUT_LEVEL (log_cfg->log_level) +#define BT_LOG_TAG "PLUGIN/CTF/META/UPDATE-DEF-CC" #include "logging/comp-logging.h" #include @@ -21,184 +21,167 @@ #include "ctf-meta-visitors.hpp" #include "logging.hpp" -static inline -int find_mapped_clock_class(struct ctf_field_class *fc, - struct ctf_clock_class **clock_class, - struct meta_log_config *log_cfg) +static inline int find_mapped_clock_class(struct ctf_field_class *fc, + struct ctf_clock_class **clock_class, + struct meta_log_config *log_cfg) { - int ret = 0; - uint64_t i; - - if (!fc) { - goto end; - } - - switch (fc->type) { - case CTF_FIELD_CLASS_TYPE_INT: - case CTF_FIELD_CLASS_TYPE_ENUM: - { - struct ctf_field_class_int *int_fc = ctf_field_class_as_int(fc); - - if (int_fc->mapped_clock_class) { - if (*clock_class && *clock_class != - int_fc->mapped_clock_class) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Stream class contains more than one " - "clock class: expected-cc-name=\"%s\", " - "other-cc-name=\"%s\"", - (*clock_class)->name->str, - int_fc->mapped_clock_class->name->str); - ret = -1; - goto end; - } - - *clock_class = int_fc->mapped_clock_class; - } - - break; - } - case CTF_FIELD_CLASS_TYPE_STRUCT: - { - struct ctf_field_class_struct *struct_fc = ctf_field_class_as_struct(fc); - - for (i = 0; i < struct_fc->members->len; i++) { - struct ctf_named_field_class *named_fc = - ctf_field_class_struct_borrow_member_by_index( - struct_fc, i); - - ret = find_mapped_clock_class(named_fc->fc, - clock_class, log_cfg); - if (ret) { - goto end; - } - } - - break; - } - case CTF_FIELD_CLASS_TYPE_VARIANT: - { - struct ctf_field_class_variant *var_fc = ctf_field_class_as_variant(fc); - - for (i = 0; i < var_fc->options->len; i++) { - struct ctf_named_field_class *named_fc = - ctf_field_class_variant_borrow_option_by_index( - var_fc, i); - - ret = find_mapped_clock_class(named_fc->fc, - clock_class, log_cfg); - if (ret) { - goto end; - } - } - - break; - } - case CTF_FIELD_CLASS_TYPE_ARRAY: - case CTF_FIELD_CLASS_TYPE_SEQUENCE: - { - struct ctf_field_class_array_base *array_fc = ctf_field_class_as_array_base(fc); - - ret = find_mapped_clock_class(array_fc->elem_fc, clock_class, - log_cfg); - if (ret) { - goto end; - } - - break; - } - default: - break; - } + int ret = 0; + uint64_t i; + + if (!fc) { + goto end; + } + + switch (fc->type) { + case CTF_FIELD_CLASS_TYPE_INT: + case CTF_FIELD_CLASS_TYPE_ENUM: + { + struct ctf_field_class_int *int_fc = ctf_field_class_as_int(fc); + + if (int_fc->mapped_clock_class) { + if (*clock_class && *clock_class != int_fc->mapped_clock_class) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Stream class contains more than one " + "clock class: expected-cc-name=\"%s\", " + "other-cc-name=\"%s\"", + (*clock_class)->name->str, + int_fc->mapped_clock_class->name->str); + ret = -1; + goto end; + } + + *clock_class = int_fc->mapped_clock_class; + } + + break; + } + case CTF_FIELD_CLASS_TYPE_STRUCT: + { + struct ctf_field_class_struct *struct_fc = ctf_field_class_as_struct(fc); + + for (i = 0; i < struct_fc->members->len; i++) { + struct ctf_named_field_class *named_fc = + ctf_field_class_struct_borrow_member_by_index(struct_fc, i); + + ret = find_mapped_clock_class(named_fc->fc, clock_class, log_cfg); + if (ret) { + goto end; + } + } + + break; + } + case CTF_FIELD_CLASS_TYPE_VARIANT: + { + struct ctf_field_class_variant *var_fc = ctf_field_class_as_variant(fc); + + for (i = 0; i < var_fc->options->len; i++) { + struct ctf_named_field_class *named_fc = + ctf_field_class_variant_borrow_option_by_index(var_fc, i); + + ret = find_mapped_clock_class(named_fc->fc, clock_class, log_cfg); + if (ret) { + goto end; + } + } + + break; + } + case CTF_FIELD_CLASS_TYPE_ARRAY: + case CTF_FIELD_CLASS_TYPE_SEQUENCE: + { + struct ctf_field_class_array_base *array_fc = ctf_field_class_as_array_base(fc); + + ret = find_mapped_clock_class(array_fc->elem_fc, clock_class, log_cfg); + if (ret) { + goto end; + } + + break; + } + default: + break; + } end: - return ret; + return ret; } -static inline -int update_stream_class_default_clock_class( - struct ctf_stream_class *stream_class, - struct meta_log_config *log_cfg) +static inline int update_stream_class_default_clock_class(struct ctf_stream_class *stream_class, + struct meta_log_config *log_cfg) { - int ret = 0; - struct ctf_clock_class *clock_class = - stream_class->default_clock_class; - uint64_t i; - - ret = find_mapped_clock_class(stream_class->packet_context_fc, - &clock_class, log_cfg); - if (ret) { - goto end; - } - - ret = find_mapped_clock_class(stream_class->event_header_fc, - &clock_class, log_cfg); - if (ret) { - goto end; - } - - ret = find_mapped_clock_class(stream_class->event_common_context_fc, - &clock_class, log_cfg); - if (ret) { - goto end; - } - - for (i = 0; i < stream_class->event_classes->len; i++) { - struct ctf_event_class *event_class = - (ctf_event_class *) stream_class->event_classes->pdata[i]; - - ret = find_mapped_clock_class(event_class->spec_context_fc, - &clock_class, log_cfg); - if (ret) { - goto end; - } - - ret = find_mapped_clock_class(event_class->payload_fc, - &clock_class, log_cfg); - if (ret) { - goto end; - } - } - - if (!stream_class->default_clock_class) { - stream_class->default_clock_class = clock_class; - } + int ret = 0; + struct ctf_clock_class *clock_class = stream_class->default_clock_class; + uint64_t i; + + ret = find_mapped_clock_class(stream_class->packet_context_fc, &clock_class, log_cfg); + if (ret) { + goto end; + } + + ret = find_mapped_clock_class(stream_class->event_header_fc, &clock_class, log_cfg); + if (ret) { + goto end; + } + + ret = find_mapped_clock_class(stream_class->event_common_context_fc, &clock_class, log_cfg); + if (ret) { + goto end; + } + + for (i = 0; i < stream_class->event_classes->len; i++) { + struct ctf_event_class *event_class = + (ctf_event_class *) stream_class->event_classes->pdata[i]; + + ret = find_mapped_clock_class(event_class->spec_context_fc, &clock_class, log_cfg); + if (ret) { + goto end; + } + + ret = find_mapped_clock_class(event_class->payload_fc, &clock_class, log_cfg); + if (ret) { + goto end; + } + } + + if (!stream_class->default_clock_class) { + stream_class->default_clock_class = clock_class; + } end: - return ret; + return ret; } BT_HIDDEN int ctf_trace_class_update_default_clock_classes(struct ctf_trace_class *ctf_tc, - struct meta_log_config *log_cfg) + struct meta_log_config *log_cfg) { - uint64_t i; - int ret = 0; - struct ctf_clock_class *clock_class = NULL; - - ret = find_mapped_clock_class(ctf_tc->packet_header_fc, &clock_class, - log_cfg); - if (ret) { - goto end; - } - - if (clock_class) { - ret = -1; - goto end; - } - - for (i = 0; i < ctf_tc->stream_classes->len; i++) { - struct ctf_stream_class *sc = - (ctf_stream_class *) ctf_tc->stream_classes->pdata[i]; - - ret = update_stream_class_default_clock_class( - (ctf_stream_class *) ctf_tc->stream_classes->pdata[i], log_cfg); - if (ret) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Stream class contains more than one " - "clock class: stream-class-id=%" PRIu64, - sc->id); - goto end; - } - } + uint64_t i; + int ret = 0; + struct ctf_clock_class *clock_class = NULL; + + ret = find_mapped_clock_class(ctf_tc->packet_header_fc, &clock_class, log_cfg); + if (ret) { + goto end; + } + + if (clock_class) { + ret = -1; + goto end; + } + + for (i = 0; i < ctf_tc->stream_classes->len; i++) { + struct ctf_stream_class *sc = (ctf_stream_class *) ctf_tc->stream_classes->pdata[i]; + + ret = update_stream_class_default_clock_class( + (ctf_stream_class *) ctf_tc->stream_classes->pdata[i], log_cfg); + if (ret) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Stream class contains more than one " + "clock class: stream-class-id=%" PRIu64, + sc->id); + goto end; + } + } end: - return ret; + return ret; } diff --git a/src/plugins/ctf/common/metadata/ctf-meta-update-in-ir.cpp b/src/plugins/ctf/common/metadata/ctf-meta-update-in-ir.cpp index 765f38c5..6967c441 100644 --- a/src/plugins/ctf/common/metadata/ctf-meta-update-in-ir.cpp +++ b/src/plugins/ctf/common/metadata/ctf-meta-update-in-ir.cpp @@ -17,217 +17,204 @@ #include "ctf-meta-visitors.hpp" -static -void force_update_field_class_in_ir(struct ctf_field_class *fc, bool in_ir) +static void force_update_field_class_in_ir(struct ctf_field_class *fc, bool in_ir) { - uint64_t i; - - if (!fc) { - goto end; - } - - fc->in_ir = in_ir; - - switch (fc->type) { - case CTF_FIELD_CLASS_TYPE_STRUCT: - { - struct ctf_field_class_struct *struct_fc = ctf_field_class_as_struct(fc); - - for (i = 0; i < struct_fc->members->len; i++) { - struct ctf_named_field_class *named_fc = - ctf_field_class_struct_borrow_member_by_index( - struct_fc, i); - - force_update_field_class_in_ir(named_fc->fc, in_ir); - } - - break; - } - case CTF_FIELD_CLASS_TYPE_VARIANT: - { - struct ctf_named_field_class *named_fc; - struct ctf_field_class_variant *var_fc = ctf_field_class_as_variant(fc); - - for (i = 0; i < var_fc->options->len; i++) { - named_fc = - ctf_field_class_variant_borrow_option_by_index( - var_fc, i); - - force_update_field_class_in_ir(named_fc->fc, in_ir); - } - - break; - } - case CTF_FIELD_CLASS_TYPE_ARRAY: - case CTF_FIELD_CLASS_TYPE_SEQUENCE: - { - struct ctf_field_class_array_base *array_fc = ctf_field_class_as_array_base(fc); - - force_update_field_class_in_ir(array_fc->elem_fc, in_ir); - break; - } - default: - break; - } + uint64_t i; + + if (!fc) { + goto end; + } + + fc->in_ir = in_ir; + + switch (fc->type) { + case CTF_FIELD_CLASS_TYPE_STRUCT: + { + struct ctf_field_class_struct *struct_fc = ctf_field_class_as_struct(fc); + + for (i = 0; i < struct_fc->members->len; i++) { + struct ctf_named_field_class *named_fc = + ctf_field_class_struct_borrow_member_by_index(struct_fc, i); + + force_update_field_class_in_ir(named_fc->fc, in_ir); + } + + break; + } + case CTF_FIELD_CLASS_TYPE_VARIANT: + { + struct ctf_named_field_class *named_fc; + struct ctf_field_class_variant *var_fc = ctf_field_class_as_variant(fc); + + for (i = 0; i < var_fc->options->len; i++) { + named_fc = ctf_field_class_variant_borrow_option_by_index(var_fc, i); + + force_update_field_class_in_ir(named_fc->fc, in_ir); + } + + break; + } + case CTF_FIELD_CLASS_TYPE_ARRAY: + case CTF_FIELD_CLASS_TYPE_SEQUENCE: + { + struct ctf_field_class_array_base *array_fc = ctf_field_class_as_array_base(fc); + + force_update_field_class_in_ir(array_fc->elem_fc, in_ir); + break; + } + default: + break; + } end: - return; + return; } -static -void update_field_class_in_ir(struct ctf_field_class *fc, - GHashTable *ft_dependents) +static void update_field_class_in_ir(struct ctf_field_class *fc, GHashTable *ft_dependents) { - int64_t i; - - if (!fc) { - goto end; - } - - switch (fc->type) { - case CTF_FIELD_CLASS_TYPE_INT: - case CTF_FIELD_CLASS_TYPE_ENUM: - { - struct ctf_field_class_int *int_fc = ctf_field_class_as_int(fc); - - /* - * Conditions to be in trace IR; one of: - * - * 1. Does NOT have a mapped clock class AND does not - * have a special meaning. - * 2. Another field class depends on it. - */ - if ((!int_fc->mapped_clock_class && - int_fc->meaning == CTF_FIELD_CLASS_MEANING_NONE) || - bt_g_hash_table_contains(ft_dependents, fc)) { - fc->in_ir = true; - } - - break; - } - case CTF_FIELD_CLASS_TYPE_STRUCT: - { - struct ctf_field_class_struct *struct_fc = ctf_field_class_as_struct(fc); - - /* - * Make it part of IR if it's empty because it was - * originally empty. - */ - if (struct_fc->members->len == 0) { - fc->in_ir = true; - } - - /* Reverse order */ - for (i = (int64_t) struct_fc->members->len - 1; i >= 0; i--) { - struct ctf_named_field_class *named_fc = - ctf_field_class_struct_borrow_member_by_index( - struct_fc, i); - - update_field_class_in_ir(named_fc->fc, ft_dependents); - - if (named_fc->fc->in_ir) { - /* At least one member is part of IR */ - fc->in_ir = true; - } - } - - break; - } - case CTF_FIELD_CLASS_TYPE_VARIANT: - { - struct ctf_named_field_class *named_fc; - struct ctf_field_class_variant *var_fc = ctf_field_class_as_variant(fc); - - /* - * Reverse order, although it is not important for this - * loop because a field class within a variant field - * type's option cannot depend on a field class in - * another option of the same variant field class. - */ - for (i = (int64_t) var_fc->options->len - 1; i >= 0; i--) { - named_fc = - ctf_field_class_variant_borrow_option_by_index( - var_fc, i); - - update_field_class_in_ir(named_fc->fc, ft_dependents); - - if (named_fc->fc->in_ir) { - /* At least one option is part of IR */ - fc->in_ir = true; - } - } - - if (fc->in_ir) { - /* - * At least one option will make it to IR. In - * this case, make all options part of IR - * because the variant's tag could still select - * (dynamically) a removed option. This can mean - * having an empty structure as an option, for - * example, but at least all the options are - * selectable. - */ - for (i = 0; i < var_fc->options->len; i++) { - ctf_field_class_variant_borrow_option_by_index( - var_fc, i)->fc->in_ir = true; - } - - /* - * This variant field class is part of IR and - * depends on a tag field class (which must also - * be part of IR). - */ - g_hash_table_insert(ft_dependents, var_fc->tag_fc, - var_fc->tag_fc); - } - - break; - } - case CTF_FIELD_CLASS_TYPE_ARRAY: - case CTF_FIELD_CLASS_TYPE_SEQUENCE: - { - struct ctf_field_class_array_base *array_fc = ctf_field_class_as_array_base(fc); - - update_field_class_in_ir(array_fc->elem_fc, ft_dependents); - fc->in_ir = array_fc->elem_fc->in_ir; - - if (fc->type == CTF_FIELD_CLASS_TYPE_ARRAY) { - struct ctf_field_class_array *arr_fc = ctf_field_class_as_array(fc); - - assert(arr_fc->meaning == CTF_FIELD_CLASS_MEANING_NONE || - arr_fc->meaning == CTF_FIELD_CLASS_MEANING_UUID); - - /* - * UUID field class: nothing depends on this, so - * it's not part of IR. - */ - if (arr_fc->meaning == CTF_FIELD_CLASS_MEANING_UUID) { - fc->in_ir = false; - array_fc->elem_fc->in_ir = false; - } - } else if (fc->type == CTF_FIELD_CLASS_TYPE_SEQUENCE) { - if (fc->in_ir) { - struct ctf_field_class_sequence *seq_fc = ctf_field_class_as_sequence(fc); - - /* - * This sequence field class is part of - * IR and depends on a length field class - * (which must also be part of IR). - */ - g_hash_table_insert(ft_dependents, - seq_fc->length_fc, seq_fc->length_fc); - } - } - - break; - } - default: - fc->in_ir = true; - break; - } + int64_t i; + + if (!fc) { + goto end; + } + + switch (fc->type) { + case CTF_FIELD_CLASS_TYPE_INT: + case CTF_FIELD_CLASS_TYPE_ENUM: + { + struct ctf_field_class_int *int_fc = ctf_field_class_as_int(fc); + + /* + * Conditions to be in trace IR; one of: + * + * 1. Does NOT have a mapped clock class AND does not + * have a special meaning. + * 2. Another field class depends on it. + */ + if ((!int_fc->mapped_clock_class && int_fc->meaning == CTF_FIELD_CLASS_MEANING_NONE) || + bt_g_hash_table_contains(ft_dependents, fc)) { + fc->in_ir = true; + } + + break; + } + case CTF_FIELD_CLASS_TYPE_STRUCT: + { + struct ctf_field_class_struct *struct_fc = ctf_field_class_as_struct(fc); + + /* + * Make it part of IR if it's empty because it was + * originally empty. + */ + if (struct_fc->members->len == 0) { + fc->in_ir = true; + } + + /* Reverse order */ + for (i = (int64_t) struct_fc->members->len - 1; i >= 0; i--) { + struct ctf_named_field_class *named_fc = + ctf_field_class_struct_borrow_member_by_index(struct_fc, i); + + update_field_class_in_ir(named_fc->fc, ft_dependents); + + if (named_fc->fc->in_ir) { + /* At least one member is part of IR */ + fc->in_ir = true; + } + } + + break; + } + case CTF_FIELD_CLASS_TYPE_VARIANT: + { + struct ctf_named_field_class *named_fc; + struct ctf_field_class_variant *var_fc = ctf_field_class_as_variant(fc); + + /* + * Reverse order, although it is not important for this + * loop because a field class within a variant field + * type's option cannot depend on a field class in + * another option of the same variant field class. + */ + for (i = (int64_t) var_fc->options->len - 1; i >= 0; i--) { + named_fc = ctf_field_class_variant_borrow_option_by_index(var_fc, i); + + update_field_class_in_ir(named_fc->fc, ft_dependents); + + if (named_fc->fc->in_ir) { + /* At least one option is part of IR */ + fc->in_ir = true; + } + } + + if (fc->in_ir) { + /* + * At least one option will make it to IR. In + * this case, make all options part of IR + * because the variant's tag could still select + * (dynamically) a removed option. This can mean + * having an empty structure as an option, for + * example, but at least all the options are + * selectable. + */ + for (i = 0; i < var_fc->options->len; i++) { + ctf_field_class_variant_borrow_option_by_index(var_fc, i)->fc->in_ir = true; + } + + /* + * This variant field class is part of IR and + * depends on a tag field class (which must also + * be part of IR). + */ + g_hash_table_insert(ft_dependents, var_fc->tag_fc, var_fc->tag_fc); + } + + break; + } + case CTF_FIELD_CLASS_TYPE_ARRAY: + case CTF_FIELD_CLASS_TYPE_SEQUENCE: + { + struct ctf_field_class_array_base *array_fc = ctf_field_class_as_array_base(fc); + + update_field_class_in_ir(array_fc->elem_fc, ft_dependents); + fc->in_ir = array_fc->elem_fc->in_ir; + + if (fc->type == CTF_FIELD_CLASS_TYPE_ARRAY) { + struct ctf_field_class_array *arr_fc = ctf_field_class_as_array(fc); + + assert(arr_fc->meaning == CTF_FIELD_CLASS_MEANING_NONE || + arr_fc->meaning == CTF_FIELD_CLASS_MEANING_UUID); + + /* + * UUID field class: nothing depends on this, so + * it's not part of IR. + */ + if (arr_fc->meaning == CTF_FIELD_CLASS_MEANING_UUID) { + fc->in_ir = false; + array_fc->elem_fc->in_ir = false; + } + } else if (fc->type == CTF_FIELD_CLASS_TYPE_SEQUENCE) { + if (fc->in_ir) { + struct ctf_field_class_sequence *seq_fc = ctf_field_class_as_sequence(fc); + + /* + * This sequence field class is part of + * IR and depends on a length field class + * (which must also be part of IR). + */ + g_hash_table_insert(ft_dependents, seq_fc->length_fc, seq_fc->length_fc); + } + } + + break; + } + default: + fc->in_ir = true; + break; + } end: - return; + return; } /* @@ -239,45 +226,39 @@ end: BT_HIDDEN int ctf_trace_class_update_in_ir(struct ctf_trace_class *ctf_tc) { - int ret = 0; - uint64_t i; - - GHashTable *ft_dependents = g_hash_table_new(g_direct_hash, - g_direct_equal); - - BT_ASSERT(ft_dependents); - - for (i = 0; i < ctf_tc->stream_classes->len; i++) { - ctf_stream_class *sc = (ctf_stream_class *) ctf_tc->stream_classes->pdata[i]; - uint64_t j; - - for (j = 0; j < sc->event_classes->len; j++) { - ctf_event_class *ec = (ctf_event_class *) sc->event_classes->pdata[j]; - - if (ec->is_translated) { - continue; - } - - update_field_class_in_ir(ec->payload_fc, ft_dependents); - update_field_class_in_ir(ec->spec_context_fc, - ft_dependents); - } - - if (!sc->is_translated) { - update_field_class_in_ir(sc->event_common_context_fc, - ft_dependents); - force_update_field_class_in_ir(sc->event_header_fc, - false); - update_field_class_in_ir(sc->packet_context_fc, - ft_dependents); - } - } - - if (!ctf_tc->is_translated) { - force_update_field_class_in_ir(ctf_tc->packet_header_fc, - false); - } - - g_hash_table_destroy(ft_dependents); - return ret; + int ret = 0; + uint64_t i; + + GHashTable *ft_dependents = g_hash_table_new(g_direct_hash, g_direct_equal); + + BT_ASSERT(ft_dependents); + + for (i = 0; i < ctf_tc->stream_classes->len; i++) { + ctf_stream_class *sc = (ctf_stream_class *) ctf_tc->stream_classes->pdata[i]; + uint64_t j; + + for (j = 0; j < sc->event_classes->len; j++) { + ctf_event_class *ec = (ctf_event_class *) sc->event_classes->pdata[j]; + + if (ec->is_translated) { + continue; + } + + update_field_class_in_ir(ec->payload_fc, ft_dependents); + update_field_class_in_ir(ec->spec_context_fc, ft_dependents); + } + + if (!sc->is_translated) { + update_field_class_in_ir(sc->event_common_context_fc, ft_dependents); + force_update_field_class_in_ir(sc->event_header_fc, false); + update_field_class_in_ir(sc->packet_context_fc, ft_dependents); + } + } + + if (!ctf_tc->is_translated) { + force_update_field_class_in_ir(ctf_tc->packet_header_fc, false); + } + + g_hash_table_destroy(ft_dependents); + return ret; } diff --git a/src/plugins/ctf/common/metadata/ctf-meta-update-meanings.cpp b/src/plugins/ctf/common/metadata/ctf-meta-update-meanings.cpp index 4e8d6471..2a4c1fd5 100644 --- a/src/plugins/ctf/common/metadata/ctf-meta-update-meanings.cpp +++ b/src/plugins/ctf/common/metadata/ctf-meta-update-meanings.cpp @@ -14,208 +14,197 @@ #include "ctf-meta-visitors.hpp" -static -int set_int_field_class_meaning_by_name(struct ctf_field_class *fc, - const char *field_name, const char *id_name, - enum ctf_field_class_meaning meaning) +static int set_int_field_class_meaning_by_name(struct ctf_field_class *fc, const char *field_name, + const char *id_name, + enum ctf_field_class_meaning meaning) { - int ret = 0; - uint64_t i; - - if (!fc) { - goto end; - } - - switch (fc->type) { - case CTF_FIELD_CLASS_TYPE_INT: - case CTF_FIELD_CLASS_TYPE_ENUM: - { - struct ctf_field_class_int *int_fc = ctf_field_class_as_int(fc); - - if (field_name && strcmp(field_name, id_name) == 0) { - int_fc->meaning = meaning; - } - - break; - } - case CTF_FIELD_CLASS_TYPE_STRUCT: - { - struct ctf_field_class_struct *struct_fc = ctf_field_class_as_struct(fc); - - for (i = 0; i < struct_fc->members->len; i++) { - struct ctf_named_field_class *named_fc = - ctf_field_class_struct_borrow_member_by_index( - struct_fc, i); - - ret = set_int_field_class_meaning_by_name(named_fc->fc, - named_fc->name->str, id_name, meaning); - if (ret) { - goto end; - } - } - - break; - } - case CTF_FIELD_CLASS_TYPE_VARIANT: - { - struct ctf_field_class_variant *var_fc = ctf_field_class_as_variant(fc); - - for (i = 0; i < var_fc->options->len; i++) { - struct ctf_named_field_class *named_fc = - ctf_field_class_variant_borrow_option_by_index( - var_fc, i); - - ret = set_int_field_class_meaning_by_name(named_fc->fc, - NULL, id_name, meaning); - if (ret) { - goto end; - } - } - - break; - } - case CTF_FIELD_CLASS_TYPE_ARRAY: - case CTF_FIELD_CLASS_TYPE_SEQUENCE: - { - struct ctf_field_class_array_base *array_fc = ctf_field_class_as_array_base(fc); - - ret = set_int_field_class_meaning_by_name(array_fc->elem_fc, - NULL, id_name, meaning); - if (ret) { - goto end; - } - - break; - } - default: - break; - } + int ret = 0; + uint64_t i; + + if (!fc) { + goto end; + } + + switch (fc->type) { + case CTF_FIELD_CLASS_TYPE_INT: + case CTF_FIELD_CLASS_TYPE_ENUM: + { + struct ctf_field_class_int *int_fc = ctf_field_class_as_int(fc); + + if (field_name && strcmp(field_name, id_name) == 0) { + int_fc->meaning = meaning; + } + + break; + } + case CTF_FIELD_CLASS_TYPE_STRUCT: + { + struct ctf_field_class_struct *struct_fc = ctf_field_class_as_struct(fc); + + for (i = 0; i < struct_fc->members->len; i++) { + struct ctf_named_field_class *named_fc = + ctf_field_class_struct_borrow_member_by_index(struct_fc, i); + + ret = set_int_field_class_meaning_by_name(named_fc->fc, named_fc->name->str, id_name, + meaning); + if (ret) { + goto end; + } + } + + break; + } + case CTF_FIELD_CLASS_TYPE_VARIANT: + { + struct ctf_field_class_variant *var_fc = ctf_field_class_as_variant(fc); + + for (i = 0; i < var_fc->options->len; i++) { + struct ctf_named_field_class *named_fc = + ctf_field_class_variant_borrow_option_by_index(var_fc, i); + + ret = set_int_field_class_meaning_by_name(named_fc->fc, NULL, id_name, meaning); + if (ret) { + goto end; + } + } + + break; + } + case CTF_FIELD_CLASS_TYPE_ARRAY: + case CTF_FIELD_CLASS_TYPE_SEQUENCE: + { + struct ctf_field_class_array_base *array_fc = ctf_field_class_as_array_base(fc); + + ret = set_int_field_class_meaning_by_name(array_fc->elem_fc, NULL, id_name, meaning); + if (ret) { + goto end; + } + + break; + } + default: + break; + } end: - return ret; + return ret; } -static -int update_stream_class_meanings(struct ctf_stream_class *sc) +static int update_stream_class_meanings(struct ctf_stream_class *sc) { - int ret = 0; - struct ctf_field_class_int *int_fc; - uint64_t i; - - if (!sc->is_translated) { - if (sc->packet_context_fc) { - int_fc = ctf_field_class_struct_borrow_member_int_field_class_by_name( - ctf_field_class_as_struct(sc->packet_context_fc), "timestamp_begin"); - if (int_fc) { - int_fc->meaning = CTF_FIELD_CLASS_MEANING_PACKET_BEGINNING_TIME; - } - - int_fc = ctf_field_class_struct_borrow_member_int_field_class_by_name( - ctf_field_class_as_struct(sc->packet_context_fc), "timestamp_end"); - if (int_fc) { - int_fc->meaning = CTF_FIELD_CLASS_MEANING_PACKET_END_TIME; - - /* - * Remove mapped clock class to avoid updating - * the clock immediately when decoding. - */ - int_fc->mapped_clock_class = NULL; - } - - int_fc = ctf_field_class_struct_borrow_member_int_field_class_by_name( - ctf_field_class_as_struct(sc->packet_context_fc), "events_discarded"); - if (int_fc) { - int_fc->meaning = CTF_FIELD_CLASS_MEANING_DISC_EV_REC_COUNTER_SNAPSHOT; - } - - int_fc = ctf_field_class_struct_borrow_member_int_field_class_by_name( - ctf_field_class_as_struct(sc->packet_context_fc), "packet_seq_num"); - if (int_fc) { - int_fc->meaning = CTF_FIELD_CLASS_MEANING_PACKET_COUNTER_SNAPSHOT; - - } - - int_fc = ctf_field_class_struct_borrow_member_int_field_class_by_name( - ctf_field_class_as_struct(sc->packet_context_fc), "packet_size"); - if (int_fc) { - int_fc->meaning = CTF_FIELD_CLASS_MEANING_EXP_PACKET_TOTAL_SIZE; - } - - int_fc = ctf_field_class_struct_borrow_member_int_field_class_by_name( - ctf_field_class_as_struct(sc->packet_context_fc), "content_size"); - if (int_fc) { - int_fc->meaning = CTF_FIELD_CLASS_MEANING_EXP_PACKET_CONTENT_SIZE; - } - } - - if (sc->event_header_fc) { - ret = set_int_field_class_meaning_by_name( - sc->event_header_fc, NULL, "id", - CTF_FIELD_CLASS_MEANING_EVENT_CLASS_ID); - if (ret) { - goto end; - } - } - } - - for (i = 0; i < sc->event_classes->len; i++) { - struct ctf_event_class *ec = (ctf_event_class *) sc->event_classes->pdata[i]; - - if (ec->is_translated) { - continue; - } - } + int ret = 0; + struct ctf_field_class_int *int_fc; + uint64_t i; + + if (!sc->is_translated) { + if (sc->packet_context_fc) { + int_fc = ctf_field_class_struct_borrow_member_int_field_class_by_name( + ctf_field_class_as_struct(sc->packet_context_fc), "timestamp_begin"); + if (int_fc) { + int_fc->meaning = CTF_FIELD_CLASS_MEANING_PACKET_BEGINNING_TIME; + } + + int_fc = ctf_field_class_struct_borrow_member_int_field_class_by_name( + ctf_field_class_as_struct(sc->packet_context_fc), "timestamp_end"); + if (int_fc) { + int_fc->meaning = CTF_FIELD_CLASS_MEANING_PACKET_END_TIME; + + /* + * Remove mapped clock class to avoid updating + * the clock immediately when decoding. + */ + int_fc->mapped_clock_class = NULL; + } + + int_fc = ctf_field_class_struct_borrow_member_int_field_class_by_name( + ctf_field_class_as_struct(sc->packet_context_fc), "events_discarded"); + if (int_fc) { + int_fc->meaning = CTF_FIELD_CLASS_MEANING_DISC_EV_REC_COUNTER_SNAPSHOT; + } + + int_fc = ctf_field_class_struct_borrow_member_int_field_class_by_name( + ctf_field_class_as_struct(sc->packet_context_fc), "packet_seq_num"); + if (int_fc) { + int_fc->meaning = CTF_FIELD_CLASS_MEANING_PACKET_COUNTER_SNAPSHOT; + } + + int_fc = ctf_field_class_struct_borrow_member_int_field_class_by_name( + ctf_field_class_as_struct(sc->packet_context_fc), "packet_size"); + if (int_fc) { + int_fc->meaning = CTF_FIELD_CLASS_MEANING_EXP_PACKET_TOTAL_SIZE; + } + + int_fc = ctf_field_class_struct_borrow_member_int_field_class_by_name( + ctf_field_class_as_struct(sc->packet_context_fc), "content_size"); + if (int_fc) { + int_fc->meaning = CTF_FIELD_CLASS_MEANING_EXP_PACKET_CONTENT_SIZE; + } + } + + if (sc->event_header_fc) { + ret = set_int_field_class_meaning_by_name(sc->event_header_fc, NULL, "id", + CTF_FIELD_CLASS_MEANING_EVENT_CLASS_ID); + if (ret) { + goto end; + } + } + } + + for (i = 0; i < sc->event_classes->len; i++) { + struct ctf_event_class *ec = (ctf_event_class *) sc->event_classes->pdata[i]; + + if (ec->is_translated) { + continue; + } + } end: - return ret; + return ret; } BT_HIDDEN int ctf_trace_class_update_meanings(struct ctf_trace_class *ctf_tc) { - int ret = 0; - struct ctf_field_class_int *int_fc; - struct ctf_named_field_class *named_fc; - uint64_t i; - - if (!ctf_tc->is_translated && ctf_tc->packet_header_fc) { - int_fc = ctf_field_class_struct_borrow_member_int_field_class_by_name( - ctf_field_class_as_struct(ctf_tc->packet_header_fc), "magic"); - if (int_fc) { - int_fc->meaning = CTF_FIELD_CLASS_MEANING_MAGIC; - } - - int_fc = ctf_field_class_struct_borrow_member_int_field_class_by_name( - ctf_field_class_as_struct(ctf_tc->packet_header_fc), "stream_id"); - if (int_fc) { - int_fc->meaning = CTF_FIELD_CLASS_MEANING_STREAM_CLASS_ID; - } - - int_fc = ctf_field_class_struct_borrow_member_int_field_class_by_name( - ctf_field_class_as_struct(ctf_tc->packet_header_fc), - "stream_instance_id"); - if (int_fc) { - int_fc->meaning = CTF_FIELD_CLASS_MEANING_DATA_STREAM_ID; - } - - named_fc = ctf_field_class_struct_borrow_member_by_name( - ctf_field_class_as_struct(ctf_tc->packet_header_fc), "uuid"); - if (named_fc && named_fc->fc->type == CTF_FIELD_CLASS_TYPE_ARRAY) { - struct ctf_field_class_array *array_fc = - ctf_field_class_as_array(named_fc->fc); - - array_fc->meaning = CTF_FIELD_CLASS_MEANING_UUID; - } - } - - for (i = 0; i < ctf_tc->stream_classes->len; i++) { - ret = update_stream_class_meanings( - (ctf_stream_class *) ctf_tc->stream_classes->pdata[i]); - if (ret) { - goto end; - } - } + int ret = 0; + struct ctf_field_class_int *int_fc; + struct ctf_named_field_class *named_fc; + uint64_t i; + + if (!ctf_tc->is_translated && ctf_tc->packet_header_fc) { + int_fc = ctf_field_class_struct_borrow_member_int_field_class_by_name( + ctf_field_class_as_struct(ctf_tc->packet_header_fc), "magic"); + if (int_fc) { + int_fc->meaning = CTF_FIELD_CLASS_MEANING_MAGIC; + } + + int_fc = ctf_field_class_struct_borrow_member_int_field_class_by_name( + ctf_field_class_as_struct(ctf_tc->packet_header_fc), "stream_id"); + if (int_fc) { + int_fc->meaning = CTF_FIELD_CLASS_MEANING_STREAM_CLASS_ID; + } + + int_fc = ctf_field_class_struct_borrow_member_int_field_class_by_name( + ctf_field_class_as_struct(ctf_tc->packet_header_fc), "stream_instance_id"); + if (int_fc) { + int_fc->meaning = CTF_FIELD_CLASS_MEANING_DATA_STREAM_ID; + } + + named_fc = ctf_field_class_struct_borrow_member_by_name( + ctf_field_class_as_struct(ctf_tc->packet_header_fc), "uuid"); + if (named_fc && named_fc->fc->type == CTF_FIELD_CLASS_TYPE_ARRAY) { + struct ctf_field_class_array *array_fc = ctf_field_class_as_array(named_fc->fc); + + array_fc->meaning = CTF_FIELD_CLASS_MEANING_UUID; + } + } + + for (i = 0; i < ctf_tc->stream_classes->len; i++) { + ret = update_stream_class_meanings((ctf_stream_class *) ctf_tc->stream_classes->pdata[i]); + if (ret) { + goto end; + } + } end: - return ret; + return ret; } diff --git a/src/plugins/ctf/common/metadata/ctf-meta-update-stream-class-config.cpp b/src/plugins/ctf/common/metadata/ctf-meta-update-stream-class-config.cpp index b3e0d6e0..f783a7e3 100644 --- a/src/plugins/ctf/common/metadata/ctf-meta-update-stream-class-config.cpp +++ b/src/plugins/ctf/common/metadata/ctf-meta-update-stream-class-config.cpp @@ -17,56 +17,49 @@ BT_HIDDEN int ctf_trace_class_update_stream_class_config(struct ctf_trace_class *ctf_tc) { - struct ctf_field_class_int *int_fc; - uint64_t i; + struct ctf_field_class_int *int_fc; + uint64_t i; - for (i = 0; i < ctf_tc->stream_classes->len; i++) { - struct ctf_stream_class *sc = - (ctf_stream_class *) ctf_tc->stream_classes->pdata[i]; + for (i = 0; i < ctf_tc->stream_classes->len; i++) { + struct ctf_stream_class *sc = (ctf_stream_class *) ctf_tc->stream_classes->pdata[i]; - if (sc->is_translated) { - continue; - } + if (sc->is_translated) { + continue; + } - if (!sc->packet_context_fc) { - continue; - } + if (!sc->packet_context_fc) { + continue; + } - int_fc = ctf_field_class_struct_borrow_member_int_field_class_by_name( - ctf_field_class_as_struct(sc->packet_context_fc), "timestamp_begin"); - if (int_fc && int_fc->meaning == - CTF_FIELD_CLASS_MEANING_PACKET_BEGINNING_TIME) { - sc->packets_have_ts_begin = true; - } + int_fc = ctf_field_class_struct_borrow_member_int_field_class_by_name( + ctf_field_class_as_struct(sc->packet_context_fc), "timestamp_begin"); + if (int_fc && int_fc->meaning == CTF_FIELD_CLASS_MEANING_PACKET_BEGINNING_TIME) { + sc->packets_have_ts_begin = true; + } - int_fc = ctf_field_class_struct_borrow_member_int_field_class_by_name( - ctf_field_class_as_struct(sc->packet_context_fc), "timestamp_end"); - if (int_fc && int_fc->meaning == - CTF_FIELD_CLASS_MEANING_PACKET_END_TIME) { - sc->packets_have_ts_end = true; - } + int_fc = ctf_field_class_struct_borrow_member_int_field_class_by_name( + ctf_field_class_as_struct(sc->packet_context_fc), "timestamp_end"); + if (int_fc && int_fc->meaning == CTF_FIELD_CLASS_MEANING_PACKET_END_TIME) { + sc->packets_have_ts_end = true; + } - int_fc = ctf_field_class_struct_borrow_member_int_field_class_by_name( - ctf_field_class_as_struct(sc->packet_context_fc), "events_discarded"); - if (int_fc && int_fc->meaning == - CTF_FIELD_CLASS_MEANING_DISC_EV_REC_COUNTER_SNAPSHOT) { - sc->has_discarded_events = true; - } + int_fc = ctf_field_class_struct_borrow_member_int_field_class_by_name( + ctf_field_class_as_struct(sc->packet_context_fc), "events_discarded"); + if (int_fc && int_fc->meaning == CTF_FIELD_CLASS_MEANING_DISC_EV_REC_COUNTER_SNAPSHOT) { + sc->has_discarded_events = true; + } - sc->discarded_events_have_default_cs = - sc->has_discarded_events && sc->packets_have_ts_begin && - sc->packets_have_ts_end; - int_fc = ctf_field_class_struct_borrow_member_int_field_class_by_name( - ctf_field_class_as_struct(sc->packet_context_fc), "packet_seq_num"); - if (int_fc && int_fc->meaning == - CTF_FIELD_CLASS_MEANING_PACKET_COUNTER_SNAPSHOT) { - sc->has_discarded_packets = true; - } + sc->discarded_events_have_default_cs = + sc->has_discarded_events && sc->packets_have_ts_begin && sc->packets_have_ts_end; + int_fc = ctf_field_class_struct_borrow_member_int_field_class_by_name( + ctf_field_class_as_struct(sc->packet_context_fc), "packet_seq_num"); + if (int_fc && int_fc->meaning == CTF_FIELD_CLASS_MEANING_PACKET_COUNTER_SNAPSHOT) { + sc->has_discarded_packets = true; + } - sc->discarded_packets_have_default_cs = - sc->has_discarded_packets && - sc->packets_have_ts_begin && sc->packets_have_ts_end; - } + sc->discarded_packets_have_default_cs = + sc->has_discarded_packets && sc->packets_have_ts_begin && sc->packets_have_ts_end; + } - return 0; + return 0; } diff --git a/src/plugins/ctf/common/metadata/ctf-meta-update-text-array-sequence.cpp b/src/plugins/ctf/common/metadata/ctf-meta-update-text-array-sequence.cpp index 186b98a6..55dd27ad 100644 --- a/src/plugins/ctf/common/metadata/ctf-meta-update-text-array-sequence.cpp +++ b/src/plugins/ctf/common/metadata/ctf-meta-update-text-array-sequence.cpp @@ -14,152 +14,140 @@ #include "ctf-meta-visitors.hpp" -static inline -int set_text_array_sequence_field_class(struct ctf_field_class *fc) +static inline int set_text_array_sequence_field_class(struct ctf_field_class *fc) { - int ret = 0; - uint64_t i; - - if (!fc) { - goto end; - } - - switch (fc->type) { - case CTF_FIELD_CLASS_TYPE_STRUCT: - { - struct ctf_field_class_struct *struct_fc = ctf_field_class_as_struct(fc); - - for (i = 0; i < struct_fc->members->len; i++) { - struct ctf_named_field_class *named_fc = - ctf_field_class_struct_borrow_member_by_index( - struct_fc, i); - - ret = set_text_array_sequence_field_class(named_fc->fc); - if (ret) { - goto end; - } - } - - break; - } - case CTF_FIELD_CLASS_TYPE_VARIANT: - { - struct ctf_field_class_variant *var_fc = ctf_field_class_as_variant(fc); - - for (i = 0; i < var_fc->options->len; i++) { - struct ctf_named_field_class *named_fc = - ctf_field_class_variant_borrow_option_by_index( - var_fc, i); - - ret = set_text_array_sequence_field_class(named_fc->fc); - if (ret) { - goto end; - } - } - - break; - } - case CTF_FIELD_CLASS_TYPE_ARRAY: - case CTF_FIELD_CLASS_TYPE_SEQUENCE: - { - struct ctf_field_class_array_base *array_fc = ctf_field_class_as_array_base(fc); - - if (array_fc->elem_fc->type == CTF_FIELD_CLASS_TYPE_INT || - array_fc->elem_fc->type == CTF_FIELD_CLASS_TYPE_ENUM) { - struct ctf_field_class_int *int_fc = - ctf_field_class_as_int(array_fc->elem_fc); - - if (int_fc->base.base.alignment == 8 && - int_fc->base.size == 8 && - int_fc->encoding == CTF_ENCODING_UTF8) { - array_fc->is_text = true; - - /* - * Force integer element to be unsigned; - * this makes the decoder enter a single - * path when reading a text - * array/sequence and we can safely - * decode bytes as characters anyway. - */ - int_fc->is_signed = false; - } - } - - ret = set_text_array_sequence_field_class(array_fc->elem_fc); - if (ret) { - goto end; - } - - break; - } - default: - break; - } + int ret = 0; + uint64_t i; + + if (!fc) { + goto end; + } + + switch (fc->type) { + case CTF_FIELD_CLASS_TYPE_STRUCT: + { + struct ctf_field_class_struct *struct_fc = ctf_field_class_as_struct(fc); + + for (i = 0; i < struct_fc->members->len; i++) { + struct ctf_named_field_class *named_fc = + ctf_field_class_struct_borrow_member_by_index(struct_fc, i); + + ret = set_text_array_sequence_field_class(named_fc->fc); + if (ret) { + goto end; + } + } + + break; + } + case CTF_FIELD_CLASS_TYPE_VARIANT: + { + struct ctf_field_class_variant *var_fc = ctf_field_class_as_variant(fc); + + for (i = 0; i < var_fc->options->len; i++) { + struct ctf_named_field_class *named_fc = + ctf_field_class_variant_borrow_option_by_index(var_fc, i); + + ret = set_text_array_sequence_field_class(named_fc->fc); + if (ret) { + goto end; + } + } + + break; + } + case CTF_FIELD_CLASS_TYPE_ARRAY: + case CTF_FIELD_CLASS_TYPE_SEQUENCE: + { + struct ctf_field_class_array_base *array_fc = ctf_field_class_as_array_base(fc); + + if (array_fc->elem_fc->type == CTF_FIELD_CLASS_TYPE_INT || + array_fc->elem_fc->type == CTF_FIELD_CLASS_TYPE_ENUM) { + struct ctf_field_class_int *int_fc = ctf_field_class_as_int(array_fc->elem_fc); + + if (int_fc->base.base.alignment == 8 && int_fc->base.size == 8 && + int_fc->encoding == CTF_ENCODING_UTF8) { + array_fc->is_text = true; + + /* + * Force integer element to be unsigned; + * this makes the decoder enter a single + * path when reading a text + * array/sequence and we can safely + * decode bytes as characters anyway. + */ + int_fc->is_signed = false; + } + } + + ret = set_text_array_sequence_field_class(array_fc->elem_fc); + if (ret) { + goto end; + } + + break; + } + default: + break; + } end: - return ret; + return ret; } BT_HIDDEN int ctf_trace_class_update_text_array_sequence(struct ctf_trace_class *ctf_tc) { - int ret = 0; - uint64_t i; - - if (!ctf_tc->is_translated) { - ret = set_text_array_sequence_field_class( - ctf_tc->packet_header_fc); - if (ret) { - goto end; - } - } - - for (i = 0; i < ctf_tc->stream_classes->len; i++) { - ctf_stream_class *sc = (ctf_stream_class *) ctf_tc->stream_classes->pdata[i]; - uint64_t j; - - if (!sc->is_translated) { - ret = set_text_array_sequence_field_class( - sc->packet_context_fc); - if (ret) { - goto end; - } - - ret = set_text_array_sequence_field_class( - sc->event_header_fc); - if (ret) { - goto end; - } - - ret = set_text_array_sequence_field_class( - sc->event_common_context_fc); - if (ret) { - goto end; - } - } - - for (j = 0; j < sc->event_classes->len; j++) { - struct ctf_event_class *ec = - (ctf_event_class *) sc->event_classes->pdata[j]; - - if (ec->is_translated) { - continue; - } - - ret = set_text_array_sequence_field_class( - ec->spec_context_fc); - if (ret) { - goto end; - } - - ret = set_text_array_sequence_field_class( - ec->payload_fc); - if (ret) { - goto end; - } - } - } + int ret = 0; + uint64_t i; + + if (!ctf_tc->is_translated) { + ret = set_text_array_sequence_field_class(ctf_tc->packet_header_fc); + if (ret) { + goto end; + } + } + + for (i = 0; i < ctf_tc->stream_classes->len; i++) { + ctf_stream_class *sc = (ctf_stream_class *) ctf_tc->stream_classes->pdata[i]; + uint64_t j; + + if (!sc->is_translated) { + ret = set_text_array_sequence_field_class(sc->packet_context_fc); + if (ret) { + goto end; + } + + ret = set_text_array_sequence_field_class(sc->event_header_fc); + if (ret) { + goto end; + } + + ret = set_text_array_sequence_field_class(sc->event_common_context_fc); + if (ret) { + goto end; + } + } + + for (j = 0; j < sc->event_classes->len; j++) { + struct ctf_event_class *ec = (ctf_event_class *) sc->event_classes->pdata[j]; + + if (ec->is_translated) { + continue; + } + + ret = set_text_array_sequence_field_class(ec->spec_context_fc); + if (ret) { + goto end; + } + + ret = set_text_array_sequence_field_class(ec->payload_fc); + if (ret) { + goto end; + } + } + } end: - return ret; + return ret; } diff --git a/src/plugins/ctf/common/metadata/ctf-meta-update-value-storing-indexes.cpp b/src/plugins/ctf/common/metadata/ctf-meta-update-value-storing-indexes.cpp index 794c5422..5962ae2e 100644 --- a/src/plugins/ctf/common/metadata/ctf-meta-update-value-storing-indexes.cpp +++ b/src/plugins/ctf/common/metadata/ctf-meta-update-value-storing-indexes.cpp @@ -14,153 +14,140 @@ #include "ctf-meta-visitors.hpp" -static -int update_field_class_stored_value_index(struct ctf_field_class *fc, - struct ctf_trace_class *tc, - struct ctf_stream_class *sc, - struct ctf_event_class *ec) +static int update_field_class_stored_value_index(struct ctf_field_class *fc, + struct ctf_trace_class *tc, + struct ctf_stream_class *sc, + struct ctf_event_class *ec) { - int ret = 0; - uint64_t i; - struct ctf_field_path *field_path = NULL; - struct ctf_field_class_int *tgt_fc = NULL; - uint64_t *stored_value_index = NULL; - - if (!fc) { - goto end; - } - - switch (fc->type) { - case CTF_FIELD_CLASS_TYPE_VARIANT: - { - ctf_field_class_variant *var_fc = ctf_field_class_as_variant(fc); - - field_path = &var_fc->tag_path; - stored_value_index = &var_fc->stored_tag_index; - tgt_fc = &var_fc->tag_fc->base; - break; - } - case CTF_FIELD_CLASS_TYPE_SEQUENCE: - { - struct ctf_field_class_sequence *seq_fc = ctf_field_class_as_sequence(fc); - - field_path = &seq_fc->length_path; - stored_value_index = &seq_fc->stored_length_index; - tgt_fc = seq_fc->length_fc; - break; - } - default: - break; - } - - if (field_path) { - BT_ASSERT(tgt_fc); - BT_ASSERT(tgt_fc->base.base.type == CTF_FIELD_CLASS_TYPE_INT || - tgt_fc->base.base.type == CTF_FIELD_CLASS_TYPE_ENUM); - if (tgt_fc->storing_index >= 0) { - /* Already storing its value */ - *stored_value_index = (uint64_t) tgt_fc->storing_index; - } else { - /* Not storing its value: allocate new index */ - tgt_fc->storing_index = tc->stored_value_count; - *stored_value_index = (uint64_t) tgt_fc->storing_index; - tc->stored_value_count++; - } - } - - switch (fc->type) { - case CTF_FIELD_CLASS_TYPE_STRUCT: - { - struct ctf_field_class_struct *struct_fc = ctf_field_class_as_struct(fc); - - for (i = 0; i < struct_fc->members->len; i++) { - struct ctf_named_field_class *named_fc = - ctf_field_class_struct_borrow_member_by_index( - struct_fc, i); - - ret = update_field_class_stored_value_index(named_fc->fc, - tc, sc, ec); - if (ret) { - goto end; - } - } - - break; - } - case CTF_FIELD_CLASS_TYPE_VARIANT: - { - struct ctf_field_class_variant *var_fc = ctf_field_class_as_variant(fc); - - for (i = 0; i < var_fc->options->len; i++) { - struct ctf_named_field_class *named_fc = - ctf_field_class_variant_borrow_option_by_index( - var_fc, i); - - ret = update_field_class_stored_value_index(named_fc->fc, - tc, sc, ec); - if (ret) { - goto end; - } - } - - break; - } - case CTF_FIELD_CLASS_TYPE_ARRAY: - case CTF_FIELD_CLASS_TYPE_SEQUENCE: - { - struct ctf_field_class_array_base *array_fc = ctf_field_class_as_array_base(fc); - - ret = update_field_class_stored_value_index(array_fc->elem_fc, - tc, sc, ec); - if (ret) { - goto end; - } - - break; - } - default: - break; - } + int ret = 0; + uint64_t i; + struct ctf_field_path *field_path = NULL; + struct ctf_field_class_int *tgt_fc = NULL; + uint64_t *stored_value_index = NULL; + + if (!fc) { + goto end; + } + + switch (fc->type) { + case CTF_FIELD_CLASS_TYPE_VARIANT: + { + ctf_field_class_variant *var_fc = ctf_field_class_as_variant(fc); + + field_path = &var_fc->tag_path; + stored_value_index = &var_fc->stored_tag_index; + tgt_fc = &var_fc->tag_fc->base; + break; + } + case CTF_FIELD_CLASS_TYPE_SEQUENCE: + { + struct ctf_field_class_sequence *seq_fc = ctf_field_class_as_sequence(fc); + + field_path = &seq_fc->length_path; + stored_value_index = &seq_fc->stored_length_index; + tgt_fc = seq_fc->length_fc; + break; + } + default: + break; + } + + if (field_path) { + BT_ASSERT(tgt_fc); + BT_ASSERT(tgt_fc->base.base.type == CTF_FIELD_CLASS_TYPE_INT || + tgt_fc->base.base.type == CTF_FIELD_CLASS_TYPE_ENUM); + if (tgt_fc->storing_index >= 0) { + /* Already storing its value */ + *stored_value_index = (uint64_t) tgt_fc->storing_index; + } else { + /* Not storing its value: allocate new index */ + tgt_fc->storing_index = tc->stored_value_count; + *stored_value_index = (uint64_t) tgt_fc->storing_index; + tc->stored_value_count++; + } + } + + switch (fc->type) { + case CTF_FIELD_CLASS_TYPE_STRUCT: + { + struct ctf_field_class_struct *struct_fc = ctf_field_class_as_struct(fc); + + for (i = 0; i < struct_fc->members->len; i++) { + struct ctf_named_field_class *named_fc = + ctf_field_class_struct_borrow_member_by_index(struct_fc, i); + + ret = update_field_class_stored_value_index(named_fc->fc, tc, sc, ec); + if (ret) { + goto end; + } + } + + break; + } + case CTF_FIELD_CLASS_TYPE_VARIANT: + { + struct ctf_field_class_variant *var_fc = ctf_field_class_as_variant(fc); + + for (i = 0; i < var_fc->options->len; i++) { + struct ctf_named_field_class *named_fc = + ctf_field_class_variant_borrow_option_by_index(var_fc, i); + + ret = update_field_class_stored_value_index(named_fc->fc, tc, sc, ec); + if (ret) { + goto end; + } + } + + break; + } + case CTF_FIELD_CLASS_TYPE_ARRAY: + case CTF_FIELD_CLASS_TYPE_SEQUENCE: + { + struct ctf_field_class_array_base *array_fc = ctf_field_class_as_array_base(fc); + + ret = update_field_class_stored_value_index(array_fc->elem_fc, tc, sc, ec); + if (ret) { + goto end; + } + + break; + } + default: + break; + } end: - return ret; + return ret; } BT_HIDDEN int ctf_trace_class_update_value_storing_indexes(struct ctf_trace_class *ctf_tc) { - uint64_t i; - - if (!ctf_tc->is_translated) { - update_field_class_stored_value_index( - ctf_tc->packet_header_fc, ctf_tc, NULL, NULL); - } - - for (i = 0; i < ctf_tc->stream_classes->len; i++) { - uint64_t j; - ctf_stream_class *sc = (ctf_stream_class *) ctf_tc->stream_classes->pdata[i]; - - if (!sc->is_translated) { - update_field_class_stored_value_index(sc->packet_context_fc, - ctf_tc, sc, NULL); - update_field_class_stored_value_index(sc->event_header_fc, - ctf_tc, sc, NULL); - update_field_class_stored_value_index( - sc->event_common_context_fc, ctf_tc, sc, NULL); - } - - for (j = 0; j < sc->event_classes->len; j++) { - struct ctf_event_class *ec = - (ctf_event_class *) sc->event_classes->pdata[j]; - - if (!ec->is_translated) { - update_field_class_stored_value_index( - ec->spec_context_fc, ctf_tc, sc, ec); - update_field_class_stored_value_index( - ec->payload_fc, ctf_tc, sc, ec); - } - } - } - - return 0; + uint64_t i; + + if (!ctf_tc->is_translated) { + update_field_class_stored_value_index(ctf_tc->packet_header_fc, ctf_tc, NULL, NULL); + } + + for (i = 0; i < ctf_tc->stream_classes->len; i++) { + uint64_t j; + ctf_stream_class *sc = (ctf_stream_class *) ctf_tc->stream_classes->pdata[i]; + + if (!sc->is_translated) { + update_field_class_stored_value_index(sc->packet_context_fc, ctf_tc, sc, NULL); + update_field_class_stored_value_index(sc->event_header_fc, ctf_tc, sc, NULL); + update_field_class_stored_value_index(sc->event_common_context_fc, ctf_tc, sc, NULL); + } + + for (j = 0; j < sc->event_classes->len; j++) { + struct ctf_event_class *ec = (ctf_event_class *) sc->event_classes->pdata[j]; + + if (!ec->is_translated) { + update_field_class_stored_value_index(ec->spec_context_fc, ctf_tc, sc, ec); + update_field_class_stored_value_index(ec->payload_fc, ctf_tc, sc, ec); + } + } + } + + return 0; } diff --git a/src/plugins/ctf/common/metadata/ctf-meta-validate.cpp b/src/plugins/ctf/common/metadata/ctf-meta-validate.cpp index d28a5fe8..4d531ebb 100644 --- a/src/plugins/ctf/common/metadata/ctf-meta-validate.cpp +++ b/src/plugins/ctf/common/metadata/ctf-meta-validate.cpp @@ -4,10 +4,10 @@ * Copyright 2018 Philippe Proulx */ -#define BT_COMP_LOG_SELF_COMP (log_cfg->self_comp) +#define BT_COMP_LOG_SELF_COMP (log_cfg->self_comp) #define BT_COMP_LOG_SELF_COMP_CLASS (log_cfg->self_comp_class) -#define BT_LOG_OUTPUT_LEVEL (log_cfg->log_level) -#define BT_LOG_TAG "PLUGIN/CTF/META/VALIDATE" +#define BT_LOG_OUTPUT_LEVEL (log_cfg->log_level) +#define BT_LOG_TAG "PLUGIN/CTF/META/VALIDATE" #include "logging/comp-logging.h" #include @@ -21,325 +21,321 @@ #include "ctf-meta-visitors.hpp" #include "logging.hpp" -static -int validate_stream_class(struct ctf_stream_class *sc, - struct meta_log_config *log_cfg) +static int validate_stream_class(struct ctf_stream_class *sc, struct meta_log_config *log_cfg) { - int ret = 0; - struct ctf_field_class_int *int_fc; - struct ctf_field_class *fc; - - if (sc->is_translated) { - goto end; - } - - fc = ctf_field_class_struct_borrow_member_field_class_by_name( - ctf_field_class_as_struct(sc->packet_context_fc), "timestamp_begin"); - if (fc) { - if (fc->type != CTF_FIELD_CLASS_TYPE_INT && - fc->type != CTF_FIELD_CLASS_TYPE_ENUM) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet context field class: " - "`timestamp_begin` member is not an integer field class."); - goto invalid; - } - - int_fc = ctf_field_class_as_int(fc); - - if (int_fc->is_signed) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet context field class: " - "`timestamp_begin` member is signed."); - goto invalid; - } - } - - fc = ctf_field_class_struct_borrow_member_field_class_by_name( - ctf_field_class_as_struct(sc->packet_context_fc), "timestamp_end"); - if (fc) { - if (fc->type != CTF_FIELD_CLASS_TYPE_INT && - fc->type != CTF_FIELD_CLASS_TYPE_ENUM) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet context field class: " - "`timestamp_end` member is not an integer field class."); - goto invalid; - } - - int_fc = ctf_field_class_as_int(fc); - - if (int_fc->is_signed) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet context field class: " - "`timestamp_end` member is signed."); - goto invalid; - } - } - - fc = ctf_field_class_struct_borrow_member_field_class_by_name( - ctf_field_class_as_struct(sc->packet_context_fc), "events_discarded"); - if (fc) { - if (fc->type != CTF_FIELD_CLASS_TYPE_INT && - fc->type != CTF_FIELD_CLASS_TYPE_ENUM) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet context field class: " - "`events_discarded` member is not an integer field class."); - goto invalid; - } - - int_fc = ctf_field_class_as_int(fc); - - if (int_fc->is_signed) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet context field class: " - "`events_discarded` member is signed."); - goto invalid; - } - } - - fc = ctf_field_class_struct_borrow_member_field_class_by_name( - ctf_field_class_as_struct(sc->packet_context_fc), "packet_seq_num"); - if (fc) { - if (fc->type != CTF_FIELD_CLASS_TYPE_INT && - fc->type != CTF_FIELD_CLASS_TYPE_ENUM) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet context field class: " - "`packet_seq_num` member is not an integer field class."); - goto invalid; - } - - int_fc = ctf_field_class_as_int(fc); - - if (int_fc->is_signed) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet context field class: " - "`packet_seq_num` member is signed."); - goto invalid; - } - } - - fc = ctf_field_class_struct_borrow_member_field_class_by_name( - ctf_field_class_as_struct(sc->packet_context_fc), "packet_size"); - if (fc) { - if (fc->type != CTF_FIELD_CLASS_TYPE_INT && - fc->type != CTF_FIELD_CLASS_TYPE_ENUM) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet context field class: " - "`packet_size` member is not an integer field class."); - goto invalid; - } - - int_fc = ctf_field_class_as_int(fc); - - if (int_fc->is_signed) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet context field class: " - "`packet_size` member is signed."); - goto invalid; - } - } - - fc = ctf_field_class_struct_borrow_member_field_class_by_name( - ctf_field_class_as_struct(sc->packet_context_fc), "content_size"); - if (fc) { - if (fc->type != CTF_FIELD_CLASS_TYPE_INT && - fc->type != CTF_FIELD_CLASS_TYPE_ENUM) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet context field class: " - "`content_size` member is not an integer field class."); - goto invalid; - } - - int_fc = ctf_field_class_as_int(fc); - - if (int_fc->is_signed) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet context field class: " - "`content_size` member is signed."); - goto invalid; - } - } - - fc = ctf_field_class_struct_borrow_member_field_class_by_name( - ctf_field_class_as_struct(sc->event_header_fc), "id"); - if (fc) { - if (fc->type != CTF_FIELD_CLASS_TYPE_INT && - fc->type != CTF_FIELD_CLASS_TYPE_ENUM) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid event header field class: " - "`id` member is not an integer field class."); - goto invalid; - } - - int_fc = ctf_field_class_as_int(fc); - - if (int_fc->is_signed) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid event header field class: " - "`id` member is signed."); - goto invalid; - } - } else { - if (sc->event_classes->len > 1) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid event header field class: " - "missing `id` member as there's " - "more than one event class."); - goto invalid; - } - } - - goto end; + int ret = 0; + struct ctf_field_class_int *int_fc; + struct ctf_field_class *fc; + + if (sc->is_translated) { + goto end; + } + + fc = ctf_field_class_struct_borrow_member_field_class_by_name( + ctf_field_class_as_struct(sc->packet_context_fc), "timestamp_begin"); + if (fc) { + if (fc->type != CTF_FIELD_CLASS_TYPE_INT && fc->type != CTF_FIELD_CLASS_TYPE_ENUM) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Invalid packet context field class: " + "`timestamp_begin` member is not an integer field class."); + goto invalid; + } + + int_fc = ctf_field_class_as_int(fc); + + if (int_fc->is_signed) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet context field class: " + "`timestamp_begin` member is signed."); + goto invalid; + } + } + + fc = ctf_field_class_struct_borrow_member_field_class_by_name( + ctf_field_class_as_struct(sc->packet_context_fc), "timestamp_end"); + if (fc) { + if (fc->type != CTF_FIELD_CLASS_TYPE_INT && fc->type != CTF_FIELD_CLASS_TYPE_ENUM) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Invalid packet context field class: " + "`timestamp_end` member is not an integer field class."); + goto invalid; + } + + int_fc = ctf_field_class_as_int(fc); + + if (int_fc->is_signed) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet context field class: " + "`timestamp_end` member is signed."); + goto invalid; + } + } + + fc = ctf_field_class_struct_borrow_member_field_class_by_name( + ctf_field_class_as_struct(sc->packet_context_fc), "events_discarded"); + if (fc) { + if (fc->type != CTF_FIELD_CLASS_TYPE_INT && fc->type != CTF_FIELD_CLASS_TYPE_ENUM) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Invalid packet context field class: " + "`events_discarded` member is not an integer field class."); + goto invalid; + } + + int_fc = ctf_field_class_as_int(fc); + + if (int_fc->is_signed) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet context field class: " + "`events_discarded` member is signed."); + goto invalid; + } + } + + fc = ctf_field_class_struct_borrow_member_field_class_by_name( + ctf_field_class_as_struct(sc->packet_context_fc), "packet_seq_num"); + if (fc) { + if (fc->type != CTF_FIELD_CLASS_TYPE_INT && fc->type != CTF_FIELD_CLASS_TYPE_ENUM) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Invalid packet context field class: " + "`packet_seq_num` member is not an integer field class."); + goto invalid; + } + + int_fc = ctf_field_class_as_int(fc); + + if (int_fc->is_signed) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet context field class: " + "`packet_seq_num` member is signed."); + goto invalid; + } + } + + fc = ctf_field_class_struct_borrow_member_field_class_by_name( + ctf_field_class_as_struct(sc->packet_context_fc), "packet_size"); + if (fc) { + if (fc->type != CTF_FIELD_CLASS_TYPE_INT && fc->type != CTF_FIELD_CLASS_TYPE_ENUM) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Invalid packet context field class: " + "`packet_size` member is not an integer field class."); + goto invalid; + } + + int_fc = ctf_field_class_as_int(fc); + + if (int_fc->is_signed) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet context field class: " + "`packet_size` member is signed."); + goto invalid; + } + } + + fc = ctf_field_class_struct_borrow_member_field_class_by_name( + ctf_field_class_as_struct(sc->packet_context_fc), "content_size"); + if (fc) { + if (fc->type != CTF_FIELD_CLASS_TYPE_INT && fc->type != CTF_FIELD_CLASS_TYPE_ENUM) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Invalid packet context field class: " + "`content_size` member is not an integer field class."); + goto invalid; + } + + int_fc = ctf_field_class_as_int(fc); + + if (int_fc->is_signed) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet context field class: " + "`content_size` member is signed."); + goto invalid; + } + } + + fc = ctf_field_class_struct_borrow_member_field_class_by_name( + ctf_field_class_as_struct(sc->event_header_fc), "id"); + if (fc) { + if (fc->type != CTF_FIELD_CLASS_TYPE_INT && fc->type != CTF_FIELD_CLASS_TYPE_ENUM) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid event header field class: " + "`id` member is not an integer field class."); + goto invalid; + } + + int_fc = ctf_field_class_as_int(fc); + + if (int_fc->is_signed) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid event header field class: " + "`id` member is signed."); + goto invalid; + } + } else { + if (sc->event_classes->len > 1) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid event header field class: " + "missing `id` member as there's " + "more than one event class."); + goto invalid; + } + } + + goto end; invalid: - ret = -1; + ret = -1; end: - return ret; + return ret; } BT_HIDDEN -int ctf_trace_class_validate(struct ctf_trace_class *ctf_tc, - struct meta_log_config *log_cfg) +int ctf_trace_class_validate(struct ctf_trace_class *ctf_tc, struct meta_log_config *log_cfg) { - int ret = 0; - struct ctf_field_class_int *int_fc; - uint64_t i; - - if (!ctf_tc->is_translated) { - struct ctf_field_class *fc; - - fc = ctf_field_class_struct_borrow_member_field_class_by_name( - ctf_field_class_as_struct(ctf_tc->packet_header_fc), "magic"); - if (fc) { - struct ctf_named_field_class *named_fc = - ctf_field_class_struct_borrow_member_by_index( - ctf_field_class_as_struct(ctf_tc->packet_header_fc), - 0); - - if (named_fc->fc != fc) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet header field class: " - "`magic` member is not the first member."); - goto invalid; - } - - if (fc->type != CTF_FIELD_CLASS_TYPE_INT && - fc->type != CTF_FIELD_CLASS_TYPE_ENUM) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet header field class: " - "`magic` member is not an integer field class."); - goto invalid; - } - - int_fc = ctf_field_class_as_int(fc); - - if (int_fc->is_signed) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet header field class: " - "`magic` member is signed."); - goto invalid; - } - - if (int_fc->base.size != 32) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet header field class: " - "`magic` member is not 32-bit."); - goto invalid; - } - } - - fc = ctf_field_class_struct_borrow_member_field_class_by_name( - ctf_field_class_as_struct(ctf_tc->packet_header_fc), "stream_id"); - if (fc) { - if (fc->type != CTF_FIELD_CLASS_TYPE_INT && - fc->type != CTF_FIELD_CLASS_TYPE_ENUM) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet header field class: " - "`stream_id` member is not an integer field class."); - goto invalid; - } - - int_fc = ctf_field_class_as_int(fc); - - if (int_fc->is_signed) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet header field class: " - "`stream_id` member is signed."); - goto invalid; - } - } else { - if (ctf_tc->stream_classes->len > 1) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet header field class: " - "missing `stream_id` member as there's " - "more than one stream class."); - goto invalid; - } - } - - fc = ctf_field_class_struct_borrow_member_field_class_by_name( - ctf_field_class_as_struct(ctf_tc->packet_header_fc), - "stream_instance_id"); - if (fc) { - if (fc->type != CTF_FIELD_CLASS_TYPE_INT && - fc->type != CTF_FIELD_CLASS_TYPE_ENUM) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet header field class: " - "`stream_instance_id` member is not an integer field class."); - goto invalid; - } - - int_fc = ctf_field_class_as_int(fc); - - if (int_fc->is_signed) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet header field class: " - "`stream_instance_id` member is signed."); - goto invalid; - } - } - - fc = ctf_field_class_struct_borrow_member_field_class_by_name( - ctf_field_class_as_struct(ctf_tc->packet_header_fc), "uuid"); - if (fc) { - if (fc->type != CTF_FIELD_CLASS_TYPE_ARRAY) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet header field class: " - "`uuid` member is not an array field class."); - goto invalid; - } - - ctf_field_class_array *array_fc = ctf_field_class_as_array(fc); - - if (array_fc->length != 16) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet header field class: " - "`uuid` member is not a 16-element array field class."); - goto invalid; - } - - if (array_fc->base.elem_fc->type != CTF_FIELD_CLASS_TYPE_INT) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet header field class: " - "`uuid` member's element field class is not " - "an integer field class."); - goto invalid; - } - - int_fc = ctf_field_class_as_int(array_fc->base.elem_fc); - - if (int_fc->is_signed) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet header field class: " - "`uuid` member's element field class " - "is a signed integer field class."); - goto invalid; - } - - if (int_fc->base.size != 8) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet header field class: " - "`uuid` member's element field class " - "is not an 8-bit integer field class."); - goto invalid; - } - - if (int_fc->base.base.alignment != 8) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet header field class: " - "`uuid` member's element field class's " - "alignment is not 8."); - goto invalid; - } - } - } - - for (i = 0; i < ctf_tc->stream_classes->len; i++) { - struct ctf_stream_class *sc = - (ctf_stream_class *) ctf_tc->stream_classes->pdata[i]; - - ret = validate_stream_class(sc, log_cfg); - if (ret) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid stream class: sc-id=%" PRIu64, sc->id); - goto invalid; - } - } - - goto end; + int ret = 0; + struct ctf_field_class_int *int_fc; + uint64_t i; + + if (!ctf_tc->is_translated) { + struct ctf_field_class *fc; + + fc = ctf_field_class_struct_borrow_member_field_class_by_name( + ctf_field_class_as_struct(ctf_tc->packet_header_fc), "magic"); + if (fc) { + struct ctf_named_field_class *named_fc = ctf_field_class_struct_borrow_member_by_index( + ctf_field_class_as_struct(ctf_tc->packet_header_fc), 0); + + if (named_fc->fc != fc) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet header field class: " + "`magic` member is not the first member."); + goto invalid; + } + + if (fc->type != CTF_FIELD_CLASS_TYPE_INT && fc->type != CTF_FIELD_CLASS_TYPE_ENUM) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Invalid packet header field class: " + "`magic` member is not an integer field class."); + goto invalid; + } + + int_fc = ctf_field_class_as_int(fc); + + if (int_fc->is_signed) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet header field class: " + "`magic` member is signed."); + goto invalid; + } + + if (int_fc->base.size != 32) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet header field class: " + "`magic` member is not 32-bit."); + goto invalid; + } + } + + fc = ctf_field_class_struct_borrow_member_field_class_by_name( + ctf_field_class_as_struct(ctf_tc->packet_header_fc), "stream_id"); + if (fc) { + if (fc->type != CTF_FIELD_CLASS_TYPE_INT && fc->type != CTF_FIELD_CLASS_TYPE_ENUM) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Invalid packet header field class: " + "`stream_id` member is not an integer field class."); + goto invalid; + } + + int_fc = ctf_field_class_as_int(fc); + + if (int_fc->is_signed) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet header field class: " + "`stream_id` member is signed."); + goto invalid; + } + } else { + if (ctf_tc->stream_classes->len > 1) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet header field class: " + "missing `stream_id` member as there's " + "more than one stream class."); + goto invalid; + } + } + + fc = ctf_field_class_struct_borrow_member_field_class_by_name( + ctf_field_class_as_struct(ctf_tc->packet_header_fc), "stream_instance_id"); + if (fc) { + if (fc->type != CTF_FIELD_CLASS_TYPE_INT && fc->type != CTF_FIELD_CLASS_TYPE_ENUM) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Invalid packet header field class: " + "`stream_instance_id` member is not an integer field class."); + goto invalid; + } + + int_fc = ctf_field_class_as_int(fc); + + if (int_fc->is_signed) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet header field class: " + "`stream_instance_id` member is signed."); + goto invalid; + } + } + + fc = ctf_field_class_struct_borrow_member_field_class_by_name( + ctf_field_class_as_struct(ctf_tc->packet_header_fc), "uuid"); + if (fc) { + if (fc->type != CTF_FIELD_CLASS_TYPE_ARRAY) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Invalid packet header field class: " + "`uuid` member is not an array field class."); + goto invalid; + } + + ctf_field_class_array *array_fc = ctf_field_class_as_array(fc); + + if (array_fc->length != 16) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Invalid packet header field class: " + "`uuid` member is not a 16-element array field class."); + goto invalid; + } + + if (array_fc->base.elem_fc->type != CTF_FIELD_CLASS_TYPE_INT) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Invalid packet header field class: " + "`uuid` member's element field class is not " + "an integer field class."); + goto invalid; + } + + int_fc = ctf_field_class_as_int(array_fc->base.elem_fc); + + if (int_fc->is_signed) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet header field class: " + "`uuid` member's element field class " + "is a signed integer field class."); + goto invalid; + } + + if (int_fc->base.size != 8) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet header field class: " + "`uuid` member's element field class " + "is not an 8-bit integer field class."); + goto invalid; + } + + if (int_fc->base.base.alignment != 8) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet header field class: " + "`uuid` member's element field class's " + "alignment is not 8."); + goto invalid; + } + } + } + + for (i = 0; i < ctf_tc->stream_classes->len; i++) { + struct ctf_stream_class *sc = (ctf_stream_class *) ctf_tc->stream_classes->pdata[i]; + + ret = validate_stream_class(sc, log_cfg); + if (ret) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid stream class: sc-id=%" PRIu64, + sc->id); + goto invalid; + } + } + + goto end; invalid: - ret = -1; + ret = -1; end: - return ret; + return ret; } diff --git a/src/plugins/ctf/common/metadata/ctf-meta-visitors.hpp b/src/plugins/ctf/common/metadata/ctf-meta-visitors.hpp index ab227517..a5d27dbd 100644 --- a/src/plugins/ctf/common/metadata/ctf-meta-visitors.hpp +++ b/src/plugins/ctf/common/metadata/ctf-meta-visitors.hpp @@ -16,16 +16,15 @@ struct meta_log_config; BT_HIDDEN int ctf_trace_class_resolve_field_classes(struct ctf_trace_class *tc, - struct meta_log_config *log_cfg); + struct meta_log_config *log_cfg); BT_HIDDEN -int ctf_trace_class_translate(bt_self_component *self_comp, - bt_trace_class *ir_tc, struct ctf_trace_class *tc); +int ctf_trace_class_translate(bt_self_component *self_comp, bt_trace_class *ir_tc, + struct ctf_trace_class *tc); BT_HIDDEN -int ctf_trace_class_update_default_clock_classes( - struct ctf_trace_class *ctf_tc, - struct meta_log_config *log_cfg); +int ctf_trace_class_update_default_clock_classes(struct ctf_trace_class *ctf_tc, + struct meta_log_config *log_cfg); BT_HIDDEN int ctf_trace_class_update_in_ir(struct ctf_trace_class *ctf_tc); @@ -46,12 +45,10 @@ BT_HIDDEN int ctf_trace_class_update_stream_class_config(struct ctf_trace_class *ctf_tc); BT_HIDDEN -int ctf_trace_class_validate(struct ctf_trace_class *ctf_tc, - struct meta_log_config *log_cfg); +int ctf_trace_class_validate(struct ctf_trace_class *ctf_tc, struct meta_log_config *log_cfg); BT_HIDDEN -void ctf_trace_class_warn_meaningless_header_fields( - struct ctf_trace_class *ctf_tc, - struct meta_log_config *log_cfg); +void ctf_trace_class_warn_meaningless_header_fields(struct ctf_trace_class *ctf_tc, + struct meta_log_config *log_cfg); #endif /* _CTF_META_VISITORS_H */ diff --git a/src/plugins/ctf/common/metadata/ctf-meta-warn-meaningless-header-fields.cpp b/src/plugins/ctf/common/metadata/ctf-meta-warn-meaningless-header-fields.cpp index 03daddf9..ccad81cf 100644 --- a/src/plugins/ctf/common/metadata/ctf-meta-warn-meaningless-header-fields.cpp +++ b/src/plugins/ctf/common/metadata/ctf-meta-warn-meaningless-header-fields.cpp @@ -5,8 +5,8 @@ */ #define BT_COMP_LOG_SELF_COMP (log_cfg->self_comp) -#define BT_LOG_OUTPUT_LEVEL (log_cfg->log_level) -#define BT_LOG_TAG "PLUGIN/CTF/META/WARN-MEANINGLESS-HEADER-FIELDS" +#define BT_LOG_OUTPUT_LEVEL (log_cfg->log_level) +#define BT_LOG_TAG "PLUGIN/CTF/META/WARN-MEANINGLESS-HEADER-FIELDS" #include "logging/comp-logging.h" #include @@ -20,122 +20,108 @@ #include "ctf-meta-visitors.hpp" #include "logging.hpp" -static inline -void warn_meaningless_field(const char *name, const char *scope_name, - struct meta_log_config *log_cfg) +static inline void warn_meaningless_field(const char *name, const char *scope_name, + struct meta_log_config *log_cfg) { - BT_ASSERT(name); - BT_COMP_LOGW("User field found in %s: ignoring: name=\"%s\"", - scope_name, name); + BT_ASSERT(name); + BT_COMP_LOGW("User field found in %s: ignoring: name=\"%s\"", scope_name, name); } -static inline -void warn_meaningless_fields(struct ctf_field_class *fc, const char *name, - const char *scope_name, struct meta_log_config *log_cfg) +static inline void warn_meaningless_fields(struct ctf_field_class *fc, const char *name, + const char *scope_name, struct meta_log_config *log_cfg) { - uint64_t i; - - if (!fc) { - goto end; - } - - /* - * 'name' is guaranteed to be non-NULL whenever the field class is not a - * structure. In the case of a structure field class, its members' names - * are used. - */ - switch (fc->type) { - case CTF_FIELD_CLASS_TYPE_FLOAT: - case CTF_FIELD_CLASS_TYPE_STRING: - warn_meaningless_field(name, scope_name, log_cfg); - break; - case CTF_FIELD_CLASS_TYPE_INT: - case CTF_FIELD_CLASS_TYPE_ENUM: - { - struct ctf_field_class_int *int_fc = ctf_field_class_as_int(fc); - - if (int_fc->meaning == CTF_FIELD_CLASS_MEANING_NONE && - !int_fc->mapped_clock_class) { - warn_meaningless_field(name, scope_name, log_cfg); - } - - break; - } - case CTF_FIELD_CLASS_TYPE_STRUCT: - { - struct ctf_field_class_struct *struct_fc = ctf_field_class_as_struct(fc); - - for (i = 0; i < struct_fc->members->len; i++) { - struct ctf_named_field_class *named_fc = - ctf_field_class_struct_borrow_member_by_index( - struct_fc, i); - - warn_meaningless_fields(named_fc->fc, - named_fc->name->str, scope_name, log_cfg); - } - - break; - } - case CTF_FIELD_CLASS_TYPE_VARIANT: - { - struct ctf_field_class_variant *var_fc = ctf_field_class_as_variant(fc); - - for (i = 0; i < var_fc->options->len; i++) { - struct ctf_named_field_class *named_fc = - ctf_field_class_variant_borrow_option_by_index( - var_fc, i); - - warn_meaningless_fields(named_fc->fc, - named_fc->name->str, scope_name, log_cfg); - } - - break; - } - case CTF_FIELD_CLASS_TYPE_ARRAY: - { - struct ctf_field_class_array *array_fc = ctf_field_class_as_array(fc); - - if (array_fc->meaning != CTF_FIELD_CLASS_MEANING_NONE) { - goto end; - } - - } - /* fall-through */ - case CTF_FIELD_CLASS_TYPE_SEQUENCE: - { - struct ctf_field_class_array_base *array_fc = ctf_field_class_as_array_base(fc); - - warn_meaningless_fields(array_fc->elem_fc, name, scope_name, - log_cfg); - break; - } - default: - bt_common_abort(); - } + uint64_t i; + + if (!fc) { + goto end; + } + + /* + * 'name' is guaranteed to be non-NULL whenever the field class is not a + * structure. In the case of a structure field class, its members' names + * are used. + */ + switch (fc->type) { + case CTF_FIELD_CLASS_TYPE_FLOAT: + case CTF_FIELD_CLASS_TYPE_STRING: + warn_meaningless_field(name, scope_name, log_cfg); + break; + case CTF_FIELD_CLASS_TYPE_INT: + case CTF_FIELD_CLASS_TYPE_ENUM: + { + struct ctf_field_class_int *int_fc = ctf_field_class_as_int(fc); + + if (int_fc->meaning == CTF_FIELD_CLASS_MEANING_NONE && !int_fc->mapped_clock_class) { + warn_meaningless_field(name, scope_name, log_cfg); + } + + break; + } + case CTF_FIELD_CLASS_TYPE_STRUCT: + { + struct ctf_field_class_struct *struct_fc = ctf_field_class_as_struct(fc); + + for (i = 0; i < struct_fc->members->len; i++) { + struct ctf_named_field_class *named_fc = + ctf_field_class_struct_borrow_member_by_index(struct_fc, i); + + warn_meaningless_fields(named_fc->fc, named_fc->name->str, scope_name, log_cfg); + } + + break; + } + case CTF_FIELD_CLASS_TYPE_VARIANT: + { + struct ctf_field_class_variant *var_fc = ctf_field_class_as_variant(fc); + + for (i = 0; i < var_fc->options->len; i++) { + struct ctf_named_field_class *named_fc = + ctf_field_class_variant_borrow_option_by_index(var_fc, i); + + warn_meaningless_fields(named_fc->fc, named_fc->name->str, scope_name, log_cfg); + } + + break; + } + case CTF_FIELD_CLASS_TYPE_ARRAY: + { + struct ctf_field_class_array *array_fc = ctf_field_class_as_array(fc); + + if (array_fc->meaning != CTF_FIELD_CLASS_MEANING_NONE) { + goto end; + } + } + /* fall-through */ + case CTF_FIELD_CLASS_TYPE_SEQUENCE: + { + struct ctf_field_class_array_base *array_fc = ctf_field_class_as_array_base(fc); + + warn_meaningless_fields(array_fc->elem_fc, name, scope_name, log_cfg); + break; + } + default: + bt_common_abort(); + } end: - return; + return; } BT_HIDDEN -void ctf_trace_class_warn_meaningless_header_fields( - struct ctf_trace_class *ctf_tc, - struct meta_log_config *log_cfg) +void ctf_trace_class_warn_meaningless_header_fields(struct ctf_trace_class *ctf_tc, + struct meta_log_config *log_cfg) { - uint64_t i; - - if (!ctf_tc->is_translated) { - warn_meaningless_fields( - ctf_tc->packet_header_fc, NULL, "packet header", - log_cfg); - } - - for (i = 0; i < ctf_tc->stream_classes->len; i++) { - ctf_stream_class *sc = (ctf_stream_class *) ctf_tc->stream_classes->pdata[i]; - - if (!sc->is_translated) { - warn_meaningless_fields(sc->event_header_fc, NULL, - "event header", log_cfg); - } - } + uint64_t i; + + if (!ctf_tc->is_translated) { + warn_meaningless_fields(ctf_tc->packet_header_fc, NULL, "packet header", log_cfg); + } + + for (i = 0; i < ctf_tc->stream_classes->len; i++) { + ctf_stream_class *sc = (ctf_stream_class *) ctf_tc->stream_classes->pdata[i]; + + if (!sc->is_translated) { + warn_meaningless_fields(sc->event_header_fc, NULL, "event header", log_cfg); + } + } } diff --git a/src/plugins/ctf/common/metadata/ctf-meta.hpp b/src/plugins/ctf/common/metadata/ctf-meta.hpp index 74c5fac1..ae20f881 100644 --- a/src/plugins/ctf/common/metadata/ctf-meta.hpp +++ b/src/plugins/ctf/common/metadata/ctf-meta.hpp @@ -16,1861 +16,1735 @@ #include #include -enum ctf_field_class_type { - CTF_FIELD_CLASS_TYPE_INT, - CTF_FIELD_CLASS_TYPE_ENUM, - CTF_FIELD_CLASS_TYPE_FLOAT, - CTF_FIELD_CLASS_TYPE_STRING, - CTF_FIELD_CLASS_TYPE_STRUCT, - CTF_FIELD_CLASS_TYPE_ARRAY, - CTF_FIELD_CLASS_TYPE_SEQUENCE, - CTF_FIELD_CLASS_TYPE_VARIANT, +enum ctf_field_class_type +{ + CTF_FIELD_CLASS_TYPE_INT, + CTF_FIELD_CLASS_TYPE_ENUM, + CTF_FIELD_CLASS_TYPE_FLOAT, + CTF_FIELD_CLASS_TYPE_STRING, + CTF_FIELD_CLASS_TYPE_STRUCT, + CTF_FIELD_CLASS_TYPE_ARRAY, + CTF_FIELD_CLASS_TYPE_SEQUENCE, + CTF_FIELD_CLASS_TYPE_VARIANT, }; -enum ctf_field_class_meaning { - CTF_FIELD_CLASS_MEANING_NONE, - CTF_FIELD_CLASS_MEANING_PACKET_BEGINNING_TIME, - CTF_FIELD_CLASS_MEANING_PACKET_END_TIME, - CTF_FIELD_CLASS_MEANING_EVENT_CLASS_ID, - CTF_FIELD_CLASS_MEANING_STREAM_CLASS_ID, - CTF_FIELD_CLASS_MEANING_DATA_STREAM_ID, - CTF_FIELD_CLASS_MEANING_MAGIC, - CTF_FIELD_CLASS_MEANING_PACKET_COUNTER_SNAPSHOT, - CTF_FIELD_CLASS_MEANING_DISC_EV_REC_COUNTER_SNAPSHOT, - CTF_FIELD_CLASS_MEANING_EXP_PACKET_TOTAL_SIZE, - CTF_FIELD_CLASS_MEANING_EXP_PACKET_CONTENT_SIZE, - CTF_FIELD_CLASS_MEANING_UUID, +enum ctf_field_class_meaning +{ + CTF_FIELD_CLASS_MEANING_NONE, + CTF_FIELD_CLASS_MEANING_PACKET_BEGINNING_TIME, + CTF_FIELD_CLASS_MEANING_PACKET_END_TIME, + CTF_FIELD_CLASS_MEANING_EVENT_CLASS_ID, + CTF_FIELD_CLASS_MEANING_STREAM_CLASS_ID, + CTF_FIELD_CLASS_MEANING_DATA_STREAM_ID, + CTF_FIELD_CLASS_MEANING_MAGIC, + CTF_FIELD_CLASS_MEANING_PACKET_COUNTER_SNAPSHOT, + CTF_FIELD_CLASS_MEANING_DISC_EV_REC_COUNTER_SNAPSHOT, + CTF_FIELD_CLASS_MEANING_EXP_PACKET_TOTAL_SIZE, + CTF_FIELD_CLASS_MEANING_EXP_PACKET_CONTENT_SIZE, + CTF_FIELD_CLASS_MEANING_UUID, }; -enum ctf_byte_order { - CTF_BYTE_ORDER_UNKNOWN, - CTF_BYTE_ORDER_DEFAULT, - CTF_BYTE_ORDER_LITTLE, - CTF_BYTE_ORDER_BIG, +enum ctf_byte_order +{ + CTF_BYTE_ORDER_UNKNOWN, + CTF_BYTE_ORDER_DEFAULT, + CTF_BYTE_ORDER_LITTLE, + CTF_BYTE_ORDER_BIG, }; -enum ctf_encoding { - CTF_ENCODING_NONE, - CTF_ENCODING_UTF8, +enum ctf_encoding +{ + CTF_ENCODING_NONE, + CTF_ENCODING_UTF8, }; -enum ctf_scope { - CTF_SCOPE_PACKET_UNKNOWN = -1, - CTF_SCOPE_PACKET_HEADER = 0, - CTF_SCOPE_PACKET_CONTEXT, - CTF_SCOPE_EVENT_HEADER, - CTF_SCOPE_EVENT_COMMON_CONTEXT, - CTF_SCOPE_EVENT_SPECIFIC_CONTEXT, - CTF_SCOPE_EVENT_PAYLOAD, +enum ctf_scope +{ + CTF_SCOPE_PACKET_UNKNOWN = -1, + CTF_SCOPE_PACKET_HEADER = 0, + CTF_SCOPE_PACKET_CONTEXT, + CTF_SCOPE_EVENT_HEADER, + CTF_SCOPE_EVENT_COMMON_CONTEXT, + CTF_SCOPE_EVENT_SPECIFIC_CONTEXT, + CTF_SCOPE_EVENT_PAYLOAD, }; -struct ctf_clock_class { - GString *name; - GString *description; - uint64_t frequency; - uint64_t precision; - int64_t offset_seconds; - uint64_t offset_cycles; - bt_uuid_t uuid; - bool has_uuid; - bool is_absolute; - - /* Weak, set during translation */ - bt_clock_class *ir_cc; +struct ctf_clock_class +{ + GString *name; + GString *description; + uint64_t frequency; + uint64_t precision; + int64_t offset_seconds; + uint64_t offset_cycles; + bt_uuid_t uuid; + bool has_uuid; + bool is_absolute; + + /* Weak, set during translation */ + bt_clock_class *ir_cc; }; -struct ctf_field_class { - enum ctf_field_class_type type; - unsigned int alignment; - bool is_compound; - bool in_ir; +struct ctf_field_class +{ + enum ctf_field_class_type type; + unsigned int alignment; + bool is_compound; + bool in_ir; - /* Weak, set during translation. NULL if `in_ir` is false below. */ - bt_field_class *ir_fc; + /* Weak, set during translation. NULL if `in_ir` is false below. */ + bt_field_class *ir_fc; }; -struct ctf_field_class_bit_array { - struct ctf_field_class base; - enum ctf_byte_order byte_order; - unsigned int size; +struct ctf_field_class_bit_array +{ + struct ctf_field_class base; + enum ctf_byte_order byte_order; + unsigned int size; }; -struct ctf_field_class_int { - struct ctf_field_class_bit_array base; - enum ctf_field_class_meaning meaning; - bool is_signed; - bt_field_class_integer_preferred_display_base disp_base; - enum ctf_encoding encoding; - int64_t storing_index; +struct ctf_field_class_int +{ + struct ctf_field_class_bit_array base; + enum ctf_field_class_meaning meaning; + bool is_signed; + bt_field_class_integer_preferred_display_base disp_base; + enum ctf_encoding encoding; + int64_t storing_index; - /* Weak */ - struct ctf_clock_class *mapped_clock_class; + /* Weak */ + struct ctf_clock_class *mapped_clock_class; }; -struct ctf_range { - union { - uint64_t u; - int64_t i; - } lower; +struct ctf_range +{ + union + { + uint64_t u; + int64_t i; + } lower; - union { - uint64_t u; - int64_t i; - } upper; + union + { + uint64_t u; + int64_t i; + } upper; }; -struct ctf_field_class_enum_mapping { - GString *label; +struct ctf_field_class_enum_mapping +{ + GString *label; - /* Array of `struct ctf_range` */ - GArray *ranges; + /* Array of `struct ctf_range` */ + GArray *ranges; }; -struct ctf_field_class_enum { - struct ctf_field_class_int base; +struct ctf_field_class_enum +{ + struct ctf_field_class_int base; - /* Array of `struct ctf_field_class_enum_mapping` */ - GArray *mappings; + /* Array of `struct ctf_field_class_enum_mapping` */ + GArray *mappings; }; -struct ctf_field_class_float { - struct ctf_field_class_bit_array base; +struct ctf_field_class_float +{ + struct ctf_field_class_bit_array base; }; -struct ctf_field_class_string { - struct ctf_field_class base; - enum ctf_encoding encoding; +struct ctf_field_class_string +{ + struct ctf_field_class base; + enum ctf_encoding encoding; }; -struct ctf_named_field_class { - /* Original name which can include a leading `_` */ - GString *orig_name; +struct ctf_named_field_class +{ + /* Original name which can include a leading `_` */ + GString *orig_name; - /* Name as translated to trace IR (leading `_` removed) */ - GString *name; + /* Name as translated to trace IR (leading `_` removed) */ + GString *name; - /* Owned by this */ - struct ctf_field_class *fc; + /* Owned by this */ + struct ctf_field_class *fc; }; -struct ctf_field_class_struct { - struct ctf_field_class base; +struct ctf_field_class_struct +{ + struct ctf_field_class base; - /* Array of `struct ctf_named_field_class` */ - GArray *members; + /* Array of `struct ctf_named_field_class` */ + GArray *members; }; -struct ctf_field_path { - enum ctf_scope root; +struct ctf_field_path +{ + enum ctf_scope root; - /* Array of `int64_t` */ - GArray *path; + /* Array of `int64_t` */ + GArray *path; }; -struct ctf_field_class_variant_range { - struct ctf_range range; - uint64_t option_index; +struct ctf_field_class_variant_range +{ + struct ctf_range range; + uint64_t option_index; }; -struct ctf_field_class_variant { - struct ctf_field_class base; - GString *tag_ref; - struct ctf_field_path tag_path; - uint64_t stored_tag_index; +struct ctf_field_class_variant +{ + struct ctf_field_class base; + GString *tag_ref; + struct ctf_field_path tag_path; + uint64_t stored_tag_index; - /* Array of `struct ctf_named_field_class` */ - GArray *options; + /* Array of `struct ctf_named_field_class` */ + GArray *options; - /* Array of `struct ctf_field_class_variant_range` */ - GArray *ranges; + /* Array of `struct ctf_field_class_variant_range` */ + GArray *ranges; - /* Weak */ - struct ctf_field_class_enum *tag_fc; + /* Weak */ + struct ctf_field_class_enum *tag_fc; }; -struct ctf_field_class_array_base { - struct ctf_field_class base; - struct ctf_field_class *elem_fc; - bool is_text; +struct ctf_field_class_array_base +{ + struct ctf_field_class base; + struct ctf_field_class *elem_fc; + bool is_text; }; -struct ctf_field_class_array { - struct ctf_field_class_array_base base; - enum ctf_field_class_meaning meaning; - uint64_t length; +struct ctf_field_class_array +{ + struct ctf_field_class_array_base base; + enum ctf_field_class_meaning meaning; + uint64_t length; }; -struct ctf_field_class_sequence { - struct ctf_field_class_array_base base; - GString *length_ref; - struct ctf_field_path length_path; - uint64_t stored_length_index; +struct ctf_field_class_sequence +{ + struct ctf_field_class_array_base base; + GString *length_ref; + struct ctf_field_path length_path; + uint64_t stored_length_index; - /* Weak */ - struct ctf_field_class_int *length_fc; + /* Weak */ + struct ctf_field_class_int *length_fc; }; -struct ctf_event_class { - GString *name; - uint64_t id; - GString *emf_uri; - bt_event_class_log_level log_level; - bool is_translated; - bool is_log_level_set; +struct ctf_event_class +{ + GString *name; + uint64_t id; + GString *emf_uri; + bt_event_class_log_level log_level; + bool is_translated; + bool is_log_level_set; - /* Owned by this */ - struct ctf_field_class *spec_context_fc; + /* Owned by this */ + struct ctf_field_class *spec_context_fc; - /* Owned by this */ - struct ctf_field_class *payload_fc; + /* Owned by this */ + struct ctf_field_class *payload_fc; - /* Weak, set during translation */ - bt_event_class *ir_ec; + /* Weak, set during translation */ + bt_event_class *ir_ec; }; -struct ctf_stream_class { - uint64_t id; - bool is_translated; - bool packets_have_ts_begin; - bool packets_have_ts_end; - bool has_discarded_events; - bool has_discarded_packets; - bool discarded_events_have_default_cs; - bool discarded_packets_have_default_cs; +struct ctf_stream_class +{ + uint64_t id; + bool is_translated; + bool packets_have_ts_begin; + bool packets_have_ts_end; + bool has_discarded_events; + bool has_discarded_packets; + bool discarded_events_have_default_cs; + bool discarded_packets_have_default_cs; - /* Owned by this */ - struct ctf_field_class *packet_context_fc; + /* Owned by this */ + struct ctf_field_class *packet_context_fc; - /* Owned by this */ - struct ctf_field_class *event_header_fc; + /* Owned by this */ + struct ctf_field_class *event_header_fc; - /* Owned by this */ - struct ctf_field_class *event_common_context_fc; + /* Owned by this */ + struct ctf_field_class *event_common_context_fc; - /* Array of `struct ctf_event_class *`, owned by this */ - GPtrArray *event_classes; + /* Array of `struct ctf_event_class *`, owned by this */ + GPtrArray *event_classes; - /* - * Hash table mapping event class IDs to `struct ctf_event_class *`, - * weak. - */ - GHashTable *event_classes_by_id; + /* + * Hash table mapping event class IDs to `struct ctf_event_class *`, + * weak. + */ + GHashTable *event_classes_by_id; - /* Weak */ - struct ctf_clock_class *default_clock_class; + /* Weak */ + struct ctf_clock_class *default_clock_class; - /* Weak, set during translation */ - bt_stream_class *ir_sc; + /* Weak, set during translation */ + bt_stream_class *ir_sc; }; -enum ctf_trace_class_env_entry_type { - CTF_TRACE_CLASS_ENV_ENTRY_TYPE_INT, - CTF_TRACE_CLASS_ENV_ENTRY_TYPE_STR, +enum ctf_trace_class_env_entry_type +{ + CTF_TRACE_CLASS_ENV_ENTRY_TYPE_INT, + CTF_TRACE_CLASS_ENV_ENTRY_TYPE_STR, }; -struct ctf_trace_class_env_entry { - enum ctf_trace_class_env_entry_type type; - GString *name; +struct ctf_trace_class_env_entry +{ + enum ctf_trace_class_env_entry_type type; + GString *name; - struct { - int64_t i; - GString *str; - } value; + struct + { + int64_t i; + GString *str; + } value; }; -struct ctf_trace_class { - unsigned int major; - unsigned int minor; - bt_uuid_t uuid; - bool is_uuid_set; - enum ctf_byte_order default_byte_order; +struct ctf_trace_class +{ + unsigned int major; + unsigned int minor; + bt_uuid_t uuid; + bool is_uuid_set; + enum ctf_byte_order default_byte_order; - /* Owned by this */ - struct ctf_field_class *packet_header_fc; + /* Owned by this */ + struct ctf_field_class *packet_header_fc; - uint64_t stored_value_count; + uint64_t stored_value_count; - /* Array of `struct ctf_clock_class *` (owned by this) */ - GPtrArray *clock_classes; + /* Array of `struct ctf_clock_class *` (owned by this) */ + GPtrArray *clock_classes; - /* Array of `struct ctf_stream_class *` */ - GPtrArray *stream_classes; + /* Array of `struct ctf_stream_class *` */ + GPtrArray *stream_classes; - /* Array of `struct ctf_trace_class_env_entry` */ - GArray *env_entries; + /* Array of `struct ctf_trace_class_env_entry` */ + GArray *env_entries; - bool is_translated; + bool is_translated; - /* Weak, set during translation */ - bt_trace_class *ir_tc; + /* Weak, set during translation */ + bt_trace_class *ir_tc; - struct { - bool lttng_crash; - bool lttng_event_after_packet; - bool barectf_event_before_packet; - } quirks; + struct + { + bool lttng_crash; + bool lttng_event_after_packet; + bool barectf_event_before_packet; + } quirks; }; -static inline -ctf_field_class_bit_array *ctf_field_class_as_bit_array(ctf_field_class *fc) +static inline ctf_field_class_bit_array *ctf_field_class_as_bit_array(ctf_field_class *fc) { - BT_ASSERT_DBG(!fc || (fc->type == CTF_FIELD_CLASS_TYPE_INT || - fc->type == CTF_FIELD_CLASS_TYPE_ENUM || - fc->type == CTF_FIELD_CLASS_TYPE_FLOAT)); - return (ctf_field_class_bit_array *) fc; + BT_ASSERT_DBG(!fc || + (fc->type == CTF_FIELD_CLASS_TYPE_INT || fc->type == CTF_FIELD_CLASS_TYPE_ENUM || + fc->type == CTF_FIELD_CLASS_TYPE_FLOAT)); + return (ctf_field_class_bit_array *) fc; } -static inline -ctf_field_class_int *ctf_field_class_as_int(ctf_field_class *fc) +static inline ctf_field_class_int *ctf_field_class_as_int(ctf_field_class *fc) { - BT_ASSERT_DBG(!fc || (fc->type == CTF_FIELD_CLASS_TYPE_INT || - fc->type == CTF_FIELD_CLASS_TYPE_ENUM)); - return (ctf_field_class_int *) fc; + BT_ASSERT_DBG(!fc || + (fc->type == CTF_FIELD_CLASS_TYPE_INT || fc->type == CTF_FIELD_CLASS_TYPE_ENUM)); + return (ctf_field_class_int *) fc; } -static inline -ctf_field_class_enum *ctf_field_class_as_enum(ctf_field_class *fc) +static inline ctf_field_class_enum *ctf_field_class_as_enum(ctf_field_class *fc) { - BT_ASSERT_DBG(!fc || fc->type == CTF_FIELD_CLASS_TYPE_ENUM); - return (ctf_field_class_enum *) fc; + BT_ASSERT_DBG(!fc || fc->type == CTF_FIELD_CLASS_TYPE_ENUM); + return (ctf_field_class_enum *) fc; } -static inline -ctf_field_class_float *ctf_field_class_as_float(ctf_field_class *fc) +static inline ctf_field_class_float *ctf_field_class_as_float(ctf_field_class *fc) { - BT_ASSERT_DBG(!fc || fc->type == CTF_FIELD_CLASS_TYPE_FLOAT); - return (ctf_field_class_float *) fc; + BT_ASSERT_DBG(!fc || fc->type == CTF_FIELD_CLASS_TYPE_FLOAT); + return (ctf_field_class_float *) fc; } -static inline -ctf_field_class_string *ctf_field_class_as_string(ctf_field_class *fc) +static inline ctf_field_class_string *ctf_field_class_as_string(ctf_field_class *fc) { - BT_ASSERT_DBG(!fc || fc->type == CTF_FIELD_CLASS_TYPE_STRING); - return (ctf_field_class_string *) fc; + BT_ASSERT_DBG(!fc || fc->type == CTF_FIELD_CLASS_TYPE_STRING); + return (ctf_field_class_string *) fc; } -static inline -ctf_field_class_struct *ctf_field_class_as_struct(ctf_field_class *fc) +static inline ctf_field_class_struct *ctf_field_class_as_struct(ctf_field_class *fc) { - BT_ASSERT_DBG(!fc || fc->type == CTF_FIELD_CLASS_TYPE_STRUCT); - return (ctf_field_class_struct *) fc; + BT_ASSERT_DBG(!fc || fc->type == CTF_FIELD_CLASS_TYPE_STRUCT); + return (ctf_field_class_struct *) fc; } -static inline -ctf_field_class_array_base *ctf_field_class_as_array_base(ctf_field_class *fc) +static inline ctf_field_class_array_base *ctf_field_class_as_array_base(ctf_field_class *fc) { - BT_ASSERT_DBG(!fc || (fc->type == CTF_FIELD_CLASS_TYPE_ARRAY || - fc->type == CTF_FIELD_CLASS_TYPE_SEQUENCE)); - return (ctf_field_class_array_base *) fc; + BT_ASSERT_DBG(!fc || (fc->type == CTF_FIELD_CLASS_TYPE_ARRAY || + fc->type == CTF_FIELD_CLASS_TYPE_SEQUENCE)); + return (ctf_field_class_array_base *) fc; } -static inline -ctf_field_class_array *ctf_field_class_as_array(ctf_field_class *fc) +static inline ctf_field_class_array *ctf_field_class_as_array(ctf_field_class *fc) { - BT_ASSERT_DBG(!fc || fc->type == CTF_FIELD_CLASS_TYPE_ARRAY); - return (ctf_field_class_array *) fc; + BT_ASSERT_DBG(!fc || fc->type == CTF_FIELD_CLASS_TYPE_ARRAY); + return (ctf_field_class_array *) fc; } -static inline -ctf_field_class_sequence *ctf_field_class_as_sequence(ctf_field_class *fc) +static inline ctf_field_class_sequence *ctf_field_class_as_sequence(ctf_field_class *fc) { - BT_ASSERT_DBG(!fc || fc->type == CTF_FIELD_CLASS_TYPE_SEQUENCE); - return (ctf_field_class_sequence *) fc; + BT_ASSERT_DBG(!fc || fc->type == CTF_FIELD_CLASS_TYPE_SEQUENCE); + return (ctf_field_class_sequence *) fc; } -static inline -ctf_field_class_variant *ctf_field_class_as_variant( - ctf_field_class *fc) +static inline ctf_field_class_variant *ctf_field_class_as_variant(ctf_field_class *fc) { - BT_ASSERT_DBG(!fc || fc->type == CTF_FIELD_CLASS_TYPE_VARIANT); - return (ctf_field_class_variant *) fc; + BT_ASSERT_DBG(!fc || fc->type == CTF_FIELD_CLASS_TYPE_VARIANT); + return (ctf_field_class_variant *) fc; } +static inline void ctf_field_class_destroy(struct ctf_field_class *fc); -static inline -void ctf_field_class_destroy(struct ctf_field_class *fc); - -static inline -void _ctf_field_class_init(struct ctf_field_class *fc, - enum ctf_field_class_type type, unsigned int alignment) +static inline void _ctf_field_class_init(struct ctf_field_class *fc, enum ctf_field_class_type type, + unsigned int alignment) { - BT_ASSERT(fc); - fc->type = type; - fc->alignment = alignment; - fc->in_ir = false; + BT_ASSERT(fc); + fc->type = type; + fc->alignment = alignment; + fc->in_ir = false; } -static inline -void _ctf_field_class_bit_array_init(struct ctf_field_class_bit_array *fc, - enum ctf_field_class_type type) +static inline void _ctf_field_class_bit_array_init(struct ctf_field_class_bit_array *fc, + enum ctf_field_class_type type) { - _ctf_field_class_init(&fc->base, type, 1); + _ctf_field_class_init(&fc->base, type, 1); } -static inline -void _ctf_field_class_int_init(struct ctf_field_class_int *fc, - enum ctf_field_class_type type) +static inline void _ctf_field_class_int_init(struct ctf_field_class_int *fc, + enum ctf_field_class_type type) { - _ctf_field_class_bit_array_init(&fc->base, type); - fc->meaning = CTF_FIELD_CLASS_MEANING_NONE; - fc->storing_index = -1; + _ctf_field_class_bit_array_init(&fc->base, type); + fc->meaning = CTF_FIELD_CLASS_MEANING_NONE; + fc->storing_index = -1; } -static inline -void ctf_field_path_init(struct ctf_field_path *field_path) +static inline void ctf_field_path_init(struct ctf_field_path *field_path) { - BT_ASSERT(field_path); - field_path->path = g_array_new(FALSE, TRUE, sizeof(int64_t)); - BT_ASSERT(field_path->path); + BT_ASSERT(field_path); + field_path->path = g_array_new(FALSE, TRUE, sizeof(int64_t)); + BT_ASSERT(field_path->path); } -static inline -void ctf_field_path_fini(struct ctf_field_path *field_path) +static inline void ctf_field_path_fini(struct ctf_field_path *field_path) { - BT_ASSERT(field_path); + BT_ASSERT(field_path); - if (field_path->path) { - g_array_free(field_path->path, TRUE); - } + if (field_path->path) { + g_array_free(field_path->path, TRUE); + } } -static inline -void _ctf_named_field_class_init(struct ctf_named_field_class *named_fc) +static inline void _ctf_named_field_class_init(struct ctf_named_field_class *named_fc) { - BT_ASSERT(named_fc); - named_fc->name = g_string_new(NULL); - BT_ASSERT(named_fc->name); - named_fc->orig_name = g_string_new(NULL); - BT_ASSERT(named_fc->orig_name); + BT_ASSERT(named_fc); + named_fc->name = g_string_new(NULL); + BT_ASSERT(named_fc->name); + named_fc->orig_name = g_string_new(NULL); + BT_ASSERT(named_fc->orig_name); } -static inline -void _ctf_named_field_class_fini(struct ctf_named_field_class *named_fc) +static inline void _ctf_named_field_class_fini(struct ctf_named_field_class *named_fc) { - BT_ASSERT(named_fc); + BT_ASSERT(named_fc); - if (named_fc->name) { - g_string_free(named_fc->name, TRUE); - } + if (named_fc->name) { + g_string_free(named_fc->name, TRUE); + } - if (named_fc->orig_name) { - g_string_free(named_fc->orig_name, TRUE); - } + if (named_fc->orig_name) { + g_string_free(named_fc->orig_name, TRUE); + } - ctf_field_class_destroy(named_fc->fc); + ctf_field_class_destroy(named_fc->fc); } -static inline -void _ctf_field_class_enum_mapping_init( - struct ctf_field_class_enum_mapping *mapping) +static inline void _ctf_field_class_enum_mapping_init(struct ctf_field_class_enum_mapping *mapping) { - BT_ASSERT(mapping); - mapping->label = g_string_new(NULL); - BT_ASSERT(mapping->label); - mapping->ranges = g_array_new(FALSE, TRUE, sizeof(struct ctf_range)); - BT_ASSERT(mapping->ranges); + BT_ASSERT(mapping); + mapping->label = g_string_new(NULL); + BT_ASSERT(mapping->label); + mapping->ranges = g_array_new(FALSE, TRUE, sizeof(struct ctf_range)); + BT_ASSERT(mapping->ranges); } -static inline -void _ctf_field_class_enum_mapping_fini( - struct ctf_field_class_enum_mapping *mapping) +static inline void _ctf_field_class_enum_mapping_fini(struct ctf_field_class_enum_mapping *mapping) { - BT_ASSERT(mapping); + BT_ASSERT(mapping); - if (mapping->label) { - g_string_free(mapping->label, TRUE); - } + if (mapping->label) { + g_string_free(mapping->label, TRUE); + } - if (mapping->ranges) { - g_array_free(mapping->ranges, TRUE); - } + if (mapping->ranges) { + g_array_free(mapping->ranges, TRUE); + } } -static inline -struct ctf_field_class_int *ctf_field_class_int_create(void) +static inline struct ctf_field_class_int *ctf_field_class_int_create(void) { - struct ctf_field_class_int *fc = g_new0(struct ctf_field_class_int, 1); + struct ctf_field_class_int *fc = g_new0(struct ctf_field_class_int, 1); - BT_ASSERT(fc); - _ctf_field_class_int_init(fc, CTF_FIELD_CLASS_TYPE_INT); - return fc; + BT_ASSERT(fc); + _ctf_field_class_int_init(fc, CTF_FIELD_CLASS_TYPE_INT); + return fc; } -static inline -struct ctf_field_class_float *ctf_field_class_float_create(void) +static inline struct ctf_field_class_float *ctf_field_class_float_create(void) { - struct ctf_field_class_float *fc = - g_new0(struct ctf_field_class_float, 1); + struct ctf_field_class_float *fc = g_new0(struct ctf_field_class_float, 1); - BT_ASSERT(fc); - _ctf_field_class_bit_array_init(&fc->base, CTF_FIELD_CLASS_TYPE_FLOAT); - return fc; + BT_ASSERT(fc); + _ctf_field_class_bit_array_init(&fc->base, CTF_FIELD_CLASS_TYPE_FLOAT); + return fc; } -static inline -struct ctf_field_class_string *ctf_field_class_string_create(void) +static inline struct ctf_field_class_string *ctf_field_class_string_create(void) { - struct ctf_field_class_string *fc = - g_new0(struct ctf_field_class_string, 1); + struct ctf_field_class_string *fc = g_new0(struct ctf_field_class_string, 1); - BT_ASSERT(fc); - _ctf_field_class_init(&fc->base, CTF_FIELD_CLASS_TYPE_STRING, 8); - return fc; + BT_ASSERT(fc); + _ctf_field_class_init(&fc->base, CTF_FIELD_CLASS_TYPE_STRING, 8); + return fc; } -static inline -struct ctf_field_class_enum *ctf_field_class_enum_create(void) +static inline struct ctf_field_class_enum *ctf_field_class_enum_create(void) { - struct ctf_field_class_enum *fc = g_new0(struct ctf_field_class_enum, 1); + struct ctf_field_class_enum *fc = g_new0(struct ctf_field_class_enum, 1); - BT_ASSERT(fc); - _ctf_field_class_int_init(&fc->base, CTF_FIELD_CLASS_TYPE_ENUM); - fc->mappings = g_array_new(FALSE, TRUE, - sizeof(struct ctf_field_class_enum_mapping)); - BT_ASSERT(fc->mappings); - return fc; + BT_ASSERT(fc); + _ctf_field_class_int_init(&fc->base, CTF_FIELD_CLASS_TYPE_ENUM); + fc->mappings = g_array_new(FALSE, TRUE, sizeof(struct ctf_field_class_enum_mapping)); + BT_ASSERT(fc->mappings); + return fc; } -static inline -struct ctf_field_class_struct *ctf_field_class_struct_create(void) +static inline struct ctf_field_class_struct *ctf_field_class_struct_create(void) { - struct ctf_field_class_struct *fc = - g_new0(struct ctf_field_class_struct, 1); + struct ctf_field_class_struct *fc = g_new0(struct ctf_field_class_struct, 1); - BT_ASSERT(fc); - _ctf_field_class_init(&fc->base, CTF_FIELD_CLASS_TYPE_STRUCT, 1); - fc->members = g_array_new(FALSE, TRUE, - sizeof(struct ctf_named_field_class)); - BT_ASSERT(fc->members); - fc->base.is_compound = true; - return fc; + BT_ASSERT(fc); + _ctf_field_class_init(&fc->base, CTF_FIELD_CLASS_TYPE_STRUCT, 1); + fc->members = g_array_new(FALSE, TRUE, sizeof(struct ctf_named_field_class)); + BT_ASSERT(fc->members); + fc->base.is_compound = true; + return fc; } -static inline -struct ctf_field_class_variant *ctf_field_class_variant_create(void) +static inline struct ctf_field_class_variant *ctf_field_class_variant_create(void) { - struct ctf_field_class_variant *fc = - g_new0(struct ctf_field_class_variant, 1); + struct ctf_field_class_variant *fc = g_new0(struct ctf_field_class_variant, 1); - BT_ASSERT(fc); - _ctf_field_class_init(&fc->base, CTF_FIELD_CLASS_TYPE_VARIANT, 1); - fc->options = g_array_new(FALSE, TRUE, - sizeof(struct ctf_named_field_class)); - BT_ASSERT(fc->options); - fc->ranges = g_array_new(FALSE, TRUE, - sizeof(struct ctf_field_class_variant_range)); - BT_ASSERT(fc->ranges); - fc->tag_ref = g_string_new(NULL); - BT_ASSERT(fc->tag_ref); - ctf_field_path_init(&fc->tag_path); - fc->base.is_compound = true; - return fc; + BT_ASSERT(fc); + _ctf_field_class_init(&fc->base, CTF_FIELD_CLASS_TYPE_VARIANT, 1); + fc->options = g_array_new(FALSE, TRUE, sizeof(struct ctf_named_field_class)); + BT_ASSERT(fc->options); + fc->ranges = g_array_new(FALSE, TRUE, sizeof(struct ctf_field_class_variant_range)); + BT_ASSERT(fc->ranges); + fc->tag_ref = g_string_new(NULL); + BT_ASSERT(fc->tag_ref); + ctf_field_path_init(&fc->tag_path); + fc->base.is_compound = true; + return fc; } -static inline -struct ctf_field_class_array *ctf_field_class_array_create(void) +static inline struct ctf_field_class_array *ctf_field_class_array_create(void) { - struct ctf_field_class_array *fc = - g_new0(struct ctf_field_class_array, 1); + struct ctf_field_class_array *fc = g_new0(struct ctf_field_class_array, 1); - BT_ASSERT(fc); - _ctf_field_class_init(&fc->base.base, CTF_FIELD_CLASS_TYPE_ARRAY, 1); - fc->base.base.is_compound = true; - return fc; + BT_ASSERT(fc); + _ctf_field_class_init(&fc->base.base, CTF_FIELD_CLASS_TYPE_ARRAY, 1); + fc->base.base.is_compound = true; + return fc; } -static inline -struct ctf_field_class_sequence *ctf_field_class_sequence_create(void) +static inline struct ctf_field_class_sequence *ctf_field_class_sequence_create(void) { - struct ctf_field_class_sequence *fc = - g_new0(struct ctf_field_class_sequence, 1); + struct ctf_field_class_sequence *fc = g_new0(struct ctf_field_class_sequence, 1); - BT_ASSERT(fc); - _ctf_field_class_init(&fc->base.base, CTF_FIELD_CLASS_TYPE_SEQUENCE, 1); - fc->length_ref = g_string_new(NULL); - BT_ASSERT(fc->length_ref); - ctf_field_path_init(&fc->length_path); - fc->base.base.is_compound = true; - return fc; + BT_ASSERT(fc); + _ctf_field_class_init(&fc->base.base, CTF_FIELD_CLASS_TYPE_SEQUENCE, 1); + fc->length_ref = g_string_new(NULL); + BT_ASSERT(fc->length_ref); + ctf_field_path_init(&fc->length_path); + fc->base.base.is_compound = true; + return fc; } -static inline -void _ctf_field_class_int_destroy(struct ctf_field_class_int *fc) +static inline void _ctf_field_class_int_destroy(struct ctf_field_class_int *fc) { - BT_ASSERT(fc); - g_free(fc); + BT_ASSERT(fc); + g_free(fc); } -static inline -void _ctf_field_class_enum_destroy(struct ctf_field_class_enum *fc) +static inline void _ctf_field_class_enum_destroy(struct ctf_field_class_enum *fc) { - BT_ASSERT(fc); + BT_ASSERT(fc); - if (fc->mappings) { - uint64_t i; + if (fc->mappings) { + uint64_t i; - for (i = 0; i < fc->mappings->len; i++) { - struct ctf_field_class_enum_mapping *mapping = - &g_array_index(fc->mappings, - struct ctf_field_class_enum_mapping, i); + for (i = 0; i < fc->mappings->len; i++) { + struct ctf_field_class_enum_mapping *mapping = + &g_array_index(fc->mappings, struct ctf_field_class_enum_mapping, i); - _ctf_field_class_enum_mapping_fini(mapping); - } + _ctf_field_class_enum_mapping_fini(mapping); + } - g_array_free(fc->mappings, TRUE); - } + g_array_free(fc->mappings, TRUE); + } - g_free(fc); + g_free(fc); } -static inline -void _ctf_field_class_float_destroy(struct ctf_field_class_float *fc) +static inline void _ctf_field_class_float_destroy(struct ctf_field_class_float *fc) { - BT_ASSERT(fc); - g_free(fc); + BT_ASSERT(fc); + g_free(fc); } -static inline -void _ctf_field_class_string_destroy(struct ctf_field_class_string *fc) +static inline void _ctf_field_class_string_destroy(struct ctf_field_class_string *fc) { - BT_ASSERT(fc); - g_free(fc); + BT_ASSERT(fc); + g_free(fc); } -static inline -void _ctf_field_class_struct_destroy(struct ctf_field_class_struct *fc) +static inline void _ctf_field_class_struct_destroy(struct ctf_field_class_struct *fc) { - BT_ASSERT(fc); + BT_ASSERT(fc); - if (fc->members) { - uint64_t i; + if (fc->members) { + uint64_t i; - for (i = 0; i < fc->members->len; i++) { - struct ctf_named_field_class *named_fc = - &g_array_index(fc->members, - struct ctf_named_field_class, i); + for (i = 0; i < fc->members->len; i++) { + struct ctf_named_field_class *named_fc = + &g_array_index(fc->members, struct ctf_named_field_class, i); - _ctf_named_field_class_fini(named_fc); - } + _ctf_named_field_class_fini(named_fc); + } - g_array_free(fc->members, TRUE); - } + g_array_free(fc->members, TRUE); + } - g_free(fc); + g_free(fc); } -static inline -void _ctf_field_class_array_base_fini(struct ctf_field_class_array_base *fc) +static inline void _ctf_field_class_array_base_fini(struct ctf_field_class_array_base *fc) { - BT_ASSERT(fc); - ctf_field_class_destroy(fc->elem_fc); + BT_ASSERT(fc); + ctf_field_class_destroy(fc->elem_fc); } -static inline -void _ctf_field_class_array_destroy(struct ctf_field_class_array *fc) +static inline void _ctf_field_class_array_destroy(struct ctf_field_class_array *fc) { - BT_ASSERT(fc); - _ctf_field_class_array_base_fini(&fc->base); - g_free(fc); + BT_ASSERT(fc); + _ctf_field_class_array_base_fini(&fc->base); + g_free(fc); } -static inline -void _ctf_field_class_sequence_destroy(struct ctf_field_class_sequence *fc) +static inline void _ctf_field_class_sequence_destroy(struct ctf_field_class_sequence *fc) { - BT_ASSERT(fc); - _ctf_field_class_array_base_fini(&fc->base); + BT_ASSERT(fc); + _ctf_field_class_array_base_fini(&fc->base); - if (fc->length_ref) { - g_string_free(fc->length_ref, TRUE); - } + if (fc->length_ref) { + g_string_free(fc->length_ref, TRUE); + } - ctf_field_path_fini(&fc->length_path); - g_free(fc); + ctf_field_path_fini(&fc->length_path); + g_free(fc); } -static inline -void _ctf_field_class_variant_destroy(struct ctf_field_class_variant *fc) +static inline void _ctf_field_class_variant_destroy(struct ctf_field_class_variant *fc) { - BT_ASSERT(fc); + BT_ASSERT(fc); - if (fc->options) { - uint64_t i; + if (fc->options) { + uint64_t i; - for (i = 0; i < fc->options->len; i++) { - struct ctf_named_field_class *named_fc = - &g_array_index(fc->options, - struct ctf_named_field_class, i); + for (i = 0; i < fc->options->len; i++) { + struct ctf_named_field_class *named_fc = + &g_array_index(fc->options, struct ctf_named_field_class, i); - _ctf_named_field_class_fini(named_fc); - } + _ctf_named_field_class_fini(named_fc); + } - g_array_free(fc->options, TRUE); - } + g_array_free(fc->options, TRUE); + } - if (fc->ranges) { - g_array_free(fc->ranges, TRUE); - } + if (fc->ranges) { + g_array_free(fc->ranges, TRUE); + } - if (fc->tag_ref) { - g_string_free(fc->tag_ref, TRUE); - } + if (fc->tag_ref) { + g_string_free(fc->tag_ref, TRUE); + } - ctf_field_path_fini(&fc->tag_path); - g_free(fc); + ctf_field_path_fini(&fc->tag_path); + g_free(fc); } -static inline -void ctf_field_class_destroy(struct ctf_field_class *fc) +static inline void ctf_field_class_destroy(struct ctf_field_class *fc) { - if (!fc) { - return; - } + if (!fc) { + return; + } - switch (fc->type) { - case CTF_FIELD_CLASS_TYPE_INT: - _ctf_field_class_int_destroy(ctf_field_class_as_int(fc)); - break; - case CTF_FIELD_CLASS_TYPE_ENUM: - _ctf_field_class_enum_destroy(ctf_field_class_as_enum(fc)); - break; - case CTF_FIELD_CLASS_TYPE_FLOAT: - _ctf_field_class_float_destroy(ctf_field_class_as_float(fc)); - break; - case CTF_FIELD_CLASS_TYPE_STRING: - _ctf_field_class_string_destroy(ctf_field_class_as_string(fc)); - break; - case CTF_FIELD_CLASS_TYPE_STRUCT: - _ctf_field_class_struct_destroy(ctf_field_class_as_struct(fc)); - break; - case CTF_FIELD_CLASS_TYPE_ARRAY: - _ctf_field_class_array_destroy(ctf_field_class_as_array(fc)); - break; - case CTF_FIELD_CLASS_TYPE_SEQUENCE: - _ctf_field_class_sequence_destroy(ctf_field_class_as_sequence(fc)); - break; - case CTF_FIELD_CLASS_TYPE_VARIANT: - _ctf_field_class_variant_destroy(ctf_field_class_as_variant(fc)); - break; - default: - bt_common_abort(); - } + switch (fc->type) { + case CTF_FIELD_CLASS_TYPE_INT: + _ctf_field_class_int_destroy(ctf_field_class_as_int(fc)); + break; + case CTF_FIELD_CLASS_TYPE_ENUM: + _ctf_field_class_enum_destroy(ctf_field_class_as_enum(fc)); + break; + case CTF_FIELD_CLASS_TYPE_FLOAT: + _ctf_field_class_float_destroy(ctf_field_class_as_float(fc)); + break; + case CTF_FIELD_CLASS_TYPE_STRING: + _ctf_field_class_string_destroy(ctf_field_class_as_string(fc)); + break; + case CTF_FIELD_CLASS_TYPE_STRUCT: + _ctf_field_class_struct_destroy(ctf_field_class_as_struct(fc)); + break; + case CTF_FIELD_CLASS_TYPE_ARRAY: + _ctf_field_class_array_destroy(ctf_field_class_as_array(fc)); + break; + case CTF_FIELD_CLASS_TYPE_SEQUENCE: + _ctf_field_class_sequence_destroy(ctf_field_class_as_sequence(fc)); + break; + case CTF_FIELD_CLASS_TYPE_VARIANT: + _ctf_field_class_variant_destroy(ctf_field_class_as_variant(fc)); + break; + default: + bt_common_abort(); + } } -static inline -struct ctf_range *ctf_field_class_enum_mapping_borrow_range_by_index( - struct ctf_field_class_enum_mapping *mapping, uint64_t index) +static inline struct ctf_range * +ctf_field_class_enum_mapping_borrow_range_by_index(struct ctf_field_class_enum_mapping *mapping, + uint64_t index) { - BT_ASSERT_DBG(mapping); - BT_ASSERT_DBG(index < mapping->ranges->len); - return &g_array_index(mapping->ranges, struct ctf_range, index); + BT_ASSERT_DBG(mapping); + BT_ASSERT_DBG(index < mapping->ranges->len); + return &g_array_index(mapping->ranges, struct ctf_range, index); } -static inline -struct ctf_field_class_enum_mapping *ctf_field_class_enum_borrow_mapping_by_index( - struct ctf_field_class_enum *fc, uint64_t index) +static inline struct ctf_field_class_enum_mapping * +ctf_field_class_enum_borrow_mapping_by_index(struct ctf_field_class_enum *fc, uint64_t index) { - BT_ASSERT_DBG(fc); - BT_ASSERT_DBG(index < fc->mappings->len); - return &g_array_index(fc->mappings, struct ctf_field_class_enum_mapping, - index); + BT_ASSERT_DBG(fc); + BT_ASSERT_DBG(index < fc->mappings->len); + return &g_array_index(fc->mappings, struct ctf_field_class_enum_mapping, index); } -static inline -struct ctf_field_class_enum_mapping *ctf_field_class_enum_borrow_mapping_by_label( - struct ctf_field_class_enum *fc, const char *label) +static inline struct ctf_field_class_enum_mapping * +ctf_field_class_enum_borrow_mapping_by_label(struct ctf_field_class_enum *fc, const char *label) { - struct ctf_field_class_enum_mapping *ret_mapping = NULL; - uint64_t i; + struct ctf_field_class_enum_mapping *ret_mapping = NULL; + uint64_t i; - BT_ASSERT_DBG(fc); - BT_ASSERT_DBG(label); + BT_ASSERT_DBG(fc); + BT_ASSERT_DBG(label); - for (i = 0; i < fc->mappings->len; i++) { - struct ctf_field_class_enum_mapping *mapping = - ctf_field_class_enum_borrow_mapping_by_index(fc, i); - - if (strcmp(mapping->label->str, label) == 0) { - ret_mapping = mapping; - goto end; - } - } + for (i = 0; i < fc->mappings->len; i++) { + struct ctf_field_class_enum_mapping *mapping = + ctf_field_class_enum_borrow_mapping_by_index(fc, i); + + if (strcmp(mapping->label->str, label) == 0) { + ret_mapping = mapping; + goto end; + } + } end: - return ret_mapping; + return ret_mapping; } -static inline -void ctf_field_class_enum_map_range(struct ctf_field_class_enum *fc, - const char *label, uint64_t u_lower, uint64_t u_upper) +static inline void ctf_field_class_enum_map_range(struct ctf_field_class_enum *fc, + const char *label, uint64_t u_lower, + uint64_t u_upper) { - struct ctf_field_class_enum_mapping *mapping = NULL; - struct ctf_range range = { - .lower = { - .u = u_lower, - }, - .upper = { - .u = u_upper, - }, - }; - uint64_t i; + struct ctf_field_class_enum_mapping *mapping = NULL; + struct ctf_range range = { + .lower = + { + .u = u_lower, + }, + .upper = + { + .u = u_upper, + }, + }; + uint64_t i; - BT_ASSERT(fc); - BT_ASSERT(label); + BT_ASSERT(fc); + BT_ASSERT(label); - for (i = 0; i < fc->mappings->len; i++) { - mapping = ctf_field_class_enum_borrow_mapping_by_index( - fc, i); + for (i = 0; i < fc->mappings->len; i++) { + mapping = ctf_field_class_enum_borrow_mapping_by_index(fc, i); - if (strcmp(mapping->label->str, label) == 0) { - break; - } - } + if (strcmp(mapping->label->str, label) == 0) { + break; + } + } - if (i == fc->mappings->len) { - mapping = NULL; - } + if (i == fc->mappings->len) { + mapping = NULL; + } - if (!mapping) { - g_array_set_size(fc->mappings, fc->mappings->len + 1); - mapping = ctf_field_class_enum_borrow_mapping_by_index( - fc, fc->mappings->len - 1); - _ctf_field_class_enum_mapping_init(mapping); - g_string_assign(mapping->label, label); - } + if (!mapping) { + g_array_set_size(fc->mappings, fc->mappings->len + 1); + mapping = ctf_field_class_enum_borrow_mapping_by_index(fc, fc->mappings->len - 1); + _ctf_field_class_enum_mapping_init(mapping); + g_string_assign(mapping->label, label); + } - g_array_append_val(mapping->ranges, range); + g_array_append_val(mapping->ranges, range); } -static inline -struct ctf_named_field_class *ctf_field_class_struct_borrow_member_by_index( - struct ctf_field_class_struct *fc, uint64_t index) +static inline struct ctf_named_field_class * +ctf_field_class_struct_borrow_member_by_index(struct ctf_field_class_struct *fc, uint64_t index) { - BT_ASSERT_DBG(fc); - BT_ASSERT_DBG(index < fc->members->len); - return &g_array_index(fc->members, struct ctf_named_field_class, - index); + BT_ASSERT_DBG(fc); + BT_ASSERT_DBG(index < fc->members->len); + return &g_array_index(fc->members, struct ctf_named_field_class, index); } -static inline -struct ctf_named_field_class *ctf_field_class_struct_borrow_member_by_name( - struct ctf_field_class_struct *fc, const char *name) +static inline struct ctf_named_field_class * +ctf_field_class_struct_borrow_member_by_name(struct ctf_field_class_struct *fc, const char *name) { - uint64_t i; - struct ctf_named_field_class *ret_named_fc = NULL; + uint64_t i; + struct ctf_named_field_class *ret_named_fc = NULL; - BT_ASSERT_DBG(fc); - BT_ASSERT_DBG(name); + BT_ASSERT_DBG(fc); + BT_ASSERT_DBG(name); - for (i = 0; i < fc->members->len; i++) { - struct ctf_named_field_class *named_fc = - ctf_field_class_struct_borrow_member_by_index(fc, i); + for (i = 0; i < fc->members->len; i++) { + struct ctf_named_field_class *named_fc = + ctf_field_class_struct_borrow_member_by_index(fc, i); - if (strcmp(name, named_fc->name->str) == 0) { - ret_named_fc = named_fc; - goto end; - } - } + if (strcmp(name, named_fc->name->str) == 0) { + ret_named_fc = named_fc; + goto end; + } + } end: - return ret_named_fc; + return ret_named_fc; } -static inline -struct ctf_field_class *ctf_field_class_struct_borrow_member_field_class_by_name( - struct ctf_field_class_struct *struct_fc, const char *name) +static inline struct ctf_field_class * +ctf_field_class_struct_borrow_member_field_class_by_name(struct ctf_field_class_struct *struct_fc, + const char *name) { - struct ctf_named_field_class *named_fc = NULL; - struct ctf_field_class *fc = NULL; + struct ctf_named_field_class *named_fc = NULL; + struct ctf_field_class *fc = NULL; - if (!struct_fc) { - goto end; - } + if (!struct_fc) { + goto end; + } - named_fc = ctf_field_class_struct_borrow_member_by_name(struct_fc, name); - if (!named_fc) { - goto end; - } + named_fc = ctf_field_class_struct_borrow_member_by_name(struct_fc, name); + if (!named_fc) { + goto end; + } - fc = named_fc->fc; + fc = named_fc->fc; end: - return fc; + return fc; } -static inline -struct ctf_field_class_int * +static inline struct ctf_field_class_int * ctf_field_class_struct_borrow_member_int_field_class_by_name( - struct ctf_field_class_struct *struct_fc, const char *name) + struct ctf_field_class_struct *struct_fc, const char *name) { - struct ctf_field_class_int *int_fc = NULL; + struct ctf_field_class_int *int_fc = NULL; - int_fc = ctf_field_class_as_int( - ctf_field_class_struct_borrow_member_field_class_by_name( - struct_fc, name)); - if (!int_fc) { - goto end; - } + int_fc = ctf_field_class_as_int( + ctf_field_class_struct_borrow_member_field_class_by_name(struct_fc, name)); + if (!int_fc) { + goto end; + } - if (int_fc->base.base.type != CTF_FIELD_CLASS_TYPE_INT && - int_fc->base.base.type != CTF_FIELD_CLASS_TYPE_ENUM) { - int_fc = NULL; - goto end; - } + if (int_fc->base.base.type != CTF_FIELD_CLASS_TYPE_INT && + int_fc->base.base.type != CTF_FIELD_CLASS_TYPE_ENUM) { + int_fc = NULL; + goto end; + } end: - return int_fc; + return int_fc; } -static inline -void _ctf_named_field_class_unescape_orig_name( - struct ctf_named_field_class *named_fc) +static inline void _ctf_named_field_class_unescape_orig_name(struct ctf_named_field_class *named_fc) { - const char *name = named_fc->orig_name->str; + const char *name = named_fc->orig_name->str; - if (name[0] == '_') { - name++; - } + if (name[0] == '_') { + name++; + } - g_string_assign(named_fc->name, name); + g_string_assign(named_fc->name, name); } -static inline -void ctf_field_class_struct_append_member(struct ctf_field_class_struct *fc, - const char *orig_name, struct ctf_field_class *member_fc) +static inline void ctf_field_class_struct_append_member(struct ctf_field_class_struct *fc, + const char *orig_name, + struct ctf_field_class *member_fc) { - struct ctf_named_field_class *named_fc; + struct ctf_named_field_class *named_fc; - BT_ASSERT(fc); - BT_ASSERT(orig_name); - g_array_set_size(fc->members, fc->members->len + 1); + BT_ASSERT(fc); + BT_ASSERT(orig_name); + g_array_set_size(fc->members, fc->members->len + 1); - named_fc = &g_array_index(fc->members, struct ctf_named_field_class, - fc->members->len - 1); - _ctf_named_field_class_init(named_fc); - g_string_assign(named_fc->orig_name, orig_name); - _ctf_named_field_class_unescape_orig_name(named_fc); - named_fc->fc = member_fc; + named_fc = &g_array_index(fc->members, struct ctf_named_field_class, fc->members->len - 1); + _ctf_named_field_class_init(named_fc); + g_string_assign(named_fc->orig_name, orig_name); + _ctf_named_field_class_unescape_orig_name(named_fc); + named_fc->fc = member_fc; - if (member_fc->alignment > fc->base.alignment) { - fc->base.alignment = member_fc->alignment; - } + if (member_fc->alignment > fc->base.alignment) { + fc->base.alignment = member_fc->alignment; + } } -static inline -struct ctf_named_field_class *ctf_field_class_variant_borrow_option_by_index( - struct ctf_field_class_variant *fc, uint64_t index) +static inline struct ctf_named_field_class * +ctf_field_class_variant_borrow_option_by_index(struct ctf_field_class_variant *fc, uint64_t index) { - BT_ASSERT_DBG(fc); - BT_ASSERT_DBG(index < fc->options->len); - return &g_array_index(fc->options, struct ctf_named_field_class, - index); + BT_ASSERT_DBG(fc); + BT_ASSERT_DBG(index < fc->options->len); + return &g_array_index(fc->options, struct ctf_named_field_class, index); } -static inline -struct ctf_named_field_class *ctf_field_class_variant_borrow_option_by_name( - struct ctf_field_class_variant *fc, const char *name) +static inline struct ctf_named_field_class * +ctf_field_class_variant_borrow_option_by_name(struct ctf_field_class_variant *fc, const char *name) { - uint64_t i; - struct ctf_named_field_class *ret_named_fc = NULL; + uint64_t i; + struct ctf_named_field_class *ret_named_fc = NULL; - BT_ASSERT_DBG(fc); - BT_ASSERT_DBG(name); + BT_ASSERT_DBG(fc); + BT_ASSERT_DBG(name); - for (i = 0; i < fc->options->len; i++) { - struct ctf_named_field_class *named_fc = - ctf_field_class_variant_borrow_option_by_index(fc, i); + for (i = 0; i < fc->options->len; i++) { + struct ctf_named_field_class *named_fc = + ctf_field_class_variant_borrow_option_by_index(fc, i); - if (strcmp(name, named_fc->name->str) == 0) { - ret_named_fc = named_fc; - goto end; - } - } + if (strcmp(name, named_fc->name->str) == 0) { + ret_named_fc = named_fc; + goto end; + } + } end: - return ret_named_fc; -} - -static inline -struct ctf_field_class_variant_range * -ctf_field_class_variant_borrow_range_by_index( - struct ctf_field_class_variant *fc, uint64_t index) -{ - BT_ASSERT_DBG(fc); - BT_ASSERT_DBG(index < fc->ranges->len); - return &g_array_index(fc->ranges, struct ctf_field_class_variant_range, - index); -} - -static inline -void ctf_field_class_variant_append_option(struct ctf_field_class_variant *fc, - const char *orig_name, struct ctf_field_class *option_fc) -{ - struct ctf_named_field_class *named_fc; - - BT_ASSERT(fc); - BT_ASSERT(orig_name); - g_array_set_size(fc->options, fc->options->len + 1); - - named_fc = &g_array_index(fc->options, struct ctf_named_field_class, - fc->options->len - 1); - _ctf_named_field_class_init(named_fc); - g_string_assign(named_fc->orig_name, orig_name); - _ctf_named_field_class_unescape_orig_name(named_fc); - named_fc->fc = option_fc; -} - -static inline -void ctf_field_class_variant_set_tag_field_class( - struct ctf_field_class_variant *fc, - struct ctf_field_class_enum *tag_fc) -{ - uint64_t option_i; - - BT_ASSERT(fc); - BT_ASSERT(tag_fc); - fc->tag_fc = tag_fc; - - for (option_i = 0; option_i < fc->options->len; option_i++) { - uint64_t range_i; - struct ctf_named_field_class *named_fc = - ctf_field_class_variant_borrow_option_by_index( - fc, option_i); - struct ctf_field_class_enum_mapping *mapping; - - mapping = ctf_field_class_enum_borrow_mapping_by_label( - tag_fc, named_fc->orig_name->str); - if (!mapping) { - continue; - } - - for (range_i = 0; range_i < mapping->ranges->len; - range_i++) { - struct ctf_range *range = - ctf_field_class_enum_mapping_borrow_range_by_index( - mapping, range_i); - struct ctf_field_class_variant_range var_range; - - var_range.range = *range; - var_range.option_index = option_i; - g_array_append_val(fc->ranges, var_range); - } - } -} - -static inline -struct ctf_field_class *ctf_field_class_compound_borrow_field_class_by_index( - struct ctf_field_class *comp_fc, uint64_t index) -{ - struct ctf_field_class *fc = NULL; - - switch (comp_fc->type) { - case CTF_FIELD_CLASS_TYPE_STRUCT: - { - struct ctf_named_field_class *named_fc = - ctf_field_class_struct_borrow_member_by_index( - (struct ctf_field_class_struct *) comp_fc, index); - - BT_ASSERT_DBG(named_fc); - fc = named_fc->fc; - break; - } - case CTF_FIELD_CLASS_TYPE_VARIANT: - { - struct ctf_named_field_class *named_fc = - ctf_field_class_variant_borrow_option_by_index( - (struct ctf_field_class_variant *) comp_fc, index); - - BT_ASSERT_DBG(named_fc); - fc = named_fc->fc; - break; - } - case CTF_FIELD_CLASS_TYPE_ARRAY: - case CTF_FIELD_CLASS_TYPE_SEQUENCE: - { - struct ctf_field_class_array_base *array_fc = - (struct ctf_field_class_array_base *) comp_fc; - - fc = array_fc->elem_fc; - break; - } - default: - break; - } - - return fc; -} - -static inline -uint64_t ctf_field_class_compound_get_field_class_count(struct ctf_field_class *fc) -{ - uint64_t field_count; - - switch (fc->type) { - case CTF_FIELD_CLASS_TYPE_STRUCT: - { - struct ctf_field_class_struct *struct_fc = - (struct ctf_field_class_struct *) fc; - - field_count = struct_fc->members->len; - break; - } - case CTF_FIELD_CLASS_TYPE_VARIANT: - { - struct ctf_field_class_variant *var_fc = - (struct ctf_field_class_variant *) fc; - - field_count = var_fc->options->len; - break; - } - case CTF_FIELD_CLASS_TYPE_ARRAY: - case CTF_FIELD_CLASS_TYPE_SEQUENCE: - /* - * Array and sequence types always contain a single - * member (the element type). - */ - field_count = 1; - break; - default: - bt_common_abort(); - } - - return field_count; -} - -static inline -int64_t ctf_field_class_compound_get_field_class_index_from_orig_name( - struct ctf_field_class *fc, const char *orig_name) -{ - int64_t ret_index = -1; - uint64_t i; - - switch (fc->type) { - case CTF_FIELD_CLASS_TYPE_STRUCT: - { - struct ctf_field_class_struct *struct_fc = - (struct ctf_field_class_struct *) fc; - - for (i = 0; i < struct_fc->members->len; i++) { - struct ctf_named_field_class *named_fc = - ctf_field_class_struct_borrow_member_by_index( - struct_fc, i); - - if (strcmp(orig_name, named_fc->orig_name->str) == 0) { - ret_index = (int64_t) i; - goto end; - } - } - - break; - } - case CTF_FIELD_CLASS_TYPE_VARIANT: - { - struct ctf_field_class_variant *var_fc - = (struct ctf_field_class_variant *) fc; - - for (i = 0; i < var_fc->options->len; i++) { - struct ctf_named_field_class *named_fc = - ctf_field_class_variant_borrow_option_by_index( - var_fc, i); - - if (strcmp(orig_name, named_fc->orig_name->str) == 0) { - ret_index = (int64_t) i; - goto end; - } - } - - break; - } - default: - break; - } + return ret_named_fc; +} + +static inline struct ctf_field_class_variant_range * +ctf_field_class_variant_borrow_range_by_index(struct ctf_field_class_variant *fc, uint64_t index) +{ + BT_ASSERT_DBG(fc); + BT_ASSERT_DBG(index < fc->ranges->len); + return &g_array_index(fc->ranges, struct ctf_field_class_variant_range, index); +} + +static inline void ctf_field_class_variant_append_option(struct ctf_field_class_variant *fc, + const char *orig_name, + struct ctf_field_class *option_fc) +{ + struct ctf_named_field_class *named_fc; + + BT_ASSERT(fc); + BT_ASSERT(orig_name); + g_array_set_size(fc->options, fc->options->len + 1); + + named_fc = &g_array_index(fc->options, struct ctf_named_field_class, fc->options->len - 1); + _ctf_named_field_class_init(named_fc); + g_string_assign(named_fc->orig_name, orig_name); + _ctf_named_field_class_unescape_orig_name(named_fc); + named_fc->fc = option_fc; +} + +static inline void ctf_field_class_variant_set_tag_field_class(struct ctf_field_class_variant *fc, + struct ctf_field_class_enum *tag_fc) +{ + uint64_t option_i; + + BT_ASSERT(fc); + BT_ASSERT(tag_fc); + fc->tag_fc = tag_fc; + + for (option_i = 0; option_i < fc->options->len; option_i++) { + uint64_t range_i; + struct ctf_named_field_class *named_fc = + ctf_field_class_variant_borrow_option_by_index(fc, option_i); + struct ctf_field_class_enum_mapping *mapping; + + mapping = ctf_field_class_enum_borrow_mapping_by_label(tag_fc, named_fc->orig_name->str); + if (!mapping) { + continue; + } + + for (range_i = 0; range_i < mapping->ranges->len; range_i++) { + struct ctf_range *range = + ctf_field_class_enum_mapping_borrow_range_by_index(mapping, range_i); + struct ctf_field_class_variant_range var_range; + + var_range.range = *range; + var_range.option_index = option_i; + g_array_append_val(fc->ranges, var_range); + } + } +} + +static inline struct ctf_field_class * +ctf_field_class_compound_borrow_field_class_by_index(struct ctf_field_class *comp_fc, + uint64_t index) +{ + struct ctf_field_class *fc = NULL; + + switch (comp_fc->type) { + case CTF_FIELD_CLASS_TYPE_STRUCT: + { + struct ctf_named_field_class *named_fc = ctf_field_class_struct_borrow_member_by_index( + (struct ctf_field_class_struct *) comp_fc, index); + + BT_ASSERT_DBG(named_fc); + fc = named_fc->fc; + break; + } + case CTF_FIELD_CLASS_TYPE_VARIANT: + { + struct ctf_named_field_class *named_fc = ctf_field_class_variant_borrow_option_by_index( + (struct ctf_field_class_variant *) comp_fc, index); + + BT_ASSERT_DBG(named_fc); + fc = named_fc->fc; + break; + } + case CTF_FIELD_CLASS_TYPE_ARRAY: + case CTF_FIELD_CLASS_TYPE_SEQUENCE: + { + struct ctf_field_class_array_base *array_fc = (struct ctf_field_class_array_base *) comp_fc; + + fc = array_fc->elem_fc; + break; + } + default: + break; + } + + return fc; +} + +static inline uint64_t ctf_field_class_compound_get_field_class_count(struct ctf_field_class *fc) +{ + uint64_t field_count; + + switch (fc->type) { + case CTF_FIELD_CLASS_TYPE_STRUCT: + { + struct ctf_field_class_struct *struct_fc = (struct ctf_field_class_struct *) fc; + + field_count = struct_fc->members->len; + break; + } + case CTF_FIELD_CLASS_TYPE_VARIANT: + { + struct ctf_field_class_variant *var_fc = (struct ctf_field_class_variant *) fc; + + field_count = var_fc->options->len; + break; + } + case CTF_FIELD_CLASS_TYPE_ARRAY: + case CTF_FIELD_CLASS_TYPE_SEQUENCE: + /* + * Array and sequence types always contain a single + * member (the element type). + */ + field_count = 1; + break; + default: + bt_common_abort(); + } + + return field_count; +} + +static inline int64_t +ctf_field_class_compound_get_field_class_index_from_orig_name(struct ctf_field_class *fc, + const char *orig_name) +{ + int64_t ret_index = -1; + uint64_t i; + + switch (fc->type) { + case CTF_FIELD_CLASS_TYPE_STRUCT: + { + struct ctf_field_class_struct *struct_fc = (struct ctf_field_class_struct *) fc; + + for (i = 0; i < struct_fc->members->len; i++) { + struct ctf_named_field_class *named_fc = + ctf_field_class_struct_borrow_member_by_index(struct_fc, i); + + if (strcmp(orig_name, named_fc->orig_name->str) == 0) { + ret_index = (int64_t) i; + goto end; + } + } + + break; + } + case CTF_FIELD_CLASS_TYPE_VARIANT: + { + struct ctf_field_class_variant *var_fc = (struct ctf_field_class_variant *) fc; + + for (i = 0; i < var_fc->options->len; i++) { + struct ctf_named_field_class *named_fc = + ctf_field_class_variant_borrow_option_by_index(var_fc, i); + + if (strcmp(orig_name, named_fc->orig_name->str) == 0) { + ret_index = (int64_t) i; + goto end; + } + } + + break; + } + default: + break; + } end: - return ret_index; + return ret_index; } -static inline -void ctf_field_path_append_index(struct ctf_field_path *fp, int64_t index) +static inline void ctf_field_path_append_index(struct ctf_field_path *fp, int64_t index) { - BT_ASSERT(fp); - g_array_append_val(fp->path, index); + BT_ASSERT(fp); + g_array_append_val(fp->path, index); } -static inline -int64_t ctf_field_path_borrow_index_by_index(struct ctf_field_path *fp, - uint64_t index) +static inline int64_t ctf_field_path_borrow_index_by_index(struct ctf_field_path *fp, + uint64_t index) { - BT_ASSERT_DBG(fp); - BT_ASSERT_DBG(index < fp->path->len); - return g_array_index(fp->path, int64_t, index); + BT_ASSERT_DBG(fp); + BT_ASSERT_DBG(index < fp->path->len); + return g_array_index(fp->path, int64_t, index); } -static inline -void ctf_field_path_clear(struct ctf_field_path *fp) +static inline void ctf_field_path_clear(struct ctf_field_path *fp) { - BT_ASSERT(fp); - g_array_set_size(fp->path, 0); + BT_ASSERT(fp); + g_array_set_size(fp->path, 0); } -static inline -const char *ctf_scope_string(enum ctf_scope scope) +static inline const char *ctf_scope_string(enum ctf_scope scope) { - switch (scope) { - case CTF_SCOPE_PACKET_HEADER: - return "PACKET_HEADER"; - case CTF_SCOPE_PACKET_CONTEXT: - return "PACKET_CONTEXT"; - case CTF_SCOPE_EVENT_HEADER: - return "EVENT_HEADER"; - case CTF_SCOPE_EVENT_COMMON_CONTEXT: - return "EVENT_COMMON_CONTEXT"; - case CTF_SCOPE_EVENT_SPECIFIC_CONTEXT: - return "EVENT_SPECIFIC_CONTEXT"; - case CTF_SCOPE_EVENT_PAYLOAD: - return "EVENT_PAYLOAD"; - default: - bt_common_abort(); - } + switch (scope) { + case CTF_SCOPE_PACKET_HEADER: + return "PACKET_HEADER"; + case CTF_SCOPE_PACKET_CONTEXT: + return "PACKET_CONTEXT"; + case CTF_SCOPE_EVENT_HEADER: + return "EVENT_HEADER"; + case CTF_SCOPE_EVENT_COMMON_CONTEXT: + return "EVENT_COMMON_CONTEXT"; + case CTF_SCOPE_EVENT_SPECIFIC_CONTEXT: + return "EVENT_SPECIFIC_CONTEXT"; + case CTF_SCOPE_EVENT_PAYLOAD: + return "EVENT_PAYLOAD"; + default: + bt_common_abort(); + } } -static inline -GString *ctf_field_path_string(struct ctf_field_path *path) +static inline GString *ctf_field_path_string(struct ctf_field_path *path) { - GString *str = g_string_new(NULL); - uint64_t i; + GString *str = g_string_new(NULL); + uint64_t i; - BT_ASSERT(path); + BT_ASSERT(path); - if (!str) { - goto end; - } + if (!str) { + goto end; + } - g_string_append_printf(str, "[%s", ctf_scope_string(path->root)); + g_string_append_printf(str, "[%s", ctf_scope_string(path->root)); - for (i = 0; i < path->path->len; i++) { - g_string_append_printf(str, ", %" PRId64, - ctf_field_path_borrow_index_by_index(path, i)); - } + for (i = 0; i < path->path->len; i++) { + g_string_append_printf(str, ", %" PRId64, ctf_field_path_borrow_index_by_index(path, i)); + } - g_string_append(str, "]"); + g_string_append(str, "]"); end: - return str; -} - -static inline -struct ctf_field_class *ctf_field_path_borrow_field_class( - struct ctf_field_path *field_path, - struct ctf_trace_class *tc, - struct ctf_stream_class *sc, - struct ctf_event_class *ec) -{ - uint64_t i; - struct ctf_field_class *fc; - - switch (field_path->root) { - case CTF_SCOPE_PACKET_HEADER: - fc = tc->packet_header_fc; - break; - case CTF_SCOPE_PACKET_CONTEXT: - fc = sc->packet_context_fc; - break; - case CTF_SCOPE_EVENT_HEADER: - fc = sc->event_header_fc; - break; - case CTF_SCOPE_EVENT_COMMON_CONTEXT: - fc = sc->event_common_context_fc; - break; - case CTF_SCOPE_EVENT_SPECIFIC_CONTEXT: - fc = ec->spec_context_fc; - break; - case CTF_SCOPE_EVENT_PAYLOAD: - fc = ec->payload_fc; - break; - default: - bt_common_abort(); - } - - BT_ASSERT_DBG(fc); + return str; +} + +static inline struct ctf_field_class * +ctf_field_path_borrow_field_class(struct ctf_field_path *field_path, struct ctf_trace_class *tc, + struct ctf_stream_class *sc, struct ctf_event_class *ec) +{ + uint64_t i; + struct ctf_field_class *fc; + + switch (field_path->root) { + case CTF_SCOPE_PACKET_HEADER: + fc = tc->packet_header_fc; + break; + case CTF_SCOPE_PACKET_CONTEXT: + fc = sc->packet_context_fc; + break; + case CTF_SCOPE_EVENT_HEADER: + fc = sc->event_header_fc; + break; + case CTF_SCOPE_EVENT_COMMON_CONTEXT: + fc = sc->event_common_context_fc; + break; + case CTF_SCOPE_EVENT_SPECIFIC_CONTEXT: + fc = ec->spec_context_fc; + break; + case CTF_SCOPE_EVENT_PAYLOAD: + fc = ec->payload_fc; + break; + default: + bt_common_abort(); + } + + BT_ASSERT_DBG(fc); - for (i = 0; i < field_path->path->len; i++) { - int64_t child_index = - ctf_field_path_borrow_index_by_index(field_path, i); - struct ctf_field_class *child_fc = - ctf_field_class_compound_borrow_field_class_by_index( - fc, child_index); - BT_ASSERT_DBG(child_fc); - fc = child_fc; - } + for (i = 0; i < field_path->path->len; i++) { + int64_t child_index = ctf_field_path_borrow_index_by_index(field_path, i); + struct ctf_field_class *child_fc = + ctf_field_class_compound_borrow_field_class_by_index(fc, child_index); + BT_ASSERT_DBG(child_fc); + fc = child_fc; + } - BT_ASSERT_DBG(fc); - return fc; + BT_ASSERT_DBG(fc); + return fc; } -static inline -struct ctf_field_class *ctf_field_class_copy(struct ctf_field_class *fc); +static inline struct ctf_field_class *ctf_field_class_copy(struct ctf_field_class *fc); -static inline -void ctf_field_class_bit_array_copy_content( - struct ctf_field_class_bit_array *dst_fc, - struct ctf_field_class_bit_array *src_fc) +static inline void ctf_field_class_bit_array_copy_content(struct ctf_field_class_bit_array *dst_fc, + struct ctf_field_class_bit_array *src_fc) { - BT_ASSERT(dst_fc); - BT_ASSERT(src_fc); - dst_fc->byte_order = src_fc->byte_order; - dst_fc->size = src_fc->size; + BT_ASSERT(dst_fc); + BT_ASSERT(src_fc); + dst_fc->byte_order = src_fc->byte_order; + dst_fc->size = src_fc->size; } -static inline -void ctf_field_class_int_copy_content( - struct ctf_field_class_int *dst_fc, - struct ctf_field_class_int *src_fc) +static inline void ctf_field_class_int_copy_content(struct ctf_field_class_int *dst_fc, + struct ctf_field_class_int *src_fc) { - ctf_field_class_bit_array_copy_content(&dst_fc->base, &src_fc->base); - dst_fc->meaning = src_fc->meaning; - dst_fc->is_signed = src_fc->is_signed; - dst_fc->disp_base = src_fc->disp_base; - dst_fc->encoding = src_fc->encoding; - dst_fc->mapped_clock_class = src_fc->mapped_clock_class; - dst_fc->storing_index = src_fc->storing_index; + ctf_field_class_bit_array_copy_content(&dst_fc->base, &src_fc->base); + dst_fc->meaning = src_fc->meaning; + dst_fc->is_signed = src_fc->is_signed; + dst_fc->disp_base = src_fc->disp_base; + dst_fc->encoding = src_fc->encoding; + dst_fc->mapped_clock_class = src_fc->mapped_clock_class; + dst_fc->storing_index = src_fc->storing_index; } -static inline -struct ctf_field_class_int *_ctf_field_class_int_copy( - struct ctf_field_class_int *fc) +static inline struct ctf_field_class_int *_ctf_field_class_int_copy(struct ctf_field_class_int *fc) { - struct ctf_field_class_int *copy_fc = ctf_field_class_int_create(); + struct ctf_field_class_int *copy_fc = ctf_field_class_int_create(); - BT_ASSERT(copy_fc); - ctf_field_class_int_copy_content(copy_fc, fc); - return copy_fc; + BT_ASSERT(copy_fc); + ctf_field_class_int_copy_content(copy_fc, fc); + return copy_fc; } -static inline -struct ctf_field_class_enum *_ctf_field_class_enum_copy( - struct ctf_field_class_enum *fc) +static inline struct ctf_field_class_enum * +_ctf_field_class_enum_copy(struct ctf_field_class_enum *fc) { - struct ctf_field_class_enum *copy_fc = ctf_field_class_enum_create(); - uint64_t i; + struct ctf_field_class_enum *copy_fc = ctf_field_class_enum_create(); + uint64_t i; - BT_ASSERT(copy_fc); - ctf_field_class_int_copy_content(©_fc->base, &fc->base); + BT_ASSERT(copy_fc); + ctf_field_class_int_copy_content(©_fc->base, &fc->base); - for (i = 0; i < fc->mappings->len; i++) { - uint64_t range_i; + for (i = 0; i < fc->mappings->len; i++) { + uint64_t range_i; - struct ctf_field_class_enum_mapping *mapping = - &g_array_index(fc->mappings, - struct ctf_field_class_enum_mapping, i); + struct ctf_field_class_enum_mapping *mapping = + &g_array_index(fc->mappings, struct ctf_field_class_enum_mapping, i); - for (range_i = 0; range_i < mapping->ranges->len; range_i++) { - struct ctf_range *range = - &g_array_index(mapping->ranges, - struct ctf_range, range_i); + for (range_i = 0; range_i < mapping->ranges->len; range_i++) { + struct ctf_range *range = &g_array_index(mapping->ranges, struct ctf_range, range_i); - ctf_field_class_enum_map_range(copy_fc, - mapping->label->str, range->lower.u, - range->upper.u); - } - } + ctf_field_class_enum_map_range(copy_fc, mapping->label->str, range->lower.u, + range->upper.u); + } + } - return copy_fc; + return copy_fc; } -static inline -struct ctf_field_class_float *_ctf_field_class_float_copy( - struct ctf_field_class_float *fc) +static inline struct ctf_field_class_float * +_ctf_field_class_float_copy(struct ctf_field_class_float *fc) { - struct ctf_field_class_float *copy_fc = ctf_field_class_float_create(); + struct ctf_field_class_float *copy_fc = ctf_field_class_float_create(); - BT_ASSERT(copy_fc); - ctf_field_class_bit_array_copy_content(©_fc->base, &fc->base); - return copy_fc; + BT_ASSERT(copy_fc); + ctf_field_class_bit_array_copy_content(©_fc->base, &fc->base); + return copy_fc; } -static inline -struct ctf_field_class_string *_ctf_field_class_string_copy( - struct ctf_field_class_string *fc) +static inline struct ctf_field_class_string * +_ctf_field_class_string_copy(struct ctf_field_class_string *fc) { - struct ctf_field_class_string *copy_fc = ctf_field_class_string_create(); + struct ctf_field_class_string *copy_fc = ctf_field_class_string_create(); - BT_ASSERT(copy_fc); - return copy_fc; + BT_ASSERT(copy_fc); + return copy_fc; } -static inline -struct ctf_field_class_struct *_ctf_field_class_struct_copy( - struct ctf_field_class_struct *fc) +static inline struct ctf_field_class_struct * +_ctf_field_class_struct_copy(struct ctf_field_class_struct *fc) { - struct ctf_field_class_struct *copy_fc = ctf_field_class_struct_create(); - uint64_t i; + struct ctf_field_class_struct *copy_fc = ctf_field_class_struct_create(); + uint64_t i; - BT_ASSERT(copy_fc); + BT_ASSERT(copy_fc); - for (i = 0; i < fc->members->len; i++) { - struct ctf_named_field_class *named_fc = - &g_array_index(fc->members, - struct ctf_named_field_class, i); + for (i = 0; i < fc->members->len; i++) { + struct ctf_named_field_class *named_fc = + &g_array_index(fc->members, struct ctf_named_field_class, i); - ctf_field_class_struct_append_member(copy_fc, - named_fc->name->str, - ctf_field_class_copy(named_fc->fc)); - } + ctf_field_class_struct_append_member(copy_fc, named_fc->name->str, + ctf_field_class_copy(named_fc->fc)); + } - return copy_fc; + return copy_fc; } -static inline -void ctf_field_path_copy_content(struct ctf_field_path *dst_fp, - struct ctf_field_path *src_fp) +static inline void ctf_field_path_copy_content(struct ctf_field_path *dst_fp, + struct ctf_field_path *src_fp) { - uint64_t i; + uint64_t i; - BT_ASSERT(dst_fp); - BT_ASSERT(src_fp); - dst_fp->root = src_fp->root; - ctf_field_path_clear(dst_fp); + BT_ASSERT(dst_fp); + BT_ASSERT(src_fp); + dst_fp->root = src_fp->root; + ctf_field_path_clear(dst_fp); - for (i = 0; i < src_fp->path->len; i++) { - int64_t index = ctf_field_path_borrow_index_by_index( - src_fp, i); + for (i = 0; i < src_fp->path->len; i++) { + int64_t index = ctf_field_path_borrow_index_by_index(src_fp, i); - ctf_field_path_append_index(dst_fp, index); - } + ctf_field_path_append_index(dst_fp, index); + } } -static inline -struct ctf_field_class_variant *_ctf_field_class_variant_copy( - struct ctf_field_class_variant *fc) +static inline struct ctf_field_class_variant * +_ctf_field_class_variant_copy(struct ctf_field_class_variant *fc) { - struct ctf_field_class_variant *copy_fc = - ctf_field_class_variant_create(); - uint64_t i; + struct ctf_field_class_variant *copy_fc = ctf_field_class_variant_create(); + uint64_t i; - BT_ASSERT(copy_fc); + BT_ASSERT(copy_fc); - for (i = 0; i < fc->options->len; i++) { - struct ctf_named_field_class *named_fc = - &g_array_index(fc->options, - struct ctf_named_field_class, i); + for (i = 0; i < fc->options->len; i++) { + struct ctf_named_field_class *named_fc = + &g_array_index(fc->options, struct ctf_named_field_class, i); - ctf_field_class_variant_append_option(copy_fc, - named_fc->name->str, - ctf_field_class_copy(named_fc->fc)); - } + ctf_field_class_variant_append_option(copy_fc, named_fc->name->str, + ctf_field_class_copy(named_fc->fc)); + } - for (i = 0; i < fc->ranges->len; i++) { - struct ctf_field_class_variant_range *range = - &g_array_index(fc->ranges, - struct ctf_field_class_variant_range, i); + for (i = 0; i < fc->ranges->len; i++) { + struct ctf_field_class_variant_range *range = + &g_array_index(fc->ranges, struct ctf_field_class_variant_range, i); - g_array_append_val(copy_fc->ranges, *range); - } + g_array_append_val(copy_fc->ranges, *range); + } - ctf_field_path_copy_content(©_fc->tag_path, &fc->tag_path); - g_string_assign(copy_fc->tag_ref, fc->tag_ref->str); - copy_fc->stored_tag_index = fc->stored_tag_index; - return copy_fc; + ctf_field_path_copy_content(©_fc->tag_path, &fc->tag_path); + g_string_assign(copy_fc->tag_ref, fc->tag_ref->str); + copy_fc->stored_tag_index = fc->stored_tag_index; + return copy_fc; } -static inline -void ctf_field_class_array_base_copy_content( - struct ctf_field_class_array_base *dst_fc, - struct ctf_field_class_array_base *src_fc) +static inline void +ctf_field_class_array_base_copy_content(struct ctf_field_class_array_base *dst_fc, + struct ctf_field_class_array_base *src_fc) { - BT_ASSERT(dst_fc); - BT_ASSERT(src_fc); - dst_fc->elem_fc = ctf_field_class_copy(src_fc->elem_fc); - dst_fc->is_text = src_fc->is_text; + BT_ASSERT(dst_fc); + BT_ASSERT(src_fc); + dst_fc->elem_fc = ctf_field_class_copy(src_fc->elem_fc); + dst_fc->is_text = src_fc->is_text; } -static inline -struct ctf_field_class_array *_ctf_field_class_array_copy( - struct ctf_field_class_array *fc) +static inline struct ctf_field_class_array * +_ctf_field_class_array_copy(struct ctf_field_class_array *fc) { - struct ctf_field_class_array *copy_fc = ctf_field_class_array_create(); + struct ctf_field_class_array *copy_fc = ctf_field_class_array_create(); - BT_ASSERT(copy_fc); - ctf_field_class_array_base_copy_content(©_fc->base, &fc->base); - copy_fc->length = fc->length; - return copy_fc; + BT_ASSERT(copy_fc); + ctf_field_class_array_base_copy_content(©_fc->base, &fc->base); + copy_fc->length = fc->length; + return copy_fc; } -static inline -struct ctf_field_class_sequence *_ctf_field_class_sequence_copy( - struct ctf_field_class_sequence *fc) +static inline struct ctf_field_class_sequence * +_ctf_field_class_sequence_copy(struct ctf_field_class_sequence *fc) { - struct ctf_field_class_sequence *copy_fc = - ctf_field_class_sequence_create(); - - BT_ASSERT(copy_fc); - ctf_field_class_array_base_copy_content(©_fc->base, &fc->base); - ctf_field_path_copy_content(©_fc->length_path, &fc->length_path); - g_string_assign(copy_fc->length_ref, fc->length_ref->str); - copy_fc->stored_length_index = fc->stored_length_index; - return copy_fc; -} - -static inline -struct ctf_field_class *ctf_field_class_copy(struct ctf_field_class *fc) -{ - struct ctf_field_class *copy_fc = NULL; + struct ctf_field_class_sequence *copy_fc = ctf_field_class_sequence_create(); + + BT_ASSERT(copy_fc); + ctf_field_class_array_base_copy_content(©_fc->base, &fc->base); + ctf_field_path_copy_content(©_fc->length_path, &fc->length_path); + g_string_assign(copy_fc->length_ref, fc->length_ref->str); + copy_fc->stored_length_index = fc->stored_length_index; + return copy_fc; +} + +static inline struct ctf_field_class *ctf_field_class_copy(struct ctf_field_class *fc) +{ + struct ctf_field_class *copy_fc = NULL; + + if (!fc) { + goto end; + } + + /* + * Translation should not have happened yet. + */ + BT_ASSERT(!fc->ir_fc); - if (!fc) { - goto end; - } - - /* - * Translation should not have happened yet. - */ - BT_ASSERT(!fc->ir_fc); - - switch (fc->type) { - case CTF_FIELD_CLASS_TYPE_INT: - copy_fc = &_ctf_field_class_int_copy(ctf_field_class_as_int (fc))->base.base; - break; - case CTF_FIELD_CLASS_TYPE_ENUM: - copy_fc = &_ctf_field_class_enum_copy(ctf_field_class_as_enum (fc))->base.base.base; - break; - case CTF_FIELD_CLASS_TYPE_FLOAT: - copy_fc = &_ctf_field_class_float_copy(ctf_field_class_as_float (fc))->base.base; - break; - case CTF_FIELD_CLASS_TYPE_STRING: - copy_fc = &_ctf_field_class_string_copy(ctf_field_class_as_string (fc))->base; - break; - case CTF_FIELD_CLASS_TYPE_STRUCT: - copy_fc = &_ctf_field_class_struct_copy(ctf_field_class_as_struct (fc))->base; - break; - case CTF_FIELD_CLASS_TYPE_ARRAY: - copy_fc = &_ctf_field_class_array_copy(ctf_field_class_as_array(fc))->base.base; - break; - case CTF_FIELD_CLASS_TYPE_SEQUENCE: - copy_fc = &_ctf_field_class_sequence_copy(ctf_field_class_as_sequence (fc))->base.base; - break; - case CTF_FIELD_CLASS_TYPE_VARIANT: - copy_fc = &_ctf_field_class_variant_copy(ctf_field_class_as_variant (fc))->base; - break; - default: - bt_common_abort(); - } - - copy_fc->type = fc->type; - copy_fc->alignment = fc->alignment; - copy_fc->in_ir = fc->in_ir; + switch (fc->type) { + case CTF_FIELD_CLASS_TYPE_INT: + copy_fc = &_ctf_field_class_int_copy(ctf_field_class_as_int(fc))->base.base; + break; + case CTF_FIELD_CLASS_TYPE_ENUM: + copy_fc = &_ctf_field_class_enum_copy(ctf_field_class_as_enum(fc))->base.base.base; + break; + case CTF_FIELD_CLASS_TYPE_FLOAT: + copy_fc = &_ctf_field_class_float_copy(ctf_field_class_as_float(fc))->base.base; + break; + case CTF_FIELD_CLASS_TYPE_STRING: + copy_fc = &_ctf_field_class_string_copy(ctf_field_class_as_string(fc))->base; + break; + case CTF_FIELD_CLASS_TYPE_STRUCT: + copy_fc = &_ctf_field_class_struct_copy(ctf_field_class_as_struct(fc))->base; + break; + case CTF_FIELD_CLASS_TYPE_ARRAY: + copy_fc = &_ctf_field_class_array_copy(ctf_field_class_as_array(fc))->base.base; + break; + case CTF_FIELD_CLASS_TYPE_SEQUENCE: + copy_fc = &_ctf_field_class_sequence_copy(ctf_field_class_as_sequence(fc))->base.base; + break; + case CTF_FIELD_CLASS_TYPE_VARIANT: + copy_fc = &_ctf_field_class_variant_copy(ctf_field_class_as_variant(fc))->base; + break; + default: + bt_common_abort(); + } + + copy_fc->type = fc->type; + copy_fc->alignment = fc->alignment; + copy_fc->in_ir = fc->in_ir; end: - return copy_fc; + return copy_fc; } -static inline -struct ctf_event_class *ctf_event_class_create(void) +static inline struct ctf_event_class *ctf_event_class_create(void) { - struct ctf_event_class *ec = g_new0(struct ctf_event_class, 1); + struct ctf_event_class *ec = g_new0(struct ctf_event_class, 1); - BT_ASSERT(ec); - ec->name = g_string_new(NULL); - BT_ASSERT(ec->name); - ec->emf_uri = g_string_new(NULL); - BT_ASSERT(ec->emf_uri); - ec->is_log_level_set = false; - return ec; + BT_ASSERT(ec); + ec->name = g_string_new(NULL); + BT_ASSERT(ec->name); + ec->emf_uri = g_string_new(NULL); + BT_ASSERT(ec->emf_uri); + ec->is_log_level_set = false; + return ec; } -static inline -void ctf_event_class_set_log_level(struct ctf_event_class *ec, - enum bt_event_class_log_level log_level) +static inline void ctf_event_class_set_log_level(struct ctf_event_class *ec, + enum bt_event_class_log_level log_level) { - BT_ASSERT(ec); - ec->log_level = log_level; - ec->is_log_level_set = true; + BT_ASSERT(ec); + ec->log_level = log_level; + ec->is_log_level_set = true; } -static inline -void ctf_event_class_destroy(struct ctf_event_class *ec) +static inline void ctf_event_class_destroy(struct ctf_event_class *ec) { - if (!ec) { - return; - } + if (!ec) { + return; + } - if (ec->name) { - g_string_free(ec->name, TRUE); - } + if (ec->name) { + g_string_free(ec->name, TRUE); + } - if (ec->emf_uri) { - g_string_free(ec->emf_uri, TRUE); - } + if (ec->emf_uri) { + g_string_free(ec->emf_uri, TRUE); + } - ctf_field_class_destroy(ec->spec_context_fc); - ctf_field_class_destroy(ec->payload_fc); - g_free(ec); + ctf_field_class_destroy(ec->spec_context_fc); + ctf_field_class_destroy(ec->payload_fc); + g_free(ec); } -static inline -struct ctf_stream_class *ctf_stream_class_create(void) +static inline struct ctf_stream_class *ctf_stream_class_create(void) { - struct ctf_stream_class *sc = g_new0(struct ctf_stream_class, 1); + struct ctf_stream_class *sc = g_new0(struct ctf_stream_class, 1); - BT_ASSERT(sc); - sc->event_classes = g_ptr_array_new_with_free_func( - (GDestroyNotify) ctf_event_class_destroy); - BT_ASSERT(sc->event_classes); - sc->event_classes_by_id = g_hash_table_new(g_direct_hash, - g_direct_equal); - BT_ASSERT(sc->event_classes_by_id); - return sc; + BT_ASSERT(sc); + sc->event_classes = g_ptr_array_new_with_free_func((GDestroyNotify) ctf_event_class_destroy); + BT_ASSERT(sc->event_classes); + sc->event_classes_by_id = g_hash_table_new(g_direct_hash, g_direct_equal); + BT_ASSERT(sc->event_classes_by_id); + return sc; } -static inline -void ctf_stream_class_destroy(struct ctf_stream_class *sc) +static inline void ctf_stream_class_destroy(struct ctf_stream_class *sc) { - if (!sc) { - return; - } + if (!sc) { + return; + } - if (sc->event_classes) { - g_ptr_array_free(sc->event_classes, TRUE); - } + if (sc->event_classes) { + g_ptr_array_free(sc->event_classes, TRUE); + } - if (sc->event_classes_by_id) { - g_hash_table_destroy(sc->event_classes_by_id); - } + if (sc->event_classes_by_id) { + g_hash_table_destroy(sc->event_classes_by_id); + } - ctf_field_class_destroy(sc->packet_context_fc); - ctf_field_class_destroy(sc->event_header_fc); - ctf_field_class_destroy(sc->event_common_context_fc); - g_free(sc); + ctf_field_class_destroy(sc->packet_context_fc); + ctf_field_class_destroy(sc->event_header_fc); + ctf_field_class_destroy(sc->event_common_context_fc); + g_free(sc); } -static inline -void ctf_stream_class_append_event_class(struct ctf_stream_class *sc, - struct ctf_event_class *ec) +static inline void ctf_stream_class_append_event_class(struct ctf_stream_class *sc, + struct ctf_event_class *ec) { - g_ptr_array_add(sc->event_classes, ec); - g_hash_table_insert(sc->event_classes_by_id, - GUINT_TO_POINTER((guint) ec->id), ec); + g_ptr_array_add(sc->event_classes, ec); + g_hash_table_insert(sc->event_classes_by_id, GUINT_TO_POINTER((guint) ec->id), ec); } -static inline -struct ctf_event_class *ctf_stream_class_borrow_event_class_by_id( - struct ctf_stream_class *sc, uint64_t type) +static inline struct ctf_event_class * +ctf_stream_class_borrow_event_class_by_id(struct ctf_stream_class *sc, uint64_t type) { - BT_ASSERT_DBG(sc); - return (struct ctf_event_class *) g_hash_table_lookup(sc->event_classes_by_id, - GUINT_TO_POINTER((guint) type)); + BT_ASSERT_DBG(sc); + return (struct ctf_event_class *) g_hash_table_lookup(sc->event_classes_by_id, + GUINT_TO_POINTER((guint) type)); } -static inline -void _ctf_trace_class_env_entry_init(struct ctf_trace_class_env_entry *entry) +static inline void _ctf_trace_class_env_entry_init(struct ctf_trace_class_env_entry *entry) { - BT_ASSERT(entry); - entry->name = g_string_new(NULL); - BT_ASSERT(entry->name); - entry->value.str = g_string_new(NULL); - BT_ASSERT(entry->value.str); + BT_ASSERT(entry); + entry->name = g_string_new(NULL); + BT_ASSERT(entry->name); + entry->value.str = g_string_new(NULL); + BT_ASSERT(entry->value.str); } -static inline -void _ctf_trace_class_env_entry_fini(struct ctf_trace_class_env_entry *entry) +static inline void _ctf_trace_class_env_entry_fini(struct ctf_trace_class_env_entry *entry) { - BT_ASSERT(entry); + BT_ASSERT(entry); - if (entry->name) { - g_string_free(entry->name, TRUE); - } + if (entry->name) { + g_string_free(entry->name, TRUE); + } - if (entry->value.str) { - g_string_free(entry->value.str, TRUE); - } + if (entry->value.str) { + g_string_free(entry->value.str, TRUE); + } } -static inline -struct ctf_clock_class *ctf_clock_class_create(void) +static inline struct ctf_clock_class *ctf_clock_class_create(void) { - struct ctf_clock_class *cc = g_new0(struct ctf_clock_class, 1); + struct ctf_clock_class *cc = g_new0(struct ctf_clock_class, 1); - BT_ASSERT(cc); - cc->name = g_string_new(NULL); - BT_ASSERT(cc->name); - cc->description = g_string_new(NULL); - BT_ASSERT(cc->description); - return cc; + BT_ASSERT(cc); + cc->name = g_string_new(NULL); + BT_ASSERT(cc->name); + cc->description = g_string_new(NULL); + BT_ASSERT(cc->description); + return cc; } -static inline -void ctf_clock_class_destroy(struct ctf_clock_class *cc) +static inline void ctf_clock_class_destroy(struct ctf_clock_class *cc) { - if (!cc) { - return; - } + if (!cc) { + return; + } - if (cc->name) { - g_string_free(cc->name, TRUE); - } + if (cc->name) { + g_string_free(cc->name, TRUE); + } - if (cc->description) { - g_string_free(cc->description, TRUE); - } + if (cc->description) { + g_string_free(cc->description, TRUE); + } - bt_clock_class_put_ref(cc->ir_cc); - g_free(cc); + bt_clock_class_put_ref(cc->ir_cc); + g_free(cc); } -static inline -struct ctf_trace_class *ctf_trace_class_create(void) +static inline struct ctf_trace_class *ctf_trace_class_create(void) { - struct ctf_trace_class *tc = g_new0(struct ctf_trace_class, 1); + struct ctf_trace_class *tc = g_new0(struct ctf_trace_class, 1); - BT_ASSERT(tc); - tc->default_byte_order = CTF_BYTE_ORDER_UNKNOWN; - tc->clock_classes = g_ptr_array_new_with_free_func( - (GDestroyNotify) ctf_clock_class_destroy); - BT_ASSERT(tc->clock_classes); - tc->stream_classes = g_ptr_array_new_with_free_func( - (GDestroyNotify) ctf_stream_class_destroy); - BT_ASSERT(tc->stream_classes); - tc->env_entries = g_array_new(FALSE, TRUE, - sizeof(struct ctf_trace_class_env_entry)); - return tc; + BT_ASSERT(tc); + tc->default_byte_order = CTF_BYTE_ORDER_UNKNOWN; + tc->clock_classes = g_ptr_array_new_with_free_func((GDestroyNotify) ctf_clock_class_destroy); + BT_ASSERT(tc->clock_classes); + tc->stream_classes = g_ptr_array_new_with_free_func((GDestroyNotify) ctf_stream_class_destroy); + BT_ASSERT(tc->stream_classes); + tc->env_entries = g_array_new(FALSE, TRUE, sizeof(struct ctf_trace_class_env_entry)); + return tc; } -static inline -void ctf_trace_class_destroy(struct ctf_trace_class *tc) +static inline void ctf_trace_class_destroy(struct ctf_trace_class *tc) { - if (!tc) { - return; - } + if (!tc) { + return; + } - ctf_field_class_destroy(tc->packet_header_fc); + ctf_field_class_destroy(tc->packet_header_fc); - if (tc->clock_classes) { - g_ptr_array_free(tc->clock_classes, TRUE); - } + if (tc->clock_classes) { + g_ptr_array_free(tc->clock_classes, TRUE); + } - if (tc->stream_classes) { - g_ptr_array_free(tc->stream_classes, TRUE); - } + if (tc->stream_classes) { + g_ptr_array_free(tc->stream_classes, TRUE); + } - if (tc->env_entries) { - uint64_t i; + if (tc->env_entries) { + uint64_t i; - for (i = 0; i < tc->env_entries->len; i++) { - struct ctf_trace_class_env_entry *entry = - &g_array_index(tc->env_entries, - struct ctf_trace_class_env_entry, i); + for (i = 0; i < tc->env_entries->len; i++) { + struct ctf_trace_class_env_entry *entry = + &g_array_index(tc->env_entries, struct ctf_trace_class_env_entry, i); - _ctf_trace_class_env_entry_fini(entry); - } + _ctf_trace_class_env_entry_fini(entry); + } - g_array_free(tc->env_entries, TRUE); - } + g_array_free(tc->env_entries, TRUE); + } - g_free(tc); + g_free(tc); } -static inline -void ctf_trace_class_append_env_entry(struct ctf_trace_class *tc, - const char *name, enum ctf_trace_class_env_entry_type type, - const char *str_value, int64_t i_value) +static inline void ctf_trace_class_append_env_entry(struct ctf_trace_class *tc, const char *name, + enum ctf_trace_class_env_entry_type type, + const char *str_value, int64_t i_value) { - struct ctf_trace_class_env_entry *entry; + struct ctf_trace_class_env_entry *entry; - BT_ASSERT(tc); - BT_ASSERT(name); - g_array_set_size(tc->env_entries, tc->env_entries->len + 1); + BT_ASSERT(tc); + BT_ASSERT(name); + g_array_set_size(tc->env_entries, tc->env_entries->len + 1); - entry = &g_array_index(tc->env_entries, - struct ctf_trace_class_env_entry, tc->env_entries->len - 1); - entry->type = type; - _ctf_trace_class_env_entry_init(entry); - g_string_assign(entry->name, name); + entry = + &g_array_index(tc->env_entries, struct ctf_trace_class_env_entry, tc->env_entries->len - 1); + entry->type = type; + _ctf_trace_class_env_entry_init(entry); + g_string_assign(entry->name, name); - if (str_value) { - g_string_assign(entry->value.str, str_value); - } + if (str_value) { + g_string_assign(entry->value.str, str_value); + } - entry->value.i = i_value; + entry->value.i = i_value; } -static inline -struct ctf_stream_class *ctf_trace_class_borrow_stream_class_by_id( - struct ctf_trace_class *tc, uint64_t id) +static inline struct ctf_stream_class * +ctf_trace_class_borrow_stream_class_by_id(struct ctf_trace_class *tc, uint64_t id) { - uint64_t i; - struct ctf_stream_class *ret_sc = NULL; + uint64_t i; + struct ctf_stream_class *ret_sc = NULL; - BT_ASSERT_DBG(tc); + BT_ASSERT_DBG(tc); - for (i = 0; i < tc->stream_classes->len; i++) { - struct ctf_stream_class *sc = - (struct ctf_stream_class *) tc->stream_classes->pdata[i]; + for (i = 0; i < tc->stream_classes->len; i++) { + struct ctf_stream_class *sc = (struct ctf_stream_class *) tc->stream_classes->pdata[i]; - if (sc->id == id) { - ret_sc = sc; - goto end; - } - } + if (sc->id == id) { + ret_sc = sc; + goto end; + } + } end: - return ret_sc; + return ret_sc; } -static inline -struct ctf_clock_class *ctf_trace_class_borrow_clock_class_by_name( - struct ctf_trace_class *tc, const char *name) +static inline struct ctf_clock_class * +ctf_trace_class_borrow_clock_class_by_name(struct ctf_trace_class *tc, const char *name) { - uint64_t i; - struct ctf_clock_class *ret_cc = NULL; + uint64_t i; + struct ctf_clock_class *ret_cc = NULL; - BT_ASSERT_DBG(tc); - BT_ASSERT_DBG(name); + BT_ASSERT_DBG(tc); + BT_ASSERT_DBG(name); - for (i = 0; i < tc->clock_classes->len; i++) { - struct ctf_clock_class *cc = - (struct ctf_clock_class *) tc->clock_classes->pdata[i]; + for (i = 0; i < tc->clock_classes->len; i++) { + struct ctf_clock_class *cc = (struct ctf_clock_class *) tc->clock_classes->pdata[i]; - BT_ASSERT_DBG(cc->name); - if (strcmp(cc->name->str, name) == 0) { - ret_cc = cc; - goto end; - } - } + BT_ASSERT_DBG(cc->name); + if (strcmp(cc->name->str, name) == 0) { + ret_cc = cc; + goto end; + } + } end: - return ret_cc; + return ret_cc; } -static inline -struct ctf_trace_class_env_entry *ctf_trace_class_borrow_env_entry_by_index( - struct ctf_trace_class *tc, uint64_t index) +static inline struct ctf_trace_class_env_entry * +ctf_trace_class_borrow_env_entry_by_index(struct ctf_trace_class *tc, uint64_t index) { - BT_ASSERT_DBG(tc); - BT_ASSERT_DBG(index < tc->env_entries->len); - return &g_array_index(tc->env_entries, struct ctf_trace_class_env_entry, - index); + BT_ASSERT_DBG(tc); + BT_ASSERT_DBG(index < tc->env_entries->len); + return &g_array_index(tc->env_entries, struct ctf_trace_class_env_entry, index); } -static inline -struct ctf_trace_class_env_entry *ctf_trace_class_borrow_env_entry_by_name( - struct ctf_trace_class *tc, const char *name) +static inline struct ctf_trace_class_env_entry * +ctf_trace_class_borrow_env_entry_by_name(struct ctf_trace_class *tc, const char *name) { - struct ctf_trace_class_env_entry *ret_entry = NULL; - uint64_t i; + struct ctf_trace_class_env_entry *ret_entry = NULL; + uint64_t i; - BT_ASSERT_DBG(tc); - BT_ASSERT_DBG(name); + BT_ASSERT_DBG(tc); + BT_ASSERT_DBG(name); - for (i = 0; i < tc->env_entries->len; i++) { - struct ctf_trace_class_env_entry *env_entry = - ctf_trace_class_borrow_env_entry_by_index(tc, i); + for (i = 0; i < tc->env_entries->len; i++) { + struct ctf_trace_class_env_entry *env_entry = + ctf_trace_class_borrow_env_entry_by_index(tc, i); - if (strcmp(env_entry->name->str, name) == 0) { - ret_entry = env_entry; - goto end; - } - } + if (strcmp(env_entry->name->str, name) == 0) { + ret_entry = env_entry; + goto end; + } + } end: - return ret_entry; + return ret_entry; } #endif /* _CTF_META_H */ diff --git a/src/plugins/ctf/common/metadata/decoder-packetized-file-stream-to-buf.cpp b/src/plugins/ctf/common/metadata/decoder-packetized-file-stream-to-buf.cpp index d0cd0304..3b7224ab 100644 --- a/src/plugins/ctf/common/metadata/decoder-packetized-file-stream-to-buf.cpp +++ b/src/plugins/ctf/common/metadata/decoder-packetized-file-stream-to-buf.cpp @@ -4,10 +4,10 @@ * Copyright 2016-2017 Philippe Proulx */ -#define BT_COMP_LOG_SELF_COMP self_comp +#define BT_COMP_LOG_SELF_COMP self_comp #define BT_COMP_LOG_SELF_COMP_CLASS self_comp_class -#define BT_LOG_OUTPUT_LEVEL log_level -#define BT_LOG_TAG "PLUGIN/CTF/META/DECODER-DECODE-PACKET" +#define BT_LOG_OUTPUT_LEVEL log_level +#define BT_LOG_TAG "PLUGIN/CTF/META/DECODER-DECODE-PACKET" #include "logging/comp-logging.h" #include "decoder-packetized-file-stream-to-buf.hpp" @@ -29,244 +29,245 @@ #include "scanner.hpp" #include "logging.hpp" -#define TSDL_MAGIC 0x75d11d57 +#define TSDL_MAGIC 0x75d11d57 -struct ctf_metadata_decoder { - struct ctf_visitor_generate_ir *visitor; - bt_uuid_t uuid; - bool is_uuid_set; - int bo; - struct ctf_metadata_decoder_config config; +struct ctf_metadata_decoder +{ + struct ctf_visitor_generate_ir *visitor; + bt_uuid_t uuid; + bool is_uuid_set; + int bo; + struct ctf_metadata_decoder_config config; }; -struct packet_header { - uint32_t magic; - bt_uuid_t uuid; - uint32_t checksum; - uint32_t content_size; - uint32_t packet_size; - uint8_t compression_scheme; - uint8_t encryption_scheme; - uint8_t checksum_scheme; - uint8_t major; - uint8_t minor; +struct packet_header +{ + uint32_t magic; + bt_uuid_t uuid; + uint32_t checksum; + uint32_t content_size; + uint32_t packet_size; + uint8_t compression_scheme; + uint8_t encryption_scheme; + uint8_t checksum_scheme; + uint8_t major; + uint8_t minor; } __attribute__((__packed__)); -static -int decode_packet(FILE *in_fp, FILE *out_fp, - int byte_order, bool *is_uuid_set, uint8_t *uuid, - bt_logging_level log_level, bt_self_component *self_comp, - bt_self_component_class *self_comp_class) +static int decode_packet(FILE *in_fp, FILE *out_fp, int byte_order, bool *is_uuid_set, + uint8_t *uuid, bt_logging_level log_level, bt_self_component *self_comp, + bt_self_component_class *self_comp_class) { - struct packet_header header; - size_t readlen, writelen, toread; - uint8_t buf[512 + 1]; /* + 1 for debug-mode \0 */ - int ret = 0; - const long offset = ftell(in_fp); - - if (offset < 0) { - BT_COMP_LOGE_APPEND_CAUSE_ERRNO(BT_COMP_LOG_SELF_COMP, - "Failed to get current metadata file position", - "."); - goto error; - } - BT_COMP_LOGD("Decoding metadata packet: offset=%ld", offset); - readlen = fread(&header, sizeof(header), 1, in_fp); - if (feof(in_fp) != 0) { - BT_COMP_LOGI("Reached end of file: offset=%ld", ftell(in_fp)); - goto end; - } - if (readlen < 1) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot decode metadata packet: offset=%ld", offset); - goto error; - } - - if (byte_order != BYTE_ORDER) { - header.magic = GUINT32_SWAP_LE_BE(header.magic); - header.checksum = GUINT32_SWAP_LE_BE(header.checksum); - header.content_size = GUINT32_SWAP_LE_BE(header.content_size); - header.packet_size = GUINT32_SWAP_LE_BE(header.packet_size); - } - - if (header.compression_scheme) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Metadata packet compression is not supported as of this version: " - "compression-scheme=%u, offset=%ld", - (unsigned int) header.compression_scheme, offset); - goto error; - } - - if (header.encryption_scheme) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Metadata packet encryption is not supported as of this version: " - "encryption-scheme=%u, offset=%ld", - (unsigned int) header.encryption_scheme, offset); - goto error; - } - - if (header.checksum || header.checksum_scheme) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Metadata packet checksum verification is not supported as of this version: " - "checksum-scheme=%u, checksum=%x, offset=%ld", - (unsigned int) header.checksum_scheme, header.checksum, - offset); - goto error; - } - - if (!ctf_metadata_decoder_is_packet_version_valid(header.major, - header.minor)) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid metadata packet version: " - "version=%u.%u, offset=%ld", - header.major, header.minor, offset); - goto error; - } - - /* Set expected trace UUID if not set; otherwise validate it */ - if (is_uuid_set) { - if (!*is_uuid_set) { - bt_uuid_copy(uuid, header.uuid); - *is_uuid_set = true; - } else if (bt_uuid_compare(header.uuid, uuid)) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Metadata UUID mismatch between packets of the same stream: " - "packet-uuid=\"" BT_UUID_FMT "\", " - "expected-uuid=\"" BT_UUID_FMT "\", " - "offset=%ld", - BT_UUID_FMT_VALUES(header.uuid), - BT_UUID_FMT_VALUES(uuid), - offset); - goto error; - } - } - - if ((header.content_size / CHAR_BIT) < sizeof(header)) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Bad metadata packet content size: content-size=%u, " - "offset=%ld", header.content_size, offset); - goto error; - } - - toread = header.content_size / CHAR_BIT - sizeof(header); - - for (;;) { - size_t loop_read; - - loop_read = MIN(sizeof(buf) - 1, toread); - readlen = fread(buf, sizeof(uint8_t), loop_read, in_fp); - if (ferror(in_fp)) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot read metadata packet buffer: " - "offset=%ld, read-size=%zu", - ftell(in_fp), loop_read); - goto error; - } - if (readlen > loop_read) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("fread returned more byte than expected: " - "read-size-asked=%zu, read-size-returned=%zu", - loop_read, readlen); - goto error; - } - - writelen = fwrite(buf, sizeof(uint8_t), readlen, out_fp); - if (writelen < readlen || ferror(out_fp)) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot write decoded metadata text to buffer: " - "read-offset=%ld, write-size=%zu", - ftell(in_fp), readlen); - goto error; - } - - toread -= readlen; - if (toread == 0) { - int fseek_ret; - - /* Read leftover padding */ - toread = (header.packet_size - header.content_size) / - CHAR_BIT; - fseek_ret = fseek(in_fp, toread, SEEK_CUR); - if (fseek_ret < 0) { - BT_COMP_LOGW_STR("Missing padding at the end of the metadata stream."); - } - break; - } - } - - goto end; + struct packet_header header; + size_t readlen, writelen, toread; + uint8_t buf[512 + 1]; /* + 1 for debug-mode \0 */ + int ret = 0; + const long offset = ftell(in_fp); + + if (offset < 0) { + BT_COMP_LOGE_APPEND_CAUSE_ERRNO(BT_COMP_LOG_SELF_COMP, + "Failed to get current metadata file position", "."); + goto error; + } + BT_COMP_LOGD("Decoding metadata packet: offset=%ld", offset); + readlen = fread(&header, sizeof(header), 1, in_fp); + if (feof(in_fp) != 0) { + BT_COMP_LOGI("Reached end of file: offset=%ld", ftell(in_fp)); + goto end; + } + if (readlen < 1) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot decode metadata packet: offset=%ld", + offset); + goto error; + } + + if (byte_order != BYTE_ORDER) { + header.magic = GUINT32_SWAP_LE_BE(header.magic); + header.checksum = GUINT32_SWAP_LE_BE(header.checksum); + header.content_size = GUINT32_SWAP_LE_BE(header.content_size); + header.packet_size = GUINT32_SWAP_LE_BE(header.packet_size); + } + + if (header.compression_scheme) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Metadata packet compression is not supported as of this version: " + "compression-scheme=%u, offset=%ld", + (unsigned int) header.compression_scheme, offset); + goto error; + } + + if (header.encryption_scheme) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Metadata packet encryption is not supported as of this version: " + "encryption-scheme=%u, offset=%ld", + (unsigned int) header.encryption_scheme, offset); + goto error; + } + + if (header.checksum || header.checksum_scheme) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Metadata packet checksum verification is not supported as of this version: " + "checksum-scheme=%u, checksum=%x, offset=%ld", + (unsigned int) header.checksum_scheme, header.checksum, offset); + goto error; + } + + if (!ctf_metadata_decoder_is_packet_version_valid(header.major, header.minor)) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid metadata packet version: " + "version=%u.%u, offset=%ld", + header.major, header.minor, offset); + goto error; + } + + /* Set expected trace UUID if not set; otherwise validate it */ + if (is_uuid_set) { + if (!*is_uuid_set) { + bt_uuid_copy(uuid, header.uuid); + *is_uuid_set = true; + } else if (bt_uuid_compare(header.uuid, uuid)) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Metadata UUID mismatch between packets of the same stream: " + "packet-uuid=\"" BT_UUID_FMT "\", " + "expected-uuid=\"" BT_UUID_FMT "\", " + "offset=%ld", + BT_UUID_FMT_VALUES(header.uuid), BT_UUID_FMT_VALUES(uuid), offset); + goto error; + } + } + + if ((header.content_size / CHAR_BIT) < sizeof(header)) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Bad metadata packet content size: content-size=%u, " + "offset=%ld", + header.content_size, offset); + goto error; + } + + toread = header.content_size / CHAR_BIT - sizeof(header); + + for (;;) { + size_t loop_read; + + loop_read = MIN(sizeof(buf) - 1, toread); + readlen = fread(buf, sizeof(uint8_t), loop_read, in_fp); + if (ferror(in_fp)) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot read metadata packet buffer: " + "offset=%ld, read-size=%zu", + ftell(in_fp), loop_read); + goto error; + } + if (readlen > loop_read) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("fread returned more byte than expected: " + "read-size-asked=%zu, read-size-returned=%zu", + loop_read, readlen); + goto error; + } + + writelen = fwrite(buf, sizeof(uint8_t), readlen, out_fp); + if (writelen < readlen || ferror(out_fp)) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Cannot write decoded metadata text to buffer: " + "read-offset=%ld, write-size=%zu", + ftell(in_fp), readlen); + goto error; + } + + toread -= readlen; + if (toread == 0) { + int fseek_ret; + + /* Read leftover padding */ + toread = (header.packet_size - header.content_size) / CHAR_BIT; + fseek_ret = fseek(in_fp, toread, SEEK_CUR); + if (fseek_ret < 0) { + BT_COMP_LOGW_STR("Missing padding at the end of the metadata stream."); + } + break; + } + } + + goto end; error: - ret = -1; + ret = -1; end: - return ret; + return ret; } BT_HIDDEN -int ctf_metadata_decoder_packetized_file_stream_to_buf(FILE *fp, - char **buf, int byte_order, bool *is_uuid_set, - uint8_t *uuid, bt_logging_level log_level, - bt_self_component *self_comp, - bt_self_component_class *self_comp_class) +int ctf_metadata_decoder_packetized_file_stream_to_buf(FILE *fp, char **buf, int byte_order, + bool *is_uuid_set, uint8_t *uuid, + bt_logging_level log_level, + bt_self_component *self_comp, + bt_self_component_class *self_comp_class) { - FILE *out_fp; - size_t size; - int ret = 0; - int tret; - size_t packet_index = 0; - - out_fp = bt_open_memstream(buf, &size); - if (!out_fp) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot open memory stream: %s.", - strerror(errno)); - goto error; - } - - for (;;) { - if (feof(fp) != 0) { - break; - } - - tret = decode_packet(fp, out_fp, byte_order, is_uuid_set, - uuid, log_level, self_comp, self_comp_class); - if (tret) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot decode packet: index=%zu", - packet_index); - goto error; - } - - packet_index++; - } - - /* Make sure the whole string ends with a null character */ - tret = fputc('\0', out_fp); - if (tret == EOF) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( - "Cannot append '\\0' to the decoded metadata buffer."); - goto error; - } - - /* Close stream, which also flushes the buffer */ - ret = bt_close_memstream(buf, &size, out_fp); - /* - * See fclose(3). Further access to out_fp after both success - * and error, even through another bt_close_memstream(), results - * in undefined behavior. Nullify out_fp to ensure we don't - * fclose it twice on error. - */ - out_fp = NULL; - if (ret < 0) { - BT_COMP_LOGE_APPEND_CAUSE_ERRNO(BT_COMP_LOG_SELF_COMP, "Cannot close memory stream", "."); - goto error; - } - - goto end; + FILE *out_fp; + size_t size; + int ret = 0; + int tret; + size_t packet_index = 0; + + out_fp = bt_open_memstream(buf, &size); + if (!out_fp) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot open memory stream: %s.", strerror(errno)); + goto error; + } + + for (;;) { + if (feof(fp) != 0) { + break; + } + + tret = decode_packet(fp, out_fp, byte_order, is_uuid_set, uuid, log_level, self_comp, + self_comp_class); + if (tret) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot decode packet: index=%zu", + packet_index); + goto error; + } + + packet_index++; + } + + /* Make sure the whole string ends with a null character */ + tret = fputc('\0', out_fp); + if (tret == EOF) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Cannot append '\\0' to the decoded metadata buffer."); + goto error; + } + + /* Close stream, which also flushes the buffer */ + ret = bt_close_memstream(buf, &size, out_fp); + /* + * See fclose(3). Further access to out_fp after both success + * and error, even through another bt_close_memstream(), results + * in undefined behavior. Nullify out_fp to ensure we don't + * fclose it twice on error. + */ + out_fp = NULL; + if (ret < 0) { + BT_COMP_LOGE_APPEND_CAUSE_ERRNO(BT_COMP_LOG_SELF_COMP, "Cannot close memory stream", "."); + goto error; + } + + goto end; error: - ret = -1; + ret = -1; - if (out_fp) { - if (bt_close_memstream(buf, &size, out_fp)) { - BT_COMP_LOGE_ERRNO("Cannot close memory stream", "."); - } - } + if (out_fp) { + if (bt_close_memstream(buf, &size, out_fp)) { + BT_COMP_LOGE_ERRNO("Cannot close memory stream", "."); + } + } - if (*buf) { - free(*buf); - *buf = NULL; - } + if (*buf) { + free(*buf); + *buf = NULL; + } end: - return ret; + return ret; } diff --git a/src/plugins/ctf/common/metadata/decoder-packetized-file-stream-to-buf.hpp b/src/plugins/ctf/common/metadata/decoder-packetized-file-stream-to-buf.hpp index cc671242..9d175967 100644 --- a/src/plugins/ctf/common/metadata/decoder-packetized-file-stream-to-buf.hpp +++ b/src/plugins/ctf/common/metadata/decoder-packetized-file-stream-to-buf.hpp @@ -13,10 +13,10 @@ #include BT_HIDDEN -int ctf_metadata_decoder_packetized_file_stream_to_buf(FILE *fp, - char **buf, int byte_order, bool *is_uuid_set, - uint8_t *uuid, bt_logging_level log_level, - bt_self_component *self_comp, - bt_self_component_class *self_comp_class); +int ctf_metadata_decoder_packetized_file_stream_to_buf(FILE *fp, char **buf, int byte_order, + bool *is_uuid_set, uint8_t *uuid, + bt_logging_level log_level, + bt_self_component *self_comp, + bt_self_component_class *self_comp_class); #endif /* SRC_PLUGINS_CTF_COMMON_METADATA_DECODER_PACKETIZED_FILE_STREAM_TO_BUF */ diff --git a/src/plugins/ctf/common/metadata/decoder.cpp b/src/plugins/ctf/common/metadata/decoder.cpp index 31019dd2..a45d7b03 100644 --- a/src/plugins/ctf/common/metadata/decoder.cpp +++ b/src/plugins/ctf/common/metadata/decoder.cpp @@ -4,10 +4,10 @@ * Copyright 2016-2017 Philippe Proulx */ -#define BT_COMP_LOG_SELF_COMP (mdec->config.self_comp) +#define BT_COMP_LOG_SELF_COMP (mdec->config.self_comp) #define BT_COMP_LOG_SELF_COMP_CLASS (mdec->config.self_comp_class) -#define BT_LOG_OUTPUT_LEVEL (mdec->config.log_level) -#define BT_LOG_TAG "PLUGIN/CTF/META/DECODER" +#define BT_LOG_OUTPUT_LEVEL (mdec->config.log_level) +#define BT_LOG_TAG "PLUGIN/CTF/META/DECODER" #include "logging/comp-logging.h" #include @@ -29,450 +29,451 @@ #include "parser-wrap.hpp" #include "decoder-packetized-file-stream-to-buf.hpp" -#define TSDL_MAGIC 0x75d11d57 - -struct ctf_metadata_decoder { - struct ctf_scanner *scanner; - GString *text; - struct ctf_visitor_generate_ir *visitor; - bt_uuid_t uuid; - bool is_uuid_set; - int bo; - struct ctf_metadata_decoder_config config; - struct meta_log_config log_cfg; +#define TSDL_MAGIC 0x75d11d57 + +struct ctf_metadata_decoder +{ + struct ctf_scanner *scanner; + GString *text; + struct ctf_visitor_generate_ir *visitor; + bt_uuid_t uuid; + bool is_uuid_set; + int bo; + struct ctf_metadata_decoder_config config; + struct meta_log_config log_cfg; }; -struct packet_header { - uint32_t magic; - bt_uuid_t uuid; - uint32_t checksum; - uint32_t content_size; - uint32_t packet_size; - uint8_t compression_scheme; - uint8_t encryption_scheme; - uint8_t checksum_scheme; - uint8_t major; - uint8_t minor; +struct packet_header +{ + uint32_t magic; + bt_uuid_t uuid; + uint32_t checksum; + uint32_t content_size; + uint32_t packet_size; + uint8_t compression_scheme; + uint8_t encryption_scheme; + uint8_t checksum_scheme; + uint8_t major; + uint8_t minor; } __attribute__((__packed__)); BT_HIDDEN -int ctf_metadata_decoder_is_packetized(FILE *fp, bool *is_packetized, - int *byte_order, bt_logging_level log_level, - bt_self_component *self_comp) +int ctf_metadata_decoder_is_packetized(FILE *fp, bool *is_packetized, int *byte_order, + bt_logging_level log_level, bt_self_component *self_comp) { - uint32_t magic; - size_t len; - int ret = 0; - - *is_packetized = false; - len = fread(&magic, sizeof(magic), 1, fp); - if (len != 1) { - BT_COMP_LOG_CUR_LVL(BT_LOG_INFO, log_level, self_comp, - "Cannot read first metadata packet header: assuming the stream is not packetized."); - ret = -1; - goto end; - } - - if (byte_order) { - if (magic == TSDL_MAGIC) { - *is_packetized = true; - *byte_order = BYTE_ORDER; - } else if (magic == GUINT32_SWAP_LE_BE(TSDL_MAGIC)) { - *is_packetized = true; - *byte_order = BYTE_ORDER == BIG_ENDIAN ? - LITTLE_ENDIAN : BIG_ENDIAN; - } - } + uint32_t magic; + size_t len; + int ret = 0; + + *is_packetized = false; + len = fread(&magic, sizeof(magic), 1, fp); + if (len != 1) { + BT_COMP_LOG_CUR_LVL( + BT_LOG_INFO, log_level, self_comp, + "Cannot read first metadata packet header: assuming the stream is not packetized."); + ret = -1; + goto end; + } + + if (byte_order) { + if (magic == TSDL_MAGIC) { + *is_packetized = true; + *byte_order = BYTE_ORDER; + } else if (magic == GUINT32_SWAP_LE_BE(TSDL_MAGIC)) { + *is_packetized = true; + *byte_order = BYTE_ORDER == BIG_ENDIAN ? LITTLE_ENDIAN : BIG_ENDIAN; + } + } end: - rewind(fp); + rewind(fp); - return ret; + return ret; } BT_HIDDEN -struct ctf_metadata_decoder *ctf_metadata_decoder_create( - const struct ctf_metadata_decoder_config *config) +struct ctf_metadata_decoder * +ctf_metadata_decoder_create(const struct ctf_metadata_decoder_config *config) { - struct ctf_metadata_decoder *mdec = - g_new0(struct ctf_metadata_decoder, 1); - - BT_ASSERT(config); - BT_COMP_LOG_CUR_LVL(BT_LOG_DEBUG, config->log_level, config->self_comp, - "Creating CTF metadata decoder: " - "clock-class-offset-s=%" PRId64 ", " - "clock-class-offset-ns=%" PRId64, - config->clock_class_offset_s, config->clock_class_offset_ns); - - if (!mdec) { - BT_COMP_LOG_CUR_LVL(BT_LOG_ERROR, config->log_level, - config->self_comp, - "Failed to allocate one CTF metadata decoder."); - goto end; - } - - mdec->log_cfg.log_level = config->log_level; - mdec->log_cfg.self_comp = config->self_comp; - mdec->log_cfg.self_comp_class = config->self_comp_class; - mdec->scanner = ctf_scanner_alloc(); - if (!mdec->scanner) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot allocate a metadata lexical scanner: " - "mdec-addr=%p", mdec); - goto error; - } - - mdec->text = g_string_new(NULL); - if (!mdec->text) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Failed to allocate one GString: " - "mdec-addr=%p", mdec); - goto error; - } - - mdec->bo = -1; - mdec->config = *config; - mdec->visitor = ctf_visitor_generate_ir_create(config); - if (!mdec->visitor) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Failed to create a CTF IR metadata AST visitor: " - "mdec-addr=%p", mdec); - goto error; - } - - BT_COMP_LOGD("Creating CTF metadata decoder: " - "clock-class-offset-s=%" PRId64 ", " - "clock-class-offset-ns=%" PRId64 ", addr=%p", - config->clock_class_offset_s, config->clock_class_offset_ns, - mdec); - goto end; + struct ctf_metadata_decoder *mdec = g_new0(struct ctf_metadata_decoder, 1); + + BT_ASSERT(config); + BT_COMP_LOG_CUR_LVL(BT_LOG_DEBUG, config->log_level, config->self_comp, + "Creating CTF metadata decoder: " + "clock-class-offset-s=%" PRId64 ", " + "clock-class-offset-ns=%" PRId64, + config->clock_class_offset_s, config->clock_class_offset_ns); + + if (!mdec) { + BT_COMP_LOG_CUR_LVL(BT_LOG_ERROR, config->log_level, config->self_comp, + "Failed to allocate one CTF metadata decoder."); + goto end; + } + + mdec->log_cfg.log_level = config->log_level; + mdec->log_cfg.self_comp = config->self_comp; + mdec->log_cfg.self_comp_class = config->self_comp_class; + mdec->scanner = ctf_scanner_alloc(); + if (!mdec->scanner) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot allocate a metadata lexical scanner: " + "mdec-addr=%p", + mdec); + goto error; + } + + mdec->text = g_string_new(NULL); + if (!mdec->text) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Failed to allocate one GString: " + "mdec-addr=%p", + mdec); + goto error; + } + + mdec->bo = -1; + mdec->config = *config; + mdec->visitor = ctf_visitor_generate_ir_create(config); + if (!mdec->visitor) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Failed to create a CTF IR metadata AST visitor: " + "mdec-addr=%p", + mdec); + goto error; + } + + BT_COMP_LOGD("Creating CTF metadata decoder: " + "clock-class-offset-s=%" PRId64 ", " + "clock-class-offset-ns=%" PRId64 ", addr=%p", + config->clock_class_offset_s, config->clock_class_offset_ns, mdec); + goto end; error: - ctf_metadata_decoder_destroy(mdec); - mdec = NULL; + ctf_metadata_decoder_destroy(mdec); + mdec = NULL; end: - return mdec; + return mdec; } BT_HIDDEN void ctf_metadata_decoder_destroy(struct ctf_metadata_decoder *mdec) { - if (!mdec) { - return; - } + if (!mdec) { + return; + } - if (mdec->scanner) { - ctf_scanner_free(mdec->scanner); - } + if (mdec->scanner) { + ctf_scanner_free(mdec->scanner); + } - if (mdec->text) { - g_string_free(mdec->text, TRUE); - } + if (mdec->text) { + g_string_free(mdec->text, TRUE); + } - BT_COMP_LOGD("Destroying CTF metadata decoder: addr=%p", mdec); - ctf_visitor_generate_ir_destroy(mdec->visitor); - g_free(mdec); + BT_COMP_LOGD("Destroying CTF metadata decoder: addr=%p", mdec); + ctf_visitor_generate_ir_destroy(mdec->visitor); + g_free(mdec); } BT_HIDDEN -enum ctf_metadata_decoder_status ctf_metadata_decoder_append_content( - struct ctf_metadata_decoder *mdec, FILE *fp) +enum ctf_metadata_decoder_status +ctf_metadata_decoder_append_content(struct ctf_metadata_decoder *mdec, FILE *fp) { - enum ctf_metadata_decoder_status status = - CTF_METADATA_DECODER_STATUS_OK; - int ret; - char *buf = NULL; - bool close_fp = false; - long start_pos = -1; - bool is_packetized; - - BT_ASSERT(mdec); - ret = ctf_metadata_decoder_is_packetized(fp, &is_packetized, &mdec->bo, - mdec->config.log_level, mdec->config.self_comp); - if (ret) { - status = CTF_METADATA_DECODER_STATUS_ERROR; - goto end; - } - - if (is_packetized) { - BT_COMP_LOGI("Metadata stream is packetized: mdec-addr=%p", mdec); - ret = ctf_metadata_decoder_packetized_file_stream_to_buf(fp, - &buf, mdec->bo, &mdec->is_uuid_set, - mdec->uuid, mdec->config.log_level, - mdec->config.self_comp, - mdec->config.self_comp_class); - if (ret) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot decode packetized metadata packets to metadata text: " - "mdec-addr=%p, ret=%d", mdec, ret); - status = CTF_METADATA_DECODER_STATUS_ERROR; - goto end; - } - - if (strlen(buf) == 0) { - /* An empty metadata packet is OK. */ - goto end; - } - - /* Convert the real file pointer to a memory file pointer */ - fp = bt_fmemopen(buf, strlen(buf), "rb"); - close_fp = true; - if (!fp) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot memory-open metadata buffer: %s: " - "mdec-addr=%p", strerror(errno), mdec); - status = CTF_METADATA_DECODER_STATUS_ERROR; - goto end; - } - } else { - unsigned int major, minor; - ssize_t nr_items; - const long init_pos = ftell(fp); - - BT_COMP_LOGI("Metadata stream is plain text: mdec-addr=%p", mdec); - - if (init_pos < 0) { - BT_COMP_LOGE_APPEND_CAUSE_ERRNO(BT_COMP_LOG_SELF_COMP, - "Failed to get current file position", "."); - status = CTF_METADATA_DECODER_STATUS_ERROR; - goto end; - } - - /* Check text-only metadata header and version */ - nr_items = fscanf(fp, "/* CTF %10u.%10u", &major, &minor); - if (nr_items < 2) { - BT_COMP_LOGW("Missing \"/* CTF major.minor\" signature in plain text metadata file stream: " - "mdec-addr=%p", mdec); - } - - BT_COMP_LOGI("Found metadata stream version in signature: version=%u.%u", major, minor); - - if (!ctf_metadata_decoder_is_packet_version_valid(major, - minor)) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid metadata version found in plain text signature: " - "version=%u.%u, mdec-addr=%p", major, minor, - mdec); - status = CTF_METADATA_DECODER_STATUS_INVAL_VERSION; - goto end; - } - - if (fseek(fp, init_pos, SEEK_SET)) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot seek metadata file stream to initial position: %s: " - "mdec-addr=%p", strerror(errno), mdec); - status = CTF_METADATA_DECODER_STATUS_ERROR; - goto end; - } - } + enum ctf_metadata_decoder_status status = CTF_METADATA_DECODER_STATUS_OK; + int ret; + char *buf = NULL; + bool close_fp = false; + long start_pos = -1; + bool is_packetized; + + BT_ASSERT(mdec); + ret = ctf_metadata_decoder_is_packetized(fp, &is_packetized, &mdec->bo, mdec->config.log_level, + mdec->config.self_comp); + if (ret) { + status = CTF_METADATA_DECODER_STATUS_ERROR; + goto end; + } + + if (is_packetized) { + BT_COMP_LOGI("Metadata stream is packetized: mdec-addr=%p", mdec); + ret = ctf_metadata_decoder_packetized_file_stream_to_buf( + fp, &buf, mdec->bo, &mdec->is_uuid_set, mdec->uuid, mdec->config.log_level, + mdec->config.self_comp, mdec->config.self_comp_class); + if (ret) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Cannot decode packetized metadata packets to metadata text: " + "mdec-addr=%p, ret=%d", + mdec, ret); + status = CTF_METADATA_DECODER_STATUS_ERROR; + goto end; + } + + if (strlen(buf) == 0) { + /* An empty metadata packet is OK. */ + goto end; + } + + /* Convert the real file pointer to a memory file pointer */ + fp = bt_fmemopen(buf, strlen(buf), "rb"); + close_fp = true; + if (!fp) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot memory-open metadata buffer: %s: " + "mdec-addr=%p", + strerror(errno), mdec); + status = CTF_METADATA_DECODER_STATUS_ERROR; + goto end; + } + } else { + unsigned int major, minor; + ssize_t nr_items; + const long init_pos = ftell(fp); + + BT_COMP_LOGI("Metadata stream is plain text: mdec-addr=%p", mdec); + + if (init_pos < 0) { + BT_COMP_LOGE_APPEND_CAUSE_ERRNO(BT_COMP_LOG_SELF_COMP, + "Failed to get current file position", "."); + status = CTF_METADATA_DECODER_STATUS_ERROR; + goto end; + } + + /* Check text-only metadata header and version */ + nr_items = fscanf(fp, "/* CTF %10u.%10u", &major, &minor); + if (nr_items < 2) { + BT_COMP_LOGW( + "Missing \"/* CTF major.minor\" signature in plain text metadata file stream: " + "mdec-addr=%p", + mdec); + } + + BT_COMP_LOGI("Found metadata stream version in signature: version=%u.%u", major, minor); + + if (!ctf_metadata_decoder_is_packet_version_valid(major, minor)) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Invalid metadata version found in plain text signature: " + "version=%u.%u, mdec-addr=%p", + major, minor, mdec); + status = CTF_METADATA_DECODER_STATUS_INVAL_VERSION; + goto end; + } + + if (fseek(fp, init_pos, SEEK_SET)) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Cannot seek metadata file stream to initial position: %s: " + "mdec-addr=%p", + strerror(errno), mdec); + status = CTF_METADATA_DECODER_STATUS_ERROR; + goto end; + } + } #if YYDEBUG - if (BT_LOG_ON_TRACE) { - yydebug = 1; - } + if (BT_LOG_ON_TRACE) { + yydebug = 1; + } #endif - /* Save the file's position: we'll seek back to append the plain text */ - BT_ASSERT(fp); - - if (mdec->config.keep_plain_text) { - start_pos = ftell(fp); - } - - /* Append the metadata text content */ - ret = ctf_scanner_append_ast(mdec->scanner, fp); - if (ret) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot create the metadata AST out of the metadata text: " - "mdec-addr=%p", mdec); - status = CTF_METADATA_DECODER_STATUS_INCOMPLETE; - goto end; - } - - /* We know it's complete: append plain text */ - if (mdec->config.keep_plain_text) { - BT_ASSERT(start_pos != -1); - ret = fseek(fp, start_pos, SEEK_SET); - if (ret) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Failed to seek file: ret=%d, mdec-addr=%p", - ret, mdec); - status = CTF_METADATA_DECODER_STATUS_ERROR; - goto end; - } - - ret = bt_common_append_file_content_to_g_string(mdec->text, fp); - if (ret) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Failed to append to current plain text: " - "ret=%d, mdec-addr=%p", ret, mdec); - status = CTF_METADATA_DECODER_STATUS_ERROR; - goto end; - } - } - - ret = ctf_visitor_semantic_check(0, &mdec->scanner->ast->root, - &mdec->log_cfg); - if (ret) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Validation of the metadata semantics failed: " - "mdec-addr=%p", mdec); - status = CTF_METADATA_DECODER_STATUS_ERROR; - goto end; - } - - if (mdec->config.create_trace_class) { - ret = ctf_visitor_generate_ir_visit_node(mdec->visitor, - &mdec->scanner->ast->root); - switch (ret) { - case 0: - /* Success */ - break; - case -EINCOMPLETE: - BT_COMP_LOGD("While visiting metadata AST: incomplete data: " - "mdec-addr=%p", mdec); - status = CTF_METADATA_DECODER_STATUS_INCOMPLETE; - goto end; - default: - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Failed to visit AST node to create CTF IR objects: " - "mdec-addr=%p, ret=%d", mdec, ret); - status = CTF_METADATA_DECODER_STATUS_IR_VISITOR_ERROR; - goto end; - } - } + /* Save the file's position: we'll seek back to append the plain text */ + BT_ASSERT(fp); + + if (mdec->config.keep_plain_text) { + start_pos = ftell(fp); + } + + /* Append the metadata text content */ + ret = ctf_scanner_append_ast(mdec->scanner, fp); + if (ret) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Cannot create the metadata AST out of the metadata text: " + "mdec-addr=%p", + mdec); + status = CTF_METADATA_DECODER_STATUS_INCOMPLETE; + goto end; + } + + /* We know it's complete: append plain text */ + if (mdec->config.keep_plain_text) { + BT_ASSERT(start_pos != -1); + ret = fseek(fp, start_pos, SEEK_SET); + if (ret) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Failed to seek file: ret=%d, mdec-addr=%p", + ret, mdec); + status = CTF_METADATA_DECODER_STATUS_ERROR; + goto end; + } + + ret = bt_common_append_file_content_to_g_string(mdec->text, fp); + if (ret) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Failed to append to current plain text: " + "ret=%d, mdec-addr=%p", + ret, mdec); + status = CTF_METADATA_DECODER_STATUS_ERROR; + goto end; + } + } + + ret = ctf_visitor_semantic_check(0, &mdec->scanner->ast->root, &mdec->log_cfg); + if (ret) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Validation of the metadata semantics failed: " + "mdec-addr=%p", + mdec); + status = CTF_METADATA_DECODER_STATUS_ERROR; + goto end; + } + + if (mdec->config.create_trace_class) { + ret = ctf_visitor_generate_ir_visit_node(mdec->visitor, &mdec->scanner->ast->root); + switch (ret) { + case 0: + /* Success */ + break; + case -EINCOMPLETE: + BT_COMP_LOGD("While visiting metadata AST: incomplete data: " + "mdec-addr=%p", + mdec); + status = CTF_METADATA_DECODER_STATUS_INCOMPLETE; + goto end; + default: + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Failed to visit AST node to create CTF IR objects: " + "mdec-addr=%p, ret=%d", + mdec, ret); + status = CTF_METADATA_DECODER_STATUS_IR_VISITOR_ERROR; + goto end; + } + } end: #if YYDEBUG - yydebug = 0; + yydebug = 0; #endif - if (fp && close_fp) { - if (fclose(fp)) { - BT_COMP_LOGE("Cannot close metadata file stream: " - "mdec-addr=%p", mdec); - } - } + if (fp && close_fp) { + if (fclose(fp)) { + BT_COMP_LOGE("Cannot close metadata file stream: " + "mdec-addr=%p", + mdec); + } + } - free(buf); + free(buf); - return status; + return status; } BT_HIDDEN -bt_trace_class *ctf_metadata_decoder_get_ir_trace_class( - struct ctf_metadata_decoder *mdec) +bt_trace_class *ctf_metadata_decoder_get_ir_trace_class(struct ctf_metadata_decoder *mdec) { - BT_ASSERT_DBG(mdec); - BT_ASSERT_DBG(mdec->config.create_trace_class); - return ctf_visitor_generate_ir_get_ir_trace_class(mdec->visitor); + BT_ASSERT_DBG(mdec); + BT_ASSERT_DBG(mdec->config.create_trace_class); + return ctf_visitor_generate_ir_get_ir_trace_class(mdec->visitor); } BT_HIDDEN -struct ctf_trace_class *ctf_metadata_decoder_borrow_ctf_trace_class( - struct ctf_metadata_decoder *mdec) +struct ctf_trace_class * +ctf_metadata_decoder_borrow_ctf_trace_class(struct ctf_metadata_decoder *mdec) { - BT_ASSERT_DBG(mdec); - BT_ASSERT_DBG(mdec->config.create_trace_class); - return ctf_visitor_generate_ir_borrow_ctf_trace_class(mdec->visitor); + BT_ASSERT_DBG(mdec); + BT_ASSERT_DBG(mdec->config.create_trace_class); + return ctf_visitor_generate_ir_borrow_ctf_trace_class(mdec->visitor); } BT_HIDDEN const char *ctf_metadata_decoder_get_text(struct ctf_metadata_decoder *mdec) { - BT_ASSERT_DBG(mdec); - BT_ASSERT_DBG(mdec->config.keep_plain_text); - return mdec->text->str; + BT_ASSERT_DBG(mdec); + BT_ASSERT_DBG(mdec->config.keep_plain_text); + return mdec->text->str; } BT_HIDDEN int ctf_metadata_decoder_get_byte_order(struct ctf_metadata_decoder *mdec) { - BT_ASSERT_DBG(mdec); - return mdec->bo; + BT_ASSERT_DBG(mdec); + return mdec->bo; } BT_HIDDEN -int ctf_metadata_decoder_get_uuid(struct ctf_metadata_decoder *mdec, - bt_uuid_t uuid) +int ctf_metadata_decoder_get_uuid(struct ctf_metadata_decoder *mdec, bt_uuid_t uuid) { - int ret = 0; + int ret = 0; - BT_ASSERT_DBG(mdec); + BT_ASSERT_DBG(mdec); - if (!mdec->is_uuid_set) { - ret = -1; - goto end; - } + if (!mdec->is_uuid_set) { + ret = -1; + goto end; + } - bt_uuid_copy(uuid, mdec->uuid); + bt_uuid_copy(uuid, mdec->uuid); end: - return ret; + return ret; } -static -enum ctf_metadata_decoder_status find_uuid_in_trace_decl( - struct ctf_metadata_decoder *mdec, struct ctf_node *trace_node, - bt_uuid_t uuid) +static enum ctf_metadata_decoder_status find_uuid_in_trace_decl(struct ctf_metadata_decoder *mdec, + struct ctf_node *trace_node, + bt_uuid_t uuid) { - enum ctf_metadata_decoder_status status = - CTF_METADATA_DECODER_STATUS_OK; - struct ctf_node *entry_node; - struct bt_list_head *decl_list = &trace_node->u.trace.declaration_list; - char *left = NULL; - - bt_list_for_each_entry(entry_node, decl_list, siblings) { - if (entry_node->type == NODE_CTF_EXPRESSION) { - int ret; - - left = ctf_ast_concatenate_unary_strings( - &entry_node->u.ctf_expression.left); - if (!left) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot concatenate unary strings."); - status = CTF_METADATA_DECODER_STATUS_ERROR; - goto end; - } - - if (strcmp(left, "uuid") == 0) { - ret = ctf_ast_get_unary_uuid( - &entry_node->u.ctf_expression.right, - uuid, mdec->config.log_level, - mdec->config.self_comp); - if (ret) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid trace's `uuid` attribute."); - status = CTF_METADATA_DECODER_STATUS_ERROR; - goto end; - } - - goto end; - } - - g_free(left); - left = NULL; - } - } - - status = CTF_METADATA_DECODER_STATUS_NONE; + enum ctf_metadata_decoder_status status = CTF_METADATA_DECODER_STATUS_OK; + struct ctf_node *entry_node; + struct bt_list_head *decl_list = &trace_node->u.trace.declaration_list; + char *left = NULL; + + bt_list_for_each_entry (entry_node, decl_list, siblings) { + if (entry_node->type == NODE_CTF_EXPRESSION) { + int ret; + + left = ctf_ast_concatenate_unary_strings(&entry_node->u.ctf_expression.left); + if (!left) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot concatenate unary strings."); + status = CTF_METADATA_DECODER_STATUS_ERROR; + goto end; + } + + if (strcmp(left, "uuid") == 0) { + ret = ctf_ast_get_unary_uuid(&entry_node->u.ctf_expression.right, uuid, + mdec->config.log_level, mdec->config.self_comp); + if (ret) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid trace's `uuid` attribute."); + status = CTF_METADATA_DECODER_STATUS_ERROR; + goto end; + } + + goto end; + } + + g_free(left); + left = NULL; + } + } + + status = CTF_METADATA_DECODER_STATUS_NONE; end: - g_free(left); - return status; + g_free(left); + return status; } BT_HIDDEN -enum ctf_metadata_decoder_status ctf_metadata_decoder_get_trace_class_uuid( - struct ctf_metadata_decoder *mdec, bt_uuid_t uuid) +enum ctf_metadata_decoder_status +ctf_metadata_decoder_get_trace_class_uuid(struct ctf_metadata_decoder *mdec, bt_uuid_t uuid) { - enum ctf_metadata_decoder_status status = - CTF_METADATA_DECODER_STATUS_INCOMPLETE; - struct ctf_node *root_node = &mdec->scanner->ast->root; - struct ctf_node *trace_node; - - if (!root_node) { - status = CTF_METADATA_DECODER_STATUS_INCOMPLETE; - goto end; - } - - trace_node = - bt_list_entry(root_node->u.root.trace.next, - struct ctf_node, siblings); - if (!trace_node) { - status = CTF_METADATA_DECODER_STATUS_INCOMPLETE; - goto end; - } - - status = find_uuid_in_trace_decl(mdec, trace_node, uuid); + enum ctf_metadata_decoder_status status = CTF_METADATA_DECODER_STATUS_INCOMPLETE; + struct ctf_node *root_node = &mdec->scanner->ast->root; + struct ctf_node *trace_node; + + if (!root_node) { + status = CTF_METADATA_DECODER_STATUS_INCOMPLETE; + goto end; + } + + trace_node = bt_list_entry(root_node->u.root.trace.next, struct ctf_node, siblings); + if (!trace_node) { + status = CTF_METADATA_DECODER_STATUS_INCOMPLETE; + goto end; + } + + status = find_uuid_in_trace_decl(mdec, trace_node, uuid); end: - return status; + return status; } diff --git a/src/plugins/ctf/common/metadata/decoder.hpp b/src/plugins/ctf/common/metadata/decoder.hpp index d8803d84..f96fc9de 100644 --- a/src/plugins/ctf/common/metadata/decoder.hpp +++ b/src/plugins/ctf/common/metadata/decoder.hpp @@ -22,40 +22,42 @@ struct ctf_trace_class; struct ctf_metadata_decoder; /* CTF metadata decoder status */ -enum ctf_metadata_decoder_status { - CTF_METADATA_DECODER_STATUS_OK = 0, - CTF_METADATA_DECODER_STATUS_NONE = 1, - CTF_METADATA_DECODER_STATUS_ERROR = -1, - CTF_METADATA_DECODER_STATUS_INCOMPLETE = -2, - CTF_METADATA_DECODER_STATUS_INVAL_VERSION = -3, - CTF_METADATA_DECODER_STATUS_IR_VISITOR_ERROR = -4, +enum ctf_metadata_decoder_status +{ + CTF_METADATA_DECODER_STATUS_OK = 0, + CTF_METADATA_DECODER_STATUS_NONE = 1, + CTF_METADATA_DECODER_STATUS_ERROR = -1, + CTF_METADATA_DECODER_STATUS_INCOMPLETE = -2, + CTF_METADATA_DECODER_STATUS_INVAL_VERSION = -3, + CTF_METADATA_DECODER_STATUS_IR_VISITOR_ERROR = -4, }; /* Decoding configuration */ -struct ctf_metadata_decoder_config { - /* Active log level to use */ - bt_logging_level log_level; - - /* - * Component or component class to use for logging (exactly one of - * them must be non-`NULL`); weak - */ - bt_self_component *self_comp; - bt_self_component_class *self_comp_class; - - /* Additional clock class offset to apply */ - int64_t clock_class_offset_s; - int64_t clock_class_offset_ns; - bool force_clock_class_origin_unix_epoch; - - /* True to create trace class objects */ - bool create_trace_class; - - /* - * True to keep the plain text when content is appended with - * ctf_metadata_decoder_append_content(). - */ - bool keep_plain_text; +struct ctf_metadata_decoder_config +{ + /* Active log level to use */ + bt_logging_level log_level; + + /* + * Component or component class to use for logging (exactly one of + * them must be non-`NULL`); weak + */ + bt_self_component *self_comp; + bt_self_component_class *self_comp_class; + + /* Additional clock class offset to apply */ + int64_t clock_class_offset_s; + int64_t clock_class_offset_ns; + bool force_clock_class_origin_unix_epoch; + + /* True to create trace class objects */ + bool create_trace_class; + + /* + * True to keep the plain text when content is appended with + * ctf_metadata_decoder_append_content(). + */ + bool keep_plain_text; }; /* @@ -64,16 +66,15 @@ struct ctf_metadata_decoder_config { * Returns `NULL` on error. */ BT_HIDDEN -struct ctf_metadata_decoder *ctf_metadata_decoder_create( - const struct ctf_metadata_decoder_config *config); +struct ctf_metadata_decoder * +ctf_metadata_decoder_create(const struct ctf_metadata_decoder_config *config); /* * Destroys a CTF metadata decoder that you created with * ctf_metadata_decoder_create(). */ BT_HIDDEN -void ctf_metadata_decoder_destroy( - struct ctf_metadata_decoder *metadata_decoder); +void ctf_metadata_decoder_destroy(struct ctf_metadata_decoder *metadata_decoder); /* * Appends content to the metadata decoder. @@ -97,8 +98,8 @@ void ctf_metadata_decoder_destroy( * `CTF_METADATA_DECODER_STATUS_OK`. */ BT_HIDDEN -enum ctf_metadata_decoder_status ctf_metadata_decoder_append_content( - struct ctf_metadata_decoder *metadata_decoder, FILE *fp); +enum ctf_metadata_decoder_status +ctf_metadata_decoder_append_content(struct ctf_metadata_decoder *metadata_decoder, FILE *fp); /* * Returns the trace IR trace class of this metadata decoder (new @@ -108,8 +109,7 @@ enum ctf_metadata_decoder_status ctf_metadata_decoder_append_content( * configured to create trace classes. */ BT_HIDDEN -bt_trace_class *ctf_metadata_decoder_get_ir_trace_class( - struct ctf_metadata_decoder *mdec); +bt_trace_class *ctf_metadata_decoder_get_ir_trace_class(struct ctf_metadata_decoder *mdec); /* * Returns the CTF IR trace class of this metadata decoder. @@ -118,8 +118,8 @@ bt_trace_class *ctf_metadata_decoder_get_ir_trace_class( * configured to create trace classes. */ BT_HIDDEN -struct ctf_trace_class *ctf_metadata_decoder_borrow_ctf_trace_class( - struct ctf_metadata_decoder *mdec); +struct ctf_trace_class * +ctf_metadata_decoder_borrow_ctf_trace_class(struct ctf_metadata_decoder *mdec); /* * Checks whether or not a given metadata file stream `fp` is @@ -131,9 +131,8 @@ struct ctf_trace_class *ctf_metadata_decoder_borrow_ctf_trace_class( * `self_comp` can be `NULL` if not available. */ BT_HIDDEN -int ctf_metadata_decoder_is_packetized(FILE *fp, bool *is_packetized, - int *byte_order, bt_logging_level log_level, - bt_self_component *self_comp); +int ctf_metadata_decoder_is_packetized(FILE *fp, bool *is_packetized, int *byte_order, + bt_logging_level log_level, bt_self_component *self_comp); /* * Returns the byte order of the decoder's metadata stream as set by the @@ -149,8 +148,7 @@ int ctf_metadata_decoder_get_byte_order(struct ctf_metadata_decoder *mdec); * call to ctf_metadata_decoder_append_content(). */ BT_HIDDEN -int ctf_metadata_decoder_get_uuid( - struct ctf_metadata_decoder *mdec, bt_uuid_t uuid); +int ctf_metadata_decoder_get_uuid(struct ctf_metadata_decoder *mdec, bt_uuid_t uuid); /* * Returns the UUID of the decoder's trace class, if available. @@ -162,8 +160,8 @@ int ctf_metadata_decoder_get_uuid( * * `CTF_METADATA_DECODER_STATUS_INCOMPLETE`: missing metadata content. */ BT_HIDDEN -enum ctf_metadata_decoder_status ctf_metadata_decoder_get_trace_class_uuid( - struct ctf_metadata_decoder *mdec, bt_uuid_t uuid); +enum ctf_metadata_decoder_status +ctf_metadata_decoder_get_trace_class_uuid(struct ctf_metadata_decoder *mdec, bt_uuid_t uuid); /* * Returns the metadata decoder's current metadata text. @@ -171,11 +169,10 @@ enum ctf_metadata_decoder_status ctf_metadata_decoder_get_trace_class_uuid( BT_HIDDEN const char *ctf_metadata_decoder_get_text(struct ctf_metadata_decoder *mdec); -static inline -bool ctf_metadata_decoder_is_packet_version_valid(unsigned int major, - unsigned int minor) +static inline bool ctf_metadata_decoder_is_packet_version_valid(unsigned int major, + unsigned int minor) { - return major == 1 && minor == 8; + return major == 1 && minor == 8; } #endif /* _METADATA_DECODER_H */ diff --git a/src/plugins/ctf/common/metadata/logging.hpp b/src/plugins/ctf/common/metadata/logging.hpp index 4488b620..a62f1e1e 100644 --- a/src/plugins/ctf/common/metadata/logging.hpp +++ b/src/plugins/ctf/common/metadata/logging.hpp @@ -20,43 +20,43 @@ BT_LOG_LEVEL_EXTERN_SYMBOL(ctf_plugin_metadata_log_level); * To be used by functions without a context structure to pass all the * logging configuration at once. */ -struct meta_log_config { - bt_logging_level log_level; +struct meta_log_config +{ + bt_logging_level log_level; - /* Weak, exactly one of these must be set */ - bt_self_component *self_comp; - bt_self_component_class *self_comp_class; + /* Weak, exactly one of these must be set */ + bt_self_component *self_comp; + bt_self_component_class *self_comp_class; }; -#define _BT_LOGT_LINENO(_lineno, _msg, args...) \ - BT_LOGT("At line %u in metadata stream: " _msg, _lineno, ## args) +#define _BT_LOGT_LINENO(_lineno, _msg, args...) \ + BT_LOGT("At line %u in metadata stream: " _msg, _lineno, ##args) -#define _BT_LOGW_LINENO(_lineno, _msg, args...) \ - BT_LOGW("At line %u in metadata stream: " _msg, _lineno, ## args) +#define _BT_LOGW_LINENO(_lineno, _msg, args...) \ + BT_LOGW("At line %u in metadata stream: " _msg, _lineno, ##args) -#define _BT_LOGE_APPEND_CAUSE_LINENO(_lineno, _msg, args...) \ - do { \ - BT_LOGE("At line %u in metadata stream: " _msg, _lineno, ## args); \ - (void) BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_UNKNOWN( \ - "CTF metadata parser", "At line %u in metadata stream: " _msg, _lineno, ## args); \ - } while (0) +#define _BT_LOGE_APPEND_CAUSE_LINENO(_lineno, _msg, args...) \ + do { \ + BT_LOGE("At line %u in metadata stream: " _msg, _lineno, ##args); \ + (void) BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_UNKNOWN( \ + "CTF metadata parser", "At line %u in metadata stream: " _msg, _lineno, ##args); \ + } while (0) -#define _BT_COMP_LOGT_LINENO(_lineno, _msg, args...) \ - BT_COMP_LOGT("At line %u in metadata stream: " _msg, _lineno, ## args) +#define _BT_COMP_LOGT_LINENO(_lineno, _msg, args...) \ + BT_COMP_LOGT("At line %u in metadata stream: " _msg, _lineno, ##args) -#define _BT_COMP_LOGW_LINENO(_lineno, _msg, args...) \ - BT_COMP_LOGW("At line %u in metadata stream: " _msg, _lineno, ## args) +#define _BT_COMP_LOGW_LINENO(_lineno, _msg, args...) \ + BT_COMP_LOGW("At line %u in metadata stream: " _msg, _lineno, ##args) -#define _BT_COMP_LOGE_LINENO(_lineno, _msg, args...) \ - BT_COMP_LOGE("At line %u in metadata stream: " _msg, _lineno, ## args) +#define _BT_COMP_LOGE_LINENO(_lineno, _msg, args...) \ + BT_COMP_LOGE("At line %u in metadata stream: " _msg, _lineno, ##args) -#define _BT_COMP_LOGE_APPEND_CAUSE_LINENO(_lineno, _msg, args...) \ - BT_COMP_LOGE_APPEND_CAUSE(BT_COMP_LOG_SELF_COMP, "At line %u in metadata stream: " _msg, _lineno, ## args) +#define _BT_COMP_LOGE_APPEND_CAUSE_LINENO(_lineno, _msg, args...) \ + BT_COMP_LOGE_APPEND_CAUSE(BT_COMP_LOG_SELF_COMP, "At line %u in metadata stream: " _msg, \ + _lineno, ##args) -#define _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(_msg, args...) \ - BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( \ - BT_COMP_LOG_SELF_COMP, \ - BT_COMP_LOG_SELF_COMP_CLASS, \ - _msg, ## args) +#define _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(_msg, args...) \ + BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(BT_COMP_LOG_SELF_COMP, BT_COMP_LOG_SELF_COMP_CLASS, \ + _msg, ##args) #endif /* CTF_METADATA_LOGGING_H */ diff --git a/src/plugins/ctf/common/metadata/objstack.cpp b/src/plugins/ctf/common/metadata/objstack.cpp index 0be8dbf7..4828de9a 100644 --- a/src/plugins/ctf/common/metadata/objstack.cpp +++ b/src/plugins/ctf/common/metadata/objstack.cpp @@ -7,7 +7,7 @@ */ #define BT_LOG_OUTPUT_LEVEL ctf_plugin_metadata_log_level -#define BT_LOG_TAG "PLUGIN/CTF/META/OBJSTACK" +#define BT_LOG_TAG "PLUGIN/CTF/META/OBJSTACK" #include "logging.hpp" #include "objstack.hpp" @@ -17,113 +17,110 @@ #include "common/macros.h" #include "common/align.h" -#define OBJSTACK_ALIGN 8 /* Object stack alignment */ -#define OBJSTACK_INIT_LEN 128 -#define OBJSTACK_POISON 0xcc +#define OBJSTACK_ALIGN 8 /* Object stack alignment */ +#define OBJSTACK_INIT_LEN 128 +#define OBJSTACK_POISON 0xcc -struct objstack { - struct bt_list_head head; /* list of struct objstack_node */ +struct objstack +{ + struct bt_list_head head; /* list of struct objstack_node */ }; -struct objstack_node { - struct bt_list_head node; - size_t len; - size_t used_len; - char __attribute__ ((aligned (OBJSTACK_ALIGN))) data[]; +struct objstack_node +{ + struct bt_list_head node; + size_t len; + size_t used_len; + char __attribute__((aligned(OBJSTACK_ALIGN))) data[]; }; BT_HIDDEN struct objstack *objstack_create(void) { - struct objstack *objstack; - struct objstack_node *node; - - objstack = (struct objstack *) calloc(1, sizeof(*objstack)); - if (!objstack) { - BT_LOGE_STR("Failed to allocate one object stack."); - return NULL; - } - node = (objstack_node *) calloc(sizeof(struct objstack_node) + OBJSTACK_INIT_LEN, - sizeof(char)); - if (!node) { - BT_LOGE_STR("Failed to allocate one object stack node."); - free(objstack); - return NULL; - } - BT_INIT_LIST_HEAD(&objstack->head); - bt_list_add_tail(&node->node, &objstack->head); - node->len = OBJSTACK_INIT_LEN; - return objstack; + struct objstack *objstack; + struct objstack_node *node; + + objstack = (struct objstack *) calloc(1, sizeof(*objstack)); + if (!objstack) { + BT_LOGE_STR("Failed to allocate one object stack."); + return NULL; + } + node = (objstack_node *) calloc(sizeof(struct objstack_node) + OBJSTACK_INIT_LEN, sizeof(char)); + if (!node) { + BT_LOGE_STR("Failed to allocate one object stack node."); + free(objstack); + return NULL; + } + BT_INIT_LIST_HEAD(&objstack->head); + bt_list_add_tail(&node->node, &objstack->head); + node->len = OBJSTACK_INIT_LEN; + return objstack; } -static -void objstack_node_free(struct objstack_node *node) +static void objstack_node_free(struct objstack_node *node) { - size_t offset, len; - char *p; - - if (!node) - return; - p = (char *) node; - len = sizeof(*node) + node->len; - for (offset = 0; offset < len; offset++) - p[offset] = OBJSTACK_POISON; - free(node); + size_t offset, len; + char *p; + + if (!node) + return; + p = (char *) node; + len = sizeof(*node) + node->len; + for (offset = 0; offset < len; offset++) + p[offset] = OBJSTACK_POISON; + free(node); } BT_HIDDEN void objstack_destroy(struct objstack *objstack) { - struct objstack_node *node, *p; - - if (!objstack) - return; - bt_list_for_each_entry_safe(node, p, &objstack->head, node) { - bt_list_del(&node->node); - objstack_node_free(node); - } - free(objstack); + struct objstack_node *node, *p; + + if (!objstack) + return; + bt_list_for_each_entry_safe (node, p, &objstack->head, node) { + bt_list_del(&node->node); + objstack_node_free(node); + } + free(objstack); } -static -struct objstack_node *objstack_append_node(struct objstack *objstack) +static struct objstack_node *objstack_append_node(struct objstack *objstack) { - struct objstack_node *last_node, *new_node; - - /* Get last node */ - last_node = bt_list_entry(objstack->head.prev, - struct objstack_node, node); - - /* Allocate new node with double of size of last node */ - new_node = (objstack_node *) calloc(sizeof(struct objstack_node) + (last_node->len << 1), - sizeof(char)); - if (!new_node) { - BT_LOGE_STR("Failed to allocate one object stack node."); - return NULL; - } - bt_list_add_tail(&new_node->node, &objstack->head); - new_node->len = last_node->len << 1; - return new_node; + struct objstack_node *last_node, *new_node; + + /* Get last node */ + last_node = bt_list_entry(objstack->head.prev, struct objstack_node, node); + + /* Allocate new node with double of size of last node */ + new_node = (objstack_node *) calloc(sizeof(struct objstack_node) + (last_node->len << 1), + sizeof(char)); + if (!new_node) { + BT_LOGE_STR("Failed to allocate one object stack node."); + return NULL; + } + bt_list_add_tail(&new_node->node, &objstack->head); + new_node->len = last_node->len << 1; + return new_node; } BT_HIDDEN void *objstack_alloc(struct objstack *objstack, size_t len) { - struct objstack_node *last_node; - void *p; - - len = BT_ALIGN(len, OBJSTACK_ALIGN); - - /* Get last node */ - last_node = bt_list_entry(objstack->head.prev, - struct objstack_node, node); - while (last_node->len - last_node->used_len < len) { - last_node = objstack_append_node(objstack); - if (!last_node) { - return NULL; - } - } - p = &last_node->data[last_node->used_len]; - last_node->used_len += len; - return p; + struct objstack_node *last_node; + void *p; + + len = BT_ALIGN(len, OBJSTACK_ALIGN); + + /* Get last node */ + last_node = bt_list_entry(objstack->head.prev, struct objstack_node, node); + while (last_node->len - last_node->used_len < len) { + last_node = objstack_append_node(objstack); + if (!last_node) { + return NULL; + } + } + p = &last_node->data[last_node->used_len]; + last_node->used_len += len; + return p; } diff --git a/src/plugins/ctf/common/metadata/parser-wrap.hpp b/src/plugins/ctf/common/metadata/parser-wrap.hpp index 6300b250..d43d391d 100644 --- a/src/plugins/ctf/common/metadata/parser-wrap.hpp +++ b/src/plugins/ctf/common/metadata/parser-wrap.hpp @@ -15,10 +15,10 @@ #include "logging/log.h" #if BT_LOG_ENABLED_TRACE -# define YYDEBUG 1 -# define YYFPRINTF(_stream, _fmt, args...) BT_LOGT(_fmt, ## args) +# define YYDEBUG 1 +# define YYFPRINTF(_stream, _fmt, args...) BT_LOGT(_fmt, ##args) #else -# define YYDEBUG 0 +# define YYDEBUG 0 #endif #define ALLOW_INCLUDE_PARSER_H diff --git a/src/plugins/ctf/common/metadata/scanner-symbols.hpp b/src/plugins/ctf/common/metadata/scanner-symbols.hpp index 8b2ee455..1f6f144d 100644 --- a/src/plugins/ctf/common/metadata/scanner-symbols.hpp +++ b/src/plugins/ctf/common/metadata/scanner-symbols.hpp @@ -7,34 +7,34 @@ #ifndef _CTF_SCANNER_SYMBOLS #define _CTF_SCANNER_SYMBOLS -#define yy_create_buffer bt_yy_create_buffer -#define yy_delete_buffer bt_yy_delete_buffer -#define yy_flush_buffer bt_yy_flush_buffer -#define yy_scan_buffer bt_yy_scan_buffer -#define yy_scan_bytes bt_yy_scan_bytes -#define yy_scan_string bt_yy_scan_string +#define yy_create_buffer bt_yy_create_buffer +#define yy_delete_buffer bt_yy_delete_buffer +#define yy_flush_buffer bt_yy_flush_buffer +#define yy_scan_buffer bt_yy_scan_buffer +#define yy_scan_bytes bt_yy_scan_bytes +#define yy_scan_string bt_yy_scan_string #define yy_switch_to_buffer bt_yy_switch_to_buffer -#define yyalloc bt_yyalloc -#define yyfree bt_yyfree -#define yyget_column bt_yyget_column -#define yyget_debug bt_yyget_debug -#define yyget_extra bt_yyget_extra -#define yyget_in bt_yyget_in -#define yyget_leng bt_yyget_leng -#define yyget_lineno bt_yyget_lineno -#define yyget_lval bt_yyget_lval -#define yyget_out bt_yyget_out -#define yyget_text bt_yyget_text -#define yylex_init bt_yylex_init -#define yypop_buffer_state bt_yypop_buffer_state +#define yyalloc bt_yyalloc +#define yyfree bt_yyfree +#define yyget_column bt_yyget_column +#define yyget_debug bt_yyget_debug +#define yyget_extra bt_yyget_extra +#define yyget_in bt_yyget_in +#define yyget_leng bt_yyget_leng +#define yyget_lineno bt_yyget_lineno +#define yyget_lval bt_yyget_lval +#define yyget_out bt_yyget_out +#define yyget_text bt_yyget_text +#define yylex_init bt_yylex_init +#define yypop_buffer_state bt_yypop_buffer_state #define yypush_buffer_state bt_yypush_buffer_state -#define yyrealloc bt_yyrealloc -#define yyset_column bt_yyset_column -#define yyset_debug bt_yyset_debug -#define yyset_extra bt_yyset_extra -#define yyset_in bt_yyset_in -#define yyset_lineno bt_yyset_lineno -#define yyset_lval bt_yyset_lval -#define yyset_out bt_yyset_out +#define yyrealloc bt_yyrealloc +#define yyset_column bt_yyset_column +#define yyset_debug bt_yyset_debug +#define yyset_extra bt_yyset_extra +#define yyset_in bt_yyset_in +#define yyset_lineno bt_yyset_lineno +#define yyset_lval bt_yyset_lval +#define yyset_out bt_yyset_out #endif /* _CTF_SCANNER_SYMBOLS */ diff --git a/src/plugins/ctf/common/metadata/scanner.hpp b/src/plugins/ctf/common/metadata/scanner.hpp index d1ab1d90..d924ec53 100644 --- a/src/plugins/ctf/common/metadata/scanner.hpp +++ b/src/plugins/ctf/common/metadata/scanner.hpp @@ -12,22 +12,24 @@ #include "ast.hpp" #ifndef YY_TYPEDEF_YY_SCANNER_T -#define YY_TYPEDEF_YY_SCANNER_T -typedef void* yyscan_t; +# define YY_TYPEDEF_YY_SCANNER_T +typedef void *yyscan_t; #endif struct ctf_scanner_scope; -struct ctf_scanner_scope { - struct ctf_scanner_scope *parent; - GHashTable *classes; +struct ctf_scanner_scope +{ + struct ctf_scanner_scope *parent; + GHashTable *classes; }; -struct ctf_scanner { - yyscan_t scanner; - struct ctf_ast *ast; - struct ctf_scanner_scope root_scope; - struct ctf_scanner_scope *cs; - struct objstack *objstack; +struct ctf_scanner +{ + yyscan_t scanner; + struct ctf_ast *ast; + struct ctf_scanner_scope root_scope; + struct ctf_scanner_scope *cs; + struct objstack *objstack; }; BT_HIDDEN @@ -39,10 +41,9 @@ void ctf_scanner_free(struct ctf_scanner *scanner); BT_HIDDEN int ctf_scanner_append_ast(struct ctf_scanner *scanner, FILE *input); -static inline -struct ctf_ast *ctf_scanner_get_ast(struct ctf_scanner *scanner) +static inline struct ctf_ast *ctf_scanner_get_ast(struct ctf_scanner *scanner) { - return scanner->ast; + return scanner->ast; } BT_HIDDEN diff --git a/src/plugins/ctf/common/metadata/visitor-generate-ir.cpp b/src/plugins/ctf/common/metadata/visitor-generate-ir.cpp index 970b838c..50d8d441 100644 --- a/src/plugins/ctf/common/metadata/visitor-generate-ir.cpp +++ b/src/plugins/ctf/common/metadata/visitor-generate-ir.cpp @@ -7,10 +7,10 @@ * Common Trace Format metadata visitor (generates CTF IR objects). */ -#define BT_COMP_LOG_SELF_COMP (ctx->log_cfg.self_comp) +#define BT_COMP_LOG_SELF_COMP (ctx->log_cfg.self_comp) #define BT_COMP_LOG_SELF_COMP_CLASS (ctx->log_cfg.self_comp_class) -#define BT_LOG_OUTPUT_LEVEL (ctx->log_cfg.log_level) -#define BT_LOG_TAG "PLUGIN/CTF/META/IR-VISITOR" +#define BT_LOG_OUTPUT_LEVEL (ctx->log_cfg.log_level) +#define BT_LOG_TAG "PLUGIN/CTF/META/IR-VISITOR" #include "logging/comp-logging.h" #include @@ -36,168 +36,173 @@ #include "ctf-meta-visitors.hpp" /* Bit value (left shift) */ -#define _BV(_val) (1 << (_val)) +#define _BV(_val) (1 << (_val)) /* Bit is set in a set of bits */ -#define _IS_SET(_set, _mask) (*(_set) & (_mask)) +#define _IS_SET(_set, _mask) (*(_set) & (_mask)) /* Set bit in a set of bits */ -#define _SET(_set, _mask) (*(_set) |= (_mask)) +#define _SET(_set, _mask) (*(_set) |= (_mask)) /* Try to push scope, or go to the `error` label */ -#define _TRY_PUSH_SCOPE_OR_GOTO_ERROR() \ - do { \ - ret = ctx_push_scope(ctx); \ - if (ret) { \ - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot push scope."); \ - goto error; \ - } \ - } while (0) +#define _TRY_PUSH_SCOPE_OR_GOTO_ERROR() \ + do { \ + ret = ctx_push_scope(ctx); \ + if (ret) { \ + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot push scope."); \ + goto error; \ + } \ + } while (0) /* Bits for verifying existing attributes in various declarations */ -enum { - _CLOCK_NAME_SET = _BV(0), - _CLOCK_UUID_SET = _BV(1), - _CLOCK_FREQ_SET = _BV(2), - _CLOCK_PRECISION_SET = _BV(3), - _CLOCK_OFFSET_S_SET = _BV(4), - _CLOCK_OFFSET_SET = _BV(5), - _CLOCK_ABSOLUTE_SET = _BV(6), - _CLOCK_DESCRIPTION_SET = _BV(7), +enum +{ + _CLOCK_NAME_SET = _BV(0), + _CLOCK_UUID_SET = _BV(1), + _CLOCK_FREQ_SET = _BV(2), + _CLOCK_PRECISION_SET = _BV(3), + _CLOCK_OFFSET_S_SET = _BV(4), + _CLOCK_OFFSET_SET = _BV(5), + _CLOCK_ABSOLUTE_SET = _BV(6), + _CLOCK_DESCRIPTION_SET = _BV(7), }; -enum { - _INTEGER_ALIGN_SET = _BV(0), - _INTEGER_SIZE_SET = _BV(1), - _INTEGER_BASE_SET = _BV(2), - _INTEGER_ENCODING_SET = _BV(3), - _INTEGER_BYTE_ORDER_SET = _BV(4), - _INTEGER_SIGNED_SET = _BV(5), - _INTEGER_MAP_SET = _BV(6), +enum +{ + _INTEGER_ALIGN_SET = _BV(0), + _INTEGER_SIZE_SET = _BV(1), + _INTEGER_BASE_SET = _BV(2), + _INTEGER_ENCODING_SET = _BV(3), + _INTEGER_BYTE_ORDER_SET = _BV(4), + _INTEGER_SIGNED_SET = _BV(5), + _INTEGER_MAP_SET = _BV(6), }; -enum { - _FLOAT_ALIGN_SET = _BV(0), - _FLOAT_MANT_DIG_SET = _BV(1), - _FLOAT_EXP_DIG_SET = _BV(2), - _FLOAT_BYTE_ORDER_SET = _BV(3), +enum +{ + _FLOAT_ALIGN_SET = _BV(0), + _FLOAT_MANT_DIG_SET = _BV(1), + _FLOAT_EXP_DIG_SET = _BV(2), + _FLOAT_BYTE_ORDER_SET = _BV(3), }; -enum { - _STRING_ENCODING_SET = _BV(0), +enum +{ + _STRING_ENCODING_SET = _BV(0), }; -enum { - _TRACE_MINOR_SET = _BV(0), - _TRACE_MAJOR_SET = _BV(1), - _TRACE_BYTE_ORDER_SET = _BV(2), - _TRACE_UUID_SET = _BV(3), - _TRACE_PACKET_HEADER_SET = _BV(4), +enum +{ + _TRACE_MINOR_SET = _BV(0), + _TRACE_MAJOR_SET = _BV(1), + _TRACE_BYTE_ORDER_SET = _BV(2), + _TRACE_UUID_SET = _BV(3), + _TRACE_PACKET_HEADER_SET = _BV(4), }; -enum { - _STREAM_ID_SET = _BV(0), - _STREAM_PACKET_CONTEXT_SET = _BV(1), - _STREAM_EVENT_HEADER_SET = _BV(2), - _STREAM_EVENT_CONTEXT_SET = _BV(3), +enum +{ + _STREAM_ID_SET = _BV(0), + _STREAM_PACKET_CONTEXT_SET = _BV(1), + _STREAM_EVENT_HEADER_SET = _BV(2), + _STREAM_EVENT_CONTEXT_SET = _BV(3), }; -enum { - _EVENT_NAME_SET = _BV(0), - _EVENT_ID_SET = _BV(1), - _EVENT_MODEL_EMF_URI_SET = _BV(2), - _EVENT_STREAM_ID_SET = _BV(3), - _EVENT_LOG_LEVEL_SET = _BV(4), - _EVENT_CONTEXT_SET = _BV(5), - _EVENT_FIELDS_SET = _BV(6), +enum +{ + _EVENT_NAME_SET = _BV(0), + _EVENT_ID_SET = _BV(1), + _EVENT_MODEL_EMF_URI_SET = _BV(2), + _EVENT_STREAM_ID_SET = _BV(3), + _EVENT_LOG_LEVEL_SET = _BV(4), + _EVENT_CONTEXT_SET = _BV(5), + _EVENT_FIELDS_SET = _BV(6), }; -enum loglevel { - LOG_LEVEL_EMERG = 0, - LOG_LEVEL_ALERT = 1, - LOG_LEVEL_CRIT = 2, - LOG_LEVEL_ERR = 3, - LOG_LEVEL_WARNING = 4, - LOG_LEVEL_NOTICE = 5, - LOG_LEVEL_INFO = 6, - LOG_LEVEL_DEBUG_SYSTEM = 7, - LOG_LEVEL_DEBUG_PROGRAM = 8, - LOG_LEVEL_DEBUG_PROCESS = 9, - LOG_LEVEL_DEBUG_MODULE = 10, - LOG_LEVEL_DEBUG_UNIT = 11, - LOG_LEVEL_DEBUG_FUNCTION = 12, - LOG_LEVEL_DEBUG_LINE = 13, - LOG_LEVEL_DEBUG = 14, - _NR_LOGLEVELS = 15, +enum loglevel +{ + LOG_LEVEL_EMERG = 0, + LOG_LEVEL_ALERT = 1, + LOG_LEVEL_CRIT = 2, + LOG_LEVEL_ERR = 3, + LOG_LEVEL_WARNING = 4, + LOG_LEVEL_NOTICE = 5, + LOG_LEVEL_INFO = 6, + LOG_LEVEL_DEBUG_SYSTEM = 7, + LOG_LEVEL_DEBUG_PROGRAM = 8, + LOG_LEVEL_DEBUG_PROCESS = 9, + LOG_LEVEL_DEBUG_MODULE = 10, + LOG_LEVEL_DEBUG_UNIT = 11, + LOG_LEVEL_DEBUG_FUNCTION = 12, + LOG_LEVEL_DEBUG_LINE = 13, + LOG_LEVEL_DEBUG = 14, + _NR_LOGLEVELS = 15, }; /* Prefixes of class aliases */ -#define _PREFIX_ALIAS 'a' -#define _PREFIX_ENUM 'e' -#define _PREFIX_STRUCT 's' -#define _PREFIX_VARIANT 'v' +#define _PREFIX_ALIAS 'a' +#define _PREFIX_ENUM 'e' +#define _PREFIX_STRUCT 's' +#define _PREFIX_VARIANT 'v' /* First entry in a BT list */ -#define _BT_LIST_FIRST_ENTRY(_ptr, _class, _member) \ - bt_list_entry((_ptr)->next, _class, _member) +#define _BT_LIST_FIRST_ENTRY(_ptr, _class, _member) bt_list_entry((_ptr)->next, _class, _member) -#define _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(_node, _attr, _entity) \ - _BT_COMP_LOGE_APPEND_CAUSE_LINENO((_node)->lineno, \ - "Duplicate attribute in %s: attr-name=\"%s\"", \ - _entity, _attr) +#define _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(_node, _attr, _entity) \ + _BT_COMP_LOGE_APPEND_CAUSE_LINENO( \ + (_node)->lineno, "Duplicate attribute in %s: attr-name=\"%s\"", _entity, _attr) -#define _BT_COMP_LOGE_NODE(_node, _msg, args...) \ - _BT_COMP_LOGE_LINENO((_node)->lineno, _msg, ## args) +#define _BT_COMP_LOGE_NODE(_node, _msg, args...) _BT_COMP_LOGE_LINENO((_node)->lineno, _msg, ##args) -#define _BT_COMP_LOGE_APPEND_CAUSE_NODE(_node, _msg, args...) \ - _BT_COMP_LOGE_APPEND_CAUSE_LINENO((_node)->lineno, _msg, ## args) +#define _BT_COMP_LOGE_APPEND_CAUSE_NODE(_node, _msg, args...) \ + _BT_COMP_LOGE_APPEND_CAUSE_LINENO((_node)->lineno, _msg, ##args) -#define _BT_COMP_LOGW_NODE(_node, _msg, args...) \ - _BT_COMP_LOGW_LINENO((_node)->lineno, _msg, ## args) +#define _BT_COMP_LOGW_NODE(_node, _msg, args...) _BT_COMP_LOGW_LINENO((_node)->lineno, _msg, ##args) -#define _BT_COMP_LOGT_NODE(_node, _msg, args...) \ - _BT_COMP_LOGT_LINENO((_node)->lineno, _msg, ## args) +#define _BT_COMP_LOGT_NODE(_node, _msg, args...) _BT_COMP_LOGT_LINENO((_node)->lineno, _msg, ##args) /* * Declaration scope of a visitor context. This represents a TSDL * lexical scope, so that aliases and named structures, variants, * and enumerations may be registered and looked up hierarchically. */ -struct ctx_decl_scope { - /* - * Alias name to field class. - * - * GQuark -> struct ctf_field_class * (owned by this) - */ - GHashTable *decl_map; - - /* Parent scope; NULL if this is the root declaration scope */ - struct ctx_decl_scope *parent_scope; +struct ctx_decl_scope +{ + /* + * Alias name to field class. + * + * GQuark -> struct ctf_field_class * (owned by this) + */ + GHashTable *decl_map; + + /* Parent scope; NULL if this is the root declaration scope */ + struct ctx_decl_scope *parent_scope; }; /* * Visitor context (private). */ -struct ctf_visitor_generate_ir { - struct meta_log_config log_cfg; +struct ctf_visitor_generate_ir +{ + struct meta_log_config log_cfg; - /* Trace IR trace class being filled (owned by this) */ - bt_trace_class *trace_class; + /* Trace IR trace class being filled (owned by this) */ + bt_trace_class *trace_class; - /* CTF meta trace being filled (owned by this) */ - struct ctf_trace_class *ctf_tc; + /* CTF meta trace being filled (owned by this) */ + struct ctf_trace_class *ctf_tc; - /* Current declaration scope (top of the stack) (owned by this) */ - struct ctx_decl_scope *current_scope; + /* Current declaration scope (top of the stack) (owned by this) */ + struct ctx_decl_scope *current_scope; - /* True if trace declaration is visited */ - bool is_trace_visited; + /* True if trace declaration is visited */ + bool is_trace_visited; - /* True if this is an LTTng trace */ - bool is_lttng; + /* True if this is an LTTng trace */ + bool is_lttng; - /* Config passed by the user */ - struct ctf_metadata_decoder_config decoder_config; + /* Config passed by the user */ + struct ctf_metadata_decoder_config decoder_config; }; /* @@ -211,24 +216,23 @@ struct ctf_visitor_generate_ir; * @param par_scope Parent scope (NULL if creating a root scope) * @returns New declaration scope, or NULL on error */ -static -struct ctx_decl_scope *ctx_decl_scope_create(struct ctf_visitor_generate_ir *ctx, - struct ctx_decl_scope *par_scope) +static struct ctx_decl_scope *ctx_decl_scope_create(struct ctf_visitor_generate_ir *ctx, + struct ctx_decl_scope *par_scope) { - struct ctx_decl_scope *scope; + struct ctx_decl_scope *scope; - scope = g_new(struct ctx_decl_scope, 1); - if (!scope) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Failed to allocate one declaration scope."); - goto end; - } + scope = g_new(struct ctx_decl_scope, 1); + if (!scope) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Failed to allocate one declaration scope."); + goto end; + } - scope->decl_map = g_hash_table_new_full(g_direct_hash, g_direct_equal, - NULL, (GDestroyNotify) ctf_field_class_destroy); - scope->parent_scope = par_scope; + scope->decl_map = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, + (GDestroyNotify) ctf_field_class_destroy); + scope->parent_scope = par_scope; end: - return scope; + return scope; } /** @@ -238,18 +242,17 @@ end: * * @param scope Scope to destroy */ -static -void ctx_decl_scope_destroy(struct ctx_decl_scope *scope) +static void ctx_decl_scope_destroy(struct ctx_decl_scope *scope) { - if (!scope) { - goto end; - } + if (!scope) { + goto end; + } - g_hash_table_destroy(scope->decl_map); - g_free(scope); + g_hash_table_destroy(scope->decl_map); + g_free(scope); end: - return; + return; } /** @@ -259,27 +262,26 @@ end: * @param name Name * @returns Associated GQuark, or 0 on error */ -static -GQuark get_prefixed_named_quark(struct ctf_visitor_generate_ir *ctx, char prefix, - const char *name) +static GQuark get_prefixed_named_quark(struct ctf_visitor_generate_ir *ctx, char prefix, + const char *name) { - GQuark qname = 0; + GQuark qname = 0; - BT_ASSERT(name); + BT_ASSERT(name); - /* Prefix character + original string + '\0' */ - char *prname = g_new(char, strlen(name) + 2); - if (!prname) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Failed to allocate a string."); - goto end; - } + /* Prefix character + original string + '\0' */ + char *prname = g_new(char, strlen(name) + 2); + if (!prname) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Failed to allocate a string."); + goto end; + } - sprintf(prname, "%c%s", prefix, name); - qname = g_quark_from_string(prname); - g_free(prname); + sprintf(prname, "%c%s", prefix, name); + qname = g_quark_from_string(prname); + g_free(prname); end: - return qname; + return qname; } /** @@ -293,46 +295,46 @@ end: * @returns Declaration (owned by caller if \p copy is true), * or NULL if not found */ -static -struct ctf_field_class *ctx_decl_scope_lookup_prefix_alias( - struct ctf_visitor_generate_ir *ctx, struct ctx_decl_scope *scope, char prefix, - const char *name, int levels, bool copy) +static struct ctf_field_class * +ctx_decl_scope_lookup_prefix_alias(struct ctf_visitor_generate_ir *ctx, + struct ctx_decl_scope *scope, char prefix, const char *name, + int levels, bool copy) { - GQuark qname = 0; - int cur_levels = 0; - struct ctf_field_class *decl = NULL; - struct ctx_decl_scope *cur_scope = scope; - - BT_ASSERT(scope); - BT_ASSERT(name); - qname = get_prefixed_named_quark(ctx, prefix, name); - if (!qname) { - goto end; - } - - if (levels < 0) { - levels = INT_MAX; - } - - while (cur_scope && cur_levels < levels) { - decl = (ctf_field_class *) g_hash_table_lookup(cur_scope->decl_map, - (gconstpointer) GUINT_TO_POINTER(qname)); - if (decl) { - /* Caller's reference */ - if (copy) { - decl = ctf_field_class_copy(decl); - BT_ASSERT(decl); - } - - goto end; - } - - cur_scope = cur_scope->parent_scope; - cur_levels++; - } + GQuark qname = 0; + int cur_levels = 0; + struct ctf_field_class *decl = NULL; + struct ctx_decl_scope *cur_scope = scope; + + BT_ASSERT(scope); + BT_ASSERT(name); + qname = get_prefixed_named_quark(ctx, prefix, name); + if (!qname) { + goto end; + } + + if (levels < 0) { + levels = INT_MAX; + } + + while (cur_scope && cur_levels < levels) { + decl = (ctf_field_class *) g_hash_table_lookup(cur_scope->decl_map, + (gconstpointer) GUINT_TO_POINTER(qname)); + if (decl) { + /* Caller's reference */ + if (copy) { + decl = ctf_field_class_copy(decl); + BT_ASSERT(decl); + } + + goto end; + } + + cur_scope = cur_scope->parent_scope; + cur_levels++; + } end: - return decl; + return decl; } /** @@ -345,13 +347,11 @@ end: * @returns Declaration (owned by caller if \p copy is true), * or NULL if not found */ -static -struct ctf_field_class *ctx_decl_scope_lookup_alias(struct ctf_visitor_generate_ir *ctx, - struct ctx_decl_scope *scope, const char *name, int levels, - bool copy) +static struct ctf_field_class *ctx_decl_scope_lookup_alias(struct ctf_visitor_generate_ir *ctx, + struct ctx_decl_scope *scope, + const char *name, int levels, bool copy) { - return ctx_decl_scope_lookup_prefix_alias(ctx, scope, _PREFIX_ALIAS, - name, levels, copy); + return ctx_decl_scope_lookup_prefix_alias(ctx, scope, _PREFIX_ALIAS, name, levels, copy); } /** @@ -364,13 +364,13 @@ struct ctf_field_class *ctx_decl_scope_lookup_alias(struct ctf_visitor_generate_ * @returns Declaration (owned by caller if \p copy is true), * or NULL if not found */ -static -struct ctf_field_class_enum *ctx_decl_scope_lookup_enum(struct ctf_visitor_generate_ir *ctx, - struct ctx_decl_scope *scope, const char *name, int levels, - bool copy) +static struct ctf_field_class_enum *ctx_decl_scope_lookup_enum(struct ctf_visitor_generate_ir *ctx, + struct ctx_decl_scope *scope, + const char *name, int levels, + bool copy) { - return ctf_field_class_as_enum(ctx_decl_scope_lookup_prefix_alias(ctx, scope, - _PREFIX_ENUM, name, levels, copy)); + return ctf_field_class_as_enum( + ctx_decl_scope_lookup_prefix_alias(ctx, scope, _PREFIX_ENUM, name, levels, copy)); } /** @@ -383,13 +383,12 @@ struct ctf_field_class_enum *ctx_decl_scope_lookup_enum(struct ctf_visitor_gener * @returns Declaration (owned by caller if \p copy is true), * or NULL if not found */ -static -struct ctf_field_class_struct *ctx_decl_scope_lookup_struct(struct ctf_visitor_generate_ir *ctx, - struct ctx_decl_scope *scope, const char *name, int levels, - bool copy) +static struct ctf_field_class_struct * +ctx_decl_scope_lookup_struct(struct ctf_visitor_generate_ir *ctx, struct ctx_decl_scope *scope, + const char *name, int levels, bool copy) { - return ctf_field_class_as_struct(ctx_decl_scope_lookup_prefix_alias(ctx, scope, - _PREFIX_STRUCT, name, levels, copy)); + return ctf_field_class_as_struct( + ctx_decl_scope_lookup_prefix_alias(ctx, scope, _PREFIX_STRUCT, name, levels, copy)); } /** @@ -402,13 +401,12 @@ struct ctf_field_class_struct *ctx_decl_scope_lookup_struct(struct ctf_visitor_g * @returns Declaration (owned by caller if \p copy is true), * or NULL if not found */ -static -struct ctf_field_class_variant *ctx_decl_scope_lookup_variant(struct ctf_visitor_generate_ir *ctx, - struct ctx_decl_scope *scope, const char *name, int levels, - bool copy) +static struct ctf_field_class_variant * +ctx_decl_scope_lookup_variant(struct ctf_visitor_generate_ir *ctx, struct ctx_decl_scope *scope, + const char *name, int levels, bool copy) { - return ctf_field_class_as_variant(ctx_decl_scope_lookup_prefix_alias(ctx, scope, - _PREFIX_VARIANT, name, levels, copy)); + return ctf_field_class_as_variant( + ctx_decl_scope_lookup_prefix_alias(ctx, scope, _PREFIX_VARIANT, name, levels, copy)); } /** @@ -420,36 +418,34 @@ struct ctf_field_class_variant *ctx_decl_scope_lookup_variant(struct ctf_visitor * @param decl Field class to register (copied) * @returns 0 if registration went okay, negative value otherwise */ -static -int ctx_decl_scope_register_prefix_alias(struct ctf_visitor_generate_ir *ctx, - struct ctx_decl_scope *scope, char prefix, const char *name, - struct ctf_field_class *decl) +static int ctx_decl_scope_register_prefix_alias(struct ctf_visitor_generate_ir *ctx, + struct ctx_decl_scope *scope, char prefix, + const char *name, struct ctf_field_class *decl) { - int ret = 0; - GQuark qname = 0; - - BT_ASSERT(scope); - BT_ASSERT(name); - BT_ASSERT(decl); - qname = get_prefixed_named_quark(ctx, prefix, name); - if (!qname) { - ret = -ENOMEM; - goto end; - } - - /* Make sure alias does not exist in local scope */ - if (ctx_decl_scope_lookup_prefix_alias(ctx, scope, prefix, name, 1, - false)) { - ret = -EEXIST; - goto end; - } - - decl = ctf_field_class_copy(decl); - BT_ASSERT(decl); - g_hash_table_insert(scope->decl_map, GUINT_TO_POINTER(qname), decl); + int ret = 0; + GQuark qname = 0; + + BT_ASSERT(scope); + BT_ASSERT(name); + BT_ASSERT(decl); + qname = get_prefixed_named_quark(ctx, prefix, name); + if (!qname) { + ret = -ENOMEM; + goto end; + } + + /* Make sure alias does not exist in local scope */ + if (ctx_decl_scope_lookup_prefix_alias(ctx, scope, prefix, name, 1, false)) { + ret = -EEXIST; + goto end; + } + + decl = ctf_field_class_copy(decl); + BT_ASSERT(decl); + g_hash_table_insert(scope->decl_map, GUINT_TO_POINTER(qname), decl); end: - return ret; + return ret; } /** @@ -460,12 +456,11 @@ end: * @param decl Field class to register (copied) * @returns 0 if registration went okay, negative value otherwise */ -static -int ctx_decl_scope_register_alias(struct ctf_visitor_generate_ir *ctx, - struct ctx_decl_scope *scope, const char *name, struct ctf_field_class *decl) +static int ctx_decl_scope_register_alias(struct ctf_visitor_generate_ir *ctx, + struct ctx_decl_scope *scope, const char *name, + struct ctf_field_class *decl) { - return ctx_decl_scope_register_prefix_alias(ctx, scope, _PREFIX_ALIAS, - name, decl); + return ctx_decl_scope_register_prefix_alias(ctx, scope, _PREFIX_ALIAS, name, decl); } /** @@ -476,13 +471,12 @@ int ctx_decl_scope_register_alias(struct ctf_visitor_generate_ir *ctx, * @param decl Enumeration field class to register (copied) * @returns 0 if registration went okay, negative value otherwise */ -static -int ctx_decl_scope_register_enum(struct ctf_visitor_generate_ir *ctx, - struct ctx_decl_scope *scope, const char *name, - struct ctf_field_class_enum *decl) +static int ctx_decl_scope_register_enum(struct ctf_visitor_generate_ir *ctx, + struct ctx_decl_scope *scope, const char *name, + struct ctf_field_class_enum *decl) { - return ctx_decl_scope_register_prefix_alias(ctx, scope, _PREFIX_ENUM, - name, &decl->base.base.base); + return ctx_decl_scope_register_prefix_alias(ctx, scope, _PREFIX_ENUM, name, + &decl->base.base.base); } /** @@ -493,13 +487,11 @@ int ctx_decl_scope_register_enum(struct ctf_visitor_generate_ir *ctx, * @param decl Structure field class to register (copied) * @returns 0 if registration went okay, negative value otherwise */ -static -int ctx_decl_scope_register_struct(struct ctf_visitor_generate_ir *ctx, - struct ctx_decl_scope *scope, const char *name, - struct ctf_field_class_struct *decl) +static int ctx_decl_scope_register_struct(struct ctf_visitor_generate_ir *ctx, + struct ctx_decl_scope *scope, const char *name, + struct ctf_field_class_struct *decl) { - return ctx_decl_scope_register_prefix_alias(ctx, scope, _PREFIX_STRUCT, - name, &decl->base); + return ctx_decl_scope_register_prefix_alias(ctx, scope, _PREFIX_STRUCT, name, &decl->base); } /** @@ -510,13 +502,11 @@ int ctx_decl_scope_register_struct(struct ctf_visitor_generate_ir *ctx, * @param decl Variant field class to register * @returns 0 if registration went okay, negative value otherwise */ -static -int ctx_decl_scope_register_variant(struct ctf_visitor_generate_ir *ctx, - struct ctx_decl_scope *scope, const char *name, - struct ctf_field_class_variant *decl) +static int ctx_decl_scope_register_variant(struct ctf_visitor_generate_ir *ctx, + struct ctx_decl_scope *scope, const char *name, + struct ctf_field_class_variant *decl) { - return ctx_decl_scope_register_prefix_alias(ctx, scope, _PREFIX_VARIANT, - name, &decl->base); + return ctx_decl_scope_register_prefix_alias(ctx, scope, _PREFIX_VARIANT, name, &decl->base); } /** @@ -524,37 +514,36 @@ int ctx_decl_scope_register_variant(struct ctf_visitor_generate_ir *ctx, * * @param ctx Visitor context to destroy */ -static -void ctx_destroy(struct ctf_visitor_generate_ir *ctx) +static void ctx_destroy(struct ctf_visitor_generate_ir *ctx) { - struct ctx_decl_scope *scope; + struct ctx_decl_scope *scope; - if (!ctx) { - goto end; - } + if (!ctx) { + goto end; + } - scope = ctx->current_scope; + scope = ctx->current_scope; - /* - * Destroy all scopes, from current one to the root scope. - */ - while (scope) { - struct ctx_decl_scope *parent_scope = scope->parent_scope; + /* + * Destroy all scopes, from current one to the root scope. + */ + while (scope) { + struct ctx_decl_scope *parent_scope = scope->parent_scope; - ctx_decl_scope_destroy(scope); - scope = parent_scope; - } + ctx_decl_scope_destroy(scope); + scope = parent_scope; + } - bt_trace_class_put_ref(ctx->trace_class); + bt_trace_class_put_ref(ctx->trace_class); - if (ctx->ctf_tc) { - ctf_trace_class_destroy(ctx->ctf_tc); - } + if (ctx->ctf_tc) { + ctf_trace_class_destroy(ctx->ctf_tc); + } - g_free(ctx); + g_free(ctx); end: - return; + return; } /** @@ -563,57 +552,54 @@ end: * @param trace Associated trace * @returns New visitor context, or NULL on error */ -static -struct ctf_visitor_generate_ir *ctx_create( - const struct ctf_metadata_decoder_config *decoder_config) +static struct ctf_visitor_generate_ir * +ctx_create(const struct ctf_metadata_decoder_config *decoder_config) { - struct ctf_visitor_generate_ir *ctx = NULL; - - BT_ASSERT(decoder_config); - - ctx = g_new0(struct ctf_visitor_generate_ir, 1); - if (!ctx) { - BT_COMP_LOG_CUR_LVL(BT_LOG_ERROR, decoder_config->log_level, - decoder_config->self_comp, - "Failed to allocate one visitor context."); - goto error; - } - - ctx->log_cfg.log_level = decoder_config->log_level; - ctx->log_cfg.self_comp = decoder_config->self_comp; - ctx->log_cfg.self_comp_class = decoder_config->self_comp_class; - - if (decoder_config->self_comp) { - ctx->trace_class = bt_trace_class_create( - decoder_config->self_comp); - if (!ctx->trace_class) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot create empty trace class."); - goto error; - } - } - - ctx->ctf_tc = ctf_trace_class_create(); - if (!ctx->ctf_tc) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot create CTF trace class."); - goto error; - } - - /* Root declaration scope */ - ctx->current_scope = ctx_decl_scope_create(ctx, NULL); - if (!ctx->current_scope) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot create declaration scope."); - goto error; - } - - ctx->decoder_config = *decoder_config; - goto end; + struct ctf_visitor_generate_ir *ctx = NULL; + + BT_ASSERT(decoder_config); + + ctx = g_new0(struct ctf_visitor_generate_ir, 1); + if (!ctx) { + BT_COMP_LOG_CUR_LVL(BT_LOG_ERROR, decoder_config->log_level, decoder_config->self_comp, + "Failed to allocate one visitor context."); + goto error; + } + + ctx->log_cfg.log_level = decoder_config->log_level; + ctx->log_cfg.self_comp = decoder_config->self_comp; + ctx->log_cfg.self_comp_class = decoder_config->self_comp_class; + + if (decoder_config->self_comp) { + ctx->trace_class = bt_trace_class_create(decoder_config->self_comp); + if (!ctx->trace_class) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot create empty trace class."); + goto error; + } + } + + ctx->ctf_tc = ctf_trace_class_create(); + if (!ctx->ctf_tc) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot create CTF trace class."); + goto error; + } + + /* Root declaration scope */ + ctx->current_scope = ctx_decl_scope_create(ctx, NULL); + if (!ctx->current_scope) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot create declaration scope."); + goto error; + } + + ctx->decoder_config = *decoder_config; + goto end; error: - ctx_destroy(ctx); - ctx = NULL; + ctx_destroy(ctx); + ctx = NULL; end: - return ctx; + return ctx; } /** @@ -623,4361 +609,4177 @@ end: * @param ctx Visitor context * @returns 0 on success, or a negative value on error */ -static -int ctx_push_scope(struct ctf_visitor_generate_ir *ctx) +static int ctx_push_scope(struct ctf_visitor_generate_ir *ctx) { - int ret = 0; - struct ctx_decl_scope *new_scope; + int ret = 0; + struct ctx_decl_scope *new_scope; - BT_ASSERT(ctx); - new_scope = ctx_decl_scope_create(ctx, ctx->current_scope); - if (!new_scope) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot create declaration scope."); - ret = -ENOMEM; - goto end; - } + BT_ASSERT(ctx); + new_scope = ctx_decl_scope_create(ctx, ctx->current_scope); + if (!new_scope) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot create declaration scope."); + ret = -ENOMEM; + goto end; + } - ctx->current_scope = new_scope; + ctx->current_scope = new_scope; end: - return ret; + return ret; } -static -void ctx_pop_scope(struct ctf_visitor_generate_ir *ctx) +static void ctx_pop_scope(struct ctf_visitor_generate_ir *ctx) { - struct ctx_decl_scope *parent_scope = NULL; + struct ctx_decl_scope *parent_scope = NULL; - BT_ASSERT(ctx); + BT_ASSERT(ctx); - if (!ctx->current_scope) { - goto end; - } + if (!ctx->current_scope) { + goto end; + } - parent_scope = ctx->current_scope->parent_scope; - ctx_decl_scope_destroy(ctx->current_scope); - ctx->current_scope = parent_scope; + parent_scope = ctx->current_scope->parent_scope; + ctx_decl_scope_destroy(ctx->current_scope); + ctx->current_scope = parent_scope; end: - return; + return; } -static -int visit_field_class_specifier_list(struct ctf_visitor_generate_ir *ctx, - struct ctf_node *ts_list, struct ctf_field_class **decl); +static int visit_field_class_specifier_list(struct ctf_visitor_generate_ir *ctx, + struct ctf_node *ts_list, + struct ctf_field_class **decl); -static -int is_unary_string(struct bt_list_head *head) +static int is_unary_string(struct bt_list_head *head) { - int ret = TRUE; - struct ctf_node *node; + int ret = TRUE; + struct ctf_node *node; - bt_list_for_each_entry(node, head, siblings) { - if (node->type != NODE_UNARY_EXPRESSION) { - ret = FALSE; - } + bt_list_for_each_entry (node, head, siblings) { + if (node->type != NODE_UNARY_EXPRESSION) { + ret = FALSE; + } - if (node->u.unary_expression.type != UNARY_STRING) { - ret = FALSE; - } - } + if (node->u.unary_expression.type != UNARY_STRING) { + ret = FALSE; + } + } - return ret; + return ret; } -static -const char *get_map_clock_name_value(struct bt_list_head *head) +static const char *get_map_clock_name_value(struct bt_list_head *head) { - int i = 0; - struct ctf_node *node; - const char *name = NULL; - - bt_list_for_each_entry(node, head, siblings) { - char *src_string; - int uexpr_type = node->u.unary_expression.type; - int uexpr_link = node->u.unary_expression.link; - int cond = node->type != NODE_UNARY_EXPRESSION || - uexpr_type != UNARY_STRING || - !((uexpr_link != UNARY_LINK_UNKNOWN) ^ (i == 0)); - if (cond) { - goto error; - } - - /* Needs to be chained with . */ - switch (node->u.unary_expression.link) { - case UNARY_DOTLINK: - break; - case UNARY_ARROWLINK: - case UNARY_DOTDOTDOT: - goto error; - default: - break; - } - - src_string = node->u.unary_expression.u.string; - - switch (i) { - case 0: - if (strcmp("clock", src_string)) { - goto error; - } - break; - case 1: - name = src_string; - break; - case 2: - if (strcmp("value", src_string)) { - goto error; - } - break; - default: - /* Extra identifier, unknown */ - goto error; - } - - i++; - } - - return name; + int i = 0; + struct ctf_node *node; + const char *name = NULL; + + bt_list_for_each_entry (node, head, siblings) { + char *src_string; + int uexpr_type = node->u.unary_expression.type; + int uexpr_link = node->u.unary_expression.link; + int cond = node->type != NODE_UNARY_EXPRESSION || uexpr_type != UNARY_STRING || + !((uexpr_link != UNARY_LINK_UNKNOWN) ^ (i == 0)); + if (cond) { + goto error; + } + + /* Needs to be chained with . */ + switch (node->u.unary_expression.link) { + case UNARY_DOTLINK: + break; + case UNARY_ARROWLINK: + case UNARY_DOTDOTDOT: + goto error; + default: + break; + } + + src_string = node->u.unary_expression.u.string; + + switch (i) { + case 0: + if (strcmp("clock", src_string)) { + goto error; + } + break; + case 1: + name = src_string; + break; + case 2: + if (strcmp("value", src_string)) { + goto error; + } + break; + default: + /* Extra identifier, unknown */ + goto error; + } + + i++; + } + + return name; error: - return NULL; + return NULL; } -static -int is_unary_unsigned(struct bt_list_head *head) +static int is_unary_unsigned(struct bt_list_head *head) { - int ret = TRUE; - struct ctf_node *node; + int ret = TRUE; + struct ctf_node *node; - bt_list_for_each_entry(node, head, siblings) { - if (node->type != NODE_UNARY_EXPRESSION) { - ret = FALSE; - } + bt_list_for_each_entry (node, head, siblings) { + if (node->type != NODE_UNARY_EXPRESSION) { + ret = FALSE; + } - if (node->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) { - ret = FALSE; - } - } + if (node->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) { + ret = FALSE; + } + } - return ret; + return ret; } -static -int get_unary_unsigned(struct ctf_visitor_generate_ir *ctx, struct bt_list_head *head, - uint64_t *value) +static int get_unary_unsigned(struct ctf_visitor_generate_ir *ctx, struct bt_list_head *head, + uint64_t *value) { - int i = 0; - int ret = 0; - struct ctf_node *node; - - *value = 0; - - if (bt_list_empty(head)) { - ret = -1; - goto end; - } - - bt_list_for_each_entry(node, head, siblings) { - int uexpr_type = node->u.unary_expression.type; - int uexpr_link = node->u.unary_expression.link; - int cond = node->type != NODE_UNARY_EXPRESSION || - uexpr_type != UNARY_UNSIGNED_CONSTANT || - uexpr_link != UNARY_LINK_UNKNOWN || i != 0; - if (cond) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Invalid constant unsigned integer."); - ret = -EINVAL; - goto end; - } - - *value = node->u.unary_expression.u.unsigned_constant; - i++; - } + int i = 0; + int ret = 0; + struct ctf_node *node; + + *value = 0; + + if (bt_list_empty(head)) { + ret = -1; + goto end; + } + + bt_list_for_each_entry (node, head, siblings) { + int uexpr_type = node->u.unary_expression.type; + int uexpr_link = node->u.unary_expression.link; + int cond = node->type != NODE_UNARY_EXPRESSION || uexpr_type != UNARY_UNSIGNED_CONSTANT || + uexpr_link != UNARY_LINK_UNKNOWN || i != 0; + if (cond) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Invalid constant unsigned integer."); + ret = -EINVAL; + goto end; + } + + *value = node->u.unary_expression.u.unsigned_constant; + i++; + } end: - return ret; + return ret; } -static -int is_unary_signed(struct bt_list_head *head) +static int is_unary_signed(struct bt_list_head *head) { - int ret = TRUE; - struct ctf_node *node; + int ret = TRUE; + struct ctf_node *node; - bt_list_for_each_entry(node, head, siblings) { - if (node->type != NODE_UNARY_EXPRESSION) { - ret = FALSE; - } + bt_list_for_each_entry (node, head, siblings) { + if (node->type != NODE_UNARY_EXPRESSION) { + ret = FALSE; + } - if (node->u.unary_expression.type != UNARY_SIGNED_CONSTANT) { - ret = FALSE; - } - } + if (node->u.unary_expression.type != UNARY_SIGNED_CONSTANT) { + ret = FALSE; + } + } - return ret; + return ret; } -static -int get_unary_signed(struct bt_list_head *head, int64_t *value) +static int get_unary_signed(struct bt_list_head *head, int64_t *value) { - int i = 0; - int ret = 0; - struct ctf_node *node; - - bt_list_for_each_entry(node, head, siblings) { - int uexpr_type = node->u.unary_expression.type; - int uexpr_link = node->u.unary_expression.link; - int cond = node->type != NODE_UNARY_EXPRESSION || - (uexpr_type != UNARY_UNSIGNED_CONSTANT && - uexpr_type != UNARY_SIGNED_CONSTANT) || - uexpr_link != UNARY_LINK_UNKNOWN || i != 0; - if (cond) { - ret = -EINVAL; - goto end; - } - - switch (uexpr_type) { - case UNARY_UNSIGNED_CONSTANT: - *value = (int64_t) - node->u.unary_expression.u.unsigned_constant; - break; - case UNARY_SIGNED_CONSTANT: - *value = node->u.unary_expression.u.signed_constant; - break; - default: - ret = -EINVAL; - goto end; - } - - i++; - } + int i = 0; + int ret = 0; + struct ctf_node *node; + + bt_list_for_each_entry (node, head, siblings) { + int uexpr_type = node->u.unary_expression.type; + int uexpr_link = node->u.unary_expression.link; + int cond = node->type != NODE_UNARY_EXPRESSION || + (uexpr_type != UNARY_UNSIGNED_CONSTANT && uexpr_type != UNARY_SIGNED_CONSTANT) || + uexpr_link != UNARY_LINK_UNKNOWN || i != 0; + if (cond) { + ret = -EINVAL; + goto end; + } + + switch (uexpr_type) { + case UNARY_UNSIGNED_CONSTANT: + *value = (int64_t) node->u.unary_expression.u.unsigned_constant; + break; + case UNARY_SIGNED_CONSTANT: + *value = node->u.unary_expression.u.signed_constant; + break; + default: + ret = -EINVAL; + goto end; + } + + i++; + } end: - return ret; + return ret; } -static -int get_unary_uuid(struct ctf_visitor_generate_ir *ctx, struct bt_list_head *head, - bt_uuid_t uuid) +static int get_unary_uuid(struct ctf_visitor_generate_ir *ctx, struct bt_list_head *head, + bt_uuid_t uuid) { - return ctf_ast_get_unary_uuid(head, uuid, ctx->log_cfg.log_level, - ctx->log_cfg.self_comp); + return ctf_ast_get_unary_uuid(head, uuid, ctx->log_cfg.log_level, ctx->log_cfg.self_comp); } -static -int get_boolean(struct ctf_visitor_generate_ir *ctx, struct ctf_node *unary_expr) +static int get_boolean(struct ctf_visitor_generate_ir *ctx, struct ctf_node *unary_expr) { - int ret = 0; - - if (unary_expr->type != NODE_UNARY_EXPRESSION) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(unary_expr, - "Expecting unary expression: node-type=%d", - unary_expr->type); - ret = -EINVAL; - goto end; - } - - switch (unary_expr->u.unary_expression.type) { - case UNARY_UNSIGNED_CONSTANT: - ret = (unary_expr->u.unary_expression.u.unsigned_constant != 0); - break; - case UNARY_SIGNED_CONSTANT: - ret = (unary_expr->u.unary_expression.u.signed_constant != 0); - break; - case UNARY_STRING: - { - const char *str = unary_expr->u.unary_expression.u.string; - - if (strcmp(str, "true") == 0 || strcmp(str, "TRUE") == 0) { - ret = TRUE; - } else if (strcmp(str, "false") == 0 || strcmp(str, "FALSE") == 0) { - ret = FALSE; - } else { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(unary_expr, - "Unexpected boolean value: value=\"%s\"", str); - ret = -EINVAL; - goto end; - } - break; - } - default: - _BT_COMP_LOGE_APPEND_CAUSE_NODE(unary_expr, - "Unexpected unary expression type: node-type=%d", - unary_expr->u.unary_expression.type); - ret = -EINVAL; - goto end; - } + int ret = 0; + + if (unary_expr->type != NODE_UNARY_EXPRESSION) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(unary_expr, "Expecting unary expression: node-type=%d", + unary_expr->type); + ret = -EINVAL; + goto end; + } + + switch (unary_expr->u.unary_expression.type) { + case UNARY_UNSIGNED_CONSTANT: + ret = (unary_expr->u.unary_expression.u.unsigned_constant != 0); + break; + case UNARY_SIGNED_CONSTANT: + ret = (unary_expr->u.unary_expression.u.signed_constant != 0); + break; + case UNARY_STRING: + { + const char *str = unary_expr->u.unary_expression.u.string; + + if (strcmp(str, "true") == 0 || strcmp(str, "TRUE") == 0) { + ret = TRUE; + } else if (strcmp(str, "false") == 0 || strcmp(str, "FALSE") == 0) { + ret = FALSE; + } else { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(unary_expr, "Unexpected boolean value: value=\"%s\"", + str); + ret = -EINVAL; + goto end; + } + break; + } + default: + _BT_COMP_LOGE_APPEND_CAUSE_NODE(unary_expr, + "Unexpected unary expression type: node-type=%d", + unary_expr->u.unary_expression.type); + ret = -EINVAL; + goto end; + } end: - return ret; + return ret; } -static -enum ctf_byte_order byte_order_from_unary_expr(struct ctf_visitor_generate_ir *ctx, - struct ctf_node *unary_expr) +static enum ctf_byte_order byte_order_from_unary_expr(struct ctf_visitor_generate_ir *ctx, + struct ctf_node *unary_expr) { - const char *str; - enum ctf_byte_order bo = CTF_BYTE_ORDER_UNKNOWN; - - if (unary_expr->u.unary_expression.type != UNARY_STRING) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(unary_expr, - "\"byte_order\" attribute: expecting `be`, `le`, `network`, or `native`."); - goto end; - } - - str = unary_expr->u.unary_expression.u.string; - - if (strcmp(str, "be") == 0 || strcmp(str, "network") == 0) { - bo = CTF_BYTE_ORDER_BIG; - } else if (strcmp(str, "le") == 0) { - bo = CTF_BYTE_ORDER_LITTLE; - } else if (strcmp(str, "native") == 0) { - bo = CTF_BYTE_ORDER_DEFAULT; - } else { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(unary_expr, - "Unexpected \"byte_order\" attribute value: " - "expecting `be`, `le`, `network`, or `native`: value=\"%s\"", - str); - goto end; - } + const char *str; + enum ctf_byte_order bo = CTF_BYTE_ORDER_UNKNOWN; + + if (unary_expr->u.unary_expression.type != UNARY_STRING) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + unary_expr, "\"byte_order\" attribute: expecting `be`, `le`, `network`, or `native`."); + goto end; + } + + str = unary_expr->u.unary_expression.u.string; + + if (strcmp(str, "be") == 0 || strcmp(str, "network") == 0) { + bo = CTF_BYTE_ORDER_BIG; + } else if (strcmp(str, "le") == 0) { + bo = CTF_BYTE_ORDER_LITTLE; + } else if (strcmp(str, "native") == 0) { + bo = CTF_BYTE_ORDER_DEFAULT; + } else { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + unary_expr, + "Unexpected \"byte_order\" attribute value: " + "expecting `be`, `le`, `network`, or `native`: value=\"%s\"", + str); + goto end; + } end: - return bo; + return bo; } -static -enum ctf_byte_order get_real_byte_order(struct ctf_visitor_generate_ir *ctx, - struct ctf_node *uexpr) +static enum ctf_byte_order get_real_byte_order(struct ctf_visitor_generate_ir *ctx, + struct ctf_node *uexpr) { - enum ctf_byte_order bo = byte_order_from_unary_expr(ctx, uexpr); + enum ctf_byte_order bo = byte_order_from_unary_expr(ctx, uexpr); - if (bo == CTF_BYTE_ORDER_DEFAULT) { - bo = ctx->ctf_tc->default_byte_order; - } + if (bo == CTF_BYTE_ORDER_DEFAULT) { + bo = ctx->ctf_tc->default_byte_order; + } - return bo; + return bo; } -static -int is_align_valid(uint64_t align) +static int is_align_valid(uint64_t align) { - return (align != 0) && !(align & (align - UINT64_C(1))); + return (align != 0) && !(align & (align - UINT64_C(1))); } -static -int get_class_specifier_name(struct ctf_visitor_generate_ir *ctx, - struct ctf_node *cls_specifier, GString *str) +static int get_class_specifier_name(struct ctf_visitor_generate_ir *ctx, + struct ctf_node *cls_specifier, GString *str) { - int ret = 0; - - if (cls_specifier->type != NODE_TYPE_SPECIFIER) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(cls_specifier, - "Unexpected node type: node-type=%d", - cls_specifier->type); - ret = -EINVAL; - goto end; - } - - switch (cls_specifier->u.field_class_specifier.type) { - case TYPESPEC_VOID: - g_string_append(str, "void"); - break; - case TYPESPEC_CHAR: - g_string_append(str, "char"); - break; - case TYPESPEC_SHORT: - g_string_append(str, "short"); - break; - case TYPESPEC_INT: - g_string_append(str, "int"); - break; - case TYPESPEC_LONG: - g_string_append(str, "long"); - break; - case TYPESPEC_FLOAT: - g_string_append(str, "float"); - break; - case TYPESPEC_DOUBLE: - g_string_append(str, "double"); - break; - case TYPESPEC_SIGNED: - g_string_append(str, "signed"); - break; - case TYPESPEC_UNSIGNED: - g_string_append(str, "unsigned"); - break; - case TYPESPEC_BOOL: - g_string_append(str, "bool"); - break; - case TYPESPEC_COMPLEX: - g_string_append(str, "_Complex"); - break; - case TYPESPEC_IMAGINARY: - g_string_append(str, "_Imaginary"); - break; - case TYPESPEC_CONST: - g_string_append(str, "const"); - break; - case TYPESPEC_ID_TYPE: - if (cls_specifier->u.field_class_specifier.id_type) { - g_string_append(str, - cls_specifier->u.field_class_specifier.id_type); - } - break; - case TYPESPEC_STRUCT: - { - struct ctf_node *node = cls_specifier->u.field_class_specifier.node; - - if (!node->u._struct.name) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Unexpected empty structure field class name."); - ret = -EINVAL; - goto end; - } - - g_string_append(str, "struct "); - g_string_append(str, node->u._struct.name); - break; - } - case TYPESPEC_VARIANT: - { - struct ctf_node *node = cls_specifier->u.field_class_specifier.node; - - if (!node->u.variant.name) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Unexpected empty variant field class name."); - ret = -EINVAL; - goto end; - } - - g_string_append(str, "variant "); - g_string_append(str, node->u.variant.name); - break; - } - case TYPESPEC_ENUM: - { - struct ctf_node *node = cls_specifier->u.field_class_specifier.node; - - if (!node->u._enum.enum_id) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, - "Unexpected empty enumeration field class (`enum`) name."); - ret = -EINVAL; - goto end; - } - - g_string_append(str, "enum "); - g_string_append(str, node->u._enum.enum_id); - break; - } - case TYPESPEC_FLOATING_POINT: - case TYPESPEC_INTEGER: - case TYPESPEC_STRING: - default: - _BT_COMP_LOGE_APPEND_CAUSE_NODE(cls_specifier->u.field_class_specifier.node, - "Unexpected field class specifier type: %d", - cls_specifier->u.field_class_specifier.type); - ret = -EINVAL; - goto end; - } + int ret = 0; + + if (cls_specifier->type != NODE_TYPE_SPECIFIER) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(cls_specifier, "Unexpected node type: node-type=%d", + cls_specifier->type); + ret = -EINVAL; + goto end; + } + + switch (cls_specifier->u.field_class_specifier.type) { + case TYPESPEC_VOID: + g_string_append(str, "void"); + break; + case TYPESPEC_CHAR: + g_string_append(str, "char"); + break; + case TYPESPEC_SHORT: + g_string_append(str, "short"); + break; + case TYPESPEC_INT: + g_string_append(str, "int"); + break; + case TYPESPEC_LONG: + g_string_append(str, "long"); + break; + case TYPESPEC_FLOAT: + g_string_append(str, "float"); + break; + case TYPESPEC_DOUBLE: + g_string_append(str, "double"); + break; + case TYPESPEC_SIGNED: + g_string_append(str, "signed"); + break; + case TYPESPEC_UNSIGNED: + g_string_append(str, "unsigned"); + break; + case TYPESPEC_BOOL: + g_string_append(str, "bool"); + break; + case TYPESPEC_COMPLEX: + g_string_append(str, "_Complex"); + break; + case TYPESPEC_IMAGINARY: + g_string_append(str, "_Imaginary"); + break; + case TYPESPEC_CONST: + g_string_append(str, "const"); + break; + case TYPESPEC_ID_TYPE: + if (cls_specifier->u.field_class_specifier.id_type) { + g_string_append(str, cls_specifier->u.field_class_specifier.id_type); + } + break; + case TYPESPEC_STRUCT: + { + struct ctf_node *node = cls_specifier->u.field_class_specifier.node; + + if (!node->u._struct.name) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Unexpected empty structure field class name."); + ret = -EINVAL; + goto end; + } + + g_string_append(str, "struct "); + g_string_append(str, node->u._struct.name); + break; + } + case TYPESPEC_VARIANT: + { + struct ctf_node *node = cls_specifier->u.field_class_specifier.node; + + if (!node->u.variant.name) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Unexpected empty variant field class name."); + ret = -EINVAL; + goto end; + } + + g_string_append(str, "variant "); + g_string_append(str, node->u.variant.name); + break; + } + case TYPESPEC_ENUM: + { + struct ctf_node *node = cls_specifier->u.field_class_specifier.node; + + if (!node->u._enum.enum_id) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + node, "Unexpected empty enumeration field class (`enum`) name."); + ret = -EINVAL; + goto end; + } + + g_string_append(str, "enum "); + g_string_append(str, node->u._enum.enum_id); + break; + } + case TYPESPEC_FLOATING_POINT: + case TYPESPEC_INTEGER: + case TYPESPEC_STRING: + default: + _BT_COMP_LOGE_APPEND_CAUSE_NODE(cls_specifier->u.field_class_specifier.node, + "Unexpected field class specifier type: %d", + cls_specifier->u.field_class_specifier.type); + ret = -EINVAL; + goto end; + } end: - return ret; + return ret; } -static -int get_class_specifier_list_name(struct ctf_visitor_generate_ir *ctx, - struct ctf_node *cls_specifier_list, GString *str) +static int get_class_specifier_list_name(struct ctf_visitor_generate_ir *ctx, + struct ctf_node *cls_specifier_list, GString *str) { - int ret = 0; - struct ctf_node *iter; - int alias_item_nr = 0; - struct bt_list_head *head = - &cls_specifier_list->u.field_class_specifier_list.head; - - bt_list_for_each_entry(iter, head, siblings) { - if (alias_item_nr != 0) { - g_string_append(str, " "); - } - - alias_item_nr++; - ret = get_class_specifier_name(ctx, iter, str); - if (ret) { - goto end; - } - } + int ret = 0; + struct ctf_node *iter; + int alias_item_nr = 0; + struct bt_list_head *head = &cls_specifier_list->u.field_class_specifier_list.head; + + bt_list_for_each_entry (iter, head, siblings) { + if (alias_item_nr != 0) { + g_string_append(str, " "); + } + + alias_item_nr++; + ret = get_class_specifier_name(ctx, iter, str); + if (ret) { + goto end; + } + } end: - return ret; + return ret; } -static -GQuark create_class_alias_identifier(struct ctf_visitor_generate_ir *ctx, - struct ctf_node *cls_specifier_list, - struct ctf_node *node_field_class_declarator) +static GQuark create_class_alias_identifier(struct ctf_visitor_generate_ir *ctx, + struct ctf_node *cls_specifier_list, + struct ctf_node *node_field_class_declarator) { - int ret; - char *str_c; - GString *str; - GQuark qalias = 0; - struct ctf_node *iter; - struct bt_list_head *pointers = - &node_field_class_declarator->u.field_class_declarator.pointers; - - str = g_string_new(""); - ret = get_class_specifier_list_name(ctx, cls_specifier_list, str); - if (ret) { - g_string_free(str, TRUE); - goto end; - } - - bt_list_for_each_entry(iter, pointers, siblings) { - g_string_append(str, " *"); - - if (iter->u.pointer.const_qualifier) { - g_string_append(str, " const"); - } - } - - str_c = g_string_free(str, FALSE); - qalias = g_quark_from_string(str_c); - g_free(str_c); + int ret; + char *str_c; + GString *str; + GQuark qalias = 0; + struct ctf_node *iter; + struct bt_list_head *pointers = &node_field_class_declarator->u.field_class_declarator.pointers; + + str = g_string_new(""); + ret = get_class_specifier_list_name(ctx, cls_specifier_list, str); + if (ret) { + g_string_free(str, TRUE); + goto end; + } + + bt_list_for_each_entry (iter, pointers, siblings) { + g_string_append(str, " *"); + + if (iter->u.pointer.const_qualifier) { + g_string_append(str, " const"); + } + } + + str_c = g_string_free(str, FALSE); + qalias = g_quark_from_string(str_c); + g_free(str_c); end: - return qalias; + return qalias; } -static -int visit_field_class_declarator(struct ctf_visitor_generate_ir *ctx, - struct ctf_node *cls_specifier_list, - GQuark *field_name, struct ctf_node *node_field_class_declarator, - struct ctf_field_class **field_decl, - struct ctf_field_class *nested_decl) +static int visit_field_class_declarator(struct ctf_visitor_generate_ir *ctx, + struct ctf_node *cls_specifier_list, GQuark *field_name, + struct ctf_node *node_field_class_declarator, + struct ctf_field_class **field_decl, + struct ctf_field_class *nested_decl) { - /* - * During this whole function, nested_decl is always OURS, - * whereas field_decl is an output which we create, but - * belongs to the caller (it is moved). - */ - int ret = 0; - *field_decl = NULL; - - /* Validate field class declarator node */ - if (node_field_class_declarator) { - if (node_field_class_declarator->u.field_class_declarator.type == - TYPEDEC_UNKNOWN) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node_field_class_declarator, - "Unexpected field class declarator type: type=%d", - node_field_class_declarator->u.field_class_declarator.type); - ret = -EINVAL; - goto error; - } - - /* TODO: GCC bitfields not supported yet */ - if (node_field_class_declarator->u.field_class_declarator.bitfield_len != - NULL) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node_field_class_declarator, - "GCC bitfields are not supported as of this version."); - ret = -EPERM; - goto error; - } - } - - /* Find the right nested declaration if not provided */ - if (!nested_decl) { - struct bt_list_head *pointers = - &node_field_class_declarator->u.field_class_declarator.pointers; - - if (node_field_class_declarator && !bt_list_empty(pointers)) { - GQuark qalias; - - /* - * If we have a pointer declarator, it HAS to + /* + * During this whole function, nested_decl is always OURS, + * whereas field_decl is an output which we create, but + * belongs to the caller (it is moved). + */ + int ret = 0; + *field_decl = NULL; + + /* Validate field class declarator node */ + if (node_field_class_declarator) { + if (node_field_class_declarator->u.field_class_declarator.type == TYPEDEC_UNKNOWN) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + node_field_class_declarator, "Unexpected field class declarator type: type=%d", + node_field_class_declarator->u.field_class_declarator.type); + ret = -EINVAL; + goto error; + } + + /* TODO: GCC bitfields not supported yet */ + if (node_field_class_declarator->u.field_class_declarator.bitfield_len != NULL) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(node_field_class_declarator, + "GCC bitfields are not supported as of this version."); + ret = -EPERM; + goto error; + } + } + + /* Find the right nested declaration if not provided */ + if (!nested_decl) { + struct bt_list_head *pointers = + &node_field_class_declarator->u.field_class_declarator.pointers; + + if (node_field_class_declarator && !bt_list_empty(pointers)) { + GQuark qalias; + + /* + * If we have a pointer declarator, it HAS to * be present in the field class aliases (else * fail). - */ - qalias = create_class_alias_identifier(ctx, - cls_specifier_list, node_field_class_declarator); - nested_decl = - ctx_decl_scope_lookup_alias(ctx, - ctx->current_scope, - g_quark_to_string(qalias), -1, true); - if (!nested_decl) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node_field_class_declarator, - "Cannot find class alias: name=\"%s\"", - g_quark_to_string(qalias)); - ret = -EINVAL; - goto error; - } - - if (nested_decl->type == CTF_FIELD_CLASS_TYPE_INT) { - /* Pointer: force integer's base to 16 */ - struct ctf_field_class_int *int_fc = - ctf_field_class_as_int(nested_decl); - - int_fc->disp_base = - BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL; - } - } else { - ret = visit_field_class_specifier_list(ctx, - cls_specifier_list, &nested_decl); - if (ret) { - BT_ASSERT(!nested_decl); - goto error; - } - } - } - - BT_ASSERT(nested_decl); - - if (!node_field_class_declarator) { - *field_decl = nested_decl; - nested_decl = NULL; - goto end; - } - - if (node_field_class_declarator->u.field_class_declarator.type == TYPEDEC_ID) { - if (node_field_class_declarator->u.field_class_declarator.u.id) { - const char *id = - node_field_class_declarator->u.field_class_declarator.u.id; - - *field_name = g_quark_from_string(id); - } else { - *field_name = 0; - } - - *field_decl = nested_decl; - nested_decl = NULL; - goto end; - } else { - struct ctf_node *first; - struct ctf_field_class *decl = NULL; - struct ctf_field_class *outer_field_decl = NULL; - struct bt_list_head *length = - &node_field_class_declarator-> - u.field_class_declarator.u.nested.length; - - /* Create array/sequence, pass nested_decl as child */ - if (bt_list_empty(length)) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node_field_class_declarator, - "Expecting length field reference or value."); - ret = -EINVAL; - goto error; - } - - first = _BT_LIST_FIRST_ENTRY(length, struct ctf_node, siblings); - if (first->type != NODE_UNARY_EXPRESSION) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(first, - "Unexpected node type: node-type=%d", - first->type); - ret = -EINVAL; - goto error; - } - - switch (first->u.unary_expression.type) { - case UNARY_UNSIGNED_CONSTANT: - { - struct ctf_field_class_array *array_decl = NULL; - - array_decl = ctf_field_class_array_create(); - BT_ASSERT(array_decl); - array_decl->length = - first->u.unary_expression.u.unsigned_constant; - array_decl->base.elem_fc = nested_decl; - nested_decl = NULL; - decl = &array_decl->base.base; - break; - } - case UNARY_STRING: - { - /* Lookup unsigned integer definition, create seq. */ - struct ctf_field_class_sequence *seq_decl = NULL; - char *length_name = ctf_ast_concatenate_unary_strings(length); - - if (!length_name) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node_field_class_declarator, - "Cannot concatenate unary strings."); - ret = -EINVAL; - goto error; - } - - if (strncmp(length_name, "env.", 4) == 0) { - /* This is, in fact, an array */ - const char *env_entry_name = &length_name[4]; - struct ctf_trace_class_env_entry *env_entry = - ctf_trace_class_borrow_env_entry_by_name( - ctx->ctf_tc, env_entry_name); - struct ctf_field_class_array *array_decl; - - if (!env_entry) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node_field_class_declarator, - "Cannot find environment entry: " - "name=\"%s\"", env_entry_name); - ret = -EINVAL; - goto error; - } - - if (env_entry->type != CTF_TRACE_CLASS_ENV_ENTRY_TYPE_INT) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node_field_class_declarator, - "Wrong environment entry type " - "(expecting integer): " - "name=\"%s\"", env_entry_name); - ret = -EINVAL; - goto error; - } - - if (env_entry->value.i < 0) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node_field_class_declarator, - "Invalid, negative array length: " - "env-entry-name=\"%s\", " - "value=%" PRId64, - env_entry_name, - env_entry->value.i); - ret = -EINVAL; - goto error; - } - - array_decl = ctf_field_class_array_create(); - BT_ASSERT(array_decl); - array_decl->length = - (uint64_t) env_entry->value.i; - array_decl->base.elem_fc = nested_decl; - nested_decl = NULL; - decl = &array_decl->base.base; - } else { - seq_decl = ctf_field_class_sequence_create(); - BT_ASSERT(seq_decl); - seq_decl->base.elem_fc = nested_decl; - nested_decl = NULL; - g_string_assign(seq_decl->length_ref, - length_name); - decl = &seq_decl->base.base; - } - - g_free(length_name); - break; - } - default: - ret = -EINVAL; - goto error; - } - - BT_ASSERT(!nested_decl); - BT_ASSERT(decl); - BT_ASSERT(!*field_decl); - - /* - * At this point, we found the next nested declaration. - * We currently own this (and lost the ownership of - * nested_decl in the meantime). Pass this next - * nested declaration as the content of the outer - * container, MOVING its ownership. - */ - ret = visit_field_class_declarator(ctx, cls_specifier_list, - field_name, - node_field_class_declarator-> - u.field_class_declarator.u.nested.field_class_declarator, - &outer_field_decl, decl); - decl = NULL; - if (ret) { - BT_ASSERT(!outer_field_decl); - ret = -EINVAL; - goto error; - } - - BT_ASSERT(outer_field_decl); - *field_decl = outer_field_decl; - outer_field_decl = NULL; - } - - BT_ASSERT(*field_decl); - goto end; + */ + qalias = + create_class_alias_identifier(ctx, cls_specifier_list, node_field_class_declarator); + nested_decl = ctx_decl_scope_lookup_alias(ctx, ctx->current_scope, + g_quark_to_string(qalias), -1, true); + if (!nested_decl) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(node_field_class_declarator, + "Cannot find class alias: name=\"%s\"", + g_quark_to_string(qalias)); + ret = -EINVAL; + goto error; + } + + if (nested_decl->type == CTF_FIELD_CLASS_TYPE_INT) { + /* Pointer: force integer's base to 16 */ + struct ctf_field_class_int *int_fc = ctf_field_class_as_int(nested_decl); + + int_fc->disp_base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL; + } + } else { + ret = visit_field_class_specifier_list(ctx, cls_specifier_list, &nested_decl); + if (ret) { + BT_ASSERT(!nested_decl); + goto error; + } + } + } + + BT_ASSERT(nested_decl); + + if (!node_field_class_declarator) { + *field_decl = nested_decl; + nested_decl = NULL; + goto end; + } + + if (node_field_class_declarator->u.field_class_declarator.type == TYPEDEC_ID) { + if (node_field_class_declarator->u.field_class_declarator.u.id) { + const char *id = node_field_class_declarator->u.field_class_declarator.u.id; + + *field_name = g_quark_from_string(id); + } else { + *field_name = 0; + } + + *field_decl = nested_decl; + nested_decl = NULL; + goto end; + } else { + struct ctf_node *first; + struct ctf_field_class *decl = NULL; + struct ctf_field_class *outer_field_decl = NULL; + struct bt_list_head *length = + &node_field_class_declarator->u.field_class_declarator.u.nested.length; + + /* Create array/sequence, pass nested_decl as child */ + if (bt_list_empty(length)) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(node_field_class_declarator, + "Expecting length field reference or value."); + ret = -EINVAL; + goto error; + } + + first = _BT_LIST_FIRST_ENTRY(length, struct ctf_node, siblings); + if (first->type != NODE_UNARY_EXPRESSION) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(first, "Unexpected node type: node-type=%d", + first->type); + ret = -EINVAL; + goto error; + } + + switch (first->u.unary_expression.type) { + case UNARY_UNSIGNED_CONSTANT: + { + struct ctf_field_class_array *array_decl = NULL; + + array_decl = ctf_field_class_array_create(); + BT_ASSERT(array_decl); + array_decl->length = first->u.unary_expression.u.unsigned_constant; + array_decl->base.elem_fc = nested_decl; + nested_decl = NULL; + decl = &array_decl->base.base; + break; + } + case UNARY_STRING: + { + /* Lookup unsigned integer definition, create seq. */ + struct ctf_field_class_sequence *seq_decl = NULL; + char *length_name = ctf_ast_concatenate_unary_strings(length); + + if (!length_name) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(node_field_class_declarator, + "Cannot concatenate unary strings."); + ret = -EINVAL; + goto error; + } + + if (strncmp(length_name, "env.", 4) == 0) { + /* This is, in fact, an array */ + const char *env_entry_name = &length_name[4]; + struct ctf_trace_class_env_entry *env_entry = + ctf_trace_class_borrow_env_entry_by_name(ctx->ctf_tc, env_entry_name); + struct ctf_field_class_array *array_decl; + + if (!env_entry) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(node_field_class_declarator, + "Cannot find environment entry: " + "name=\"%s\"", + env_entry_name); + ret = -EINVAL; + goto error; + } + + if (env_entry->type != CTF_TRACE_CLASS_ENV_ENTRY_TYPE_INT) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(node_field_class_declarator, + "Wrong environment entry type " + "(expecting integer): " + "name=\"%s\"", + env_entry_name); + ret = -EINVAL; + goto error; + } + + if (env_entry->value.i < 0) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(node_field_class_declarator, + "Invalid, negative array length: " + "env-entry-name=\"%s\", " + "value=%" PRId64, + env_entry_name, env_entry->value.i); + ret = -EINVAL; + goto error; + } + + array_decl = ctf_field_class_array_create(); + BT_ASSERT(array_decl); + array_decl->length = (uint64_t) env_entry->value.i; + array_decl->base.elem_fc = nested_decl; + nested_decl = NULL; + decl = &array_decl->base.base; + } else { + seq_decl = ctf_field_class_sequence_create(); + BT_ASSERT(seq_decl); + seq_decl->base.elem_fc = nested_decl; + nested_decl = NULL; + g_string_assign(seq_decl->length_ref, length_name); + decl = &seq_decl->base.base; + } + + g_free(length_name); + break; + } + default: + ret = -EINVAL; + goto error; + } + + BT_ASSERT(!nested_decl); + BT_ASSERT(decl); + BT_ASSERT(!*field_decl); + + /* + * At this point, we found the next nested declaration. + * We currently own this (and lost the ownership of + * nested_decl in the meantime). Pass this next + * nested declaration as the content of the outer + * container, MOVING its ownership. + */ + ret = visit_field_class_declarator( + ctx, cls_specifier_list, field_name, + node_field_class_declarator->u.field_class_declarator.u.nested.field_class_declarator, + &outer_field_decl, decl); + decl = NULL; + if (ret) { + BT_ASSERT(!outer_field_decl); + ret = -EINVAL; + goto error; + } + + BT_ASSERT(outer_field_decl); + *field_decl = outer_field_decl; + outer_field_decl = NULL; + } + + BT_ASSERT(*field_decl); + goto end; error: - ctf_field_class_destroy(*field_decl); - *field_decl = NULL; + ctf_field_class_destroy(*field_decl); + *field_decl = NULL; - if (ret >= 0) { - ret = -1; - } + if (ret >= 0) { + ret = -1; + } end: - ctf_field_class_destroy(nested_decl); - nested_decl = NULL; - return ret; + ctf_field_class_destroy(nested_decl); + nested_decl = NULL; + return ret; } -static -int visit_struct_decl_field(struct ctf_visitor_generate_ir *ctx, - struct ctf_field_class_struct *struct_decl, - struct ctf_node *cls_specifier_list, - struct bt_list_head *field_class_declarators) +static int visit_struct_decl_field(struct ctf_visitor_generate_ir *ctx, + struct ctf_field_class_struct *struct_decl, + struct ctf_node *cls_specifier_list, + struct bt_list_head *field_class_declarators) { - int ret = 0; - struct ctf_node *iter; - struct ctf_field_class *field_decl = NULL; - - bt_list_for_each_entry(iter, field_class_declarators, siblings) { - field_decl = NULL; - GQuark qfield_name; - const char *field_name; - - ret = visit_field_class_declarator(ctx, cls_specifier_list, - &qfield_name, iter, &field_decl, NULL); - if (ret) { - BT_ASSERT(!field_decl); - _BT_COMP_LOGE_APPEND_CAUSE_NODE(cls_specifier_list, - "Cannot visit field class declarator: ret=%d", ret); - goto error; - } - - BT_ASSERT(field_decl); - field_name = g_quark_to_string(qfield_name); - - /* Check if field with same name already exists */ - if (ctf_field_class_struct_borrow_member_by_name( - struct_decl, field_name)) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(cls_specifier_list, - "Duplicate field in structure field class: " - "field-name=\"%s\"", field_name); - ret = -EINVAL; - goto error; - } - - /* Add field to structure */ - ctf_field_class_struct_append_member(struct_decl, - field_name, field_decl); - field_decl = NULL; - } - - return 0; + int ret = 0; + struct ctf_node *iter; + struct ctf_field_class *field_decl = NULL; + + bt_list_for_each_entry (iter, field_class_declarators, siblings) { + field_decl = NULL; + GQuark qfield_name; + const char *field_name; + + ret = visit_field_class_declarator(ctx, cls_specifier_list, &qfield_name, iter, &field_decl, + NULL); + if (ret) { + BT_ASSERT(!field_decl); + _BT_COMP_LOGE_APPEND_CAUSE_NODE(cls_specifier_list, + "Cannot visit field class declarator: ret=%d", ret); + goto error; + } + + BT_ASSERT(field_decl); + field_name = g_quark_to_string(qfield_name); + + /* Check if field with same name already exists */ + if (ctf_field_class_struct_borrow_member_by_name(struct_decl, field_name)) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(cls_specifier_list, + "Duplicate field in structure field class: " + "field-name=\"%s\"", + field_name); + ret = -EINVAL; + goto error; + } + + /* Add field to structure */ + ctf_field_class_struct_append_member(struct_decl, field_name, field_decl); + field_decl = NULL; + } + + return 0; error: - ctf_field_class_destroy(field_decl); - field_decl = NULL; - return ret; + ctf_field_class_destroy(field_decl); + field_decl = NULL; + return ret; } -static -int visit_variant_decl_field(struct ctf_visitor_generate_ir *ctx, - struct ctf_field_class_variant *variant_decl, - struct ctf_node *cls_specifier_list, - struct bt_list_head *field_class_declarators) +static int visit_variant_decl_field(struct ctf_visitor_generate_ir *ctx, + struct ctf_field_class_variant *variant_decl, + struct ctf_node *cls_specifier_list, + struct bt_list_head *field_class_declarators) { - int ret = 0; - struct ctf_node *iter; - struct ctf_field_class *field_decl = NULL; - - bt_list_for_each_entry(iter, field_class_declarators, siblings) { - field_decl = NULL; - GQuark qfield_name; - const char *field_name; - - ret = visit_field_class_declarator(ctx, cls_specifier_list, - &qfield_name, iter, &field_decl, NULL); - if (ret) { - BT_ASSERT(!field_decl); - _BT_COMP_LOGE_APPEND_CAUSE_NODE(cls_specifier_list, - "Cannot visit field class declarator: ret=%d", ret); - goto error; - } - - BT_ASSERT(field_decl); - field_name = g_quark_to_string(qfield_name); - - /* Check if field with same name already exists */ - if (ctf_field_class_variant_borrow_option_by_name( - variant_decl, field_name)) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(cls_specifier_list, - "Duplicate field in variant field class: " - "field-name=\"%s\"", field_name); - ret = -EINVAL; - goto error; - } - - /* Add field to structure */ - ctf_field_class_variant_append_option(variant_decl, - field_name, field_decl); - field_decl = NULL; - } - - return 0; + int ret = 0; + struct ctf_node *iter; + struct ctf_field_class *field_decl = NULL; + + bt_list_for_each_entry (iter, field_class_declarators, siblings) { + field_decl = NULL; + GQuark qfield_name; + const char *field_name; + + ret = visit_field_class_declarator(ctx, cls_specifier_list, &qfield_name, iter, &field_decl, + NULL); + if (ret) { + BT_ASSERT(!field_decl); + _BT_COMP_LOGE_APPEND_CAUSE_NODE(cls_specifier_list, + "Cannot visit field class declarator: ret=%d", ret); + goto error; + } + + BT_ASSERT(field_decl); + field_name = g_quark_to_string(qfield_name); + + /* Check if field with same name already exists */ + if (ctf_field_class_variant_borrow_option_by_name(variant_decl, field_name)) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(cls_specifier_list, + "Duplicate field in variant field class: " + "field-name=\"%s\"", + field_name); + ret = -EINVAL; + goto error; + } + + /* Add field to structure */ + ctf_field_class_variant_append_option(variant_decl, field_name, field_decl); + field_decl = NULL; + } + + return 0; error: - ctf_field_class_destroy(field_decl); - field_decl = NULL; - return ret; + ctf_field_class_destroy(field_decl); + field_decl = NULL; + return ret; } -static -int visit_field_class_def(struct ctf_visitor_generate_ir *ctx, - struct ctf_node *cls_specifier_list, - struct bt_list_head *field_class_declarators) +static int visit_field_class_def(struct ctf_visitor_generate_ir *ctx, + struct ctf_node *cls_specifier_list, + struct bt_list_head *field_class_declarators) { - int ret = 0; - GQuark qidentifier; - struct ctf_node *iter; - struct ctf_field_class *class_decl = NULL; - - bt_list_for_each_entry(iter, field_class_declarators, siblings) { - ret = visit_field_class_declarator(ctx, cls_specifier_list, - &qidentifier, iter, &class_decl, NULL); - if (ret) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter, - "Cannot visit field class declarator: ret=%d", ret); - ret = -EINVAL; - goto end; - } - - /* Do not allow field class def and alias of untagged variants */ - if (class_decl->type == CTF_FIELD_CLASS_TYPE_VARIANT) { - struct ctf_field_class_variant *var_fc = - ctf_field_class_as_variant(class_decl); - - if (var_fc->tag_path.path->len == 0) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter, - "Type definition of untagged variant field class is not allowed."); - ret = -EPERM; - goto end; - } - } - - ret = ctx_decl_scope_register_alias(ctx, ctx->current_scope, - g_quark_to_string(qidentifier), class_decl); - if (ret) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter, - "Cannot register field class alias: name=\"%s\"", - g_quark_to_string(qidentifier)); - goto end; - } - } + int ret = 0; + GQuark qidentifier; + struct ctf_node *iter; + struct ctf_field_class *class_decl = NULL; + + bt_list_for_each_entry (iter, field_class_declarators, siblings) { + ret = visit_field_class_declarator(ctx, cls_specifier_list, &qidentifier, iter, &class_decl, + NULL); + if (ret) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter, "Cannot visit field class declarator: ret=%d", + ret); + ret = -EINVAL; + goto end; + } + + /* Do not allow field class def and alias of untagged variants */ + if (class_decl->type == CTF_FIELD_CLASS_TYPE_VARIANT) { + struct ctf_field_class_variant *var_fc = ctf_field_class_as_variant(class_decl); + + if (var_fc->tag_path.path->len == 0) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + iter, "Type definition of untagged variant field class is not allowed."); + ret = -EPERM; + goto end; + } + } + + ret = ctx_decl_scope_register_alias(ctx, ctx->current_scope, g_quark_to_string(qidentifier), + class_decl); + if (ret) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter, "Cannot register field class alias: name=\"%s\"", + g_quark_to_string(qidentifier)); + goto end; + } + } end: - ctf_field_class_destroy(class_decl); - class_decl = NULL; - return ret; + ctf_field_class_destroy(class_decl); + class_decl = NULL; + return ret; } -static -int visit_field_class_alias(struct ctf_visitor_generate_ir *ctx, struct ctf_node *target, - struct ctf_node *alias) +static int visit_field_class_alias(struct ctf_visitor_generate_ir *ctx, struct ctf_node *target, + struct ctf_node *alias) { - int ret = 0; - GQuark qalias; - struct ctf_node *node; - GQuark qdummy_field_name; - struct ctf_field_class *class_decl = NULL; - - /* Create target field class */ - if (bt_list_empty(&target->u.field_class_alias_target.field_class_declarators)) { - node = NULL; - } else { - node = _BT_LIST_FIRST_ENTRY( - &target->u.field_class_alias_target.field_class_declarators, - struct ctf_node, siblings); - } - - ret = visit_field_class_declarator(ctx, - target->u.field_class_alias_target.field_class_specifier_list, - &qdummy_field_name, node, &class_decl, NULL); - if (ret) { - BT_ASSERT(!class_decl); - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, - "Cannot visit field class declarator: ret=%d", ret); - goto end; - } - - /* Do not allow field class def and alias of untagged variants */ - if (class_decl->type == CTF_FIELD_CLASS_TYPE_VARIANT) { - struct ctf_field_class_variant *var_fc = - ctf_field_class_as_variant(class_decl); - - if (var_fc->tag_path.path->len == 0) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(target, - "Type definition of untagged variant field class is not allowed."); - ret = -EPERM; - goto end; - } - } - - /* - * The semantic validator does not check whether the target is - * abstract or not (if it has an identifier). Check it here. - */ - if (qdummy_field_name != 0) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(target, - "Expecting empty identifier: id=\"%s\"", - g_quark_to_string(qdummy_field_name)); - ret = -EINVAL; - goto end; - } - - /* Create alias identifier */ - node = _BT_LIST_FIRST_ENTRY(&alias->u.field_class_alias_name.field_class_declarators, - struct ctf_node, siblings); - qalias = create_class_alias_identifier(ctx, - alias->u.field_class_alias_name.field_class_specifier_list, node); - ret = ctx_decl_scope_register_alias(ctx, ctx->current_scope, - g_quark_to_string(qalias), class_decl); - if (ret) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, - "Cannot register class alias: name=\"%s\"", - g_quark_to_string(qalias)); - goto end; - } + int ret = 0; + GQuark qalias; + struct ctf_node *node; + GQuark qdummy_field_name; + struct ctf_field_class *class_decl = NULL; + + /* Create target field class */ + if (bt_list_empty(&target->u.field_class_alias_target.field_class_declarators)) { + node = NULL; + } else { + node = _BT_LIST_FIRST_ENTRY(&target->u.field_class_alias_target.field_class_declarators, + struct ctf_node, siblings); + } + + ret = visit_field_class_declarator( + ctx, target->u.field_class_alias_target.field_class_specifier_list, &qdummy_field_name, + node, &class_decl, NULL); + if (ret) { + BT_ASSERT(!class_decl); + _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Cannot visit field class declarator: ret=%d", ret); + goto end; + } + + /* Do not allow field class def and alias of untagged variants */ + if (class_decl->type == CTF_FIELD_CLASS_TYPE_VARIANT) { + struct ctf_field_class_variant *var_fc = ctf_field_class_as_variant(class_decl); + + if (var_fc->tag_path.path->len == 0) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + target, "Type definition of untagged variant field class is not allowed."); + ret = -EPERM; + goto end; + } + } + + /* + * The semantic validator does not check whether the target is + * abstract or not (if it has an identifier). Check it here. + */ + if (qdummy_field_name != 0) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(target, "Expecting empty identifier: id=\"%s\"", + g_quark_to_string(qdummy_field_name)); + ret = -EINVAL; + goto end; + } + + /* Create alias identifier */ + node = _BT_LIST_FIRST_ENTRY(&alias->u.field_class_alias_name.field_class_declarators, + struct ctf_node, siblings); + qalias = create_class_alias_identifier( + ctx, alias->u.field_class_alias_name.field_class_specifier_list, node); + ret = ctx_decl_scope_register_alias(ctx, ctx->current_scope, g_quark_to_string(qalias), + class_decl); + if (ret) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Cannot register class alias: name=\"%s\"", + g_quark_to_string(qalias)); + goto end; + } end: - ctf_field_class_destroy(class_decl); - class_decl = NULL; - return ret; + ctf_field_class_destroy(class_decl); + class_decl = NULL; + return ret; } -static -int visit_struct_decl_entry(struct ctf_visitor_generate_ir *ctx, struct ctf_node *entry_node, - struct ctf_field_class_struct *struct_decl) +static int visit_struct_decl_entry(struct ctf_visitor_generate_ir *ctx, struct ctf_node *entry_node, + struct ctf_field_class_struct *struct_decl) { - int ret = 0; - - switch (entry_node->type) { - case NODE_TYPEDEF: - ret = visit_field_class_def(ctx, - entry_node->u.field_class_def.field_class_specifier_list, - &entry_node->u.field_class_def.field_class_declarators); - if (ret) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node, - "Cannot add field class found in structure field class: ret=%d", - ret); - goto end; - } - break; - case NODE_TYPEALIAS: - ret = visit_field_class_alias(ctx, entry_node->u.field_class_alias.target, - entry_node->u.field_class_alias.alias); - if (ret) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node, - "Cannot add field class alias found in structure field class: ret=%d", - ret); - goto end; - } - break; - case NODE_STRUCT_OR_VARIANT_DECLARATION: - /* Field */ - ret = visit_struct_decl_field(ctx, struct_decl, - entry_node->u.struct_or_variant_declaration. - field_class_specifier_list, - &entry_node->u.struct_or_variant_declaration. - field_class_declarators); - if (ret) { - goto end; - } - break; - default: - _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node, - "Unexpected node type: node-type=%d", entry_node->type); - ret = -EINVAL; - goto end; - } + int ret = 0; + + switch (entry_node->type) { + case NODE_TYPEDEF: + ret = visit_field_class_def(ctx, entry_node->u.field_class_def.field_class_specifier_list, + &entry_node->u.field_class_def.field_class_declarators); + if (ret) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + entry_node, "Cannot add field class found in structure field class: ret=%d", ret); + goto end; + } + break; + case NODE_TYPEALIAS: + ret = visit_field_class_alias(ctx, entry_node->u.field_class_alias.target, + entry_node->u.field_class_alias.alias); + if (ret) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + entry_node, "Cannot add field class alias found in structure field class: ret=%d", + ret); + goto end; + } + break; + case NODE_STRUCT_OR_VARIANT_DECLARATION: + /* Field */ + ret = visit_struct_decl_field( + ctx, struct_decl, + entry_node->u.struct_or_variant_declaration.field_class_specifier_list, + &entry_node->u.struct_or_variant_declaration.field_class_declarators); + if (ret) { + goto end; + } + break; + default: + _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node, "Unexpected node type: node-type=%d", + entry_node->type); + ret = -EINVAL; + goto end; + } end: - return ret; + return ret; } -static -int visit_variant_decl_entry(struct ctf_visitor_generate_ir *ctx, struct ctf_node *entry_node, - struct ctf_field_class_variant *variant_decl) +static int visit_variant_decl_entry(struct ctf_visitor_generate_ir *ctx, + struct ctf_node *entry_node, + struct ctf_field_class_variant *variant_decl) { - int ret = 0; - - switch (entry_node->type) { - case NODE_TYPEDEF: - ret = visit_field_class_def(ctx, - entry_node->u.field_class_def.field_class_specifier_list, - &entry_node->u.field_class_def.field_class_declarators); - if (ret) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node, - "Cannot add field class found in variant field class: ret=%d", - ret); - goto end; - } - break; - case NODE_TYPEALIAS: - ret = visit_field_class_alias(ctx, entry_node->u.field_class_alias.target, - entry_node->u.field_class_alias.alias); - if (ret) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node, - "Cannot add field class alias found in variant field class: ret=%d", - ret); - goto end; - } - break; - case NODE_STRUCT_OR_VARIANT_DECLARATION: - /* Field */ - ret = visit_variant_decl_field(ctx, variant_decl, - entry_node->u.struct_or_variant_declaration. - field_class_specifier_list, - &entry_node->u.struct_or_variant_declaration. - field_class_declarators); - if (ret) { - goto end; - } - break; - default: - _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node, - "Unexpected node type: node-type=%d", - entry_node->type); - ret = -EINVAL; - goto end; - } + int ret = 0; + + switch (entry_node->type) { + case NODE_TYPEDEF: + ret = visit_field_class_def(ctx, entry_node->u.field_class_def.field_class_specifier_list, + &entry_node->u.field_class_def.field_class_declarators); + if (ret) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + entry_node, "Cannot add field class found in variant field class: ret=%d", ret); + goto end; + } + break; + case NODE_TYPEALIAS: + ret = visit_field_class_alias(ctx, entry_node->u.field_class_alias.target, + entry_node->u.field_class_alias.alias); + if (ret) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + entry_node, "Cannot add field class alias found in variant field class: ret=%d", + ret); + goto end; + } + break; + case NODE_STRUCT_OR_VARIANT_DECLARATION: + /* Field */ + ret = visit_variant_decl_field( + ctx, variant_decl, + entry_node->u.struct_or_variant_declaration.field_class_specifier_list, + &entry_node->u.struct_or_variant_declaration.field_class_declarators); + if (ret) { + goto end; + } + break; + default: + _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node, "Unexpected node type: node-type=%d", + entry_node->type); + ret = -EINVAL; + goto end; + } end: - return ret; + return ret; } -static -int visit_struct_decl(struct ctf_visitor_generate_ir *ctx, const char *name, - struct bt_list_head *decl_list, int has_body, - struct bt_list_head *min_align, - struct ctf_field_class_struct **struct_decl) +static int visit_struct_decl(struct ctf_visitor_generate_ir *ctx, const char *name, + struct bt_list_head *decl_list, int has_body, + struct bt_list_head *min_align, + struct ctf_field_class_struct **struct_decl) { - int ret = 0; - - BT_ASSERT(struct_decl); - *struct_decl = NULL; - - /* For named struct (without body), lookup in declaration scope */ - if (!has_body) { - if (!name) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Bodyless structure field class: missing name."); - ret = -EPERM; - goto error; - } - - *struct_decl = ctx_decl_scope_lookup_struct(ctx, ctx->current_scope, - name, -1, true); - if (!*struct_decl) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot find structure field class: name=\"struct %s\"", - name); - ret = -EINVAL; - goto error; - } - } else { - struct ctf_node *entry_node; - uint64_t min_align_value = 0; - - if (name) { - if (ctx_decl_scope_lookup_struct(ctx, - ctx->current_scope, name, 1, false)) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Structure field class already declared in local scope: " - "name=\"struct %s\"", name); - ret = -EINVAL; - goto error; - } - } - - if (!bt_list_empty(min_align)) { - ret = get_unary_unsigned(ctx, min_align, - &min_align_value); - if (ret) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Unexpected unary expression for structure field class's `align` attribute: " - "ret=%d", ret); - goto error; - } - } - - *struct_decl = ctf_field_class_struct_create(); - BT_ASSERT(*struct_decl); - - if (min_align_value != 0) { - (*struct_decl)->base.alignment = min_align_value; - } - - _TRY_PUSH_SCOPE_OR_GOTO_ERROR(); - - bt_list_for_each_entry(entry_node, decl_list, siblings) { - ret = visit_struct_decl_entry(ctx, entry_node, - *struct_decl); - if (ret) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node, - "Cannot visit structure field class entry: " - "ret=%d", ret); - ctx_pop_scope(ctx); - goto error; - } - } - - ctx_pop_scope(ctx); - - if (name) { - ret = ctx_decl_scope_register_struct(ctx, - ctx->current_scope, name, *struct_decl); - if (ret) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot register structure field class in declaration scope: " - "name=\"struct %s\", ret=%d", name, ret); - goto error; - } - } - } - - return 0; + int ret = 0; + + BT_ASSERT(struct_decl); + *struct_decl = NULL; + + /* For named struct (without body), lookup in declaration scope */ + if (!has_body) { + if (!name) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Bodyless structure field class: missing name."); + ret = -EPERM; + goto error; + } + + *struct_decl = ctx_decl_scope_lookup_struct(ctx, ctx->current_scope, name, -1, true); + if (!*struct_decl) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Cannot find structure field class: name=\"struct %s\"", name); + ret = -EINVAL; + goto error; + } + } else { + struct ctf_node *entry_node; + uint64_t min_align_value = 0; + + if (name) { + if (ctx_decl_scope_lookup_struct(ctx, ctx->current_scope, name, 1, false)) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Structure field class already declared in local scope: " + "name=\"struct %s\"", + name); + ret = -EINVAL; + goto error; + } + } + + if (!bt_list_empty(min_align)) { + ret = get_unary_unsigned(ctx, min_align, &min_align_value); + if (ret) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Unexpected unary expression for structure field class's `align` attribute: " + "ret=%d", + ret); + goto error; + } + } + + *struct_decl = ctf_field_class_struct_create(); + BT_ASSERT(*struct_decl); + + if (min_align_value != 0) { + (*struct_decl)->base.alignment = min_align_value; + } + + _TRY_PUSH_SCOPE_OR_GOTO_ERROR(); + + bt_list_for_each_entry (entry_node, decl_list, siblings) { + ret = visit_struct_decl_entry(ctx, entry_node, *struct_decl); + if (ret) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node, + "Cannot visit structure field class entry: " + "ret=%d", + ret); + ctx_pop_scope(ctx); + goto error; + } + } + + ctx_pop_scope(ctx); + + if (name) { + ret = ctx_decl_scope_register_struct(ctx, ctx->current_scope, name, *struct_decl); + if (ret) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Cannot register structure field class in declaration scope: " + "name=\"struct %s\", ret=%d", + name, ret); + goto error; + } + } + } + + return 0; error: - ctf_field_class_destroy(&(*struct_decl)->base); - *struct_decl = NULL; - return ret; + ctf_field_class_destroy(&(*struct_decl)->base); + *struct_decl = NULL; + return ret; } -static -int visit_variant_decl(struct ctf_visitor_generate_ir *ctx, const char *name, - const char *tag, struct bt_list_head *decl_list, - int has_body, struct ctf_field_class_variant **variant_decl) +static int visit_variant_decl(struct ctf_visitor_generate_ir *ctx, const char *name, + const char *tag, struct bt_list_head *decl_list, int has_body, + struct ctf_field_class_variant **variant_decl) { - int ret = 0; - struct ctf_field_class_variant *untagged_variant_decl = NULL; - - BT_ASSERT(variant_decl); - *variant_decl = NULL; - - /* For named variant (without body), lookup in declaration scope */ - if (!has_body) { - if (!name) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Bodyless variant field class: missing name."); - ret = -EPERM; - goto error; - } - - untagged_variant_decl = - ctx_decl_scope_lookup_variant(ctx, ctx->current_scope, - name, -1, true); - if (!untagged_variant_decl) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot find variant field class: name=\"variant %s\"", - name); - ret = -EINVAL; - goto error; - } - } else { - struct ctf_node *entry_node; - - if (name) { - if (ctx_decl_scope_lookup_variant(ctx, - ctx->current_scope, name, 1, false)) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Variant field class already declared in local scope: " - "name=\"variant %s\"", name); - ret = -EINVAL; - goto error; - } - } - - untagged_variant_decl = ctf_field_class_variant_create(); - BT_ASSERT(untagged_variant_decl); - _TRY_PUSH_SCOPE_OR_GOTO_ERROR(); - - bt_list_for_each_entry(entry_node, decl_list, siblings) { - ret = visit_variant_decl_entry(ctx, entry_node, - untagged_variant_decl); - if (ret) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node, - "Cannot visit variant field class entry: " - "ret=%d", ret); - ctx_pop_scope(ctx); - goto error; - } - } - - ctx_pop_scope(ctx); - - if (name) { - ret = ctx_decl_scope_register_variant(ctx, - ctx->current_scope, name, - untagged_variant_decl); - if (ret) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot register variant field class in declaration scope: " - "name=\"variant %s\", ret=%d", name, ret); - goto error; - } - } - } - - /* - * If tagged, create tagged variant and return; otherwise - * return untagged variant. - */ - if (!tag) { - *variant_decl = untagged_variant_decl; - untagged_variant_decl = NULL; - } else { - /* - * At this point, we have a fresh untagged variant; nobody - * else owns it. Set its tag now. - */ - g_string_assign(untagged_variant_decl->tag_ref, tag); - *variant_decl = untagged_variant_decl; - untagged_variant_decl = NULL; - } - - BT_ASSERT(!untagged_variant_decl); - BT_ASSERT(*variant_decl); - return 0; + int ret = 0; + struct ctf_field_class_variant *untagged_variant_decl = NULL; + + BT_ASSERT(variant_decl); + *variant_decl = NULL; + + /* For named variant (without body), lookup in declaration scope */ + if (!has_body) { + if (!name) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Bodyless variant field class: missing name."); + ret = -EPERM; + goto error; + } + + untagged_variant_decl = + ctx_decl_scope_lookup_variant(ctx, ctx->current_scope, name, -1, true); + if (!untagged_variant_decl) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Cannot find variant field class: name=\"variant %s\"", name); + ret = -EINVAL; + goto error; + } + } else { + struct ctf_node *entry_node; + + if (name) { + if (ctx_decl_scope_lookup_variant(ctx, ctx->current_scope, name, 1, false)) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Variant field class already declared in local scope: " + "name=\"variant %s\"", + name); + ret = -EINVAL; + goto error; + } + } + + untagged_variant_decl = ctf_field_class_variant_create(); + BT_ASSERT(untagged_variant_decl); + _TRY_PUSH_SCOPE_OR_GOTO_ERROR(); + + bt_list_for_each_entry (entry_node, decl_list, siblings) { + ret = visit_variant_decl_entry(ctx, entry_node, untagged_variant_decl); + if (ret) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node, + "Cannot visit variant field class entry: " + "ret=%d", + ret); + ctx_pop_scope(ctx); + goto error; + } + } + + ctx_pop_scope(ctx); + + if (name) { + ret = ctx_decl_scope_register_variant(ctx, ctx->current_scope, name, + untagged_variant_decl); + if (ret) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Cannot register variant field class in declaration scope: " + "name=\"variant %s\", ret=%d", + name, ret); + goto error; + } + } + } + + /* + * If tagged, create tagged variant and return; otherwise + * return untagged variant. + */ + if (!tag) { + *variant_decl = untagged_variant_decl; + untagged_variant_decl = NULL; + } else { + /* + * At this point, we have a fresh untagged variant; nobody + * else owns it. Set its tag now. + */ + g_string_assign(untagged_variant_decl->tag_ref, tag); + *variant_decl = untagged_variant_decl; + untagged_variant_decl = NULL; + } + + BT_ASSERT(!untagged_variant_decl); + BT_ASSERT(*variant_decl); + return 0; error: - ctf_field_class_destroy(&untagged_variant_decl->base); - untagged_variant_decl = NULL; - ctf_field_class_destroy(&(*variant_decl)->base); - *variant_decl = NULL; - return ret; + ctf_field_class_destroy(&untagged_variant_decl->base); + untagged_variant_decl = NULL; + ctf_field_class_destroy(&(*variant_decl)->base); + *variant_decl = NULL; + return ret; } -struct uori { - bool is_signed; - union { - uint64_t u; - uint64_t i; - } value; +struct uori +{ + bool is_signed; + union + { + uint64_t u; + uint64_t i; + } value; }; -static -int visit_enum_decl_entry(struct ctf_visitor_generate_ir *ctx, struct ctf_node *enumerator, - struct ctf_field_class_enum *enum_decl, struct uori *last) +static int visit_enum_decl_entry(struct ctf_visitor_generate_ir *ctx, struct ctf_node *enumerator, + struct ctf_field_class_enum *enum_decl, struct uori *last) { - int ret = 0; - int nr_vals = 0; - struct ctf_node *iter; - struct uori start = { - .is_signed = false, - .value = { - .u = 0, - }, - }; - struct uori end = { - .is_signed = false, - .value = { - .u = 0, - }, - }; - const char *label = enumerator->u.enumerator.id; - struct bt_list_head *values = &enumerator->u.enumerator.values; - - bt_list_for_each_entry(iter, values, siblings) { - struct uori *target; - - if (iter->type != NODE_UNARY_EXPRESSION) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter, - "Wrong expression for enumeration field class label: " - "node-type=%d, label=\"%s\"", iter->type, - label); - ret = -EINVAL; - goto error; - } - - if (nr_vals == 0) { - target = &start; - } else { - target = &end; - } - - switch (iter->u.unary_expression.type) { - case UNARY_SIGNED_CONSTANT: - target->is_signed = true; - target->value.i = - iter->u.unary_expression.u.signed_constant; - break; - case UNARY_UNSIGNED_CONSTANT: - target->is_signed = false; - target->value.u = - iter->u.unary_expression.u.unsigned_constant; - break; - default: - _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter, - "Invalid enumeration field class entry: " - "expecting constant signed or unsigned integer: " - "node-type=%d, label=\"%s\"", - iter->u.unary_expression.type, label); - ret = -EINVAL; - goto error; - } - - if (nr_vals > 1) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter, - "Invalid enumeration field class entry: label=\"%s\"", - label); - ret = -EINVAL; - goto error; - } - - nr_vals++; - } - - if (nr_vals == 0) { - start = *last; - } - - if (nr_vals <= 1) { - end = start; - } - - if (end.is_signed) { - last->value.i = end.value.i + 1; - } else { - last->value.u = end.value.u + 1; - } - - ctf_field_class_enum_map_range(enum_decl, label, - start.value.u, end.value.u); - return 0; + int ret = 0; + int nr_vals = 0; + struct ctf_node *iter; + struct uori start = { + .is_signed = false, + .value = + { + .u = 0, + }, + }; + struct uori end = { + .is_signed = false, + .value = + { + .u = 0, + }, + }; + const char *label = enumerator->u.enumerator.id; + struct bt_list_head *values = &enumerator->u.enumerator.values; + + bt_list_for_each_entry (iter, values, siblings) { + struct uori *target; + + if (iter->type != NODE_UNARY_EXPRESSION) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter, + "Wrong expression for enumeration field class label: " + "node-type=%d, label=\"%s\"", + iter->type, label); + ret = -EINVAL; + goto error; + } + + if (nr_vals == 0) { + target = &start; + } else { + target = &end; + } + + switch (iter->u.unary_expression.type) { + case UNARY_SIGNED_CONSTANT: + target->is_signed = true; + target->value.i = iter->u.unary_expression.u.signed_constant; + break; + case UNARY_UNSIGNED_CONSTANT: + target->is_signed = false; + target->value.u = iter->u.unary_expression.u.unsigned_constant; + break; + default: + _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter, + "Invalid enumeration field class entry: " + "expecting constant signed or unsigned integer: " + "node-type=%d, label=\"%s\"", + iter->u.unary_expression.type, label); + ret = -EINVAL; + goto error; + } + + if (nr_vals > 1) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + iter, "Invalid enumeration field class entry: label=\"%s\"", label); + ret = -EINVAL; + goto error; + } + + nr_vals++; + } + + if (nr_vals == 0) { + start = *last; + } + + if (nr_vals <= 1) { + end = start; + } + + if (end.is_signed) { + last->value.i = end.value.i + 1; + } else { + last->value.u = end.value.u + 1; + } + + ctf_field_class_enum_map_range(enum_decl, label, start.value.u, end.value.u); + return 0; error: - return ret; + return ret; } -static -int visit_enum_decl(struct ctf_visitor_generate_ir *ctx, const char *name, - struct ctf_node *container_cls, - struct bt_list_head *enumerator_list, - int has_body, struct ctf_field_class_enum **enum_decl) +static int visit_enum_decl(struct ctf_visitor_generate_ir *ctx, const char *name, + struct ctf_node *container_cls, struct bt_list_head *enumerator_list, + int has_body, struct ctf_field_class_enum **enum_decl) { - int ret = 0; - GQuark qdummy_id; - struct ctf_field_class_int *integer_decl = NULL; - - BT_ASSERT(enum_decl); - *enum_decl = NULL; - - /* For named enum (without body), lookup in declaration scope */ - if (!has_body) { - if (!name) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Bodyless enumeration field class: missing name."); - ret = -EPERM; - goto error; - } - - *enum_decl = ctx_decl_scope_lookup_enum(ctx, ctx->current_scope, - name, -1, true); - if (!*enum_decl) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot find enumeration field class: " - "name=\"enum %s\"", name); - ret = -EINVAL; - goto error; - } - } else { - struct ctf_node *iter; - struct uori last_value = { - .is_signed = false, - .value = { - .u = 0, - }, - }; - - if (name) { - if (ctx_decl_scope_lookup_enum(ctx, ctx->current_scope, - name, 1, false)) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Enumeration field class already declared in local scope: " - "name=\"enum %s\"", name); - ret = -EINVAL; - goto error; - } - } - - if (!container_cls) { - integer_decl = ctf_field_class_as_int(ctx_decl_scope_lookup_alias(ctx, - ctx->current_scope, "int", -1, true)); - if (!integer_decl) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot find implicit `int` field class alias for enumeration field class."); - ret = -EINVAL; - goto error; - } - } else { - ctf_field_class *decl; - - ret = visit_field_class_declarator(ctx, container_cls, - &qdummy_id, NULL, &decl, NULL); - if (ret) { - BT_ASSERT(!decl); - ret = -EINVAL; - goto error; - } - - integer_decl = ctf_field_class_as_int(decl); - } - - BT_ASSERT(integer_decl); - - if (integer_decl->base.base.type != CTF_FIELD_CLASS_TYPE_INT) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Container field class for enumeration field class is not an integer field class: " - "fc-type=%d", integer_decl->base.base.type); - ret = -EINVAL; - goto error; - } - - *enum_decl = ctf_field_class_enum_create(); - BT_ASSERT(*enum_decl); - (*enum_decl)->base.base.base.alignment = - integer_decl->base.base.alignment; - ctf_field_class_int_copy_content( - &(*enum_decl)->base, integer_decl); - last_value.is_signed = (*enum_decl)->base.is_signed; - - bt_list_for_each_entry(iter, enumerator_list, siblings) { - ret = visit_enum_decl_entry(ctx, iter, *enum_decl, - &last_value); - if (ret) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter, - "Cannot visit enumeration field class entry: " - "ret=%d", ret); - goto error; - } - } - - if (name) { - ret = ctx_decl_scope_register_enum(ctx, - ctx->current_scope, name, *enum_decl); - if (ret) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot register enumeration field class in declaration scope: " - "ret=%d", ret); - goto error; - } - } - } - - goto end; + int ret = 0; + GQuark qdummy_id; + struct ctf_field_class_int *integer_decl = NULL; + + BT_ASSERT(enum_decl); + *enum_decl = NULL; + + /* For named enum (without body), lookup in declaration scope */ + if (!has_body) { + if (!name) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Bodyless enumeration field class: missing name."); + ret = -EPERM; + goto error; + } + + *enum_decl = ctx_decl_scope_lookup_enum(ctx, ctx->current_scope, name, -1, true); + if (!*enum_decl) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot find enumeration field class: " + "name=\"enum %s\"", + name); + ret = -EINVAL; + goto error; + } + } else { + struct ctf_node *iter; + struct uori last_value = { + .is_signed = false, + .value = + { + .u = 0, + }, + }; + + if (name) { + if (ctx_decl_scope_lookup_enum(ctx, ctx->current_scope, name, 1, false)) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Enumeration field class already declared in local scope: " + "name=\"enum %s\"", + name); + ret = -EINVAL; + goto error; + } + } + + if (!container_cls) { + integer_decl = ctf_field_class_as_int( + ctx_decl_scope_lookup_alias(ctx, ctx->current_scope, "int", -1, true)); + if (!integer_decl) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Cannot find implicit `int` field class alias for enumeration field class."); + ret = -EINVAL; + goto error; + } + } else { + ctf_field_class *decl; + + ret = visit_field_class_declarator(ctx, container_cls, &qdummy_id, NULL, &decl, NULL); + if (ret) { + BT_ASSERT(!decl); + ret = -EINVAL; + goto error; + } + + integer_decl = ctf_field_class_as_int(decl); + } + + BT_ASSERT(integer_decl); + + if (integer_decl->base.base.type != CTF_FIELD_CLASS_TYPE_INT) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Container field class for enumeration field class is not an integer field class: " + "fc-type=%d", + integer_decl->base.base.type); + ret = -EINVAL; + goto error; + } + + *enum_decl = ctf_field_class_enum_create(); + BT_ASSERT(*enum_decl); + (*enum_decl)->base.base.base.alignment = integer_decl->base.base.alignment; + ctf_field_class_int_copy_content(&(*enum_decl)->base, integer_decl); + last_value.is_signed = (*enum_decl)->base.is_signed; + + bt_list_for_each_entry (iter, enumerator_list, siblings) { + ret = visit_enum_decl_entry(ctx, iter, *enum_decl, &last_value); + if (ret) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter, + "Cannot visit enumeration field class entry: " + "ret=%d", + ret); + goto error; + } + } + + if (name) { + ret = ctx_decl_scope_register_enum(ctx, ctx->current_scope, name, *enum_decl); + if (ret) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Cannot register enumeration field class in declaration scope: " + "ret=%d", + ret); + goto error; + } + } + } + + goto end; error: - ctf_field_class_destroy(&(*enum_decl)->base.base.base); - *enum_decl = NULL; + ctf_field_class_destroy(&(*enum_decl)->base.base.base); + *enum_decl = NULL; end: - ctf_field_class_destroy(&integer_decl->base.base); - integer_decl = NULL; - return ret; + ctf_field_class_destroy(&integer_decl->base.base); + integer_decl = NULL; + return ret; } -static -int visit_field_class_specifier(struct ctf_visitor_generate_ir *ctx, - struct ctf_node *cls_specifier_list, - struct ctf_field_class **decl) +static int visit_field_class_specifier(struct ctf_visitor_generate_ir *ctx, + struct ctf_node *cls_specifier_list, + struct ctf_field_class **decl) { - int ret = 0; - GString *str = NULL; - - *decl = NULL; - str = g_string_new(""); - ret = get_class_specifier_list_name(ctx, cls_specifier_list, str); - if (ret) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(cls_specifier_list, - "Cannot get field class specifier list's name: ret=%d", ret); - goto error; - } - - *decl = ctx_decl_scope_lookup_alias(ctx, ctx->current_scope, str->str, - -1, true); - if (!*decl) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(cls_specifier_list, - "Cannot find field class alias: name=\"%s\"", str->str); - ret = -EINVAL; - goto error; - } - - goto end; + int ret = 0; + GString *str = NULL; + + *decl = NULL; + str = g_string_new(""); + ret = get_class_specifier_list_name(ctx, cls_specifier_list, str); + if (ret) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + cls_specifier_list, "Cannot get field class specifier list's name: ret=%d", ret); + goto error; + } + + *decl = ctx_decl_scope_lookup_alias(ctx, ctx->current_scope, str->str, -1, true); + if (!*decl) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(cls_specifier_list, + "Cannot find field class alias: name=\"%s\"", str->str); + ret = -EINVAL; + goto error; + } + + goto end; error: - ctf_field_class_destroy(*decl); - *decl = NULL; + ctf_field_class_destroy(*decl); + *decl = NULL; end: - if (str) { - g_string_free(str, TRUE); - } + if (str) { + g_string_free(str, TRUE); + } - return ret; + return ret; } -static -int visit_integer_decl(struct ctf_visitor_generate_ir *ctx, - struct bt_list_head *expressions, - struct ctf_field_class_int **integer_decl) +static int visit_integer_decl(struct ctf_visitor_generate_ir *ctx, struct bt_list_head *expressions, + struct ctf_field_class_int **integer_decl) { - int set = 0; - int ret = 0; - int signedness = 0; - struct ctf_node *expression; - uint64_t alignment = 0, size = 0; - struct ctf_clock_class *mapped_clock_class = NULL; - enum ctf_encoding encoding = CTF_ENCODING_NONE; - bt_field_class_integer_preferred_display_base base = - BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL; - enum ctf_byte_order byte_order = ctx->ctf_tc->default_byte_order; - - *integer_decl = NULL; - - bt_list_for_each_entry(expression, expressions, siblings) { - struct ctf_node *left, *right; - - left = _BT_LIST_FIRST_ENTRY(&expression->u.ctf_expression.left, - struct ctf_node, siblings); - right = _BT_LIST_FIRST_ENTRY( - &expression->u.ctf_expression.right, struct ctf_node, - siblings); - - if (left->u.unary_expression.type != UNARY_STRING) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(left, - "Unexpected unary expression type: type=%d", - left->u.unary_expression.type); - ret = -EINVAL; - goto error; - } - - if (strcmp(left->u.unary_expression.u.string, "signed") == 0) { - if (_IS_SET(&set, _INTEGER_SIGNED_SET)) { - _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(left, "signed", - "integer field class"); - ret = -EPERM; - goto error; - } - - signedness = get_boolean(ctx, right); - if (signedness < 0) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(right, - "Invalid boolean value for integer field class's `signed` attribute: " - "ret=%d", ret); - ret = -EINVAL; - goto error; - } - - _SET(&set, _INTEGER_SIGNED_SET); - } else if (strcmp(left->u.unary_expression.u.string, "byte_order") == 0) { - if (_IS_SET(&set, _INTEGER_BYTE_ORDER_SET)) { - _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(left, "byte_order", - "integer field class"); - ret = -EPERM; - goto error; - } - - byte_order = get_real_byte_order(ctx, right); - if (byte_order == CTF_BYTE_ORDER_UNKNOWN) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(right, - "Invalid `byte_order` attribute in integer field class: " - "ret=%d", ret); - ret = -EINVAL; - goto error; - } - - _SET(&set, _INTEGER_BYTE_ORDER_SET); - } else if (strcmp(left->u.unary_expression.u.string, "size") == 0) { - if (_IS_SET(&set, _INTEGER_SIZE_SET)) { - _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(left, "size", - "integer field class"); - ret = -EPERM; - goto error; - } - - if (right->u.unary_expression.type != - UNARY_UNSIGNED_CONSTANT) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(right, - "Invalid `size` attribute in integer field class: " - "expecting unsigned constant integer: " - "node-type=%d", - right->u.unary_expression.type); - ret = -EINVAL; - goto error; - } - - size = right->u.unary_expression.u.unsigned_constant; - if (size == 0) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(right, - "Invalid `size` attribute in integer field class: " - "expecting positive constant integer: " - "size=%" PRIu64, size); - ret = -EINVAL; - goto error; - } else if (size > 64) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(right, - "Invalid `size` attribute in integer field class: " - "integer fields over 64 bits are not supported as of this version: " - "size=%" PRIu64, size); - ret = -EINVAL; - goto error; - } - - _SET(&set, _INTEGER_SIZE_SET); - } else if (strcmp(left->u.unary_expression.u.string, "align") == 0) { - if (_IS_SET(&set, _INTEGER_ALIGN_SET)) { - _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(left, "align", - "integer field class"); - ret = -EPERM; - goto error; - } - - if (right->u.unary_expression.type != - UNARY_UNSIGNED_CONSTANT) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(right, - "Invalid `align` attribute in integer field class: " - "expecting unsigned constant integer: " - "node-type=%d", - right->u.unary_expression.type); - ret = -EINVAL; - goto error; - } - - alignment = - right->u.unary_expression.u.unsigned_constant; - if (!is_align_valid(alignment)) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(right, - "Invalid `align` attribute in integer field class: " - "expecting power of two: " - "align=%" PRIu64, alignment); - ret = -EINVAL; - goto error; - } - - _SET(&set, _INTEGER_ALIGN_SET); - } else if (strcmp(left->u.unary_expression.u.string, "base") == 0) { - if (_IS_SET(&set, _INTEGER_BASE_SET)) { - _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(left, "base", - "integer field class"); - ret = -EPERM; - goto error; - } - - switch (right->u.unary_expression.type) { - case UNARY_UNSIGNED_CONSTANT: - { - uint64_t constant = right->u.unary_expression. - u.unsigned_constant; - - switch (constant) { - case 2: - base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_BINARY; - break; - case 8: - base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_OCTAL; - break; - case 10: - base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL; - break; - case 16: - base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL; - break; - default: - _BT_COMP_LOGE_APPEND_CAUSE_NODE(right, - "Invalid `base` attribute in integer field class: " - "base=%" PRIu64, - right->u.unary_expression.u.unsigned_constant); - ret = -EINVAL; - goto error; - } - break; - } - case UNARY_STRING: - { - char *s_right = ctf_ast_concatenate_unary_strings( - &expression->u.ctf_expression.right); - if (!s_right) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(right, - "Unexpected unary expression for integer field class's `base` attribute."); - ret = -EINVAL; - goto error; - } - - if (strcmp(s_right, "decimal") == 0 || - strcmp(s_right, "dec") == 0 || - strcmp(s_right, "d") == 0 || - strcmp(s_right, "i") == 0 || - strcmp(s_right, "u") == 0) { - base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL; - } else if (strcmp(s_right, "hexadecimal") == 0 || - strcmp(s_right, "hex") == 0 || - strcmp(s_right, "x") == 0 || - strcmp(s_right, "X") == 0 || - strcmp(s_right, "p") == 0) { - base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL; - } else if (strcmp(s_right, "octal") == 0 || - strcmp(s_right, "oct") == 0 || - strcmp(s_right, "o") == 0) { - base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_OCTAL; - } else if (strcmp(s_right, "binary") == 0 || - strcmp(s_right, "b") == 0) { - base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_BINARY; - } else { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(right, - "Unexpected unary expression for integer field class's `base` attribute: " - "base=\"%s\"", s_right); - g_free(s_right); - ret = -EINVAL; - goto error; - } - - g_free(s_right); - break; - } - default: - _BT_COMP_LOGE_APPEND_CAUSE_NODE(right, - "Invalid `base` attribute in integer field class: " - "expecting unsigned constant integer or unary string."); - ret = -EINVAL; - goto error; - } - - _SET(&set, _INTEGER_BASE_SET); - } else if (strcmp(left->u.unary_expression.u.string, "encoding") == 0) { - char *s_right; - - if (_IS_SET(&set, _INTEGER_ENCODING_SET)) { - _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(left, "encoding", - "integer field class"); - ret = -EPERM; - goto error; - } - - if (right->u.unary_expression.type != UNARY_STRING) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(right, - "Invalid `encoding` attribute in integer field class: " - "expecting unary string."); - ret = -EINVAL; - goto error; - } - - s_right = ctf_ast_concatenate_unary_strings( - &expression->u.ctf_expression.right); - if (!s_right) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(right, - "Unexpected unary expression for integer field class's `encoding` attribute."); - ret = -EINVAL; - goto error; - } - - if (strcmp(s_right, "UTF8") == 0 || - strcmp(s_right, "utf8") == 0 || - strcmp(s_right, "utf-8") == 0 || - strcmp(s_right, "UTF-8") == 0 || - strcmp(s_right, "ASCII") == 0 || - strcmp(s_right, "ascii") == 0) { - encoding = CTF_ENCODING_UTF8; - } else if (strcmp(s_right, "none") == 0) { - encoding = CTF_ENCODING_NONE; - } else { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(right, - "Invalid `encoding` attribute in integer field class: " - "unknown encoding: encoding=\"%s\"", - s_right); - g_free(s_right); - ret = -EINVAL; - goto error; - } - - g_free(s_right); - _SET(&set, _INTEGER_ENCODING_SET); - } else if (strcmp(left->u.unary_expression.u.string, "map") == 0) { - const char *clock_name; - - if (_IS_SET(&set, _INTEGER_MAP_SET)) { - _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(left, "map", - "integer field class"); - ret = -EPERM; - goto error; - } - - if (right->u.unary_expression.type != UNARY_STRING) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(right, - "Invalid `map` attribute in integer field class: " - "expecting unary string."); - ret = -EINVAL; - goto error; - } - - clock_name = - get_map_clock_name_value( - &expression->u.ctf_expression.right); - if (!clock_name) { - char *s_right = ctf_ast_concatenate_unary_strings( - &expression->u.ctf_expression.right); - - if (!s_right) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(right, - "Unexpected unary expression for integer field class's `map` attribute."); - ret = -EINVAL; - goto error; - } - - _BT_COMP_LOGE_NODE(right, - "Invalid `map` attribute in integer field class: " - "cannot find clock class at this point: name=\"%s\"", - s_right); - _SET(&set, _INTEGER_MAP_SET); - g_free(s_right); - continue; - } - - mapped_clock_class = - ctf_trace_class_borrow_clock_class_by_name( - ctx->ctf_tc, clock_name); - if (!mapped_clock_class) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(right, - "Invalid `map` attribute in integer field class: " - "cannot find clock class at this point: name=\"%s\"", - clock_name); - ret = -EINVAL; - goto error; - } - - _SET(&set, _INTEGER_MAP_SET); - } else { - _BT_COMP_LOGW_NODE(left, - "Unknown attribute in integer field class: " - "attr-name=\"%s\"", - left->u.unary_expression.u.string); - } - } - - if (!_IS_SET(&set, _INTEGER_SIZE_SET)) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Missing `size` attribute in integer field class."); - ret = -EPERM; - goto error; - } - - if (!_IS_SET(&set, _INTEGER_ALIGN_SET)) { - if (size % CHAR_BIT) { - /* Bit-packed alignment */ - alignment = 1; - } else { - /* Byte-packed alignment */ - alignment = CHAR_BIT; - } - } - - *integer_decl = ctf_field_class_int_create(); - BT_ASSERT(*integer_decl); - (*integer_decl)->base.base.alignment = alignment; - (*integer_decl)->base.byte_order = byte_order; - (*integer_decl)->base.size = size; - (*integer_decl)->is_signed = (signedness > 0); - (*integer_decl)->disp_base = base; - (*integer_decl)->encoding = encoding; - (*integer_decl)->mapped_clock_class = mapped_clock_class; - return 0; + int set = 0; + int ret = 0; + int signedness = 0; + struct ctf_node *expression; + uint64_t alignment = 0, size = 0; + struct ctf_clock_class *mapped_clock_class = NULL; + enum ctf_encoding encoding = CTF_ENCODING_NONE; + bt_field_class_integer_preferred_display_base base = + BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL; + enum ctf_byte_order byte_order = ctx->ctf_tc->default_byte_order; + + *integer_decl = NULL; + + bt_list_for_each_entry (expression, expressions, siblings) { + struct ctf_node *left, *right; + + left = _BT_LIST_FIRST_ENTRY(&expression->u.ctf_expression.left, struct ctf_node, siblings); + right = + _BT_LIST_FIRST_ENTRY(&expression->u.ctf_expression.right, struct ctf_node, siblings); + + if (left->u.unary_expression.type != UNARY_STRING) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(left, "Unexpected unary expression type: type=%d", + left->u.unary_expression.type); + ret = -EINVAL; + goto error; + } + + if (strcmp(left->u.unary_expression.u.string, "signed") == 0) { + if (_IS_SET(&set, _INTEGER_SIGNED_SET)) { + _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(left, "signed", "integer field class"); + ret = -EPERM; + goto error; + } + + signedness = get_boolean(ctx, right); + if (signedness < 0) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + right, + "Invalid boolean value for integer field class's `signed` attribute: " + "ret=%d", + ret); + ret = -EINVAL; + goto error; + } + + _SET(&set, _INTEGER_SIGNED_SET); + } else if (strcmp(left->u.unary_expression.u.string, "byte_order") == 0) { + if (_IS_SET(&set, _INTEGER_BYTE_ORDER_SET)) { + _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(left, "byte_order", "integer field class"); + ret = -EPERM; + goto error; + } + + byte_order = get_real_byte_order(ctx, right); + if (byte_order == CTF_BYTE_ORDER_UNKNOWN) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + right, + "Invalid `byte_order` attribute in integer field class: " + "ret=%d", + ret); + ret = -EINVAL; + goto error; + } + + _SET(&set, _INTEGER_BYTE_ORDER_SET); + } else if (strcmp(left->u.unary_expression.u.string, "size") == 0) { + if (_IS_SET(&set, _INTEGER_SIZE_SET)) { + _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(left, "size", "integer field class"); + ret = -EPERM; + goto error; + } + + if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(right, + "Invalid `size` attribute in integer field class: " + "expecting unsigned constant integer: " + "node-type=%d", + right->u.unary_expression.type); + ret = -EINVAL; + goto error; + } + + size = right->u.unary_expression.u.unsigned_constant; + if (size == 0) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(right, + "Invalid `size` attribute in integer field class: " + "expecting positive constant integer: " + "size=%" PRIu64, + size); + ret = -EINVAL; + goto error; + } else if (size > 64) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + right, + "Invalid `size` attribute in integer field class: " + "integer fields over 64 bits are not supported as of this version: " + "size=%" PRIu64, + size); + ret = -EINVAL; + goto error; + } + + _SET(&set, _INTEGER_SIZE_SET); + } else if (strcmp(left->u.unary_expression.u.string, "align") == 0) { + if (_IS_SET(&set, _INTEGER_ALIGN_SET)) { + _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(left, "align", "integer field class"); + ret = -EPERM; + goto error; + } + + if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(right, + "Invalid `align` attribute in integer field class: " + "expecting unsigned constant integer: " + "node-type=%d", + right->u.unary_expression.type); + ret = -EINVAL; + goto error; + } + + alignment = right->u.unary_expression.u.unsigned_constant; + if (!is_align_valid(alignment)) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(right, + "Invalid `align` attribute in integer field class: " + "expecting power of two: " + "align=%" PRIu64, + alignment); + ret = -EINVAL; + goto error; + } + + _SET(&set, _INTEGER_ALIGN_SET); + } else if (strcmp(left->u.unary_expression.u.string, "base") == 0) { + if (_IS_SET(&set, _INTEGER_BASE_SET)) { + _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(left, "base", "integer field class"); + ret = -EPERM; + goto error; + } + + switch (right->u.unary_expression.type) { + case UNARY_UNSIGNED_CONSTANT: + { + uint64_t constant = right->u.unary_expression.u.unsigned_constant; + + switch (constant) { + case 2: + base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_BINARY; + break; + case 8: + base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_OCTAL; + break; + case 10: + base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL; + break; + case 16: + base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL; + break; + default: + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + right, + "Invalid `base` attribute in integer field class: " + "base=%" PRIu64, + right->u.unary_expression.u.unsigned_constant); + ret = -EINVAL; + goto error; + } + break; + } + case UNARY_STRING: + { + char *s_right = + ctf_ast_concatenate_unary_strings(&expression->u.ctf_expression.right); + if (!s_right) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + right, + "Unexpected unary expression for integer field class's `base` attribute."); + ret = -EINVAL; + goto error; + } + + if (strcmp(s_right, "decimal") == 0 || strcmp(s_right, "dec") == 0 || + strcmp(s_right, "d") == 0 || strcmp(s_right, "i") == 0 || + strcmp(s_right, "u") == 0) { + base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL; + } else if (strcmp(s_right, "hexadecimal") == 0 || strcmp(s_right, "hex") == 0 || + strcmp(s_right, "x") == 0 || strcmp(s_right, "X") == 0 || + strcmp(s_right, "p") == 0) { + base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL; + } else if (strcmp(s_right, "octal") == 0 || strcmp(s_right, "oct") == 0 || + strcmp(s_right, "o") == 0) { + base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_OCTAL; + } else if (strcmp(s_right, "binary") == 0 || strcmp(s_right, "b") == 0) { + base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_BINARY; + } else { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + right, + "Unexpected unary expression for integer field class's `base` attribute: " + "base=\"%s\"", + s_right); + g_free(s_right); + ret = -EINVAL; + goto error; + } + + g_free(s_right); + break; + } + default: + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + right, "Invalid `base` attribute in integer field class: " + "expecting unsigned constant integer or unary string."); + ret = -EINVAL; + goto error; + } + + _SET(&set, _INTEGER_BASE_SET); + } else if (strcmp(left->u.unary_expression.u.string, "encoding") == 0) { + char *s_right; + + if (_IS_SET(&set, _INTEGER_ENCODING_SET)) { + _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(left, "encoding", "integer field class"); + ret = -EPERM; + goto error; + } + + if (right->u.unary_expression.type != UNARY_STRING) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + right, "Invalid `encoding` attribute in integer field class: " + "expecting unary string."); + ret = -EINVAL; + goto error; + } + + s_right = ctf_ast_concatenate_unary_strings(&expression->u.ctf_expression.right); + if (!s_right) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + right, + "Unexpected unary expression for integer field class's `encoding` attribute."); + ret = -EINVAL; + goto error; + } + + if (strcmp(s_right, "UTF8") == 0 || strcmp(s_right, "utf8") == 0 || + strcmp(s_right, "utf-8") == 0 || strcmp(s_right, "UTF-8") == 0 || + strcmp(s_right, "ASCII") == 0 || strcmp(s_right, "ascii") == 0) { + encoding = CTF_ENCODING_UTF8; + } else if (strcmp(s_right, "none") == 0) { + encoding = CTF_ENCODING_NONE; + } else { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + right, + "Invalid `encoding` attribute in integer field class: " + "unknown encoding: encoding=\"%s\"", + s_right); + g_free(s_right); + ret = -EINVAL; + goto error; + } + + g_free(s_right); + _SET(&set, _INTEGER_ENCODING_SET); + } else if (strcmp(left->u.unary_expression.u.string, "map") == 0) { + const char *clock_name; + + if (_IS_SET(&set, _INTEGER_MAP_SET)) { + _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(left, "map", "integer field class"); + ret = -EPERM; + goto error; + } + + if (right->u.unary_expression.type != UNARY_STRING) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(right, + "Invalid `map` attribute in integer field class: " + "expecting unary string."); + ret = -EINVAL; + goto error; + } + + clock_name = get_map_clock_name_value(&expression->u.ctf_expression.right); + if (!clock_name) { + char *s_right = + ctf_ast_concatenate_unary_strings(&expression->u.ctf_expression.right); + + if (!s_right) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + right, + "Unexpected unary expression for integer field class's `map` attribute."); + ret = -EINVAL; + goto error; + } + + _BT_COMP_LOGE_NODE(right, + "Invalid `map` attribute in integer field class: " + "cannot find clock class at this point: name=\"%s\"", + s_right); + _SET(&set, _INTEGER_MAP_SET); + g_free(s_right); + continue; + } + + mapped_clock_class = + ctf_trace_class_borrow_clock_class_by_name(ctx->ctf_tc, clock_name); + if (!mapped_clock_class) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + right, + "Invalid `map` attribute in integer field class: " + "cannot find clock class at this point: name=\"%s\"", + clock_name); + ret = -EINVAL; + goto error; + } + + _SET(&set, _INTEGER_MAP_SET); + } else { + _BT_COMP_LOGW_NODE(left, + "Unknown attribute in integer field class: " + "attr-name=\"%s\"", + left->u.unary_expression.u.string); + } + } + + if (!_IS_SET(&set, _INTEGER_SIZE_SET)) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Missing `size` attribute in integer field class."); + ret = -EPERM; + goto error; + } + + if (!_IS_SET(&set, _INTEGER_ALIGN_SET)) { + if (size % CHAR_BIT) { + /* Bit-packed alignment */ + alignment = 1; + } else { + /* Byte-packed alignment */ + alignment = CHAR_BIT; + } + } + + *integer_decl = ctf_field_class_int_create(); + BT_ASSERT(*integer_decl); + (*integer_decl)->base.base.alignment = alignment; + (*integer_decl)->base.byte_order = byte_order; + (*integer_decl)->base.size = size; + (*integer_decl)->is_signed = (signedness > 0); + (*integer_decl)->disp_base = base; + (*integer_decl)->encoding = encoding; + (*integer_decl)->mapped_clock_class = mapped_clock_class; + return 0; error: - ctf_field_class_destroy(&(*integer_decl)->base.base); - *integer_decl = NULL; - return ret; + ctf_field_class_destroy(&(*integer_decl)->base.base); + *integer_decl = NULL; + return ret; } -static -int visit_floating_point_number_decl(struct ctf_visitor_generate_ir *ctx, - struct bt_list_head *expressions, - struct ctf_field_class_float **float_decl) +static int visit_floating_point_number_decl(struct ctf_visitor_generate_ir *ctx, + struct bt_list_head *expressions, + struct ctf_field_class_float **float_decl) { - int set = 0; - int ret = 0; - struct ctf_node *expression; - uint64_t alignment = 1, exp_dig = 0, mant_dig = 0; - enum ctf_byte_order byte_order = ctx->ctf_tc->default_byte_order; - - *float_decl = NULL; - - bt_list_for_each_entry(expression, expressions, siblings) { - struct ctf_node *left, *right; - - left = _BT_LIST_FIRST_ENTRY(&expression->u.ctf_expression.left, - struct ctf_node, siblings); - right = _BT_LIST_FIRST_ENTRY( - &expression->u.ctf_expression.right, struct ctf_node, - siblings); - - if (left->u.unary_expression.type != UNARY_STRING) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(left, - "Unexpected unary expression type: type=%d", - left->u.unary_expression.type); - ret = -EINVAL; - goto error; - } - - if (strcmp(left->u.unary_expression.u.string, "byte_order") == 0) { - if (_IS_SET(&set, _FLOAT_BYTE_ORDER_SET)) { - _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(left, "byte_order", - "floating point number field class"); - ret = -EPERM; - goto error; - } - - byte_order = get_real_byte_order(ctx, right); - if (byte_order == CTF_BYTE_ORDER_UNKNOWN) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(right, - "Invalid `byte_order` attribute in floating point number field class: " - "ret=%d", ret); - ret = -EINVAL; - goto error; - } - - _SET(&set, _FLOAT_BYTE_ORDER_SET); - } else if (strcmp(left->u.unary_expression.u.string, "exp_dig") == 0) { - if (_IS_SET(&set, _FLOAT_EXP_DIG_SET)) { - _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(left, "exp_dig", - "floating point number field class"); - ret = -EPERM; - goto error; - } - - if (right->u.unary_expression.type != - UNARY_UNSIGNED_CONSTANT) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(right, - "Invalid `exp_dig` attribute in floating point number field class: " - "expecting unsigned constant integer: " - "node-type=%d", - right->u.unary_expression.type); - ret = -EINVAL; - goto error; - } - - exp_dig = right->u.unary_expression.u.unsigned_constant; - _SET(&set, _FLOAT_EXP_DIG_SET); - } else if (strcmp(left->u.unary_expression.u.string, "mant_dig") == 0) { - if (_IS_SET(&set, _FLOAT_MANT_DIG_SET)) { - _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(left, "mant_dig", - "floating point number field class"); - ret = -EPERM; - goto error; - } - - if (right->u.unary_expression.type != - UNARY_UNSIGNED_CONSTANT) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(right, - "Invalid `mant_dig` attribute in floating point number field class: " - "expecting unsigned constant integer: " - "node-type=%d", - right->u.unary_expression.type); - ret = -EINVAL; - goto error; - } - - mant_dig = right->u.unary_expression.u. - unsigned_constant; - _SET(&set, _FLOAT_MANT_DIG_SET); - } else if (strcmp(left->u.unary_expression.u.string, "align") == 0) { - if (_IS_SET(&set, _FLOAT_ALIGN_SET)) { - _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(left, "align", - "floating point number field class"); - ret = -EPERM; - goto error; - } - - if (right->u.unary_expression.type != - UNARY_UNSIGNED_CONSTANT) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(right, - "Invalid `align` attribute in floating point number field class: " - "expecting unsigned constant integer: " - "node-type=%d", - right->u.unary_expression.type); - ret = -EINVAL; - goto error; - } - - alignment = right->u.unary_expression.u. - unsigned_constant; - - if (!is_align_valid(alignment)) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(right, - "Invalid `align` attribute in floating point number field class: " - "expecting power of two: " - "align=%" PRIu64, alignment); - ret = -EINVAL; - goto error; - } - - _SET(&set, _FLOAT_ALIGN_SET); - } else { - _BT_COMP_LOGW_NODE(left, - "Unknown attribute in floating point number field class: " - "attr-name=\"%s\"", - left->u.unary_expression.u.string); - } - } - - if (!_IS_SET(&set, _FLOAT_MANT_DIG_SET)) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Missing `mant_dig` attribute in floating point number field class."); - ret = -EPERM; - goto error; - } - - if (!_IS_SET(&set, _FLOAT_EXP_DIG_SET)) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Missing `exp_dig` attribute in floating point number field class."); - ret = -EPERM; - goto error; - } - - if (mant_dig != 24 && mant_dig != 53) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("`mant_dig` attribute: expecting 24 or 53."); - ret = -EPERM; - goto error; - } - - if (mant_dig == 24 && exp_dig != 8) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("`exp_dig` attribute: expecting 8 because `mant_dig` is 24."); - ret = -EPERM; - goto error; - } - - if (mant_dig == 53 && exp_dig != 11) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("`exp_dig` attribute: expecting 11 because `mant_dig` is 53."); - ret = -EPERM; - goto error; - } - - if (!_IS_SET(&set, _INTEGER_ALIGN_SET)) { - if ((mant_dig + exp_dig) % CHAR_BIT) { - /* Bit-packed alignment */ - alignment = 1; - } else { - /* Byte-packed alignment */ - alignment = CHAR_BIT; - } - } - - *float_decl = ctf_field_class_float_create(); - BT_ASSERT(*float_decl); - (*float_decl)->base.base.alignment = alignment; - (*float_decl)->base.byte_order = byte_order; - (*float_decl)->base.size = mant_dig + exp_dig; - return 0; + int set = 0; + int ret = 0; + struct ctf_node *expression; + uint64_t alignment = 1, exp_dig = 0, mant_dig = 0; + enum ctf_byte_order byte_order = ctx->ctf_tc->default_byte_order; + + *float_decl = NULL; + + bt_list_for_each_entry (expression, expressions, siblings) { + struct ctf_node *left, *right; + + left = _BT_LIST_FIRST_ENTRY(&expression->u.ctf_expression.left, struct ctf_node, siblings); + right = + _BT_LIST_FIRST_ENTRY(&expression->u.ctf_expression.right, struct ctf_node, siblings); + + if (left->u.unary_expression.type != UNARY_STRING) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(left, "Unexpected unary expression type: type=%d", + left->u.unary_expression.type); + ret = -EINVAL; + goto error; + } + + if (strcmp(left->u.unary_expression.u.string, "byte_order") == 0) { + if (_IS_SET(&set, _FLOAT_BYTE_ORDER_SET)) { + _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(left, "byte_order", + "floating point number field class"); + ret = -EPERM; + goto error; + } + + byte_order = get_real_byte_order(ctx, right); + if (byte_order == CTF_BYTE_ORDER_UNKNOWN) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + right, + "Invalid `byte_order` attribute in floating point number field class: " + "ret=%d", + ret); + ret = -EINVAL; + goto error; + } + + _SET(&set, _FLOAT_BYTE_ORDER_SET); + } else if (strcmp(left->u.unary_expression.u.string, "exp_dig") == 0) { + if (_IS_SET(&set, _FLOAT_EXP_DIG_SET)) { + _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(left, "exp_dig", + "floating point number field class"); + ret = -EPERM; + goto error; + } + + if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + right, + "Invalid `exp_dig` attribute in floating point number field class: " + "expecting unsigned constant integer: " + "node-type=%d", + right->u.unary_expression.type); + ret = -EINVAL; + goto error; + } + + exp_dig = right->u.unary_expression.u.unsigned_constant; + _SET(&set, _FLOAT_EXP_DIG_SET); + } else if (strcmp(left->u.unary_expression.u.string, "mant_dig") == 0) { + if (_IS_SET(&set, _FLOAT_MANT_DIG_SET)) { + _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(left, "mant_dig", + "floating point number field class"); + ret = -EPERM; + goto error; + } + + if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + right, + "Invalid `mant_dig` attribute in floating point number field class: " + "expecting unsigned constant integer: " + "node-type=%d", + right->u.unary_expression.type); + ret = -EINVAL; + goto error; + } + + mant_dig = right->u.unary_expression.u.unsigned_constant; + _SET(&set, _FLOAT_MANT_DIG_SET); + } else if (strcmp(left->u.unary_expression.u.string, "align") == 0) { + if (_IS_SET(&set, _FLOAT_ALIGN_SET)) { + _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(left, "align", + "floating point number field class"); + ret = -EPERM; + goto error; + } + + if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + right, + "Invalid `align` attribute in floating point number field class: " + "expecting unsigned constant integer: " + "node-type=%d", + right->u.unary_expression.type); + ret = -EINVAL; + goto error; + } + + alignment = right->u.unary_expression.u.unsigned_constant; + + if (!is_align_valid(alignment)) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + right, + "Invalid `align` attribute in floating point number field class: " + "expecting power of two: " + "align=%" PRIu64, + alignment); + ret = -EINVAL; + goto error; + } + + _SET(&set, _FLOAT_ALIGN_SET); + } else { + _BT_COMP_LOGW_NODE(left, + "Unknown attribute in floating point number field class: " + "attr-name=\"%s\"", + left->u.unary_expression.u.string); + } + } + + if (!_IS_SET(&set, _FLOAT_MANT_DIG_SET)) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Missing `mant_dig` attribute in floating point number field class."); + ret = -EPERM; + goto error; + } + + if (!_IS_SET(&set, _FLOAT_EXP_DIG_SET)) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Missing `exp_dig` attribute in floating point number field class."); + ret = -EPERM; + goto error; + } + + if (mant_dig != 24 && mant_dig != 53) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("`mant_dig` attribute: expecting 24 or 53."); + ret = -EPERM; + goto error; + } + + if (mant_dig == 24 && exp_dig != 8) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "`exp_dig` attribute: expecting 8 because `mant_dig` is 24."); + ret = -EPERM; + goto error; + } + + if (mant_dig == 53 && exp_dig != 11) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "`exp_dig` attribute: expecting 11 because `mant_dig` is 53."); + ret = -EPERM; + goto error; + } + + if (!_IS_SET(&set, _INTEGER_ALIGN_SET)) { + if ((mant_dig + exp_dig) % CHAR_BIT) { + /* Bit-packed alignment */ + alignment = 1; + } else { + /* Byte-packed alignment */ + alignment = CHAR_BIT; + } + } + + *float_decl = ctf_field_class_float_create(); + BT_ASSERT(*float_decl); + (*float_decl)->base.base.alignment = alignment; + (*float_decl)->base.byte_order = byte_order; + (*float_decl)->base.size = mant_dig + exp_dig; + return 0; error: - ctf_field_class_destroy(&(*float_decl)->base.base); - *float_decl = NULL; - return ret; + ctf_field_class_destroy(&(*float_decl)->base.base); + *float_decl = NULL; + return ret; } -static -int visit_string_decl(struct ctf_visitor_generate_ir *ctx, - struct bt_list_head *expressions, - struct ctf_field_class_string **string_decl) +static int visit_string_decl(struct ctf_visitor_generate_ir *ctx, struct bt_list_head *expressions, + struct ctf_field_class_string **string_decl) { - int set = 0; - int ret = 0; - struct ctf_node *expression; - enum ctf_encoding encoding = CTF_ENCODING_UTF8; - - *string_decl = NULL; - - bt_list_for_each_entry(expression, expressions, siblings) { - struct ctf_node *left, *right; - - left = _BT_LIST_FIRST_ENTRY(&expression->u.ctf_expression.left, - struct ctf_node, siblings); - right = _BT_LIST_FIRST_ENTRY( - &expression->u.ctf_expression.right, struct ctf_node, - siblings); - - if (left->u.unary_expression.type != UNARY_STRING) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(left, - "Unexpected unary expression type: type=%d", - left->u.unary_expression.type); - ret = -EINVAL; - goto error; - } - - if (strcmp(left->u.unary_expression.u.string, "encoding") == 0) { - char *s_right; - - if (_IS_SET(&set, _STRING_ENCODING_SET)) { - _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(left, "encoding", - "string field class"); - ret = -EPERM; - goto error; - } - - if (right->u.unary_expression.type != UNARY_STRING) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(right, - "Invalid `encoding` attribute in string field class: " - "expecting unary string."); - ret = -EINVAL; - goto error; - } - - s_right = ctf_ast_concatenate_unary_strings( - &expression->u.ctf_expression.right); - if (!s_right) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(right, - "Unexpected unary expression for string field class's `encoding` attribute."); - ret = -EINVAL; - goto error; - } - - if (strcmp(s_right, "UTF8") == 0 || - strcmp(s_right, "utf8") == 0 || - strcmp(s_right, "utf-8") == 0 || - strcmp(s_right, "UTF-8") == 0 || - strcmp(s_right, "ASCII") == 0 || - strcmp(s_right, "ascii") == 0) { - encoding = CTF_ENCODING_UTF8; - } else if (strcmp(s_right, "none") == 0) { - encoding = CTF_ENCODING_NONE; - } else { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(right, - "Invalid `encoding` attribute in string field class: " - "unknown encoding: encoding=\"%s\"", - s_right); - g_free(s_right); - ret = -EINVAL; - goto error; - } - - g_free(s_right); - _SET(&set, _STRING_ENCODING_SET); - } else { - _BT_COMP_LOGW_NODE(left, - "Unknown attribute in string field class: " - "attr-name=\"%s\"", - left->u.unary_expression.u.string); - } - } - - *string_decl = ctf_field_class_string_create(); - BT_ASSERT(*string_decl); - (*string_decl)->encoding = encoding; - return 0; + int set = 0; + int ret = 0; + struct ctf_node *expression; + enum ctf_encoding encoding = CTF_ENCODING_UTF8; + + *string_decl = NULL; + + bt_list_for_each_entry (expression, expressions, siblings) { + struct ctf_node *left, *right; + + left = _BT_LIST_FIRST_ENTRY(&expression->u.ctf_expression.left, struct ctf_node, siblings); + right = + _BT_LIST_FIRST_ENTRY(&expression->u.ctf_expression.right, struct ctf_node, siblings); + + if (left->u.unary_expression.type != UNARY_STRING) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(left, "Unexpected unary expression type: type=%d", + left->u.unary_expression.type); + ret = -EINVAL; + goto error; + } + + if (strcmp(left->u.unary_expression.u.string, "encoding") == 0) { + char *s_right; + + if (_IS_SET(&set, _STRING_ENCODING_SET)) { + _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(left, "encoding", "string field class"); + ret = -EPERM; + goto error; + } + + if (right->u.unary_expression.type != UNARY_STRING) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + right, "Invalid `encoding` attribute in string field class: " + "expecting unary string."); + ret = -EINVAL; + goto error; + } + + s_right = ctf_ast_concatenate_unary_strings(&expression->u.ctf_expression.right); + if (!s_right) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + right, + "Unexpected unary expression for string field class's `encoding` attribute."); + ret = -EINVAL; + goto error; + } + + if (strcmp(s_right, "UTF8") == 0 || strcmp(s_right, "utf8") == 0 || + strcmp(s_right, "utf-8") == 0 || strcmp(s_right, "UTF-8") == 0 || + strcmp(s_right, "ASCII") == 0 || strcmp(s_right, "ascii") == 0) { + encoding = CTF_ENCODING_UTF8; + } else if (strcmp(s_right, "none") == 0) { + encoding = CTF_ENCODING_NONE; + } else { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + right, + "Invalid `encoding` attribute in string field class: " + "unknown encoding: encoding=\"%s\"", + s_right); + g_free(s_right); + ret = -EINVAL; + goto error; + } + + g_free(s_right); + _SET(&set, _STRING_ENCODING_SET); + } else { + _BT_COMP_LOGW_NODE(left, + "Unknown attribute in string field class: " + "attr-name=\"%s\"", + left->u.unary_expression.u.string); + } + } + + *string_decl = ctf_field_class_string_create(); + BT_ASSERT(*string_decl); + (*string_decl)->encoding = encoding; + return 0; error: - ctf_field_class_destroy(&(*string_decl)->base); - *string_decl = NULL; - return ret; + ctf_field_class_destroy(&(*string_decl)->base); + *string_decl = NULL; + return ret; } -static -int visit_field_class_specifier_list(struct ctf_visitor_generate_ir *ctx, - struct ctf_node *ts_list, struct ctf_field_class **decl) +static int visit_field_class_specifier_list(struct ctf_visitor_generate_ir *ctx, + struct ctf_node *ts_list, struct ctf_field_class **decl) { - int ret = 0; - struct ctf_node *first, *node; - - *decl = NULL; - - if (ts_list->type != NODE_TYPE_SPECIFIER_LIST) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(ts_list, - "Unexpected node type: node-type=%d", ts_list->type); - ret = -EINVAL; - goto error; - } - - first = _BT_LIST_FIRST_ENTRY(&ts_list->u.field_class_specifier_list.head, - struct ctf_node, siblings); - if (first->type != NODE_TYPE_SPECIFIER) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(first, - "Unexpected node type: node-type=%d", first->type); - ret = -EINVAL; - goto error; - } - - node = first->u.field_class_specifier.node; - - switch (first->u.field_class_specifier.type) { - case TYPESPEC_INTEGER: { - ctf_field_class_int *int_decl; - - ret = visit_integer_decl(ctx, &node->u.integer.expressions, - &int_decl); - if (ret) { - BT_ASSERT(!int_decl); - goto error; - } - - *decl = &int_decl->base.base; - break; - } - case TYPESPEC_FLOATING_POINT: { - ctf_field_class_float *float_decl; - - ret = visit_floating_point_number_decl(ctx, - &node->u.floating_point.expressions, &float_decl); - if (ret) { - BT_ASSERT(!float_decl); - goto error; - } - - *decl = &float_decl->base.base; - break; - } - case TYPESPEC_STRING: { - ctf_field_class_string *string_decl; - - ret = visit_string_decl(ctx, - &node->u.string.expressions, &string_decl); - if (ret) { - BT_ASSERT(!string_decl); - goto error; - } - - *decl = &string_decl->base; - break; - } - case TYPESPEC_STRUCT: { - ctf_field_class_struct *struct_decl; - - ret = visit_struct_decl(ctx, node->u._struct.name, - &node->u._struct.declaration_list, - node->u._struct.has_body, - &node->u._struct.min_align, &struct_decl); - if (ret) { - BT_ASSERT(!struct_decl); - goto error; - } - - *decl = &struct_decl->base; - break; - } - case TYPESPEC_VARIANT: { - ctf_field_class_variant *variant_decl; - - ret = visit_variant_decl(ctx, node->u.variant.name, - node->u.variant.choice, - &node->u.variant.declaration_list, - node->u.variant.has_body, &variant_decl); - if (ret) { - BT_ASSERT(!variant_decl); - goto error; - } - - *decl = &variant_decl->base; - break; - } - case TYPESPEC_ENUM: { - ctf_field_class_enum *enum_decl; - - ret = visit_enum_decl(ctx, node->u._enum.enum_id, - node->u._enum.container_field_class, - &node->u._enum.enumerator_list, - node->u._enum.has_body, &enum_decl); - if (ret) { - BT_ASSERT(!enum_decl); - goto error; - } - - *decl = &enum_decl->base.base.base; - break; - } - case TYPESPEC_VOID: - case TYPESPEC_CHAR: - case TYPESPEC_SHORT: - case TYPESPEC_INT: - case TYPESPEC_LONG: - case TYPESPEC_FLOAT: - case TYPESPEC_DOUBLE: - case TYPESPEC_SIGNED: - case TYPESPEC_UNSIGNED: - case TYPESPEC_BOOL: - case TYPESPEC_COMPLEX: - case TYPESPEC_IMAGINARY: - case TYPESPEC_CONST: - case TYPESPEC_ID_TYPE: - ret = visit_field_class_specifier(ctx, ts_list, decl); - if (ret) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(first, - "Cannot visit field class specifier: ret=%d", - ret); - BT_ASSERT(!*decl); - goto error; - } - break; - default: - _BT_COMP_LOGE_APPEND_CAUSE_NODE(first, - "Unexpected field class specifier type: node-type=%d", - first->u.field_class_specifier.type); - ret = -EINVAL; - goto error; - } - - BT_ASSERT(*decl); - return 0; + int ret = 0; + struct ctf_node *first, *node; + + *decl = NULL; + + if (ts_list->type != NODE_TYPE_SPECIFIER_LIST) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(ts_list, "Unexpected node type: node-type=%d", + ts_list->type); + ret = -EINVAL; + goto error; + } + + first = _BT_LIST_FIRST_ENTRY(&ts_list->u.field_class_specifier_list.head, struct ctf_node, + siblings); + if (first->type != NODE_TYPE_SPECIFIER) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(first, "Unexpected node type: node-type=%d", first->type); + ret = -EINVAL; + goto error; + } + + node = first->u.field_class_specifier.node; + + switch (first->u.field_class_specifier.type) { + case TYPESPEC_INTEGER: + { + ctf_field_class_int *int_decl; + + ret = visit_integer_decl(ctx, &node->u.integer.expressions, &int_decl); + if (ret) { + BT_ASSERT(!int_decl); + goto error; + } + + *decl = &int_decl->base.base; + break; + } + case TYPESPEC_FLOATING_POINT: + { + ctf_field_class_float *float_decl; + + ret = + visit_floating_point_number_decl(ctx, &node->u.floating_point.expressions, &float_decl); + if (ret) { + BT_ASSERT(!float_decl); + goto error; + } + + *decl = &float_decl->base.base; + break; + } + case TYPESPEC_STRING: + { + ctf_field_class_string *string_decl; + + ret = visit_string_decl(ctx, &node->u.string.expressions, &string_decl); + if (ret) { + BT_ASSERT(!string_decl); + goto error; + } + + *decl = &string_decl->base; + break; + } + case TYPESPEC_STRUCT: + { + ctf_field_class_struct *struct_decl; + + ret = visit_struct_decl(ctx, node->u._struct.name, &node->u._struct.declaration_list, + node->u._struct.has_body, &node->u._struct.min_align, &struct_decl); + if (ret) { + BT_ASSERT(!struct_decl); + goto error; + } + + *decl = &struct_decl->base; + break; + } + case TYPESPEC_VARIANT: + { + ctf_field_class_variant *variant_decl; + + ret = visit_variant_decl(ctx, node->u.variant.name, node->u.variant.choice, + &node->u.variant.declaration_list, node->u.variant.has_body, + &variant_decl); + if (ret) { + BT_ASSERT(!variant_decl); + goto error; + } + + *decl = &variant_decl->base; + break; + } + case TYPESPEC_ENUM: + { + ctf_field_class_enum *enum_decl; + + ret = visit_enum_decl(ctx, node->u._enum.enum_id, node->u._enum.container_field_class, + &node->u._enum.enumerator_list, node->u._enum.has_body, &enum_decl); + if (ret) { + BT_ASSERT(!enum_decl); + goto error; + } + + *decl = &enum_decl->base.base.base; + break; + } + case TYPESPEC_VOID: + case TYPESPEC_CHAR: + case TYPESPEC_SHORT: + case TYPESPEC_INT: + case TYPESPEC_LONG: + case TYPESPEC_FLOAT: + case TYPESPEC_DOUBLE: + case TYPESPEC_SIGNED: + case TYPESPEC_UNSIGNED: + case TYPESPEC_BOOL: + case TYPESPEC_COMPLEX: + case TYPESPEC_IMAGINARY: + case TYPESPEC_CONST: + case TYPESPEC_ID_TYPE: + ret = visit_field_class_specifier(ctx, ts_list, decl); + if (ret) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(first, "Cannot visit field class specifier: ret=%d", + ret); + BT_ASSERT(!*decl); + goto error; + } + break; + default: + _BT_COMP_LOGE_APPEND_CAUSE_NODE(first, + "Unexpected field class specifier type: node-type=%d", + first->u.field_class_specifier.type); + ret = -EINVAL; + goto error; + } + + BT_ASSERT(*decl); + return 0; error: - ctf_field_class_destroy(*decl); - *decl = NULL; - return ret; + ctf_field_class_destroy(*decl); + *decl = NULL; + return ret; } -static -int visit_event_decl_entry(struct ctf_visitor_generate_ir *ctx, struct ctf_node *node, - struct ctf_event_class *event_class, uint64_t *stream_id, - int *set) +static int visit_event_decl_entry(struct ctf_visitor_generate_ir *ctx, struct ctf_node *node, + struct ctf_event_class *event_class, uint64_t *stream_id, + int *set) { - int ret = 0; - char *left = NULL; - - switch (node->type) { - case NODE_TYPEDEF: - ret = visit_field_class_def(ctx, node->u.field_class_def.field_class_specifier_list, - &node->u.field_class_def.field_class_declarators); - if (ret) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, - "Cannot add field class found in event class."); - goto error; - } - break; - case NODE_TYPEALIAS: - ret = visit_field_class_alias(ctx, node->u.field_class_alias.target, - node->u.field_class_alias.alias); - if (ret) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, - "Cannot add field class alias found in event class."); - goto error; - } - break; - case NODE_CTF_EXPRESSION: - { - left = ctf_ast_concatenate_unary_strings(&node->u.ctf_expression.left); - if (!left) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Cannot concatenate unary strings."); - ret = -EINVAL; - goto error; - } - - if (strcmp(left, "name") == 0) { - /* This is already known at this stage */ - if (_IS_SET(set, _EVENT_NAME_SET)) { - _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(node, "name", "event class"); - ret = -EPERM; - goto error; - } - - _SET(set, _EVENT_NAME_SET); - } else if (strcmp(left, "id") == 0) { - int64_t id = -1; - - if (_IS_SET(set, _EVENT_ID_SET)) { - _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(node, "id", "event class"); - ret = -EPERM; - goto error; - } - - ret = get_unary_unsigned(ctx, - &node->u.ctf_expression.right, - (uint64_t *) &id); - /* Only read "id" if get_unary_unsigned() succeeded. */ - if (ret || (!ret && id < 0)) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, - "Unexpected unary expression for event class's `id` attribute."); - ret = -EINVAL; - goto error; - } - - event_class->id = id; - _SET(set, _EVENT_ID_SET); - } else if (strcmp(left, "stream_id") == 0) { - if (_IS_SET(set, _EVENT_STREAM_ID_SET)) { - _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(node, "stream_id", - "event class"); - ret = -EPERM; - goto error; - } - - ret = get_unary_unsigned(ctx, - &node->u.ctf_expression.right, stream_id); - - /* - * Only read "stream_id" if get_unary_unsigned() - * succeeded. - */ - if (ret) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, - "Unexpected unary expression for event class's `stream_id` attribute."); - ret = -EINVAL; - goto error; - } - - _SET(set, _EVENT_STREAM_ID_SET); - } else if (strcmp(left, "context") == 0) { - if (_IS_SET(set, _EVENT_CONTEXT_SET)) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, - "Duplicate `context` entry in event class."); - ret = -EPERM; - goto error; - } - - ret = visit_field_class_specifier_list(ctx, - _BT_LIST_FIRST_ENTRY( - &node->u.ctf_expression.right, - struct ctf_node, siblings), - &event_class->spec_context_fc); - if (ret) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, - "Cannot create event class's context field class."); - goto error; - } - - BT_ASSERT(event_class->spec_context_fc); - _SET(set, _EVENT_CONTEXT_SET); - } else if (strcmp(left, "fields") == 0) { - if (_IS_SET(set, _EVENT_FIELDS_SET)) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, - "Duplicate `fields` entry in event class."); - ret = -EPERM; - goto error; - } - - ret = visit_field_class_specifier_list(ctx, - _BT_LIST_FIRST_ENTRY( - &node->u.ctf_expression.right, - struct ctf_node, siblings), - &event_class->payload_fc); - if (ret) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, - "Cannot create event class's payload field class."); - goto error; - } - - BT_ASSERT(event_class->payload_fc); - _SET(set, _EVENT_FIELDS_SET); - } else if (strcmp(left, "loglevel") == 0) { - uint64_t loglevel_value; - bool is_log_level_known = true; - bt_event_class_log_level log_level; - - if (_IS_SET(set, _EVENT_LOG_LEVEL_SET)) { - _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(node, "loglevel", - "event class"); - ret = -EPERM; - goto error; - } - - ret = get_unary_unsigned(ctx, - &node->u.ctf_expression.right, &loglevel_value); - if (ret) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, - "Unexpected unary expression for event class's `loglevel` attribute."); - ret = -EINVAL; - goto error; - } - - switch (loglevel_value) { - case 0: - log_level = BT_EVENT_CLASS_LOG_LEVEL_EMERGENCY; - break; - case 1: - log_level = BT_EVENT_CLASS_LOG_LEVEL_ALERT; - break; - case 2: - log_level = BT_EVENT_CLASS_LOG_LEVEL_CRITICAL; - break; - case 3: - log_level = BT_EVENT_CLASS_LOG_LEVEL_ERROR; - break; - case 4: - log_level = BT_EVENT_CLASS_LOG_LEVEL_WARNING; - break; - case 5: - log_level = BT_EVENT_CLASS_LOG_LEVEL_NOTICE; - break; - case 6: - log_level = BT_EVENT_CLASS_LOG_LEVEL_INFO; - break; - case 7: - log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_SYSTEM; - break; - case 8: - log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROGRAM; - break; - case 9: - log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROCESS; - break; - case 10: - log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_MODULE; - break; - case 11: - log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_UNIT; - break; - case 12: - log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_FUNCTION; - break; - case 13: - log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_LINE; - break; - case 14: - log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG; - break; - default: - is_log_level_known = false; - _BT_COMP_LOGW_NODE(node, "Not setting event class's log level because its value is unknown: " - "log-level=%" PRIu64, loglevel_value); - } - - if (is_log_level_known) { - ctf_event_class_set_log_level(event_class, log_level); - } - - _SET(set, _EVENT_LOG_LEVEL_SET); - } else if (strcmp(left, "model.emf.uri") == 0) { - char *right; - - if (_IS_SET(set, _EVENT_MODEL_EMF_URI_SET)) { - _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(node, "model.emf.uri", - "event class"); - ret = -EPERM; - goto error; - } - - right = ctf_ast_concatenate_unary_strings( - &node->u.ctf_expression.right); - if (!right) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, - "Unexpected unary expression for event class's `model.emf.uri` attribute."); - ret = -EINVAL; - goto error; - } - - if (strlen(right) == 0) { - _BT_COMP_LOGW_NODE(node, - "Not setting event class's EMF URI because it's empty."); - } else { - g_string_assign(event_class->emf_uri, - right); - } - - g_free(right); - _SET(set, _EVENT_MODEL_EMF_URI_SET); - } else { - _BT_COMP_LOGW_NODE(node, - "Unknown attribute in event class: " - "attr-name=\"%s\"", left); - } - - g_free(left); - left = NULL; - break; - } - default: - ret = -EPERM; - goto error; - } - - goto end; + int ret = 0; + char *left = NULL; + + switch (node->type) { + case NODE_TYPEDEF: + ret = visit_field_class_def(ctx, node->u.field_class_def.field_class_specifier_list, + &node->u.field_class_def.field_class_declarators); + if (ret) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Cannot add field class found in event class."); + goto error; + } + break; + case NODE_TYPEALIAS: + ret = visit_field_class_alias(ctx, node->u.field_class_alias.target, + node->u.field_class_alias.alias); + if (ret) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, + "Cannot add field class alias found in event class."); + goto error; + } + break; + case NODE_CTF_EXPRESSION: + { + left = ctf_ast_concatenate_unary_strings(&node->u.ctf_expression.left); + if (!left) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Cannot concatenate unary strings."); + ret = -EINVAL; + goto error; + } + + if (strcmp(left, "name") == 0) { + /* This is already known at this stage */ + if (_IS_SET(set, _EVENT_NAME_SET)) { + _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(node, "name", "event class"); + ret = -EPERM; + goto error; + } + + _SET(set, _EVENT_NAME_SET); + } else if (strcmp(left, "id") == 0) { + int64_t id = -1; + + if (_IS_SET(set, _EVENT_ID_SET)) { + _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(node, "id", "event class"); + ret = -EPERM; + goto error; + } + + ret = get_unary_unsigned(ctx, &node->u.ctf_expression.right, (uint64_t *) &id); + /* Only read "id" if get_unary_unsigned() succeeded. */ + if (ret || (!ret && id < 0)) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + node, "Unexpected unary expression for event class's `id` attribute."); + ret = -EINVAL; + goto error; + } + + event_class->id = id; + _SET(set, _EVENT_ID_SET); + } else if (strcmp(left, "stream_id") == 0) { + if (_IS_SET(set, _EVENT_STREAM_ID_SET)) { + _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(node, "stream_id", "event class"); + ret = -EPERM; + goto error; + } + + ret = get_unary_unsigned(ctx, &node->u.ctf_expression.right, stream_id); + + /* + * Only read "stream_id" if get_unary_unsigned() + * succeeded. + */ + if (ret) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + node, "Unexpected unary expression for event class's `stream_id` attribute."); + ret = -EINVAL; + goto error; + } + + _SET(set, _EVENT_STREAM_ID_SET); + } else if (strcmp(left, "context") == 0) { + if (_IS_SET(set, _EVENT_CONTEXT_SET)) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Duplicate `context` entry in event class."); + ret = -EPERM; + goto error; + } + + ret = visit_field_class_specifier_list( + ctx, _BT_LIST_FIRST_ENTRY(&node->u.ctf_expression.right, struct ctf_node, siblings), + &event_class->spec_context_fc); + if (ret) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, + "Cannot create event class's context field class."); + goto error; + } + + BT_ASSERT(event_class->spec_context_fc); + _SET(set, _EVENT_CONTEXT_SET); + } else if (strcmp(left, "fields") == 0) { + if (_IS_SET(set, _EVENT_FIELDS_SET)) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Duplicate `fields` entry in event class."); + ret = -EPERM; + goto error; + } + + ret = visit_field_class_specifier_list( + ctx, _BT_LIST_FIRST_ENTRY(&node->u.ctf_expression.right, struct ctf_node, siblings), + &event_class->payload_fc); + if (ret) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, + "Cannot create event class's payload field class."); + goto error; + } + + BT_ASSERT(event_class->payload_fc); + _SET(set, _EVENT_FIELDS_SET); + } else if (strcmp(left, "loglevel") == 0) { + uint64_t loglevel_value; + bool is_log_level_known = true; + bt_event_class_log_level log_level; + + if (_IS_SET(set, _EVENT_LOG_LEVEL_SET)) { + _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(node, "loglevel", "event class"); + ret = -EPERM; + goto error; + } + + ret = get_unary_unsigned(ctx, &node->u.ctf_expression.right, &loglevel_value); + if (ret) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + node, "Unexpected unary expression for event class's `loglevel` attribute."); + ret = -EINVAL; + goto error; + } + + switch (loglevel_value) { + case 0: + log_level = BT_EVENT_CLASS_LOG_LEVEL_EMERGENCY; + break; + case 1: + log_level = BT_EVENT_CLASS_LOG_LEVEL_ALERT; + break; + case 2: + log_level = BT_EVENT_CLASS_LOG_LEVEL_CRITICAL; + break; + case 3: + log_level = BT_EVENT_CLASS_LOG_LEVEL_ERROR; + break; + case 4: + log_level = BT_EVENT_CLASS_LOG_LEVEL_WARNING; + break; + case 5: + log_level = BT_EVENT_CLASS_LOG_LEVEL_NOTICE; + break; + case 6: + log_level = BT_EVENT_CLASS_LOG_LEVEL_INFO; + break; + case 7: + log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_SYSTEM; + break; + case 8: + log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROGRAM; + break; + case 9: + log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROCESS; + break; + case 10: + log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_MODULE; + break; + case 11: + log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_UNIT; + break; + case 12: + log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_FUNCTION; + break; + case 13: + log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_LINE; + break; + case 14: + log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG; + break; + default: + is_log_level_known = false; + _BT_COMP_LOGW_NODE( + node, + "Not setting event class's log level because its value is unknown: " + "log-level=%" PRIu64, + loglevel_value); + } + + if (is_log_level_known) { + ctf_event_class_set_log_level(event_class, log_level); + } + + _SET(set, _EVENT_LOG_LEVEL_SET); + } else if (strcmp(left, "model.emf.uri") == 0) { + char *right; + + if (_IS_SET(set, _EVENT_MODEL_EMF_URI_SET)) { + _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(node, "model.emf.uri", "event class"); + ret = -EPERM; + goto error; + } + + right = ctf_ast_concatenate_unary_strings(&node->u.ctf_expression.right); + if (!right) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + node, + "Unexpected unary expression for event class's `model.emf.uri` attribute."); + ret = -EINVAL; + goto error; + } + + if (strlen(right) == 0) { + _BT_COMP_LOGW_NODE(node, "Not setting event class's EMF URI because it's empty."); + } else { + g_string_assign(event_class->emf_uri, right); + } + + g_free(right); + _SET(set, _EVENT_MODEL_EMF_URI_SET); + } else { + _BT_COMP_LOGW_NODE(node, + "Unknown attribute in event class: " + "attr-name=\"%s\"", + left); + } + + g_free(left); + left = NULL; + break; + } + default: + ret = -EPERM; + goto error; + } + + goto end; error: - g_free(left); + g_free(left); end: - return ret; + return ret; } -static -char *get_event_decl_name(struct ctf_visitor_generate_ir *ctx, struct ctf_node *node) +static char *get_event_decl_name(struct ctf_visitor_generate_ir *ctx, struct ctf_node *node) { - char *left = NULL; - char *name = NULL; - struct ctf_node *iter; - struct bt_list_head *decl_list = &node->u.event.declaration_list; - - bt_list_for_each_entry(iter, decl_list, siblings) { - if (iter->type != NODE_CTF_EXPRESSION) { - continue; - } - - left = ctf_ast_concatenate_unary_strings(&iter->u.ctf_expression.left); - if (!left) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter, - "Cannot concatenate unary strings."); - goto error; - } - - if (strcmp(left, "name") == 0) { - name = ctf_ast_concatenate_unary_strings( - &iter->u.ctf_expression.right); - if (!name) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter, - "Unexpected unary expression for event class's `name` attribute."); - goto error; - } - } - - g_free(left); - left = NULL; - - if (name) { - break; - } - } - - return name; + char *left = NULL; + char *name = NULL; + struct ctf_node *iter; + struct bt_list_head *decl_list = &node->u.event.declaration_list; + + bt_list_for_each_entry (iter, decl_list, siblings) { + if (iter->type != NODE_CTF_EXPRESSION) { + continue; + } + + left = ctf_ast_concatenate_unary_strings(&iter->u.ctf_expression.left); + if (!left) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter, "Cannot concatenate unary strings."); + goto error; + } + + if (strcmp(left, "name") == 0) { + name = ctf_ast_concatenate_unary_strings(&iter->u.ctf_expression.right); + if (!name) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + iter, "Unexpected unary expression for event class's `name` attribute."); + goto error; + } + } + + g_free(left); + left = NULL; + + if (name) { + break; + } + } + + return name; error: - g_free(left); - return NULL; + g_free(left); + return NULL; } -static -int visit_event_decl(struct ctf_visitor_generate_ir *ctx, struct ctf_node *node) +static int visit_event_decl(struct ctf_visitor_generate_ir *ctx, struct ctf_node *node) { - int ret = 0; - int set = 0; - struct ctf_node *iter; - uint64_t stream_id = 0; - char *event_name = NULL; - struct ctf_event_class *event_class = NULL; - struct ctf_stream_class *stream_class = NULL; - struct bt_list_head *decl_list = &node->u.event.declaration_list; - bool pop_scope = false; - - if (node->visited) { - goto end; - } - - node->visited = TRUE; - event_name = get_event_decl_name(ctx, node); - if (!event_name) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, - "Missing `name` attribute in event class."); - ret = -EPERM; - goto error; - } - - event_class = ctf_event_class_create(); - BT_ASSERT(event_class); - g_string_assign(event_class->name, event_name); - _TRY_PUSH_SCOPE_OR_GOTO_ERROR(); - pop_scope = true; - - bt_list_for_each_entry(iter, decl_list, siblings) { - ret = visit_event_decl_entry(ctx, iter, event_class, - &stream_id, &set); - if (ret) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter, "Cannot visit event class's entry: " - "ret=%d", ret); - goto error; - } - } - - if (!_IS_SET(&set, _EVENT_STREAM_ID_SET)) { - /* - * Allow missing stream_id if there is only a single - * stream class. - */ - switch (ctx->ctf_tc->stream_classes->len) { - case 0: - /* Create implicit stream class if there's none */ - stream_id = 0; - stream_class = ctf_stream_class_create(); - BT_ASSERT(stream_class); - stream_class->id = stream_id; - g_ptr_array_add(ctx->ctf_tc->stream_classes, - stream_class); - break; - case 1: - /* Single stream class: get its ID */ - stream_class = (ctf_stream_class *) ctx->ctf_tc->stream_classes->pdata[0]; - stream_id = stream_class->id; - break; - default: - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, - "Missing `stream_id` attribute in event class."); - ret = -EPERM; - goto error; - } - } - - /* We have the stream ID now; get the stream class if found */ - if (!stream_class) { - stream_class = ctf_trace_class_borrow_stream_class_by_id( - ctx->ctf_tc, stream_id); - if (!stream_class) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, - "Cannot find stream class at this point: " - "id=%" PRId64, stream_id); - ret = -EINVAL; - goto error; - } - } - - BT_ASSERT(stream_class); - - if (!_IS_SET(&set, _EVENT_ID_SET)) { - /* Allow only one event without ID per stream */ - if (stream_class->event_classes->len != 0) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, - "Missing `id` attribute in event class."); - ret = -EPERM; - goto error; - } - - /* Automatic ID */ - event_class->id = 0; - } - - if (ctf_stream_class_borrow_event_class_by_id(stream_class, - event_class->id)) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, - "Duplicate event class (same ID) in the same stream class: " - "id=%" PRId64, event_class->id); - ret = -EEXIST; - goto error; - } - - ctf_stream_class_append_event_class(stream_class, event_class); - event_class = NULL; - goto end; + int ret = 0; + int set = 0; + struct ctf_node *iter; + uint64_t stream_id = 0; + char *event_name = NULL; + struct ctf_event_class *event_class = NULL; + struct ctf_stream_class *stream_class = NULL; + struct bt_list_head *decl_list = &node->u.event.declaration_list; + bool pop_scope = false; + + if (node->visited) { + goto end; + } + + node->visited = TRUE; + event_name = get_event_decl_name(ctx, node); + if (!event_name) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Missing `name` attribute in event class."); + ret = -EPERM; + goto error; + } + + event_class = ctf_event_class_create(); + BT_ASSERT(event_class); + g_string_assign(event_class->name, event_name); + _TRY_PUSH_SCOPE_OR_GOTO_ERROR(); + pop_scope = true; + + bt_list_for_each_entry (iter, decl_list, siblings) { + ret = visit_event_decl_entry(ctx, iter, event_class, &stream_id, &set); + if (ret) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter, + "Cannot visit event class's entry: " + "ret=%d", + ret); + goto error; + } + } + + if (!_IS_SET(&set, _EVENT_STREAM_ID_SET)) { + /* + * Allow missing stream_id if there is only a single + * stream class. + */ + switch (ctx->ctf_tc->stream_classes->len) { + case 0: + /* Create implicit stream class if there's none */ + stream_id = 0; + stream_class = ctf_stream_class_create(); + BT_ASSERT(stream_class); + stream_class->id = stream_id; + g_ptr_array_add(ctx->ctf_tc->stream_classes, stream_class); + break; + case 1: + /* Single stream class: get its ID */ + stream_class = (ctf_stream_class *) ctx->ctf_tc->stream_classes->pdata[0]; + stream_id = stream_class->id; + break; + default: + _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Missing `stream_id` attribute in event class."); + ret = -EPERM; + goto error; + } + } + + /* We have the stream ID now; get the stream class if found */ + if (!stream_class) { + stream_class = ctf_trace_class_borrow_stream_class_by_id(ctx->ctf_tc, stream_id); + if (!stream_class) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, + "Cannot find stream class at this point: " + "id=%" PRId64, + stream_id); + ret = -EINVAL; + goto error; + } + } + + BT_ASSERT(stream_class); + + if (!_IS_SET(&set, _EVENT_ID_SET)) { + /* Allow only one event without ID per stream */ + if (stream_class->event_classes->len != 0) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Missing `id` attribute in event class."); + ret = -EPERM; + goto error; + } + + /* Automatic ID */ + event_class->id = 0; + } + + if (ctf_stream_class_borrow_event_class_by_id(stream_class, event_class->id)) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, + "Duplicate event class (same ID) in the same stream class: " + "id=%" PRId64, + event_class->id); + ret = -EEXIST; + goto error; + } + + ctf_stream_class_append_event_class(stream_class, event_class); + event_class = NULL; + goto end; error: - ctf_event_class_destroy(event_class); - event_class = NULL; + ctf_event_class_destroy(event_class); + event_class = NULL; - if (ret >= 0) { - ret = -1; - } + if (ret >= 0) { + ret = -1; + } end: - if (pop_scope) { - ctx_pop_scope(ctx); - } + if (pop_scope) { + ctx_pop_scope(ctx); + } - g_free(event_name); + g_free(event_name); - return ret; + return ret; } -static -int auto_map_field_to_trace_clock_class(struct ctf_visitor_generate_ir *ctx, - struct ctf_field_class *fc) +static int auto_map_field_to_trace_clock_class(struct ctf_visitor_generate_ir *ctx, + struct ctf_field_class *fc) { - struct ctf_clock_class *clock_class_to_map_to = NULL; - struct ctf_field_class_int *int_fc = ctf_field_class_as_int(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 = ctf_clock_class_create(); - BT_ASSERT(clock_class_to_map_to); - clock_class_to_map_to->frequency = UINT64_C(1000000000); - g_string_assign(clock_class_to_map_to->name, "default"); - BT_ASSERT(ret == 0); - g_ptr_array_add(ctx->ctf_tc->clock_classes, - 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 = (ctf_clock_class *) ctx->ctf_tc->clock_classes->pdata[0]; - 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_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("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; + struct ctf_clock_class *clock_class_to_map_to = NULL; + struct ctf_field_class_int *int_fc = ctf_field_class_as_int(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 = ctf_clock_class_create(); + BT_ASSERT(clock_class_to_map_to); + clock_class_to_map_to->frequency = UINT64_C(1000000000); + g_string_assign(clock_class_to_map_to->name, "default"); + BT_ASSERT(ret == 0); + g_ptr_array_add(ctx->ctf_tc->clock_classes, 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 = (ctf_clock_class *) ctx->ctf_tc->clock_classes->pdata[0]; + 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_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "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; end: - return ret; + return ret; } -static -int auto_map_fields_to_trace_clock_class(struct ctf_visitor_generate_ir *ctx, - struct ctf_field_class *root_fc, const char *field_name) +static int auto_map_fields_to_trace_clock_class(struct ctf_visitor_generate_ir *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 = (ctf_field_class_struct *) root_fc; - struct ctf_field_class_variant *var_fc = (ctf_field_class_variant *) 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); - } else { - bt_common_abort(); - } - - if (strcmp(named_fc->name->str, field_name) == 0) { - ret = auto_map_field_to_trace_clock_class(ctx, - named_fc->fc); - if (ret) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("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_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("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; - } - } + int ret = 0; + uint64_t i, count; + struct ctf_field_class_struct *struct_fc = (ctf_field_class_struct *) root_fc; + struct ctf_field_class_variant *var_fc = (ctf_field_class_variant *) 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); + } else { + bt_common_abort(); + } + + if (strcmp(named_fc->name->str, field_name) == 0) { + ret = auto_map_field_to_trace_clock_class(ctx, named_fc->fc); + if (ret) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "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_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "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: - return ret; + return ret; } -static -int visit_stream_decl_entry(struct ctf_visitor_generate_ir *ctx, struct ctf_node *node, - struct ctf_stream_class *stream_class, int *set) +static int visit_stream_decl_entry(struct ctf_visitor_generate_ir *ctx, struct ctf_node *node, + struct ctf_stream_class *stream_class, int *set) { - int ret = 0; - char *left = NULL; - - switch (node->type) { - case NODE_TYPEDEF: - ret = visit_field_class_def(ctx, node->u.field_class_def.field_class_specifier_list, - &node->u.field_class_def.field_class_declarators); - if (ret) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, - "Cannot add field class found in stream class."); - goto error; - } - break; - case NODE_TYPEALIAS: - ret = visit_field_class_alias(ctx, node->u.field_class_alias.target, - node->u.field_class_alias.alias); - if (ret) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, - "Cannot add field class alias found in stream class."); - goto error; - } - break; - case NODE_CTF_EXPRESSION: - { - left = ctf_ast_concatenate_unary_strings(&node->u.ctf_expression.left); - if (!left) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Cannot concatenate unary strings."); - ret = -EINVAL; - goto error; - } - - if (strcmp(left, "id") == 0) { - int64_t id; - - if (_IS_SET(set, _STREAM_ID_SET)) { - _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(node, "id", - "stream declaration"); - ret = -EPERM; - goto error; - } - - ret = get_unary_unsigned(ctx, - &node->u.ctf_expression.right, - (uint64_t *) &id); - - /* Only read "id" if get_unary_unsigned() succeeded. */ - if (ret || (!ret && id < 0)) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, - "Unexpected unary expression for stream class's `id` attribute."); - ret = -EINVAL; - goto error; - } - - if (ctf_trace_class_borrow_stream_class_by_id( - ctx->ctf_tc, id)) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, - "Duplicate stream class (same ID): id=%" PRId64, - id); - ret = -EEXIST; - goto error; - } - - stream_class->id = id; - _SET(set, _STREAM_ID_SET); - } else if (strcmp(left, "event.header") == 0) { - if (_IS_SET(set, _STREAM_EVENT_HEADER_SET)) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, - "Duplicate `event.header` entry in stream class."); - ret = -EPERM; - goto error; - } - - ret = visit_field_class_specifier_list(ctx, - _BT_LIST_FIRST_ENTRY( - &node->u.ctf_expression.right, - struct ctf_node, siblings), - &stream_class->event_header_fc); - if (ret) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, - "Cannot create stream class's event header field class."); - goto error; - } - - BT_ASSERT(stream_class->event_header_fc); - ret = auto_map_fields_to_trace_clock_class(ctx, - stream_class->event_header_fc, "timestamp"); - if (ret) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, - "Cannot automatically map specific event header field class fields named `timestamp` to trace's clock class."); - goto error; - } - - _SET(set, _STREAM_EVENT_HEADER_SET); - } else if (strcmp(left, "event.context") == 0) { - if (_IS_SET(set, _STREAM_EVENT_CONTEXT_SET)) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, - "Duplicate `event.context` entry in stream class."); - ret = -EPERM; - goto error; - } - - ret = visit_field_class_specifier_list(ctx, - _BT_LIST_FIRST_ENTRY( - &node->u.ctf_expression.right, - struct ctf_node, siblings), - &stream_class->event_common_context_fc); - if (ret) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, - "Cannot create stream class's event context field class."); - goto error; - } - - BT_ASSERT(stream_class->event_common_context_fc); - _SET(set, _STREAM_EVENT_CONTEXT_SET); - } else if (strcmp(left, "packet.context") == 0) { - if (_IS_SET(set, _STREAM_PACKET_CONTEXT_SET)) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, - "Duplicate `packet.context` entry in stream class."); - ret = -EPERM; - goto error; - } - - ret = visit_field_class_specifier_list(ctx, - _BT_LIST_FIRST_ENTRY( - &node->u.ctf_expression.right, - struct ctf_node, siblings), - &stream_class->packet_context_fc); - if (ret) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, - "Cannot create stream class's packet context field class."); - goto error; - } - - BT_ASSERT(stream_class->packet_context_fc); - ret = auto_map_fields_to_trace_clock_class(ctx, - stream_class->packet_context_fc, - "timestamp_begin"); - if (ret) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, - "Cannot automatically map specific packet context field class fields named `timestamp_begin` to trace's clock class."); - goto error; - } - - ret = auto_map_fields_to_trace_clock_class(ctx, - stream_class->packet_context_fc, - "timestamp_end"); - if (ret) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, - "Cannot automatically map specific packet context field class fields named `timestamp_end` to trace's clock class."); - goto error; - } - - _SET(set, _STREAM_PACKET_CONTEXT_SET); - } else { - _BT_COMP_LOGW_NODE(node, - "Unknown attribute in stream class: " - "attr-name=\"%s\"", left); - } - - g_free(left); - left = NULL; - break; - } - - default: - ret = -EPERM; - goto error; - } - - return 0; + int ret = 0; + char *left = NULL; + + switch (node->type) { + case NODE_TYPEDEF: + ret = visit_field_class_def(ctx, node->u.field_class_def.field_class_specifier_list, + &node->u.field_class_def.field_class_declarators); + if (ret) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Cannot add field class found in stream class."); + goto error; + } + break; + case NODE_TYPEALIAS: + ret = visit_field_class_alias(ctx, node->u.field_class_alias.target, + node->u.field_class_alias.alias); + if (ret) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, + "Cannot add field class alias found in stream class."); + goto error; + } + break; + case NODE_CTF_EXPRESSION: + { + left = ctf_ast_concatenate_unary_strings(&node->u.ctf_expression.left); + if (!left) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Cannot concatenate unary strings."); + ret = -EINVAL; + goto error; + } + + if (strcmp(left, "id") == 0) { + int64_t id; + + if (_IS_SET(set, _STREAM_ID_SET)) { + _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(node, "id", "stream declaration"); + ret = -EPERM; + goto error; + } + + ret = get_unary_unsigned(ctx, &node->u.ctf_expression.right, (uint64_t *) &id); + + /* Only read "id" if get_unary_unsigned() succeeded. */ + if (ret || (!ret && id < 0)) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + node, "Unexpected unary expression for stream class's `id` attribute."); + ret = -EINVAL; + goto error; + } + + if (ctf_trace_class_borrow_stream_class_by_id(ctx->ctf_tc, id)) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + node, "Duplicate stream class (same ID): id=%" PRId64, id); + ret = -EEXIST; + goto error; + } + + stream_class->id = id; + _SET(set, _STREAM_ID_SET); + } else if (strcmp(left, "event.header") == 0) { + if (_IS_SET(set, _STREAM_EVENT_HEADER_SET)) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, + "Duplicate `event.header` entry in stream class."); + ret = -EPERM; + goto error; + } + + ret = visit_field_class_specifier_list( + ctx, _BT_LIST_FIRST_ENTRY(&node->u.ctf_expression.right, struct ctf_node, siblings), + &stream_class->event_header_fc); + if (ret) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + node, "Cannot create stream class's event header field class."); + goto error; + } + + BT_ASSERT(stream_class->event_header_fc); + ret = auto_map_fields_to_trace_clock_class(ctx, stream_class->event_header_fc, + "timestamp"); + if (ret) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + node, + "Cannot automatically map specific event header field class fields named `timestamp` to trace's clock class."); + goto error; + } + + _SET(set, _STREAM_EVENT_HEADER_SET); + } else if (strcmp(left, "event.context") == 0) { + if (_IS_SET(set, _STREAM_EVENT_CONTEXT_SET)) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, + "Duplicate `event.context` entry in stream class."); + ret = -EPERM; + goto error; + } + + ret = visit_field_class_specifier_list( + ctx, _BT_LIST_FIRST_ENTRY(&node->u.ctf_expression.right, struct ctf_node, siblings), + &stream_class->event_common_context_fc); + if (ret) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + node, "Cannot create stream class's event context field class."); + goto error; + } + + BT_ASSERT(stream_class->event_common_context_fc); + _SET(set, _STREAM_EVENT_CONTEXT_SET); + } else if (strcmp(left, "packet.context") == 0) { + if (_IS_SET(set, _STREAM_PACKET_CONTEXT_SET)) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + node, "Duplicate `packet.context` entry in stream class."); + ret = -EPERM; + goto error; + } + + ret = visit_field_class_specifier_list( + ctx, _BT_LIST_FIRST_ENTRY(&node->u.ctf_expression.right, struct ctf_node, siblings), + &stream_class->packet_context_fc); + if (ret) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + node, "Cannot create stream class's packet context field class."); + goto error; + } + + BT_ASSERT(stream_class->packet_context_fc); + ret = auto_map_fields_to_trace_clock_class(ctx, stream_class->packet_context_fc, + "timestamp_begin"); + if (ret) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + node, + "Cannot automatically map specific packet context field class fields named `timestamp_begin` to trace's clock class."); + goto error; + } + + ret = auto_map_fields_to_trace_clock_class(ctx, stream_class->packet_context_fc, + "timestamp_end"); + if (ret) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + node, + "Cannot automatically map specific packet context field class fields named `timestamp_end` to trace's clock class."); + goto error; + } + + _SET(set, _STREAM_PACKET_CONTEXT_SET); + } else { + _BT_COMP_LOGW_NODE(node, + "Unknown attribute in stream class: " + "attr-name=\"%s\"", + left); + } + + g_free(left); + left = NULL; + break; + } + + default: + ret = -EPERM; + goto error; + } + + return 0; error: - g_free(left); - return ret; + g_free(left); + return ret; } -static -int visit_stream_decl(struct ctf_visitor_generate_ir *ctx, struct ctf_node *node) +static int visit_stream_decl(struct ctf_visitor_generate_ir *ctx, struct ctf_node *node) { - int set = 0; - int ret = 0; - struct ctf_node *iter; - struct ctf_stream_class *stream_class = NULL; - struct bt_list_head *decl_list = &node->u.stream.declaration_list; - - if (node->visited) { - goto end; - } - - node->visited = TRUE; - stream_class = ctf_stream_class_create(); - BT_ASSERT(stream_class); - _TRY_PUSH_SCOPE_OR_GOTO_ERROR(); - - bt_list_for_each_entry(iter, decl_list, siblings) { - ret = visit_stream_decl_entry(ctx, iter, stream_class, &set); - if (ret) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter, - "Cannot visit stream class's entry: " - "ret=%d", ret); - ctx_pop_scope(ctx); - goto error; - } - } - - ctx_pop_scope(ctx); - - if (_IS_SET(&set, _STREAM_ID_SET)) { - /* Check that packet header has `stream_id` field */ - struct ctf_named_field_class *named_fc = NULL; - - if (!ctx->ctf_tc->packet_header_fc) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, - "Stream class has a `id` attribute, " - "but trace has no packet header field class."); - ret = -EINVAL; - goto error; - } - - named_fc = ctf_field_class_struct_borrow_member_by_name( - ctf_field_class_as_struct(ctx->ctf_tc->packet_header_fc), "stream_id"); - if (!named_fc) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, - "Stream class has a `id` attribute, " - "but trace's packet header field class has no `stream_id` field."); - ret = -EINVAL; - goto error; - } - - if (named_fc->fc->type != CTF_FIELD_CLASS_TYPE_INT && - named_fc->fc->type != CTF_FIELD_CLASS_TYPE_ENUM) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, - "Stream class has a `id` attribute, " - "but trace's packet header field class's `stream_id` field is not an integer field class."); - ret = -EINVAL; - goto error; - } - } else { - /* Allow only _one_ ID-less stream */ - if (ctx->ctf_tc->stream_classes->len != 0) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, - "Missing `id` attribute in stream class as there's more than one stream class in the trace."); - ret = -EPERM; - goto error; - } - - /* Automatic ID: 0 */ - stream_class->id = 0; - } - - /* - * Make sure that this stream class's ID is currently unique in - * the trace. - */ - if (ctf_trace_class_borrow_stream_class_by_id(ctx->ctf_tc, - stream_class->id)) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, - "Duplicate stream class (same ID): id=%" PRId64, - stream_class->id); - ret = -EINVAL; - goto error; - } - - g_ptr_array_add(ctx->ctf_tc->stream_classes, stream_class); - stream_class = NULL; - goto end; + int set = 0; + int ret = 0; + struct ctf_node *iter; + struct ctf_stream_class *stream_class = NULL; + struct bt_list_head *decl_list = &node->u.stream.declaration_list; + + if (node->visited) { + goto end; + } + + node->visited = TRUE; + stream_class = ctf_stream_class_create(); + BT_ASSERT(stream_class); + _TRY_PUSH_SCOPE_OR_GOTO_ERROR(); + + bt_list_for_each_entry (iter, decl_list, siblings) { + ret = visit_stream_decl_entry(ctx, iter, stream_class, &set); + if (ret) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter, + "Cannot visit stream class's entry: " + "ret=%d", + ret); + ctx_pop_scope(ctx); + goto error; + } + } + + ctx_pop_scope(ctx); + + if (_IS_SET(&set, _STREAM_ID_SET)) { + /* Check that packet header has `stream_id` field */ + struct ctf_named_field_class *named_fc = NULL; + + if (!ctx->ctf_tc->packet_header_fc) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Stream class has a `id` attribute, " + "but trace has no packet header field class."); + ret = -EINVAL; + goto error; + } + + named_fc = ctf_field_class_struct_borrow_member_by_name( + ctf_field_class_as_struct(ctx->ctf_tc->packet_header_fc), "stream_id"); + if (!named_fc) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + node, "Stream class has a `id` attribute, " + "but trace's packet header field class has no `stream_id` field."); + ret = -EINVAL; + goto error; + } + + if (named_fc->fc->type != CTF_FIELD_CLASS_TYPE_INT && + named_fc->fc->type != CTF_FIELD_CLASS_TYPE_ENUM) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + node, + "Stream class has a `id` attribute, " + "but trace's packet header field class's `stream_id` field is not an integer field class."); + ret = -EINVAL; + goto error; + } + } else { + /* Allow only _one_ ID-less stream */ + if (ctx->ctf_tc->stream_classes->len != 0) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + node, + "Missing `id` attribute in stream class as there's more than one stream class in the trace."); + ret = -EPERM; + goto error; + } + + /* Automatic ID: 0 */ + stream_class->id = 0; + } + + /* + * Make sure that this stream class's ID is currently unique in + * the trace. + */ + if (ctf_trace_class_borrow_stream_class_by_id(ctx->ctf_tc, stream_class->id)) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Duplicate stream class (same ID): id=%" PRId64, + stream_class->id); + ret = -EINVAL; + goto error; + } + + g_ptr_array_add(ctx->ctf_tc->stream_classes, stream_class); + stream_class = NULL; + goto end; error: - ctf_stream_class_destroy(stream_class); - stream_class = NULL; + ctf_stream_class_destroy(stream_class); + stream_class = NULL; end: - return ret; + return ret; } -static -int visit_trace_decl_entry(struct ctf_visitor_generate_ir *ctx, struct ctf_node *node, - int *set) +static int visit_trace_decl_entry(struct ctf_visitor_generate_ir *ctx, struct ctf_node *node, + int *set) { - int ret = 0; - char *left = NULL; - uint64_t val; - - switch (node->type) { - case NODE_TYPEDEF: - ret = visit_field_class_def(ctx, node->u.field_class_def.field_class_specifier_list, - &node->u.field_class_def.field_class_declarators); - if (ret) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, - "Cannot add field class found in trace (`trace` block)."); - goto error; - } - break; - case NODE_TYPEALIAS: - ret = visit_field_class_alias(ctx, node->u.field_class_alias.target, - node->u.field_class_alias.alias); - if (ret) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, - "Cannot add field class alias found in trace (`trace` block)."); - goto error; - } - break; - case NODE_CTF_EXPRESSION: - { - left = ctf_ast_concatenate_unary_strings(&node->u.ctf_expression.left); - if (!left) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Cannot concatenate unary strings."); - ret = -EINVAL; - goto error; - } - - if (strcmp(left, "major") == 0) { - if (_IS_SET(set, _TRACE_MAJOR_SET)) { - _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(node, "major", "trace"); - ret = -EPERM; - goto error; - } - - ret = get_unary_unsigned(ctx, - &node->u.ctf_expression.right, &val); - if (ret) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, - "Unexpected unary expression for trace's `major` attribute."); - ret = -EINVAL; - goto error; - } - - if (val != 1) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, - "Invalid trace's `minor` attribute: expecting 1."); - ret = -EINVAL; - goto error; - } - - ctx->ctf_tc->major = val; - _SET(set, _TRACE_MAJOR_SET); - } else if (strcmp(left, "minor") == 0) { - if (_IS_SET(set, _TRACE_MINOR_SET)) { - _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(node, "minor", "trace"); - ret = -EPERM; - goto error; - } - - ret = get_unary_unsigned(ctx, - &node->u.ctf_expression.right, &val); - if (ret) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, - "Unexpected unary expression for trace's `minor` attribute."); - ret = -EINVAL; - goto error; - } - - if (val != 8) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, - "Invalid trace's `minor` attribute: expecting 8."); - ret = -EINVAL; - goto error; - } - - ctx->ctf_tc->minor = val; - _SET(set, _TRACE_MINOR_SET); - } else if (strcmp(left, "uuid") == 0) { - if (_IS_SET(set, _TRACE_UUID_SET)) { - _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(node, "uuid", "trace"); - ret = -EPERM; - goto error; - } - - ret = get_unary_uuid(ctx, - &node->u.ctf_expression.right, - ctx->ctf_tc->uuid); - if (ret) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, - "Invalid trace's `uuid` attribute."); - goto error; - } - - ctx->ctf_tc->is_uuid_set = true; - _SET(set, _TRACE_UUID_SET); - } else if (strcmp(left, "byte_order") == 0) { - /* Default byte order is already known at this stage */ - if (_IS_SET(set, _TRACE_BYTE_ORDER_SET)) { - _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(node, "byte_order", - "trace"); - ret = -EPERM; - goto error; - } - - BT_ASSERT(ctx->ctf_tc->default_byte_order != CTF_BYTE_ORDER_UNKNOWN); - _SET(set, _TRACE_BYTE_ORDER_SET); - } else if (strcmp(left, "packet.header") == 0) { - if (_IS_SET(set, _TRACE_PACKET_HEADER_SET)) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, - "Duplicate `packet.header` entry in trace."); - ret = -EPERM; - goto error; - } - - ret = visit_field_class_specifier_list(ctx, - _BT_LIST_FIRST_ENTRY( - &node->u.ctf_expression.right, - struct ctf_node, siblings), - &ctx->ctf_tc->packet_header_fc); - if (ret) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, - "Cannot create trace's packet header field class."); - goto error; - } - - BT_ASSERT(ctx->ctf_tc->packet_header_fc); - _SET(set, _TRACE_PACKET_HEADER_SET); - } else { - _BT_COMP_LOGW_NODE(node, - "Unknown attribute in stream class: " - "attr-name=\"%s\"", left); - } - - g_free(left); - left = NULL; - break; - } - default: - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Unknown expression in trace."); - ret = -EINVAL; - goto error; - } - - return 0; + int ret = 0; + char *left = NULL; + uint64_t val; + + switch (node->type) { + case NODE_TYPEDEF: + ret = visit_field_class_def(ctx, node->u.field_class_def.field_class_specifier_list, + &node->u.field_class_def.field_class_declarators); + if (ret) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + node, "Cannot add field class found in trace (`trace` block)."); + goto error; + } + break; + case NODE_TYPEALIAS: + ret = visit_field_class_alias(ctx, node->u.field_class_alias.target, + node->u.field_class_alias.alias); + if (ret) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + node, "Cannot add field class alias found in trace (`trace` block)."); + goto error; + } + break; + case NODE_CTF_EXPRESSION: + { + left = ctf_ast_concatenate_unary_strings(&node->u.ctf_expression.left); + if (!left) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Cannot concatenate unary strings."); + ret = -EINVAL; + goto error; + } + + if (strcmp(left, "major") == 0) { + if (_IS_SET(set, _TRACE_MAJOR_SET)) { + _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(node, "major", "trace"); + ret = -EPERM; + goto error; + } + + ret = get_unary_unsigned(ctx, &node->u.ctf_expression.right, &val); + if (ret) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + node, "Unexpected unary expression for trace's `major` attribute."); + ret = -EINVAL; + goto error; + } + + if (val != 1) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, + "Invalid trace's `minor` attribute: expecting 1."); + ret = -EINVAL; + goto error; + } + + ctx->ctf_tc->major = val; + _SET(set, _TRACE_MAJOR_SET); + } else if (strcmp(left, "minor") == 0) { + if (_IS_SET(set, _TRACE_MINOR_SET)) { + _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(node, "minor", "trace"); + ret = -EPERM; + goto error; + } + + ret = get_unary_unsigned(ctx, &node->u.ctf_expression.right, &val); + if (ret) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + node, "Unexpected unary expression for trace's `minor` attribute."); + ret = -EINVAL; + goto error; + } + + if (val != 8) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, + "Invalid trace's `minor` attribute: expecting 8."); + ret = -EINVAL; + goto error; + } + + ctx->ctf_tc->minor = val; + _SET(set, _TRACE_MINOR_SET); + } else if (strcmp(left, "uuid") == 0) { + if (_IS_SET(set, _TRACE_UUID_SET)) { + _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(node, "uuid", "trace"); + ret = -EPERM; + goto error; + } + + ret = get_unary_uuid(ctx, &node->u.ctf_expression.right, ctx->ctf_tc->uuid); + if (ret) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Invalid trace's `uuid` attribute."); + goto error; + } + + ctx->ctf_tc->is_uuid_set = true; + _SET(set, _TRACE_UUID_SET); + } else if (strcmp(left, "byte_order") == 0) { + /* Default byte order is already known at this stage */ + if (_IS_SET(set, _TRACE_BYTE_ORDER_SET)) { + _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(node, "byte_order", "trace"); + ret = -EPERM; + goto error; + } + + BT_ASSERT(ctx->ctf_tc->default_byte_order != CTF_BYTE_ORDER_UNKNOWN); + _SET(set, _TRACE_BYTE_ORDER_SET); + } else if (strcmp(left, "packet.header") == 0) { + if (_IS_SET(set, _TRACE_PACKET_HEADER_SET)) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Duplicate `packet.header` entry in trace."); + ret = -EPERM; + goto error; + } + + ret = visit_field_class_specifier_list( + ctx, _BT_LIST_FIRST_ENTRY(&node->u.ctf_expression.right, struct ctf_node, siblings), + &ctx->ctf_tc->packet_header_fc); + if (ret) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, + "Cannot create trace's packet header field class."); + goto error; + } + + BT_ASSERT(ctx->ctf_tc->packet_header_fc); + _SET(set, _TRACE_PACKET_HEADER_SET); + } else { + _BT_COMP_LOGW_NODE(node, + "Unknown attribute in stream class: " + "attr-name=\"%s\"", + left); + } + + g_free(left); + left = NULL; + break; + } + default: + _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Unknown expression in trace."); + ret = -EINVAL; + goto error; + } + + return 0; error: - g_free(left); - return ret; + g_free(left); + return ret; } -static -int visit_trace_decl(struct ctf_visitor_generate_ir *ctx, struct ctf_node *node) +static int visit_trace_decl(struct ctf_visitor_generate_ir *ctx, struct ctf_node *node) { - int ret = 0; - int set = 0; - struct ctf_node *iter; - struct bt_list_head *decl_list = &node->u.trace.declaration_list; - - if (node->visited) { - goto end; - } - - node->visited = TRUE; - - if (ctx->is_trace_visited) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Duplicate trace (`trace` block)."); - ret = -EEXIST; - goto error; - } - - _TRY_PUSH_SCOPE_OR_GOTO_ERROR(); - - bt_list_for_each_entry(iter, decl_list, siblings) { - ret = visit_trace_decl_entry(ctx, iter, &set); - if (ret) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter, "Cannot visit trace's entry (`trace` block): " - "ret=%d", ret); - ctx_pop_scope(ctx); - goto error; - } - } - - ctx_pop_scope(ctx); - - if (!_IS_SET(&set, _TRACE_MAJOR_SET)) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, - "Missing `major` attribute in trace (`trace` block)."); - ret = -EPERM; - goto error; - } - - if (!_IS_SET(&set, _TRACE_MINOR_SET)) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, - "Missing `minor` attribute in trace (`trace` block)."); - ret = -EPERM; - goto error; - } - - if (!_IS_SET(&set, _TRACE_BYTE_ORDER_SET)) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, - "Missing `byte_order` attribute in trace (`trace` block)."); - ret = -EPERM; - goto error; - } - - ctx->is_trace_visited = true; + int ret = 0; + int set = 0; + struct ctf_node *iter; + struct bt_list_head *decl_list = &node->u.trace.declaration_list; + + if (node->visited) { + goto end; + } + + node->visited = TRUE; + + if (ctx->is_trace_visited) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Duplicate trace (`trace` block)."); + ret = -EEXIST; + goto error; + } + + _TRY_PUSH_SCOPE_OR_GOTO_ERROR(); + + bt_list_for_each_entry (iter, decl_list, siblings) { + ret = visit_trace_decl_entry(ctx, iter, &set); + if (ret) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter, + "Cannot visit trace's entry (`trace` block): " + "ret=%d", + ret); + ctx_pop_scope(ctx); + goto error; + } + } + + ctx_pop_scope(ctx); + + if (!_IS_SET(&set, _TRACE_MAJOR_SET)) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, + "Missing `major` attribute in trace (`trace` block)."); + ret = -EPERM; + goto error; + } + + if (!_IS_SET(&set, _TRACE_MINOR_SET)) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, + "Missing `minor` attribute in trace (`trace` block)."); + ret = -EPERM; + goto error; + } + + if (!_IS_SET(&set, _TRACE_BYTE_ORDER_SET)) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, + "Missing `byte_order` attribute in trace (`trace` block)."); + ret = -EPERM; + goto error; + } + + ctx->is_trace_visited = true; end: - return 0; + return 0; error: - return ret; + return ret; } -static -int visit_env(struct ctf_visitor_generate_ir *ctx, struct ctf_node *node) +static int visit_env(struct ctf_visitor_generate_ir *ctx, struct ctf_node *node) { - int ret = 0; - char *left = NULL; - struct ctf_node *entry_node; - struct bt_list_head *decl_list = &node->u.env.declaration_list; - - if (node->visited) { - goto end; - } - - node->visited = TRUE; - - bt_list_for_each_entry(entry_node, decl_list, siblings) { - struct bt_list_head *right_head = - &entry_node->u.ctf_expression.right; - - if (entry_node->type != NODE_CTF_EXPRESSION) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node, - "Wrong expression in environment entry: " - "node-type=%d", entry_node->type); - ret = -EPERM; - goto error; - } - - left = ctf_ast_concatenate_unary_strings( - &entry_node->u.ctf_expression.left); - if (!left) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node, - "Cannot get environment entry's name."); - ret = -EINVAL; - goto error; - } - - if (is_unary_string(right_head)) { - char *right = ctf_ast_concatenate_unary_strings(right_head); - - if (!right) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node, - "Unexpected unary expression for environment entry's value: " - "name=\"%s\"", left); - ret = -EINVAL; - goto error; - } - - if (strcmp(left, "tracer_name") == 0) { - if (strncmp(right, "lttng", 5) == 0) { - BT_COMP_LOGI("Detected LTTng trace from `%s` environment value: " - "tracer-name=\"%s\"", - left, right); - ctx->is_lttng = true; - } - } - - ctf_trace_class_append_env_entry(ctx->ctf_tc, - left, CTF_TRACE_CLASS_ENV_ENTRY_TYPE_STR, - right, 0); - g_free(right); - } else if (is_unary_unsigned(right_head) || - is_unary_signed(right_head)) { - int64_t v; - - if (is_unary_unsigned(right_head)) { - ret = get_unary_unsigned(ctx, right_head, - (uint64_t *) &v); - } else { - ret = get_unary_signed(right_head, &v); - } - if (ret) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node, - "Unexpected unary expression for environment entry's value: " - "name=\"%s\"", left); - ret = -EINVAL; - goto error; - } - - ctf_trace_class_append_env_entry(ctx->ctf_tc, - left, CTF_TRACE_CLASS_ENV_ENTRY_TYPE_INT, - NULL, v); - } else { - _BT_COMP_LOGW_NODE(entry_node, - "Environment entry has unknown type: " - "name=\"%s\"", left); - } - - g_free(left); - left = NULL; - } + int ret = 0; + char *left = NULL; + struct ctf_node *entry_node; + struct bt_list_head *decl_list = &node->u.env.declaration_list; + + if (node->visited) { + goto end; + } + + node->visited = TRUE; + + bt_list_for_each_entry (entry_node, decl_list, siblings) { + struct bt_list_head *right_head = &entry_node->u.ctf_expression.right; + + if (entry_node->type != NODE_CTF_EXPRESSION) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node, + "Wrong expression in environment entry: " + "node-type=%d", + entry_node->type); + ret = -EPERM; + goto error; + } + + left = ctf_ast_concatenate_unary_strings(&entry_node->u.ctf_expression.left); + if (!left) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node, "Cannot get environment entry's name."); + ret = -EINVAL; + goto error; + } + + if (is_unary_string(right_head)) { + char *right = ctf_ast_concatenate_unary_strings(right_head); + + if (!right) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + entry_node, + "Unexpected unary expression for environment entry's value: " + "name=\"%s\"", + left); + ret = -EINVAL; + goto error; + } + + if (strcmp(left, "tracer_name") == 0) { + if (strncmp(right, "lttng", 5) == 0) { + BT_COMP_LOGI("Detected LTTng trace from `%s` environment value: " + "tracer-name=\"%s\"", + left, right); + ctx->is_lttng = true; + } + } + + ctf_trace_class_append_env_entry(ctx->ctf_tc, left, CTF_TRACE_CLASS_ENV_ENTRY_TYPE_STR, + right, 0); + g_free(right); + } else if (is_unary_unsigned(right_head) || is_unary_signed(right_head)) { + int64_t v; + + if (is_unary_unsigned(right_head)) { + ret = get_unary_unsigned(ctx, right_head, (uint64_t *) &v); + } else { + ret = get_unary_signed(right_head, &v); + } + if (ret) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + entry_node, + "Unexpected unary expression for environment entry's value: " + "name=\"%s\"", + left); + ret = -EINVAL; + goto error; + } + + ctf_trace_class_append_env_entry(ctx->ctf_tc, left, CTF_TRACE_CLASS_ENV_ENTRY_TYPE_INT, + NULL, v); + } else { + _BT_COMP_LOGW_NODE(entry_node, + "Environment entry has unknown type: " + "name=\"%s\"", + left); + } + + g_free(left); + left = NULL; + } end: - return 0; + return 0; error: - g_free(left); - return ret; + g_free(left); + return ret; } -static -int set_trace_byte_order(struct ctf_visitor_generate_ir *ctx, struct ctf_node *trace_node) +static int set_trace_byte_order(struct ctf_visitor_generate_ir *ctx, struct ctf_node *trace_node) { - int ret = 0; - int set = 0; - char *left = NULL; - struct ctf_node *node; - struct bt_list_head *decl_list = &trace_node->u.trace.declaration_list; - - bt_list_for_each_entry(node, decl_list, siblings) { - if (node->type == NODE_CTF_EXPRESSION) { - struct ctf_node *right_node; - - left = ctf_ast_concatenate_unary_strings( - &node->u.ctf_expression.left); - if (!left) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, - "Cannot concatenate unary strings."); - ret = -EINVAL; - goto error; - } - - if (strcmp(left, "byte_order") == 0) { - enum ctf_byte_order bo; - - if (_IS_SET(&set, _TRACE_BYTE_ORDER_SET)) { - _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(node, "byte_order", - "trace"); - ret = -EPERM; - goto error; - } - - _SET(&set, _TRACE_BYTE_ORDER_SET); - right_node = _BT_LIST_FIRST_ENTRY( - &node->u.ctf_expression.right, - struct ctf_node, siblings); - bo = byte_order_from_unary_expr(ctx, - right_node); - if (bo == CTF_BYTE_ORDER_UNKNOWN) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, - "Invalid `byte_order` attribute in trace (`trace` block): " - "expecting `le`, `be`, or `network`."); - ret = -EINVAL; - goto error; - } else if (bo == CTF_BYTE_ORDER_DEFAULT) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, - "Invalid `byte_order` attribute in trace (`trace` block): " - "cannot be set to `native` here."); - ret = -EPERM; - goto error; - } - - ctx->ctf_tc->default_byte_order = bo; - } - - g_free(left); - left = NULL; - } - } - - if (!_IS_SET(&set, _TRACE_BYTE_ORDER_SET)) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(trace_node, - "Missing `byte_order` attribute in trace (`trace` block)."); - ret = -EINVAL; - goto error; - } - - return 0; + int ret = 0; + int set = 0; + char *left = NULL; + struct ctf_node *node; + struct bt_list_head *decl_list = &trace_node->u.trace.declaration_list; + + bt_list_for_each_entry (node, decl_list, siblings) { + if (node->type == NODE_CTF_EXPRESSION) { + struct ctf_node *right_node; + + left = ctf_ast_concatenate_unary_strings(&node->u.ctf_expression.left); + if (!left) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Cannot concatenate unary strings."); + ret = -EINVAL; + goto error; + } + + if (strcmp(left, "byte_order") == 0) { + enum ctf_byte_order bo; + + if (_IS_SET(&set, _TRACE_BYTE_ORDER_SET)) { + _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(node, "byte_order", "trace"); + ret = -EPERM; + goto error; + } + + _SET(&set, _TRACE_BYTE_ORDER_SET); + right_node = + _BT_LIST_FIRST_ENTRY(&node->u.ctf_expression.right, struct ctf_node, siblings); + bo = byte_order_from_unary_expr(ctx, right_node); + if (bo == CTF_BYTE_ORDER_UNKNOWN) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + node, "Invalid `byte_order` attribute in trace (`trace` block): " + "expecting `le`, `be`, or `network`."); + ret = -EINVAL; + goto error; + } else if (bo == CTF_BYTE_ORDER_DEFAULT) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + node, "Invalid `byte_order` attribute in trace (`trace` block): " + "cannot be set to `native` here."); + ret = -EPERM; + goto error; + } + + ctx->ctf_tc->default_byte_order = bo; + } + + g_free(left); + left = NULL; + } + } + + if (!_IS_SET(&set, _TRACE_BYTE_ORDER_SET)) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(trace_node, + "Missing `byte_order` attribute in trace (`trace` block)."); + ret = -EINVAL; + goto error; + } + + return 0; error: - g_free(left); - return ret; + g_free(left); + return ret; } -static -int visit_clock_decl_entry(struct ctf_visitor_generate_ir *ctx, struct ctf_node *entry_node, - struct ctf_clock_class *clock, int *set, int64_t *offset_seconds, - uint64_t *offset_cycles) +static int visit_clock_decl_entry(struct ctf_visitor_generate_ir *ctx, struct ctf_node *entry_node, + struct ctf_clock_class *clock, int *set, int64_t *offset_seconds, + uint64_t *offset_cycles) { - int ret = 0; - char *left = NULL; - - if (entry_node->type != NODE_CTF_EXPRESSION) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node, - "Unexpected node type: node-type=%d", - entry_node->type); - ret = -EPERM; - goto error; - } - - left = ctf_ast_concatenate_unary_strings(&entry_node->u.ctf_expression.left); - if (!left) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node, "Cannot concatenate unary strings."); - ret = -EINVAL; - goto error; - } - - if (strcmp(left, "name") == 0) { - char *right; - - if (_IS_SET(set, _CLOCK_NAME_SET)) { - _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(entry_node, "name", "clock class"); - ret = -EPERM; - goto error; - } - - right = ctf_ast_concatenate_unary_strings( - &entry_node->u.ctf_expression.right); - if (!right) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node, - "Unexpected unary expression for clock class's `name` attribute."); - ret = -EINVAL; - goto error; - } - - g_string_assign(clock->name, right); - g_free(right); - _SET(set, _CLOCK_NAME_SET); - } else if (strcmp(left, "uuid") == 0) { - bt_uuid_t uuid; - - if (_IS_SET(set, _CLOCK_UUID_SET)) { - _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(entry_node, "uuid", "clock class"); - ret = -EPERM; - goto error; - } - - ret = get_unary_uuid(ctx, &entry_node->u.ctf_expression.right, - uuid); - if (ret) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node, - "Invalid clock class's `uuid` attribute."); - goto error; - } - - clock->has_uuid = true; - bt_uuid_copy(clock->uuid, uuid); - _SET(set, _CLOCK_UUID_SET); - } else if (strcmp(left, "description") == 0) { - char *right; - - if (_IS_SET(set, _CLOCK_DESCRIPTION_SET)) { - _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(entry_node, "description", - "clock class"); - ret = -EPERM; - goto error; - } - - right = ctf_ast_concatenate_unary_strings( - &entry_node->u.ctf_expression.right); - if (!right) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node, - "Unexpected unary expression for clock class's `description` attribute."); - ret = -EINVAL; - goto error; - } - - g_string_assign(clock->description, right); - g_free(right); - _SET(set, _CLOCK_DESCRIPTION_SET); - } else if (strcmp(left, "freq") == 0) { - uint64_t freq = UINT64_C(-1); - - if (_IS_SET(set, _CLOCK_FREQ_SET)) { - _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(entry_node, "freq", "clock class"); - ret = -EPERM; - goto error; - } - - ret = get_unary_unsigned(ctx, - &entry_node->u.ctf_expression.right, &freq); - if (ret) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node, - "Unexpected unary expression for clock class's `freq` attribute."); - ret = -EINVAL; - goto error; - } - - if (freq == UINT64_C(-1) || freq == 0) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node, - "Invalid clock class frequency: freq=%" PRIu64, - freq); - ret = -EINVAL; - goto error; - } - - clock->frequency = freq; - _SET(set, _CLOCK_FREQ_SET); - } else if (strcmp(left, "precision") == 0) { - uint64_t precision; - - if (_IS_SET(set, _CLOCK_PRECISION_SET)) { - _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(entry_node, "precision", - "clock class"); - ret = -EPERM; - goto error; - } - - ret = get_unary_unsigned(ctx, - &entry_node->u.ctf_expression.right, &precision); - if (ret) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node, - "Unexpected unary expression for clock class's `precision` attribute."); - ret = -EINVAL; - goto error; - } - - clock->precision = precision; - _SET(set, _CLOCK_PRECISION_SET); - } else if (strcmp(left, "offset_s") == 0) { - if (_IS_SET(set, _CLOCK_OFFSET_S_SET)) { - _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(entry_node, "offset_s", - "clock class"); - ret = -EPERM; - goto error; - } - - ret = get_unary_signed( - &entry_node->u.ctf_expression.right, offset_seconds); - if (ret) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node, - "Unexpected unary expression for clock class's `offset_s` attribute."); - ret = -EINVAL; - goto error; - } - - _SET(set, _CLOCK_OFFSET_S_SET); - } else if (strcmp(left, "offset") == 0) { - if (_IS_SET(set, _CLOCK_OFFSET_SET)) { - _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(entry_node, "offset", "clock class"); - ret = -EPERM; - goto error; - } - - ret = get_unary_unsigned(ctx, - &entry_node->u.ctf_expression.right, offset_cycles); - if (ret) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node, - "Unexpected unary expression for clock class's `offset` attribute."); - ret = -EINVAL; - goto error; - } - - _SET(set, _CLOCK_OFFSET_SET); - } else if (strcmp(left, "absolute") == 0) { - struct ctf_node *right; - - if (_IS_SET(set, _CLOCK_ABSOLUTE_SET)) { - _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(entry_node, "absolute", - "clock class"); - ret = -EPERM; - goto error; - } - - right = _BT_LIST_FIRST_ENTRY( - &entry_node->u.ctf_expression.right, - struct ctf_node, siblings); - ret = get_boolean(ctx, right); - if (ret < 0) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node, - "Unexpected unary expression for clock class's `absolute` attribute."); - ret = -EINVAL; - goto error; - } - - clock->is_absolute = ret; - _SET(set, _CLOCK_ABSOLUTE_SET); - } else { - _BT_COMP_LOGW_NODE(entry_node, - "Unknown attribute in clock class: attr-name=\"%s\"", - left); - } - - g_free(left); - left = NULL; - return 0; + int ret = 0; + char *left = NULL; + + if (entry_node->type != NODE_CTF_EXPRESSION) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node, "Unexpected node type: node-type=%d", + entry_node->type); + ret = -EPERM; + goto error; + } + + left = ctf_ast_concatenate_unary_strings(&entry_node->u.ctf_expression.left); + if (!left) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node, "Cannot concatenate unary strings."); + ret = -EINVAL; + goto error; + } + + if (strcmp(left, "name") == 0) { + char *right; + + if (_IS_SET(set, _CLOCK_NAME_SET)) { + _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(entry_node, "name", "clock class"); + ret = -EPERM; + goto error; + } + + right = ctf_ast_concatenate_unary_strings(&entry_node->u.ctf_expression.right); + if (!right) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + entry_node, "Unexpected unary expression for clock class's `name` attribute."); + ret = -EINVAL; + goto error; + } + + g_string_assign(clock->name, right); + g_free(right); + _SET(set, _CLOCK_NAME_SET); + } else if (strcmp(left, "uuid") == 0) { + bt_uuid_t uuid; + + if (_IS_SET(set, _CLOCK_UUID_SET)) { + _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(entry_node, "uuid", "clock class"); + ret = -EPERM; + goto error; + } + + ret = get_unary_uuid(ctx, &entry_node->u.ctf_expression.right, uuid); + if (ret) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node, "Invalid clock class's `uuid` attribute."); + goto error; + } + + clock->has_uuid = true; + bt_uuid_copy(clock->uuid, uuid); + _SET(set, _CLOCK_UUID_SET); + } else if (strcmp(left, "description") == 0) { + char *right; + + if (_IS_SET(set, _CLOCK_DESCRIPTION_SET)) { + _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(entry_node, "description", "clock class"); + ret = -EPERM; + goto error; + } + + right = ctf_ast_concatenate_unary_strings(&entry_node->u.ctf_expression.right); + if (!right) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + entry_node, + "Unexpected unary expression for clock class's `description` attribute."); + ret = -EINVAL; + goto error; + } + + g_string_assign(clock->description, right); + g_free(right); + _SET(set, _CLOCK_DESCRIPTION_SET); + } else if (strcmp(left, "freq") == 0) { + uint64_t freq = UINT64_C(-1); + + if (_IS_SET(set, _CLOCK_FREQ_SET)) { + _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(entry_node, "freq", "clock class"); + ret = -EPERM; + goto error; + } + + ret = get_unary_unsigned(ctx, &entry_node->u.ctf_expression.right, &freq); + if (ret) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + entry_node, "Unexpected unary expression for clock class's `freq` attribute."); + ret = -EINVAL; + goto error; + } + + if (freq == UINT64_C(-1) || freq == 0) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node, + "Invalid clock class frequency: freq=%" PRIu64, freq); + ret = -EINVAL; + goto error; + } + + clock->frequency = freq; + _SET(set, _CLOCK_FREQ_SET); + } else if (strcmp(left, "precision") == 0) { + uint64_t precision; + + if (_IS_SET(set, _CLOCK_PRECISION_SET)) { + _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(entry_node, "precision", "clock class"); + ret = -EPERM; + goto error; + } + + ret = get_unary_unsigned(ctx, &entry_node->u.ctf_expression.right, &precision); + if (ret) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + entry_node, "Unexpected unary expression for clock class's `precision` attribute."); + ret = -EINVAL; + goto error; + } + + clock->precision = precision; + _SET(set, _CLOCK_PRECISION_SET); + } else if (strcmp(left, "offset_s") == 0) { + if (_IS_SET(set, _CLOCK_OFFSET_S_SET)) { + _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(entry_node, "offset_s", "clock class"); + ret = -EPERM; + goto error; + } + + ret = get_unary_signed(&entry_node->u.ctf_expression.right, offset_seconds); + if (ret) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + entry_node, "Unexpected unary expression for clock class's `offset_s` attribute."); + ret = -EINVAL; + goto error; + } + + _SET(set, _CLOCK_OFFSET_S_SET); + } else if (strcmp(left, "offset") == 0) { + if (_IS_SET(set, _CLOCK_OFFSET_SET)) { + _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(entry_node, "offset", "clock class"); + ret = -EPERM; + goto error; + } + + ret = get_unary_unsigned(ctx, &entry_node->u.ctf_expression.right, offset_cycles); + if (ret) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + entry_node, "Unexpected unary expression for clock class's `offset` attribute."); + ret = -EINVAL; + goto error; + } + + _SET(set, _CLOCK_OFFSET_SET); + } else if (strcmp(left, "absolute") == 0) { + struct ctf_node *right; + + if (_IS_SET(set, _CLOCK_ABSOLUTE_SET)) { + _BT_COMP_LOGE_APPEND_CAUSE_DUP_ATTR(entry_node, "absolute", "clock class"); + ret = -EPERM; + goto error; + } + + right = + _BT_LIST_FIRST_ENTRY(&entry_node->u.ctf_expression.right, struct ctf_node, siblings); + ret = get_boolean(ctx, right); + if (ret < 0) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + entry_node, "Unexpected unary expression for clock class's `absolute` attribute."); + ret = -EINVAL; + goto error; + } + + clock->is_absolute = ret; + _SET(set, _CLOCK_ABSOLUTE_SET); + } else { + _BT_COMP_LOGW_NODE(entry_node, "Unknown attribute in clock class: attr-name=\"%s\"", left); + } + + g_free(left); + left = NULL; + return 0; error: - g_free(left); - return ret; + g_free(left); + return ret; } -static inline -uint64_t cycles_from_ns(uint64_t frequency, uint64_t ns) +static inline uint64_t cycles_from_ns(uint64_t frequency, uint64_t ns) { - uint64_t cycles; + uint64_t cycles; - /* 1GHz */ - if (frequency == UINT64_C(1000000000)) { - cycles = ns; - } else { - cycles = (uint64_t) (((double) ns * (double) frequency) / 1e9); - } + /* 1GHz */ + if (frequency == UINT64_C(1000000000)) { + cycles = ns; + } else { + cycles = (uint64_t) (((double) ns * (double) frequency) / 1e9); + } - return cycles; + return cycles; } -static -void calibrate_clock_class_offsets(int64_t *offset_seconds, - uint64_t *offset_cycles, uint64_t freq) +static void calibrate_clock_class_offsets(int64_t *offset_seconds, uint64_t *offset_cycles, + uint64_t freq) { - if (*offset_cycles >= freq) { - const uint64_t s_in_offset_cycles = *offset_cycles / freq; + if (*offset_cycles >= freq) { + const uint64_t s_in_offset_cycles = *offset_cycles / freq; - *offset_seconds += (int64_t) s_in_offset_cycles; - *offset_cycles -= (s_in_offset_cycles * freq); - } + *offset_seconds += (int64_t) s_in_offset_cycles; + *offset_cycles -= (s_in_offset_cycles * freq); + } } -static -void apply_clock_class_is_absolute(struct ctf_visitor_generate_ir *ctx, - struct ctf_clock_class *clock) +static void apply_clock_class_is_absolute(struct ctf_visitor_generate_ir *ctx, + struct ctf_clock_class *clock) { - if (ctx->decoder_config.force_clock_class_origin_unix_epoch) { - clock->is_absolute = true; - } + if (ctx->decoder_config.force_clock_class_origin_unix_epoch) { + clock->is_absolute = true; + } - return; + return; } -static -void apply_clock_class_offset(struct ctf_visitor_generate_ir *ctx, - struct ctf_clock_class *clock) +static void apply_clock_class_offset(struct ctf_visitor_generate_ir *ctx, + struct ctf_clock_class *clock) { - uint64_t freq; - int64_t offset_s_to_apply = ctx->decoder_config.clock_class_offset_s; - uint64_t offset_ns_to_apply; - int64_t cur_offset_s; - uint64_t cur_offset_cycles; - - if (ctx->decoder_config.clock_class_offset_s == 0 && - ctx->decoder_config.clock_class_offset_ns == 0) { - goto end; - } - - /* Transfer nanoseconds to seconds as much as possible */ - if (ctx->decoder_config.clock_class_offset_ns < 0) { - const int64_t abs_ns = -ctx->decoder_config.clock_class_offset_ns; - const int64_t abs_extra_s = abs_ns / INT64_C(1000000000) + 1; - const int64_t extra_s = -abs_extra_s; - const int64_t offset_ns = ctx->decoder_config.clock_class_offset_ns - - (extra_s * INT64_C(1000000000)); - - BT_ASSERT(offset_ns > 0); - offset_ns_to_apply = (uint64_t) offset_ns; - offset_s_to_apply += extra_s; - } else { - const int64_t extra_s = ctx->decoder_config.clock_class_offset_ns / - INT64_C(1000000000); - const int64_t offset_ns = ctx->decoder_config.clock_class_offset_ns - - (extra_s * INT64_C(1000000000)); - - BT_ASSERT(offset_ns >= 0); - offset_ns_to_apply = (uint64_t) offset_ns; - offset_s_to_apply += extra_s; - } - - freq = clock->frequency; - cur_offset_s = clock->offset_seconds; - cur_offset_cycles = clock->offset_cycles; - - /* Apply offsets */ - cur_offset_s += offset_s_to_apply; - cur_offset_cycles += cycles_from_ns(freq, offset_ns_to_apply); - - /* - * Recalibrate offsets because the part in cycles can be greater - * than the frequency at this point. - */ - calibrate_clock_class_offsets(&cur_offset_s, &cur_offset_cycles, freq); - - /* Set final offsets */ - clock->offset_seconds = cur_offset_s; - clock->offset_cycles = cur_offset_cycles; + uint64_t freq; + int64_t offset_s_to_apply = ctx->decoder_config.clock_class_offset_s; + uint64_t offset_ns_to_apply; + int64_t cur_offset_s; + uint64_t cur_offset_cycles; + + if (ctx->decoder_config.clock_class_offset_s == 0 && + ctx->decoder_config.clock_class_offset_ns == 0) { + goto end; + } + + /* Transfer nanoseconds to seconds as much as possible */ + if (ctx->decoder_config.clock_class_offset_ns < 0) { + const int64_t abs_ns = -ctx->decoder_config.clock_class_offset_ns; + const int64_t abs_extra_s = abs_ns / INT64_C(1000000000) + 1; + const int64_t extra_s = -abs_extra_s; + const int64_t offset_ns = + ctx->decoder_config.clock_class_offset_ns - (extra_s * INT64_C(1000000000)); + + BT_ASSERT(offset_ns > 0); + offset_ns_to_apply = (uint64_t) offset_ns; + offset_s_to_apply += extra_s; + } else { + const int64_t extra_s = ctx->decoder_config.clock_class_offset_ns / INT64_C(1000000000); + const int64_t offset_ns = + ctx->decoder_config.clock_class_offset_ns - (extra_s * INT64_C(1000000000)); + + BT_ASSERT(offset_ns >= 0); + offset_ns_to_apply = (uint64_t) offset_ns; + offset_s_to_apply += extra_s; + } + + freq = clock->frequency; + cur_offset_s = clock->offset_seconds; + cur_offset_cycles = clock->offset_cycles; + + /* Apply offsets */ + cur_offset_s += offset_s_to_apply; + cur_offset_cycles += cycles_from_ns(freq, offset_ns_to_apply); + + /* + * Recalibrate offsets because the part in cycles can be greater + * than the frequency at this point. + */ + calibrate_clock_class_offsets(&cur_offset_s, &cur_offset_cycles, freq); + + /* Set final offsets */ + clock->offset_seconds = cur_offset_s; + clock->offset_cycles = cur_offset_cycles; end: - return; + return; } -static -int visit_clock_decl(struct ctf_visitor_generate_ir *ctx, struct ctf_node *clock_node) +static int visit_clock_decl(struct ctf_visitor_generate_ir *ctx, struct ctf_node *clock_node) { - int ret = 0; - int set = 0; - struct ctf_clock_class *clock; - struct ctf_node *entry_node; - struct bt_list_head *decl_list = &clock_node->u.clock.declaration_list; - const char *clock_class_name; - int64_t offset_seconds = 0; - uint64_t offset_cycles = 0; - uint64_t freq; - - if (clock_node->visited) { - return 0; - } - - clock_node->visited = TRUE; - - /* CTF 1.8's default frequency for a clock class is 1 GHz */ - clock = ctf_clock_class_create(); - if (!clock) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(clock_node, - "Cannot create default clock class."); - ret = -ENOMEM; - goto end; - } - - bt_list_for_each_entry(entry_node, decl_list, siblings) { - ret = visit_clock_decl_entry(ctx, entry_node, clock, &set, - &offset_seconds, &offset_cycles); - if (ret) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node, - "Cannot visit clock class's entry: ret=%d", - ret); - goto end; - } - } - - if (!_IS_SET(&set, _CLOCK_NAME_SET)) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(clock_node, - "Missing `name` attribute in clock class."); - ret = -EPERM; - goto end; - } - - clock_class_name = clock->name->str; - BT_ASSERT(clock_class_name); - if (ctx->is_lttng && strcmp(clock_class_name, "monotonic") == 0) { - /* - * Old versions of LTTng forgot to set its clock class - * as absolute, even if it is. This is important because - * it's a condition to be able to sort messages - * from different sources. - */ - clock->is_absolute = true; - } - - /* - * Adjust offsets so that the part in cycles is less than the - * frequency (move to the part in seconds). - */ - freq = clock->frequency; - calibrate_clock_class_offsets(&offset_seconds, &offset_cycles, freq); - BT_ASSERT(offset_cycles < clock->frequency); - clock->offset_seconds = offset_seconds; - clock->offset_cycles = offset_cycles; - apply_clock_class_offset(ctx, clock); - apply_clock_class_is_absolute(ctx, clock); - g_ptr_array_add(ctx->ctf_tc->clock_classes, clock); - clock = NULL; + int ret = 0; + int set = 0; + struct ctf_clock_class *clock; + struct ctf_node *entry_node; + struct bt_list_head *decl_list = &clock_node->u.clock.declaration_list; + const char *clock_class_name; + int64_t offset_seconds = 0; + uint64_t offset_cycles = 0; + uint64_t freq; + + if (clock_node->visited) { + return 0; + } + + clock_node->visited = TRUE; + + /* CTF 1.8's default frequency for a clock class is 1 GHz */ + clock = ctf_clock_class_create(); + if (!clock) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(clock_node, "Cannot create default clock class."); + ret = -ENOMEM; + goto end; + } + + bt_list_for_each_entry (entry_node, decl_list, siblings) { + ret = visit_clock_decl_entry(ctx, entry_node, clock, &set, &offset_seconds, &offset_cycles); + if (ret) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(entry_node, "Cannot visit clock class's entry: ret=%d", + ret); + goto end; + } + } + + if (!_IS_SET(&set, _CLOCK_NAME_SET)) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(clock_node, "Missing `name` attribute in clock class."); + ret = -EPERM; + goto end; + } + + clock_class_name = clock->name->str; + BT_ASSERT(clock_class_name); + if (ctx->is_lttng && strcmp(clock_class_name, "monotonic") == 0) { + /* + * Old versions of LTTng forgot to set its clock class + * as absolute, even if it is. This is important because + * it's a condition to be able to sort messages + * from different sources. + */ + clock->is_absolute = true; + } + + /* + * Adjust offsets so that the part in cycles is less than the + * frequency (move to the part in seconds). + */ + freq = clock->frequency; + calibrate_clock_class_offsets(&offset_seconds, &offset_cycles, freq); + BT_ASSERT(offset_cycles < clock->frequency); + clock->offset_seconds = offset_seconds; + clock->offset_cycles = offset_cycles; + apply_clock_class_offset(ctx, clock); + apply_clock_class_is_absolute(ctx, clock); + g_ptr_array_add(ctx->ctf_tc->clock_classes, clock); + clock = NULL; end: - if (clock) { - ctf_clock_class_destroy(clock); - } + if (clock) { + ctf_clock_class_destroy(clock); + } - return ret; + return ret; } -static -int visit_root_decl(struct ctf_visitor_generate_ir *ctx, struct ctf_node *root_decl_node) +static int visit_root_decl(struct ctf_visitor_generate_ir *ctx, struct ctf_node *root_decl_node) { - int ret = 0; - - if (root_decl_node->visited) { - goto end; - } - - root_decl_node->visited = TRUE; - - switch (root_decl_node->type) { - case NODE_TYPEDEF: - ret = visit_field_class_def(ctx, - root_decl_node->u.field_class_def.field_class_specifier_list, - &root_decl_node->u.field_class_def.field_class_declarators); - if (ret) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(root_decl_node, - "Cannot add field class found in root scope."); - goto end; - } - break; - case NODE_TYPEALIAS: - ret = visit_field_class_alias(ctx, root_decl_node->u.field_class_alias.target, - root_decl_node->u.field_class_alias.alias); - if (ret) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(root_decl_node, - "Cannot add field class alias found in root scope."); - goto end; - } - break; - case NODE_TYPE_SPECIFIER_LIST: - { - struct ctf_field_class *decl = NULL; - - /* - * Just add the field class specifier to the root - * declaration scope. Put local reference. - */ - ret = visit_field_class_specifier_list(ctx, root_decl_node, &decl); - if (ret) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(root_decl_node, - "Cannot visit root scope's field class: " - "ret=%d", ret); - BT_ASSERT(!decl); - goto end; - } - - ctf_field_class_destroy(decl); - decl = NULL; - break; - } - default: - _BT_COMP_LOGE_APPEND_CAUSE_NODE(root_decl_node, - "Unexpected node type: node-type=%d", - root_decl_node->type); - ret = -EPERM; - goto end; - } + int ret = 0; + + if (root_decl_node->visited) { + goto end; + } + + root_decl_node->visited = TRUE; + + switch (root_decl_node->type) { + case NODE_TYPEDEF: + ret = + visit_field_class_def(ctx, root_decl_node->u.field_class_def.field_class_specifier_list, + &root_decl_node->u.field_class_def.field_class_declarators); + if (ret) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(root_decl_node, + "Cannot add field class found in root scope."); + goto end; + } + break; + case NODE_TYPEALIAS: + ret = visit_field_class_alias(ctx, root_decl_node->u.field_class_alias.target, + root_decl_node->u.field_class_alias.alias); + if (ret) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(root_decl_node, + "Cannot add field class alias found in root scope."); + goto end; + } + break; + case NODE_TYPE_SPECIFIER_LIST: + { + struct ctf_field_class *decl = NULL; + + /* + * Just add the field class specifier to the root + * declaration scope. Put local reference. + */ + ret = visit_field_class_specifier_list(ctx, root_decl_node, &decl); + if (ret) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(root_decl_node, + "Cannot visit root scope's field class: " + "ret=%d", + ret); + BT_ASSERT(!decl); + goto end; + } + + ctf_field_class_destroy(decl); + decl = NULL; + break; + } + default: + _BT_COMP_LOGE_APPEND_CAUSE_NODE(root_decl_node, "Unexpected node type: node-type=%d", + root_decl_node->type); + ret = -EPERM; + goto end; + } end: - return ret; + return ret; } BT_HIDDEN -struct ctf_visitor_generate_ir *ctf_visitor_generate_ir_create( - const struct ctf_metadata_decoder_config *decoder_config) +struct ctf_visitor_generate_ir * +ctf_visitor_generate_ir_create(const struct ctf_metadata_decoder_config *decoder_config) { - struct ctf_visitor_generate_ir *ctx = NULL; + struct ctf_visitor_generate_ir *ctx = NULL; - /* Create visitor's context */ - ctx = ctx_create(decoder_config); - if (!ctx) { - BT_COMP_LOG_CUR_LVL(BT_LOG_ERROR, decoder_config->log_level, - decoder_config->self_comp, - "Cannot create visitor's context."); - goto error; - } + /* Create visitor's context */ + ctx = ctx_create(decoder_config); + if (!ctx) { + BT_COMP_LOG_CUR_LVL(BT_LOG_ERROR, decoder_config->log_level, decoder_config->self_comp, + "Cannot create visitor's context."); + goto error; + } - goto end; + goto end; error: - ctx_destroy(ctx); - ctx = NULL; + ctx_destroy(ctx); + ctx = NULL; end: - return ctx; + return ctx; } BT_HIDDEN void ctf_visitor_generate_ir_destroy(struct ctf_visitor_generate_ir *visitor) { - ctx_destroy(visitor); + ctx_destroy(visitor); } BT_HIDDEN -bt_trace_class *ctf_visitor_generate_ir_get_ir_trace_class( - struct ctf_visitor_generate_ir *ctx) +bt_trace_class *ctf_visitor_generate_ir_get_ir_trace_class(struct ctf_visitor_generate_ir *ctx) { - BT_ASSERT_DBG(ctx); + BT_ASSERT_DBG(ctx); - if (ctx->trace_class) { - bt_trace_class_get_ref(ctx->trace_class); - } + if (ctx->trace_class) { + bt_trace_class_get_ref(ctx->trace_class); + } - return ctx->trace_class; + return ctx->trace_class; } BT_HIDDEN -struct ctf_trace_class *ctf_visitor_generate_ir_borrow_ctf_trace_class( - struct ctf_visitor_generate_ir *ctx) +struct ctf_trace_class * +ctf_visitor_generate_ir_borrow_ctf_trace_class(struct ctf_visitor_generate_ir *ctx) { - BT_ASSERT_DBG(ctx); - BT_ASSERT_DBG(ctx->ctf_tc); - return ctx->ctf_tc; + BT_ASSERT_DBG(ctx); + BT_ASSERT_DBG(ctx->ctf_tc); + return ctx->ctf_tc; } BT_HIDDEN -int ctf_visitor_generate_ir_visit_node(struct ctf_visitor_generate_ir *ctx, - struct ctf_node *node) +int ctf_visitor_generate_ir_visit_node(struct ctf_visitor_generate_ir *ctx, struct ctf_node *node) { - int ret = 0; - - BT_COMP_LOGI_STR("Visiting metadata's AST to generate CTF IR objects."); - - switch (node->type) { - case NODE_ROOT: - { - struct ctf_node *iter; - bool got_trace_decl = false; - - /* - * The first thing we need is the native byte order of - * the trace block, because early class aliases can have - * a `byte_order` attribute set to `native`. If we don't - * have the native byte order yet, and we don't have any - * trace block yet, then fail with EINCOMPLETE. - */ - if (ctx->ctf_tc->default_byte_order == CTF_BYTE_ORDER_UNKNOWN) { - bt_list_for_each_entry(iter, &node->u.root.trace, siblings) { - if (got_trace_decl) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, - "Duplicate trace (`trace` block)."); - ret = -1; - goto end; - } - - ret = set_trace_byte_order(ctx, iter); - if (ret) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, - "Cannot set trace's native byte order: " - "ret=%d", ret); - goto end; - } - - got_trace_decl = true; - } - - if (!got_trace_decl) { - BT_COMP_LOGD_STR("Incomplete AST: need trace (`trace` block)."); - ret = -EINCOMPLETE; - goto end; - } - } - - BT_ASSERT(ctx->ctf_tc->default_byte_order == CTF_BYTE_ORDER_LITTLE || - ctx->ctf_tc->default_byte_order == CTF_BYTE_ORDER_BIG); - BT_ASSERT(ctx->current_scope && - !ctx->current_scope->parent_scope); - - /* Environment */ - bt_list_for_each_entry(iter, &node->u.root.env, siblings) { - ret = visit_env(ctx, iter); - if (ret) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter, - "Cannot visit trace's environment (`env` block) entry: " - "ret=%d", ret); - goto end; - } - } - - BT_ASSERT(ctx->current_scope && - !ctx->current_scope->parent_scope); - - /* - * Visit clock blocks. - */ - bt_list_for_each_entry(iter, &node->u.root.clock, siblings) { - ret = visit_clock_decl(ctx, iter); - if (ret) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter, - "Cannot visit clock class: ret=%d", - ret); - goto end; - } - } - - BT_ASSERT(ctx->current_scope && - !ctx->current_scope->parent_scope); - - /* - * Visit root declarations next, as they can be used by any - * following entity. - */ - bt_list_for_each_entry(iter, &node->u.root.declaration_list, - siblings) { - ret = visit_root_decl(ctx, iter); - if (ret) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter, - "Cannot visit root entry: ret=%d", - ret); - goto end; - } - } - - BT_ASSERT(ctx->current_scope && - !ctx->current_scope->parent_scope); - - /* Callsite blocks are not supported */ - bt_list_for_each_entry(iter, &node->u.root.callsite, siblings) { - _BT_COMP_LOGW_NODE(iter, - "\"callsite\" blocks are not supported as of this version."); - } - - BT_ASSERT(ctx->current_scope && - !ctx->current_scope->parent_scope); - - /* Trace */ - bt_list_for_each_entry(iter, &node->u.root.trace, siblings) { - ret = visit_trace_decl(ctx, iter); - if (ret) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter, - "Cannot visit trace (`trace` block): " - "ret=%d", ret); - goto end; - } - } - - BT_ASSERT(ctx->current_scope && - !ctx->current_scope->parent_scope); - - /* Streams */ - bt_list_for_each_entry(iter, &node->u.root.stream, siblings) { - ret = visit_stream_decl(ctx, iter); - if (ret) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter, - "Cannot visit stream class: ret=%d", - ret); - goto end; - } - } - - BT_ASSERT(ctx->current_scope && - !ctx->current_scope->parent_scope); - - /* Events */ - bt_list_for_each_entry(iter, &node->u.root.event, siblings) { - ret = visit_event_decl(ctx, iter); - if (ret) { - _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter, - "Cannot visit event class: ret=%d", - ret); - goto end; - } - } - - BT_ASSERT(ctx->current_scope && - !ctx->current_scope->parent_scope); - break; - } - default: - _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, - "Unexpected node type: node-type=%d", - node->type); - ret = -EINVAL; - goto end; - } - - /* Update default clock classes */ - ret = ctf_trace_class_update_default_clock_classes(ctx->ctf_tc, - &ctx->log_cfg); - if (ret) { - ret = -EINVAL; - goto end; - } - - /* Update trace class meanings */ - ret = ctf_trace_class_update_meanings(ctx->ctf_tc); - if (ret) { - ret = -EINVAL; - goto end; - } - - /* Update stream class configuration */ - ret = ctf_trace_class_update_stream_class_config(ctx->ctf_tc); - if (ret) { - ret = -EINVAL; - goto end; - } - - /* Update text arrays and sequences */ - ret = ctf_trace_class_update_text_array_sequence(ctx->ctf_tc); - if (ret) { - ret = -EINVAL; - goto end; - } - - /* Update structure/array/sequence alignments */ - ret = ctf_trace_class_update_alignments(ctx->ctf_tc); - if (ret) { - ret = -EINVAL; - goto end; - } - - /* Resolve sequence lengths and variant tags */ - ret = ctf_trace_class_resolve_field_classes(ctx->ctf_tc, &ctx->log_cfg); - if (ret) { - ret = -EINVAL; - goto end; - } - - if (ctx->trace_class) { - /* - * Update "in IR" for field classes. - * - * If we have no IR trace class, then we'll have no way - * to create IR fields anyway, so we leave all the - * `in_ir` members false. - */ - ret = ctf_trace_class_update_in_ir(ctx->ctf_tc); - if (ret) { - ret = -EINVAL; - goto end; - } - } - - /* Update saved value indexes */ - ret = ctf_trace_class_update_value_storing_indexes(ctx->ctf_tc); - if (ret) { - ret = -EINVAL; - goto end; - } - - /* Validate what we have so far */ - ret = ctf_trace_class_validate(ctx->ctf_tc, &ctx->log_cfg); - if (ret) { - ret = -EINVAL; - goto end; - } - - /* - * If there are fields which are not related to the CTF format - * itself in the packet header and in event header field - * classes, warn about it because they are never translated. - */ - ctf_trace_class_warn_meaningless_header_fields(ctx->ctf_tc, - &ctx->log_cfg); - - if (ctx->trace_class) { - /* Copy new CTF metadata -> new IR metadata */ - ret = ctf_trace_class_translate(ctx->log_cfg.self_comp, - ctx->trace_class, ctx->ctf_tc); - if (ret) { - ret = -EINVAL; - goto end; - } - } + int ret = 0; + + BT_COMP_LOGI_STR("Visiting metadata's AST to generate CTF IR objects."); + + switch (node->type) { + case NODE_ROOT: + { + struct ctf_node *iter; + bool got_trace_decl = false; + + /* + * The first thing we need is the native byte order of + * the trace block, because early class aliases can have + * a `byte_order` attribute set to `native`. If we don't + * have the native byte order yet, and we don't have any + * trace block yet, then fail with EINCOMPLETE. + */ + if (ctx->ctf_tc->default_byte_order == CTF_BYTE_ORDER_UNKNOWN) { + bt_list_for_each_entry (iter, &node->u.root.trace, siblings) { + if (got_trace_decl) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Duplicate trace (`trace` block)."); + ret = -1; + goto end; + } + + ret = set_trace_byte_order(ctx, iter); + if (ret) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, + "Cannot set trace's native byte order: " + "ret=%d", + ret); + goto end; + } + + got_trace_decl = true; + } + + if (!got_trace_decl) { + BT_COMP_LOGD_STR("Incomplete AST: need trace (`trace` block)."); + ret = -EINCOMPLETE; + goto end; + } + } + + BT_ASSERT(ctx->ctf_tc->default_byte_order == CTF_BYTE_ORDER_LITTLE || + ctx->ctf_tc->default_byte_order == CTF_BYTE_ORDER_BIG); + BT_ASSERT(ctx->current_scope && !ctx->current_scope->parent_scope); + + /* Environment */ + bt_list_for_each_entry (iter, &node->u.root.env, siblings) { + ret = visit_env(ctx, iter); + if (ret) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE( + iter, + "Cannot visit trace's environment (`env` block) entry: " + "ret=%d", + ret); + goto end; + } + } + + BT_ASSERT(ctx->current_scope && !ctx->current_scope->parent_scope); + + /* + * Visit clock blocks. + */ + bt_list_for_each_entry (iter, &node->u.root.clock, siblings) { + ret = visit_clock_decl(ctx, iter); + if (ret) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter, "Cannot visit clock class: ret=%d", ret); + goto end; + } + } + + BT_ASSERT(ctx->current_scope && !ctx->current_scope->parent_scope); + + /* + * Visit root declarations next, as they can be used by any + * following entity. + */ + bt_list_for_each_entry (iter, &node->u.root.declaration_list, siblings) { + ret = visit_root_decl(ctx, iter); + if (ret) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter, "Cannot visit root entry: ret=%d", ret); + goto end; + } + } + + BT_ASSERT(ctx->current_scope && !ctx->current_scope->parent_scope); + + /* Callsite blocks are not supported */ + bt_list_for_each_entry (iter, &node->u.root.callsite, siblings) { + _BT_COMP_LOGW_NODE(iter, "\"callsite\" blocks are not supported as of this version."); + } + + BT_ASSERT(ctx->current_scope && !ctx->current_scope->parent_scope); + + /* Trace */ + bt_list_for_each_entry (iter, &node->u.root.trace, siblings) { + ret = visit_trace_decl(ctx, iter); + if (ret) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter, + "Cannot visit trace (`trace` block): " + "ret=%d", + ret); + goto end; + } + } + + BT_ASSERT(ctx->current_scope && !ctx->current_scope->parent_scope); + + /* Streams */ + bt_list_for_each_entry (iter, &node->u.root.stream, siblings) { + ret = visit_stream_decl(ctx, iter); + if (ret) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter, "Cannot visit stream class: ret=%d", ret); + goto end; + } + } + + BT_ASSERT(ctx->current_scope && !ctx->current_scope->parent_scope); + + /* Events */ + bt_list_for_each_entry (iter, &node->u.root.event, siblings) { + ret = visit_event_decl(ctx, iter); + if (ret) { + _BT_COMP_LOGE_APPEND_CAUSE_NODE(iter, "Cannot visit event class: ret=%d", ret); + goto end; + } + } + + BT_ASSERT(ctx->current_scope && !ctx->current_scope->parent_scope); + break; + } + default: + _BT_COMP_LOGE_APPEND_CAUSE_NODE(node, "Unexpected node type: node-type=%d", node->type); + ret = -EINVAL; + goto end; + } + + /* Update default clock classes */ + ret = ctf_trace_class_update_default_clock_classes(ctx->ctf_tc, &ctx->log_cfg); + if (ret) { + ret = -EINVAL; + goto end; + } + + /* Update trace class meanings */ + ret = ctf_trace_class_update_meanings(ctx->ctf_tc); + if (ret) { + ret = -EINVAL; + goto end; + } + + /* Update stream class configuration */ + ret = ctf_trace_class_update_stream_class_config(ctx->ctf_tc); + if (ret) { + ret = -EINVAL; + goto end; + } + + /* Update text arrays and sequences */ + ret = ctf_trace_class_update_text_array_sequence(ctx->ctf_tc); + if (ret) { + ret = -EINVAL; + goto end; + } + + /* Update structure/array/sequence alignments */ + ret = ctf_trace_class_update_alignments(ctx->ctf_tc); + if (ret) { + ret = -EINVAL; + goto end; + } + + /* Resolve sequence lengths and variant tags */ + ret = ctf_trace_class_resolve_field_classes(ctx->ctf_tc, &ctx->log_cfg); + if (ret) { + ret = -EINVAL; + goto end; + } + + if (ctx->trace_class) { + /* + * Update "in IR" for field classes. + * + * If we have no IR trace class, then we'll have no way + * to create IR fields anyway, so we leave all the + * `in_ir` members false. + */ + ret = ctf_trace_class_update_in_ir(ctx->ctf_tc); + if (ret) { + ret = -EINVAL; + goto end; + } + } + + /* Update saved value indexes */ + ret = ctf_trace_class_update_value_storing_indexes(ctx->ctf_tc); + if (ret) { + ret = -EINVAL; + goto end; + } + + /* Validate what we have so far */ + ret = ctf_trace_class_validate(ctx->ctf_tc, &ctx->log_cfg); + if (ret) { + ret = -EINVAL; + goto end; + } + + /* + * If there are fields which are not related to the CTF format + * itself in the packet header and in event header field + * classes, warn about it because they are never translated. + */ + ctf_trace_class_warn_meaningless_header_fields(ctx->ctf_tc, &ctx->log_cfg); + + if (ctx->trace_class) { + /* Copy new CTF metadata -> new IR metadata */ + ret = ctf_trace_class_translate(ctx->log_cfg.self_comp, ctx->trace_class, ctx->ctf_tc); + if (ret) { + ret = -EINVAL; + goto end; + } + } end: - return ret; + return ret; } diff --git a/src/plugins/ctf/common/metadata/visitor-parent-links.cpp b/src/plugins/ctf/common/metadata/visitor-parent-links.cpp index f34df9f5..724ada65 100644 --- a/src/plugins/ctf/common/metadata/visitor-parent-links.cpp +++ b/src/plugins/ctf/common/metadata/visitor-parent-links.cpp @@ -7,8 +7,8 @@ */ #define BT_COMP_LOG_SELF_COMP (log_cfg->self_comp) -#define BT_LOG_OUTPUT_LEVEL (log_cfg->log_level) -#define BT_LOG_TAG "PLUGIN/CTF/META/PARENT-LINKS-VISITOR" +#define BT_LOG_OUTPUT_LEVEL (log_cfg->log_level) +#define BT_LOG_TAG "PLUGIN/CTF/META/PARENT-LINKS-VISITOR" #include "logging/comp-logging.h" #include @@ -25,474 +25,425 @@ #include "ast.hpp" #include "logging.hpp" -static -int ctf_visitor_unary_expression(int depth, struct ctf_node *node, - struct meta_log_config *log_cfg) +static int ctf_visitor_unary_expression(int depth, struct ctf_node *node, + struct meta_log_config *log_cfg) { - int ret = 0; + int ret = 0; - switch (node->u.unary_expression.link) { - case UNARY_LINK_UNKNOWN: - case UNARY_DOTLINK: - case UNARY_ARROWLINK: - case UNARY_DOTDOTDOT: - break; - default: - _BT_COMP_LOGE_APPEND_CAUSE_LINENO(node->lineno, - "Unknown expression link type: type=%d\n", - node->u.unary_expression.link); - return -EINVAL; - } + switch (node->u.unary_expression.link) { + case UNARY_LINK_UNKNOWN: + case UNARY_DOTLINK: + case UNARY_ARROWLINK: + case UNARY_DOTDOTDOT: + break; + default: + _BT_COMP_LOGE_APPEND_CAUSE_LINENO(node->lineno, "Unknown expression link type: type=%d\n", + node->u.unary_expression.link); + return -EINVAL; + } - switch (node->u.unary_expression.type) { - case UNARY_STRING: - case UNARY_SIGNED_CONSTANT: - case UNARY_UNSIGNED_CONSTANT: - break; - case UNARY_SBRAC: - node->u.unary_expression.u.sbrac_exp->parent = node; - ret = ctf_visitor_unary_expression(depth + 1, - node->u.unary_expression.u.sbrac_exp, - log_cfg); - if (ret) - return ret; - break; + switch (node->u.unary_expression.type) { + case UNARY_STRING: + case UNARY_SIGNED_CONSTANT: + case UNARY_UNSIGNED_CONSTANT: + break; + case UNARY_SBRAC: + node->u.unary_expression.u.sbrac_exp->parent = node; + ret = + ctf_visitor_unary_expression(depth + 1, node->u.unary_expression.u.sbrac_exp, log_cfg); + if (ret) + return ret; + break; - case UNARY_UNKNOWN: - default: - _BT_COMP_LOGE_APPEND_CAUSE_LINENO(node->lineno, - "Unknown expression link type: type=%d\n", - node->u.unary_expression.link); - return -EINVAL; - } - return 0; + case UNARY_UNKNOWN: + default: + _BT_COMP_LOGE_APPEND_CAUSE_LINENO(node->lineno, "Unknown expression link type: type=%d\n", + node->u.unary_expression.link); + return -EINVAL; + } + return 0; } -static -int ctf_visitor_type_specifier(int depth, struct ctf_node *node, - struct meta_log_config *log_cfg) +static int ctf_visitor_type_specifier(int depth, struct ctf_node *node, + struct meta_log_config *log_cfg) { - int ret; + int ret; - switch (node->u.field_class_specifier.type) { - case TYPESPEC_VOID: - case TYPESPEC_CHAR: - case TYPESPEC_SHORT: - case TYPESPEC_INT: - case TYPESPEC_LONG: - case TYPESPEC_FLOAT: - case TYPESPEC_DOUBLE: - case TYPESPEC_SIGNED: - case TYPESPEC_UNSIGNED: - case TYPESPEC_BOOL: - case TYPESPEC_COMPLEX: - case TYPESPEC_IMAGINARY: - case TYPESPEC_CONST: - case TYPESPEC_ID_TYPE: - break; - case TYPESPEC_FLOATING_POINT: - case TYPESPEC_INTEGER: - case TYPESPEC_STRING: - case TYPESPEC_STRUCT: - case TYPESPEC_VARIANT: - case TYPESPEC_ENUM: - node->u.field_class_specifier.node->parent = node; - ret = ctf_visitor_parent_links(depth + 1, - node->u.field_class_specifier.node, - log_cfg); - if (ret) - return ret; - break; + switch (node->u.field_class_specifier.type) { + case TYPESPEC_VOID: + case TYPESPEC_CHAR: + case TYPESPEC_SHORT: + case TYPESPEC_INT: + case TYPESPEC_LONG: + case TYPESPEC_FLOAT: + case TYPESPEC_DOUBLE: + case TYPESPEC_SIGNED: + case TYPESPEC_UNSIGNED: + case TYPESPEC_BOOL: + case TYPESPEC_COMPLEX: + case TYPESPEC_IMAGINARY: + case TYPESPEC_CONST: + case TYPESPEC_ID_TYPE: + break; + case TYPESPEC_FLOATING_POINT: + case TYPESPEC_INTEGER: + case TYPESPEC_STRING: + case TYPESPEC_STRUCT: + case TYPESPEC_VARIANT: + case TYPESPEC_ENUM: + node->u.field_class_specifier.node->parent = node; + ret = ctf_visitor_parent_links(depth + 1, node->u.field_class_specifier.node, log_cfg); + if (ret) + return ret; + break; - case TYPESPEC_UNKNOWN: - default: - _BT_COMP_LOGE_APPEND_CAUSE_LINENO(node->lineno, - "Unknown type specifier: type=%d\n", - node->u.field_class_specifier.type); - return -EINVAL; - } - return 0; + case TYPESPEC_UNKNOWN: + default: + _BT_COMP_LOGE_APPEND_CAUSE_LINENO(node->lineno, "Unknown type specifier: type=%d\n", + node->u.field_class_specifier.type); + return -EINVAL; + } + return 0; } -static -int ctf_visitor_field_class_declarator(int depth, struct ctf_node *node, - struct meta_log_config *log_cfg) +static int ctf_visitor_field_class_declarator(int depth, struct ctf_node *node, + struct meta_log_config *log_cfg) { - int ret = 0; - struct ctf_node *iter; + int ret = 0; + struct ctf_node *iter; - depth++; + depth++; - bt_list_for_each_entry(iter, &node->u.field_class_declarator.pointers, - siblings) { - iter->parent = node; - ret = ctf_visitor_parent_links(depth + 1, iter, log_cfg); - if (ret) - return ret; - } + bt_list_for_each_entry (iter, &node->u.field_class_declarator.pointers, siblings) { + iter->parent = node; + ret = ctf_visitor_parent_links(depth + 1, iter, log_cfg); + if (ret) + return ret; + } - switch (node->u.field_class_declarator.type) { - case TYPEDEC_ID: - break; - case TYPEDEC_NESTED: - if (node->u.field_class_declarator.u.nested.field_class_declarator) { - node->u.field_class_declarator.u.nested.field_class_declarator->parent = node; - ret = ctf_visitor_parent_links(depth + 1, - node->u.field_class_declarator.u.nested.field_class_declarator, - log_cfg); - if (ret) - return ret; - } - if (!node->u.field_class_declarator.u.nested.abstract_array) { - bt_list_for_each_entry(iter, &node->u.field_class_declarator.u.nested.length, - siblings) { - iter->parent = node; - ret = ctf_visitor_parent_links(depth + 1, iter, - log_cfg); - if (ret) - return ret; - } - } - if (node->u.field_class_declarator.bitfield_len) { - node->u.field_class_declarator.bitfield_len = node; - ret = ctf_visitor_parent_links(depth + 1, - node->u.field_class_declarator.bitfield_len, - log_cfg); - if (ret) - return ret; - } - break; - case TYPEDEC_UNKNOWN: - default: - _BT_COMP_LOGE_APPEND_CAUSE_LINENO(node->lineno, - "Unknown type declarator: type=%d\n", - node->u.field_class_declarator.type); - return -EINVAL; - } - depth--; - return 0; + switch (node->u.field_class_declarator.type) { + case TYPEDEC_ID: + break; + case TYPEDEC_NESTED: + if (node->u.field_class_declarator.u.nested.field_class_declarator) { + node->u.field_class_declarator.u.nested.field_class_declarator->parent = node; + ret = ctf_visitor_parent_links( + depth + 1, node->u.field_class_declarator.u.nested.field_class_declarator, log_cfg); + if (ret) + return ret; + } + if (!node->u.field_class_declarator.u.nested.abstract_array) { + bt_list_for_each_entry (iter, &node->u.field_class_declarator.u.nested.length, + siblings) { + iter->parent = node; + ret = ctf_visitor_parent_links(depth + 1, iter, log_cfg); + if (ret) + return ret; + } + } + if (node->u.field_class_declarator.bitfield_len) { + node->u.field_class_declarator.bitfield_len = node; + ret = ctf_visitor_parent_links(depth + 1, node->u.field_class_declarator.bitfield_len, + log_cfg); + if (ret) + return ret; + } + break; + case TYPEDEC_UNKNOWN: + default: + _BT_COMP_LOGE_APPEND_CAUSE_LINENO(node->lineno, "Unknown type declarator: type=%d\n", + node->u.field_class_declarator.type); + return -EINVAL; + } + depth--; + return 0; } -int ctf_visitor_parent_links(int depth, struct ctf_node *node, - struct meta_log_config *log_cfg) +int ctf_visitor_parent_links(int depth, struct ctf_node *node, struct meta_log_config *log_cfg) { - int ret = 0; - struct ctf_node *iter; + int ret = 0; + struct ctf_node *iter; - if (node->visited) - return 0; + if (node->visited) + return 0; - switch (node->type) { - case NODE_ROOT: - bt_list_for_each_entry(iter, &node->u.root.declaration_list, siblings) { - iter->parent = node; - ret = ctf_visitor_parent_links(depth + 1, iter, - log_cfg); - if (ret) - return ret; - } - bt_list_for_each_entry(iter, &node->u.root.trace, siblings) { - iter->parent = node; - ret = ctf_visitor_parent_links(depth + 1, iter, - log_cfg); - if (ret) - return ret; - } - bt_list_for_each_entry(iter, &node->u.root.stream, siblings) { - iter->parent = node; - ret = ctf_visitor_parent_links(depth + 1, iter, - log_cfg); - if (ret) - return ret; - } - bt_list_for_each_entry(iter, &node->u.root.event, siblings) { - iter->parent = node; - ret = ctf_visitor_parent_links(depth + 1, iter, - log_cfg); - if (ret) - return ret; - } - bt_list_for_each_entry(iter, &node->u.root.clock, siblings) { - iter->parent = node; - ret = ctf_visitor_parent_links(depth + 1, iter, - log_cfg); - if (ret) - return ret; - } - bt_list_for_each_entry(iter, &node->u.root.callsite, siblings) { - iter->parent = node; - ret = ctf_visitor_parent_links(depth + 1, iter, - log_cfg); - if (ret) - return ret; - } - break; + switch (node->type) { + case NODE_ROOT: + bt_list_for_each_entry (iter, &node->u.root.declaration_list, siblings) { + iter->parent = node; + ret = ctf_visitor_parent_links(depth + 1, iter, log_cfg); + if (ret) + return ret; + } + bt_list_for_each_entry (iter, &node->u.root.trace, siblings) { + iter->parent = node; + ret = ctf_visitor_parent_links(depth + 1, iter, log_cfg); + if (ret) + return ret; + } + bt_list_for_each_entry (iter, &node->u.root.stream, siblings) { + iter->parent = node; + ret = ctf_visitor_parent_links(depth + 1, iter, log_cfg); + if (ret) + return ret; + } + bt_list_for_each_entry (iter, &node->u.root.event, siblings) { + iter->parent = node; + ret = ctf_visitor_parent_links(depth + 1, iter, log_cfg); + if (ret) + return ret; + } + bt_list_for_each_entry (iter, &node->u.root.clock, siblings) { + iter->parent = node; + ret = ctf_visitor_parent_links(depth + 1, iter, log_cfg); + if (ret) + return ret; + } + bt_list_for_each_entry (iter, &node->u.root.callsite, siblings) { + iter->parent = node; + ret = ctf_visitor_parent_links(depth + 1, iter, log_cfg); + if (ret) + return ret; + } + break; - case NODE_EVENT: - bt_list_for_each_entry(iter, &node->u.event.declaration_list, siblings) { - iter->parent = node; - ret = ctf_visitor_parent_links(depth + 1, iter, - log_cfg); - if (ret) - return ret; - } - break; - case NODE_STREAM: - bt_list_for_each_entry(iter, &node->u.stream.declaration_list, siblings) { - iter->parent = node; - ret = ctf_visitor_parent_links(depth + 1, iter, - log_cfg); - if (ret) - return ret; - } - break; - case NODE_ENV: - bt_list_for_each_entry(iter, &node->u.env.declaration_list, siblings) { - iter->parent = node; - ret = ctf_visitor_parent_links(depth + 1, iter, - log_cfg); - if (ret) - return ret; - } - break; - case NODE_TRACE: - bt_list_for_each_entry(iter, &node->u.trace.declaration_list, siblings) { - iter->parent = node; - ret = ctf_visitor_parent_links(depth + 1, iter, - log_cfg); - if (ret) - return ret; - } - break; - case NODE_CLOCK: - bt_list_for_each_entry(iter, &node->u.clock.declaration_list, siblings) { - iter->parent = node; - ret = ctf_visitor_parent_links(depth + 1, iter, - log_cfg); - if (ret) - return ret; - } - break; - case NODE_CALLSITE: - bt_list_for_each_entry(iter, &node->u.callsite.declaration_list, siblings) { - iter->parent = node; - ret = ctf_visitor_parent_links(depth + 1, iter, - log_cfg); - if (ret) - return ret; - } - break; + case NODE_EVENT: + bt_list_for_each_entry (iter, &node->u.event.declaration_list, siblings) { + iter->parent = node; + ret = ctf_visitor_parent_links(depth + 1, iter, log_cfg); + if (ret) + return ret; + } + break; + case NODE_STREAM: + bt_list_for_each_entry (iter, &node->u.stream.declaration_list, siblings) { + iter->parent = node; + ret = ctf_visitor_parent_links(depth + 1, iter, log_cfg); + if (ret) + return ret; + } + break; + case NODE_ENV: + bt_list_for_each_entry (iter, &node->u.env.declaration_list, siblings) { + iter->parent = node; + ret = ctf_visitor_parent_links(depth + 1, iter, log_cfg); + if (ret) + return ret; + } + break; + case NODE_TRACE: + bt_list_for_each_entry (iter, &node->u.trace.declaration_list, siblings) { + iter->parent = node; + ret = ctf_visitor_parent_links(depth + 1, iter, log_cfg); + if (ret) + return ret; + } + break; + case NODE_CLOCK: + bt_list_for_each_entry (iter, &node->u.clock.declaration_list, siblings) { + iter->parent = node; + ret = ctf_visitor_parent_links(depth + 1, iter, log_cfg); + if (ret) + return ret; + } + break; + case NODE_CALLSITE: + bt_list_for_each_entry (iter, &node->u.callsite.declaration_list, siblings) { + iter->parent = node; + ret = ctf_visitor_parent_links(depth + 1, iter, log_cfg); + if (ret) + return ret; + } + break; - case NODE_CTF_EXPRESSION: - depth++; - bt_list_for_each_entry(iter, &node->u.ctf_expression.left, siblings) { - iter->parent = node; - ret = ctf_visitor_parent_links(depth + 1, iter, - log_cfg); - if (ret) - return ret; - } - bt_list_for_each_entry(iter, &node->u.ctf_expression.right, siblings) { - iter->parent = node; - ret = ctf_visitor_parent_links(depth + 1, iter, - log_cfg); - if (ret) - return ret; - } - depth--; - break; - case NODE_UNARY_EXPRESSION: - return ctf_visitor_unary_expression(depth, node, log_cfg); + case NODE_CTF_EXPRESSION: + depth++; + bt_list_for_each_entry (iter, &node->u.ctf_expression.left, siblings) { + iter->parent = node; + ret = ctf_visitor_parent_links(depth + 1, iter, log_cfg); + if (ret) + return ret; + } + bt_list_for_each_entry (iter, &node->u.ctf_expression.right, siblings) { + iter->parent = node; + ret = ctf_visitor_parent_links(depth + 1, iter, log_cfg); + if (ret) + return ret; + } + depth--; + break; + case NODE_UNARY_EXPRESSION: + return ctf_visitor_unary_expression(depth, node, log_cfg); - case NODE_TYPEDEF: - depth++; - node->u.field_class_def.field_class_specifier_list->parent = node; - ret = ctf_visitor_parent_links(depth + 1, - node->u.field_class_def.field_class_specifier_list, - log_cfg); - if (ret) - return ret; - bt_list_for_each_entry(iter, &node->u.field_class_def.field_class_declarators, siblings) { - iter->parent = node; - ret = ctf_visitor_parent_links(depth + 1, iter, - log_cfg); - if (ret) - return ret; - } - depth--; - break; - case NODE_TYPEALIAS_TARGET: - depth++; - node->u.field_class_alias_target.field_class_specifier_list->parent = node; - ret = ctf_visitor_parent_links(depth + 1, - node->u.field_class_alias_target.field_class_specifier_list, - log_cfg); - if (ret) - return ret; - bt_list_for_each_entry(iter, &node->u.field_class_alias_target.field_class_declarators, siblings) { - iter->parent = node; - ret = ctf_visitor_parent_links(depth + 1, iter, - log_cfg); - if (ret) - return ret; - } - depth--; - break; - case NODE_TYPEALIAS_ALIAS: - depth++; - node->u.field_class_alias_name.field_class_specifier_list->parent = node; - ret = ctf_visitor_parent_links(depth + 1, - node->u.field_class_alias_name.field_class_specifier_list, - log_cfg); - if (ret) - return ret; - bt_list_for_each_entry(iter, &node->u.field_class_alias_name.field_class_declarators, siblings) { - iter->parent = node; - ret = ctf_visitor_parent_links(depth + 1, iter, - log_cfg); - if (ret) - return ret; - } - depth--; - break; - case NODE_TYPEALIAS: - node->u.field_class_alias.target->parent = node; - ret = ctf_visitor_parent_links(depth + 1, - node->u.field_class_alias.target, log_cfg); - if (ret) - return ret; - node->u.field_class_alias.alias->parent = node; - ret = ctf_visitor_parent_links(depth + 1, - node->u.field_class_alias.alias, log_cfg); - if (ret) - return ret; - break; + case NODE_TYPEDEF: + depth++; + node->u.field_class_def.field_class_specifier_list->parent = node; + ret = ctf_visitor_parent_links(depth + 1, + node->u.field_class_def.field_class_specifier_list, log_cfg); + if (ret) + return ret; + bt_list_for_each_entry (iter, &node->u.field_class_def.field_class_declarators, siblings) { + iter->parent = node; + ret = ctf_visitor_parent_links(depth + 1, iter, log_cfg); + if (ret) + return ret; + } + depth--; + break; + case NODE_TYPEALIAS_TARGET: + depth++; + node->u.field_class_alias_target.field_class_specifier_list->parent = node; + ret = ctf_visitor_parent_links( + depth + 1, node->u.field_class_alias_target.field_class_specifier_list, log_cfg); + if (ret) + return ret; + bt_list_for_each_entry (iter, &node->u.field_class_alias_target.field_class_declarators, + siblings) { + iter->parent = node; + ret = ctf_visitor_parent_links(depth + 1, iter, log_cfg); + if (ret) + return ret; + } + depth--; + break; + case NODE_TYPEALIAS_ALIAS: + depth++; + node->u.field_class_alias_name.field_class_specifier_list->parent = node; + ret = ctf_visitor_parent_links( + depth + 1, node->u.field_class_alias_name.field_class_specifier_list, log_cfg); + if (ret) + return ret; + bt_list_for_each_entry (iter, &node->u.field_class_alias_name.field_class_declarators, + siblings) { + iter->parent = node; + ret = ctf_visitor_parent_links(depth + 1, iter, log_cfg); + if (ret) + return ret; + } + depth--; + break; + case NODE_TYPEALIAS: + node->u.field_class_alias.target->parent = node; + ret = ctf_visitor_parent_links(depth + 1, node->u.field_class_alias.target, log_cfg); + if (ret) + return ret; + node->u.field_class_alias.alias->parent = node; + ret = ctf_visitor_parent_links(depth + 1, node->u.field_class_alias.alias, log_cfg); + if (ret) + return ret; + break; - case NODE_TYPE_SPECIFIER_LIST: - bt_list_for_each_entry(iter, &node->u.field_class_specifier_list.head, siblings) { - iter->parent = node; - ret = ctf_visitor_parent_links(depth + 1, iter, - log_cfg); - if (ret) - return ret; - } - break; + case NODE_TYPE_SPECIFIER_LIST: + bt_list_for_each_entry (iter, &node->u.field_class_specifier_list.head, siblings) { + iter->parent = node; + ret = ctf_visitor_parent_links(depth + 1, iter, log_cfg); + if (ret) + return ret; + } + break; - case NODE_TYPE_SPECIFIER: - ret = ctf_visitor_type_specifier(depth, node, log_cfg); - if (ret) - return ret; - break; - case NODE_POINTER: - break; - case NODE_TYPE_DECLARATOR: - ret = ctf_visitor_field_class_declarator(depth, node, - log_cfg); - if (ret) - return ret; - break; + case NODE_TYPE_SPECIFIER: + ret = ctf_visitor_type_specifier(depth, node, log_cfg); + if (ret) + return ret; + break; + case NODE_POINTER: + break; + case NODE_TYPE_DECLARATOR: + ret = ctf_visitor_field_class_declarator(depth, node, log_cfg); + if (ret) + return ret; + break; - case NODE_FLOATING_POINT: - bt_list_for_each_entry(iter, &node->u.floating_point.expressions, siblings) { - iter->parent = node; - ret = ctf_visitor_parent_links(depth + 1, iter, - log_cfg); - if (ret) - return ret; - } - break; - case NODE_INTEGER: - bt_list_for_each_entry(iter, &node->u.integer.expressions, siblings) { - iter->parent = node; - ret = ctf_visitor_parent_links(depth + 1, iter, - log_cfg); - if (ret) - return ret; - } - break; - case NODE_STRING: - bt_list_for_each_entry(iter, &node->u.string.expressions, siblings) { - iter->parent = node; - ret = ctf_visitor_parent_links(depth + 1, iter, - log_cfg); - if (ret) - return ret; - } - break; - case NODE_ENUMERATOR: - bt_list_for_each_entry(iter, &node->u.enumerator.values, siblings) { - iter->parent = node; - ret = ctf_visitor_parent_links(depth + 1, iter, - log_cfg); - if (ret) - return ret; - } - break; - case NODE_ENUM: - depth++; - if (node->u._enum.container_field_class) { - ret = ctf_visitor_parent_links(depth + 1, - node->u._enum.container_field_class, log_cfg); - if (ret) - return ret; - } + case NODE_FLOATING_POINT: + bt_list_for_each_entry (iter, &node->u.floating_point.expressions, siblings) { + iter->parent = node; + ret = ctf_visitor_parent_links(depth + 1, iter, log_cfg); + if (ret) + return ret; + } + break; + case NODE_INTEGER: + bt_list_for_each_entry (iter, &node->u.integer.expressions, siblings) { + iter->parent = node; + ret = ctf_visitor_parent_links(depth + 1, iter, log_cfg); + if (ret) + return ret; + } + break; + case NODE_STRING: + bt_list_for_each_entry (iter, &node->u.string.expressions, siblings) { + iter->parent = node; + ret = ctf_visitor_parent_links(depth + 1, iter, log_cfg); + if (ret) + return ret; + } + break; + case NODE_ENUMERATOR: + bt_list_for_each_entry (iter, &node->u.enumerator.values, siblings) { + iter->parent = node; + ret = ctf_visitor_parent_links(depth + 1, iter, log_cfg); + if (ret) + return ret; + } + break; + case NODE_ENUM: + depth++; + if (node->u._enum.container_field_class) { + ret = ctf_visitor_parent_links(depth + 1, node->u._enum.container_field_class, log_cfg); + if (ret) + return ret; + } - bt_list_for_each_entry(iter, &node->u._enum.enumerator_list, siblings) { - iter->parent = node; - ret = ctf_visitor_parent_links(depth + 1, iter, - log_cfg); - if (ret) - return ret; - } - depth--; - break; - case NODE_STRUCT_OR_VARIANT_DECLARATION: - node->u.struct_or_variant_declaration.field_class_specifier_list->parent = node; - ret = ctf_visitor_parent_links(depth + 1, - node->u.struct_or_variant_declaration.field_class_specifier_list, - log_cfg); - if (ret) - return ret; - bt_list_for_each_entry(iter, &node->u.struct_or_variant_declaration.field_class_declarators, siblings) { - iter->parent = node; - ret = ctf_visitor_parent_links(depth + 1, iter, - log_cfg); - if (ret) - return ret; - } - break; - case NODE_VARIANT: - bt_list_for_each_entry(iter, &node->u.variant.declaration_list, siblings) { - iter->parent = node; - ret = ctf_visitor_parent_links(depth + 1, iter, - log_cfg); - if (ret) - return ret; - } - break; - case NODE_STRUCT: - bt_list_for_each_entry(iter, &node->u._struct.declaration_list, siblings) { - iter->parent = node; - ret = ctf_visitor_parent_links(depth + 1, iter, - log_cfg); - if (ret) - return ret; - } - bt_list_for_each_entry(iter, &node->u._struct.min_align, - siblings) { - iter->parent = node; - ret = ctf_visitor_parent_links(depth + 1, iter, - log_cfg); - if (ret) - return ret; - } - break; + bt_list_for_each_entry (iter, &node->u._enum.enumerator_list, siblings) { + iter->parent = node; + ret = ctf_visitor_parent_links(depth + 1, iter, log_cfg); + if (ret) + return ret; + } + depth--; + break; + case NODE_STRUCT_OR_VARIANT_DECLARATION: + node->u.struct_or_variant_declaration.field_class_specifier_list->parent = node; + ret = ctf_visitor_parent_links( + depth + 1, node->u.struct_or_variant_declaration.field_class_specifier_list, log_cfg); + if (ret) + return ret; + bt_list_for_each_entry ( + iter, &node->u.struct_or_variant_declaration.field_class_declarators, siblings) { + iter->parent = node; + ret = ctf_visitor_parent_links(depth + 1, iter, log_cfg); + if (ret) + return ret; + } + break; + case NODE_VARIANT: + bt_list_for_each_entry (iter, &node->u.variant.declaration_list, siblings) { + iter->parent = node; + ret = ctf_visitor_parent_links(depth + 1, iter, log_cfg); + if (ret) + return ret; + } + break; + case NODE_STRUCT: + bt_list_for_each_entry (iter, &node->u._struct.declaration_list, siblings) { + iter->parent = node; + ret = ctf_visitor_parent_links(depth + 1, iter, log_cfg); + if (ret) + return ret; + } + bt_list_for_each_entry (iter, &node->u._struct.min_align, siblings) { + iter->parent = node; + ret = ctf_visitor_parent_links(depth + 1, iter, log_cfg); + if (ret) + return ret; + } + break; - case NODE_UNKNOWN: - default: - _BT_COMP_LOGE_APPEND_CAUSE_LINENO(node->lineno, - "Unknown node type: type=%d\n", node->type); - return -EINVAL; - } - return ret; + case NODE_UNKNOWN: + default: + _BT_COMP_LOGE_APPEND_CAUSE_LINENO(node->lineno, "Unknown node type: type=%d\n", node->type); + return -EINVAL; + } + return ret; } diff --git a/src/plugins/ctf/common/metadata/visitor-semantic-validator.cpp b/src/plugins/ctf/common/metadata/visitor-semantic-validator.cpp index 14025eb7..d2d084df 100644 --- a/src/plugins/ctf/common/metadata/visitor-semantic-validator.cpp +++ b/src/plugins/ctf/common/metadata/visitor-semantic-validator.cpp @@ -7,8 +7,8 @@ */ #define BT_COMP_LOG_SELF_COMP (log_cfg->self_comp) -#define BT_LOG_OUTPUT_LEVEL (log_cfg->log_level) -#define BT_LOG_TAG "PLUGIN/CTF/META/SEMANTIC-VALIDATOR-VISITOR" +#define BT_LOG_OUTPUT_LEVEL (log_cfg->log_level) +#define BT_LOG_TAG "PLUGIN/CTF/META/SEMANTIC-VALIDATOR-VISITOR" #include "logging/comp-logging.h" #include @@ -24,1016 +24,981 @@ #include "ast.hpp" #include "logging.hpp" -#define _bt_list_first_entry(ptr, type, member) \ - bt_list_entry((ptr)->next, type, member) +#define _bt_list_first_entry(ptr, type, member) bt_list_entry((ptr)->next, type, member) -static -int _ctf_visitor_semantic_check(int depth, struct ctf_node *node, - struct meta_log_config *log_cfg); +static int _ctf_visitor_semantic_check(int depth, struct ctf_node *node, + struct meta_log_config *log_cfg); -static -int ctf_visitor_unary_expression(int depth, struct ctf_node *node, - struct meta_log_config *log_cfg) +static int ctf_visitor_unary_expression(int depth, struct ctf_node *node, + struct meta_log_config *log_cfg) { - struct ctf_node *iter; - int is_ctf_exp = 0, is_ctf_exp_left = 0; - - switch (node->parent->type) { - case NODE_CTF_EXPRESSION: - is_ctf_exp = 1; - bt_list_for_each_entry(iter, &node->parent->u.ctf_expression.left, - siblings) { - if (iter == node) { - is_ctf_exp_left = 1; - /* - * We are a left child of a ctf expression. - * We are only allowed to be a string. - */ - if (node->u.unary_expression.type != UNARY_STRING) { - _BT_COMP_LOGE_APPEND_CAUSE_LINENO(node->lineno, - "Left child of a CTF expression is only allowed to be a string."); - goto errperm; - } - break; - } - } - /* Right child of a ctf expression can be any type of unary exp. */ - break; /* OK */ - case NODE_TYPE_DECLARATOR: - /* - * We are the length of a type declarator. - */ - switch (node->u.unary_expression.type) { - case UNARY_UNSIGNED_CONSTANT: - case UNARY_STRING: - break; - default: - _BT_COMP_LOGE_APPEND_CAUSE_LINENO(node->lineno, - "Children of field class declarator and `enum` can only be unsigned numeric constants or references to fields (e.g., `a.b.c`)."); - goto errperm; - } - break; /* OK */ - - case NODE_STRUCT: - /* - * We are the size of a struct align attribute. - */ - switch (node->u.unary_expression.type) { - case UNARY_UNSIGNED_CONSTANT: - break; - default: - _BT_COMP_LOGE_APPEND_CAUSE_LINENO(node->lineno, - "Structure alignment attribute can only be an unsigned numeric constant."); - goto errperm; - } - break; - - case NODE_ENUMERATOR: - /* The enumerator's parent has validated its validity already. */ - break; /* OK */ - - case NODE_UNARY_EXPRESSION: - /* - * We disallow nested unary expressions and "sbrac" unary - * expressions. - */ - _BT_COMP_LOGE_APPEND_CAUSE_LINENO(node->lineno, - "Nested unary expressions not allowed (`()` and `[]`)."); - goto errperm; - - case NODE_ROOT: - case NODE_EVENT: - case NODE_STREAM: - case NODE_ENV: - case NODE_TRACE: - case NODE_CLOCK: - case NODE_CALLSITE: - case NODE_TYPEDEF: - case NODE_TYPEALIAS_TARGET: - case NODE_TYPEALIAS_ALIAS: - case NODE_TYPEALIAS: - case NODE_TYPE_SPECIFIER: - case NODE_POINTER: - case NODE_FLOATING_POINT: - case NODE_INTEGER: - case NODE_STRING: - case NODE_ENUM: - case NODE_STRUCT_OR_VARIANT_DECLARATION: - case NODE_VARIANT: - default: - goto errinval; - } - - switch (node->u.unary_expression.link) { - case UNARY_LINK_UNKNOWN: - /* We don't allow empty link except on the first node of the list */ - if (is_ctf_exp && _bt_list_first_entry(is_ctf_exp_left ? - &node->parent->u.ctf_expression.left : - &node->parent->u.ctf_expression.right, - struct ctf_node, - siblings) != node) { - _BT_COMP_LOGE_APPEND_CAUSE_LINENO(node->lineno, - "Empty link is not allowed except on first node of unary expression (need to separate nodes with `.` or `->`)."); - goto errperm; - } - break; /* OK */ - case UNARY_DOTLINK: - case UNARY_ARROWLINK: - /* We only allow -> and . links between children of ctf_expression. */ - if (node->parent->type != NODE_CTF_EXPRESSION) { - _BT_COMP_LOGE_APPEND_CAUSE_LINENO(node->lineno, - "Links `.` and `->` are only allowed as children of CTF expression."); - goto errperm; - } - /* - * Only strings can be separated linked by . or ->. - * This includes "", '' and non-quoted identifiers. - */ - if (node->u.unary_expression.type != UNARY_STRING) { - _BT_COMP_LOGE_APPEND_CAUSE_LINENO(node->lineno, - "Links `.` and `->` are only allowed to separate strings and identifiers."); - goto errperm; - } - /* We don't allow link on the first node of the list */ - if (is_ctf_exp && _bt_list_first_entry(is_ctf_exp_left ? - &node->parent->u.ctf_expression.left : - &node->parent->u.ctf_expression.right, - struct ctf_node, - siblings) == node) { - _BT_COMP_LOGE_APPEND_CAUSE_LINENO(node->lineno, - "Links `.` and `->` are not allowed before first node of the unary expression list."); - goto errperm; - } - break; - case UNARY_DOTDOTDOT: - /* We only allow ... link between children of enumerator. */ - if (node->parent->type != NODE_ENUMERATOR) { - _BT_COMP_LOGE_APPEND_CAUSE_LINENO(node->lineno, - "Link `...` is only allowed within enumerator."); - goto errperm; - } - /* We don't allow link on the first node of the list */ - if (_bt_list_first_entry(&node->parent->u.enumerator.values, - struct ctf_node, - siblings) == node) { - _BT_COMP_LOGE_APPEND_CAUSE_LINENO(node->lineno, - "Link `...` is not allowed on the first node of the unary expression list."); - goto errperm; - } - break; - default: - _BT_COMP_LOGE_APPEND_CAUSE_LINENO(node->lineno, - "Unknown expression link type: type=%d", - node->u.unary_expression.link); - return -EINVAL; - } - return 0; + struct ctf_node *iter; + int is_ctf_exp = 0, is_ctf_exp_left = 0; + + switch (node->parent->type) { + case NODE_CTF_EXPRESSION: + is_ctf_exp = 1; + bt_list_for_each_entry (iter, &node->parent->u.ctf_expression.left, siblings) { + if (iter == node) { + is_ctf_exp_left = 1; + /* + * We are a left child of a ctf expression. + * We are only allowed to be a string. + */ + if (node->u.unary_expression.type != UNARY_STRING) { + _BT_COMP_LOGE_APPEND_CAUSE_LINENO( + node->lineno, + "Left child of a CTF expression is only allowed to be a string."); + goto errperm; + } + break; + } + } + /* Right child of a ctf expression can be any type of unary exp. */ + break; /* OK */ + case NODE_TYPE_DECLARATOR: + /* + * We are the length of a type declarator. + */ + switch (node->u.unary_expression.type) { + case UNARY_UNSIGNED_CONSTANT: + case UNARY_STRING: + break; + default: + _BT_COMP_LOGE_APPEND_CAUSE_LINENO( + node->lineno, + "Children of field class declarator and `enum` can only be unsigned numeric constants or references to fields (e.g., `a.b.c`)."); + goto errperm; + } + break; /* OK */ + + case NODE_STRUCT: + /* + * We are the size of a struct align attribute. + */ + switch (node->u.unary_expression.type) { + case UNARY_UNSIGNED_CONSTANT: + break; + default: + _BT_COMP_LOGE_APPEND_CAUSE_LINENO( + node->lineno, + "Structure alignment attribute can only be an unsigned numeric constant."); + goto errperm; + } + break; + + case NODE_ENUMERATOR: + /* The enumerator's parent has validated its validity already. */ + break; /* OK */ + + case NODE_UNARY_EXPRESSION: + /* + * We disallow nested unary expressions and "sbrac" unary + * expressions. + */ + _BT_COMP_LOGE_APPEND_CAUSE_LINENO(node->lineno, + "Nested unary expressions not allowed (`()` and `[]`)."); + goto errperm; + + case NODE_ROOT: + case NODE_EVENT: + case NODE_STREAM: + case NODE_ENV: + case NODE_TRACE: + case NODE_CLOCK: + case NODE_CALLSITE: + case NODE_TYPEDEF: + case NODE_TYPEALIAS_TARGET: + case NODE_TYPEALIAS_ALIAS: + case NODE_TYPEALIAS: + case NODE_TYPE_SPECIFIER: + case NODE_POINTER: + case NODE_FLOATING_POINT: + case NODE_INTEGER: + case NODE_STRING: + case NODE_ENUM: + case NODE_STRUCT_OR_VARIANT_DECLARATION: + case NODE_VARIANT: + default: + goto errinval; + } + + switch (node->u.unary_expression.link) { + case UNARY_LINK_UNKNOWN: + /* We don't allow empty link except on the first node of the list */ + if (is_ctf_exp && + _bt_list_first_entry(is_ctf_exp_left ? &node->parent->u.ctf_expression.left : + &node->parent->u.ctf_expression.right, + struct ctf_node, siblings) != node) { + _BT_COMP_LOGE_APPEND_CAUSE_LINENO( + node->lineno, + "Empty link is not allowed except on first node of unary expression (need to separate nodes with `.` or `->`)."); + goto errperm; + } + break; /* OK */ + case UNARY_DOTLINK: + case UNARY_ARROWLINK: + /* We only allow -> and . links between children of ctf_expression. */ + if (node->parent->type != NODE_CTF_EXPRESSION) { + _BT_COMP_LOGE_APPEND_CAUSE_LINENO( + node->lineno, "Links `.` and `->` are only allowed as children of CTF expression."); + goto errperm; + } + /* + * Only strings can be separated linked by . or ->. + * This includes "", '' and non-quoted identifiers. + */ + if (node->u.unary_expression.type != UNARY_STRING) { + _BT_COMP_LOGE_APPEND_CAUSE_LINENO( + node->lineno, + "Links `.` and `->` are only allowed to separate strings and identifiers."); + goto errperm; + } + /* We don't allow link on the first node of the list */ + if (is_ctf_exp && + _bt_list_first_entry(is_ctf_exp_left ? &node->parent->u.ctf_expression.left : + &node->parent->u.ctf_expression.right, + struct ctf_node, siblings) == node) { + _BT_COMP_LOGE_APPEND_CAUSE_LINENO( + node->lineno, + "Links `.` and `->` are not allowed before first node of the unary expression list."); + goto errperm; + } + break; + case UNARY_DOTDOTDOT: + /* We only allow ... link between children of enumerator. */ + if (node->parent->type != NODE_ENUMERATOR) { + _BT_COMP_LOGE_APPEND_CAUSE_LINENO(node->lineno, + "Link `...` is only allowed within enumerator."); + goto errperm; + } + /* We don't allow link on the first node of the list */ + if (_bt_list_first_entry(&node->parent->u.enumerator.values, struct ctf_node, siblings) == + node) { + _BT_COMP_LOGE_APPEND_CAUSE_LINENO( + node->lineno, + "Link `...` is not allowed on the first node of the unary expression list."); + goto errperm; + } + break; + default: + _BT_COMP_LOGE_APPEND_CAUSE_LINENO(node->lineno, "Unknown expression link type: type=%d", + node->u.unary_expression.link); + return -EINVAL; + } + return 0; errinval: - _BT_COMP_LOGE_APPEND_CAUSE_LINENO(node->lineno, - "Incoherent parent node's type: node-type=%s, parent-node-type=%s", - node_type(node), node_type(node->parent)); - return -EINVAL; /* Incoherent structure */ + _BT_COMP_LOGE_APPEND_CAUSE_LINENO( + node->lineno, "Incoherent parent node's type: node-type=%s, parent-node-type=%s", + node_type(node), node_type(node->parent)); + return -EINVAL; /* Incoherent structure */ errperm: - _BT_COMP_LOGE_APPEND_CAUSE_LINENO(node->lineno, - "Semantic error: node-type=%s, parent-node-type=%s", - node_type(node), node_type(node->parent)); - return -EPERM; /* Structure not allowed */ + _BT_COMP_LOGE_APPEND_CAUSE_LINENO(node->lineno, + "Semantic error: node-type=%s, parent-node-type=%s", + node_type(node), node_type(node->parent)); + return -EPERM; /* Structure not allowed */ } -static -int ctf_visitor_field_class_specifier_list(int depth, struct ctf_node *node, - struct meta_log_config *log_cfg) +static int ctf_visitor_field_class_specifier_list(int depth, struct ctf_node *node, + struct meta_log_config *log_cfg) { - switch (node->parent->type) { - case NODE_CTF_EXPRESSION: - case NODE_TYPE_DECLARATOR: - case NODE_TYPEDEF: - case NODE_TYPEALIAS_TARGET: - case NODE_TYPEALIAS_ALIAS: - case NODE_ENUM: - case NODE_STRUCT_OR_VARIANT_DECLARATION: - case NODE_ROOT: - break; /* OK */ - - case NODE_EVENT: - case NODE_STREAM: - case NODE_ENV: - case NODE_TRACE: - case NODE_CLOCK: - case NODE_CALLSITE: - case NODE_UNARY_EXPRESSION: - case NODE_TYPEALIAS: - case NODE_TYPE_SPECIFIER: - case NODE_TYPE_SPECIFIER_LIST: - case NODE_POINTER: - case NODE_FLOATING_POINT: - case NODE_INTEGER: - case NODE_STRING: - case NODE_ENUMERATOR: - case NODE_VARIANT: - case NODE_STRUCT: - default: - goto errinval; - } - return 0; + switch (node->parent->type) { + case NODE_CTF_EXPRESSION: + case NODE_TYPE_DECLARATOR: + case NODE_TYPEDEF: + case NODE_TYPEALIAS_TARGET: + case NODE_TYPEALIAS_ALIAS: + case NODE_ENUM: + case NODE_STRUCT_OR_VARIANT_DECLARATION: + case NODE_ROOT: + break; /* OK */ + + case NODE_EVENT: + case NODE_STREAM: + case NODE_ENV: + case NODE_TRACE: + case NODE_CLOCK: + case NODE_CALLSITE: + case NODE_UNARY_EXPRESSION: + case NODE_TYPEALIAS: + case NODE_TYPE_SPECIFIER: + case NODE_TYPE_SPECIFIER_LIST: + case NODE_POINTER: + case NODE_FLOATING_POINT: + case NODE_INTEGER: + case NODE_STRING: + case NODE_ENUMERATOR: + case NODE_VARIANT: + case NODE_STRUCT: + default: + goto errinval; + } + return 0; errinval: - _BT_COMP_LOGE_APPEND_CAUSE_LINENO(node->lineno, - "Incoherent parent node's type: node-type=%s, parent-node-type=%s", - node_type(node), node_type(node->parent)); - return -EINVAL; /* Incoherent structure */ + _BT_COMP_LOGE_APPEND_CAUSE_LINENO( + node->lineno, "Incoherent parent node's type: node-type=%s, parent-node-type=%s", + node_type(node), node_type(node->parent)); + return -EINVAL; /* Incoherent structure */ } -static -int ctf_visitor_field_class_specifier(int depth, struct ctf_node *node, - struct meta_log_config *log_cfg) +static int ctf_visitor_field_class_specifier(int depth, struct ctf_node *node, + struct meta_log_config *log_cfg) { - switch (node->parent->type) { - case NODE_TYPE_SPECIFIER_LIST: - break; /* OK */ - - case NODE_CTF_EXPRESSION: - case NODE_TYPE_DECLARATOR: - case NODE_TYPEDEF: - case NODE_TYPEALIAS_TARGET: - case NODE_TYPEALIAS_ALIAS: - case NODE_ENUM: - case NODE_STRUCT_OR_VARIANT_DECLARATION: - case NODE_ROOT: - case NODE_EVENT: - case NODE_STREAM: - case NODE_ENV: - case NODE_TRACE: - case NODE_CLOCK: - case NODE_CALLSITE: - case NODE_UNARY_EXPRESSION: - case NODE_TYPEALIAS: - case NODE_TYPE_SPECIFIER: - case NODE_POINTER: - case NODE_FLOATING_POINT: - case NODE_INTEGER: - case NODE_STRING: - case NODE_ENUMERATOR: - case NODE_VARIANT: - case NODE_STRUCT: - default: - goto errinval; - } - return 0; + switch (node->parent->type) { + case NODE_TYPE_SPECIFIER_LIST: + break; /* OK */ + + case NODE_CTF_EXPRESSION: + case NODE_TYPE_DECLARATOR: + case NODE_TYPEDEF: + case NODE_TYPEALIAS_TARGET: + case NODE_TYPEALIAS_ALIAS: + case NODE_ENUM: + case NODE_STRUCT_OR_VARIANT_DECLARATION: + case NODE_ROOT: + case NODE_EVENT: + case NODE_STREAM: + case NODE_ENV: + case NODE_TRACE: + case NODE_CLOCK: + case NODE_CALLSITE: + case NODE_UNARY_EXPRESSION: + case NODE_TYPEALIAS: + case NODE_TYPE_SPECIFIER: + case NODE_POINTER: + case NODE_FLOATING_POINT: + case NODE_INTEGER: + case NODE_STRING: + case NODE_ENUMERATOR: + case NODE_VARIANT: + case NODE_STRUCT: + default: + goto errinval; + } + return 0; errinval: - _BT_COMP_LOGE_APPEND_CAUSE_LINENO(node->lineno, - "Incoherent parent node's type: node-type=%s, parent-node-type=%s", - node_type(node), node_type(node->parent)); - return -EINVAL; /* Incoherent structure */ + _BT_COMP_LOGE_APPEND_CAUSE_LINENO( + node->lineno, "Incoherent parent node's type: node-type=%s, parent-node-type=%s", + node_type(node), node_type(node->parent)); + return -EINVAL; /* Incoherent structure */ } -static -int ctf_visitor_field_class_declarator(int depth, struct ctf_node *node, - struct meta_log_config *log_cfg) +static int ctf_visitor_field_class_declarator(int depth, struct ctf_node *node, + struct meta_log_config *log_cfg) { - int ret = 0; - struct ctf_node *iter; - - depth++; - - switch (node->parent->type) { - case NODE_TYPE_DECLARATOR: - /* - * A nested field class declarator is not allowed to - * contain pointers. - */ - if (!bt_list_empty(&node->u.field_class_declarator.pointers)) - goto errperm; - break; /* OK */ - case NODE_TYPEALIAS_TARGET: - break; /* OK */ - case NODE_TYPEALIAS_ALIAS: - /* - * Only accept alias name containing: - * - identifier - * - identifier * (any number of pointers) - * NOT accepting alias names containing [] (would otherwise - * cause semantic clash for later declarations of - * arrays/sequences of elements, where elements could be - * arrays/sequences themselves (if allowed in field class alias). - * NOT accepting alias with identifier. The declarator should - * be either empty or contain pointer(s). - */ - if (node->u.field_class_declarator.type == TYPEDEC_NESTED) - goto errperm; - bt_list_for_each_entry(iter, &node->parent->u.field_class_alias_name.field_class_specifier_list->u.field_class_specifier_list.head, - siblings) { - switch (iter->u.field_class_specifier.type) { - case TYPESPEC_FLOATING_POINT: - case TYPESPEC_INTEGER: - case TYPESPEC_STRING: - case TYPESPEC_STRUCT: - case TYPESPEC_VARIANT: - case TYPESPEC_ENUM: - if (bt_list_empty(&node->u.field_class_declarator.pointers)) - goto errperm; - break; - default: - break; - } - } - if (node->u.field_class_declarator.type == TYPEDEC_ID && - node->u.field_class_declarator.u.id) - goto errperm; - break; /* OK */ - case NODE_TYPEDEF: - case NODE_STRUCT_OR_VARIANT_DECLARATION: - break; /* OK */ - - case NODE_ROOT: - case NODE_EVENT: - case NODE_STREAM: - case NODE_ENV: - case NODE_TRACE: - case NODE_CLOCK: - case NODE_CALLSITE: - case NODE_CTF_EXPRESSION: - case NODE_UNARY_EXPRESSION: - case NODE_TYPEALIAS: - case NODE_TYPE_SPECIFIER: - case NODE_POINTER: - case NODE_FLOATING_POINT: - case NODE_INTEGER: - case NODE_STRING: - case NODE_ENUMERATOR: - case NODE_ENUM: - case NODE_VARIANT: - case NODE_STRUCT: - default: - goto errinval; - } - - bt_list_for_each_entry(iter, &node->u.field_class_declarator.pointers, - siblings) { - ret = _ctf_visitor_semantic_check(depth + 1, iter, log_cfg); - if (ret) - return ret; - } - - switch (node->u.field_class_declarator.type) { - case TYPEDEC_ID: - break; - case TYPEDEC_NESTED: - { - if (node->u.field_class_declarator.u.nested.field_class_declarator) { - ret = _ctf_visitor_semantic_check(depth + 1, - node->u.field_class_declarator.u.nested.field_class_declarator, - log_cfg); - if (ret) - return ret; - } - if (!node->u.field_class_declarator.u.nested.abstract_array) { - bt_list_for_each_entry(iter, &node->u.field_class_declarator.u.nested.length, - siblings) { - if (iter->type != NODE_UNARY_EXPRESSION) { - _BT_COMP_LOGE_APPEND_CAUSE_LINENO(node->lineno, - "Expecting unary expression as length: node-type=%s", - node_type(iter)); - return -EINVAL; - } - ret = _ctf_visitor_semantic_check(depth + 1, - iter, log_cfg); - if (ret) - return ret; - } - } else { - if (node->parent->type == NODE_TYPEALIAS_TARGET) { - _BT_COMP_LOGE_APPEND_CAUSE_LINENO(node->lineno, - "Abstract array declarator not permitted as target of field class alias."); - return -EINVAL; - } - } - if (node->u.field_class_declarator.bitfield_len) { - ret = _ctf_visitor_semantic_check(depth + 1, - node->u.field_class_declarator.bitfield_len, - log_cfg); - if (ret) - return ret; - } - break; - } - case TYPEDEC_UNKNOWN: - default: - _BT_COMP_LOGE_APPEND_CAUSE_LINENO(node->lineno, - "Unknown field class declarator: type=%d", - node->u.field_class_declarator.type); - return -EINVAL; - } - depth--; - return 0; + int ret = 0; + struct ctf_node *iter; + + depth++; + + switch (node->parent->type) { + case NODE_TYPE_DECLARATOR: + /* + * A nested field class declarator is not allowed to + * contain pointers. + */ + if (!bt_list_empty(&node->u.field_class_declarator.pointers)) + goto errperm; + break; /* OK */ + case NODE_TYPEALIAS_TARGET: + break; /* OK */ + case NODE_TYPEALIAS_ALIAS: + /* + * Only accept alias name containing: + * - identifier + * - identifier * (any number of pointers) + * NOT accepting alias names containing [] (would otherwise + * cause semantic clash for later declarations of + * arrays/sequences of elements, where elements could be + * arrays/sequences themselves (if allowed in field class alias). + * NOT accepting alias with identifier. The declarator should + * be either empty or contain pointer(s). + */ + if (node->u.field_class_declarator.type == TYPEDEC_NESTED) + goto errperm; + bt_list_for_each_entry (iter, + &node->parent->u.field_class_alias_name.field_class_specifier_list + ->u.field_class_specifier_list.head, + siblings) { + switch (iter->u.field_class_specifier.type) { + case TYPESPEC_FLOATING_POINT: + case TYPESPEC_INTEGER: + case TYPESPEC_STRING: + case TYPESPEC_STRUCT: + case TYPESPEC_VARIANT: + case TYPESPEC_ENUM: + if (bt_list_empty(&node->u.field_class_declarator.pointers)) + goto errperm; + break; + default: + break; + } + } + if (node->u.field_class_declarator.type == TYPEDEC_ID && + node->u.field_class_declarator.u.id) + goto errperm; + break; /* OK */ + case NODE_TYPEDEF: + case NODE_STRUCT_OR_VARIANT_DECLARATION: + break; /* OK */ + + case NODE_ROOT: + case NODE_EVENT: + case NODE_STREAM: + case NODE_ENV: + case NODE_TRACE: + case NODE_CLOCK: + case NODE_CALLSITE: + case NODE_CTF_EXPRESSION: + case NODE_UNARY_EXPRESSION: + case NODE_TYPEALIAS: + case NODE_TYPE_SPECIFIER: + case NODE_POINTER: + case NODE_FLOATING_POINT: + case NODE_INTEGER: + case NODE_STRING: + case NODE_ENUMERATOR: + case NODE_ENUM: + case NODE_VARIANT: + case NODE_STRUCT: + default: + goto errinval; + } + + bt_list_for_each_entry (iter, &node->u.field_class_declarator.pointers, siblings) { + ret = _ctf_visitor_semantic_check(depth + 1, iter, log_cfg); + if (ret) + return ret; + } + + switch (node->u.field_class_declarator.type) { + case TYPEDEC_ID: + break; + case TYPEDEC_NESTED: + { + if (node->u.field_class_declarator.u.nested.field_class_declarator) { + ret = _ctf_visitor_semantic_check( + depth + 1, node->u.field_class_declarator.u.nested.field_class_declarator, log_cfg); + if (ret) + return ret; + } + if (!node->u.field_class_declarator.u.nested.abstract_array) { + bt_list_for_each_entry (iter, &node->u.field_class_declarator.u.nested.length, + siblings) { + if (iter->type != NODE_UNARY_EXPRESSION) { + _BT_COMP_LOGE_APPEND_CAUSE_LINENO( + node->lineno, "Expecting unary expression as length: node-type=%s", + node_type(iter)); + return -EINVAL; + } + ret = _ctf_visitor_semantic_check(depth + 1, iter, log_cfg); + if (ret) + return ret; + } + } else { + if (node->parent->type == NODE_TYPEALIAS_TARGET) { + _BT_COMP_LOGE_APPEND_CAUSE_LINENO( + node->lineno, + "Abstract array declarator not permitted as target of field class alias."); + return -EINVAL; + } + } + if (node->u.field_class_declarator.bitfield_len) { + ret = _ctf_visitor_semantic_check(depth + 1, + node->u.field_class_declarator.bitfield_len, log_cfg); + if (ret) + return ret; + } + break; + } + case TYPEDEC_UNKNOWN: + default: + _BT_COMP_LOGE_APPEND_CAUSE_LINENO(node->lineno, "Unknown field class declarator: type=%d", + node->u.field_class_declarator.type); + return -EINVAL; + } + depth--; + return 0; errinval: - _BT_COMP_LOGE_APPEND_CAUSE_LINENO(node->lineno, - "Incoherent parent node's type: node-type=%s, parent-node-type=%s", - node_type(node), node_type(node->parent)); - return -EINVAL; /* Incoherent structure */ + _BT_COMP_LOGE_APPEND_CAUSE_LINENO( + node->lineno, "Incoherent parent node's type: node-type=%s, parent-node-type=%s", + node_type(node), node_type(node->parent)); + return -EINVAL; /* Incoherent structure */ errperm: - _BT_COMP_LOGE_APPEND_CAUSE_LINENO(node->lineno, - "Semantic error: node-type=%s, parent-node-type=%s", - node_type(node), node_type(node->parent)); - return -EPERM; /* Structure not allowed */ + _BT_COMP_LOGE_APPEND_CAUSE_LINENO(node->lineno, + "Semantic error: node-type=%s, parent-node-type=%s", + node_type(node), node_type(node->parent)); + return -EPERM; /* Structure not allowed */ } -static -int _ctf_visitor_semantic_check(int depth, struct ctf_node *node, - struct meta_log_config *log_cfg) +static int _ctf_visitor_semantic_check(int depth, struct ctf_node *node, + struct meta_log_config *log_cfg) { - int ret = 0; - struct ctf_node *iter; - - if (node->visited) - return 0; - - switch (node->type) { - case NODE_ROOT: - bt_list_for_each_entry(iter, &node->u.root.declaration_list, siblings) { - ret = _ctf_visitor_semantic_check(depth + 1, iter, - log_cfg); - if (ret) - return ret; - } - bt_list_for_each_entry(iter, &node->u.root.trace, siblings) { - ret = _ctf_visitor_semantic_check(depth + 1, iter, - log_cfg); - if (ret) - return ret; - } - bt_list_for_each_entry(iter, &node->u.root.stream, siblings) { - ret = _ctf_visitor_semantic_check(depth + 1, iter, - log_cfg); - if (ret) - return ret; - } - bt_list_for_each_entry(iter, &node->u.root.event, siblings) { - ret = _ctf_visitor_semantic_check(depth + 1, iter, - log_cfg); - if (ret) - return ret; - } - break; - - case NODE_EVENT: - switch (node->parent->type) { - case NODE_ROOT: - break; /* OK */ - default: - goto errinval; - } - - bt_list_for_each_entry(iter, &node->u.event.declaration_list, siblings) { - ret = _ctf_visitor_semantic_check(depth + 1, iter, - log_cfg); - if (ret) - return ret; - } - break; - case NODE_STREAM: - switch (node->parent->type) { - case NODE_ROOT: - break; /* OK */ - default: - goto errinval; - } - - bt_list_for_each_entry(iter, &node->u.stream.declaration_list, siblings) { - ret = _ctf_visitor_semantic_check(depth + 1, iter, - log_cfg); - if (ret) - return ret; - } - break; - case NODE_ENV: - switch (node->parent->type) { - case NODE_ROOT: - break; /* OK */ - default: - goto errinval; - } - - bt_list_for_each_entry(iter, &node->u.env.declaration_list, siblings) { - ret = _ctf_visitor_semantic_check(depth + 1, iter, - log_cfg); - if (ret) - return ret; - } - break; - case NODE_TRACE: - switch (node->parent->type) { - case NODE_ROOT: - break; /* OK */ - default: - goto errinval; - } - - bt_list_for_each_entry(iter, &node->u.trace.declaration_list, siblings) { - ret = _ctf_visitor_semantic_check(depth + 1, iter, - log_cfg); - if (ret) - return ret; - } - break; - case NODE_CLOCK: - switch (node->parent->type) { - case NODE_ROOT: - break; /* OK */ - default: - goto errinval; - } - - bt_list_for_each_entry(iter, &node->u.clock.declaration_list, siblings) { - ret = _ctf_visitor_semantic_check(depth + 1, iter, - log_cfg); - if (ret) - return ret; - } - break; - case NODE_CALLSITE: - switch (node->parent->type) { - case NODE_ROOT: - break; /* OK */ - default: - goto errinval; - } - - bt_list_for_each_entry(iter, &node->u.callsite.declaration_list, siblings) { - ret = _ctf_visitor_semantic_check(depth + 1, iter, - log_cfg); - if (ret) - return ret; - } - break; - - case NODE_CTF_EXPRESSION: - switch (node->parent->type) { - case NODE_ROOT: - case NODE_EVENT: - case NODE_STREAM: - case NODE_ENV: - case NODE_TRACE: - case NODE_CLOCK: - case NODE_CALLSITE: - case NODE_FLOATING_POINT: - case NODE_INTEGER: - case NODE_STRING: - break; /* OK */ - - case NODE_CTF_EXPRESSION: - case NODE_UNARY_EXPRESSION: - case NODE_TYPEDEF: - case NODE_TYPEALIAS_TARGET: - case NODE_TYPEALIAS_ALIAS: - case NODE_STRUCT_OR_VARIANT_DECLARATION: - case NODE_TYPEALIAS: - case NODE_TYPE_SPECIFIER: - case NODE_TYPE_SPECIFIER_LIST: - case NODE_POINTER: - case NODE_TYPE_DECLARATOR: - case NODE_ENUMERATOR: - case NODE_ENUM: - case NODE_VARIANT: - case NODE_STRUCT: - default: - goto errinval; - } - - depth++; - bt_list_for_each_entry(iter, &node->u.ctf_expression.left, siblings) { - ret = _ctf_visitor_semantic_check(depth + 1, iter, - log_cfg); - if (ret) - return ret; - } - bt_list_for_each_entry(iter, &node->u.ctf_expression.right, siblings) { - ret = _ctf_visitor_semantic_check(depth + 1, iter, - log_cfg); - if (ret) - return ret; - } - depth--; - break; - case NODE_UNARY_EXPRESSION: - return ctf_visitor_unary_expression(depth, node, log_cfg); - - case NODE_TYPEDEF: - switch (node->parent->type) { - case NODE_ROOT: - case NODE_EVENT: - case NODE_STREAM: - case NODE_TRACE: - case NODE_VARIANT: - case NODE_STRUCT: - break; /* OK */ - - case NODE_CTF_EXPRESSION: - case NODE_UNARY_EXPRESSION: - case NODE_TYPEDEF: - case NODE_TYPEALIAS_TARGET: - case NODE_TYPEALIAS_ALIAS: - case NODE_TYPEALIAS: - case NODE_STRUCT_OR_VARIANT_DECLARATION: - case NODE_TYPE_SPECIFIER: - case NODE_TYPE_SPECIFIER_LIST: - case NODE_POINTER: - case NODE_TYPE_DECLARATOR: - case NODE_FLOATING_POINT: - case NODE_INTEGER: - case NODE_STRING: - case NODE_ENUMERATOR: - case NODE_ENUM: - case NODE_CLOCK: - case NODE_CALLSITE: - case NODE_ENV: - default: - goto errinval; - } - - depth++; - ret = _ctf_visitor_semantic_check(depth + 1, - node->u.field_class_def.field_class_specifier_list, - log_cfg); - if (ret) - return ret; - bt_list_for_each_entry(iter, &node->u.field_class_def.field_class_declarators, siblings) { - ret = _ctf_visitor_semantic_check(depth + 1, iter, - log_cfg); - if (ret) - return ret; - } - depth--; - break; - case NODE_TYPEALIAS_TARGET: - { - int nr_declarators; - - switch (node->parent->type) { - case NODE_TYPEALIAS: - break; /* OK */ - default: - goto errinval; - } - - depth++; - ret = _ctf_visitor_semantic_check(depth + 1, - node->u.field_class_alias_target.field_class_specifier_list, - log_cfg); - if (ret) - return ret; - nr_declarators = 0; - bt_list_for_each_entry(iter, &node->u.field_class_alias_target.field_class_declarators, siblings) { - ret = _ctf_visitor_semantic_check(depth + 1, iter, - log_cfg); - if (ret) - return ret; - nr_declarators++; - } - if (nr_declarators > 1) { - _BT_COMP_LOGE_APPEND_CAUSE_LINENO(node->lineno, - "Too many declarators in field class alias's name (maximum is 1): count=%d", - nr_declarators); - return -EINVAL; - } - depth--; - break; - } - case NODE_TYPEALIAS_ALIAS: - { - int nr_declarators; - - switch (node->parent->type) { - case NODE_TYPEALIAS: - break; /* OK */ - default: - goto errinval; - } - - depth++; - ret = _ctf_visitor_semantic_check(depth + 1, - node->u.field_class_alias_name.field_class_specifier_list, - log_cfg); - if (ret) - return ret; - nr_declarators = 0; - bt_list_for_each_entry(iter, &node->u.field_class_alias_name.field_class_declarators, siblings) { - ret = _ctf_visitor_semantic_check(depth + 1, iter, - log_cfg); - if (ret) - return ret; - nr_declarators++; - } - if (nr_declarators > 1) { - _BT_COMP_LOGE_APPEND_CAUSE_LINENO(node->lineno, - "Too many declarators in field class alias's name (maximum is 1): count=%d", - nr_declarators); - return -EINVAL; - } - depth--; - break; - } - case NODE_TYPEALIAS: - switch (node->parent->type) { - case NODE_ROOT: - case NODE_EVENT: - case NODE_STREAM: - case NODE_TRACE: - case NODE_VARIANT: - case NODE_STRUCT: - break; /* OK */ - - case NODE_CTF_EXPRESSION: - case NODE_UNARY_EXPRESSION: - case NODE_TYPEDEF: - case NODE_TYPEALIAS_TARGET: - case NODE_TYPEALIAS_ALIAS: - case NODE_TYPEALIAS: - case NODE_STRUCT_OR_VARIANT_DECLARATION: - case NODE_TYPE_SPECIFIER: - case NODE_TYPE_SPECIFIER_LIST: - case NODE_POINTER: - case NODE_TYPE_DECLARATOR: - case NODE_FLOATING_POINT: - case NODE_INTEGER: - case NODE_STRING: - case NODE_ENUMERATOR: - case NODE_ENUM: - case NODE_CLOCK: - case NODE_CALLSITE: - case NODE_ENV: - default: - goto errinval; - } - - ret = _ctf_visitor_semantic_check(depth + 1, - node->u.field_class_alias.target, log_cfg); - if (ret) - return ret; - ret = _ctf_visitor_semantic_check(depth + 1, - node->u.field_class_alias.alias, log_cfg); - if (ret) - return ret; - break; - - case NODE_TYPE_SPECIFIER_LIST: - ret = ctf_visitor_field_class_specifier_list(depth, node, - log_cfg); - if (ret) - return ret; - break; - case NODE_TYPE_SPECIFIER: - ret = ctf_visitor_field_class_specifier(depth, node, - log_cfg); - if (ret) - return ret; - break; - case NODE_POINTER: - switch (node->parent->type) { - case NODE_TYPE_DECLARATOR: - break; /* OK */ - default: - goto errinval; - } - break; - case NODE_TYPE_DECLARATOR: - ret = ctf_visitor_field_class_declarator(depth, node, - log_cfg); - if (ret) - return ret; - break; - - case NODE_FLOATING_POINT: - switch (node->parent->type) { - case NODE_TYPE_SPECIFIER: - break; /* OK */ - default: - goto errinval; - - case NODE_UNARY_EXPRESSION: - goto errperm; - } - bt_list_for_each_entry(iter, &node->u.floating_point.expressions, siblings) { - ret = _ctf_visitor_semantic_check(depth + 1, iter, - log_cfg); - if (ret) - return ret; - } - break; - case NODE_INTEGER: - switch (node->parent->type) { - case NODE_TYPE_SPECIFIER: - break; /* OK */ - default: - goto errinval; - - } - - bt_list_for_each_entry(iter, &node->u.integer.expressions, siblings) { - ret = _ctf_visitor_semantic_check(depth + 1, iter, - log_cfg); - if (ret) - return ret; - } - break; - case NODE_STRING: - switch (node->parent->type) { - case NODE_TYPE_SPECIFIER: - break; /* OK */ - default: - goto errinval; - - case NODE_UNARY_EXPRESSION: - goto errperm; - } - - bt_list_for_each_entry(iter, &node->u.string.expressions, siblings) { - ret = _ctf_visitor_semantic_check(depth + 1, iter, - log_cfg); - if (ret) - return ret; - } - break; - case NODE_ENUMERATOR: - switch (node->parent->type) { - case NODE_ENUM: - break; - default: - goto errinval; - } - /* - * Enumerators are only allows to contain: - * numeric unary expression - * or num. unary exp. ... num. unary exp - */ - { - int count = 0; - - bt_list_for_each_entry(iter, &node->u.enumerator.values, - siblings) { - switch (count++) { - case 0: if (iter->type != NODE_UNARY_EXPRESSION - || (iter->u.unary_expression.type != UNARY_SIGNED_CONSTANT - && iter->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) - || iter->u.unary_expression.link != UNARY_LINK_UNKNOWN) { - _BT_COMP_LOGE_APPEND_CAUSE_LINENO(iter->lineno, - "First unary expression of enumerator is unexpected."); - goto errperm; - } - break; - case 1: if (iter->type != NODE_UNARY_EXPRESSION - || (iter->u.unary_expression.type != UNARY_SIGNED_CONSTANT - && iter->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) - || iter->u.unary_expression.link != UNARY_DOTDOTDOT) { - _BT_COMP_LOGE_APPEND_CAUSE_LINENO(iter->lineno, - "Second unary expression of enumerator is unexpected."); - goto errperm; - } - break; - default: - goto errperm; - } - } - } - - bt_list_for_each_entry(iter, &node->u.enumerator.values, siblings) { - ret = _ctf_visitor_semantic_check(depth + 1, iter, - log_cfg); - if (ret) - return ret; - } - break; - case NODE_ENUM: - switch (node->parent->type) { - case NODE_TYPE_SPECIFIER: - break; /* OK */ - default: - goto errinval; - - case NODE_UNARY_EXPRESSION: - goto errperm; - } - - depth++; - ret = _ctf_visitor_semantic_check(depth + 1, - node->u._enum.container_field_class, log_cfg); - if (ret) - return ret; - - bt_list_for_each_entry(iter, &node->u._enum.enumerator_list, siblings) { - ret = _ctf_visitor_semantic_check(depth + 1, iter, - log_cfg); - if (ret) - return ret; - } - depth--; - break; - case NODE_STRUCT_OR_VARIANT_DECLARATION: - switch (node->parent->type) { - case NODE_STRUCT: - case NODE_VARIANT: - break; - default: - goto errinval; - } - ret = _ctf_visitor_semantic_check(depth + 1, - node->u.struct_or_variant_declaration.field_class_specifier_list, - log_cfg); - if (ret) - return ret; - bt_list_for_each_entry(iter, &node->u.struct_or_variant_declaration.field_class_declarators, siblings) { - ret = _ctf_visitor_semantic_check(depth + 1, iter, - log_cfg); - if (ret) - return ret; - } - break; - case NODE_VARIANT: - switch (node->parent->type) { - case NODE_TYPE_SPECIFIER: - break; /* OK */ - default: - goto errinval; - - case NODE_UNARY_EXPRESSION: - goto errperm; - } - bt_list_for_each_entry(iter, &node->u.variant.declaration_list, siblings) { - ret = _ctf_visitor_semantic_check(depth + 1, iter, - log_cfg); - if (ret) - return ret; - } - break; - - case NODE_STRUCT: - switch (node->parent->type) { - case NODE_TYPE_SPECIFIER: - break; /* OK */ - default: - goto errinval; - - case NODE_UNARY_EXPRESSION: - goto errperm; - } - bt_list_for_each_entry(iter, &node->u._struct.declaration_list, siblings) { - ret = _ctf_visitor_semantic_check(depth + 1, iter, - log_cfg); - if (ret) - return ret; - } - break; - - case NODE_UNKNOWN: - default: - _BT_COMP_LOGE_APPEND_CAUSE_LINENO(node->lineno, - "Unknown node type: type=%d", node->type); - return -EINVAL; - } - return ret; + int ret = 0; + struct ctf_node *iter; + + if (node->visited) + return 0; + + switch (node->type) { + case NODE_ROOT: + bt_list_for_each_entry (iter, &node->u.root.declaration_list, siblings) { + ret = _ctf_visitor_semantic_check(depth + 1, iter, log_cfg); + if (ret) + return ret; + } + bt_list_for_each_entry (iter, &node->u.root.trace, siblings) { + ret = _ctf_visitor_semantic_check(depth + 1, iter, log_cfg); + if (ret) + return ret; + } + bt_list_for_each_entry (iter, &node->u.root.stream, siblings) { + ret = _ctf_visitor_semantic_check(depth + 1, iter, log_cfg); + if (ret) + return ret; + } + bt_list_for_each_entry (iter, &node->u.root.event, siblings) { + ret = _ctf_visitor_semantic_check(depth + 1, iter, log_cfg); + if (ret) + return ret; + } + break; + + case NODE_EVENT: + switch (node->parent->type) { + case NODE_ROOT: + break; /* OK */ + default: + goto errinval; + } + + bt_list_for_each_entry (iter, &node->u.event.declaration_list, siblings) { + ret = _ctf_visitor_semantic_check(depth + 1, iter, log_cfg); + if (ret) + return ret; + } + break; + case NODE_STREAM: + switch (node->parent->type) { + case NODE_ROOT: + break; /* OK */ + default: + goto errinval; + } + + bt_list_for_each_entry (iter, &node->u.stream.declaration_list, siblings) { + ret = _ctf_visitor_semantic_check(depth + 1, iter, log_cfg); + if (ret) + return ret; + } + break; + case NODE_ENV: + switch (node->parent->type) { + case NODE_ROOT: + break; /* OK */ + default: + goto errinval; + } + + bt_list_for_each_entry (iter, &node->u.env.declaration_list, siblings) { + ret = _ctf_visitor_semantic_check(depth + 1, iter, log_cfg); + if (ret) + return ret; + } + break; + case NODE_TRACE: + switch (node->parent->type) { + case NODE_ROOT: + break; /* OK */ + default: + goto errinval; + } + + bt_list_for_each_entry (iter, &node->u.trace.declaration_list, siblings) { + ret = _ctf_visitor_semantic_check(depth + 1, iter, log_cfg); + if (ret) + return ret; + } + break; + case NODE_CLOCK: + switch (node->parent->type) { + case NODE_ROOT: + break; /* OK */ + default: + goto errinval; + } + + bt_list_for_each_entry (iter, &node->u.clock.declaration_list, siblings) { + ret = _ctf_visitor_semantic_check(depth + 1, iter, log_cfg); + if (ret) + return ret; + } + break; + case NODE_CALLSITE: + switch (node->parent->type) { + case NODE_ROOT: + break; /* OK */ + default: + goto errinval; + } + + bt_list_for_each_entry (iter, &node->u.callsite.declaration_list, siblings) { + ret = _ctf_visitor_semantic_check(depth + 1, iter, log_cfg); + if (ret) + return ret; + } + break; + + case NODE_CTF_EXPRESSION: + switch (node->parent->type) { + case NODE_ROOT: + case NODE_EVENT: + case NODE_STREAM: + case NODE_ENV: + case NODE_TRACE: + case NODE_CLOCK: + case NODE_CALLSITE: + case NODE_FLOATING_POINT: + case NODE_INTEGER: + case NODE_STRING: + break; /* OK */ + + case NODE_CTF_EXPRESSION: + case NODE_UNARY_EXPRESSION: + case NODE_TYPEDEF: + case NODE_TYPEALIAS_TARGET: + case NODE_TYPEALIAS_ALIAS: + case NODE_STRUCT_OR_VARIANT_DECLARATION: + case NODE_TYPEALIAS: + case NODE_TYPE_SPECIFIER: + case NODE_TYPE_SPECIFIER_LIST: + case NODE_POINTER: + case NODE_TYPE_DECLARATOR: + case NODE_ENUMERATOR: + case NODE_ENUM: + case NODE_VARIANT: + case NODE_STRUCT: + default: + goto errinval; + } + + depth++; + bt_list_for_each_entry (iter, &node->u.ctf_expression.left, siblings) { + ret = _ctf_visitor_semantic_check(depth + 1, iter, log_cfg); + if (ret) + return ret; + } + bt_list_for_each_entry (iter, &node->u.ctf_expression.right, siblings) { + ret = _ctf_visitor_semantic_check(depth + 1, iter, log_cfg); + if (ret) + return ret; + } + depth--; + break; + case NODE_UNARY_EXPRESSION: + return ctf_visitor_unary_expression(depth, node, log_cfg); + + case NODE_TYPEDEF: + switch (node->parent->type) { + case NODE_ROOT: + case NODE_EVENT: + case NODE_STREAM: + case NODE_TRACE: + case NODE_VARIANT: + case NODE_STRUCT: + break; /* OK */ + + case NODE_CTF_EXPRESSION: + case NODE_UNARY_EXPRESSION: + case NODE_TYPEDEF: + case NODE_TYPEALIAS_TARGET: + case NODE_TYPEALIAS_ALIAS: + case NODE_TYPEALIAS: + case NODE_STRUCT_OR_VARIANT_DECLARATION: + case NODE_TYPE_SPECIFIER: + case NODE_TYPE_SPECIFIER_LIST: + case NODE_POINTER: + case NODE_TYPE_DECLARATOR: + case NODE_FLOATING_POINT: + case NODE_INTEGER: + case NODE_STRING: + case NODE_ENUMERATOR: + case NODE_ENUM: + case NODE_CLOCK: + case NODE_CALLSITE: + case NODE_ENV: + default: + goto errinval; + } + + depth++; + ret = _ctf_visitor_semantic_check( + depth + 1, node->u.field_class_def.field_class_specifier_list, log_cfg); + if (ret) + return ret; + bt_list_for_each_entry (iter, &node->u.field_class_def.field_class_declarators, siblings) { + ret = _ctf_visitor_semantic_check(depth + 1, iter, log_cfg); + if (ret) + return ret; + } + depth--; + break; + case NODE_TYPEALIAS_TARGET: + { + int nr_declarators; + + switch (node->parent->type) { + case NODE_TYPEALIAS: + break; /* OK */ + default: + goto errinval; + } + + depth++; + ret = _ctf_visitor_semantic_check( + depth + 1, node->u.field_class_alias_target.field_class_specifier_list, log_cfg); + if (ret) + return ret; + nr_declarators = 0; + bt_list_for_each_entry (iter, &node->u.field_class_alias_target.field_class_declarators, + siblings) { + ret = _ctf_visitor_semantic_check(depth + 1, iter, log_cfg); + if (ret) + return ret; + nr_declarators++; + } + if (nr_declarators > 1) { + _BT_COMP_LOGE_APPEND_CAUSE_LINENO( + node->lineno, + "Too many declarators in field class alias's name (maximum is 1): count=%d", + nr_declarators); + return -EINVAL; + } + depth--; + break; + } + case NODE_TYPEALIAS_ALIAS: + { + int nr_declarators; + + switch (node->parent->type) { + case NODE_TYPEALIAS: + break; /* OK */ + default: + goto errinval; + } + + depth++; + ret = _ctf_visitor_semantic_check( + depth + 1, node->u.field_class_alias_name.field_class_specifier_list, log_cfg); + if (ret) + return ret; + nr_declarators = 0; + bt_list_for_each_entry (iter, &node->u.field_class_alias_name.field_class_declarators, + siblings) { + ret = _ctf_visitor_semantic_check(depth + 1, iter, log_cfg); + if (ret) + return ret; + nr_declarators++; + } + if (nr_declarators > 1) { + _BT_COMP_LOGE_APPEND_CAUSE_LINENO( + node->lineno, + "Too many declarators in field class alias's name (maximum is 1): count=%d", + nr_declarators); + return -EINVAL; + } + depth--; + break; + } + case NODE_TYPEALIAS: + switch (node->parent->type) { + case NODE_ROOT: + case NODE_EVENT: + case NODE_STREAM: + case NODE_TRACE: + case NODE_VARIANT: + case NODE_STRUCT: + break; /* OK */ + + case NODE_CTF_EXPRESSION: + case NODE_UNARY_EXPRESSION: + case NODE_TYPEDEF: + case NODE_TYPEALIAS_TARGET: + case NODE_TYPEALIAS_ALIAS: + case NODE_TYPEALIAS: + case NODE_STRUCT_OR_VARIANT_DECLARATION: + case NODE_TYPE_SPECIFIER: + case NODE_TYPE_SPECIFIER_LIST: + case NODE_POINTER: + case NODE_TYPE_DECLARATOR: + case NODE_FLOATING_POINT: + case NODE_INTEGER: + case NODE_STRING: + case NODE_ENUMERATOR: + case NODE_ENUM: + case NODE_CLOCK: + case NODE_CALLSITE: + case NODE_ENV: + default: + goto errinval; + } + + ret = _ctf_visitor_semantic_check(depth + 1, node->u.field_class_alias.target, log_cfg); + if (ret) + return ret; + ret = _ctf_visitor_semantic_check(depth + 1, node->u.field_class_alias.alias, log_cfg); + if (ret) + return ret; + break; + + case NODE_TYPE_SPECIFIER_LIST: + ret = ctf_visitor_field_class_specifier_list(depth, node, log_cfg); + if (ret) + return ret; + break; + case NODE_TYPE_SPECIFIER: + ret = ctf_visitor_field_class_specifier(depth, node, log_cfg); + if (ret) + return ret; + break; + case NODE_POINTER: + switch (node->parent->type) { + case NODE_TYPE_DECLARATOR: + break; /* OK */ + default: + goto errinval; + } + break; + case NODE_TYPE_DECLARATOR: + ret = ctf_visitor_field_class_declarator(depth, node, log_cfg); + if (ret) + return ret; + break; + + case NODE_FLOATING_POINT: + switch (node->parent->type) { + case NODE_TYPE_SPECIFIER: + break; /* OK */ + default: + goto errinval; + + case NODE_UNARY_EXPRESSION: + goto errperm; + } + bt_list_for_each_entry (iter, &node->u.floating_point.expressions, siblings) { + ret = _ctf_visitor_semantic_check(depth + 1, iter, log_cfg); + if (ret) + return ret; + } + break; + case NODE_INTEGER: + switch (node->parent->type) { + case NODE_TYPE_SPECIFIER: + break; /* OK */ + default: + goto errinval; + } + + bt_list_for_each_entry (iter, &node->u.integer.expressions, siblings) { + ret = _ctf_visitor_semantic_check(depth + 1, iter, log_cfg); + if (ret) + return ret; + } + break; + case NODE_STRING: + switch (node->parent->type) { + case NODE_TYPE_SPECIFIER: + break; /* OK */ + default: + goto errinval; + + case NODE_UNARY_EXPRESSION: + goto errperm; + } + + bt_list_for_each_entry (iter, &node->u.string.expressions, siblings) { + ret = _ctf_visitor_semantic_check(depth + 1, iter, log_cfg); + if (ret) + return ret; + } + break; + case NODE_ENUMERATOR: + switch (node->parent->type) { + case NODE_ENUM: + break; + default: + goto errinval; + } + /* + * Enumerators are only allows to contain: + * numeric unary expression + * or num. unary exp. ... num. unary exp + */ + { + int count = 0; + + bt_list_for_each_entry (iter, &node->u.enumerator.values, siblings) { + switch (count++) { + case 0: + if (iter->type != NODE_UNARY_EXPRESSION || + (iter->u.unary_expression.type != UNARY_SIGNED_CONSTANT && + iter->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) || + iter->u.unary_expression.link != UNARY_LINK_UNKNOWN) { + _BT_COMP_LOGE_APPEND_CAUSE_LINENO( + iter->lineno, "First unary expression of enumerator is unexpected."); + goto errperm; + } + break; + case 1: + if (iter->type != NODE_UNARY_EXPRESSION || + (iter->u.unary_expression.type != UNARY_SIGNED_CONSTANT && + iter->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) || + iter->u.unary_expression.link != UNARY_DOTDOTDOT) { + _BT_COMP_LOGE_APPEND_CAUSE_LINENO( + iter->lineno, "Second unary expression of enumerator is unexpected."); + goto errperm; + } + break; + default: + goto errperm; + } + } + } + + bt_list_for_each_entry (iter, &node->u.enumerator.values, siblings) { + ret = _ctf_visitor_semantic_check(depth + 1, iter, log_cfg); + if (ret) + return ret; + } + break; + case NODE_ENUM: + switch (node->parent->type) { + case NODE_TYPE_SPECIFIER: + break; /* OK */ + default: + goto errinval; + + case NODE_UNARY_EXPRESSION: + goto errperm; + } + + depth++; + ret = _ctf_visitor_semantic_check(depth + 1, node->u._enum.container_field_class, log_cfg); + if (ret) + return ret; + + bt_list_for_each_entry (iter, &node->u._enum.enumerator_list, siblings) { + ret = _ctf_visitor_semantic_check(depth + 1, iter, log_cfg); + if (ret) + return ret; + } + depth--; + break; + case NODE_STRUCT_OR_VARIANT_DECLARATION: + switch (node->parent->type) { + case NODE_STRUCT: + case NODE_VARIANT: + break; + default: + goto errinval; + } + ret = _ctf_visitor_semantic_check( + depth + 1, node->u.struct_or_variant_declaration.field_class_specifier_list, log_cfg); + if (ret) + return ret; + bt_list_for_each_entry ( + iter, &node->u.struct_or_variant_declaration.field_class_declarators, siblings) { + ret = _ctf_visitor_semantic_check(depth + 1, iter, log_cfg); + if (ret) + return ret; + } + break; + case NODE_VARIANT: + switch (node->parent->type) { + case NODE_TYPE_SPECIFIER: + break; /* OK */ + default: + goto errinval; + + case NODE_UNARY_EXPRESSION: + goto errperm; + } + bt_list_for_each_entry (iter, &node->u.variant.declaration_list, siblings) { + ret = _ctf_visitor_semantic_check(depth + 1, iter, log_cfg); + if (ret) + return ret; + } + break; + + case NODE_STRUCT: + switch (node->parent->type) { + case NODE_TYPE_SPECIFIER: + break; /* OK */ + default: + goto errinval; + + case NODE_UNARY_EXPRESSION: + goto errperm; + } + bt_list_for_each_entry (iter, &node->u._struct.declaration_list, siblings) { + ret = _ctf_visitor_semantic_check(depth + 1, iter, log_cfg); + if (ret) + return ret; + } + break; + + case NODE_UNKNOWN: + default: + _BT_COMP_LOGE_APPEND_CAUSE_LINENO(node->lineno, "Unknown node type: type=%d", node->type); + return -EINVAL; + } + return ret; errinval: - _BT_COMP_LOGE_APPEND_CAUSE_LINENO(node->lineno, - "Incoherent parent node's type: node-type=%s, parent-node-type=%s", - node_type(node), node_type(node->parent)); - return -EINVAL; /* Incoherent structure */ + _BT_COMP_LOGE_APPEND_CAUSE_LINENO( + node->lineno, "Incoherent parent node's type: node-type=%s, parent-node-type=%s", + node_type(node), node_type(node->parent)); + return -EINVAL; /* Incoherent structure */ errperm: - _BT_COMP_LOGE_APPEND_CAUSE_LINENO(node->lineno, - "Semantic error: node-type=%s, parent-node-type=%s", - node_type(node), node_type(node->parent)); - return -EPERM; /* Structure not allowed */ + _BT_COMP_LOGE_APPEND_CAUSE_LINENO(node->lineno, + "Semantic error: node-type=%s, parent-node-type=%s", + node_type(node), node_type(node->parent)); + return -EPERM; /* Structure not allowed */ } -int ctf_visitor_semantic_check(int depth, struct ctf_node *node, - struct meta_log_config *log_cfg) +int ctf_visitor_semantic_check(int depth, struct ctf_node *node, struct meta_log_config *log_cfg) { - int ret = 0; - - /* - * First make sure we create the parent links for all children. Let's - * take the safe route and recreate them at each validation, just in - * case the structure has changed. - */ - ret = ctf_visitor_parent_links(depth, node, log_cfg); - if (ret) { - _BT_COMP_LOGE_APPEND_CAUSE_LINENO(node->lineno, - "Cannot create parent links in metadata's AST: " - "ret=%d", ret); - goto end; - } - - ret = _ctf_visitor_semantic_check(depth, node, log_cfg); - if (ret) { - _BT_COMP_LOGE_APPEND_CAUSE_LINENO(node->lineno, - "Cannot check metadata's AST semantics: " - "ret=%d", ret); - goto end; - } + int ret = 0; + + /* + * First make sure we create the parent links for all children. Let's + * take the safe route and recreate them at each validation, just in + * case the structure has changed. + */ + ret = ctf_visitor_parent_links(depth, node, log_cfg); + if (ret) { + _BT_COMP_LOGE_APPEND_CAUSE_LINENO(node->lineno, + "Cannot create parent links in metadata's AST: " + "ret=%d", + ret); + goto end; + } + + ret = _ctf_visitor_semantic_check(depth, node, log_cfg); + if (ret) { + _BT_COMP_LOGE_APPEND_CAUSE_LINENO(node->lineno, + "Cannot check metadata's AST semantics: " + "ret=%d", + ret); + goto end; + } end: - return ret; + return ret; } diff --git a/src/plugins/ctf/common/msg-iter/msg-iter.cpp b/src/plugins/ctf/common/msg-iter/msg-iter.cpp index fd0cbf24..e4190724 100644 --- a/src/plugins/ctf/common/msg-iter/msg-iter.cpp +++ b/src/plugins/ctf/common/msg-iter/msg-iter.cpp @@ -8,8 +8,8 @@ */ #define BT_COMP_LOG_SELF_COMP (msg_it->self_comp) -#define BT_LOG_OUTPUT_LEVEL (msg_it->log_level) -#define BT_LOG_TAG "PLUGIN/CTF/MSG-ITER" +#define BT_LOG_OUTPUT_LEVEL (msg_it->log_level) +#define BT_LOG_TAG "PLUGIN/CTF/MSG-ITER" #include "logging/comp-logging.h" #include @@ -30,1791 +30,1674 @@ struct ctf_msg_iter; /* A visit stack entry */ -struct stack_entry { - /* - * Current base field, one of: - * - * * string - * * structure - * * array - * * sequence - * * variant - * - * Field is borrowed. - */ - bt_field *base; - - /* Index of next field to set */ - size_t index; +struct stack_entry +{ + /* + * Current base field, one of: + * + * * string + * * structure + * * array + * * sequence + * * variant + * + * Field is borrowed. + */ + bt_field *base; + + /* Index of next field to set */ + size_t index; }; struct ctf_msg_iter; /* Visit stack */ -struct stack { - struct ctf_msg_iter *msg_it; +struct stack +{ + struct ctf_msg_iter *msg_it; - /* Entries (struct stack_entry) */ - GArray *entries; + /* Entries (struct stack_entry) */ + GArray *entries; - /* Number of active entries */ - size_t size; + /* Number of active entries */ + size_t size; }; /* State */ -enum state { - STATE_INIT, - STATE_SWITCH_PACKET, - STATE_DSCOPE_TRACE_PACKET_HEADER_BEGIN, - STATE_DSCOPE_TRACE_PACKET_HEADER_CONTINUE, - STATE_AFTER_TRACE_PACKET_HEADER, - STATE_DSCOPE_STREAM_PACKET_CONTEXT_BEGIN, - STATE_DSCOPE_STREAM_PACKET_CONTEXT_CONTINUE, - STATE_AFTER_STREAM_PACKET_CONTEXT, - STATE_EMIT_MSG_STREAM_BEGINNING, - STATE_CHECK_EMIT_MSG_DISCARDED_EVENTS, - STATE_CHECK_EMIT_MSG_DISCARDED_PACKETS, - STATE_EMIT_MSG_DISCARDED_EVENTS, - STATE_EMIT_MSG_DISCARDED_PACKETS, - STATE_EMIT_MSG_PACKET_BEGINNING, - STATE_DSCOPE_EVENT_HEADER_BEGIN, - STATE_DSCOPE_EVENT_HEADER_CONTINUE, - STATE_AFTER_EVENT_HEADER, - STATE_DSCOPE_EVENT_COMMON_CONTEXT_BEGIN, - STATE_DSCOPE_EVENT_COMMON_CONTEXT_CONTINUE, - STATE_DSCOPE_EVENT_SPEC_CONTEXT_BEGIN, - STATE_DSCOPE_EVENT_SPEC_CONTEXT_CONTINUE, - STATE_DSCOPE_EVENT_PAYLOAD_BEGIN, - STATE_DSCOPE_EVENT_PAYLOAD_CONTINUE, - STATE_EMIT_MSG_EVENT, - STATE_EMIT_QUEUED_MSG_EVENT, - STATE_SKIP_PACKET_PADDING, - STATE_EMIT_MSG_PACKET_END_MULTI, - STATE_EMIT_MSG_PACKET_END_SINGLE, - STATE_EMIT_QUEUED_MSG_PACKET_END, - STATE_CHECK_EMIT_MSG_STREAM_END, - STATE_EMIT_MSG_STREAM_END, - STATE_DONE, +enum state +{ + STATE_INIT, + STATE_SWITCH_PACKET, + STATE_DSCOPE_TRACE_PACKET_HEADER_BEGIN, + STATE_DSCOPE_TRACE_PACKET_HEADER_CONTINUE, + STATE_AFTER_TRACE_PACKET_HEADER, + STATE_DSCOPE_STREAM_PACKET_CONTEXT_BEGIN, + STATE_DSCOPE_STREAM_PACKET_CONTEXT_CONTINUE, + STATE_AFTER_STREAM_PACKET_CONTEXT, + STATE_EMIT_MSG_STREAM_BEGINNING, + STATE_CHECK_EMIT_MSG_DISCARDED_EVENTS, + STATE_CHECK_EMIT_MSG_DISCARDED_PACKETS, + STATE_EMIT_MSG_DISCARDED_EVENTS, + STATE_EMIT_MSG_DISCARDED_PACKETS, + STATE_EMIT_MSG_PACKET_BEGINNING, + STATE_DSCOPE_EVENT_HEADER_BEGIN, + STATE_DSCOPE_EVENT_HEADER_CONTINUE, + STATE_AFTER_EVENT_HEADER, + STATE_DSCOPE_EVENT_COMMON_CONTEXT_BEGIN, + STATE_DSCOPE_EVENT_COMMON_CONTEXT_CONTINUE, + STATE_DSCOPE_EVENT_SPEC_CONTEXT_BEGIN, + STATE_DSCOPE_EVENT_SPEC_CONTEXT_CONTINUE, + STATE_DSCOPE_EVENT_PAYLOAD_BEGIN, + STATE_DSCOPE_EVENT_PAYLOAD_CONTINUE, + STATE_EMIT_MSG_EVENT, + STATE_EMIT_QUEUED_MSG_EVENT, + STATE_SKIP_PACKET_PADDING, + STATE_EMIT_MSG_PACKET_END_MULTI, + STATE_EMIT_MSG_PACKET_END_SINGLE, + STATE_EMIT_QUEUED_MSG_PACKET_END, + STATE_CHECK_EMIT_MSG_STREAM_END, + STATE_EMIT_MSG_STREAM_END, + STATE_DONE, }; -struct end_of_packet_snapshots { - uint64_t discarded_events; - uint64_t packets; - uint64_t beginning_clock; - uint64_t end_clock; +struct end_of_packet_snapshots +{ + uint64_t discarded_events; + uint64_t packets; + uint64_t beginning_clock; + uint64_t end_clock; }; /* CTF message iterator */ -struct ctf_msg_iter { - /* Visit stack */ - struct stack *stack; - - /* Current message iterator to create messages (weak) */ - bt_self_message_iterator *self_msg_iter; - - /* - * True if library objects are unavailable during the decoding and - * should not be created/used. - */ - bool dry_run; - - /* - * Current dynamic scope field pointer. - * - * This is set by read_dscope_begin_state() and contains the - * value of one of the pointers in `dscopes` below. - */ - bt_field *cur_dscope_field; - - /* - * True if we're done filling a string field from a text - * array/sequence payload. - */ - bool done_filling_string; - - /* Trace and classes */ - /* True to set IR fields */ - bool set_ir_fields; - - struct { - struct ctf_trace_class *tc; - struct ctf_stream_class *sc; - struct ctf_event_class *ec; - } meta; - - /* Current packet (NULL if not created yet) */ - bt_packet *packet; - - /* Current stream (NULL if not set yet) */ - bt_stream *stream; - - /* Current event (NULL if not created yet) */ - bt_event *event; - - /* Current event message (NULL if not created yet) */ - bt_message *event_msg; - - /* - * True if we need to emit a packet beginning message before we emit - * the next event message or the packet end message. - */ - bool emit_delayed_packet_beginning_msg; - - /* - * True if this is the first packet we are reading, and therefore if we - * should emit a stream beginning message. - */ - bool emit_stream_beginning_message; - - /* - * True if we need to emit a stream end message at the end of the - * current stream. A live stream may never receive any data and thus - * never send a stream beginning message which removes the need to emit - * a stream end message. - */ - bool emit_stream_end_message; - - /* Database of current dynamic scopes */ - struct { - bt_field *stream_packet_context; - bt_field *event_common_context; - bt_field *event_spec_context; - bt_field *event_payload; - } dscopes; - - /* Current state */ - enum state state; - - /* Current medium buffer data */ - struct { - /* Last address provided by medium */ - const uint8_t *addr; - - /* Buffer size provided by medium (bytes) */ - size_t sz; - - /* Offset within whole packet of addr (bits) */ - size_t packet_offset; - - /* Current position from addr (bits) */ - size_t at; - - /* Position of the last event header from addr (bits) */ - size_t last_eh_at; - } buf; - - /* Binary type reader */ - struct bt_bfcr *bfcr; - - /* Current medium data */ - struct { - struct ctf_msg_iter_medium_ops medops; - size_t max_request_sz; - void *data; - } medium; - - /* Current packet size (bits) (-1 if unknown) */ - int64_t cur_exp_packet_total_size; - - /* Current content size (bits) (-1 if unknown) */ - int64_t cur_exp_packet_content_size; - - /* Current stream class ID */ - int64_t cur_stream_class_id; - - /* Current event class ID */ - int64_t cur_event_class_id; - - /* Current data stream ID */ - int64_t cur_data_stream_id; - - /* - * Offset, in the underlying media, of the current packet's - * start (-1 if unknown). - */ - off_t cur_packet_offset; - - /* Default clock's current value */ - uint64_t default_clock_snapshot; - - /* End of current packet snapshots */ - struct end_of_packet_snapshots snapshots; - - /* End of previous packet snapshots */ - struct end_of_packet_snapshots prev_packet_snapshots; +struct ctf_msg_iter +{ + /* Visit stack */ + struct stack *stack; + + /* Current message iterator to create messages (weak) */ + bt_self_message_iterator *self_msg_iter; + + /* + * True if library objects are unavailable during the decoding and + * should not be created/used. + */ + bool dry_run; + + /* + * Current dynamic scope field pointer. + * + * This is set by read_dscope_begin_state() and contains the + * value of one of the pointers in `dscopes` below. + */ + bt_field *cur_dscope_field; + + /* + * True if we're done filling a string field from a text + * array/sequence payload. + */ + bool done_filling_string; + + /* Trace and classes */ + /* True to set IR fields */ + bool set_ir_fields; + + struct + { + struct ctf_trace_class *tc; + struct ctf_stream_class *sc; + struct ctf_event_class *ec; + } meta; + + /* Current packet (NULL if not created yet) */ + bt_packet *packet; + + /* Current stream (NULL if not set yet) */ + bt_stream *stream; + + /* Current event (NULL if not created yet) */ + bt_event *event; + + /* Current event message (NULL if not created yet) */ + bt_message *event_msg; + + /* + * True if we need to emit a packet beginning message before we emit + * the next event message or the packet end message. + */ + bool emit_delayed_packet_beginning_msg; + + /* + * True if this is the first packet we are reading, and therefore if we + * should emit a stream beginning message. + */ + bool emit_stream_beginning_message; + + /* + * True if we need to emit a stream end message at the end of the + * current stream. A live stream may never receive any data and thus + * never send a stream beginning message which removes the need to emit + * a stream end message. + */ + bool emit_stream_end_message; + + /* Database of current dynamic scopes */ + struct + { + bt_field *stream_packet_context; + bt_field *event_common_context; + bt_field *event_spec_context; + bt_field *event_payload; + } dscopes; + + /* Current state */ + enum state state; + + /* Current medium buffer data */ + struct + { + /* Last address provided by medium */ + const uint8_t *addr; + + /* Buffer size provided by medium (bytes) */ + size_t sz; + + /* Offset within whole packet of addr (bits) */ + size_t packet_offset; + + /* Current position from addr (bits) */ + size_t at; + + /* Position of the last event header from addr (bits) */ + size_t last_eh_at; + } buf; + + /* Binary type reader */ + struct bt_bfcr *bfcr; + + /* Current medium data */ + struct + { + struct ctf_msg_iter_medium_ops medops; + size_t max_request_sz; + void *data; + } medium; + + /* Current packet size (bits) (-1 if unknown) */ + int64_t cur_exp_packet_total_size; + + /* Current content size (bits) (-1 if unknown) */ + int64_t cur_exp_packet_content_size; + + /* Current stream class ID */ + int64_t cur_stream_class_id; + + /* Current event class ID */ + int64_t cur_event_class_id; + + /* Current data stream ID */ + int64_t cur_data_stream_id; + + /* + * Offset, in the underlying media, of the current packet's + * start (-1 if unknown). + */ + off_t cur_packet_offset; + + /* Default clock's current value */ + uint64_t default_clock_snapshot; - /* Stored values (for sequence lengths, variant tags) */ - GArray *stored_values; - - /* Iterator's current log level */ - bt_logging_level log_level; - - /* Iterator's owning self component, or `NULL` if none (query) */ - bt_self_component *self_comp; + /* End of current packet snapshots */ + struct end_of_packet_snapshots snapshots; + + /* End of previous packet snapshots */ + struct end_of_packet_snapshots prev_packet_snapshots; + + /* Stored values (for sequence lengths, variant tags) */ + GArray *stored_values; + + /* Iterator's current log level */ + bt_logging_level log_level; + + /* Iterator's owning self component, or `NULL` if none (query) */ + bt_self_component *self_comp; }; -static inline -const char *state_string(enum state state) -{ - switch (state) { - case STATE_INIT: - return "INIT"; - case STATE_SWITCH_PACKET: - return "SWITCH_PACKET"; - case STATE_DSCOPE_TRACE_PACKET_HEADER_BEGIN: - return "DSCOPE_TRACE_PACKET_HEADER_BEGIN"; - case STATE_DSCOPE_TRACE_PACKET_HEADER_CONTINUE: - return "DSCOPE_TRACE_PACKET_HEADER_CONTINUE"; - case STATE_AFTER_TRACE_PACKET_HEADER: - return "AFTER_TRACE_PACKET_HEADER"; - case STATE_DSCOPE_STREAM_PACKET_CONTEXT_BEGIN: - return "DSCOPE_STREAM_PACKET_CONTEXT_BEGIN"; - case STATE_DSCOPE_STREAM_PACKET_CONTEXT_CONTINUE: - return "DSCOPE_STREAM_PACKET_CONTEXT_CONTINUE"; - case STATE_AFTER_STREAM_PACKET_CONTEXT: - return "AFTER_STREAM_PACKET_CONTEXT"; - case STATE_EMIT_MSG_STREAM_BEGINNING: - return "EMIT_MSG_STREAM_BEGINNING"; - case STATE_CHECK_EMIT_MSG_DISCARDED_EVENTS: - return "CHECK_EMIT_MSG_DISCARDED_EVENTS"; - case STATE_CHECK_EMIT_MSG_DISCARDED_PACKETS: - return "CHECK_EMIT_MSG_DISCARDED_PACKETS"; - case STATE_EMIT_MSG_PACKET_BEGINNING: - return "EMIT_MSG_PACKET_BEGINNING"; - case STATE_EMIT_MSG_DISCARDED_EVENTS: - return "EMIT_MSG_DISCARDED_EVENTS"; - case STATE_EMIT_MSG_DISCARDED_PACKETS: - return "EMIT_MSG_DISCARDED_PACKETS"; - case STATE_DSCOPE_EVENT_HEADER_BEGIN: - return "DSCOPE_EVENT_HEADER_BEGIN"; - case STATE_DSCOPE_EVENT_HEADER_CONTINUE: - return "DSCOPE_EVENT_HEADER_CONTINUE"; - case STATE_AFTER_EVENT_HEADER: - return "AFTER_EVENT_HEADER"; - case STATE_DSCOPE_EVENT_COMMON_CONTEXT_BEGIN: - return "DSCOPE_EVENT_COMMON_CONTEXT_BEGIN"; - case STATE_DSCOPE_EVENT_COMMON_CONTEXT_CONTINUE: - return "DSCOPE_EVENT_COMMON_CONTEXT_CONTINUE"; - case STATE_DSCOPE_EVENT_SPEC_CONTEXT_BEGIN: - return "DSCOPE_EVENT_SPEC_CONTEXT_BEGIN"; - case STATE_DSCOPE_EVENT_SPEC_CONTEXT_CONTINUE: - return "DSCOPE_EVENT_SPEC_CONTEXT_CONTINUE"; - case STATE_DSCOPE_EVENT_PAYLOAD_BEGIN: - return "DSCOPE_EVENT_PAYLOAD_BEGIN"; - case STATE_DSCOPE_EVENT_PAYLOAD_CONTINUE: - return "DSCOPE_EVENT_PAYLOAD_CONTINUE"; - case STATE_EMIT_MSG_EVENT: - return "EMIT_MSG_EVENT"; - case STATE_EMIT_QUEUED_MSG_EVENT: - return "EMIT_QUEUED_MSG_EVENT"; - case STATE_SKIP_PACKET_PADDING: - return "SKIP_PACKET_PADDING"; - case STATE_EMIT_MSG_PACKET_END_MULTI: - return "EMIT_MSG_PACKET_END_MULTI"; - case STATE_EMIT_MSG_PACKET_END_SINGLE: - return "EMIT_MSG_PACKET_END_SINGLE"; - case STATE_EMIT_QUEUED_MSG_PACKET_END: - return "EMIT_QUEUED_MSG_PACKET_END"; - case STATE_CHECK_EMIT_MSG_STREAM_END: - return "CHECK_EMIT_MSG_STREAM_END"; - case STATE_EMIT_MSG_STREAM_END: - return "EMIT_MSG_STREAM_END"; - case STATE_DONE: - return "DONE"; - } - - bt_common_abort(); -} - -static -struct stack *stack_new(struct ctf_msg_iter *msg_it) -{ - bt_self_component *self_comp = msg_it->self_comp; - struct stack *stack = NULL; - - stack = g_new0(struct stack, 1); - if (!stack) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Failed to allocate one stack."); - goto error; - } - - stack->msg_it = msg_it; - stack->entries = g_array_new(FALSE, TRUE, sizeof(struct stack_entry)); - if (!stack->entries) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Failed to allocate a GArray."); - goto error; - } - - BT_COMP_LOGD("Created stack: msg-it-addr=%p, stack-addr=%p", msg_it, stack); - goto end; +static inline const char *state_string(enum state state) +{ + switch (state) { + case STATE_INIT: + return "INIT"; + case STATE_SWITCH_PACKET: + return "SWITCH_PACKET"; + case STATE_DSCOPE_TRACE_PACKET_HEADER_BEGIN: + return "DSCOPE_TRACE_PACKET_HEADER_BEGIN"; + case STATE_DSCOPE_TRACE_PACKET_HEADER_CONTINUE: + return "DSCOPE_TRACE_PACKET_HEADER_CONTINUE"; + case STATE_AFTER_TRACE_PACKET_HEADER: + return "AFTER_TRACE_PACKET_HEADER"; + case STATE_DSCOPE_STREAM_PACKET_CONTEXT_BEGIN: + return "DSCOPE_STREAM_PACKET_CONTEXT_BEGIN"; + case STATE_DSCOPE_STREAM_PACKET_CONTEXT_CONTINUE: + return "DSCOPE_STREAM_PACKET_CONTEXT_CONTINUE"; + case STATE_AFTER_STREAM_PACKET_CONTEXT: + return "AFTER_STREAM_PACKET_CONTEXT"; + case STATE_EMIT_MSG_STREAM_BEGINNING: + return "EMIT_MSG_STREAM_BEGINNING"; + case STATE_CHECK_EMIT_MSG_DISCARDED_EVENTS: + return "CHECK_EMIT_MSG_DISCARDED_EVENTS"; + case STATE_CHECK_EMIT_MSG_DISCARDED_PACKETS: + return "CHECK_EMIT_MSG_DISCARDED_PACKETS"; + case STATE_EMIT_MSG_PACKET_BEGINNING: + return "EMIT_MSG_PACKET_BEGINNING"; + case STATE_EMIT_MSG_DISCARDED_EVENTS: + return "EMIT_MSG_DISCARDED_EVENTS"; + case STATE_EMIT_MSG_DISCARDED_PACKETS: + return "EMIT_MSG_DISCARDED_PACKETS"; + case STATE_DSCOPE_EVENT_HEADER_BEGIN: + return "DSCOPE_EVENT_HEADER_BEGIN"; + case STATE_DSCOPE_EVENT_HEADER_CONTINUE: + return "DSCOPE_EVENT_HEADER_CONTINUE"; + case STATE_AFTER_EVENT_HEADER: + return "AFTER_EVENT_HEADER"; + case STATE_DSCOPE_EVENT_COMMON_CONTEXT_BEGIN: + return "DSCOPE_EVENT_COMMON_CONTEXT_BEGIN"; + case STATE_DSCOPE_EVENT_COMMON_CONTEXT_CONTINUE: + return "DSCOPE_EVENT_COMMON_CONTEXT_CONTINUE"; + case STATE_DSCOPE_EVENT_SPEC_CONTEXT_BEGIN: + return "DSCOPE_EVENT_SPEC_CONTEXT_BEGIN"; + case STATE_DSCOPE_EVENT_SPEC_CONTEXT_CONTINUE: + return "DSCOPE_EVENT_SPEC_CONTEXT_CONTINUE"; + case STATE_DSCOPE_EVENT_PAYLOAD_BEGIN: + return "DSCOPE_EVENT_PAYLOAD_BEGIN"; + case STATE_DSCOPE_EVENT_PAYLOAD_CONTINUE: + return "DSCOPE_EVENT_PAYLOAD_CONTINUE"; + case STATE_EMIT_MSG_EVENT: + return "EMIT_MSG_EVENT"; + case STATE_EMIT_QUEUED_MSG_EVENT: + return "EMIT_QUEUED_MSG_EVENT"; + case STATE_SKIP_PACKET_PADDING: + return "SKIP_PACKET_PADDING"; + case STATE_EMIT_MSG_PACKET_END_MULTI: + return "EMIT_MSG_PACKET_END_MULTI"; + case STATE_EMIT_MSG_PACKET_END_SINGLE: + return "EMIT_MSG_PACKET_END_SINGLE"; + case STATE_EMIT_QUEUED_MSG_PACKET_END: + return "EMIT_QUEUED_MSG_PACKET_END"; + case STATE_CHECK_EMIT_MSG_STREAM_END: + return "CHECK_EMIT_MSG_STREAM_END"; + case STATE_EMIT_MSG_STREAM_END: + return "EMIT_MSG_STREAM_END"; + case STATE_DONE: + return "DONE"; + } + + bt_common_abort(); +} + +static struct stack *stack_new(struct ctf_msg_iter *msg_it) +{ + bt_self_component *self_comp = msg_it->self_comp; + struct stack *stack = NULL; + + stack = g_new0(struct stack, 1); + if (!stack) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Failed to allocate one stack."); + goto error; + } + + stack->msg_it = msg_it; + stack->entries = g_array_new(FALSE, TRUE, sizeof(struct stack_entry)); + if (!stack->entries) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Failed to allocate a GArray."); + goto error; + } + + BT_COMP_LOGD("Created stack: msg-it-addr=%p, stack-addr=%p", msg_it, stack); + goto end; error: - g_free(stack); - stack = NULL; + g_free(stack); + stack = NULL; end: - return stack; + return stack; } -static -void stack_destroy(struct stack *stack) +static void stack_destroy(struct stack *stack) { - struct ctf_msg_iter *msg_it; + struct ctf_msg_iter *msg_it; - BT_ASSERT_DBG(stack); - msg_it = stack->msg_it; - BT_COMP_LOGD("Destroying stack: addr=%p", stack); + BT_ASSERT_DBG(stack); + msg_it = stack->msg_it; + BT_COMP_LOGD("Destroying stack: addr=%p", stack); - if (stack->entries) { - g_array_free(stack->entries, TRUE); - } + if (stack->entries) { + g_array_free(stack->entries, TRUE); + } - g_free(stack); + g_free(stack); } -static -void stack_push(struct stack *stack, bt_field *base) +static void stack_push(struct stack *stack, bt_field *base) { - struct stack_entry *entry; - struct ctf_msg_iter *msg_it; + struct stack_entry *entry; + struct ctf_msg_iter *msg_it; - BT_ASSERT_DBG(stack); - msg_it = stack->msg_it; - BT_ASSERT_DBG(base); - BT_COMP_LOGT("Pushing base field on stack: stack-addr=%p, " - "stack-size-before=%zu, stack-size-after=%zu", - stack, stack->size, stack->size + 1); + BT_ASSERT_DBG(stack); + msg_it = stack->msg_it; + BT_ASSERT_DBG(base); + BT_COMP_LOGT("Pushing base field on stack: stack-addr=%p, " + "stack-size-before=%zu, stack-size-after=%zu", + stack, stack->size, stack->size + 1); - if (stack->entries->len == stack->size) { - g_array_set_size(stack->entries, stack->size + 1); - } + if (stack->entries->len == stack->size) { + g_array_set_size(stack->entries, stack->size + 1); + } - entry = &g_array_index(stack->entries, struct stack_entry, stack->size); - entry->base = base; - entry->index = 0; - stack->size++; + entry = &g_array_index(stack->entries, struct stack_entry, stack->size); + entry->base = base; + entry->index = 0; + stack->size++; } -static inline -unsigned int stack_size(struct stack *stack) +static inline unsigned int stack_size(struct stack *stack) { - BT_ASSERT_DBG(stack); - return stack->size; + BT_ASSERT_DBG(stack); + return stack->size; } -static -void stack_pop(struct stack *stack) +static void stack_pop(struct stack *stack) { - struct ctf_msg_iter *msg_it; + struct ctf_msg_iter *msg_it; - BT_ASSERT_DBG(stack); - BT_ASSERT_DBG(stack_size(stack)); - msg_it = stack->msg_it; - BT_COMP_LOGT("Popping from stack: " - "stack-addr=%p, stack-size-before=%zu, stack-size-after=%zu", - stack, stack->size, stack->size - 1); - stack->size--; + BT_ASSERT_DBG(stack); + BT_ASSERT_DBG(stack_size(stack)); + msg_it = stack->msg_it; + BT_COMP_LOGT("Popping from stack: " + "stack-addr=%p, stack-size-before=%zu, stack-size-after=%zu", + stack, stack->size, stack->size - 1); + stack->size--; } -static inline -struct stack_entry *stack_top(struct stack *stack) +static inline struct stack_entry *stack_top(struct stack *stack) { - BT_ASSERT_DBG(stack); - BT_ASSERT_DBG(stack_size(stack)); - return &g_array_index(stack->entries, struct stack_entry, - stack->size - 1); + BT_ASSERT_DBG(stack); + BT_ASSERT_DBG(stack_size(stack)); + return &g_array_index(stack->entries, struct stack_entry, stack->size - 1); } -static inline -bool stack_empty(struct stack *stack) +static inline bool stack_empty(struct stack *stack) { - return stack_size(stack) == 0; + return stack_size(stack) == 0; } -static -void stack_clear(struct stack *stack) +static void stack_clear(struct stack *stack) { - BT_ASSERT_DBG(stack); - stack->size = 0; + BT_ASSERT_DBG(stack); + stack->size = 0; } -static inline -enum ctf_msg_iter_status msg_iter_status_from_m_status( - enum ctf_msg_iter_medium_status m_status) +static inline enum ctf_msg_iter_status +msg_iter_status_from_m_status(enum ctf_msg_iter_medium_status m_status) { - /* They are the same */ - return (ctf_msg_iter_status) m_status; + /* They are the same */ + return (ctf_msg_iter_status) m_status; } -static inline -size_t buf_size_bits(struct ctf_msg_iter *msg_it) +static inline size_t buf_size_bits(struct ctf_msg_iter *msg_it) { - return msg_it->buf.sz * 8; + return msg_it->buf.sz * 8; } -static inline -size_t buf_available_bits(struct ctf_msg_iter *msg_it) +static inline size_t buf_available_bits(struct ctf_msg_iter *msg_it) { - return buf_size_bits(msg_it) - msg_it->buf.at; + return buf_size_bits(msg_it) - msg_it->buf.at; } -static inline -size_t packet_at(struct ctf_msg_iter *msg_it) +static inline size_t packet_at(struct ctf_msg_iter *msg_it) { - return msg_it->buf.packet_offset + msg_it->buf.at; + return msg_it->buf.packet_offset + msg_it->buf.at; } -static inline -void buf_consume_bits(struct ctf_msg_iter *msg_it, size_t incr) +static inline void buf_consume_bits(struct ctf_msg_iter *msg_it, size_t incr) { - BT_COMP_LOGT("Advancing cursor: msg-it-addr=%p, cur-before=%zu, cur-after=%zu", - msg_it, msg_it->buf.at, msg_it->buf.at + incr); - msg_it->buf.at += incr; + BT_COMP_LOGT("Advancing cursor: msg-it-addr=%p, cur-before=%zu, cur-after=%zu", msg_it, + msg_it->buf.at, msg_it->buf.at + incr); + msg_it->buf.at += incr; } -static -enum ctf_msg_iter_status request_medium_bytes( - struct ctf_msg_iter *msg_it) +static enum ctf_msg_iter_status request_medium_bytes(struct ctf_msg_iter *msg_it) { - bt_self_component *self_comp = msg_it->self_comp; - uint8_t *buffer_addr = NULL; - size_t buffer_sz = 0; - enum ctf_msg_iter_medium_status m_status; + bt_self_component *self_comp = msg_it->self_comp; + uint8_t *buffer_addr = NULL; + size_t buffer_sz = 0; + enum ctf_msg_iter_medium_status m_status; + + BT_COMP_LOGD("Calling user function (request bytes): msg-it-addr=%p, " + "request-size=%zu", + msg_it, msg_it->medium.max_request_sz); + m_status = msg_it->medium.medops.request_bytes(msg_it->medium.max_request_sz, &buffer_addr, + &buffer_sz, msg_it->medium.data); + BT_COMP_LOGD("User function returned: status=%s, buf-addr=%p, buf-size=%zu", + ctf_msg_iter_medium_status_string(m_status), buffer_addr, buffer_sz); + if (m_status == CTF_MSG_ITER_MEDIUM_STATUS_OK) { + BT_ASSERT(buffer_sz != 0); - BT_COMP_LOGD("Calling user function (request bytes): msg-it-addr=%p, " - "request-size=%zu", msg_it, msg_it->medium.max_request_sz); - m_status = msg_it->medium.medops.request_bytes( - msg_it->medium.max_request_sz, &buffer_addr, - &buffer_sz, msg_it->medium.data); - BT_COMP_LOGD("User function returned: status=%s, buf-addr=%p, buf-size=%zu", - ctf_msg_iter_medium_status_string(m_status), - buffer_addr, buffer_sz); - if (m_status == CTF_MSG_ITER_MEDIUM_STATUS_OK) { - BT_ASSERT(buffer_sz != 0); + /* New packet offset is old one + old size (in bits) */ + msg_it->buf.packet_offset += buf_size_bits(msg_it); - /* New packet offset is old one + old size (in bits) */ - msg_it->buf.packet_offset += buf_size_bits(msg_it); + /* Restart at the beginning of the new medium buffer */ + msg_it->buf.at = 0; + msg_it->buf.last_eh_at = SIZE_MAX; - /* Restart at the beginning of the new medium buffer */ - msg_it->buf.at = 0; - msg_it->buf.last_eh_at = SIZE_MAX; + /* New medium buffer size */ + msg_it->buf.sz = buffer_sz; - /* New medium buffer size */ - msg_it->buf.sz = buffer_sz; + /* New medium buffer address */ + msg_it->buf.addr = buffer_addr; - /* New medium buffer address */ - msg_it->buf.addr = buffer_addr; + BT_COMP_LOGD("User function returned new bytes: " + "packet-offset=%zu, cur=%zu, size=%zu, addr=%p", + msg_it->buf.packet_offset, msg_it->buf.at, msg_it->buf.sz, msg_it->buf.addr); + BT_COMP_LOGT_MEM(buffer_addr, buffer_sz, "Returned bytes at %p:", buffer_addr); + } else if (m_status == CTF_MSG_ITER_MEDIUM_STATUS_EOF) { + /* + * User returned end of stream: validate that we're not + * in the middle of a packet header, packet context, or + * event. + */ + if (msg_it->cur_exp_packet_total_size >= 0) { + if (packet_at(msg_it) == msg_it->cur_exp_packet_total_size) { + goto end; + } + } else { + if (packet_at(msg_it) == 0) { + goto end; + } - BT_COMP_LOGD("User function returned new bytes: " - "packet-offset=%zu, cur=%zu, size=%zu, addr=%p", - msg_it->buf.packet_offset, msg_it->buf.at, - msg_it->buf.sz, msg_it->buf.addr); - BT_COMP_LOGT_MEM(buffer_addr, buffer_sz, "Returned bytes at %p:", - buffer_addr); - } else if (m_status == CTF_MSG_ITER_MEDIUM_STATUS_EOF) { - /* - * User returned end of stream: validate that we're not - * in the middle of a packet header, packet context, or - * event. - */ - if (msg_it->cur_exp_packet_total_size >= 0) { - if (packet_at(msg_it) == - msg_it->cur_exp_packet_total_size) { - goto end; - } - } else { - if (packet_at(msg_it) == 0) { - goto end; - } + if (msg_it->buf.last_eh_at != SIZE_MAX && msg_it->buf.at == msg_it->buf.last_eh_at) { + goto end; + } + } - if (msg_it->buf.last_eh_at != SIZE_MAX && - msg_it->buf.at == msg_it->buf.last_eh_at) { - goto end; - } - } - - /* All other states are invalid */ - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "User function returned %s, but message iterator is in an unexpected state: " - "state=%s, cur-packet-size=%" PRId64 ", cur=%zu, " - "packet-cur=%zu, last-eh-at=%zu", - ctf_msg_iter_medium_status_string(m_status), - state_string(msg_it->state), - msg_it->cur_exp_packet_total_size, - msg_it->buf.at, packet_at(msg_it), - msg_it->buf.last_eh_at); - m_status = CTF_MSG_ITER_MEDIUM_STATUS_ERROR; - } else if (m_status < 0) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, "User function failed: " - "status=%s", ctf_msg_iter_medium_status_string(m_status)); - } + /* All other states are invalid */ + BT_COMP_LOGE_APPEND_CAUSE( + self_comp, + "User function returned %s, but message iterator is in an unexpected state: " + "state=%s, cur-packet-size=%" PRId64 ", cur=%zu, " + "packet-cur=%zu, last-eh-at=%zu", + ctf_msg_iter_medium_status_string(m_status), state_string(msg_it->state), + msg_it->cur_exp_packet_total_size, msg_it->buf.at, packet_at(msg_it), + msg_it->buf.last_eh_at); + m_status = CTF_MSG_ITER_MEDIUM_STATUS_ERROR; + } else if (m_status < 0) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, + "User function failed: " + "status=%s", + ctf_msg_iter_medium_status_string(m_status)); + } end: - return msg_iter_status_from_m_status(m_status); -} - -static inline -enum ctf_msg_iter_status buf_ensure_available_bits( - struct ctf_msg_iter *msg_it) -{ - enum ctf_msg_iter_status status = CTF_MSG_ITER_STATUS_OK; - - if (G_UNLIKELY(buf_available_bits(msg_it) == 0)) { - /* - * This _cannot_ return CTF_MSG_ITER_STATUS_OK - * _and_ no bits. - */ - status = request_medium_bytes(msg_it); - } - - return status; -} - -static -enum ctf_msg_iter_status read_dscope_begin_state( - struct ctf_msg_iter *msg_it, - struct ctf_field_class *dscope_fc, - enum state done_state, enum state continue_state, - bt_field *dscope_field) -{ - enum ctf_msg_iter_status status = CTF_MSG_ITER_STATUS_OK; - bt_self_component *self_comp = msg_it->self_comp; - enum bt_bfcr_status bfcr_status; - size_t consumed_bits; - - msg_it->cur_dscope_field = dscope_field; - BT_COMP_LOGT("Starting BFCR: msg-it-addr=%p, bfcr-addr=%p, fc-addr=%p", - msg_it, msg_it->bfcr, dscope_fc); - consumed_bits = bt_bfcr_start(msg_it->bfcr, dscope_fc, - msg_it->buf.addr, msg_it->buf.at, packet_at(msg_it), - msg_it->buf.sz, &bfcr_status); - BT_COMP_LOGT("BFCR consumed bits: size=%zu", consumed_bits); - - switch (bfcr_status) { - case BT_BFCR_STATUS_OK: - /* Field class was read completely */ - BT_COMP_LOGT_STR("Field was completely decoded."); - msg_it->state = done_state; - break; - case BT_BFCR_STATUS_EOF: - BT_COMP_LOGT_STR("BFCR needs more data to decode field completely."); - msg_it->state = continue_state; - break; - default: - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "BFCR failed to start: msg-it-addr=%p, bfcr-addr=%p, " - "status=%s", msg_it, msg_it->bfcr, - bt_bfcr_status_string(bfcr_status)); - status = CTF_MSG_ITER_STATUS_ERROR; - goto end; - } - - /* Consume bits now since we know we're not in an error state */ - buf_consume_bits(msg_it, consumed_bits); + return msg_iter_status_from_m_status(m_status); +} + +static inline enum ctf_msg_iter_status buf_ensure_available_bits(struct ctf_msg_iter *msg_it) +{ + enum ctf_msg_iter_status status = CTF_MSG_ITER_STATUS_OK; + + if (G_UNLIKELY(buf_available_bits(msg_it) == 0)) { + /* + * This _cannot_ return CTF_MSG_ITER_STATUS_OK + * _and_ no bits. + */ + status = request_medium_bytes(msg_it); + } + + return status; +} + +static enum ctf_msg_iter_status +read_dscope_begin_state(struct ctf_msg_iter *msg_it, struct ctf_field_class *dscope_fc, + enum state done_state, enum state continue_state, bt_field *dscope_field) +{ + enum ctf_msg_iter_status status = CTF_MSG_ITER_STATUS_OK; + bt_self_component *self_comp = msg_it->self_comp; + enum bt_bfcr_status bfcr_status; + size_t consumed_bits; + + msg_it->cur_dscope_field = dscope_field; + BT_COMP_LOGT("Starting BFCR: msg-it-addr=%p, bfcr-addr=%p, fc-addr=%p", msg_it, msg_it->bfcr, + dscope_fc); + consumed_bits = bt_bfcr_start(msg_it->bfcr, dscope_fc, msg_it->buf.addr, msg_it->buf.at, + packet_at(msg_it), msg_it->buf.sz, &bfcr_status); + BT_COMP_LOGT("BFCR consumed bits: size=%zu", consumed_bits); + + switch (bfcr_status) { + case BT_BFCR_STATUS_OK: + /* Field class was read completely */ + BT_COMP_LOGT_STR("Field was completely decoded."); + msg_it->state = done_state; + break; + case BT_BFCR_STATUS_EOF: + BT_COMP_LOGT_STR("BFCR needs more data to decode field completely."); + msg_it->state = continue_state; + break; + default: + BT_COMP_LOGE_APPEND_CAUSE(self_comp, + "BFCR failed to start: msg-it-addr=%p, bfcr-addr=%p, " + "status=%s", + msg_it, msg_it->bfcr, bt_bfcr_status_string(bfcr_status)); + status = CTF_MSG_ITER_STATUS_ERROR; + goto end; + } + + /* Consume bits now since we know we're not in an error state */ + buf_consume_bits(msg_it, consumed_bits); end: - return status; -} - -static -enum ctf_msg_iter_status read_dscope_continue_state( - struct ctf_msg_iter *msg_it, enum state done_state) -{ - enum ctf_msg_iter_status status = CTF_MSG_ITER_STATUS_OK; - bt_self_component *self_comp = msg_it->self_comp; - enum bt_bfcr_status bfcr_status; - size_t consumed_bits; - - BT_COMP_LOGT("Continuing BFCR: msg-it-addr=%p, bfcr-addr=%p", - msg_it, msg_it->bfcr); - - status = buf_ensure_available_bits(msg_it); - if (status != CTF_MSG_ITER_STATUS_OK) { - if (status < 0) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Cannot ensure that buffer has at least one byte: " - "msg-addr=%p, status=%s", - msg_it, ctf_msg_iter_status_string(status)); - } else { - BT_COMP_LOGT("Cannot ensure that buffer has at least one byte: " - "msg-addr=%p, status=%s", - msg_it, ctf_msg_iter_status_string(status)); - } - - goto end; - } - - consumed_bits = bt_bfcr_continue(msg_it->bfcr, msg_it->buf.addr, - msg_it->buf.sz, &bfcr_status); - BT_COMP_LOGT("BFCR consumed bits: size=%zu", consumed_bits); - - switch (bfcr_status) { - case BT_BFCR_STATUS_OK: - /* Type was read completely. */ - BT_COMP_LOGT_STR("Field was completely decoded."); - msg_it->state = done_state; - break; - case BT_BFCR_STATUS_EOF: - /* Stay in this continue state. */ - BT_COMP_LOGT_STR("BFCR needs more data to decode field completely."); - break; - default: - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "BFCR failed to continue: msg-it-addr=%p, bfcr-addr=%p, " - "status=%s", msg_it, msg_it->bfcr, - bt_bfcr_status_string(bfcr_status)); - status = CTF_MSG_ITER_STATUS_ERROR; - goto end; - } - - /* Consume bits now since we know we're not in an error state. */ - buf_consume_bits(msg_it, consumed_bits); + return status; +} + +static enum ctf_msg_iter_status read_dscope_continue_state(struct ctf_msg_iter *msg_it, + enum state done_state) +{ + enum ctf_msg_iter_status status = CTF_MSG_ITER_STATUS_OK; + bt_self_component *self_comp = msg_it->self_comp; + enum bt_bfcr_status bfcr_status; + size_t consumed_bits; + + BT_COMP_LOGT("Continuing BFCR: msg-it-addr=%p, bfcr-addr=%p", msg_it, msg_it->bfcr); + + status = buf_ensure_available_bits(msg_it); + if (status != CTF_MSG_ITER_STATUS_OK) { + if (status < 0) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, + "Cannot ensure that buffer has at least one byte: " + "msg-addr=%p, status=%s", + msg_it, ctf_msg_iter_status_string(status)); + } else { + BT_COMP_LOGT("Cannot ensure that buffer has at least one byte: " + "msg-addr=%p, status=%s", + msg_it, ctf_msg_iter_status_string(status)); + } + + goto end; + } + + consumed_bits = bt_bfcr_continue(msg_it->bfcr, msg_it->buf.addr, msg_it->buf.sz, &bfcr_status); + BT_COMP_LOGT("BFCR consumed bits: size=%zu", consumed_bits); + + switch (bfcr_status) { + case BT_BFCR_STATUS_OK: + /* Type was read completely. */ + BT_COMP_LOGT_STR("Field was completely decoded."); + msg_it->state = done_state; + break; + case BT_BFCR_STATUS_EOF: + /* Stay in this continue state. */ + BT_COMP_LOGT_STR("BFCR needs more data to decode field completely."); + break; + default: + BT_COMP_LOGE_APPEND_CAUSE(self_comp, + "BFCR failed to continue: msg-it-addr=%p, bfcr-addr=%p, " + "status=%s", + msg_it, msg_it->bfcr, bt_bfcr_status_string(bfcr_status)); + status = CTF_MSG_ITER_STATUS_ERROR; + goto end; + } + + /* Consume bits now since we know we're not in an error state. */ + buf_consume_bits(msg_it, consumed_bits); end: - return status; -} - -static -void release_event_dscopes(struct ctf_msg_iter *msg_it) -{ - msg_it->dscopes.event_common_context = NULL; - msg_it->dscopes.event_spec_context = NULL; - msg_it->dscopes.event_payload = NULL; -} - -static -void release_all_dscopes(struct ctf_msg_iter *msg_it) -{ - msg_it->dscopes.stream_packet_context = NULL; - - release_event_dscopes(msg_it); -} - -static -enum ctf_msg_iter_status switch_packet_state(struct ctf_msg_iter *msg_it) -{ - enum ctf_msg_iter_status status; - bt_self_component *self_comp = msg_it->self_comp; - - /* - * We don't put the stream class here because we need to make - * sure that all the packets processed by the same message - * iterator refer to the same stream class (the first one). - */ - BT_ASSERT(msg_it); - - if (msg_it->cur_exp_packet_total_size != -1) { - msg_it->cur_packet_offset += msg_it->cur_exp_packet_total_size; - } - - BT_COMP_LOGD("Switching packet: msg-it-addr=%p, cur=%zu, " - "packet-offset=%" PRId64, msg_it, msg_it->buf.at, - msg_it->cur_packet_offset); - stack_clear(msg_it->stack); - msg_it->meta.ec = NULL; - BT_PACKET_PUT_REF_AND_RESET(msg_it->packet); - BT_MESSAGE_PUT_REF_AND_RESET(msg_it->event_msg); - release_all_dscopes(msg_it); - msg_it->cur_dscope_field = NULL; - - if (msg_it->medium.medops.switch_packet) { - enum ctf_msg_iter_medium_status medium_status; - - medium_status = msg_it->medium.medops.switch_packet(msg_it->medium.data); - if (medium_status == CTF_MSG_ITER_MEDIUM_STATUS_EOF) { - /* No more packets. */ - msg_it->state = STATE_CHECK_EMIT_MSG_STREAM_END; - status = CTF_MSG_ITER_STATUS_OK; - goto end; - } else if (medium_status != CTF_MSG_ITER_MEDIUM_STATUS_OK) { - status = msg_iter_status_from_m_status(medium_status); - goto end; - } - - /* - * After the packet switch, the medium might want to give us a - * different buffer for the new packet. - */ - status = request_medium_bytes(msg_it); - if (status != CTF_MSG_ITER_STATUS_OK) { - goto end; - } - } - - /* - * Adjust current buffer so that addr points to the beginning of the new - * packet. - */ - if (msg_it->buf.addr) { - size_t consumed_bytes = (size_t) (msg_it->buf.at / CHAR_BIT); - - /* Packets are assumed to start on a byte frontier. */ - if (msg_it->buf.at % CHAR_BIT) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Cannot switch packet: current position is not a multiple of 8: " - "msg-it-addr=%p, cur=%zu", msg_it, msg_it->buf.at); - status = CTF_MSG_ITER_STATUS_ERROR; - goto end; - } - - msg_it->buf.addr += consumed_bytes; - msg_it->buf.sz -= consumed_bytes; - msg_it->buf.at = 0; - msg_it->buf.packet_offset = 0; - BT_COMP_LOGD("Adjusted buffer: addr=%p, size=%zu", - msg_it->buf.addr, msg_it->buf.sz); - } - - msg_it->cur_exp_packet_content_size = -1; - msg_it->cur_exp_packet_total_size = -1; - msg_it->cur_stream_class_id = -1; - msg_it->cur_event_class_id = -1; - msg_it->cur_data_stream_id = -1; - msg_it->prev_packet_snapshots = msg_it->snapshots; - msg_it->snapshots.discarded_events = UINT64_C(-1); - msg_it->snapshots.packets = UINT64_C(-1); - msg_it->snapshots.beginning_clock = UINT64_C(-1); - msg_it->snapshots.end_clock = UINT64_C(-1); - msg_it->state = STATE_DSCOPE_TRACE_PACKET_HEADER_BEGIN; - - status = CTF_MSG_ITER_STATUS_OK; + return status; +} + +static void release_event_dscopes(struct ctf_msg_iter *msg_it) +{ + msg_it->dscopes.event_common_context = NULL; + msg_it->dscopes.event_spec_context = NULL; + msg_it->dscopes.event_payload = NULL; +} + +static void release_all_dscopes(struct ctf_msg_iter *msg_it) +{ + msg_it->dscopes.stream_packet_context = NULL; + + release_event_dscopes(msg_it); +} + +static enum ctf_msg_iter_status switch_packet_state(struct ctf_msg_iter *msg_it) +{ + enum ctf_msg_iter_status status; + bt_self_component *self_comp = msg_it->self_comp; + + /* + * We don't put the stream class here because we need to make + * sure that all the packets processed by the same message + * iterator refer to the same stream class (the first one). + */ + BT_ASSERT(msg_it); + + if (msg_it->cur_exp_packet_total_size != -1) { + msg_it->cur_packet_offset += msg_it->cur_exp_packet_total_size; + } + + BT_COMP_LOGD("Switching packet: msg-it-addr=%p, cur=%zu, " + "packet-offset=%" PRId64, + msg_it, msg_it->buf.at, msg_it->cur_packet_offset); + stack_clear(msg_it->stack); + msg_it->meta.ec = NULL; + BT_PACKET_PUT_REF_AND_RESET(msg_it->packet); + BT_MESSAGE_PUT_REF_AND_RESET(msg_it->event_msg); + release_all_dscopes(msg_it); + msg_it->cur_dscope_field = NULL; + + if (msg_it->medium.medops.switch_packet) { + enum ctf_msg_iter_medium_status medium_status; + + medium_status = msg_it->medium.medops.switch_packet(msg_it->medium.data); + if (medium_status == CTF_MSG_ITER_MEDIUM_STATUS_EOF) { + /* No more packets. */ + msg_it->state = STATE_CHECK_EMIT_MSG_STREAM_END; + status = CTF_MSG_ITER_STATUS_OK; + goto end; + } else if (medium_status != CTF_MSG_ITER_MEDIUM_STATUS_OK) { + status = msg_iter_status_from_m_status(medium_status); + goto end; + } + + /* + * After the packet switch, the medium might want to give us a + * different buffer for the new packet. + */ + status = request_medium_bytes(msg_it); + if (status != CTF_MSG_ITER_STATUS_OK) { + goto end; + } + } + + /* + * Adjust current buffer so that addr points to the beginning of the new + * packet. + */ + if (msg_it->buf.addr) { + size_t consumed_bytes = (size_t) (msg_it->buf.at / CHAR_BIT); + + /* Packets are assumed to start on a byte frontier. */ + if (msg_it->buf.at % CHAR_BIT) { + BT_COMP_LOGE_APPEND_CAUSE( + self_comp, + "Cannot switch packet: current position is not a multiple of 8: " + "msg-it-addr=%p, cur=%zu", + msg_it, msg_it->buf.at); + status = CTF_MSG_ITER_STATUS_ERROR; + goto end; + } + + msg_it->buf.addr += consumed_bytes; + msg_it->buf.sz -= consumed_bytes; + msg_it->buf.at = 0; + msg_it->buf.packet_offset = 0; + BT_COMP_LOGD("Adjusted buffer: addr=%p, size=%zu", msg_it->buf.addr, msg_it->buf.sz); + } + + msg_it->cur_exp_packet_content_size = -1; + msg_it->cur_exp_packet_total_size = -1; + msg_it->cur_stream_class_id = -1; + msg_it->cur_event_class_id = -1; + msg_it->cur_data_stream_id = -1; + msg_it->prev_packet_snapshots = msg_it->snapshots; + msg_it->snapshots.discarded_events = UINT64_C(-1); + msg_it->snapshots.packets = UINT64_C(-1); + msg_it->snapshots.beginning_clock = UINT64_C(-1); + msg_it->snapshots.end_clock = UINT64_C(-1); + msg_it->state = STATE_DSCOPE_TRACE_PACKET_HEADER_BEGIN; + + status = CTF_MSG_ITER_STATUS_OK; end: - return status; -} - -static -enum ctf_msg_iter_status read_packet_header_begin_state( - struct ctf_msg_iter *msg_it) -{ - struct ctf_field_class *packet_header_fc = NULL; - bt_self_component *self_comp = msg_it->self_comp; - enum ctf_msg_iter_status status = CTF_MSG_ITER_STATUS_OK; - - /* - * Make sure at least one bit is available for this packet. An - * empty packet is impossible. If we reach the end of the medium - * at this point, then it's considered the end of the stream. - */ - status = buf_ensure_available_bits(msg_it); - switch (status) { - case CTF_MSG_ITER_STATUS_OK: - break; - case CTF_MSG_ITER_STATUS_EOF: - status = CTF_MSG_ITER_STATUS_OK; - msg_it->state = STATE_CHECK_EMIT_MSG_STREAM_END; - goto end; - default: - goto end; - } - - /* Packet header class is common to the whole trace class. */ - packet_header_fc = msg_it->meta.tc->packet_header_fc; - if (!packet_header_fc) { - msg_it->state = STATE_AFTER_TRACE_PACKET_HEADER; - goto end; - } - - msg_it->cur_stream_class_id = -1; - msg_it->cur_event_class_id = -1; - msg_it->cur_data_stream_id = -1; - BT_COMP_LOGD("Decoding packet header field: " - "msg-it-addr=%p, trace-class-addr=%p, fc-addr=%p", - msg_it, msg_it->meta.tc, packet_header_fc); - status = read_dscope_begin_state(msg_it, packet_header_fc, - STATE_AFTER_TRACE_PACKET_HEADER, - STATE_DSCOPE_TRACE_PACKET_HEADER_CONTINUE, NULL); - if (status < 0) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Cannot decode packet header field: " - "msg-it-addr=%p, trace-class-addr=%p, " - "fc-addr=%p", - msg_it, msg_it->meta.tc, packet_header_fc); - } + return status; +} + +static enum ctf_msg_iter_status read_packet_header_begin_state(struct ctf_msg_iter *msg_it) +{ + struct ctf_field_class *packet_header_fc = NULL; + bt_self_component *self_comp = msg_it->self_comp; + enum ctf_msg_iter_status status = CTF_MSG_ITER_STATUS_OK; + + /* + * Make sure at least one bit is available for this packet. An + * empty packet is impossible. If we reach the end of the medium + * at this point, then it's considered the end of the stream. + */ + status = buf_ensure_available_bits(msg_it); + switch (status) { + case CTF_MSG_ITER_STATUS_OK: + break; + case CTF_MSG_ITER_STATUS_EOF: + status = CTF_MSG_ITER_STATUS_OK; + msg_it->state = STATE_CHECK_EMIT_MSG_STREAM_END; + goto end; + default: + goto end; + } + + /* Packet header class is common to the whole trace class. */ + packet_header_fc = msg_it->meta.tc->packet_header_fc; + if (!packet_header_fc) { + msg_it->state = STATE_AFTER_TRACE_PACKET_HEADER; + goto end; + } + + msg_it->cur_stream_class_id = -1; + msg_it->cur_event_class_id = -1; + msg_it->cur_data_stream_id = -1; + BT_COMP_LOGD("Decoding packet header field: " + "msg-it-addr=%p, trace-class-addr=%p, fc-addr=%p", + msg_it, msg_it->meta.tc, packet_header_fc); + status = read_dscope_begin_state(msg_it, packet_header_fc, STATE_AFTER_TRACE_PACKET_HEADER, + STATE_DSCOPE_TRACE_PACKET_HEADER_CONTINUE, NULL); + if (status < 0) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, + "Cannot decode packet header field: " + "msg-it-addr=%p, trace-class-addr=%p, " + "fc-addr=%p", + msg_it, msg_it->meta.tc, packet_header_fc); + } end: - return status; -} - -static -enum ctf_msg_iter_status read_packet_header_continue_state( - struct ctf_msg_iter *msg_it) -{ - return read_dscope_continue_state(msg_it, - STATE_AFTER_TRACE_PACKET_HEADER); -} - -static inline -enum ctf_msg_iter_status set_current_stream_class(struct ctf_msg_iter *msg_it) -{ - enum ctf_msg_iter_status status = CTF_MSG_ITER_STATUS_OK; - bt_self_component *self_comp = msg_it->self_comp; - struct ctf_stream_class *new_stream_class = NULL; - - if (msg_it->cur_stream_class_id == -1) { - /* - * No current stream class ID field, therefore only one - * stream class. - */ - if (msg_it->meta.tc->stream_classes->len != 1) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Need exactly one stream class since there's " - "no stream class ID field: " - "msg-it-addr=%p", msg_it); - status = CTF_MSG_ITER_STATUS_ERROR; - goto end; - } - - new_stream_class = (ctf_stream_class *) msg_it->meta.tc->stream_classes->pdata[0]; - msg_it->cur_stream_class_id = new_stream_class->id; - } - - new_stream_class = ctf_trace_class_borrow_stream_class_by_id( - msg_it->meta.tc, msg_it->cur_stream_class_id); - if (!new_stream_class) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "No stream class with ID of stream class ID to use in trace class: " - "msg-it-addr=%p, stream-class-id=%" PRIu64 ", " - "trace-class-addr=%p", - msg_it, msg_it->cur_stream_class_id, msg_it->meta.tc); - status = CTF_MSG_ITER_STATUS_ERROR; - goto end; - } - - if (msg_it->meta.sc) { - if (new_stream_class != msg_it->meta.sc) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Two packets refer to two different stream classes within the same packet sequence: " - "msg-it-addr=%p, prev-stream-class-addr=%p, " - "prev-stream-class-id=%" PRId64 ", " - "next-stream-class-addr=%p, " - "next-stream-class-id=%" PRId64 ", " - "trace-addr=%p", - msg_it, msg_it->meta.sc, - msg_it->meta.sc->id, - new_stream_class, - new_stream_class->id, - msg_it->meta.tc); - status = CTF_MSG_ITER_STATUS_ERROR; - goto end; - } - } else { - msg_it->meta.sc = new_stream_class; - } - - BT_COMP_LOGD("Set current stream class: " - "msg-it-addr=%p, stream-class-addr=%p, " - "stream-class-id=%" PRId64, - msg_it, msg_it->meta.sc, msg_it->meta.sc->id); + return status; +} + +static enum ctf_msg_iter_status read_packet_header_continue_state(struct ctf_msg_iter *msg_it) +{ + return read_dscope_continue_state(msg_it, STATE_AFTER_TRACE_PACKET_HEADER); +} + +static inline enum ctf_msg_iter_status set_current_stream_class(struct ctf_msg_iter *msg_it) +{ + enum ctf_msg_iter_status status = CTF_MSG_ITER_STATUS_OK; + bt_self_component *self_comp = msg_it->self_comp; + struct ctf_stream_class *new_stream_class = NULL; + + if (msg_it->cur_stream_class_id == -1) { + /* + * No current stream class ID field, therefore only one + * stream class. + */ + if (msg_it->meta.tc->stream_classes->len != 1) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, + "Need exactly one stream class since there's " + "no stream class ID field: " + "msg-it-addr=%p", + msg_it); + status = CTF_MSG_ITER_STATUS_ERROR; + goto end; + } + + new_stream_class = (ctf_stream_class *) msg_it->meta.tc->stream_classes->pdata[0]; + msg_it->cur_stream_class_id = new_stream_class->id; + } + + new_stream_class = + ctf_trace_class_borrow_stream_class_by_id(msg_it->meta.tc, msg_it->cur_stream_class_id); + if (!new_stream_class) { + BT_COMP_LOGE_APPEND_CAUSE( + self_comp, + "No stream class with ID of stream class ID to use in trace class: " + "msg-it-addr=%p, stream-class-id=%" PRIu64 ", " + "trace-class-addr=%p", + msg_it, msg_it->cur_stream_class_id, msg_it->meta.tc); + status = CTF_MSG_ITER_STATUS_ERROR; + goto end; + } + + if (msg_it->meta.sc) { + if (new_stream_class != msg_it->meta.sc) { + BT_COMP_LOGE_APPEND_CAUSE( + self_comp, + "Two packets refer to two different stream classes within the same packet sequence: " + "msg-it-addr=%p, prev-stream-class-addr=%p, " + "prev-stream-class-id=%" PRId64 ", " + "next-stream-class-addr=%p, " + "next-stream-class-id=%" PRId64 ", " + "trace-addr=%p", + msg_it, msg_it->meta.sc, msg_it->meta.sc->id, new_stream_class, + new_stream_class->id, msg_it->meta.tc); + status = CTF_MSG_ITER_STATUS_ERROR; + goto end; + } + } else { + msg_it->meta.sc = new_stream_class; + } + + BT_COMP_LOGD("Set current stream class: " + "msg-it-addr=%p, stream-class-addr=%p, " + "stream-class-id=%" PRId64, + msg_it, msg_it->meta.sc, msg_it->meta.sc->id); end: - return status; -} - -static inline -enum ctf_msg_iter_status set_current_stream(struct ctf_msg_iter *msg_it) -{ - enum ctf_msg_iter_status status = CTF_MSG_ITER_STATUS_OK; - bt_self_component *self_comp = msg_it->self_comp; - bt_stream *stream = NULL; - - BT_COMP_LOGD("Calling user function (get stream): msg-it-addr=%p, " - "stream-class-addr=%p, stream-class-id=%" PRId64, - msg_it, msg_it->meta.sc, - msg_it->meta.sc->id); - stream = msg_it->medium.medops.borrow_stream( - msg_it->meta.sc->ir_sc, msg_it->cur_data_stream_id, - msg_it->medium.data); - bt_stream_get_ref(stream); - BT_COMP_LOGD("User function returned: stream-addr=%p", stream); - if (!stream) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "User function failed to return a stream object for the given stream class."); - status = CTF_MSG_ITER_STATUS_ERROR; - goto end; - } - - if (msg_it->stream && stream != msg_it->stream) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "User function returned a different stream than the previous one for the same sequence of packets."); - status = CTF_MSG_ITER_STATUS_ERROR; - goto end; - } - - BT_STREAM_MOVE_REF(msg_it->stream, stream); + return status; +} + +static inline enum ctf_msg_iter_status set_current_stream(struct ctf_msg_iter *msg_it) +{ + enum ctf_msg_iter_status status = CTF_MSG_ITER_STATUS_OK; + bt_self_component *self_comp = msg_it->self_comp; + bt_stream *stream = NULL; + + BT_COMP_LOGD("Calling user function (get stream): msg-it-addr=%p, " + "stream-class-addr=%p, stream-class-id=%" PRId64, + msg_it, msg_it->meta.sc, msg_it->meta.sc->id); + stream = msg_it->medium.medops.borrow_stream(msg_it->meta.sc->ir_sc, msg_it->cur_data_stream_id, + msg_it->medium.data); + bt_stream_get_ref(stream); + BT_COMP_LOGD("User function returned: stream-addr=%p", stream); + if (!stream) { + BT_COMP_LOGE_APPEND_CAUSE( + self_comp, + "User function failed to return a stream object for the given stream class."); + status = CTF_MSG_ITER_STATUS_ERROR; + goto end; + } + + if (msg_it->stream && stream != msg_it->stream) { + BT_COMP_LOGE_APPEND_CAUSE( + self_comp, + "User function returned a different stream than the previous one for the same sequence of packets."); + status = CTF_MSG_ITER_STATUS_ERROR; + goto end; + } + + BT_STREAM_MOVE_REF(msg_it->stream, stream); end: - bt_stream_put_ref(stream); - return status; -} - -static inline -enum ctf_msg_iter_status set_current_packet(struct ctf_msg_iter *msg_it) -{ - enum ctf_msg_iter_status status = CTF_MSG_ITER_STATUS_OK; - bt_self_component *self_comp = msg_it->self_comp; - bt_packet *packet = NULL; - - BT_COMP_LOGD("Creating packet from stream: " - "msg-it-addr=%p, stream-addr=%p, " - "stream-class-addr=%p, " - "stream-class-id=%" PRId64, - msg_it, msg_it->stream, msg_it->meta.sc, - msg_it->meta.sc->id); - - /* Create packet */ - BT_ASSERT(msg_it->stream); - packet = bt_packet_create(msg_it->stream); - if (!packet) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Cannot create packet from stream: " - "msg-it-addr=%p, stream-addr=%p, " - "stream-class-addr=%p, " - "stream-class-id=%" PRId64, - msg_it, msg_it->stream, msg_it->meta.sc, - msg_it->meta.sc->id); - goto error; - } - - goto end; + bt_stream_put_ref(stream); + return status; +} + +static inline enum ctf_msg_iter_status set_current_packet(struct ctf_msg_iter *msg_it) +{ + enum ctf_msg_iter_status status = CTF_MSG_ITER_STATUS_OK; + bt_self_component *self_comp = msg_it->self_comp; + bt_packet *packet = NULL; + + BT_COMP_LOGD("Creating packet from stream: " + "msg-it-addr=%p, stream-addr=%p, " + "stream-class-addr=%p, " + "stream-class-id=%" PRId64, + msg_it, msg_it->stream, msg_it->meta.sc, msg_it->meta.sc->id); + + /* Create packet */ + BT_ASSERT(msg_it->stream); + packet = bt_packet_create(msg_it->stream); + if (!packet) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, + "Cannot create packet from stream: " + "msg-it-addr=%p, stream-addr=%p, " + "stream-class-addr=%p, " + "stream-class-id=%" PRId64, + msg_it, msg_it->stream, msg_it->meta.sc, msg_it->meta.sc->id); + goto error; + } + + goto end; error: - BT_PACKET_PUT_REF_AND_RESET(packet); - status = CTF_MSG_ITER_STATUS_ERROR; + BT_PACKET_PUT_REF_AND_RESET(packet); + status = CTF_MSG_ITER_STATUS_ERROR; end: - BT_PACKET_MOVE_REF(msg_it->packet, packet); - return status; + BT_PACKET_MOVE_REF(msg_it->packet, packet); + return status; } -static -enum ctf_msg_iter_status after_packet_header_state( - struct ctf_msg_iter *msg_it) +static enum ctf_msg_iter_status after_packet_header_state(struct ctf_msg_iter *msg_it) { - enum ctf_msg_iter_status status; + enum ctf_msg_iter_status status; - status = set_current_stream_class(msg_it); - if (status != CTF_MSG_ITER_STATUS_OK) { - goto end; - } + status = set_current_stream_class(msg_it); + if (status != CTF_MSG_ITER_STATUS_OK) { + goto end; + } - if (!msg_it->dry_run) { - status = set_current_stream(msg_it); - if (status != CTF_MSG_ITER_STATUS_OK) { - goto end; - } + if (!msg_it->dry_run) { + status = set_current_stream(msg_it); + if (status != CTF_MSG_ITER_STATUS_OK) { + goto end; + } - status = set_current_packet(msg_it); - if (status != CTF_MSG_ITER_STATUS_OK) { - goto end; - } - } + status = set_current_packet(msg_it); + if (status != CTF_MSG_ITER_STATUS_OK) { + goto end; + } + } - msg_it->state = STATE_DSCOPE_STREAM_PACKET_CONTEXT_BEGIN; + msg_it->state = STATE_DSCOPE_STREAM_PACKET_CONTEXT_BEGIN; - status = CTF_MSG_ITER_STATUS_OK; + status = CTF_MSG_ITER_STATUS_OK; end: - return status; -} - -static -enum ctf_msg_iter_status read_packet_context_begin_state( - struct ctf_msg_iter *msg_it) -{ - enum ctf_msg_iter_status status = CTF_MSG_ITER_STATUS_OK; - bt_self_component *self_comp = msg_it->self_comp; - struct ctf_field_class *packet_context_fc; - - BT_ASSERT(msg_it->meta.sc); - packet_context_fc = msg_it->meta.sc->packet_context_fc; - if (!packet_context_fc) { - BT_COMP_LOGD("No packet packet context field class in stream class: continuing: " - "msg-it-addr=%p, stream-class-addr=%p, " - "stream-class-id=%" PRId64, - msg_it, msg_it->meta.sc, - msg_it->meta.sc->id); - msg_it->state = STATE_AFTER_STREAM_PACKET_CONTEXT; - goto end; - } - - if (packet_context_fc->in_ir && !msg_it->dry_run) { - BT_ASSERT(!msg_it->dscopes.stream_packet_context); - BT_ASSERT(msg_it->packet); - msg_it->dscopes.stream_packet_context = - bt_packet_borrow_context_field(msg_it->packet); - BT_ASSERT(msg_it->dscopes.stream_packet_context); - } - - BT_COMP_LOGD("Decoding packet context field: " - "msg-it-addr=%p, stream-class-addr=%p, " - "stream-class-id=%" PRId64 ", fc-addr=%p", - msg_it, msg_it->meta.sc, - msg_it->meta.sc->id, packet_context_fc); - status = read_dscope_begin_state(msg_it, packet_context_fc, - STATE_AFTER_STREAM_PACKET_CONTEXT, - STATE_DSCOPE_STREAM_PACKET_CONTEXT_CONTINUE, - msg_it->dscopes.stream_packet_context); - if (status < 0) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Cannot decode packet context field: " - "msg-it-addr=%p, stream-class-addr=%p, " - "stream-class-id=%" PRId64 ", fc-addr=%p", - msg_it, msg_it->meta.sc, - msg_it->meta.sc->id, - packet_context_fc); - } + return status; +} + +static enum ctf_msg_iter_status read_packet_context_begin_state(struct ctf_msg_iter *msg_it) +{ + enum ctf_msg_iter_status status = CTF_MSG_ITER_STATUS_OK; + bt_self_component *self_comp = msg_it->self_comp; + struct ctf_field_class *packet_context_fc; + + BT_ASSERT(msg_it->meta.sc); + packet_context_fc = msg_it->meta.sc->packet_context_fc; + if (!packet_context_fc) { + BT_COMP_LOGD("No packet packet context field class in stream class: continuing: " + "msg-it-addr=%p, stream-class-addr=%p, " + "stream-class-id=%" PRId64, + msg_it, msg_it->meta.sc, msg_it->meta.sc->id); + msg_it->state = STATE_AFTER_STREAM_PACKET_CONTEXT; + goto end; + } + + if (packet_context_fc->in_ir && !msg_it->dry_run) { + BT_ASSERT(!msg_it->dscopes.stream_packet_context); + BT_ASSERT(msg_it->packet); + msg_it->dscopes.stream_packet_context = bt_packet_borrow_context_field(msg_it->packet); + BT_ASSERT(msg_it->dscopes.stream_packet_context); + } + + BT_COMP_LOGD("Decoding packet context field: " + "msg-it-addr=%p, stream-class-addr=%p, " + "stream-class-id=%" PRId64 ", fc-addr=%p", + msg_it, msg_it->meta.sc, msg_it->meta.sc->id, packet_context_fc); + status = read_dscope_begin_state(msg_it, packet_context_fc, STATE_AFTER_STREAM_PACKET_CONTEXT, + STATE_DSCOPE_STREAM_PACKET_CONTEXT_CONTINUE, + msg_it->dscopes.stream_packet_context); + if (status < 0) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, + "Cannot decode packet context field: " + "msg-it-addr=%p, stream-class-addr=%p, " + "stream-class-id=%" PRId64 ", fc-addr=%p", + msg_it, msg_it->meta.sc, msg_it->meta.sc->id, packet_context_fc); + } end: - return status; -} - -static -enum ctf_msg_iter_status read_packet_context_continue_state( - struct ctf_msg_iter *msg_it) -{ - return read_dscope_continue_state(msg_it, - STATE_AFTER_STREAM_PACKET_CONTEXT); -} - -static -enum ctf_msg_iter_status set_current_packet_content_sizes( - struct ctf_msg_iter *msg_it) -{ - enum ctf_msg_iter_status status = CTF_MSG_ITER_STATUS_OK; - bt_self_component *self_comp = msg_it->self_comp; - - if (msg_it->cur_exp_packet_total_size == -1) { - if (msg_it->cur_exp_packet_content_size != -1) { - msg_it->cur_exp_packet_total_size = - msg_it->cur_exp_packet_content_size; - } - } else { - if (msg_it->cur_exp_packet_content_size == -1) { - msg_it->cur_exp_packet_content_size = - msg_it->cur_exp_packet_total_size; - } - } - - BT_ASSERT((msg_it->cur_exp_packet_total_size >= 0 && - msg_it->cur_exp_packet_content_size >= 0) || - (msg_it->cur_exp_packet_total_size < 0 && - msg_it->cur_exp_packet_content_size < 0)); - - if (msg_it->cur_exp_packet_content_size > - msg_it->cur_exp_packet_total_size) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Invalid packet or content size: " - "content size is greater than packet size: " - "msg-it-addr=%p, packet-context-field-addr=%p, " - "packet-size=%" PRId64 ", content-size=%" PRId64, - msg_it, msg_it->dscopes.stream_packet_context, - msg_it->cur_exp_packet_total_size, - msg_it->cur_exp_packet_content_size); - status = CTF_MSG_ITER_STATUS_ERROR; - goto end; - } - - BT_COMP_LOGD("Set current packet and content sizes: " - "msg-it-addr=%p, packet-size=%" PRIu64 ", content-size=%" PRIu64, - msg_it, msg_it->cur_exp_packet_total_size, - msg_it->cur_exp_packet_content_size); + return status; +} + +static enum ctf_msg_iter_status read_packet_context_continue_state(struct ctf_msg_iter *msg_it) +{ + return read_dscope_continue_state(msg_it, STATE_AFTER_STREAM_PACKET_CONTEXT); +} + +static enum ctf_msg_iter_status set_current_packet_content_sizes(struct ctf_msg_iter *msg_it) +{ + enum ctf_msg_iter_status status = CTF_MSG_ITER_STATUS_OK; + bt_self_component *self_comp = msg_it->self_comp; + + if (msg_it->cur_exp_packet_total_size == -1) { + if (msg_it->cur_exp_packet_content_size != -1) { + msg_it->cur_exp_packet_total_size = msg_it->cur_exp_packet_content_size; + } + } else { + if (msg_it->cur_exp_packet_content_size == -1) { + msg_it->cur_exp_packet_content_size = msg_it->cur_exp_packet_total_size; + } + } + + BT_ASSERT( + (msg_it->cur_exp_packet_total_size >= 0 && msg_it->cur_exp_packet_content_size >= 0) || + (msg_it->cur_exp_packet_total_size < 0 && msg_it->cur_exp_packet_content_size < 0)); + + if (msg_it->cur_exp_packet_content_size > msg_it->cur_exp_packet_total_size) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, + "Invalid packet or content size: " + "content size is greater than packet size: " + "msg-it-addr=%p, packet-context-field-addr=%p, " + "packet-size=%" PRId64 ", content-size=%" PRId64, + msg_it, msg_it->dscopes.stream_packet_context, + msg_it->cur_exp_packet_total_size, + msg_it->cur_exp_packet_content_size); + status = CTF_MSG_ITER_STATUS_ERROR; + goto end; + } + + BT_COMP_LOGD("Set current packet and content sizes: " + "msg-it-addr=%p, packet-size=%" PRIu64 ", content-size=%" PRIu64, + msg_it, msg_it->cur_exp_packet_total_size, msg_it->cur_exp_packet_content_size); end: - return status; + return status; } -static -enum ctf_msg_iter_status after_packet_context_state(struct ctf_msg_iter *msg_it) +static enum ctf_msg_iter_status after_packet_context_state(struct ctf_msg_iter *msg_it) { - enum ctf_msg_iter_status status; + enum ctf_msg_iter_status status; - status = set_current_packet_content_sizes(msg_it); - if (status != CTF_MSG_ITER_STATUS_OK) { - goto end; - } + status = set_current_packet_content_sizes(msg_it); + if (status != CTF_MSG_ITER_STATUS_OK) { + goto end; + } - if (msg_it->emit_stream_beginning_message) { - msg_it->state = STATE_EMIT_MSG_STREAM_BEGINNING; - } else { - msg_it->state = STATE_CHECK_EMIT_MSG_DISCARDED_EVENTS; - } + if (msg_it->emit_stream_beginning_message) { + msg_it->state = STATE_EMIT_MSG_STREAM_BEGINNING; + } else { + msg_it->state = STATE_CHECK_EMIT_MSG_DISCARDED_EVENTS; + } end: - return status; -} - -static -enum ctf_msg_iter_status read_event_header_begin_state(struct ctf_msg_iter *msg_it) -{ - enum ctf_msg_iter_status status = CTF_MSG_ITER_STATUS_OK; - bt_self_component *self_comp = msg_it->self_comp; - struct ctf_field_class *event_header_fc = NULL; - - /* Reset the position of the last event header */ - msg_it->buf.last_eh_at = msg_it->buf.at; - msg_it->cur_event_class_id = -1; - - /* Check if we have some content left */ - if (msg_it->cur_exp_packet_content_size >= 0) { - if (G_UNLIKELY(packet_at(msg_it) == - msg_it->cur_exp_packet_content_size)) { - /* No more events! */ - BT_COMP_LOGD("Reached end of packet: msg-it-addr=%p, " - "cur=%zu", msg_it, packet_at(msg_it)); - msg_it->state = STATE_EMIT_MSG_PACKET_END_MULTI; - goto end; - } else if (G_UNLIKELY(packet_at(msg_it) > - msg_it->cur_exp_packet_content_size)) { - /* That's not supposed to happen */ - BT_COMP_LOGD("Before decoding event header field: cursor is passed the packet's content: " - "msg-it-addr=%p, content-size=%" PRId64 ", " - "cur=%zu", msg_it, - msg_it->cur_exp_packet_content_size, - packet_at(msg_it)); - status = CTF_MSG_ITER_STATUS_ERROR; - goto end; - } - } else { - /* - * "Infinite" content: we're done when the medium has - * nothing else for us. - */ - status = buf_ensure_available_bits(msg_it); - switch (status) { - case CTF_MSG_ITER_STATUS_OK: - break; - case CTF_MSG_ITER_STATUS_EOF: - status = CTF_MSG_ITER_STATUS_OK; - msg_it->state = STATE_EMIT_MSG_PACKET_END_SINGLE; - goto end; - default: - goto end; - } - } - - release_event_dscopes(msg_it); - BT_ASSERT(msg_it->meta.sc); - event_header_fc = msg_it->meta.sc->event_header_fc; - if (!event_header_fc) { - msg_it->state = STATE_AFTER_EVENT_HEADER; - goto end; - } - - BT_COMP_LOGD("Decoding event header field: " - "msg-it-addr=%p, stream-class-addr=%p, " - "stream-class-id=%" PRId64 ", " - "fc-addr=%p", - msg_it, msg_it->meta.sc, - msg_it->meta.sc->id, - event_header_fc); - status = read_dscope_begin_state(msg_it, event_header_fc, - STATE_AFTER_EVENT_HEADER, - STATE_DSCOPE_EVENT_HEADER_CONTINUE, NULL); - if (status < 0) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Cannot decode event header field: " - "msg-it-addr=%p, stream-class-addr=%p, " - "stream-class-id=%" PRId64 ", fc-addr=%p", - msg_it, msg_it->meta.sc, - msg_it->meta.sc->id, - event_header_fc); - } + return status; +} + +static enum ctf_msg_iter_status read_event_header_begin_state(struct ctf_msg_iter *msg_it) +{ + enum ctf_msg_iter_status status = CTF_MSG_ITER_STATUS_OK; + bt_self_component *self_comp = msg_it->self_comp; + struct ctf_field_class *event_header_fc = NULL; + + /* Reset the position of the last event header */ + msg_it->buf.last_eh_at = msg_it->buf.at; + msg_it->cur_event_class_id = -1; + + /* Check if we have some content left */ + if (msg_it->cur_exp_packet_content_size >= 0) { + if (G_UNLIKELY(packet_at(msg_it) == msg_it->cur_exp_packet_content_size)) { + /* No more events! */ + BT_COMP_LOGD("Reached end of packet: msg-it-addr=%p, " + "cur=%zu", + msg_it, packet_at(msg_it)); + msg_it->state = STATE_EMIT_MSG_PACKET_END_MULTI; + goto end; + } else if (G_UNLIKELY(packet_at(msg_it) > msg_it->cur_exp_packet_content_size)) { + /* That's not supposed to happen */ + BT_COMP_LOGD( + "Before decoding event header field: cursor is passed the packet's content: " + "msg-it-addr=%p, content-size=%" PRId64 ", " + "cur=%zu", + msg_it, msg_it->cur_exp_packet_content_size, packet_at(msg_it)); + status = CTF_MSG_ITER_STATUS_ERROR; + goto end; + } + } else { + /* + * "Infinite" content: we're done when the medium has + * nothing else for us. + */ + status = buf_ensure_available_bits(msg_it); + switch (status) { + case CTF_MSG_ITER_STATUS_OK: + break; + case CTF_MSG_ITER_STATUS_EOF: + status = CTF_MSG_ITER_STATUS_OK; + msg_it->state = STATE_EMIT_MSG_PACKET_END_SINGLE; + goto end; + default: + goto end; + } + } + + release_event_dscopes(msg_it); + BT_ASSERT(msg_it->meta.sc); + event_header_fc = msg_it->meta.sc->event_header_fc; + if (!event_header_fc) { + msg_it->state = STATE_AFTER_EVENT_HEADER; + goto end; + } + + BT_COMP_LOGD("Decoding event header field: " + "msg-it-addr=%p, stream-class-addr=%p, " + "stream-class-id=%" PRId64 ", " + "fc-addr=%p", + msg_it, msg_it->meta.sc, msg_it->meta.sc->id, event_header_fc); + status = read_dscope_begin_state(msg_it, event_header_fc, STATE_AFTER_EVENT_HEADER, + STATE_DSCOPE_EVENT_HEADER_CONTINUE, NULL); + if (status < 0) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, + "Cannot decode event header field: " + "msg-it-addr=%p, stream-class-addr=%p, " + "stream-class-id=%" PRId64 ", fc-addr=%p", + msg_it, msg_it->meta.sc, msg_it->meta.sc->id, event_header_fc); + } end: - return status; -} - -static -enum ctf_msg_iter_status read_event_header_continue_state( - struct ctf_msg_iter *msg_it) -{ - return read_dscope_continue_state(msg_it, - STATE_AFTER_EVENT_HEADER); -} - -static inline -enum ctf_msg_iter_status set_current_event_class(struct ctf_msg_iter *msg_it) -{ - enum ctf_msg_iter_status status = CTF_MSG_ITER_STATUS_OK; - bt_self_component *self_comp = msg_it->self_comp; - - struct ctf_event_class *new_event_class = NULL; - - if (msg_it->cur_event_class_id == -1) { - /* - * No current event class ID field, therefore only one - * event class. - */ - if (msg_it->meta.sc->event_classes->len != 1) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Need exactly one event class since there's no event class ID field: " - "msg-it-addr=%p", msg_it); - status = CTF_MSG_ITER_STATUS_ERROR; - goto end; - } - - new_event_class = (ctf_event_class *) msg_it->meta.sc->event_classes->pdata[0]; - msg_it->cur_event_class_id = new_event_class->id; - } - - new_event_class = ctf_stream_class_borrow_event_class_by_id( - msg_it->meta.sc, msg_it->cur_event_class_id); - if (!new_event_class) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "No event class with ID of event class ID to use in stream class: " - "msg-it-addr=%p, stream-class-id=%" PRIu64 ", " - "event-class-id=%" PRIu64 ", " - "trace-class-addr=%p", - msg_it, msg_it->meta.sc->id, msg_it->cur_event_class_id, - msg_it->meta.tc); - status = CTF_MSG_ITER_STATUS_ERROR; - goto end; - } - - msg_it->meta.ec = new_event_class; - BT_COMP_LOGD("Set current event class: " - "msg-it-addr=%p, event-class-addr=%p, " - "event-class-id=%" PRId64 ", " - "event-class-name=\"%s\"", - msg_it, msg_it->meta.ec, msg_it->meta.ec->id, - msg_it->meta.ec->name->str); + return status; +} + +static enum ctf_msg_iter_status read_event_header_continue_state(struct ctf_msg_iter *msg_it) +{ + return read_dscope_continue_state(msg_it, STATE_AFTER_EVENT_HEADER); +} + +static inline enum ctf_msg_iter_status set_current_event_class(struct ctf_msg_iter *msg_it) +{ + enum ctf_msg_iter_status status = CTF_MSG_ITER_STATUS_OK; + bt_self_component *self_comp = msg_it->self_comp; + + struct ctf_event_class *new_event_class = NULL; + + if (msg_it->cur_event_class_id == -1) { + /* + * No current event class ID field, therefore only one + * event class. + */ + if (msg_it->meta.sc->event_classes->len != 1) { + BT_COMP_LOGE_APPEND_CAUSE( + self_comp, + "Need exactly one event class since there's no event class ID field: " + "msg-it-addr=%p", + msg_it); + status = CTF_MSG_ITER_STATUS_ERROR; + goto end; + } + + new_event_class = (ctf_event_class *) msg_it->meta.sc->event_classes->pdata[0]; + msg_it->cur_event_class_id = new_event_class->id; + } + + new_event_class = + ctf_stream_class_borrow_event_class_by_id(msg_it->meta.sc, msg_it->cur_event_class_id); + if (!new_event_class) { + BT_COMP_LOGE_APPEND_CAUSE( + self_comp, + "No event class with ID of event class ID to use in stream class: " + "msg-it-addr=%p, stream-class-id=%" PRIu64 ", " + "event-class-id=%" PRIu64 ", " + "trace-class-addr=%p", + msg_it, msg_it->meta.sc->id, msg_it->cur_event_class_id, msg_it->meta.tc); + status = CTF_MSG_ITER_STATUS_ERROR; + goto end; + } + + msg_it->meta.ec = new_event_class; + BT_COMP_LOGD("Set current event class: " + "msg-it-addr=%p, event-class-addr=%p, " + "event-class-id=%" PRId64 ", " + "event-class-name=\"%s\"", + msg_it, msg_it->meta.ec, msg_it->meta.ec->id, msg_it->meta.ec->name->str); end: - return status; -} - -static inline -enum ctf_msg_iter_status set_current_event_message( - struct ctf_msg_iter *msg_it) -{ - enum ctf_msg_iter_status status = CTF_MSG_ITER_STATUS_OK; - bt_self_component *self_comp = msg_it->self_comp; - bt_message *msg = NULL; - - BT_ASSERT_DBG(msg_it->meta.ec); - BT_ASSERT_DBG(msg_it->packet); - BT_COMP_LOGD("Creating event message from event class and packet: " - "msg-it-addr=%p, ec-addr=%p, ec-name=\"%s\", packet-addr=%p", - msg_it, msg_it->meta.ec, - msg_it->meta.ec->name->str, - msg_it->packet); - BT_ASSERT_DBG(msg_it->self_msg_iter); - BT_ASSERT_DBG(msg_it->meta.sc); - - if (bt_stream_class_borrow_default_clock_class(msg_it->meta.sc->ir_sc)) { - msg = bt_message_event_create_with_packet_and_default_clock_snapshot( - msg_it->self_msg_iter, msg_it->meta.ec->ir_ec, - msg_it->packet, msg_it->default_clock_snapshot); - } else { - msg = bt_message_event_create_with_packet(msg_it->self_msg_iter, - msg_it->meta.ec->ir_ec, msg_it->packet); - } - - if (!msg) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Cannot create event message: " - "msg-it-addr=%p, ec-addr=%p, ec-name=\"%s\", " - "packet-addr=%p", - msg_it, msg_it->meta.ec, - msg_it->meta.ec->name->str, - msg_it->packet); - goto error; - } - - goto end; + return status; +} + +static inline enum ctf_msg_iter_status set_current_event_message(struct ctf_msg_iter *msg_it) +{ + enum ctf_msg_iter_status status = CTF_MSG_ITER_STATUS_OK; + bt_self_component *self_comp = msg_it->self_comp; + bt_message *msg = NULL; + + BT_ASSERT_DBG(msg_it->meta.ec); + BT_ASSERT_DBG(msg_it->packet); + BT_COMP_LOGD("Creating event message from event class and packet: " + "msg-it-addr=%p, ec-addr=%p, ec-name=\"%s\", packet-addr=%p", + msg_it, msg_it->meta.ec, msg_it->meta.ec->name->str, msg_it->packet); + BT_ASSERT_DBG(msg_it->self_msg_iter); + BT_ASSERT_DBG(msg_it->meta.sc); + + if (bt_stream_class_borrow_default_clock_class(msg_it->meta.sc->ir_sc)) { + msg = bt_message_event_create_with_packet_and_default_clock_snapshot( + msg_it->self_msg_iter, msg_it->meta.ec->ir_ec, msg_it->packet, + msg_it->default_clock_snapshot); + } else { + msg = bt_message_event_create_with_packet(msg_it->self_msg_iter, msg_it->meta.ec->ir_ec, + msg_it->packet); + } + + if (!msg) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, + "Cannot create event message: " + "msg-it-addr=%p, ec-addr=%p, ec-name=\"%s\", " + "packet-addr=%p", + msg_it, msg_it->meta.ec, msg_it->meta.ec->name->str, + msg_it->packet); + goto error; + } + + goto end; error: - BT_MESSAGE_PUT_REF_AND_RESET(msg); - status = CTF_MSG_ITER_STATUS_ERROR; + BT_MESSAGE_PUT_REF_AND_RESET(msg); + status = CTF_MSG_ITER_STATUS_ERROR; end: - BT_MESSAGE_MOVE_REF(msg_it->event_msg, msg); - return status; + BT_MESSAGE_MOVE_REF(msg_it->event_msg, msg); + return status; } -static -enum ctf_msg_iter_status after_event_header_state( - struct ctf_msg_iter *msg_it) +static enum ctf_msg_iter_status after_event_header_state(struct ctf_msg_iter *msg_it) { - enum ctf_msg_iter_status status; + enum ctf_msg_iter_status status; - status = set_current_event_class(msg_it); - if (status != CTF_MSG_ITER_STATUS_OK) { - goto end; - } + status = set_current_event_class(msg_it); + if (status != CTF_MSG_ITER_STATUS_OK) { + goto end; + } - if (G_UNLIKELY(msg_it->dry_run)) { - goto next_state; - } + if (G_UNLIKELY(msg_it->dry_run)) { + goto next_state; + } - status = set_current_event_message(msg_it); - if (status != CTF_MSG_ITER_STATUS_OK) { - goto end; - } + status = set_current_event_message(msg_it); + if (status != CTF_MSG_ITER_STATUS_OK) { + goto end; + } - msg_it->event = bt_message_event_borrow_event( - msg_it->event_msg); - BT_ASSERT_DBG(msg_it->event); + msg_it->event = bt_message_event_borrow_event(msg_it->event_msg); + BT_ASSERT_DBG(msg_it->event); next_state: - msg_it->state = STATE_DSCOPE_EVENT_COMMON_CONTEXT_BEGIN; + msg_it->state = STATE_DSCOPE_EVENT_COMMON_CONTEXT_BEGIN; end: - return status; -} - -static -enum ctf_msg_iter_status read_event_common_context_begin_state( - struct ctf_msg_iter *msg_it) -{ - enum ctf_msg_iter_status status = CTF_MSG_ITER_STATUS_OK; - bt_self_component *self_comp = msg_it->self_comp; - struct ctf_field_class *event_common_context_fc; - - event_common_context_fc = msg_it->meta.sc->event_common_context_fc; - if (!event_common_context_fc) { - msg_it->state = STATE_DSCOPE_EVENT_SPEC_CONTEXT_BEGIN; - goto end; - } - - if (event_common_context_fc->in_ir && !msg_it->dry_run) { - BT_ASSERT_DBG(!msg_it->dscopes.event_common_context); - msg_it->dscopes.event_common_context = - bt_event_borrow_common_context_field( - msg_it->event); - BT_ASSERT_DBG(msg_it->dscopes.event_common_context); - } - - BT_COMP_LOGT("Decoding event common context field: " - "msg-it-addr=%p, stream-class-addr=%p, " - "stream-class-id=%" PRId64 ", " - "fc-addr=%p", - msg_it, msg_it->meta.sc, - msg_it->meta.sc->id, - event_common_context_fc); - status = read_dscope_begin_state(msg_it, event_common_context_fc, - STATE_DSCOPE_EVENT_SPEC_CONTEXT_BEGIN, - STATE_DSCOPE_EVENT_COMMON_CONTEXT_CONTINUE, - msg_it->dscopes.event_common_context); - if (status < 0) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Cannot decode event common context field: " - "msg-it-addr=%p, stream-class-addr=%p, " - "stream-class-id=%" PRId64 ", fc-addr=%p", - msg_it, msg_it->meta.sc, - msg_it->meta.sc->id, - event_common_context_fc); - } + return status; +} + +static enum ctf_msg_iter_status read_event_common_context_begin_state(struct ctf_msg_iter *msg_it) +{ + enum ctf_msg_iter_status status = CTF_MSG_ITER_STATUS_OK; + bt_self_component *self_comp = msg_it->self_comp; + struct ctf_field_class *event_common_context_fc; + + event_common_context_fc = msg_it->meta.sc->event_common_context_fc; + if (!event_common_context_fc) { + msg_it->state = STATE_DSCOPE_EVENT_SPEC_CONTEXT_BEGIN; + goto end; + } + + if (event_common_context_fc->in_ir && !msg_it->dry_run) { + BT_ASSERT_DBG(!msg_it->dscopes.event_common_context); + msg_it->dscopes.event_common_context = bt_event_borrow_common_context_field(msg_it->event); + BT_ASSERT_DBG(msg_it->dscopes.event_common_context); + } + + BT_COMP_LOGT("Decoding event common context field: " + "msg-it-addr=%p, stream-class-addr=%p, " + "stream-class-id=%" PRId64 ", " + "fc-addr=%p", + msg_it, msg_it->meta.sc, msg_it->meta.sc->id, event_common_context_fc); + status = read_dscope_begin_state( + msg_it, event_common_context_fc, STATE_DSCOPE_EVENT_SPEC_CONTEXT_BEGIN, + STATE_DSCOPE_EVENT_COMMON_CONTEXT_CONTINUE, msg_it->dscopes.event_common_context); + if (status < 0) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, + "Cannot decode event common context field: " + "msg-it-addr=%p, stream-class-addr=%p, " + "stream-class-id=%" PRId64 ", fc-addr=%p", + msg_it, msg_it->meta.sc, msg_it->meta.sc->id, + event_common_context_fc); + } end: - return status; -} - -static -enum ctf_msg_iter_status read_event_common_context_continue_state( - struct ctf_msg_iter *msg_it) -{ - return read_dscope_continue_state(msg_it, - STATE_DSCOPE_EVENT_SPEC_CONTEXT_BEGIN); -} - -static -enum ctf_msg_iter_status read_event_spec_context_begin_state( - struct ctf_msg_iter *msg_it) -{ - enum ctf_msg_iter_status status = CTF_MSG_ITER_STATUS_OK; - bt_self_component *self_comp = msg_it->self_comp; - struct ctf_field_class *event_spec_context_fc; - - event_spec_context_fc = msg_it->meta.ec->spec_context_fc; - if (!event_spec_context_fc) { - msg_it->state = STATE_DSCOPE_EVENT_PAYLOAD_BEGIN; - goto end; - } - - if (event_spec_context_fc->in_ir && !msg_it->dry_run) { - BT_ASSERT_DBG(!msg_it->dscopes.event_spec_context); - msg_it->dscopes.event_spec_context = - bt_event_borrow_specific_context_field( - msg_it->event); - BT_ASSERT_DBG(msg_it->dscopes.event_spec_context); - } - - BT_COMP_LOGT("Decoding event specific context field: " - "msg-it-addr=%p, event-class-addr=%p, " - "event-class-name=\"%s\", event-class-id=%" PRId64 ", " - "fc-addr=%p", - msg_it, msg_it->meta.ec, - msg_it->meta.ec->name->str, - msg_it->meta.ec->id, - event_spec_context_fc); - status = read_dscope_begin_state(msg_it, event_spec_context_fc, - STATE_DSCOPE_EVENT_PAYLOAD_BEGIN, - STATE_DSCOPE_EVENT_SPEC_CONTEXT_CONTINUE, - msg_it->dscopes.event_spec_context); - if (status < 0) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Cannot decode event specific context field: " - "msg-it-addr=%p, event-class-addr=%p, " - "event-class-name=\"%s\", " - "event-class-id=%" PRId64 ", fc-addr=%p", - msg_it, msg_it->meta.ec, - msg_it->meta.ec->name->str, - msg_it->meta.ec->id, - event_spec_context_fc); - } + return status; +} + +static enum ctf_msg_iter_status +read_event_common_context_continue_state(struct ctf_msg_iter *msg_it) +{ + return read_dscope_continue_state(msg_it, STATE_DSCOPE_EVENT_SPEC_CONTEXT_BEGIN); +} + +static enum ctf_msg_iter_status read_event_spec_context_begin_state(struct ctf_msg_iter *msg_it) +{ + enum ctf_msg_iter_status status = CTF_MSG_ITER_STATUS_OK; + bt_self_component *self_comp = msg_it->self_comp; + struct ctf_field_class *event_spec_context_fc; + + event_spec_context_fc = msg_it->meta.ec->spec_context_fc; + if (!event_spec_context_fc) { + msg_it->state = STATE_DSCOPE_EVENT_PAYLOAD_BEGIN; + goto end; + } + + if (event_spec_context_fc->in_ir && !msg_it->dry_run) { + BT_ASSERT_DBG(!msg_it->dscopes.event_spec_context); + msg_it->dscopes.event_spec_context = bt_event_borrow_specific_context_field(msg_it->event); + BT_ASSERT_DBG(msg_it->dscopes.event_spec_context); + } + + BT_COMP_LOGT("Decoding event specific context field: " + "msg-it-addr=%p, event-class-addr=%p, " + "event-class-name=\"%s\", event-class-id=%" PRId64 ", " + "fc-addr=%p", + msg_it, msg_it->meta.ec, msg_it->meta.ec->name->str, msg_it->meta.ec->id, + event_spec_context_fc); + status = read_dscope_begin_state( + msg_it, event_spec_context_fc, STATE_DSCOPE_EVENT_PAYLOAD_BEGIN, + STATE_DSCOPE_EVENT_SPEC_CONTEXT_CONTINUE, msg_it->dscopes.event_spec_context); + if (status < 0) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, + "Cannot decode event specific context field: " + "msg-it-addr=%p, event-class-addr=%p, " + "event-class-name=\"%s\", " + "event-class-id=%" PRId64 ", fc-addr=%p", + msg_it, msg_it->meta.ec, msg_it->meta.ec->name->str, + msg_it->meta.ec->id, event_spec_context_fc); + } end: - return status; -} - -static -enum ctf_msg_iter_status read_event_spec_context_continue_state( - struct ctf_msg_iter *msg_it) -{ - return read_dscope_continue_state(msg_it, - STATE_DSCOPE_EVENT_PAYLOAD_BEGIN); -} - -static -enum ctf_msg_iter_status read_event_payload_begin_state( - struct ctf_msg_iter *msg_it) -{ - enum ctf_msg_iter_status status = CTF_MSG_ITER_STATUS_OK; - bt_self_component *self_comp = msg_it->self_comp; - struct ctf_field_class *event_payload_fc; - - event_payload_fc = msg_it->meta.ec->payload_fc; - if (!event_payload_fc) { - msg_it->state = STATE_EMIT_MSG_EVENT; - goto end; - } - - if (event_payload_fc->in_ir && !msg_it->dry_run) { - BT_ASSERT_DBG(!msg_it->dscopes.event_payload); - msg_it->dscopes.event_payload = - bt_event_borrow_payload_field( - msg_it->event); - BT_ASSERT_DBG(msg_it->dscopes.event_payload); - } - - BT_COMP_LOGT("Decoding event payload field: " - "msg-it-addr=%p, event-class-addr=%p, " - "event-class-name=\"%s\", event-class-id=%" PRId64 ", " - "fc-addr=%p", - msg_it, msg_it->meta.ec, - msg_it->meta.ec->name->str, - msg_it->meta.ec->id, - event_payload_fc); - status = read_dscope_begin_state(msg_it, event_payload_fc, - STATE_EMIT_MSG_EVENT, - STATE_DSCOPE_EVENT_PAYLOAD_CONTINUE, - msg_it->dscopes.event_payload); - if (status < 0) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Cannot decode event payload field: " - "msg-it-addr=%p, event-class-addr=%p, " - "event-class-name=\"%s\", " - "event-class-id=%" PRId64 ", fc-addr=%p", - msg_it, msg_it->meta.ec, - msg_it->meta.ec->name->str, - msg_it->meta.ec->id, - event_payload_fc); - } + return status; +} + +static enum ctf_msg_iter_status read_event_spec_context_continue_state(struct ctf_msg_iter *msg_it) +{ + return read_dscope_continue_state(msg_it, STATE_DSCOPE_EVENT_PAYLOAD_BEGIN); +} + +static enum ctf_msg_iter_status read_event_payload_begin_state(struct ctf_msg_iter *msg_it) +{ + enum ctf_msg_iter_status status = CTF_MSG_ITER_STATUS_OK; + bt_self_component *self_comp = msg_it->self_comp; + struct ctf_field_class *event_payload_fc; + + event_payload_fc = msg_it->meta.ec->payload_fc; + if (!event_payload_fc) { + msg_it->state = STATE_EMIT_MSG_EVENT; + goto end; + } + + if (event_payload_fc->in_ir && !msg_it->dry_run) { + BT_ASSERT_DBG(!msg_it->dscopes.event_payload); + msg_it->dscopes.event_payload = bt_event_borrow_payload_field(msg_it->event); + BT_ASSERT_DBG(msg_it->dscopes.event_payload); + } + + BT_COMP_LOGT("Decoding event payload field: " + "msg-it-addr=%p, event-class-addr=%p, " + "event-class-name=\"%s\", event-class-id=%" PRId64 ", " + "fc-addr=%p", + msg_it, msg_it->meta.ec, msg_it->meta.ec->name->str, msg_it->meta.ec->id, + event_payload_fc); + status = + read_dscope_begin_state(msg_it, event_payload_fc, STATE_EMIT_MSG_EVENT, + STATE_DSCOPE_EVENT_PAYLOAD_CONTINUE, msg_it->dscopes.event_payload); + if (status < 0) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, + "Cannot decode event payload field: " + "msg-it-addr=%p, event-class-addr=%p, " + "event-class-name=\"%s\", " + "event-class-id=%" PRId64 ", fc-addr=%p", + msg_it, msg_it->meta.ec, msg_it->meta.ec->name->str, + msg_it->meta.ec->id, event_payload_fc); + } end: - return status; -} - -static -enum ctf_msg_iter_status read_event_payload_continue_state( - struct ctf_msg_iter *msg_it) -{ - return read_dscope_continue_state(msg_it, STATE_EMIT_MSG_EVENT); -} - -static -enum ctf_msg_iter_status skip_packet_padding_state(struct ctf_msg_iter *msg_it) -{ - enum ctf_msg_iter_status status = CTF_MSG_ITER_STATUS_OK; - size_t bits_to_skip; - const enum state next_state = STATE_SWITCH_PACKET; - - BT_ASSERT(msg_it->cur_exp_packet_total_size > 0); - bits_to_skip = msg_it->cur_exp_packet_total_size - packet_at(msg_it); - if (bits_to_skip == 0) { - msg_it->state = next_state; - goto end; - } else { - size_t bits_to_consume; - - BT_COMP_LOGD("Trying to skip %zu bits of padding: msg-it-addr=%p, size=%zu", - bits_to_skip, msg_it, bits_to_skip); - status = buf_ensure_available_bits(msg_it); - if (status != CTF_MSG_ITER_STATUS_OK) { - goto end; - } - - bits_to_consume = MIN(buf_available_bits(msg_it), bits_to_skip); - BT_COMP_LOGD("Skipping %zu bits of padding: msg-it-addr=%p, size=%zu", - bits_to_consume, msg_it, bits_to_consume); - buf_consume_bits(msg_it, bits_to_consume); - bits_to_skip = msg_it->cur_exp_packet_total_size - - packet_at(msg_it); - if (bits_to_skip == 0) { - msg_it->state = next_state; - goto end; - } - } + return status; +} + +static enum ctf_msg_iter_status read_event_payload_continue_state(struct ctf_msg_iter *msg_it) +{ + return read_dscope_continue_state(msg_it, STATE_EMIT_MSG_EVENT); +} + +static enum ctf_msg_iter_status skip_packet_padding_state(struct ctf_msg_iter *msg_it) +{ + enum ctf_msg_iter_status status = CTF_MSG_ITER_STATUS_OK; + size_t bits_to_skip; + const enum state next_state = STATE_SWITCH_PACKET; + + BT_ASSERT(msg_it->cur_exp_packet_total_size > 0); + bits_to_skip = msg_it->cur_exp_packet_total_size - packet_at(msg_it); + if (bits_to_skip == 0) { + msg_it->state = next_state; + goto end; + } else { + size_t bits_to_consume; + + BT_COMP_LOGD("Trying to skip %zu bits of padding: msg-it-addr=%p, size=%zu", bits_to_skip, + msg_it, bits_to_skip); + status = buf_ensure_available_bits(msg_it); + if (status != CTF_MSG_ITER_STATUS_OK) { + goto end; + } + + bits_to_consume = MIN(buf_available_bits(msg_it), bits_to_skip); + BT_COMP_LOGD("Skipping %zu bits of padding: msg-it-addr=%p, size=%zu", bits_to_consume, + msg_it, bits_to_consume); + buf_consume_bits(msg_it, bits_to_consume); + bits_to_skip = msg_it->cur_exp_packet_total_size - packet_at(msg_it); + if (bits_to_skip == 0) { + msg_it->state = next_state; + goto end; + } + } end: - return status; -} - -static -enum ctf_msg_iter_status check_emit_msg_discarded_events( - struct ctf_msg_iter *msg_it) -{ - msg_it->state = STATE_EMIT_MSG_DISCARDED_EVENTS; - - if (!msg_it->meta.sc->has_discarded_events) { - msg_it->state = STATE_CHECK_EMIT_MSG_DISCARDED_PACKETS; - goto end; - } - - if (msg_it->prev_packet_snapshots.discarded_events == UINT64_C(-1)) { - if (msg_it->snapshots.discarded_events == 0 || - msg_it->snapshots.discarded_events == UINT64_C(-1)) { - /* - * Stream's first packet with no discarded - * events or no information about discarded - * events: do not emit. - */ - msg_it->state = STATE_CHECK_EMIT_MSG_DISCARDED_PACKETS; - } - } else { - /* - * If the previous packet has a value for this counter, - * then this counter is defined for the whole stream. - */ - BT_ASSERT(msg_it->snapshots.discarded_events != UINT64_C(-1)); - - if (msg_it->snapshots.discarded_events - - msg_it->prev_packet_snapshots.discarded_events == 0) { - /* - * No discarded events since previous packet: do - * not emit. - */ - msg_it->state = STATE_CHECK_EMIT_MSG_DISCARDED_PACKETS; - } - } + return status; +} + +static enum ctf_msg_iter_status check_emit_msg_discarded_events(struct ctf_msg_iter *msg_it) +{ + msg_it->state = STATE_EMIT_MSG_DISCARDED_EVENTS; + + if (!msg_it->meta.sc->has_discarded_events) { + msg_it->state = STATE_CHECK_EMIT_MSG_DISCARDED_PACKETS; + goto end; + } + + if (msg_it->prev_packet_snapshots.discarded_events == UINT64_C(-1)) { + if (msg_it->snapshots.discarded_events == 0 || + msg_it->snapshots.discarded_events == UINT64_C(-1)) { + /* + * Stream's first packet with no discarded + * events or no information about discarded + * events: do not emit. + */ + msg_it->state = STATE_CHECK_EMIT_MSG_DISCARDED_PACKETS; + } + } else { + /* + * If the previous packet has a value for this counter, + * then this counter is defined for the whole stream. + */ + BT_ASSERT(msg_it->snapshots.discarded_events != UINT64_C(-1)); + + if (msg_it->snapshots.discarded_events - msg_it->prev_packet_snapshots.discarded_events == + 0) { + /* + * No discarded events since previous packet: do + * not emit. + */ + msg_it->state = STATE_CHECK_EMIT_MSG_DISCARDED_PACKETS; + } + } end: - return CTF_MSG_ITER_STATUS_OK; -} - -static -enum ctf_msg_iter_status check_emit_msg_discarded_packets( - struct ctf_msg_iter *msg_it) -{ - msg_it->state = STATE_EMIT_MSG_DISCARDED_PACKETS; - - if (!msg_it->meta.sc->has_discarded_packets) { - msg_it->state = STATE_EMIT_MSG_PACKET_BEGINNING; - goto end; - } - - if (msg_it->prev_packet_snapshots.packets == UINT64_C(-1)) { - /* - * Stream's first packet or no information about - * discarded packets: do not emit. In other words, if - * this is the first packet and its sequence number is - * not 0, do not consider that packets were previously - * lost: we might be reading a partial stream (LTTng - * snapshot for example). - */ - msg_it->state = STATE_EMIT_MSG_PACKET_BEGINNING; - } else { - /* - * If the previous packet has a value for this counter, - * then this counter is defined for the whole stream. - */ - BT_ASSERT(msg_it->snapshots.packets != UINT64_C(-1)); - - if (msg_it->snapshots.packets - - msg_it->prev_packet_snapshots.packets <= 1) { - /* - * No discarded packets since previous packet: - * do not emit. - */ - msg_it->state = STATE_EMIT_MSG_PACKET_BEGINNING; - } - } + return CTF_MSG_ITER_STATUS_OK; +} + +static enum ctf_msg_iter_status check_emit_msg_discarded_packets(struct ctf_msg_iter *msg_it) +{ + msg_it->state = STATE_EMIT_MSG_DISCARDED_PACKETS; + + if (!msg_it->meta.sc->has_discarded_packets) { + msg_it->state = STATE_EMIT_MSG_PACKET_BEGINNING; + goto end; + } + + if (msg_it->prev_packet_snapshots.packets == UINT64_C(-1)) { + /* + * Stream's first packet or no information about + * discarded packets: do not emit. In other words, if + * this is the first packet and its sequence number is + * not 0, do not consider that packets were previously + * lost: we might be reading a partial stream (LTTng + * snapshot for example). + */ + msg_it->state = STATE_EMIT_MSG_PACKET_BEGINNING; + } else { + /* + * If the previous packet has a value for this counter, + * then this counter is defined for the whole stream. + */ + BT_ASSERT(msg_it->snapshots.packets != UINT64_C(-1)); + + if (msg_it->snapshots.packets - msg_it->prev_packet_snapshots.packets <= 1) { + /* + * No discarded packets since previous packet: + * do not emit. + */ + msg_it->state = STATE_EMIT_MSG_PACKET_BEGINNING; + } + } end: - return CTF_MSG_ITER_STATUS_OK; -} - -static inline -enum state check_emit_msg_stream_end(struct ctf_msg_iter *msg_it) -{ - enum state next_state; - - if (msg_it->emit_stream_end_message) { - next_state = STATE_EMIT_MSG_STREAM_END; - } else { - next_state = STATE_DONE; - } - - return next_state; -} - -static inline -enum ctf_msg_iter_status handle_state(struct ctf_msg_iter *msg_it) -{ - enum ctf_msg_iter_status status = CTF_MSG_ITER_STATUS_OK; - const enum state state = msg_it->state; - - BT_COMP_LOGT("Handling state: msg-it-addr=%p, state=%s", - msg_it, state_string(state)); - - // TODO: optimalize! - switch (state) { - case STATE_INIT: - msg_it->state = STATE_SWITCH_PACKET; - break; - case STATE_SWITCH_PACKET: - status = switch_packet_state(msg_it); - break; - case STATE_DSCOPE_TRACE_PACKET_HEADER_BEGIN: - status = read_packet_header_begin_state(msg_it); - break; - case STATE_DSCOPE_TRACE_PACKET_HEADER_CONTINUE: - status = read_packet_header_continue_state(msg_it); - break; - case STATE_AFTER_TRACE_PACKET_HEADER: - status = after_packet_header_state(msg_it); - break; - case STATE_DSCOPE_STREAM_PACKET_CONTEXT_BEGIN: - status = read_packet_context_begin_state(msg_it); - break; - case STATE_DSCOPE_STREAM_PACKET_CONTEXT_CONTINUE: - status = read_packet_context_continue_state(msg_it); - break; - case STATE_AFTER_STREAM_PACKET_CONTEXT: - status = after_packet_context_state(msg_it); - break; - case STATE_EMIT_MSG_STREAM_BEGINNING: - msg_it->state = STATE_CHECK_EMIT_MSG_DISCARDED_EVENTS; - break; - case STATE_CHECK_EMIT_MSG_DISCARDED_EVENTS: - status = check_emit_msg_discarded_events(msg_it); - break; - case STATE_EMIT_MSG_DISCARDED_EVENTS: - msg_it->state = STATE_CHECK_EMIT_MSG_DISCARDED_PACKETS; - break; - case STATE_CHECK_EMIT_MSG_DISCARDED_PACKETS: - status = check_emit_msg_discarded_packets(msg_it); - break; - case STATE_EMIT_MSG_DISCARDED_PACKETS: - msg_it->state = STATE_EMIT_MSG_PACKET_BEGINNING; - break; - case STATE_EMIT_MSG_PACKET_BEGINNING: - msg_it->state = STATE_DSCOPE_EVENT_HEADER_BEGIN; - break; - case STATE_DSCOPE_EVENT_HEADER_BEGIN: - status = read_event_header_begin_state(msg_it); - break; - case STATE_DSCOPE_EVENT_HEADER_CONTINUE: - status = read_event_header_continue_state(msg_it); - break; - case STATE_AFTER_EVENT_HEADER: - status = after_event_header_state(msg_it); - break; - case STATE_DSCOPE_EVENT_COMMON_CONTEXT_BEGIN: - status = read_event_common_context_begin_state(msg_it); - break; - case STATE_DSCOPE_EVENT_COMMON_CONTEXT_CONTINUE: - status = read_event_common_context_continue_state(msg_it); - break; - case STATE_DSCOPE_EVENT_SPEC_CONTEXT_BEGIN: - status = read_event_spec_context_begin_state(msg_it); - break; - case STATE_DSCOPE_EVENT_SPEC_CONTEXT_CONTINUE: - status = read_event_spec_context_continue_state(msg_it); - break; - case STATE_DSCOPE_EVENT_PAYLOAD_BEGIN: - status = read_event_payload_begin_state(msg_it); - break; - case STATE_DSCOPE_EVENT_PAYLOAD_CONTINUE: - status = read_event_payload_continue_state(msg_it); - break; - case STATE_EMIT_MSG_EVENT: - msg_it->state = STATE_DSCOPE_EVENT_HEADER_BEGIN; - break; - case STATE_EMIT_QUEUED_MSG_EVENT: - msg_it->state = STATE_EMIT_MSG_EVENT; - break; - case STATE_SKIP_PACKET_PADDING: - status = skip_packet_padding_state(msg_it); - break; - case STATE_EMIT_MSG_PACKET_END_MULTI: - msg_it->state = STATE_SKIP_PACKET_PADDING; - break; - case STATE_EMIT_MSG_PACKET_END_SINGLE: - msg_it->state = STATE_EMIT_MSG_STREAM_END; - break; - case STATE_EMIT_QUEUED_MSG_PACKET_END: - msg_it->state = STATE_EMIT_MSG_PACKET_END_SINGLE; - break; - case STATE_CHECK_EMIT_MSG_STREAM_END: - msg_it->state = check_emit_msg_stream_end(msg_it); - break; - case STATE_EMIT_MSG_STREAM_END: - msg_it->state = STATE_DONE; - break; - case STATE_DONE: - break; - default: - BT_COMP_LOGF("Unknown CTF plugin message iterator state: " - "msg-it-addr=%p, state=%d", msg_it, msg_it->state); - bt_common_abort(); - } - - BT_COMP_LOGT("Handled state: msg-it-addr=%p, status=%s, " - "prev-state=%s, cur-state=%s", - msg_it, ctf_msg_iter_status_string(status), - state_string(state), state_string(msg_it->state)); - return status; + return CTF_MSG_ITER_STATUS_OK; +} + +static inline enum state check_emit_msg_stream_end(struct ctf_msg_iter *msg_it) +{ + enum state next_state; + + if (msg_it->emit_stream_end_message) { + next_state = STATE_EMIT_MSG_STREAM_END; + } else { + next_state = STATE_DONE; + } + + return next_state; +} + +static inline enum ctf_msg_iter_status handle_state(struct ctf_msg_iter *msg_it) +{ + enum ctf_msg_iter_status status = CTF_MSG_ITER_STATUS_OK; + const enum state state = msg_it->state; + + BT_COMP_LOGT("Handling state: msg-it-addr=%p, state=%s", msg_it, state_string(state)); + + // TODO: optimalize! + switch (state) { + case STATE_INIT: + msg_it->state = STATE_SWITCH_PACKET; + break; + case STATE_SWITCH_PACKET: + status = switch_packet_state(msg_it); + break; + case STATE_DSCOPE_TRACE_PACKET_HEADER_BEGIN: + status = read_packet_header_begin_state(msg_it); + break; + case STATE_DSCOPE_TRACE_PACKET_HEADER_CONTINUE: + status = read_packet_header_continue_state(msg_it); + break; + case STATE_AFTER_TRACE_PACKET_HEADER: + status = after_packet_header_state(msg_it); + break; + case STATE_DSCOPE_STREAM_PACKET_CONTEXT_BEGIN: + status = read_packet_context_begin_state(msg_it); + break; + case STATE_DSCOPE_STREAM_PACKET_CONTEXT_CONTINUE: + status = read_packet_context_continue_state(msg_it); + break; + case STATE_AFTER_STREAM_PACKET_CONTEXT: + status = after_packet_context_state(msg_it); + break; + case STATE_EMIT_MSG_STREAM_BEGINNING: + msg_it->state = STATE_CHECK_EMIT_MSG_DISCARDED_EVENTS; + break; + case STATE_CHECK_EMIT_MSG_DISCARDED_EVENTS: + status = check_emit_msg_discarded_events(msg_it); + break; + case STATE_EMIT_MSG_DISCARDED_EVENTS: + msg_it->state = STATE_CHECK_EMIT_MSG_DISCARDED_PACKETS; + break; + case STATE_CHECK_EMIT_MSG_DISCARDED_PACKETS: + status = check_emit_msg_discarded_packets(msg_it); + break; + case STATE_EMIT_MSG_DISCARDED_PACKETS: + msg_it->state = STATE_EMIT_MSG_PACKET_BEGINNING; + break; + case STATE_EMIT_MSG_PACKET_BEGINNING: + msg_it->state = STATE_DSCOPE_EVENT_HEADER_BEGIN; + break; + case STATE_DSCOPE_EVENT_HEADER_BEGIN: + status = read_event_header_begin_state(msg_it); + break; + case STATE_DSCOPE_EVENT_HEADER_CONTINUE: + status = read_event_header_continue_state(msg_it); + break; + case STATE_AFTER_EVENT_HEADER: + status = after_event_header_state(msg_it); + break; + case STATE_DSCOPE_EVENT_COMMON_CONTEXT_BEGIN: + status = read_event_common_context_begin_state(msg_it); + break; + case STATE_DSCOPE_EVENT_COMMON_CONTEXT_CONTINUE: + status = read_event_common_context_continue_state(msg_it); + break; + case STATE_DSCOPE_EVENT_SPEC_CONTEXT_BEGIN: + status = read_event_spec_context_begin_state(msg_it); + break; + case STATE_DSCOPE_EVENT_SPEC_CONTEXT_CONTINUE: + status = read_event_spec_context_continue_state(msg_it); + break; + case STATE_DSCOPE_EVENT_PAYLOAD_BEGIN: + status = read_event_payload_begin_state(msg_it); + break; + case STATE_DSCOPE_EVENT_PAYLOAD_CONTINUE: + status = read_event_payload_continue_state(msg_it); + break; + case STATE_EMIT_MSG_EVENT: + msg_it->state = STATE_DSCOPE_EVENT_HEADER_BEGIN; + break; + case STATE_EMIT_QUEUED_MSG_EVENT: + msg_it->state = STATE_EMIT_MSG_EVENT; + break; + case STATE_SKIP_PACKET_PADDING: + status = skip_packet_padding_state(msg_it); + break; + case STATE_EMIT_MSG_PACKET_END_MULTI: + msg_it->state = STATE_SKIP_PACKET_PADDING; + break; + case STATE_EMIT_MSG_PACKET_END_SINGLE: + msg_it->state = STATE_EMIT_MSG_STREAM_END; + break; + case STATE_EMIT_QUEUED_MSG_PACKET_END: + msg_it->state = STATE_EMIT_MSG_PACKET_END_SINGLE; + break; + case STATE_CHECK_EMIT_MSG_STREAM_END: + msg_it->state = check_emit_msg_stream_end(msg_it); + break; + case STATE_EMIT_MSG_STREAM_END: + msg_it->state = STATE_DONE; + break; + case STATE_DONE: + break; + default: + BT_COMP_LOGF("Unknown CTF plugin message iterator state: " + "msg-it-addr=%p, state=%d", + msg_it, msg_it->state); + bt_common_abort(); + } + + BT_COMP_LOGT("Handled state: msg-it-addr=%p, status=%s, " + "prev-state=%s, cur-state=%s", + msg_it, ctf_msg_iter_status_string(status), state_string(state), + state_string(msg_it->state)); + return status; } BT_HIDDEN void ctf_msg_iter_reset_for_next_stream_file(struct ctf_msg_iter *msg_it) { - BT_ASSERT(msg_it); - BT_COMP_LOGD("Resetting message iterator: addr=%p", msg_it); - stack_clear(msg_it->stack); - msg_it->meta.sc = NULL; - msg_it->meta.ec = NULL; - BT_PACKET_PUT_REF_AND_RESET(msg_it->packet); - BT_STREAM_PUT_REF_AND_RESET(msg_it->stream); - BT_MESSAGE_PUT_REF_AND_RESET(msg_it->event_msg); - release_all_dscopes(msg_it); - msg_it->cur_dscope_field = NULL; - - msg_it->buf.addr = NULL; - msg_it->buf.sz = 0; - msg_it->buf.at = 0; - msg_it->buf.last_eh_at = SIZE_MAX; - msg_it->buf.packet_offset = 0; - msg_it->state = STATE_INIT; - msg_it->cur_exp_packet_content_size = -1; - msg_it->cur_exp_packet_total_size = -1; - msg_it->cur_packet_offset = -1; - msg_it->cur_event_class_id = -1; - msg_it->snapshots.beginning_clock = UINT64_C(-1); - msg_it->snapshots.end_clock = UINT64_C(-1); + BT_ASSERT(msg_it); + BT_COMP_LOGD("Resetting message iterator: addr=%p", msg_it); + stack_clear(msg_it->stack); + msg_it->meta.sc = NULL; + msg_it->meta.ec = NULL; + BT_PACKET_PUT_REF_AND_RESET(msg_it->packet); + BT_STREAM_PUT_REF_AND_RESET(msg_it->stream); + BT_MESSAGE_PUT_REF_AND_RESET(msg_it->event_msg); + release_all_dscopes(msg_it); + msg_it->cur_dscope_field = NULL; + + msg_it->buf.addr = NULL; + msg_it->buf.sz = 0; + msg_it->buf.at = 0; + msg_it->buf.last_eh_at = SIZE_MAX; + msg_it->buf.packet_offset = 0; + msg_it->state = STATE_INIT; + msg_it->cur_exp_packet_content_size = -1; + msg_it->cur_exp_packet_total_size = -1; + msg_it->cur_packet_offset = -1; + msg_it->cur_event_class_id = -1; + msg_it->snapshots.beginning_clock = UINT64_C(-1); + msg_it->snapshots.end_clock = UINT64_C(-1); } /** @@ -1823,1369 +1706,1295 @@ void ctf_msg_iter_reset_for_next_stream_file(struct ctf_msg_iter *msg_it) BT_HIDDEN void ctf_msg_iter_reset(struct ctf_msg_iter *msg_it) { - ctf_msg_iter_reset_for_next_stream_file(msg_it); - msg_it->cur_stream_class_id = -1; - msg_it->cur_data_stream_id = -1; - msg_it->snapshots.discarded_events = UINT64_C(-1); - msg_it->snapshots.packets = UINT64_C(-1); - msg_it->prev_packet_snapshots.discarded_events = UINT64_C(-1); - msg_it->prev_packet_snapshots.packets = UINT64_C(-1); - msg_it->prev_packet_snapshots.beginning_clock = UINT64_C(-1); - msg_it->prev_packet_snapshots.end_clock = UINT64_C(-1); - msg_it->emit_stream_beginning_message = true; - msg_it->emit_stream_end_message = false; -} - -static -bt_field *borrow_next_field(struct ctf_msg_iter *msg_it) -{ - bt_field *next_field = NULL; - bt_field *base_field; - const bt_field_class *base_fc; - bt_field_class_type base_fc_type; - size_t index; - - BT_ASSERT_DBG(!stack_empty(msg_it->stack)); - index = stack_top(msg_it->stack)->index; - base_field = stack_top(msg_it->stack)->base; - BT_ASSERT_DBG(base_field); - base_fc = bt_field_borrow_class_const(base_field); - BT_ASSERT_DBG(base_fc); - base_fc_type = bt_field_class_get_type(base_fc); - - if (base_fc_type == BT_FIELD_CLASS_TYPE_STRUCTURE) { - BT_ASSERT_DBG(index < - bt_field_class_structure_get_member_count( - bt_field_borrow_class_const( - base_field))); - next_field = - bt_field_structure_borrow_member_field_by_index( - base_field, index); - } else if (bt_field_class_type_is(base_fc_type, - BT_FIELD_CLASS_TYPE_ARRAY)) { - BT_ASSERT_DBG(index < bt_field_array_get_length(base_field)); - next_field = bt_field_array_borrow_element_field_by_index( - base_field, index); - } else if (bt_field_class_type_is(base_fc_type, - BT_FIELD_CLASS_TYPE_VARIANT)) { - BT_ASSERT_DBG(index == 0); - next_field = bt_field_variant_borrow_selected_option_field( - base_field); - } else { - bt_common_abort(); - } - - BT_ASSERT_DBG(next_field); - return next_field; -} - -static -void update_default_clock(struct ctf_msg_iter *msg_it, uint64_t new_val, - uint64_t new_val_size) -{ - uint64_t new_val_mask; - uint64_t cur_value_masked; - - BT_ASSERT_DBG(new_val_size > 0); - - /* - * Special case for a 64-bit new value, which is the limit - * of a clock value as of this version: overwrite the - * current value directly. - */ - if (new_val_size == 64) { - msg_it->default_clock_snapshot = new_val; - goto end; - } - - new_val_mask = (1ULL << new_val_size) - 1; - cur_value_masked = msg_it->default_clock_snapshot & new_val_mask; - - if (new_val < cur_value_masked) { - /* - * It looks like a wrap happened on the number of bits - * of the requested new value. Assume that the clock - * value wrapped only one time. - */ - msg_it->default_clock_snapshot += new_val_mask + 1; - } - - /* Clear the low bits of the current clock value. */ - msg_it->default_clock_snapshot &= ~new_val_mask; - - /* Set the low bits of the current clock value. */ - msg_it->default_clock_snapshot |= new_val; + ctf_msg_iter_reset_for_next_stream_file(msg_it); + msg_it->cur_stream_class_id = -1; + msg_it->cur_data_stream_id = -1; + msg_it->snapshots.discarded_events = UINT64_C(-1); + msg_it->snapshots.packets = UINT64_C(-1); + msg_it->prev_packet_snapshots.discarded_events = UINT64_C(-1); + msg_it->prev_packet_snapshots.packets = UINT64_C(-1); + msg_it->prev_packet_snapshots.beginning_clock = UINT64_C(-1); + msg_it->prev_packet_snapshots.end_clock = UINT64_C(-1); + msg_it->emit_stream_beginning_message = true; + msg_it->emit_stream_end_message = false; +} + +static bt_field *borrow_next_field(struct ctf_msg_iter *msg_it) +{ + bt_field *next_field = NULL; + bt_field *base_field; + const bt_field_class *base_fc; + bt_field_class_type base_fc_type; + size_t index; + + BT_ASSERT_DBG(!stack_empty(msg_it->stack)); + index = stack_top(msg_it->stack)->index; + base_field = stack_top(msg_it->stack)->base; + BT_ASSERT_DBG(base_field); + base_fc = bt_field_borrow_class_const(base_field); + BT_ASSERT_DBG(base_fc); + base_fc_type = bt_field_class_get_type(base_fc); + + if (base_fc_type == BT_FIELD_CLASS_TYPE_STRUCTURE) { + BT_ASSERT_DBG(index < bt_field_class_structure_get_member_count( + bt_field_borrow_class_const(base_field))); + next_field = bt_field_structure_borrow_member_field_by_index(base_field, index); + } else if (bt_field_class_type_is(base_fc_type, BT_FIELD_CLASS_TYPE_ARRAY)) { + BT_ASSERT_DBG(index < bt_field_array_get_length(base_field)); + next_field = bt_field_array_borrow_element_field_by_index(base_field, index); + } else if (bt_field_class_type_is(base_fc_type, BT_FIELD_CLASS_TYPE_VARIANT)) { + BT_ASSERT_DBG(index == 0); + next_field = bt_field_variant_borrow_selected_option_field(base_field); + } else { + bt_common_abort(); + } + + BT_ASSERT_DBG(next_field); + return next_field; +} + +static void update_default_clock(struct ctf_msg_iter *msg_it, uint64_t new_val, + uint64_t new_val_size) +{ + uint64_t new_val_mask; + uint64_t cur_value_masked; + + BT_ASSERT_DBG(new_val_size > 0); + + /* + * Special case for a 64-bit new value, which is the limit + * of a clock value as of this version: overwrite the + * current value directly. + */ + if (new_val_size == 64) { + msg_it->default_clock_snapshot = new_val; + goto end; + } + + new_val_mask = (1ULL << new_val_size) - 1; + cur_value_masked = msg_it->default_clock_snapshot & new_val_mask; + + if (new_val < cur_value_masked) { + /* + * It looks like a wrap happened on the number of bits + * of the requested new value. Assume that the clock + * value wrapped only one time. + */ + msg_it->default_clock_snapshot += new_val_mask + 1; + } + + /* Clear the low bits of the current clock value. */ + msg_it->default_clock_snapshot &= ~new_val_mask; + + /* Set the low bits of the current clock value. */ + msg_it->default_clock_snapshot |= new_val; end: - BT_COMP_LOGT("Updated default clock's value from integer field's value: " - "value=%" PRIu64, msg_it->default_clock_snapshot); -} - -static -enum bt_bfcr_status bfcr_unsigned_int_cb(uint64_t value, - struct ctf_field_class *fc, void *data) -{ - ctf_msg_iter *msg_it = (ctf_msg_iter *) data; - bt_self_component *self_comp = msg_it->self_comp; - enum bt_bfcr_status status = BT_BFCR_STATUS_OK; - - bt_field *field = NULL; - ctf_field_class_int *int_fc = ctf_field_class_as_int(fc); - - BT_COMP_LOGT("Unsigned integer function called from BFCR: " - "msg-it-addr=%p, bfcr-addr=%p, fc-addr=%p, " - "fc-type=%d, fc-in-ir=%d, value=%" PRIu64, - msg_it, msg_it->bfcr, fc, fc->type, fc->in_ir, value); - - if (G_LIKELY(int_fc->meaning == CTF_FIELD_CLASS_MEANING_NONE)) { - goto update_def_clock; - } - - switch (int_fc->meaning) { - case CTF_FIELD_CLASS_MEANING_EVENT_CLASS_ID: - msg_it->cur_event_class_id = value; - break; - case CTF_FIELD_CLASS_MEANING_DATA_STREAM_ID: - msg_it->cur_data_stream_id = value; - break; - case CTF_FIELD_CLASS_MEANING_PACKET_BEGINNING_TIME: - msg_it->snapshots.beginning_clock = value; - break; - case CTF_FIELD_CLASS_MEANING_PACKET_END_TIME: - msg_it->snapshots.end_clock = value; - break; - case CTF_FIELD_CLASS_MEANING_STREAM_CLASS_ID: - msg_it->cur_stream_class_id = value; - break; - case CTF_FIELD_CLASS_MEANING_MAGIC: - if (value != 0xc1fc1fc1) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Invalid CTF magic number: msg-it-addr=%p, " - "magic=%" PRIx64, msg_it, value); - status = BT_BFCR_STATUS_ERROR; - goto end; - } - - break; - case CTF_FIELD_CLASS_MEANING_PACKET_COUNTER_SNAPSHOT: - msg_it->snapshots.packets = value; - break; - case CTF_FIELD_CLASS_MEANING_DISC_EV_REC_COUNTER_SNAPSHOT: - msg_it->snapshots.discarded_events = value; - break; - case CTF_FIELD_CLASS_MEANING_EXP_PACKET_TOTAL_SIZE: - msg_it->cur_exp_packet_total_size = value; - break; - case CTF_FIELD_CLASS_MEANING_EXP_PACKET_CONTENT_SIZE: - msg_it->cur_exp_packet_content_size = value; - break; - default: - bt_common_abort(); - } + BT_COMP_LOGT("Updated default clock's value from integer field's value: " + "value=%" PRIu64, + msg_it->default_clock_snapshot); +} + +static enum bt_bfcr_status bfcr_unsigned_int_cb(uint64_t value, struct ctf_field_class *fc, + void *data) +{ + ctf_msg_iter *msg_it = (ctf_msg_iter *) data; + bt_self_component *self_comp = msg_it->self_comp; + enum bt_bfcr_status status = BT_BFCR_STATUS_OK; + + bt_field *field = NULL; + ctf_field_class_int *int_fc = ctf_field_class_as_int(fc); + + BT_COMP_LOGT("Unsigned integer function called from BFCR: " + "msg-it-addr=%p, bfcr-addr=%p, fc-addr=%p, " + "fc-type=%d, fc-in-ir=%d, value=%" PRIu64, + msg_it, msg_it->bfcr, fc, fc->type, fc->in_ir, value); + + if (G_LIKELY(int_fc->meaning == CTF_FIELD_CLASS_MEANING_NONE)) { + goto update_def_clock; + } + + switch (int_fc->meaning) { + case CTF_FIELD_CLASS_MEANING_EVENT_CLASS_ID: + msg_it->cur_event_class_id = value; + break; + case CTF_FIELD_CLASS_MEANING_DATA_STREAM_ID: + msg_it->cur_data_stream_id = value; + break; + case CTF_FIELD_CLASS_MEANING_PACKET_BEGINNING_TIME: + msg_it->snapshots.beginning_clock = value; + break; + case CTF_FIELD_CLASS_MEANING_PACKET_END_TIME: + msg_it->snapshots.end_clock = value; + break; + case CTF_FIELD_CLASS_MEANING_STREAM_CLASS_ID: + msg_it->cur_stream_class_id = value; + break; + case CTF_FIELD_CLASS_MEANING_MAGIC: + if (value != 0xc1fc1fc1) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, + "Invalid CTF magic number: msg-it-addr=%p, " + "magic=%" PRIx64, + msg_it, value); + status = BT_BFCR_STATUS_ERROR; + goto end; + } + + break; + case CTF_FIELD_CLASS_MEANING_PACKET_COUNTER_SNAPSHOT: + msg_it->snapshots.packets = value; + break; + case CTF_FIELD_CLASS_MEANING_DISC_EV_REC_COUNTER_SNAPSHOT: + msg_it->snapshots.discarded_events = value; + break; + case CTF_FIELD_CLASS_MEANING_EXP_PACKET_TOTAL_SIZE: + msg_it->cur_exp_packet_total_size = value; + break; + case CTF_FIELD_CLASS_MEANING_EXP_PACKET_CONTENT_SIZE: + msg_it->cur_exp_packet_content_size = value; + break; + default: + bt_common_abort(); + } update_def_clock: - if (G_UNLIKELY(int_fc->mapped_clock_class)) { - update_default_clock(msg_it, value, int_fc->base.size); - } - - if (G_UNLIKELY(int_fc->storing_index >= 0)) { - g_array_index(msg_it->stored_values, uint64_t, - (uint64_t) int_fc->storing_index) = value; - } - - if (G_UNLIKELY(!fc->in_ir || msg_it->dry_run)) { - goto end; - } - - field = borrow_next_field(msg_it); - BT_ASSERT_DBG(field); - BT_ASSERT_DBG(bt_field_borrow_class_const(field) == fc->ir_fc); - BT_ASSERT_DBG(bt_field_class_type_is(bt_field_get_class_type(field), - BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER)); - bt_field_integer_unsigned_set_value(field, value); - stack_top(msg_it->stack)->index++; + if (G_UNLIKELY(int_fc->mapped_clock_class)) { + update_default_clock(msg_it, value, int_fc->base.size); + } + + if (G_UNLIKELY(int_fc->storing_index >= 0)) { + g_array_index(msg_it->stored_values, uint64_t, (uint64_t) int_fc->storing_index) = value; + } + + if (G_UNLIKELY(!fc->in_ir || msg_it->dry_run)) { + goto end; + } + + field = borrow_next_field(msg_it); + BT_ASSERT_DBG(field); + BT_ASSERT_DBG(bt_field_borrow_class_const(field) == fc->ir_fc); + BT_ASSERT_DBG(bt_field_class_type_is(bt_field_get_class_type(field), + BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER)); + bt_field_integer_unsigned_set_value(field, value); + stack_top(msg_it->stack)->index++; end: - return status; -} - -static -enum bt_bfcr_status bfcr_unsigned_int_char_cb(uint64_t value, - struct ctf_field_class *fc, void *data) -{ - int ret; - ctf_msg_iter *msg_it = (ctf_msg_iter *) data; - bt_self_component *self_comp = msg_it->self_comp; - enum bt_bfcr_status status = BT_BFCR_STATUS_OK; - bt_field *string_field = NULL; - ctf_field_class_int *int_fc = ctf_field_class_as_int(fc); - char str[2] = {'\0', '\0'}; - - BT_COMP_LOGT("Unsigned integer character function called from BFCR: " - "msg-it-addr=%p, bfcr-addr=%p, fc-addr=%p, " - "fc-type=%d, fc-in-ir=%d, value=%" PRIu64, - msg_it, msg_it->bfcr, fc, fc->type, fc->in_ir, value); - BT_ASSERT_DBG(int_fc->meaning == CTF_FIELD_CLASS_MEANING_NONE); - BT_ASSERT_DBG(!int_fc->mapped_clock_class); - BT_ASSERT_DBG(int_fc->storing_index < 0); - - if (G_UNLIKELY(!fc->in_ir || msg_it->dry_run)) { - goto end; - } - - if (msg_it->done_filling_string) { - goto end; - } - - if (value == 0) { - msg_it->done_filling_string = true; - goto end; - } - - string_field = stack_top(msg_it->stack)->base; - BT_ASSERT_DBG(bt_field_get_class_type(string_field) == - BT_FIELD_CLASS_TYPE_STRING); - - /* Append character */ - str[0] = (char) value; - ret = bt_field_string_append_with_length(string_field, str, 1); - if (ret) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Cannot append character to string field's value: " - "msg-it-addr=%p, field-addr=%p, ret=%d", - msg_it, string_field, ret); - status = BT_BFCR_STATUS_ERROR; - goto end; - } + return status; +} + +static enum bt_bfcr_status bfcr_unsigned_int_char_cb(uint64_t value, struct ctf_field_class *fc, + void *data) +{ + int ret; + ctf_msg_iter *msg_it = (ctf_msg_iter *) data; + bt_self_component *self_comp = msg_it->self_comp; + enum bt_bfcr_status status = BT_BFCR_STATUS_OK; + bt_field *string_field = NULL; + ctf_field_class_int *int_fc = ctf_field_class_as_int(fc); + char str[2] = {'\0', '\0'}; + + BT_COMP_LOGT("Unsigned integer character function called from BFCR: " + "msg-it-addr=%p, bfcr-addr=%p, fc-addr=%p, " + "fc-type=%d, fc-in-ir=%d, value=%" PRIu64, + msg_it, msg_it->bfcr, fc, fc->type, fc->in_ir, value); + BT_ASSERT_DBG(int_fc->meaning == CTF_FIELD_CLASS_MEANING_NONE); + BT_ASSERT_DBG(!int_fc->mapped_clock_class); + BT_ASSERT_DBG(int_fc->storing_index < 0); + + if (G_UNLIKELY(!fc->in_ir || msg_it->dry_run)) { + goto end; + } + + if (msg_it->done_filling_string) { + goto end; + } + + if (value == 0) { + msg_it->done_filling_string = true; + goto end; + } + + string_field = stack_top(msg_it->stack)->base; + BT_ASSERT_DBG(bt_field_get_class_type(string_field) == BT_FIELD_CLASS_TYPE_STRING); + + /* Append character */ + str[0] = (char) value; + ret = bt_field_string_append_with_length(string_field, str, 1); + if (ret) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, + "Cannot append character to string field's value: " + "msg-it-addr=%p, field-addr=%p, ret=%d", + msg_it, string_field, ret); + status = BT_BFCR_STATUS_ERROR; + goto end; + } end: - return status; + return status; } -static -enum bt_bfcr_status bfcr_signed_int_cb(int64_t value, - struct ctf_field_class *fc, void *data) +static enum bt_bfcr_status bfcr_signed_int_cb(int64_t value, struct ctf_field_class *fc, void *data) { - enum bt_bfcr_status status = BT_BFCR_STATUS_OK; - bt_field *field = NULL; - ctf_msg_iter *msg_it = (ctf_msg_iter *) data; - ctf_field_class_int *int_fc = ctf_field_class_as_int(fc); + enum bt_bfcr_status status = BT_BFCR_STATUS_OK; + bt_field *field = NULL; + ctf_msg_iter *msg_it = (ctf_msg_iter *) data; + ctf_field_class_int *int_fc = ctf_field_class_as_int(fc); - BT_COMP_LOGT("Signed integer function called from BFCR: " - "msg-it-addr=%p, bfcr-addr=%p, fc-addr=%p, " - "fc-type=%d, fc-in-ir=%d, value=%" PRId64, - msg_it, msg_it->bfcr, fc, fc->type, fc->in_ir, value); - BT_ASSERT_DBG(int_fc->meaning == CTF_FIELD_CLASS_MEANING_NONE); + BT_COMP_LOGT("Signed integer function called from BFCR: " + "msg-it-addr=%p, bfcr-addr=%p, fc-addr=%p, " + "fc-type=%d, fc-in-ir=%d, value=%" PRId64, + msg_it, msg_it->bfcr, fc, fc->type, fc->in_ir, value); + BT_ASSERT_DBG(int_fc->meaning == CTF_FIELD_CLASS_MEANING_NONE); - if (G_UNLIKELY(int_fc->storing_index >= 0)) { - g_array_index(msg_it->stored_values, uint64_t, - (uint64_t) int_fc->storing_index) = (uint64_t) value; - } + if (G_UNLIKELY(int_fc->storing_index >= 0)) { + g_array_index(msg_it->stored_values, uint64_t, (uint64_t) int_fc->storing_index) = + (uint64_t) value; + } - if (G_UNLIKELY(!fc->in_ir || msg_it->dry_run)) { - goto end; - } + if (G_UNLIKELY(!fc->in_ir || msg_it->dry_run)) { + goto end; + } - field = borrow_next_field(msg_it); - BT_ASSERT_DBG(field); - BT_ASSERT_DBG(bt_field_borrow_class_const(field) == fc->ir_fc); - BT_ASSERT_DBG(bt_field_class_type_is(bt_field_get_class_type(field), - BT_FIELD_CLASS_TYPE_SIGNED_INTEGER)); - bt_field_integer_signed_set_value(field, value); - stack_top(msg_it->stack)->index++; + field = borrow_next_field(msg_it); + BT_ASSERT_DBG(field); + BT_ASSERT_DBG(bt_field_borrow_class_const(field) == fc->ir_fc); + BT_ASSERT_DBG( + bt_field_class_type_is(bt_field_get_class_type(field), BT_FIELD_CLASS_TYPE_SIGNED_INTEGER)); + bt_field_integer_signed_set_value(field, value); + stack_top(msg_it->stack)->index++; end: - return status; + return status; } -static -enum bt_bfcr_status bfcr_floating_point_cb(double value, - struct ctf_field_class *fc, void *data) +static enum bt_bfcr_status bfcr_floating_point_cb(double value, struct ctf_field_class *fc, + void *data) { - enum bt_bfcr_status status = BT_BFCR_STATUS_OK; - bt_field *field = NULL; - ctf_msg_iter *msg_it = (ctf_msg_iter *) data; - bt_field_class_type type; + enum bt_bfcr_status status = BT_BFCR_STATUS_OK; + bt_field *field = NULL; + ctf_msg_iter *msg_it = (ctf_msg_iter *) data; + bt_field_class_type type; - BT_COMP_LOGT("Floating point number function called from BFCR: " - "msg-it-addr=%p, bfcr-addr=%p, fc-addr=%p, " - "fc-type=%d, fc-in-ir=%d, value=%f", - msg_it, msg_it->bfcr, fc, fc->type, fc->in_ir, value); + BT_COMP_LOGT("Floating point number function called from BFCR: " + "msg-it-addr=%p, bfcr-addr=%p, fc-addr=%p, " + "fc-type=%d, fc-in-ir=%d, value=%f", + msg_it, msg_it->bfcr, fc, fc->type, fc->in_ir, value); - if (G_UNLIKELY(!fc->in_ir || msg_it->dry_run)) { - goto end; - } + if (G_UNLIKELY(!fc->in_ir || msg_it->dry_run)) { + goto end; + } - field = borrow_next_field(msg_it); - type = bt_field_get_class_type(field); - BT_ASSERT_DBG(field); - BT_ASSERT_DBG(bt_field_borrow_class_const(field) == fc->ir_fc); - BT_ASSERT_DBG(bt_field_class_type_is(type, BT_FIELD_CLASS_TYPE_REAL)); + field = borrow_next_field(msg_it); + type = bt_field_get_class_type(field); + BT_ASSERT_DBG(field); + BT_ASSERT_DBG(bt_field_borrow_class_const(field) == fc->ir_fc); + BT_ASSERT_DBG(bt_field_class_type_is(type, BT_FIELD_CLASS_TYPE_REAL)); - if (type == BT_FIELD_CLASS_TYPE_SINGLE_PRECISION_REAL) { - bt_field_real_single_precision_set_value(field, (float) value); - } else { - bt_field_real_double_precision_set_value(field, value); - } - stack_top(msg_it->stack)->index++; + if (type == BT_FIELD_CLASS_TYPE_SINGLE_PRECISION_REAL) { + bt_field_real_single_precision_set_value(field, (float) value); + } else { + bt_field_real_double_precision_set_value(field, value); + } + stack_top(msg_it->stack)->index++; end: - return status; + return status; } -static -enum bt_bfcr_status bfcr_string_begin_cb( - struct ctf_field_class *fc, void *data) +static enum bt_bfcr_status bfcr_string_begin_cb(struct ctf_field_class *fc, void *data) { - bt_field *field = NULL; - ctf_msg_iter *msg_it = (ctf_msg_iter *) data; + bt_field *field = NULL; + ctf_msg_iter *msg_it = (ctf_msg_iter *) data; - BT_COMP_LOGT("String (beginning) function called from BFCR: " - "msg-it-addr=%p, bfcr-addr=%p, fc-addr=%p, " - "fc-type=%d, fc-in-ir=%d", - msg_it, msg_it->bfcr, fc, fc->type, fc->in_ir); + BT_COMP_LOGT("String (beginning) function called from BFCR: " + "msg-it-addr=%p, bfcr-addr=%p, fc-addr=%p, " + "fc-type=%d, fc-in-ir=%d", + msg_it, msg_it->bfcr, fc, fc->type, fc->in_ir); - if (G_UNLIKELY(!fc->in_ir || msg_it->dry_run)) { - goto end; - } + if (G_UNLIKELY(!fc->in_ir || msg_it->dry_run)) { + goto end; + } - field = borrow_next_field(msg_it); - BT_ASSERT_DBG(field); - BT_ASSERT_DBG(bt_field_borrow_class_const(field) == fc->ir_fc); - BT_ASSERT_DBG(bt_field_get_class_type(field) == - BT_FIELD_CLASS_TYPE_STRING); - bt_field_string_clear(field); + field = borrow_next_field(msg_it); + BT_ASSERT_DBG(field); + BT_ASSERT_DBG(bt_field_borrow_class_const(field) == fc->ir_fc); + BT_ASSERT_DBG(bt_field_get_class_type(field) == BT_FIELD_CLASS_TYPE_STRING); + bt_field_string_clear(field); - /* - * Push on stack. Not a compound class per se, but we know that - * only bfcr_string_cb() may be called between this call and a - * subsequent call to bfcr_string_end_cb(). - */ - stack_push(msg_it->stack, field); + /* + * Push on stack. Not a compound class per se, but we know that + * only bfcr_string_cb() may be called between this call and a + * subsequent call to bfcr_string_end_cb(). + */ + stack_push(msg_it->stack, field); end: - return BT_BFCR_STATUS_OK; -} - -static -enum bt_bfcr_status bfcr_string_cb(const char *value, - size_t len, struct ctf_field_class *fc, void *data) -{ - enum bt_bfcr_status status = BT_BFCR_STATUS_OK; - bt_field *field = NULL; - ctf_msg_iter *msg_it = (ctf_msg_iter *) data; - bt_self_component *self_comp = msg_it->self_comp; - int ret; - - BT_COMP_LOGT("String (substring) function called from BFCR: " - "msg-it-addr=%p, bfcr-addr=%p, fc-addr=%p, " - "fc-type=%d, fc-in-ir=%d, string-length=%zu", - msg_it, msg_it->bfcr, fc, fc->type, fc->in_ir, - len); - - if (G_UNLIKELY(!fc->in_ir || msg_it->dry_run)) { - goto end; - } - - field = stack_top(msg_it->stack)->base; - BT_ASSERT_DBG(field); - - /* Append current substring */ - ret = bt_field_string_append_with_length(field, value, len); - if (ret) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Cannot append substring to string field's value: " - "msg-it-addr=%p, field-addr=%p, string-length=%zu, " - "ret=%d", msg_it, field, len, ret); - status = BT_BFCR_STATUS_ERROR; - goto end; - } + return BT_BFCR_STATUS_OK; +} + +static enum bt_bfcr_status bfcr_string_cb(const char *value, size_t len, struct ctf_field_class *fc, + void *data) +{ + enum bt_bfcr_status status = BT_BFCR_STATUS_OK; + bt_field *field = NULL; + ctf_msg_iter *msg_it = (ctf_msg_iter *) data; + bt_self_component *self_comp = msg_it->self_comp; + int ret; + + BT_COMP_LOGT("String (substring) function called from BFCR: " + "msg-it-addr=%p, bfcr-addr=%p, fc-addr=%p, " + "fc-type=%d, fc-in-ir=%d, string-length=%zu", + msg_it, msg_it->bfcr, fc, fc->type, fc->in_ir, len); + + if (G_UNLIKELY(!fc->in_ir || msg_it->dry_run)) { + goto end; + } + + field = stack_top(msg_it->stack)->base; + BT_ASSERT_DBG(field); + + /* Append current substring */ + ret = bt_field_string_append_with_length(field, value, len); + if (ret) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, + "Cannot append substring to string field's value: " + "msg-it-addr=%p, field-addr=%p, string-length=%zu, " + "ret=%d", + msg_it, field, len, ret); + status = BT_BFCR_STATUS_ERROR; + goto end; + } end: - return status; + return status; } -static -enum bt_bfcr_status bfcr_string_end_cb( - struct ctf_field_class *fc, void *data) +static enum bt_bfcr_status bfcr_string_end_cb(struct ctf_field_class *fc, void *data) { - ctf_msg_iter *msg_it = (ctf_msg_iter *) data; + ctf_msg_iter *msg_it = (ctf_msg_iter *) data; - BT_COMP_LOGT("String (end) function called from BFCR: " - "msg-it-addr=%p, bfcr-addr=%p, fc-addr=%p, " - "fc-type=%d, fc-in-ir=%d", - msg_it, msg_it->bfcr, fc, fc->type, fc->in_ir); + BT_COMP_LOGT("String (end) function called from BFCR: " + "msg-it-addr=%p, bfcr-addr=%p, fc-addr=%p, " + "fc-type=%d, fc-in-ir=%d", + msg_it, msg_it->bfcr, fc, fc->type, fc->in_ir); - if (G_UNLIKELY(!fc->in_ir || msg_it->dry_run)) { - goto end; - } + if (G_UNLIKELY(!fc->in_ir || msg_it->dry_run)) { + goto end; + } - /* Pop string field */ - stack_pop(msg_it->stack); + /* Pop string field */ + stack_pop(msg_it->stack); - /* Go to next field */ - stack_top(msg_it->stack)->index++; + /* Go to next field */ + stack_top(msg_it->stack)->index++; end: - return BT_BFCR_STATUS_OK; -} - -static -enum bt_bfcr_status bfcr_compound_begin_cb( - struct ctf_field_class *fc, void *data) -{ - ctf_msg_iter *msg_it = (ctf_msg_iter *) data; - bt_field *field; - - BT_COMP_LOGT("Compound (beginning) function called from BFCR: " - "msg-it-addr=%p, bfcr-addr=%p, fc-addr=%p, " - "fc-type=%d, fc-in-ir=%d", - msg_it, msg_it->bfcr, fc, fc->type, fc->in_ir); - - if (G_UNLIKELY(!fc->in_ir || msg_it->dry_run)) { - goto end; - } - - /* Borrow field */ - if (stack_empty(msg_it->stack)) { - /* Root: already set by read_dscope_begin_state() */ - field = msg_it->cur_dscope_field; - } else { - field = borrow_next_field(msg_it); - BT_ASSERT_DBG(field); - } - - /* Push field */ - BT_ASSERT_DBG(field); - BT_ASSERT_DBG(bt_field_borrow_class_const(field) == fc->ir_fc); - stack_push(msg_it->stack, field); - - /* - * Change BFCR "unsigned int" callback if it's a text - * array/sequence. - */ - if (fc->type == CTF_FIELD_CLASS_TYPE_ARRAY || - fc->type == CTF_FIELD_CLASS_TYPE_SEQUENCE) { - ctf_field_class_array_base *array_fc = ctf_field_class_as_array_base(fc); - - if (array_fc->is_text) { - BT_ASSERT_DBG(bt_field_get_class_type(field) == - BT_FIELD_CLASS_TYPE_STRING); - msg_it->done_filling_string = false; - bt_field_string_clear(field); - bt_bfcr_set_unsigned_int_cb(msg_it->bfcr, - bfcr_unsigned_int_char_cb); - } - } + return BT_BFCR_STATUS_OK; +} + +static enum bt_bfcr_status bfcr_compound_begin_cb(struct ctf_field_class *fc, void *data) +{ + ctf_msg_iter *msg_it = (ctf_msg_iter *) data; + bt_field *field; + + BT_COMP_LOGT("Compound (beginning) function called from BFCR: " + "msg-it-addr=%p, bfcr-addr=%p, fc-addr=%p, " + "fc-type=%d, fc-in-ir=%d", + msg_it, msg_it->bfcr, fc, fc->type, fc->in_ir); + + if (G_UNLIKELY(!fc->in_ir || msg_it->dry_run)) { + goto end; + } + + /* Borrow field */ + if (stack_empty(msg_it->stack)) { + /* Root: already set by read_dscope_begin_state() */ + field = msg_it->cur_dscope_field; + } else { + field = borrow_next_field(msg_it); + BT_ASSERT_DBG(field); + } + + /* Push field */ + BT_ASSERT_DBG(field); + BT_ASSERT_DBG(bt_field_borrow_class_const(field) == fc->ir_fc); + stack_push(msg_it->stack, field); + + /* + * Change BFCR "unsigned int" callback if it's a text + * array/sequence. + */ + if (fc->type == CTF_FIELD_CLASS_TYPE_ARRAY || fc->type == CTF_FIELD_CLASS_TYPE_SEQUENCE) { + ctf_field_class_array_base *array_fc = ctf_field_class_as_array_base(fc); + + if (array_fc->is_text) { + BT_ASSERT_DBG(bt_field_get_class_type(field) == BT_FIELD_CLASS_TYPE_STRING); + msg_it->done_filling_string = false; + bt_field_string_clear(field); + bt_bfcr_set_unsigned_int_cb(msg_it->bfcr, bfcr_unsigned_int_char_cb); + } + } end: - return BT_BFCR_STATUS_OK; + return BT_BFCR_STATUS_OK; } -static -enum bt_bfcr_status bfcr_compound_end_cb( - struct ctf_field_class *fc, void *data) +static enum bt_bfcr_status bfcr_compound_end_cb(struct ctf_field_class *fc, void *data) { - ctf_msg_iter *msg_it = (ctf_msg_iter *) data; + ctf_msg_iter *msg_it = (ctf_msg_iter *) data; - BT_COMP_LOGT("Compound (end) function called from BFCR: " - "msg-it-addr=%p, bfcr-addr=%p, fc-addr=%p, " - "fc-type=%d, fc-in-ir=%d", - msg_it, msg_it->bfcr, fc, fc->type, fc->in_ir); + BT_COMP_LOGT("Compound (end) function called from BFCR: " + "msg-it-addr=%p, bfcr-addr=%p, fc-addr=%p, " + "fc-type=%d, fc-in-ir=%d", + msg_it, msg_it->bfcr, fc, fc->type, fc->in_ir); - if (G_UNLIKELY(!fc->in_ir || msg_it->dry_run)) { - goto end; - } + if (G_UNLIKELY(!fc->in_ir || msg_it->dry_run)) { + goto end; + } - BT_ASSERT_DBG(!stack_empty(msg_it->stack)); - BT_ASSERT_DBG(bt_field_borrow_class_const(stack_top(msg_it->stack)->base) == - fc->ir_fc); + BT_ASSERT_DBG(!stack_empty(msg_it->stack)); + BT_ASSERT_DBG(bt_field_borrow_class_const(stack_top(msg_it->stack)->base) == fc->ir_fc); - /* - * Reset BFCR "unsigned int" callback if it's a text - * array/sequence. - */ - if (fc->type == CTF_FIELD_CLASS_TYPE_ARRAY || - fc->type == CTF_FIELD_CLASS_TYPE_SEQUENCE) { - ctf_field_class_array_base *array_fc = ctf_field_class_as_array_base(fc); + /* + * Reset BFCR "unsigned int" callback if it's a text + * array/sequence. + */ + if (fc->type == CTF_FIELD_CLASS_TYPE_ARRAY || fc->type == CTF_FIELD_CLASS_TYPE_SEQUENCE) { + ctf_field_class_array_base *array_fc = ctf_field_class_as_array_base(fc); - if (array_fc->is_text) { - BT_ASSERT_DBG(bt_field_get_class_type( - stack_top(msg_it->stack)->base) == - BT_FIELD_CLASS_TYPE_STRING); - bt_bfcr_set_unsigned_int_cb(msg_it->bfcr, - bfcr_unsigned_int_cb); - } - } + if (array_fc->is_text) { + BT_ASSERT_DBG(bt_field_get_class_type(stack_top(msg_it->stack)->base) == + BT_FIELD_CLASS_TYPE_STRING); + bt_bfcr_set_unsigned_int_cb(msg_it->bfcr, bfcr_unsigned_int_cb); + } + } - /* Pop stack */ - stack_pop(msg_it->stack); + /* Pop stack */ + stack_pop(msg_it->stack); - /* If the stack is not empty, increment the base's index */ - if (!stack_empty(msg_it->stack)) { - stack_top(msg_it->stack)->index++; - } + /* If the stack is not empty, increment the base's index */ + if (!stack_empty(msg_it->stack)) { + stack_top(msg_it->stack)->index++; + } end: - return BT_BFCR_STATUS_OK; -} - -static -int64_t bfcr_get_sequence_length_cb(struct ctf_field_class *fc, void *data) -{ - bt_field *seq_field; - ctf_msg_iter *msg_it = (ctf_msg_iter *) data; - bt_self_component *self_comp = msg_it->self_comp; - struct ctf_field_class_sequence *seq_fc = ctf_field_class_as_sequence(fc); - int64_t length; - int ret; - - length = (uint64_t) g_array_index(msg_it->stored_values, uint64_t, - seq_fc->stored_length_index); - - if (G_UNLIKELY(msg_it->dry_run)){ - goto end; - } - - seq_field = stack_top(msg_it->stack)->base; - BT_ASSERT_DBG(seq_field); - - /* - * bfcr_get_sequence_length_cb() also gets called back for a - * text sequence, but the destination field is a string field. - * Only set the field's sequence length if the destination field - * is a sequence field. - */ - if (!seq_fc->base.is_text) { - BT_ASSERT_DBG(bt_field_class_type_is( - bt_field_get_class_type(seq_field), - BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY)); - ret = bt_field_array_dynamic_set_length(seq_field, - (uint64_t) length); - if (ret) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Cannot set dynamic array field's length field: " - "msg-it-addr=%p, field-addr=%p, " - "length=%" PRIu64, msg_it, seq_field, length); - length = -1; - } - } + return BT_BFCR_STATUS_OK; +} + +static int64_t bfcr_get_sequence_length_cb(struct ctf_field_class *fc, void *data) +{ + bt_field *seq_field; + ctf_msg_iter *msg_it = (ctf_msg_iter *) data; + bt_self_component *self_comp = msg_it->self_comp; + struct ctf_field_class_sequence *seq_fc = ctf_field_class_as_sequence(fc); + int64_t length; + int ret; + + length = (uint64_t) g_array_index(msg_it->stored_values, uint64_t, seq_fc->stored_length_index); + + if (G_UNLIKELY(msg_it->dry_run)) { + goto end; + } + + seq_field = stack_top(msg_it->stack)->base; + BT_ASSERT_DBG(seq_field); + + /* + * bfcr_get_sequence_length_cb() also gets called back for a + * text sequence, but the destination field is a string field. + * Only set the field's sequence length if the destination field + * is a sequence field. + */ + if (!seq_fc->base.is_text) { + BT_ASSERT_DBG(bt_field_class_type_is(bt_field_get_class_type(seq_field), + BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY)); + ret = bt_field_array_dynamic_set_length(seq_field, (uint64_t) length); + if (ret) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, + "Cannot set dynamic array field's length field: " + "msg-it-addr=%p, field-addr=%p, " + "length=%" PRIu64, + msg_it, seq_field, length); + length = -1; + } + } end: - return length; -} - -static -struct ctf_field_class *bfcr_borrow_variant_selected_field_class_cb( - struct ctf_field_class *fc, void *data) -{ - int ret; - uint64_t i; - int64_t option_index = -1; - ctf_msg_iter *msg_it = (ctf_msg_iter *) data; - ctf_field_class_variant *var_fc = ctf_field_class_as_variant(fc); - struct ctf_named_field_class *selected_option = NULL; - bt_self_component *self_comp = msg_it->self_comp; - struct ctf_field_class *ret_fc = NULL; - union { - uint64_t u; - int64_t i; - } tag; - - /* Get variant's tag */ - tag.u = g_array_index(msg_it->stored_values, uint64_t, - var_fc->stored_tag_index); - - /* - * Check each range to find the selected option's index. - */ - if (var_fc->tag_fc->base.is_signed) { - for (i = 0; i < var_fc->ranges->len; i++) { - struct ctf_field_class_variant_range *range = - ctf_field_class_variant_borrow_range_by_index( - var_fc, i); - - if (tag.i >= range->range.lower.i && - tag.i <= range->range.upper.i) { - option_index = (int64_t) range->option_index; - break; - } - } - } else { - for (i = 0; i < var_fc->ranges->len; i++) { - struct ctf_field_class_variant_range *range = - ctf_field_class_variant_borrow_range_by_index( - var_fc, i); - - if (tag.u >= range->range.lower.u && - tag.u <= range->range.upper.u) { - option_index = (int64_t) range->option_index; - break; - } - } - } - - if (option_index < 0) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Cannot find variant field class's option: " - "msg-it-addr=%p, var-fc-addr=%p, u-tag=%" PRIu64 ", " - "i-tag=%" PRId64, msg_it, var_fc, tag.u, tag.i); - ret_fc = NULL; - goto end; - } - - selected_option = ctf_field_class_variant_borrow_option_by_index( - var_fc, (uint64_t) option_index); - - if (selected_option->fc->in_ir && !msg_it->dry_run) { - bt_field *var_field = stack_top(msg_it->stack)->base; - - ret = bt_field_variant_select_option_by_index( - var_field, option_index); - if (ret) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Cannot select variant field's option field: " - "msg-it-addr=%p, var-field-addr=%p, " - "opt-index=%" PRId64, msg_it, var_field, - option_index); - ret_fc = NULL; - goto end; - } - } - - ret_fc = selected_option->fc; + return length; +} + +static struct ctf_field_class * +bfcr_borrow_variant_selected_field_class_cb(struct ctf_field_class *fc, void *data) +{ + int ret; + uint64_t i; + int64_t option_index = -1; + ctf_msg_iter *msg_it = (ctf_msg_iter *) data; + ctf_field_class_variant *var_fc = ctf_field_class_as_variant(fc); + struct ctf_named_field_class *selected_option = NULL; + bt_self_component *self_comp = msg_it->self_comp; + struct ctf_field_class *ret_fc = NULL; + union + { + uint64_t u; + int64_t i; + } tag; + + /* Get variant's tag */ + tag.u = g_array_index(msg_it->stored_values, uint64_t, var_fc->stored_tag_index); + + /* + * Check each range to find the selected option's index. + */ + if (var_fc->tag_fc->base.is_signed) { + for (i = 0; i < var_fc->ranges->len; i++) { + struct ctf_field_class_variant_range *range = + ctf_field_class_variant_borrow_range_by_index(var_fc, i); + + if (tag.i >= range->range.lower.i && tag.i <= range->range.upper.i) { + option_index = (int64_t) range->option_index; + break; + } + } + } else { + for (i = 0; i < var_fc->ranges->len; i++) { + struct ctf_field_class_variant_range *range = + ctf_field_class_variant_borrow_range_by_index(var_fc, i); + + if (tag.u >= range->range.lower.u && tag.u <= range->range.upper.u) { + option_index = (int64_t) range->option_index; + break; + } + } + } + + if (option_index < 0) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, + "Cannot find variant field class's option: " + "msg-it-addr=%p, var-fc-addr=%p, u-tag=%" PRIu64 ", " + "i-tag=%" PRId64, + msg_it, var_fc, tag.u, tag.i); + ret_fc = NULL; + goto end; + } + + selected_option = + ctf_field_class_variant_borrow_option_by_index(var_fc, (uint64_t) option_index); + + if (selected_option->fc->in_ir && !msg_it->dry_run) { + bt_field *var_field = stack_top(msg_it->stack)->base; + + ret = bt_field_variant_select_option_by_index(var_field, option_index); + if (ret) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, + "Cannot select variant field's option field: " + "msg-it-addr=%p, var-field-addr=%p, " + "opt-index=%" PRId64, + msg_it, var_field, option_index); + ret_fc = NULL; + goto end; + } + } + + ret_fc = selected_option->fc; end: - return ret_fc; + return ret_fc; } -static -bt_message *create_msg_stream_beginning(struct ctf_msg_iter *msg_it) +static bt_message *create_msg_stream_beginning(struct ctf_msg_iter *msg_it) { - bt_self_component *self_comp = msg_it->self_comp; - bt_message *msg; + bt_self_component *self_comp = msg_it->self_comp; + bt_message *msg; - BT_ASSERT(msg_it->stream); - BT_ASSERT(msg_it->self_msg_iter); - msg = bt_message_stream_beginning_create(msg_it->self_msg_iter, - msg_it->stream); - if (!msg) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Cannot create stream beginning message: " - "msg-it-addr=%p, stream-addr=%p", - msg_it, msg_it->stream); - } + BT_ASSERT(msg_it->stream); + BT_ASSERT(msg_it->self_msg_iter); + msg = bt_message_stream_beginning_create(msg_it->self_msg_iter, msg_it->stream); + if (!msg) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, + "Cannot create stream beginning message: " + "msg-it-addr=%p, stream-addr=%p", + msg_it, msg_it->stream); + } - return msg; + return msg; } -static -bt_message *create_msg_stream_end(struct ctf_msg_iter *msg_it) +static bt_message *create_msg_stream_end(struct ctf_msg_iter *msg_it) { - bt_self_component *self_comp = msg_it->self_comp; - bt_message *msg; + bt_self_component *self_comp = msg_it->self_comp; + bt_message *msg; - if (!msg_it->stream) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Cannot create stream end message because stream is NULL: " - "msg-it-addr=%p", msg_it); - msg = NULL; - goto end; - } + if (!msg_it->stream) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, + "Cannot create stream end message because stream is NULL: " + "msg-it-addr=%p", + msg_it); + msg = NULL; + goto end; + } - BT_ASSERT(msg_it->self_msg_iter); - msg = bt_message_stream_end_create(msg_it->self_msg_iter, - msg_it->stream); - if (!msg) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Cannot create stream end message: " - "msg-it-addr=%p, stream-addr=%p", - msg_it, msg_it->stream); - } + BT_ASSERT(msg_it->self_msg_iter); + msg = bt_message_stream_end_create(msg_it->self_msg_iter, msg_it->stream); + if (!msg) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, + "Cannot create stream end message: " + "msg-it-addr=%p, stream-addr=%p", + msg_it, msg_it->stream); + } end: - return msg; -} - -static -bt_message *create_msg_packet_beginning(struct ctf_msg_iter *msg_it, - bool use_default_cs) -{ - bt_self_component *self_comp = msg_it->self_comp; - bt_message *msg; - const bt_stream_class *sc = msg_it->meta.sc->ir_sc; - - BT_ASSERT(msg_it->packet); - BT_ASSERT(sc); - BT_ASSERT(msg_it->self_msg_iter); - - if (msg_it->meta.sc->packets_have_ts_begin) { - BT_ASSERT(msg_it->snapshots.beginning_clock != UINT64_C(-1)); - uint64_t raw_cs_value; - - /* - * Either use the decoded packet `timestamp_begin` field or the - * current stream's default clock_snapshot. - */ - if (use_default_cs) { - raw_cs_value = msg_it->default_clock_snapshot; - } else { - raw_cs_value = msg_it->snapshots.beginning_clock; - } - - msg = bt_message_packet_beginning_create_with_default_clock_snapshot( - msg_it->self_msg_iter, msg_it->packet, - raw_cs_value); - } else { - msg = bt_message_packet_beginning_create(msg_it->self_msg_iter, - msg_it->packet); - } - - if (!msg) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Cannot create packet beginning message: " - "msg-it-addr=%p, packet-addr=%p", - msg_it, msg_it->packet); - goto end; - } + return msg; +} + +static bt_message *create_msg_packet_beginning(struct ctf_msg_iter *msg_it, bool use_default_cs) +{ + bt_self_component *self_comp = msg_it->self_comp; + bt_message *msg; + const bt_stream_class *sc = msg_it->meta.sc->ir_sc; + + BT_ASSERT(msg_it->packet); + BT_ASSERT(sc); + BT_ASSERT(msg_it->self_msg_iter); + + if (msg_it->meta.sc->packets_have_ts_begin) { + BT_ASSERT(msg_it->snapshots.beginning_clock != UINT64_C(-1)); + uint64_t raw_cs_value; + + /* + * Either use the decoded packet `timestamp_begin` field or the + * current stream's default clock_snapshot. + */ + if (use_default_cs) { + raw_cs_value = msg_it->default_clock_snapshot; + } else { + raw_cs_value = msg_it->snapshots.beginning_clock; + } + + msg = bt_message_packet_beginning_create_with_default_clock_snapshot( + msg_it->self_msg_iter, msg_it->packet, raw_cs_value); + } else { + msg = bt_message_packet_beginning_create(msg_it->self_msg_iter, msg_it->packet); + } + + if (!msg) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, + "Cannot create packet beginning message: " + "msg-it-addr=%p, packet-addr=%p", + msg_it, msg_it->packet); + goto end; + } end: - return msg; -} - -static -bt_message *emit_delayed_packet_beg_msg(struct ctf_msg_iter *msg_it) -{ - bool packet_beg_ts_need_fix_up; - - msg_it->emit_delayed_packet_beginning_msg = false; - - /* - * Only fix the packet's timestamp_begin if it's larger than the first - * event of the packet. If there was no event in the packet, the - * `default_clock_snapshot` field will be either equal or greater than - * `snapshots.beginning_clock` so there is not fix needed. - */ - packet_beg_ts_need_fix_up = - msg_it->default_clock_snapshot < msg_it->snapshots.beginning_clock; - - /* create_msg_packet_beginning() logs errors */ - return create_msg_packet_beginning(msg_it, packet_beg_ts_need_fix_up); -} - - -static -bt_message *create_msg_packet_end(struct ctf_msg_iter *msg_it) -{ - bt_message *msg; - bool update_default_cs = true; - bt_self_component *self_comp = msg_it->self_comp; - - if (!msg_it->packet) { - msg = NULL; - goto end; - } - - /* - * Check if we need to emit the delayed packet - * beginning message instead of the packet end message. - */ - if (G_UNLIKELY(msg_it->emit_delayed_packet_beginning_msg)) { - msg = emit_delayed_packet_beg_msg(msg_it); - /* Don't forget to emit the packet end message. */ - msg_it->state = STATE_EMIT_QUEUED_MSG_PACKET_END; - goto end; - } - - /* Check if may be affected by lttng-crash timestamp_end quirk. */ - if (G_UNLIKELY(msg_it->meta.tc->quirks.lttng_crash)) { - /* - * Check if the `timestamp_begin` field is non-zero but - * `timestamp_end` is zero. It means the trace is affected by - * the lttng-crash packet `timestamp_end` quirk and must be - * fixed up by omitting to update the default clock snapshot to - * the `timestamp_end` as is typically done. - */ - if (msg_it->snapshots.beginning_clock != 0 && - msg_it->snapshots.end_clock == 0) { - update_default_cs = false; - } - } - - /* - * Check if may be affected by lttng event-after-packet `timestamp_end` - * quirk. - */ - if (msg_it->meta.tc->quirks.lttng_event_after_packet) { - /* - * Check if `timestamp_end` is smaller then the current - * default_clock_snapshot (which is set to the last event - * decoded). It means the trace is affected by the lttng - * `event-after-packet` packet `timestamp_end` quirk and must - * be fixed up by omitting to update the default clock snapshot - * to the `timestamp_end` as is typically done. - */ - if (msg_it->snapshots.end_clock < msg_it->default_clock_snapshot) { - update_default_cs = false; - } - } - - /* Update default clock from packet's end time. */ - if (msg_it->snapshots.end_clock != UINT64_C(-1) && update_default_cs) { - msg_it->default_clock_snapshot = msg_it->snapshots.end_clock; - } - - BT_ASSERT(msg_it->self_msg_iter); - - if (msg_it->meta.sc->packets_have_ts_end) { - BT_ASSERT(msg_it->snapshots.end_clock != UINT64_C(-1)); - msg = bt_message_packet_end_create_with_default_clock_snapshot( - msg_it->self_msg_iter, msg_it->packet, - msg_it->default_clock_snapshot); - } else { - msg = bt_message_packet_end_create(msg_it->self_msg_iter, - msg_it->packet); - } - - if (!msg) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Cannot create packet end message: " - "msg-it-addr=%p, packet-addr=%p", - msg_it, msg_it->packet); - goto end; - - } - - BT_PACKET_PUT_REF_AND_RESET(msg_it->packet); + return msg; +} + +static bt_message *emit_delayed_packet_beg_msg(struct ctf_msg_iter *msg_it) +{ + bool packet_beg_ts_need_fix_up; + + msg_it->emit_delayed_packet_beginning_msg = false; + + /* + * Only fix the packet's timestamp_begin if it's larger than the first + * event of the packet. If there was no event in the packet, the + * `default_clock_snapshot` field will be either equal or greater than + * `snapshots.beginning_clock` so there is not fix needed. + */ + packet_beg_ts_need_fix_up = msg_it->default_clock_snapshot < msg_it->snapshots.beginning_clock; + + /* create_msg_packet_beginning() logs errors */ + return create_msg_packet_beginning(msg_it, packet_beg_ts_need_fix_up); +} + +static bt_message *create_msg_packet_end(struct ctf_msg_iter *msg_it) +{ + bt_message *msg; + bool update_default_cs = true; + bt_self_component *self_comp = msg_it->self_comp; + + if (!msg_it->packet) { + msg = NULL; + goto end; + } + + /* + * Check if we need to emit the delayed packet + * beginning message instead of the packet end message. + */ + if (G_UNLIKELY(msg_it->emit_delayed_packet_beginning_msg)) { + msg = emit_delayed_packet_beg_msg(msg_it); + /* Don't forget to emit the packet end message. */ + msg_it->state = STATE_EMIT_QUEUED_MSG_PACKET_END; + goto end; + } + + /* Check if may be affected by lttng-crash timestamp_end quirk. */ + if (G_UNLIKELY(msg_it->meta.tc->quirks.lttng_crash)) { + /* + * Check if the `timestamp_begin` field is non-zero but + * `timestamp_end` is zero. It means the trace is affected by + * the lttng-crash packet `timestamp_end` quirk and must be + * fixed up by omitting to update the default clock snapshot to + * the `timestamp_end` as is typically done. + */ + if (msg_it->snapshots.beginning_clock != 0 && msg_it->snapshots.end_clock == 0) { + update_default_cs = false; + } + } + + /* + * Check if may be affected by lttng event-after-packet `timestamp_end` + * quirk. + */ + if (msg_it->meta.tc->quirks.lttng_event_after_packet) { + /* + * Check if `timestamp_end` is smaller then the current + * default_clock_snapshot (which is set to the last event + * decoded). It means the trace is affected by the lttng + * `event-after-packet` packet `timestamp_end` quirk and must + * be fixed up by omitting to update the default clock snapshot + * to the `timestamp_end` as is typically done. + */ + if (msg_it->snapshots.end_clock < msg_it->default_clock_snapshot) { + update_default_cs = false; + } + } + + /* Update default clock from packet's end time. */ + if (msg_it->snapshots.end_clock != UINT64_C(-1) && update_default_cs) { + msg_it->default_clock_snapshot = msg_it->snapshots.end_clock; + } + + BT_ASSERT(msg_it->self_msg_iter); + + if (msg_it->meta.sc->packets_have_ts_end) { + BT_ASSERT(msg_it->snapshots.end_clock != UINT64_C(-1)); + msg = bt_message_packet_end_create_with_default_clock_snapshot( + msg_it->self_msg_iter, msg_it->packet, msg_it->default_clock_snapshot); + } else { + msg = bt_message_packet_end_create(msg_it->self_msg_iter, msg_it->packet); + } + + if (!msg) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, + "Cannot create packet end message: " + "msg-it-addr=%p, packet-addr=%p", + msg_it, msg_it->packet); + goto end; + } + + BT_PACKET_PUT_REF_AND_RESET(msg_it->packet); end: - return msg; -} - -static -bt_message *create_msg_discarded_events(struct ctf_msg_iter *msg_it) -{ - bt_message *msg; - bt_self_component *self_comp = msg_it->self_comp; - uint64_t beginning_raw_value = UINT64_C(-1); - uint64_t end_raw_value = UINT64_C(-1); - - BT_ASSERT(msg_it->self_msg_iter); - BT_ASSERT(msg_it->stream); - BT_ASSERT(msg_it->meta.sc->has_discarded_events); - - if (msg_it->meta.sc->discarded_events_have_default_cs) { - if (msg_it->prev_packet_snapshots.discarded_events == UINT64_C(-1)) { - /* - * We discarded events, but before (and possibly - * including) the current packet: use this packet's time - * range, and do not have a specific count. - */ - beginning_raw_value = msg_it->snapshots.beginning_clock; - end_raw_value = msg_it->snapshots.end_clock; - } else { - beginning_raw_value = msg_it->prev_packet_snapshots.end_clock; - end_raw_value = msg_it->snapshots.end_clock; - } - - BT_ASSERT(beginning_raw_value != UINT64_C(-1)); - BT_ASSERT(end_raw_value != UINT64_C(-1)); - msg = bt_message_discarded_events_create_with_default_clock_snapshots( - msg_it->self_msg_iter, msg_it->stream, beginning_raw_value, - end_raw_value); - } else { - msg = bt_message_discarded_events_create(msg_it->self_msg_iter, - msg_it->stream); - } - - if (!msg) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Cannot create discarded events message: " - "msg-it-addr=%p, stream-addr=%p", - msg_it, msg_it->stream); - goto end; - } - - if (msg_it->prev_packet_snapshots.discarded_events != UINT64_C(-1)) { - bt_message_discarded_events_set_count(msg, - msg_it->snapshots.discarded_events - - msg_it->prev_packet_snapshots.discarded_events); - } + return msg; +} + +static bt_message *create_msg_discarded_events(struct ctf_msg_iter *msg_it) +{ + bt_message *msg; + bt_self_component *self_comp = msg_it->self_comp; + uint64_t beginning_raw_value = UINT64_C(-1); + uint64_t end_raw_value = UINT64_C(-1); + + BT_ASSERT(msg_it->self_msg_iter); + BT_ASSERT(msg_it->stream); + BT_ASSERT(msg_it->meta.sc->has_discarded_events); + + if (msg_it->meta.sc->discarded_events_have_default_cs) { + if (msg_it->prev_packet_snapshots.discarded_events == UINT64_C(-1)) { + /* + * We discarded events, but before (and possibly + * including) the current packet: use this packet's time + * range, and do not have a specific count. + */ + beginning_raw_value = msg_it->snapshots.beginning_clock; + end_raw_value = msg_it->snapshots.end_clock; + } else { + beginning_raw_value = msg_it->prev_packet_snapshots.end_clock; + end_raw_value = msg_it->snapshots.end_clock; + } + + BT_ASSERT(beginning_raw_value != UINT64_C(-1)); + BT_ASSERT(end_raw_value != UINT64_C(-1)); + msg = bt_message_discarded_events_create_with_default_clock_snapshots( + msg_it->self_msg_iter, msg_it->stream, beginning_raw_value, end_raw_value); + } else { + msg = bt_message_discarded_events_create(msg_it->self_msg_iter, msg_it->stream); + } + + if (!msg) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, + "Cannot create discarded events message: " + "msg-it-addr=%p, stream-addr=%p", + msg_it, msg_it->stream); + goto end; + } + + if (msg_it->prev_packet_snapshots.discarded_events != UINT64_C(-1)) { + bt_message_discarded_events_set_count(msg, + msg_it->snapshots.discarded_events - + msg_it->prev_packet_snapshots.discarded_events); + } end: - return msg; -} - -static -bt_message *create_msg_discarded_packets(struct ctf_msg_iter *msg_it) -{ - bt_message *msg; - bt_self_component *self_comp = msg_it->self_comp; - - BT_ASSERT(msg_it->self_msg_iter); - BT_ASSERT(msg_it->stream); - BT_ASSERT(msg_it->meta.sc->has_discarded_packets); - BT_ASSERT(msg_it->prev_packet_snapshots.packets != - UINT64_C(-1)); - - if (msg_it->meta.sc->discarded_packets_have_default_cs) { - BT_ASSERT(msg_it->prev_packet_snapshots.end_clock != UINT64_C(-1)); - BT_ASSERT(msg_it->snapshots.beginning_clock != UINT64_C(-1)); - msg = bt_message_discarded_packets_create_with_default_clock_snapshots( - msg_it->self_msg_iter, msg_it->stream, - msg_it->prev_packet_snapshots.end_clock, - msg_it->snapshots.beginning_clock); - } else { - msg = bt_message_discarded_packets_create(msg_it->self_msg_iter, - msg_it->stream); - } - - if (!msg) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Cannot create discarded packets message: " - "msg-it-addr=%p, stream-addr=%p", - msg_it, msg_it->stream); - goto end; - } - - bt_message_discarded_packets_set_count(msg, - msg_it->snapshots.packets - - msg_it->prev_packet_snapshots.packets - 1); + return msg; +} + +static bt_message *create_msg_discarded_packets(struct ctf_msg_iter *msg_it) +{ + bt_message *msg; + bt_self_component *self_comp = msg_it->self_comp; + + BT_ASSERT(msg_it->self_msg_iter); + BT_ASSERT(msg_it->stream); + BT_ASSERT(msg_it->meta.sc->has_discarded_packets); + BT_ASSERT(msg_it->prev_packet_snapshots.packets != UINT64_C(-1)); + + if (msg_it->meta.sc->discarded_packets_have_default_cs) { + BT_ASSERT(msg_it->prev_packet_snapshots.end_clock != UINT64_C(-1)); + BT_ASSERT(msg_it->snapshots.beginning_clock != UINT64_C(-1)); + msg = bt_message_discarded_packets_create_with_default_clock_snapshots( + msg_it->self_msg_iter, msg_it->stream, msg_it->prev_packet_snapshots.end_clock, + msg_it->snapshots.beginning_clock); + } else { + msg = bt_message_discarded_packets_create(msg_it->self_msg_iter, msg_it->stream); + } + + if (!msg) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, + "Cannot create discarded packets message: " + "msg-it-addr=%p, stream-addr=%p", + msg_it, msg_it->stream); + goto end; + } + + bt_message_discarded_packets_set_count(msg, msg_it->snapshots.packets - + msg_it->prev_packet_snapshots.packets - 1); end: - return msg; + return msg; } BT_HIDDEN -struct ctf_msg_iter *ctf_msg_iter_create( - struct ctf_trace_class *tc, - size_t max_request_sz, - struct ctf_msg_iter_medium_ops medops, void *data, - bt_logging_level log_level, - bt_self_component *self_comp, - bt_self_message_iterator *self_msg_iter) -{ - struct ctf_msg_iter *msg_it = NULL; - struct bt_bfcr_cbs cbs = { - .classes = { - .signed_int = bfcr_signed_int_cb, - .unsigned_int = bfcr_unsigned_int_cb, - .floating_point = bfcr_floating_point_cb, - .string_begin = bfcr_string_begin_cb, - .string = bfcr_string_cb, - .string_end = bfcr_string_end_cb, - .compound_begin = bfcr_compound_begin_cb, - .compound_end = bfcr_compound_end_cb, - }, - .query = { - .get_sequence_length = bfcr_get_sequence_length_cb, - .borrow_variant_selected_field_class = bfcr_borrow_variant_selected_field_class_cb, - }, - }; - - BT_ASSERT(tc); - BT_ASSERT(medops.request_bytes); - BT_ASSERT(medops.borrow_stream); - BT_ASSERT(max_request_sz > 0); - - BT_COMP_LOG_CUR_LVL(BT_LOG_DEBUG, log_level, self_comp, - "Creating CTF plugin message iterator: " - "trace-addr=%p, max-request-size=%zu, " - "data=%p, log-level=%s", tc, max_request_sz, data, - bt_common_logging_level_string(log_level)); - msg_it = g_new0(struct ctf_msg_iter, 1); - if (!msg_it) { - BT_COMP_LOG_CUR_LVL(BT_LOG_ERROR, log_level, self_comp, - "Failed to allocate one CTF plugin message iterator."); - goto end; - } - msg_it->self_comp = self_comp; - msg_it->self_msg_iter = self_msg_iter; - msg_it->log_level = log_level; - msg_it->meta.tc = tc; - msg_it->medium.medops = medops; - msg_it->medium.max_request_sz = max_request_sz; - msg_it->medium.data = data; - msg_it->stack = stack_new(msg_it); - msg_it->stored_values = g_array_new(FALSE, TRUE, sizeof(uint64_t)); - g_array_set_size(msg_it->stored_values, tc->stored_value_count); - - if (!msg_it->stack) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Failed to create field stack."); - goto error; - } - - msg_it->bfcr = bt_bfcr_create(cbs, msg_it, log_level, NULL); - if (!msg_it->bfcr) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Failed to create binary class reader (BFCR)."); - goto error; - } - - ctf_msg_iter_reset(msg_it); - BT_COMP_LOGD("Created CTF plugin message iterator: " - "trace-addr=%p, max-request-size=%zu, " - "data=%p, msg-it-addr=%p, log-level=%s", - tc, max_request_sz, data, msg_it, - bt_common_logging_level_string(log_level)); - msg_it->cur_packet_offset = 0; +struct ctf_msg_iter *ctf_msg_iter_create(struct ctf_trace_class *tc, size_t max_request_sz, + struct ctf_msg_iter_medium_ops medops, void *data, + bt_logging_level log_level, bt_self_component *self_comp, + bt_self_message_iterator *self_msg_iter) +{ + struct ctf_msg_iter *msg_it = NULL; + struct bt_bfcr_cbs cbs = { + .classes = + { + .signed_int = bfcr_signed_int_cb, + .unsigned_int = bfcr_unsigned_int_cb, + .floating_point = bfcr_floating_point_cb, + .string_begin = bfcr_string_begin_cb, + .string = bfcr_string_cb, + .string_end = bfcr_string_end_cb, + .compound_begin = bfcr_compound_begin_cb, + .compound_end = bfcr_compound_end_cb, + }, + .query = + { + .get_sequence_length = bfcr_get_sequence_length_cb, + .borrow_variant_selected_field_class = bfcr_borrow_variant_selected_field_class_cb, + }, + }; + + BT_ASSERT(tc); + BT_ASSERT(medops.request_bytes); + BT_ASSERT(medops.borrow_stream); + BT_ASSERT(max_request_sz > 0); + + BT_COMP_LOG_CUR_LVL(BT_LOG_DEBUG, log_level, self_comp, + "Creating CTF plugin message iterator: " + "trace-addr=%p, max-request-size=%zu, " + "data=%p, log-level=%s", + tc, max_request_sz, data, bt_common_logging_level_string(log_level)); + msg_it = g_new0(struct ctf_msg_iter, 1); + if (!msg_it) { + BT_COMP_LOG_CUR_LVL(BT_LOG_ERROR, log_level, self_comp, + "Failed to allocate one CTF plugin message iterator."); + goto end; + } + msg_it->self_comp = self_comp; + msg_it->self_msg_iter = self_msg_iter; + msg_it->log_level = log_level; + msg_it->meta.tc = tc; + msg_it->medium.medops = medops; + msg_it->medium.max_request_sz = max_request_sz; + msg_it->medium.data = data; + msg_it->stack = stack_new(msg_it); + msg_it->stored_values = g_array_new(FALSE, TRUE, sizeof(uint64_t)); + g_array_set_size(msg_it->stored_values, tc->stored_value_count); + + if (!msg_it->stack) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Failed to create field stack."); + goto error; + } + + msg_it->bfcr = bt_bfcr_create(cbs, msg_it, log_level, NULL); + if (!msg_it->bfcr) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Failed to create binary class reader (BFCR)."); + goto error; + } + + ctf_msg_iter_reset(msg_it); + BT_COMP_LOGD("Created CTF plugin message iterator: " + "trace-addr=%p, max-request-size=%zu, " + "data=%p, msg-it-addr=%p, log-level=%s", + tc, max_request_sz, data, msg_it, bt_common_logging_level_string(log_level)); + msg_it->cur_packet_offset = 0; end: - return msg_it; + return msg_it; error: - ctf_msg_iter_destroy(msg_it); - msg_it = NULL; - goto end; + ctf_msg_iter_destroy(msg_it); + msg_it = NULL; + goto end; } void ctf_msg_iter_destroy(struct ctf_msg_iter *msg_it) { - BT_PACKET_PUT_REF_AND_RESET(msg_it->packet); - BT_STREAM_PUT_REF_AND_RESET(msg_it->stream); - release_all_dscopes(msg_it); - - BT_COMP_LOGD("Destroying CTF plugin message iterator: addr=%p", msg_it); - - if (msg_it->stack) { - BT_COMP_LOGD_STR("Destroying field stack."); - stack_destroy(msg_it->stack); - } - - if (msg_it->bfcr) { - BT_COMP_LOGD("Destroying BFCR: bfcr-addr=%p", msg_it->bfcr); - bt_bfcr_destroy(msg_it->bfcr); - } - - if (msg_it->stored_values) { - g_array_free(msg_it->stored_values, TRUE); - } - - g_free(msg_it); -} - -enum ctf_msg_iter_status ctf_msg_iter_get_next_message( - struct ctf_msg_iter *msg_it, - const bt_message **message) -{ - enum ctf_msg_iter_status status = CTF_MSG_ITER_STATUS_OK; - bt_self_component *self_comp = msg_it->self_comp; - - BT_ASSERT_DBG(msg_it); - BT_ASSERT_DBG(message); - BT_COMP_LOGD("Getting next message: msg-it-addr=%p", msg_it); - - while (true) { - status = handle_state(msg_it); - if (G_UNLIKELY(status == CTF_MSG_ITER_STATUS_AGAIN)) { - BT_COMP_LOGD_STR("Medium returned CTF_MSG_ITER_STATUS_AGAIN."); - goto end; - } else if (G_UNLIKELY(status != CTF_MSG_ITER_STATUS_OK)) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Cannot handle state: msg-it-addr=%p, state=%s", - msg_it, state_string(msg_it->state)); - goto end; - } - - switch (msg_it->state) { - case STATE_EMIT_MSG_EVENT: - BT_ASSERT_DBG(msg_it->event_msg); - - /* - * Check if we need to emit the delayed packet - * beginning message instead of the event message. - */ - if (G_UNLIKELY(msg_it->emit_delayed_packet_beginning_msg)) { - *message = emit_delayed_packet_beg_msg(msg_it); - if (!*message) { - status = CTF_MSG_ITER_STATUS_ERROR; - } - - /* - * Don't forget to emit the event message of - * the event record that was just decoded. - */ - msg_it->state = STATE_EMIT_QUEUED_MSG_EVENT; - - } else { - *message = msg_it->event_msg; - msg_it->event_msg = NULL; - } - goto end; - case STATE_EMIT_MSG_DISCARDED_EVENTS: - /* create_msg_discared_events() logs errors */ - *message = create_msg_discarded_events(msg_it); - - if (!*message) { - status = CTF_MSG_ITER_STATUS_ERROR; - } - - goto end; - case STATE_EMIT_MSG_DISCARDED_PACKETS: - /* create_msg_discared_packets() logs errors */ - *message = create_msg_discarded_packets(msg_it); - - if (!*message) { - status = CTF_MSG_ITER_STATUS_ERROR; - } - - goto end; - case STATE_EMIT_MSG_PACKET_BEGINNING: - if (G_UNLIKELY(msg_it->meta.tc->quirks.barectf_event_before_packet)) { - msg_it->emit_delayed_packet_beginning_msg = true; - /* - * There is no message to return yet as this - * packet beginning message is delayed until we - * decode the first event message of the - * packet. - */ - break; - } else { - /* create_msg_packet_beginning() logs errors */ - *message = create_msg_packet_beginning(msg_it, false); - if (!*message) { - status = CTF_MSG_ITER_STATUS_ERROR; - } - } - - goto end; - case STATE_EMIT_MSG_PACKET_END_SINGLE: - case STATE_EMIT_MSG_PACKET_END_MULTI: - /* create_msg_packet_end() logs errors */ - *message = create_msg_packet_end(msg_it); - - if (!*message) { - status = CTF_MSG_ITER_STATUS_ERROR; - } - - goto end; - case STATE_EMIT_MSG_STREAM_BEGINNING: - /* create_msg_stream_beginning() logs errors */ - *message = create_msg_stream_beginning(msg_it); - msg_it->emit_stream_beginning_message = false; - msg_it->emit_stream_end_message = true; - - if (!*message) { - status = CTF_MSG_ITER_STATUS_ERROR; - } - - goto end; - case STATE_EMIT_MSG_STREAM_END: - /* create_msg_stream_end() logs errors */ - *message = create_msg_stream_end(msg_it); - msg_it->emit_stream_end_message = false; - - if (!*message) { - status = CTF_MSG_ITER_STATUS_ERROR; - } - - goto end; - case STATE_DONE: - status = CTF_MSG_ITER_STATUS_EOF; - goto end; - default: - /* Non-emitting state: continue */ - break; - } - } + BT_PACKET_PUT_REF_AND_RESET(msg_it->packet); + BT_STREAM_PUT_REF_AND_RESET(msg_it->stream); + release_all_dscopes(msg_it); + + BT_COMP_LOGD("Destroying CTF plugin message iterator: addr=%p", msg_it); + + if (msg_it->stack) { + BT_COMP_LOGD_STR("Destroying field stack."); + stack_destroy(msg_it->stack); + } + + if (msg_it->bfcr) { + BT_COMP_LOGD("Destroying BFCR: bfcr-addr=%p", msg_it->bfcr); + bt_bfcr_destroy(msg_it->bfcr); + } + + if (msg_it->stored_values) { + g_array_free(msg_it->stored_values, TRUE); + } + + g_free(msg_it); +} + +enum ctf_msg_iter_status ctf_msg_iter_get_next_message(struct ctf_msg_iter *msg_it, + const bt_message **message) +{ + enum ctf_msg_iter_status status = CTF_MSG_ITER_STATUS_OK; + bt_self_component *self_comp = msg_it->self_comp; + + BT_ASSERT_DBG(msg_it); + BT_ASSERT_DBG(message); + BT_COMP_LOGD("Getting next message: msg-it-addr=%p", msg_it); + + while (true) { + status = handle_state(msg_it); + if (G_UNLIKELY(status == CTF_MSG_ITER_STATUS_AGAIN)) { + BT_COMP_LOGD_STR("Medium returned CTF_MSG_ITER_STATUS_AGAIN."); + goto end; + } else if (G_UNLIKELY(status != CTF_MSG_ITER_STATUS_OK)) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Cannot handle state: msg-it-addr=%p, state=%s", + msg_it, state_string(msg_it->state)); + goto end; + } + + switch (msg_it->state) { + case STATE_EMIT_MSG_EVENT: + BT_ASSERT_DBG(msg_it->event_msg); + + /* + * Check if we need to emit the delayed packet + * beginning message instead of the event message. + */ + if (G_UNLIKELY(msg_it->emit_delayed_packet_beginning_msg)) { + *message = emit_delayed_packet_beg_msg(msg_it); + if (!*message) { + status = CTF_MSG_ITER_STATUS_ERROR; + } + + /* + * Don't forget to emit the event message of + * the event record that was just decoded. + */ + msg_it->state = STATE_EMIT_QUEUED_MSG_EVENT; + + } else { + *message = msg_it->event_msg; + msg_it->event_msg = NULL; + } + goto end; + case STATE_EMIT_MSG_DISCARDED_EVENTS: + /* create_msg_discared_events() logs errors */ + *message = create_msg_discarded_events(msg_it); + + if (!*message) { + status = CTF_MSG_ITER_STATUS_ERROR; + } + + goto end; + case STATE_EMIT_MSG_DISCARDED_PACKETS: + /* create_msg_discared_packets() logs errors */ + *message = create_msg_discarded_packets(msg_it); + + if (!*message) { + status = CTF_MSG_ITER_STATUS_ERROR; + } + + goto end; + case STATE_EMIT_MSG_PACKET_BEGINNING: + if (G_UNLIKELY(msg_it->meta.tc->quirks.barectf_event_before_packet)) { + msg_it->emit_delayed_packet_beginning_msg = true; + /* + * There is no message to return yet as this + * packet beginning message is delayed until we + * decode the first event message of the + * packet. + */ + break; + } else { + /* create_msg_packet_beginning() logs errors */ + *message = create_msg_packet_beginning(msg_it, false); + if (!*message) { + status = CTF_MSG_ITER_STATUS_ERROR; + } + } + + goto end; + case STATE_EMIT_MSG_PACKET_END_SINGLE: + case STATE_EMIT_MSG_PACKET_END_MULTI: + /* create_msg_packet_end() logs errors */ + *message = create_msg_packet_end(msg_it); + + if (!*message) { + status = CTF_MSG_ITER_STATUS_ERROR; + } + + goto end; + case STATE_EMIT_MSG_STREAM_BEGINNING: + /* create_msg_stream_beginning() logs errors */ + *message = create_msg_stream_beginning(msg_it); + msg_it->emit_stream_beginning_message = false; + msg_it->emit_stream_end_message = true; + + if (!*message) { + status = CTF_MSG_ITER_STATUS_ERROR; + } + + goto end; + case STATE_EMIT_MSG_STREAM_END: + /* create_msg_stream_end() logs errors */ + *message = create_msg_stream_end(msg_it); + msg_it->emit_stream_end_message = false; + + if (!*message) { + status = CTF_MSG_ITER_STATUS_ERROR; + } + + goto end; + case STATE_DONE: + status = CTF_MSG_ITER_STATUS_EOF; + goto end; + default: + /* Non-emitting state: continue */ + break; + } + } end: - return status; -} - -static -enum ctf_msg_iter_status decode_until_state( struct ctf_msg_iter *msg_it, - enum state target_state_1, enum state target_state_2) -{ - enum ctf_msg_iter_status status = CTF_MSG_ITER_STATUS_OK; - bt_self_component *self_comp = msg_it->self_comp; - - BT_ASSERT_DBG(msg_it); - - do { - /* - * Check if we reached the state at which we want to stop - * decoding. - */ - if (msg_it->state == target_state_1 || - msg_it->state == target_state_2) { - goto end; - } - - status = handle_state(msg_it); - if (G_UNLIKELY(status == CTF_MSG_ITER_STATUS_AGAIN)) { - BT_COMP_LOGD_STR("Medium returned CTF_MSG_ITER_STATUS_AGAIN."); - goto end; - } else if (G_UNLIKELY(status != CTF_MSG_ITER_STATUS_OK)) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Cannot handle state: msg-it-addr=%p, state=%s", - msg_it, state_string(msg_it->state)); - goto end; - } - - switch (msg_it->state) { - case STATE_INIT: - case STATE_SWITCH_PACKET: - case STATE_DSCOPE_TRACE_PACKET_HEADER_BEGIN: - case STATE_DSCOPE_TRACE_PACKET_HEADER_CONTINUE: - case STATE_AFTER_TRACE_PACKET_HEADER: - case STATE_DSCOPE_STREAM_PACKET_CONTEXT_BEGIN: - case STATE_DSCOPE_STREAM_PACKET_CONTEXT_CONTINUE: - case STATE_AFTER_STREAM_PACKET_CONTEXT: - case STATE_EMIT_MSG_STREAM_BEGINNING: - case STATE_CHECK_EMIT_MSG_DISCARDED_EVENTS: - case STATE_EMIT_MSG_DISCARDED_EVENTS: - case STATE_CHECK_EMIT_MSG_DISCARDED_PACKETS: - case STATE_EMIT_MSG_DISCARDED_PACKETS: - case STATE_EMIT_MSG_PACKET_BEGINNING: - case STATE_DSCOPE_EVENT_HEADER_BEGIN: - case STATE_DSCOPE_EVENT_HEADER_CONTINUE: - case STATE_AFTER_EVENT_HEADER: - case STATE_DSCOPE_EVENT_COMMON_CONTEXT_BEGIN: - case STATE_DSCOPE_EVENT_COMMON_CONTEXT_CONTINUE: - case STATE_DSCOPE_EVENT_SPEC_CONTEXT_BEGIN: - case STATE_DSCOPE_EVENT_SPEC_CONTEXT_CONTINUE: - case STATE_DSCOPE_EVENT_PAYLOAD_BEGIN: - case STATE_DSCOPE_EVENT_PAYLOAD_CONTINUE: - case STATE_EMIT_MSG_EVENT: - case STATE_EMIT_QUEUED_MSG_EVENT: - case STATE_SKIP_PACKET_PADDING: - case STATE_EMIT_MSG_PACKET_END_MULTI: - case STATE_EMIT_MSG_PACKET_END_SINGLE: - case STATE_EMIT_QUEUED_MSG_PACKET_END: - case STATE_EMIT_MSG_STREAM_END: - break; - case STATE_DONE: - /* fall-through */ - default: - /* We should never get to the STATE_DONE state. */ - BT_COMP_LOGF("Unexpected state: msg-it-addr=%p, state=%s", - msg_it, state_string(msg_it->state)); - bt_common_abort(); - } - } while (true); + return status; +} + +static enum ctf_msg_iter_status decode_until_state(struct ctf_msg_iter *msg_it, + enum state target_state_1, + enum state target_state_2) +{ + enum ctf_msg_iter_status status = CTF_MSG_ITER_STATUS_OK; + bt_self_component *self_comp = msg_it->self_comp; + + BT_ASSERT_DBG(msg_it); + + do { + /* + * Check if we reached the state at which we want to stop + * decoding. + */ + if (msg_it->state == target_state_1 || msg_it->state == target_state_2) { + goto end; + } + + status = handle_state(msg_it); + if (G_UNLIKELY(status == CTF_MSG_ITER_STATUS_AGAIN)) { + BT_COMP_LOGD_STR("Medium returned CTF_MSG_ITER_STATUS_AGAIN."); + goto end; + } else if (G_UNLIKELY(status != CTF_MSG_ITER_STATUS_OK)) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Cannot handle state: msg-it-addr=%p, state=%s", + msg_it, state_string(msg_it->state)); + goto end; + } + + switch (msg_it->state) { + case STATE_INIT: + case STATE_SWITCH_PACKET: + case STATE_DSCOPE_TRACE_PACKET_HEADER_BEGIN: + case STATE_DSCOPE_TRACE_PACKET_HEADER_CONTINUE: + case STATE_AFTER_TRACE_PACKET_HEADER: + case STATE_DSCOPE_STREAM_PACKET_CONTEXT_BEGIN: + case STATE_DSCOPE_STREAM_PACKET_CONTEXT_CONTINUE: + case STATE_AFTER_STREAM_PACKET_CONTEXT: + case STATE_EMIT_MSG_STREAM_BEGINNING: + case STATE_CHECK_EMIT_MSG_DISCARDED_EVENTS: + case STATE_EMIT_MSG_DISCARDED_EVENTS: + case STATE_CHECK_EMIT_MSG_DISCARDED_PACKETS: + case STATE_EMIT_MSG_DISCARDED_PACKETS: + case STATE_EMIT_MSG_PACKET_BEGINNING: + case STATE_DSCOPE_EVENT_HEADER_BEGIN: + case STATE_DSCOPE_EVENT_HEADER_CONTINUE: + case STATE_AFTER_EVENT_HEADER: + case STATE_DSCOPE_EVENT_COMMON_CONTEXT_BEGIN: + case STATE_DSCOPE_EVENT_COMMON_CONTEXT_CONTINUE: + case STATE_DSCOPE_EVENT_SPEC_CONTEXT_BEGIN: + case STATE_DSCOPE_EVENT_SPEC_CONTEXT_CONTINUE: + case STATE_DSCOPE_EVENT_PAYLOAD_BEGIN: + case STATE_DSCOPE_EVENT_PAYLOAD_CONTINUE: + case STATE_EMIT_MSG_EVENT: + case STATE_EMIT_QUEUED_MSG_EVENT: + case STATE_SKIP_PACKET_PADDING: + case STATE_EMIT_MSG_PACKET_END_MULTI: + case STATE_EMIT_MSG_PACKET_END_SINGLE: + case STATE_EMIT_QUEUED_MSG_PACKET_END: + case STATE_EMIT_MSG_STREAM_END: + break; + case STATE_DONE: + /* fall-through */ + default: + /* We should never get to the STATE_DONE state. */ + BT_COMP_LOGF("Unexpected state: msg-it-addr=%p, state=%s", msg_it, + state_string(msg_it->state)); + bt_common_abort(); + } + } while (true); end: - return status; + return status; } -static -enum ctf_msg_iter_status read_packet_header_context_fields( - struct ctf_msg_iter *msg_it) +static enum ctf_msg_iter_status read_packet_header_context_fields(struct ctf_msg_iter *msg_it) { - int ret; - enum ctf_msg_iter_status status = CTF_MSG_ITER_STATUS_OK; + int ret; + enum ctf_msg_iter_status status = CTF_MSG_ITER_STATUS_OK; - status = decode_until_state(msg_it, STATE_EMIT_MSG_PACKET_BEGINNING, (state) -1); - if (status != CTF_MSG_ITER_STATUS_OK) { - goto end; - } + status = decode_until_state(msg_it, STATE_EMIT_MSG_PACKET_BEGINNING, (state) -1); + if (status != CTF_MSG_ITER_STATUS_OK) { + goto end; + } - ret = set_current_packet_content_sizes(msg_it); - if (ret) { - status = CTF_MSG_ITER_STATUS_ERROR; - goto end; - } + ret = set_current_packet_content_sizes(msg_it); + if (ret) { + status = CTF_MSG_ITER_STATUS_ERROR; + goto end; + } end: - return status; + return status; } BT_HIDDEN -enum ctf_msg_iter_status ctf_msg_iter_seek(struct ctf_msg_iter *msg_it, - off_t offset) +enum ctf_msg_iter_status ctf_msg_iter_seek(struct ctf_msg_iter *msg_it, off_t offset) { - enum ctf_msg_iter_status status = CTF_MSG_ITER_STATUS_OK; - enum ctf_msg_iter_medium_status medium_status; + enum ctf_msg_iter_status status = CTF_MSG_ITER_STATUS_OK; + enum ctf_msg_iter_medium_status medium_status; - BT_ASSERT(msg_it); - BT_ASSERT(offset >= 0); - BT_ASSERT(msg_it->medium.medops.seek); + BT_ASSERT(msg_it); + BT_ASSERT(offset >= 0); + BT_ASSERT(msg_it->medium.medops.seek); - medium_status = msg_it->medium.medops.seek(offset, msg_it->medium.data); - if (medium_status != CTF_MSG_ITER_MEDIUM_STATUS_OK) { - if (medium_status == CTF_MSG_ITER_MEDIUM_STATUS_EOF) { - status = CTF_MSG_ITER_STATUS_EOF; - } else { - status = CTF_MSG_ITER_STATUS_ERROR; - goto end; - } - } + medium_status = msg_it->medium.medops.seek(offset, msg_it->medium.data); + if (medium_status != CTF_MSG_ITER_MEDIUM_STATUS_OK) { + if (medium_status == CTF_MSG_ITER_MEDIUM_STATUS_EOF) { + status = CTF_MSG_ITER_STATUS_EOF; + } else { + status = CTF_MSG_ITER_STATUS_ERROR; + goto end; + } + } - ctf_msg_iter_reset(msg_it); - msg_it->cur_packet_offset = offset; + ctf_msg_iter_reset(msg_it); + msg_it->cur_packet_offset = offset; end: - return status; + return status; } -static -enum ctf_msg_iter_status clock_snapshot_at_msg_iter_state( - struct ctf_msg_iter *msg_it, enum state target_state_1, - enum state target_state_2, uint64_t *clock_snapshot) +static enum ctf_msg_iter_status clock_snapshot_at_msg_iter_state(struct ctf_msg_iter *msg_it, + enum state target_state_1, + enum state target_state_2, + uint64_t *clock_snapshot) { - enum ctf_msg_iter_status status = CTF_MSG_ITER_STATUS_OK; + enum ctf_msg_iter_status status = CTF_MSG_ITER_STATUS_OK; - BT_ASSERT_DBG(msg_it); - BT_ASSERT_DBG(clock_snapshot); - status = decode_until_state(msg_it, target_state_1, target_state_2); - if (status != CTF_MSG_ITER_STATUS_OK) { - goto end; - } + BT_ASSERT_DBG(msg_it); + BT_ASSERT_DBG(clock_snapshot); + status = decode_until_state(msg_it, target_state_1, target_state_2); + if (status != CTF_MSG_ITER_STATUS_OK) { + goto end; + } - *clock_snapshot = msg_it->default_clock_snapshot; + *clock_snapshot = msg_it->default_clock_snapshot; end: - return status; + return status; } BT_HIDDEN -enum ctf_msg_iter_status ctf_msg_iter_curr_packet_first_event_clock_snapshot( - struct ctf_msg_iter *msg_it, uint64_t *first_clock_snapshot) +enum ctf_msg_iter_status +ctf_msg_iter_curr_packet_first_event_clock_snapshot(struct ctf_msg_iter *msg_it, + uint64_t *first_clock_snapshot) { - return clock_snapshot_at_msg_iter_state(msg_it, - STATE_AFTER_EVENT_HEADER, (state) -1, first_clock_snapshot); + return clock_snapshot_at_msg_iter_state(msg_it, STATE_AFTER_EVENT_HEADER, (state) -1, + first_clock_snapshot); } BT_HIDDEN -enum ctf_msg_iter_status ctf_msg_iter_curr_packet_last_event_clock_snapshot( - struct ctf_msg_iter *msg_it, uint64_t *last_clock_snapshot) +enum ctf_msg_iter_status +ctf_msg_iter_curr_packet_last_event_clock_snapshot(struct ctf_msg_iter *msg_it, + uint64_t *last_clock_snapshot) { - return clock_snapshot_at_msg_iter_state(msg_it, - STATE_EMIT_MSG_PACKET_END_SINGLE, - STATE_EMIT_MSG_PACKET_END_MULTI, last_clock_snapshot); + return clock_snapshot_at_msg_iter_state(msg_it, STATE_EMIT_MSG_PACKET_END_SINGLE, + STATE_EMIT_MSG_PACKET_END_MULTI, last_clock_snapshot); } BT_HIDDEN -enum ctf_msg_iter_status ctf_msg_iter_get_packet_properties( - struct ctf_msg_iter *msg_it, - struct ctf_msg_iter_packet_properties *props) -{ - enum ctf_msg_iter_status status; - - BT_ASSERT_DBG(msg_it); - BT_ASSERT_DBG(props); - status = read_packet_header_context_fields(msg_it); - if (status != CTF_MSG_ITER_STATUS_OK) { - goto end; - } - - props->exp_packet_total_size = msg_it->cur_exp_packet_total_size; - props->exp_packet_content_size = msg_it->cur_exp_packet_content_size; - props->stream_class_id = (uint64_t) msg_it->cur_stream_class_id; - props->data_stream_id = msg_it->cur_data_stream_id; - props->snapshots.discarded_events = msg_it->snapshots.discarded_events; - props->snapshots.packets = msg_it->snapshots.packets; - props->snapshots.beginning_clock = msg_it->snapshots.beginning_clock; - props->snapshots.end_clock = msg_it->snapshots.end_clock; +enum ctf_msg_iter_status +ctf_msg_iter_get_packet_properties(struct ctf_msg_iter *msg_it, + struct ctf_msg_iter_packet_properties *props) +{ + enum ctf_msg_iter_status status; + + BT_ASSERT_DBG(msg_it); + BT_ASSERT_DBG(props); + status = read_packet_header_context_fields(msg_it); + if (status != CTF_MSG_ITER_STATUS_OK) { + goto end; + } + + props->exp_packet_total_size = msg_it->cur_exp_packet_total_size; + props->exp_packet_content_size = msg_it->cur_exp_packet_content_size; + props->stream_class_id = (uint64_t) msg_it->cur_stream_class_id; + props->data_stream_id = msg_it->cur_data_stream_id; + props->snapshots.discarded_events = msg_it->snapshots.discarded_events; + props->snapshots.packets = msg_it->snapshots.packets; + props->snapshots.beginning_clock = msg_it->snapshots.beginning_clock; + props->snapshots.end_clock = msg_it->snapshots.end_clock; end: - return status; + return status; } BT_HIDDEN -void ctf_msg_iter_set_dry_run(struct ctf_msg_iter *msg_it, - bool val) +void ctf_msg_iter_set_dry_run(struct ctf_msg_iter *msg_it, bool val) { - msg_it->dry_run = val; + msg_it->dry_run = val; } diff --git a/src/plugins/ctf/common/msg-iter/msg-iter.hpp b/src/plugins/ctf/common/msg-iter/msg-iter.hpp index 393da16b..669cfe3d 100644 --- a/src/plugins/ctf/common/msg-iter/msg-iter.hpp +++ b/src/plugins/ctf/common/msg-iter/msg-iter.hpp @@ -32,61 +32,63 @@ * Medium operations status codes. These use the same values as * libbabeltrace2. */ -enum ctf_msg_iter_medium_status { - /** - * End of file. - * - * The medium function called by the message iterator - * function reached the end of the file. - */ - CTF_MSG_ITER_MEDIUM_STATUS_EOF = 1, - - /** - * There is no data available right now, try again later. - */ - CTF_MSG_ITER_MEDIUM_STATUS_AGAIN = 11, - - /** General error. */ - CTF_MSG_ITER_MEDIUM_STATUS_ERROR = -1, - - /** Memory error. */ - CTF_MSG_ITER_MEDIUM_STATUS_MEMORY_ERROR = -12, - - /** Everything okay. */ - CTF_MSG_ITER_MEDIUM_STATUS_OK = 0, +enum ctf_msg_iter_medium_status +{ + /** + * End of file. + * + * The medium function called by the message iterator + * function reached the end of the file. + */ + CTF_MSG_ITER_MEDIUM_STATUS_EOF = 1, + + /** + * There is no data available right now, try again later. + */ + CTF_MSG_ITER_MEDIUM_STATUS_AGAIN = 11, + + /** General error. */ + CTF_MSG_ITER_MEDIUM_STATUS_ERROR = -1, + + /** Memory error. */ + CTF_MSG_ITER_MEDIUM_STATUS_MEMORY_ERROR = -12, + + /** Everything okay. */ + CTF_MSG_ITER_MEDIUM_STATUS_OK = 0, }; /** * CTF message iterator API status code. */ -enum ctf_msg_iter_status { - /** - * End of file. - * - * The medium function called by the message iterator - * function reached the end of the file. - */ - CTF_MSG_ITER_STATUS_EOF = CTF_MSG_ITER_MEDIUM_STATUS_EOF, - - /** - * There is no data available right now, try again later. - * - * Some condition resulted in the - * ctf_msg_iter_medium_ops::request_bytes() user function not - * having access to any data now. You should retry calling the - * last called message iterator function once the situation - * is resolved. - */ - CTF_MSG_ITER_STATUS_AGAIN = CTF_MSG_ITER_MEDIUM_STATUS_AGAIN, - - /** General error. */ - CTF_MSG_ITER_STATUS_ERROR = CTF_MSG_ITER_MEDIUM_STATUS_ERROR, - - /** Memory error. */ - CTF_MSG_ITER_STATUS_MEMORY_ERROR = CTF_MSG_ITER_MEDIUM_STATUS_MEMORY_ERROR, - - /** Everything okay. */ - CTF_MSG_ITER_STATUS_OK = CTF_MSG_ITER_MEDIUM_STATUS_OK, +enum ctf_msg_iter_status +{ + /** + * End of file. + * + * The medium function called by the message iterator + * function reached the end of the file. + */ + CTF_MSG_ITER_STATUS_EOF = CTF_MSG_ITER_MEDIUM_STATUS_EOF, + + /** + * There is no data available right now, try again later. + * + * Some condition resulted in the + * ctf_msg_iter_medium_ops::request_bytes() user function not + * having access to any data now. You should retry calling the + * last called message iterator function once the situation + * is resolved. + */ + CTF_MSG_ITER_STATUS_AGAIN = CTF_MSG_ITER_MEDIUM_STATUS_AGAIN, + + /** General error. */ + CTF_MSG_ITER_STATUS_ERROR = CTF_MSG_ITER_MEDIUM_STATUS_ERROR, + + /** Memory error. */ + CTF_MSG_ITER_STATUS_MEMORY_ERROR = CTF_MSG_ITER_MEDIUM_STATUS_MEMORY_ERROR, + + /** Everything okay. */ + CTF_MSG_ITER_STATUS_OK = CTF_MSG_ITER_MEDIUM_STATUS_OK, }; /** @@ -95,114 +97,114 @@ enum ctf_msg_iter_status { * Those user functions are called by the message iterator * functions to request medium actions. */ -struct ctf_msg_iter_medium_ops { - /** - * Returns the next byte buffer to be used by the binary file - * reader to deserialize binary data. - * - * This function \em must be defined. - * - * The purpose of this function is to return a buffer of bytes - * to the message iterator, of a maximum of \p request_sz - * bytes. If this function cannot return a buffer of at least - * \p request_sz bytes, it may return a smaller buffer. In - * either cases, \p buffer_sz must be set to the returned buffer - * size (in bytes). - * - * The returned buffer's ownership remains the medium, in that - * it won't be freed by the message iterator functions. The - * returned buffer won't be modified by the message - * iterator functions either. - * - * When this function is called for the first time for a given - * file, the offset within the file is considered to be 0. The - * next times this function is called, the returned buffer's - * byte offset within the complete file must be the previous - * offset plus the last returned value of \p buffer_sz by this - * medium. - * - * This function must return one of the following statuses: - * - * - #CTF_MSG_ITER_MEDIUM_STATUS_OK: Everything - * is okay, i.e. \p buffer_sz is set to a positive value - * reflecting the number of available bytes in the buffer - * starting at the address written in \p buffer_addr. - * - #CTF_MSG_ITER_MEDIUM_STATUS_AGAIN: No data is - * available right now. In this case, the message - * iterator function called by the user returns - * #CTF_MSG_ITER_STATUS_AGAIN, and it is the user's - * responsibility to make sure enough data becomes available - * before calling the \em same message iterator - * function again to continue the decoding process. - * - #CTF_MSG_ITER_MEDIUM_STATUS_EOF: The end of - * the file was reached, and no more data will ever be - * available for this file. In this case, the message - * iterator function called by the user returns - * #CTF_MSG_ITER_STATUS_EOF. This must \em not be - * returned when returning at least one byte of data to the - * caller, i.e. this must be returned when there's - * absolutely nothing left; should the request size be - * larger than what's left in the file, this function must - * return what's left, setting \p buffer_sz to the number of - * remaining bytes, and return - * #CTF_MSG_ITER_MEDIUM_STATUS_EOF on the \em following - * call. - * - #CTF_MSG_ITER_MEDIUM_STATUS_ERROR: A fatal - * error occurred during this operation. In this case, the - * message iterator function called by the user returns - * #CTF_MSG_ITER_STATUS_ERROR. - * - * If #CTF_MSG_ITER_MEDIUM_STATUS_OK is not returned, the - * values of \p buffer_sz and \p buffer_addr are \em ignored by - * the caller. - * - * @param request_sz Requested buffer size (bytes) - * @param buffer_addr Returned buffer address - * @param buffer_sz Returned buffer's size (bytes) - * @param data User data - * @returns Status code (see description above) - */ - enum ctf_msg_iter_medium_status (* request_bytes)(size_t request_sz, - uint8_t **buffer_addr, size_t *buffer_sz, void *data); - - /** - * Repositions the underlying stream's position. - * - * This *optional* method repositions the underlying stream - * to a given absolute position in the medium. - * - * @param offset Offset to use for the given directive - * @param data User data - * @returns One of #ctf_msg_iter_medium_status values - */ - enum ctf_msg_iter_medium_status (* seek)(off_t offset, void *data); - - /** - * Called when the message iterator wishes to inform the medium that it - * is about to start a new packet. - * - * After the iterator has called switch_packet, the following call to - * request_bytes must return the content at the start of the next - * packet. */ - enum ctf_msg_iter_medium_status (* switch_packet)(void *data); - - /** - * Returns a stream instance (weak reference) for the given - * stream class. - * - * This is called after a packet header is read, and the - * corresponding stream class is found by the message - * iterator. - * - * @param stream_class Stream class of the stream to get - * @param stream_id Stream (instance) ID of the stream - * to get (-1ULL if not available) - * @param data User data - * @returns Stream instance (weak reference) or - * \c NULL on error - */ - bt_stream * (* borrow_stream)(bt_stream_class *stream_class, - int64_t stream_id, void *data); +struct ctf_msg_iter_medium_ops +{ + /** + * Returns the next byte buffer to be used by the binary file + * reader to deserialize binary data. + * + * This function \em must be defined. + * + * The purpose of this function is to return a buffer of bytes + * to the message iterator, of a maximum of \p request_sz + * bytes. If this function cannot return a buffer of at least + * \p request_sz bytes, it may return a smaller buffer. In + * either cases, \p buffer_sz must be set to the returned buffer + * size (in bytes). + * + * The returned buffer's ownership remains the medium, in that + * it won't be freed by the message iterator functions. The + * returned buffer won't be modified by the message + * iterator functions either. + * + * When this function is called for the first time for a given + * file, the offset within the file is considered to be 0. The + * next times this function is called, the returned buffer's + * byte offset within the complete file must be the previous + * offset plus the last returned value of \p buffer_sz by this + * medium. + * + * This function must return one of the following statuses: + * + * - #CTF_MSG_ITER_MEDIUM_STATUS_OK: Everything + * is okay, i.e. \p buffer_sz is set to a positive value + * reflecting the number of available bytes in the buffer + * starting at the address written in \p buffer_addr. + * - #CTF_MSG_ITER_MEDIUM_STATUS_AGAIN: No data is + * available right now. In this case, the message + * iterator function called by the user returns + * #CTF_MSG_ITER_STATUS_AGAIN, and it is the user's + * responsibility to make sure enough data becomes available + * before calling the \em same message iterator + * function again to continue the decoding process. + * - #CTF_MSG_ITER_MEDIUM_STATUS_EOF: The end of + * the file was reached, and no more data will ever be + * available for this file. In this case, the message + * iterator function called by the user returns + * #CTF_MSG_ITER_STATUS_EOF. This must \em not be + * returned when returning at least one byte of data to the + * caller, i.e. this must be returned when there's + * absolutely nothing left; should the request size be + * larger than what's left in the file, this function must + * return what's left, setting \p buffer_sz to the number of + * remaining bytes, and return + * #CTF_MSG_ITER_MEDIUM_STATUS_EOF on the \em following + * call. + * - #CTF_MSG_ITER_MEDIUM_STATUS_ERROR: A fatal + * error occurred during this operation. In this case, the + * message iterator function called by the user returns + * #CTF_MSG_ITER_STATUS_ERROR. + * + * If #CTF_MSG_ITER_MEDIUM_STATUS_OK is not returned, the + * values of \p buffer_sz and \p buffer_addr are \em ignored by + * the caller. + * + * @param request_sz Requested buffer size (bytes) + * @param buffer_addr Returned buffer address + * @param buffer_sz Returned buffer's size (bytes) + * @param data User data + * @returns Status code (see description above) + */ + enum ctf_msg_iter_medium_status (*request_bytes)(size_t request_sz, uint8_t **buffer_addr, + size_t *buffer_sz, void *data); + + /** + * Repositions the underlying stream's position. + * + * This *optional* method repositions the underlying stream + * to a given absolute position in the medium. + * + * @param offset Offset to use for the given directive + * @param data User data + * @returns One of #ctf_msg_iter_medium_status values + */ + enum ctf_msg_iter_medium_status (*seek)(off_t offset, void *data); + + /** + * Called when the message iterator wishes to inform the medium that it + * is about to start a new packet. + * + * After the iterator has called switch_packet, the following call to + * request_bytes must return the content at the start of the next + * packet. */ + enum ctf_msg_iter_medium_status (*switch_packet)(void *data); + + /** + * Returns a stream instance (weak reference) for the given + * stream class. + * + * This is called after a packet header is read, and the + * corresponding stream class is found by the message + * iterator. + * + * @param stream_class Stream class of the stream to get + * @param stream_id Stream (instance) ID of the stream + * to get (-1ULL if not available) + * @param data User data + * @returns Stream instance (weak reference) or + * \c NULL on error + */ + bt_stream *(*borrow_stream)(bt_stream_class *stream_class, int64_t stream_id, void *data); }; /** CTF message iterator. */ @@ -225,14 +227,10 @@ struct ctf_msg_iter; * success, or \c NULL on error */ BT_HIDDEN -struct ctf_msg_iter *ctf_msg_iter_create( - struct ctf_trace_class *tc, - size_t max_request_sz, - struct ctf_msg_iter_medium_ops medops, - void *medops_data, - bt_logging_level log_level, - bt_self_component *self_comp, - bt_self_message_iterator *self_msg_iter); +struct ctf_msg_iter *ctf_msg_iter_create(struct ctf_trace_class *tc, size_t max_request_sz, + struct ctf_msg_iter_medium_ops medops, void *medops_data, + bt_logging_level log_level, bt_self_component *self_comp, + bt_self_message_iterator *self_msg_iter); /** * Destroys a CTF message iterator, freeing all internal resources. @@ -262,40 +260,42 @@ void ctf_msg_iter_destroy(struct ctf_msg_iter *msg_iter); * @returns One of #ctf_msg_iter_status values */ BT_HIDDEN -enum ctf_msg_iter_status ctf_msg_iter_get_next_message( - struct ctf_msg_iter *msg_it, - const bt_message **message); - -struct ctf_msg_iter_packet_properties { - int64_t exp_packet_total_size; - int64_t exp_packet_content_size; - uint64_t stream_class_id; - int64_t data_stream_id; - - struct { - uint64_t discarded_events; - uint64_t packets; - uint64_t beginning_clock; - uint64_t end_clock; - } snapshots; +enum ctf_msg_iter_status ctf_msg_iter_get_next_message(struct ctf_msg_iter *msg_it, + const bt_message **message); + +struct ctf_msg_iter_packet_properties +{ + int64_t exp_packet_total_size; + int64_t exp_packet_content_size; + uint64_t stream_class_id; + int64_t data_stream_id; + + struct + { + uint64_t discarded_events; + uint64_t packets; + uint64_t beginning_clock; + uint64_t end_clock; + } snapshots; }; BT_HIDDEN -enum ctf_msg_iter_status ctf_msg_iter_get_packet_properties( - struct ctf_msg_iter *msg_it, - struct ctf_msg_iter_packet_properties *props); +enum ctf_msg_iter_status +ctf_msg_iter_get_packet_properties(struct ctf_msg_iter *msg_it, + struct ctf_msg_iter_packet_properties *props); BT_HIDDEN -enum ctf_msg_iter_status ctf_msg_iter_curr_packet_first_event_clock_snapshot( - struct ctf_msg_iter *msg_it, uint64_t *first_event_cs); +enum ctf_msg_iter_status +ctf_msg_iter_curr_packet_first_event_clock_snapshot(struct ctf_msg_iter *msg_it, + uint64_t *first_event_cs); BT_HIDDEN -enum ctf_msg_iter_status ctf_msg_iter_curr_packet_last_event_clock_snapshot( - struct ctf_msg_iter *msg_it, uint64_t *last_event_cs); +enum ctf_msg_iter_status +ctf_msg_iter_curr_packet_last_event_clock_snapshot(struct ctf_msg_iter *msg_it, + uint64_t *last_event_cs); BT_HIDDEN -enum ctf_msg_iter_status ctf_msg_iter_seek( - struct ctf_msg_iter *msg_it, off_t offset); +enum ctf_msg_iter_status ctf_msg_iter_seek(struct ctf_msg_iter *msg_it, off_t offset); /* * Resets the iterator so that the next requested medium bytes are @@ -314,47 +314,42 @@ BT_HIDDEN void ctf_msg_iter_reset_for_next_stream_file(struct ctf_msg_iter *msg_it); BT_HIDDEN -void ctf_msg_iter_set_dry_run(struct ctf_msg_iter *msg_it, - bool val); +void ctf_msg_iter_set_dry_run(struct ctf_msg_iter *msg_it, bool val); -static inline -const char *ctf_msg_iter_medium_status_string( - enum ctf_msg_iter_medium_status status) +static inline const char *ctf_msg_iter_medium_status_string(enum ctf_msg_iter_medium_status status) { - switch (status) { - case CTF_MSG_ITER_MEDIUM_STATUS_EOF: - return "EOF"; - case CTF_MSG_ITER_MEDIUM_STATUS_AGAIN: - return "AGAIN"; - case CTF_MSG_ITER_MEDIUM_STATUS_ERROR: - return "ERROR"; - case CTF_MSG_ITER_MEDIUM_STATUS_MEMORY_ERROR: - return "MEMORY_ERROR"; - case CTF_MSG_ITER_MEDIUM_STATUS_OK: - return "OK"; - } - - bt_common_abort(); + switch (status) { + case CTF_MSG_ITER_MEDIUM_STATUS_EOF: + return "EOF"; + case CTF_MSG_ITER_MEDIUM_STATUS_AGAIN: + return "AGAIN"; + case CTF_MSG_ITER_MEDIUM_STATUS_ERROR: + return "ERROR"; + case CTF_MSG_ITER_MEDIUM_STATUS_MEMORY_ERROR: + return "MEMORY_ERROR"; + case CTF_MSG_ITER_MEDIUM_STATUS_OK: + return "OK"; + } + + bt_common_abort(); } -static inline -const char *ctf_msg_iter_status_string( - enum ctf_msg_iter_status status) +static inline const char *ctf_msg_iter_status_string(enum ctf_msg_iter_status status) { - switch (status) { - case CTF_MSG_ITER_STATUS_EOF: - return "EOF"; - case CTF_MSG_ITER_STATUS_AGAIN: - return "AGAIN"; - case CTF_MSG_ITER_STATUS_ERROR: - return "ERROR"; - case CTF_MSG_ITER_STATUS_MEMORY_ERROR: - return "MEMORY_ERROR"; - case CTF_MSG_ITER_STATUS_OK: - return "OK"; - } - - bt_common_abort(); + switch (status) { + case CTF_MSG_ITER_STATUS_EOF: + return "EOF"; + case CTF_MSG_ITER_STATUS_AGAIN: + return "AGAIN"; + case CTF_MSG_ITER_STATUS_ERROR: + return "ERROR"; + case CTF_MSG_ITER_STATUS_MEMORY_ERROR: + return "MEMORY_ERROR"; + case CTF_MSG_ITER_STATUS_OK: + return "OK"; + } + + bt_common_abort(); } #endif /* CTF_MSG_ITER_H */ diff --git a/src/plugins/ctf/common/print.hpp b/src/plugins/ctf/common/print.hpp index a2f744e5..90c8d409 100644 --- a/src/plugins/ctf/common/print.hpp +++ b/src/plugins/ctf/common/print.hpp @@ -12,31 +12,25 @@ #include #include "common/macros.h" -#define PERR(fmt, ...) \ - do { \ - if (PRINT_ERR_STREAM) { \ - fprintf(PRINT_ERR_STREAM, \ - "Error: " PRINT_PREFIX ": " fmt, \ - ##__VA_ARGS__); \ - } \ - } while (0) +#define PERR(fmt, ...) \ + do { \ + if (PRINT_ERR_STREAM) { \ + fprintf(PRINT_ERR_STREAM, "Error: " PRINT_PREFIX ": " fmt, ##__VA_ARGS__); \ + } \ + } while (0) -#define PWARN(fmt, ...) \ - do { \ - if (PRINT_ERR_STREAM) { \ - fprintf(PRINT_ERR_STREAM, \ - "Warning: " PRINT_PREFIX ": " fmt, \ - ##__VA_ARGS__); \ - } \ - } while (0) +#define PWARN(fmt, ...) \ + do { \ + if (PRINT_ERR_STREAM) { \ + fprintf(PRINT_ERR_STREAM, "Warning: " PRINT_PREFIX ": " fmt, ##__VA_ARGS__); \ + } \ + } while (0) -#define PDBG(fmt, ...) \ - do { \ - if (babeltrace_debug) { \ - fprintf(stderr, \ - "Debug: " PRINT_PREFIX ": " fmt, \ - ##__VA_ARGS__); \ - } \ - } while (0) +#define PDBG(fmt, ...) \ + do { \ + if (babeltrace_debug) { \ + fprintf(stderr, "Debug: " PRINT_PREFIX ": " fmt, ##__VA_ARGS__); \ + } \ + } while (0) #endif /* CTF_BTR_PRINT_H */ diff --git a/src/plugins/ctf/fs-sink/fs-sink-ctf-meta.hpp b/src/plugins/ctf/fs-sink/fs-sink-ctf-meta.hpp index 8e30ab90..e56ab526 100644 --- a/src/plugins/ctf/fs-sink/fs-sink-ctf-meta.hpp +++ b/src/plugins/ctf/fs-sink/fs-sink-ctf-meta.hpp @@ -17,1027 +17,935 @@ #include #include -enum fs_sink_ctf_field_class_type { - FS_SINK_CTF_FIELD_CLASS_TYPE_BOOL, - FS_SINK_CTF_FIELD_CLASS_TYPE_BIT_ARRAY, - FS_SINK_CTF_FIELD_CLASS_TYPE_INT, - FS_SINK_CTF_FIELD_CLASS_TYPE_FLOAT, - FS_SINK_CTF_FIELD_CLASS_TYPE_STRING, - FS_SINK_CTF_FIELD_CLASS_TYPE_STRUCT, - FS_SINK_CTF_FIELD_CLASS_TYPE_ARRAY, - FS_SINK_CTF_FIELD_CLASS_TYPE_SEQUENCE, - FS_SINK_CTF_FIELD_CLASS_TYPE_OPTION, - FS_SINK_CTF_FIELD_CLASS_TYPE_VARIANT, +enum fs_sink_ctf_field_class_type +{ + FS_SINK_CTF_FIELD_CLASS_TYPE_BOOL, + FS_SINK_CTF_FIELD_CLASS_TYPE_BIT_ARRAY, + FS_SINK_CTF_FIELD_CLASS_TYPE_INT, + FS_SINK_CTF_FIELD_CLASS_TYPE_FLOAT, + FS_SINK_CTF_FIELD_CLASS_TYPE_STRING, + FS_SINK_CTF_FIELD_CLASS_TYPE_STRUCT, + FS_SINK_CTF_FIELD_CLASS_TYPE_ARRAY, + FS_SINK_CTF_FIELD_CLASS_TYPE_SEQUENCE, + FS_SINK_CTF_FIELD_CLASS_TYPE_OPTION, + FS_SINK_CTF_FIELD_CLASS_TYPE_VARIANT, }; -struct fs_sink_ctf_field_class { - enum fs_sink_ctf_field_class_type type; +struct fs_sink_ctf_field_class +{ + enum fs_sink_ctf_field_class_type type; - /* Weak */ - const bt_field_class *ir_fc; + /* Weak */ + const bt_field_class *ir_fc; - unsigned int alignment; + unsigned int alignment; - /* Index of the field class within its own parent */ - uint64_t index_in_parent; + /* Index of the field class within its own parent */ + uint64_t index_in_parent; }; -struct fs_sink_ctf_field_class_bit_array { - struct fs_sink_ctf_field_class base; - unsigned int size; +struct fs_sink_ctf_field_class_bit_array +{ + struct fs_sink_ctf_field_class base; + unsigned int size; }; -struct fs_sink_ctf_field_class_bool { - struct fs_sink_ctf_field_class_bit_array base; +struct fs_sink_ctf_field_class_bool +{ + struct fs_sink_ctf_field_class_bit_array base; }; -struct fs_sink_ctf_field_class_int { - struct fs_sink_ctf_field_class_bit_array base; - bool is_signed; +struct fs_sink_ctf_field_class_int +{ + struct fs_sink_ctf_field_class_bit_array base; + bool is_signed; }; -struct fs_sink_ctf_field_class_float { - struct fs_sink_ctf_field_class_bit_array base; +struct fs_sink_ctf_field_class_float +{ + struct fs_sink_ctf_field_class_bit_array base; }; -struct fs_sink_ctf_field_class_string { - struct fs_sink_ctf_field_class base; +struct fs_sink_ctf_field_class_string +{ + struct fs_sink_ctf_field_class base; }; -struct fs_sink_ctf_named_field_class { - GString *name; +struct fs_sink_ctf_named_field_class +{ + GString *name; - /* Owned by this */ - struct fs_sink_ctf_field_class *fc; + /* Owned by this */ + struct fs_sink_ctf_field_class *fc; }; -struct fs_sink_ctf_field_class_struct { - struct fs_sink_ctf_field_class base; +struct fs_sink_ctf_field_class_struct +{ + struct fs_sink_ctf_field_class base; - /* Array of `struct fs_sink_ctf_named_field_class` */ - GArray *members; + /* Array of `struct fs_sink_ctf_named_field_class` */ + GArray *members; }; -struct fs_sink_ctf_field_class_option { - struct fs_sink_ctf_field_class base; - struct fs_sink_ctf_field_class *content_fc; - GString *tag_ref; +struct fs_sink_ctf_field_class_option +{ + struct fs_sink_ctf_field_class base; + struct fs_sink_ctf_field_class *content_fc; + GString *tag_ref; }; -struct fs_sink_ctf_field_class_variant { - struct fs_sink_ctf_field_class base; - GString *tag_ref; - bool tag_is_before; +struct fs_sink_ctf_field_class_variant +{ + struct fs_sink_ctf_field_class base; + GString *tag_ref; + bool tag_is_before; - /* Array of `struct fs_sink_ctf_named_field_class` */ - GArray *options; + /* Array of `struct fs_sink_ctf_named_field_class` */ + GArray *options; }; -struct fs_sink_ctf_field_class_array_base { - struct fs_sink_ctf_field_class base; - struct fs_sink_ctf_field_class *elem_fc; +struct fs_sink_ctf_field_class_array_base +{ + struct fs_sink_ctf_field_class base; + struct fs_sink_ctf_field_class *elem_fc; }; -struct fs_sink_ctf_field_class_array { - struct fs_sink_ctf_field_class_array_base base; - uint64_t length; +struct fs_sink_ctf_field_class_array +{ + struct fs_sink_ctf_field_class_array_base base; + uint64_t length; }; -struct fs_sink_ctf_field_class_sequence { - struct fs_sink_ctf_field_class_array_base base; - GString *length_ref; - bool length_is_before; +struct fs_sink_ctf_field_class_sequence +{ + struct fs_sink_ctf_field_class_array_base base; + GString *length_ref; + bool length_is_before; }; -static inline -fs_sink_ctf_field_class_bit_array *fs_sink_ctf_field_class_as_bit_array( - fs_sink_ctf_field_class *fc) +static inline fs_sink_ctf_field_class_bit_array * +fs_sink_ctf_field_class_as_bit_array(fs_sink_ctf_field_class *fc) { - BT_ASSERT_DBG(!fc || (fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_BIT_ARRAY || - fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_INT || - fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_BOOL || - fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_FLOAT)); + BT_ASSERT_DBG(!fc || (fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_BIT_ARRAY || + fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_INT || + fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_BOOL || + fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_FLOAT)); - return (fs_sink_ctf_field_class_bit_array *) fc; + return (fs_sink_ctf_field_class_bit_array *) fc; } -static inline -fs_sink_ctf_field_class_bool *fs_sink_ctf_field_class_as_bool( - fs_sink_ctf_field_class *fc) +static inline fs_sink_ctf_field_class_bool * +fs_sink_ctf_field_class_as_bool(fs_sink_ctf_field_class *fc) { - BT_ASSERT_DBG(!fc || fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_BOOL); + BT_ASSERT_DBG(!fc || fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_BOOL); - return (fs_sink_ctf_field_class_bool *) fc; + return (fs_sink_ctf_field_class_bool *) fc; } -static inline -fs_sink_ctf_field_class_int *fs_sink_ctf_field_class_as_int( - fs_sink_ctf_field_class *fc) +static inline fs_sink_ctf_field_class_int * +fs_sink_ctf_field_class_as_int(fs_sink_ctf_field_class *fc) { - BT_ASSERT_DBG(!fc || fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_INT); + BT_ASSERT_DBG(!fc || fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_INT); - return (fs_sink_ctf_field_class_int *) fc; + return (fs_sink_ctf_field_class_int *) fc; } -static inline -fs_sink_ctf_field_class_float *fs_sink_ctf_field_class_as_float( - fs_sink_ctf_field_class *fc) +static inline fs_sink_ctf_field_class_float * +fs_sink_ctf_field_class_as_float(fs_sink_ctf_field_class *fc) { - BT_ASSERT_DBG(!fc || fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_FLOAT); + BT_ASSERT_DBG(!fc || fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_FLOAT); - return (fs_sink_ctf_field_class_float *) fc; + return (fs_sink_ctf_field_class_float *) fc; } -static inline -fs_sink_ctf_field_class_string *fs_sink_ctf_field_class_as_string( - fs_sink_ctf_field_class *fc) +static inline fs_sink_ctf_field_class_string * +fs_sink_ctf_field_class_as_string(fs_sink_ctf_field_class *fc) { - BT_ASSERT_DBG(!fc || fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_STRING); + BT_ASSERT_DBG(!fc || fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_STRING); - return (fs_sink_ctf_field_class_string *) fc; + return (fs_sink_ctf_field_class_string *) fc; } -static inline -fs_sink_ctf_field_class_struct *fs_sink_ctf_field_class_as_struct( - fs_sink_ctf_field_class *fc) +static inline fs_sink_ctf_field_class_struct * +fs_sink_ctf_field_class_as_struct(fs_sink_ctf_field_class *fc) { - BT_ASSERT_DBG(!fc || fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_STRUCT); + BT_ASSERT_DBG(!fc || fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_STRUCT); - return (fs_sink_ctf_field_class_struct *) fc; + return (fs_sink_ctf_field_class_struct *) fc; } -static inline -fs_sink_ctf_field_class_array_base *fs_sink_ctf_field_class_as_array_base( - fs_sink_ctf_field_class *fc) +static inline fs_sink_ctf_field_class_array_base * +fs_sink_ctf_field_class_as_array_base(fs_sink_ctf_field_class *fc) { - BT_ASSERT_DBG(!fc || (fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_ARRAY || - fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_SEQUENCE)); + BT_ASSERT_DBG(!fc || (fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_ARRAY || + fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_SEQUENCE)); - return (fs_sink_ctf_field_class_array_base *) fc; + return (fs_sink_ctf_field_class_array_base *) fc; } -static inline -fs_sink_ctf_field_class_array *fs_sink_ctf_field_class_as_array( - fs_sink_ctf_field_class *fc) +static inline fs_sink_ctf_field_class_array * +fs_sink_ctf_field_class_as_array(fs_sink_ctf_field_class *fc) { - BT_ASSERT_DBG(!fc || fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_ARRAY); + BT_ASSERT_DBG(!fc || fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_ARRAY); - return (fs_sink_ctf_field_class_array *) fc; + return (fs_sink_ctf_field_class_array *) fc; } -static inline -fs_sink_ctf_field_class_sequence *fs_sink_ctf_field_class_as_sequence( - fs_sink_ctf_field_class *fc) +static inline fs_sink_ctf_field_class_sequence * +fs_sink_ctf_field_class_as_sequence(fs_sink_ctf_field_class *fc) { - BT_ASSERT_DBG(!fc || fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_SEQUENCE); + BT_ASSERT_DBG(!fc || fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_SEQUENCE); - return (fs_sink_ctf_field_class_sequence *) fc; + return (fs_sink_ctf_field_class_sequence *) fc; } -static inline -fs_sink_ctf_field_class_option *fs_sink_ctf_field_class_as_option( - fs_sink_ctf_field_class *fc) +static inline fs_sink_ctf_field_class_option * +fs_sink_ctf_field_class_as_option(fs_sink_ctf_field_class *fc) { - BT_ASSERT_DBG(!fc || fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_OPTION); + BT_ASSERT_DBG(!fc || fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_OPTION); - return (fs_sink_ctf_field_class_option *) fc; + return (fs_sink_ctf_field_class_option *) fc; } -static inline -fs_sink_ctf_field_class_variant *fs_sink_ctf_field_class_as_variant( - fs_sink_ctf_field_class *fc) +static inline fs_sink_ctf_field_class_variant * +fs_sink_ctf_field_class_as_variant(fs_sink_ctf_field_class *fc) { - BT_ASSERT_DBG(!fc || fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_VARIANT); + BT_ASSERT_DBG(!fc || fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_VARIANT); - return (fs_sink_ctf_field_class_variant *) fc; + return (fs_sink_ctf_field_class_variant *) fc; } struct fs_sink_ctf_stream_class; -struct fs_sink_ctf_event_class { - /* Weak */ - const bt_event_class *ir_ec; +struct fs_sink_ctf_event_class +{ + /* Weak */ + const bt_event_class *ir_ec; - /* Weak */ - struct fs_sink_ctf_stream_class *sc; + /* Weak */ + struct fs_sink_ctf_stream_class *sc; - /* Owned by this */ - struct fs_sink_ctf_field_class *spec_context_fc; + /* Owned by this */ + struct fs_sink_ctf_field_class *spec_context_fc; - /* Owned by this */ - struct fs_sink_ctf_field_class *payload_fc; + /* Owned by this */ + struct fs_sink_ctf_field_class *payload_fc; }; struct fs_sink_ctf_trace; -struct fs_sink_ctf_stream_class { - /* Weak */ - struct fs_sink_ctf_trace *trace; +struct fs_sink_ctf_stream_class +{ + /* Weak */ + struct fs_sink_ctf_trace *trace; - /* Weak */ - const bt_stream_class *ir_sc; + /* Weak */ + const bt_stream_class *ir_sc; - /* Weak */ - const bt_clock_class *default_clock_class; + /* Weak */ + const bt_clock_class *default_clock_class; - GString *default_clock_class_name; - bool has_packets; - bool packets_have_ts_begin; - bool packets_have_ts_end; - bool has_discarded_events; - bool discarded_events_has_ts; - bool discarded_packets_has_ts; + GString *default_clock_class_name; + bool has_packets; + bool packets_have_ts_begin; + bool packets_have_ts_end; + bool has_discarded_events; + bool discarded_events_has_ts; + bool discarded_packets_has_ts; - /* Owned by this */ - struct fs_sink_ctf_field_class *packet_context_fc; + /* Owned by this */ + struct fs_sink_ctf_field_class *packet_context_fc; - /* Owned by this */ - struct fs_sink_ctf_field_class *event_common_context_fc; + /* Owned by this */ + struct fs_sink_ctf_field_class *event_common_context_fc; - /* Array of `struct fs_sink_ctf_event_class *` (owned by this) */ - GPtrArray *event_classes; + /* Array of `struct fs_sink_ctf_event_class *` (owned by this) */ + GPtrArray *event_classes; - /* - * `const bt_event_class *` (weak) -> - * `struct fs_sink_ctf_event_class *` (weak) - */ - GHashTable *event_classes_from_ir; + /* + * `const bt_event_class *` (weak) -> + * `struct fs_sink_ctf_event_class *` (weak) + */ + GHashTable *event_classes_from_ir; }; -struct fs_sink_ctf_trace { - /* Weak */ - const bt_trace *ir_trace; +struct fs_sink_ctf_trace +{ + /* Weak */ + const bt_trace *ir_trace; - /* Weak */ - const bt_trace_class *ir_tc; + /* Weak */ + const bt_trace_class *ir_tc; - bt_uuid_t uuid; + bt_uuid_t uuid; - /* Array of `struct fs_sink_ctf_stream_class *` (owned by this) */ - GPtrArray *stream_classes; + /* Array of `struct fs_sink_ctf_stream_class *` (owned by this) */ + GPtrArray *stream_classes; }; -static inline -void fs_sink_ctf_field_class_destroy(struct fs_sink_ctf_field_class *fc); +static inline void fs_sink_ctf_field_class_destroy(struct fs_sink_ctf_field_class *fc); -static inline -void _fs_sink_ctf_field_class_init(struct fs_sink_ctf_field_class *fc, - enum fs_sink_ctf_field_class_type type, - const bt_field_class *ir_fc, unsigned int alignment, - uint64_t index_in_parent) +static inline void _fs_sink_ctf_field_class_init(struct fs_sink_ctf_field_class *fc, + enum fs_sink_ctf_field_class_type type, + const bt_field_class *ir_fc, + unsigned int alignment, uint64_t index_in_parent) { - BT_ASSERT(fc); - fc->type = type; - fc->ir_fc = ir_fc; - fc->alignment = alignment; - fc->index_in_parent = index_in_parent; + BT_ASSERT(fc); + fc->type = type; + fc->ir_fc = ir_fc; + fc->alignment = alignment; + fc->index_in_parent = index_in_parent; } -static inline -void _fs_sink_ctf_field_class_bit_array_init( - struct fs_sink_ctf_field_class_bit_array *fc, - enum fs_sink_ctf_field_class_type type, - const bt_field_class *ir_fc, unsigned int size, - uint64_t index_in_parent) +static inline void _fs_sink_ctf_field_class_bit_array_init( + struct fs_sink_ctf_field_class_bit_array *fc, enum fs_sink_ctf_field_class_type type, + const bt_field_class *ir_fc, unsigned int size, uint64_t index_in_parent) { - _fs_sink_ctf_field_class_init(&fc->base, type, ir_fc, - size % 8 == 0 ? 8 : 1, index_in_parent); - fc->size = size; + _fs_sink_ctf_field_class_init(&fc->base, type, ir_fc, size % 8 == 0 ? 8 : 1, index_in_parent); + fc->size = size; } -static inline -void _fs_sink_ctf_field_class_int_init(struct fs_sink_ctf_field_class_int *fc, - enum fs_sink_ctf_field_class_type type, - const bt_field_class *ir_fc, uint64_t index_in_parent) +static inline void _fs_sink_ctf_field_class_int_init(struct fs_sink_ctf_field_class_int *fc, + enum fs_sink_ctf_field_class_type type, + const bt_field_class *ir_fc, + uint64_t index_in_parent) { - bt_field_class_type ir_fc_type = bt_field_class_get_type(ir_fc); + bt_field_class_type ir_fc_type = bt_field_class_get_type(ir_fc); - _fs_sink_ctf_field_class_bit_array_init(&fc->base, type, ir_fc, - (unsigned int) bt_field_class_integer_get_field_value_range( - ir_fc), - index_in_parent); - fc->is_signed = bt_field_class_type_is(ir_fc_type, - BT_FIELD_CLASS_TYPE_SIGNED_INTEGER); + _fs_sink_ctf_field_class_bit_array_init( + &fc->base, type, ir_fc, (unsigned int) bt_field_class_integer_get_field_value_range(ir_fc), + index_in_parent); + fc->is_signed = bt_field_class_type_is(ir_fc_type, BT_FIELD_CLASS_TYPE_SIGNED_INTEGER); } -static inline -void _fs_sink_ctf_named_field_class_init( - struct fs_sink_ctf_named_field_class *named_fc) +static inline void +_fs_sink_ctf_named_field_class_init(struct fs_sink_ctf_named_field_class *named_fc) { - BT_ASSERT(named_fc); - named_fc->name = g_string_new(NULL); - BT_ASSERT(named_fc->name); + BT_ASSERT(named_fc); + named_fc->name = g_string_new(NULL); + BT_ASSERT(named_fc->name); } -static inline -void _fs_sink_ctf_named_field_class_fini( - struct fs_sink_ctf_named_field_class *named_fc) +static inline void +_fs_sink_ctf_named_field_class_fini(struct fs_sink_ctf_named_field_class *named_fc) { - BT_ASSERT(named_fc); + BT_ASSERT(named_fc); - if (named_fc->name) { - g_string_free(named_fc->name, TRUE); - named_fc->name = NULL; - } + if (named_fc->name) { + g_string_free(named_fc->name, TRUE); + named_fc->name = NULL; + } - fs_sink_ctf_field_class_destroy(named_fc->fc); - named_fc->fc = NULL; + fs_sink_ctf_field_class_destroy(named_fc->fc); + named_fc->fc = NULL; } -static inline -struct fs_sink_ctf_field_class_bit_array * -fs_sink_ctf_field_class_bit_array_create( - const bt_field_class *ir_fc, uint64_t index_in_parent) +static inline struct fs_sink_ctf_field_class_bit_array * +fs_sink_ctf_field_class_bit_array_create(const bt_field_class *ir_fc, uint64_t index_in_parent) { - struct fs_sink_ctf_field_class_bit_array *fc = - g_new0(struct fs_sink_ctf_field_class_bit_array, 1); + struct fs_sink_ctf_field_class_bit_array *fc = + g_new0(struct fs_sink_ctf_field_class_bit_array, 1); - BT_ASSERT(fc); - _fs_sink_ctf_field_class_bit_array_init(fc, - FS_SINK_CTF_FIELD_CLASS_TYPE_BIT_ARRAY, ir_fc, - (unsigned int) bt_field_class_bit_array_get_length(ir_fc), - index_in_parent); - return fc; + BT_ASSERT(fc); + _fs_sink_ctf_field_class_bit_array_init( + fc, FS_SINK_CTF_FIELD_CLASS_TYPE_BIT_ARRAY, ir_fc, + (unsigned int) bt_field_class_bit_array_get_length(ir_fc), index_in_parent); + return fc; } -static inline -struct fs_sink_ctf_field_class_bool *fs_sink_ctf_field_class_bool_create( - const bt_field_class *ir_fc, uint64_t index_in_parent) +static inline struct fs_sink_ctf_field_class_bool * +fs_sink_ctf_field_class_bool_create(const bt_field_class *ir_fc, uint64_t index_in_parent) { - struct fs_sink_ctf_field_class_bool *fc = - g_new0(struct fs_sink_ctf_field_class_bool, 1); + struct fs_sink_ctf_field_class_bool *fc = g_new0(struct fs_sink_ctf_field_class_bool, 1); - BT_ASSERT(fc); + BT_ASSERT(fc); - /* - * CTF 1.8 has no boolean field class type, so this component - * translates it to an 8-bit unsigned integer field class. - */ - _fs_sink_ctf_field_class_bit_array_init(&fc->base, - FS_SINK_CTF_FIELD_CLASS_TYPE_BOOL, ir_fc, - 8, index_in_parent); - return fc; + /* + * CTF 1.8 has no boolean field class type, so this component + * translates it to an 8-bit unsigned integer field class. + */ + _fs_sink_ctf_field_class_bit_array_init(&fc->base, FS_SINK_CTF_FIELD_CLASS_TYPE_BOOL, ir_fc, 8, + index_in_parent); + return fc; } -static inline -struct fs_sink_ctf_field_class_int *fs_sink_ctf_field_class_int_create( - const bt_field_class *ir_fc, uint64_t index_in_parent) +static inline struct fs_sink_ctf_field_class_int * +fs_sink_ctf_field_class_int_create(const bt_field_class *ir_fc, uint64_t index_in_parent) { - struct fs_sink_ctf_field_class_int *fc = - g_new0(struct fs_sink_ctf_field_class_int, 1); + struct fs_sink_ctf_field_class_int *fc = g_new0(struct fs_sink_ctf_field_class_int, 1); - BT_ASSERT(fc); - _fs_sink_ctf_field_class_int_init(fc, FS_SINK_CTF_FIELD_CLASS_TYPE_INT, - ir_fc, index_in_parent); - return fc; + BT_ASSERT(fc); + _fs_sink_ctf_field_class_int_init(fc, FS_SINK_CTF_FIELD_CLASS_TYPE_INT, ir_fc, index_in_parent); + return fc; } -static inline -struct fs_sink_ctf_field_class_float *fs_sink_ctf_field_class_float_create( - const bt_field_class *ir_fc, uint64_t index_in_parent) -{ - struct fs_sink_ctf_field_class_float *fc = - g_new0(struct fs_sink_ctf_field_class_float, 1); - - BT_ASSERT(fc); - _fs_sink_ctf_field_class_bit_array_init(&fc->base, - FS_SINK_CTF_FIELD_CLASS_TYPE_FLOAT, - ir_fc, - bt_field_class_get_type(ir_fc) == - BT_FIELD_CLASS_TYPE_SINGLE_PRECISION_REAL ? 32 : 64, - index_in_parent); - return fc; +static inline struct fs_sink_ctf_field_class_float * +fs_sink_ctf_field_class_float_create(const bt_field_class *ir_fc, uint64_t index_in_parent) +{ + struct fs_sink_ctf_field_class_float *fc = g_new0(struct fs_sink_ctf_field_class_float, 1); + + BT_ASSERT(fc); + _fs_sink_ctf_field_class_bit_array_init( + &fc->base, FS_SINK_CTF_FIELD_CLASS_TYPE_FLOAT, ir_fc, + bt_field_class_get_type(ir_fc) == BT_FIELD_CLASS_TYPE_SINGLE_PRECISION_REAL ? 32 : 64, + index_in_parent); + return fc; } -static inline -struct fs_sink_ctf_field_class_string *fs_sink_ctf_field_class_string_create( - const bt_field_class *ir_fc, uint64_t index_in_parent) +static inline struct fs_sink_ctf_field_class_string * +fs_sink_ctf_field_class_string_create(const bt_field_class *ir_fc, uint64_t index_in_parent) { - struct fs_sink_ctf_field_class_string *fc = - g_new0(struct fs_sink_ctf_field_class_string, 1); + struct fs_sink_ctf_field_class_string *fc = g_new0(struct fs_sink_ctf_field_class_string, 1); - BT_ASSERT(fc); - _fs_sink_ctf_field_class_init(&fc->base, - FS_SINK_CTF_FIELD_CLASS_TYPE_STRING, ir_fc, - 8, index_in_parent); - return fc; + BT_ASSERT(fc); + _fs_sink_ctf_field_class_init(&fc->base, FS_SINK_CTF_FIELD_CLASS_TYPE_STRING, ir_fc, 8, + index_in_parent); + return fc; } -static inline -struct fs_sink_ctf_field_class_struct *fs_sink_ctf_field_class_struct_create_empty( - const bt_field_class *ir_fc, uint64_t index_in_parent) +static inline struct fs_sink_ctf_field_class_struct * +fs_sink_ctf_field_class_struct_create_empty(const bt_field_class *ir_fc, uint64_t index_in_parent) { - struct fs_sink_ctf_field_class_struct *fc = - g_new0(struct fs_sink_ctf_field_class_struct, 1); + struct fs_sink_ctf_field_class_struct *fc = g_new0(struct fs_sink_ctf_field_class_struct, 1); - BT_ASSERT(fc); - _fs_sink_ctf_field_class_init(&fc->base, - FS_SINK_CTF_FIELD_CLASS_TYPE_STRUCT, ir_fc, 1, index_in_parent); - fc->members = g_array_new(FALSE, TRUE, - sizeof(struct fs_sink_ctf_named_field_class)); - BT_ASSERT(fc->members); - return fc; + BT_ASSERT(fc); + _fs_sink_ctf_field_class_init(&fc->base, FS_SINK_CTF_FIELD_CLASS_TYPE_STRUCT, ir_fc, 1, + index_in_parent); + fc->members = g_array_new(FALSE, TRUE, sizeof(struct fs_sink_ctf_named_field_class)); + BT_ASSERT(fc->members); + return fc; } -static inline -struct fs_sink_ctf_field_class_option *fs_sink_ctf_field_class_option_create_empty( - const bt_field_class *ir_fc, uint64_t index_in_parent) +static inline struct fs_sink_ctf_field_class_option * +fs_sink_ctf_field_class_option_create_empty(const bt_field_class *ir_fc, uint64_t index_in_parent) { - struct fs_sink_ctf_field_class_option *fc = - g_new0(struct fs_sink_ctf_field_class_option, 1); + struct fs_sink_ctf_field_class_option *fc = g_new0(struct fs_sink_ctf_field_class_option, 1); - BT_ASSERT(fc); - _fs_sink_ctf_field_class_init(&fc->base, - FS_SINK_CTF_FIELD_CLASS_TYPE_OPTION, ir_fc, - 1, index_in_parent); - fc->tag_ref = g_string_new(NULL); - BT_ASSERT(fc->tag_ref); - return fc; + BT_ASSERT(fc); + _fs_sink_ctf_field_class_init(&fc->base, FS_SINK_CTF_FIELD_CLASS_TYPE_OPTION, ir_fc, 1, + index_in_parent); + fc->tag_ref = g_string_new(NULL); + BT_ASSERT(fc->tag_ref); + return fc; } -static inline -struct fs_sink_ctf_field_class_variant *fs_sink_ctf_field_class_variant_create_empty( - const bt_field_class *ir_fc, uint64_t index_in_parent) -{ - struct fs_sink_ctf_field_class_variant *fc = - g_new0(struct fs_sink_ctf_field_class_variant, 1); - - BT_ASSERT(fc); - _fs_sink_ctf_field_class_init(&fc->base, - FS_SINK_CTF_FIELD_CLASS_TYPE_VARIANT, ir_fc, - 1, index_in_parent); - fc->options = g_array_new(FALSE, TRUE, - sizeof(struct fs_sink_ctf_named_field_class)); - BT_ASSERT(fc->options); - fc->tag_ref = g_string_new(NULL); - BT_ASSERT(fc->tag_ref); - fc->tag_is_before = - bt_field_class_get_type(fc->base.ir_fc) == - BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR_FIELD; - return fc; +static inline struct fs_sink_ctf_field_class_variant * +fs_sink_ctf_field_class_variant_create_empty(const bt_field_class *ir_fc, uint64_t index_in_parent) +{ + struct fs_sink_ctf_field_class_variant *fc = g_new0(struct fs_sink_ctf_field_class_variant, 1); + + BT_ASSERT(fc); + _fs_sink_ctf_field_class_init(&fc->base, FS_SINK_CTF_FIELD_CLASS_TYPE_VARIANT, ir_fc, 1, + index_in_parent); + fc->options = g_array_new(FALSE, TRUE, sizeof(struct fs_sink_ctf_named_field_class)); + BT_ASSERT(fc->options); + fc->tag_ref = g_string_new(NULL); + BT_ASSERT(fc->tag_ref); + fc->tag_is_before = bt_field_class_get_type(fc->base.ir_fc) == + BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR_FIELD; + return fc; } -static inline -struct fs_sink_ctf_field_class_array *fs_sink_ctf_field_class_array_create_empty( - const bt_field_class *ir_fc, uint64_t index_in_parent) +static inline struct fs_sink_ctf_field_class_array * +fs_sink_ctf_field_class_array_create_empty(const bt_field_class *ir_fc, uint64_t index_in_parent) { - struct fs_sink_ctf_field_class_array *fc = - g_new0(struct fs_sink_ctf_field_class_array, 1); + struct fs_sink_ctf_field_class_array *fc = g_new0(struct fs_sink_ctf_field_class_array, 1); - BT_ASSERT(fc); - _fs_sink_ctf_field_class_init(&fc->base.base, - FS_SINK_CTF_FIELD_CLASS_TYPE_ARRAY, ir_fc, - 1, index_in_parent); - fc->length = bt_field_class_array_static_get_length(ir_fc); - return fc; + BT_ASSERT(fc); + _fs_sink_ctf_field_class_init(&fc->base.base, FS_SINK_CTF_FIELD_CLASS_TYPE_ARRAY, ir_fc, 1, + index_in_parent); + fc->length = bt_field_class_array_static_get_length(ir_fc); + return fc; } -static inline -struct fs_sink_ctf_field_class_sequence *fs_sink_ctf_field_class_sequence_create_empty( - const bt_field_class *ir_fc, uint64_t index_in_parent) -{ - struct fs_sink_ctf_field_class_sequence *fc = - g_new0(struct fs_sink_ctf_field_class_sequence, 1); - - BT_ASSERT(fc); - _fs_sink_ctf_field_class_init(&fc->base.base, - FS_SINK_CTF_FIELD_CLASS_TYPE_SEQUENCE, - ir_fc, 1, index_in_parent); - fc->length_ref = g_string_new(NULL); - BT_ASSERT(fc->length_ref); - fc->length_is_before = - bt_field_class_get_type(ir_fc) == - BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITHOUT_LENGTH_FIELD; - return fc; +static inline struct fs_sink_ctf_field_class_sequence * +fs_sink_ctf_field_class_sequence_create_empty(const bt_field_class *ir_fc, uint64_t index_in_parent) +{ + struct fs_sink_ctf_field_class_sequence *fc = + g_new0(struct fs_sink_ctf_field_class_sequence, 1); + + BT_ASSERT(fc); + _fs_sink_ctf_field_class_init(&fc->base.base, FS_SINK_CTF_FIELD_CLASS_TYPE_SEQUENCE, ir_fc, 1, + index_in_parent); + fc->length_ref = g_string_new(NULL); + BT_ASSERT(fc->length_ref); + fc->length_is_before = + bt_field_class_get_type(ir_fc) == BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITHOUT_LENGTH_FIELD; + return fc; } -static inline -struct fs_sink_ctf_named_field_class * -fs_sink_ctf_field_class_struct_borrow_member_by_index( - struct fs_sink_ctf_field_class_struct *fc, uint64_t index); +static inline struct fs_sink_ctf_named_field_class * +fs_sink_ctf_field_class_struct_borrow_member_by_index(struct fs_sink_ctf_field_class_struct *fc, + uint64_t index); -static inline -struct fs_sink_ctf_named_field_class * -fs_sink_ctf_field_class_variant_borrow_option_by_index( - struct fs_sink_ctf_field_class_variant *fc, uint64_t index); +static inline struct fs_sink_ctf_named_field_class * +fs_sink_ctf_field_class_variant_borrow_option_by_index(struct fs_sink_ctf_field_class_variant *fc, + uint64_t index); -static inline -void _fs_sink_ctf_field_class_fini(struct fs_sink_ctf_field_class *fc) +static inline void _fs_sink_ctf_field_class_fini(struct fs_sink_ctf_field_class *fc) { - BT_ASSERT(fc); + BT_ASSERT(fc); } -static inline -void _fs_sink_ctf_field_class_bit_array_destroy( - struct fs_sink_ctf_field_class_bit_array *fc) +static inline void +_fs_sink_ctf_field_class_bit_array_destroy(struct fs_sink_ctf_field_class_bit_array *fc) { - BT_ASSERT(fc); - _fs_sink_ctf_field_class_fini(&fc->base); - g_free(fc); + BT_ASSERT(fc); + _fs_sink_ctf_field_class_fini(&fc->base); + g_free(fc); } -static inline -void _fs_sink_ctf_field_class_bool_destroy( - struct fs_sink_ctf_field_class_bool *fc) +static inline void _fs_sink_ctf_field_class_bool_destroy(struct fs_sink_ctf_field_class_bool *fc) { - BT_ASSERT(fc); - _fs_sink_ctf_field_class_fini(&fc->base.base); - g_free(fc); + BT_ASSERT(fc); + _fs_sink_ctf_field_class_fini(&fc->base.base); + g_free(fc); } -static inline -void _fs_sink_ctf_field_class_int_destroy( - struct fs_sink_ctf_field_class_int *fc) +static inline void _fs_sink_ctf_field_class_int_destroy(struct fs_sink_ctf_field_class_int *fc) { - BT_ASSERT(fc); - _fs_sink_ctf_field_class_fini(&fc->base.base); - g_free(fc); + BT_ASSERT(fc); + _fs_sink_ctf_field_class_fini(&fc->base.base); + g_free(fc); } -static inline -void _fs_sink_ctf_field_class_float_destroy( - struct fs_sink_ctf_field_class_float *fc) +static inline void _fs_sink_ctf_field_class_float_destroy(struct fs_sink_ctf_field_class_float *fc) { - BT_ASSERT(fc); - _fs_sink_ctf_field_class_fini(&fc->base.base); - g_free(fc); + BT_ASSERT(fc); + _fs_sink_ctf_field_class_fini(&fc->base.base); + g_free(fc); } -static inline -void _fs_sink_ctf_field_class_string_destroy( - struct fs_sink_ctf_field_class_string *fc) +static inline void +_fs_sink_ctf_field_class_string_destroy(struct fs_sink_ctf_field_class_string *fc) { - BT_ASSERT(fc); - _fs_sink_ctf_field_class_fini(&fc->base); - g_free(fc); + BT_ASSERT(fc); + _fs_sink_ctf_field_class_fini(&fc->base); + g_free(fc); } -static inline -void _fs_sink_ctf_field_class_struct_destroy( - struct fs_sink_ctf_field_class_struct *fc) +static inline void +_fs_sink_ctf_field_class_struct_destroy(struct fs_sink_ctf_field_class_struct *fc) { - BT_ASSERT(fc); - _fs_sink_ctf_field_class_fini(&fc->base); + BT_ASSERT(fc); + _fs_sink_ctf_field_class_fini(&fc->base); - if (fc->members) { - uint64_t i; + if (fc->members) { + uint64_t i; - for (i = 0; i < fc->members->len; i++) { - struct fs_sink_ctf_named_field_class *named_fc = - fs_sink_ctf_field_class_struct_borrow_member_by_index( - fc, i); + for (i = 0; i < fc->members->len; i++) { + struct fs_sink_ctf_named_field_class *named_fc = + fs_sink_ctf_field_class_struct_borrow_member_by_index(fc, i); - _fs_sink_ctf_named_field_class_fini(named_fc); - } + _fs_sink_ctf_named_field_class_fini(named_fc); + } - g_array_free(fc->members, TRUE); - fc->members = NULL; - } + g_array_free(fc->members, TRUE); + fc->members = NULL; + } - g_free(fc); + g_free(fc); } -static inline -void _fs_sink_ctf_field_class_array_base_fini( - struct fs_sink_ctf_field_class_array_base *fc) +static inline void +_fs_sink_ctf_field_class_array_base_fini(struct fs_sink_ctf_field_class_array_base *fc) { - BT_ASSERT(fc); - _fs_sink_ctf_field_class_fini(&fc->base); - fs_sink_ctf_field_class_destroy(fc->elem_fc); - fc->elem_fc = NULL; + BT_ASSERT(fc); + _fs_sink_ctf_field_class_fini(&fc->base); + fs_sink_ctf_field_class_destroy(fc->elem_fc); + fc->elem_fc = NULL; } -static inline -void _fs_sink_ctf_field_class_array_destroy( - struct fs_sink_ctf_field_class_array *fc) +static inline void _fs_sink_ctf_field_class_array_destroy(struct fs_sink_ctf_field_class_array *fc) { - BT_ASSERT(fc); - _fs_sink_ctf_field_class_array_base_fini(&fc->base); - g_free(fc); + BT_ASSERT(fc); + _fs_sink_ctf_field_class_array_base_fini(&fc->base); + g_free(fc); } -static inline -void _fs_sink_ctf_field_class_sequence_destroy( - struct fs_sink_ctf_field_class_sequence *fc) +static inline void +_fs_sink_ctf_field_class_sequence_destroy(struct fs_sink_ctf_field_class_sequence *fc) { - BT_ASSERT(fc); - _fs_sink_ctf_field_class_array_base_fini(&fc->base); + BT_ASSERT(fc); + _fs_sink_ctf_field_class_array_base_fini(&fc->base); - if (fc->length_ref) { - g_string_free(fc->length_ref, TRUE); - fc->length_ref = NULL; - } + if (fc->length_ref) { + g_string_free(fc->length_ref, TRUE); + fc->length_ref = NULL; + } - g_free(fc); + g_free(fc); } -static inline -void _fs_sink_ctf_field_class_option_destroy( - struct fs_sink_ctf_field_class_option *fc) +static inline void +_fs_sink_ctf_field_class_option_destroy(struct fs_sink_ctf_field_class_option *fc) { - BT_ASSERT(fc); - _fs_sink_ctf_field_class_fini(&fc->base); - fs_sink_ctf_field_class_destroy(fc->content_fc); + BT_ASSERT(fc); + _fs_sink_ctf_field_class_fini(&fc->base); + fs_sink_ctf_field_class_destroy(fc->content_fc); - if (fc->tag_ref) { - g_string_free(fc->tag_ref, TRUE); - fc->tag_ref = NULL; - } + if (fc->tag_ref) { + g_string_free(fc->tag_ref, TRUE); + fc->tag_ref = NULL; + } - g_free(fc); + g_free(fc); } -static inline -void _fs_sink_ctf_field_class_variant_destroy( - struct fs_sink_ctf_field_class_variant *fc) +static inline void +_fs_sink_ctf_field_class_variant_destroy(struct fs_sink_ctf_field_class_variant *fc) { - BT_ASSERT(fc); - _fs_sink_ctf_field_class_fini(&fc->base); + BT_ASSERT(fc); + _fs_sink_ctf_field_class_fini(&fc->base); - if (fc->options) { - uint64_t i; + if (fc->options) { + uint64_t i; - for (i = 0; i < fc->options->len; i++) { - struct fs_sink_ctf_named_field_class *named_fc = - fs_sink_ctf_field_class_variant_borrow_option_by_index( - fc, i); + for (i = 0; i < fc->options->len; i++) { + struct fs_sink_ctf_named_field_class *named_fc = + fs_sink_ctf_field_class_variant_borrow_option_by_index(fc, i); - _fs_sink_ctf_named_field_class_fini(named_fc); - } + _fs_sink_ctf_named_field_class_fini(named_fc); + } - g_array_free(fc->options, TRUE); - fc->options = NULL; - } + g_array_free(fc->options, TRUE); + fc->options = NULL; + } - if (fc->tag_ref) { - g_string_free(fc->tag_ref, TRUE); - fc->tag_ref = NULL; - } + if (fc->tag_ref) { + g_string_free(fc->tag_ref, TRUE); + fc->tag_ref = NULL; + } - g_free(fc); + g_free(fc); } -static inline -void fs_sink_ctf_field_class_destroy(struct fs_sink_ctf_field_class *fc) -{ - if (!fc) { - return; - } - - switch (fc->type) { - case FS_SINK_CTF_FIELD_CLASS_TYPE_BOOL: - _fs_sink_ctf_field_class_bool_destroy(fs_sink_ctf_field_class_as_bool(fc)); - break; - case FS_SINK_CTF_FIELD_CLASS_TYPE_BIT_ARRAY: - _fs_sink_ctf_field_class_bit_array_destroy(fs_sink_ctf_field_class_as_bit_array(fc)); - break; - case FS_SINK_CTF_FIELD_CLASS_TYPE_INT: - _fs_sink_ctf_field_class_int_destroy(fs_sink_ctf_field_class_as_int(fc)); - break; - case FS_SINK_CTF_FIELD_CLASS_TYPE_FLOAT: - _fs_sink_ctf_field_class_float_destroy(fs_sink_ctf_field_class_as_float(fc)); - break; - case FS_SINK_CTF_FIELD_CLASS_TYPE_STRING: - _fs_sink_ctf_field_class_string_destroy(fs_sink_ctf_field_class_as_string(fc)); - break; - case FS_SINK_CTF_FIELD_CLASS_TYPE_STRUCT: - _fs_sink_ctf_field_class_struct_destroy(fs_sink_ctf_field_class_as_struct(fc)); - break; - case FS_SINK_CTF_FIELD_CLASS_TYPE_ARRAY: - _fs_sink_ctf_field_class_array_destroy(fs_sink_ctf_field_class_as_array(fc)); - break; - case FS_SINK_CTF_FIELD_CLASS_TYPE_SEQUENCE: - _fs_sink_ctf_field_class_sequence_destroy(fs_sink_ctf_field_class_as_sequence(fc)); - break; - case FS_SINK_CTF_FIELD_CLASS_TYPE_OPTION: - _fs_sink_ctf_field_class_option_destroy(fs_sink_ctf_field_class_as_option(fc)); - break; - case FS_SINK_CTF_FIELD_CLASS_TYPE_VARIANT: - _fs_sink_ctf_field_class_variant_destroy(fs_sink_ctf_field_class_as_variant(fc)); - break; - default: - bt_common_abort(); - } -} - -static inline -struct fs_sink_ctf_named_field_class * -fs_sink_ctf_field_class_struct_borrow_member_by_index( - struct fs_sink_ctf_field_class_struct *fc, uint64_t index) +static inline void fs_sink_ctf_field_class_destroy(struct fs_sink_ctf_field_class *fc) { - BT_ASSERT_DBG(fc); - BT_ASSERT_DBG(index < fc->members->len); - return &g_array_index(fc->members, struct fs_sink_ctf_named_field_class, - index); + if (!fc) { + return; + } + + switch (fc->type) { + case FS_SINK_CTF_FIELD_CLASS_TYPE_BOOL: + _fs_sink_ctf_field_class_bool_destroy(fs_sink_ctf_field_class_as_bool(fc)); + break; + case FS_SINK_CTF_FIELD_CLASS_TYPE_BIT_ARRAY: + _fs_sink_ctf_field_class_bit_array_destroy(fs_sink_ctf_field_class_as_bit_array(fc)); + break; + case FS_SINK_CTF_FIELD_CLASS_TYPE_INT: + _fs_sink_ctf_field_class_int_destroy(fs_sink_ctf_field_class_as_int(fc)); + break; + case FS_SINK_CTF_FIELD_CLASS_TYPE_FLOAT: + _fs_sink_ctf_field_class_float_destroy(fs_sink_ctf_field_class_as_float(fc)); + break; + case FS_SINK_CTF_FIELD_CLASS_TYPE_STRING: + _fs_sink_ctf_field_class_string_destroy(fs_sink_ctf_field_class_as_string(fc)); + break; + case FS_SINK_CTF_FIELD_CLASS_TYPE_STRUCT: + _fs_sink_ctf_field_class_struct_destroy(fs_sink_ctf_field_class_as_struct(fc)); + break; + case FS_SINK_CTF_FIELD_CLASS_TYPE_ARRAY: + _fs_sink_ctf_field_class_array_destroy(fs_sink_ctf_field_class_as_array(fc)); + break; + case FS_SINK_CTF_FIELD_CLASS_TYPE_SEQUENCE: + _fs_sink_ctf_field_class_sequence_destroy(fs_sink_ctf_field_class_as_sequence(fc)); + break; + case FS_SINK_CTF_FIELD_CLASS_TYPE_OPTION: + _fs_sink_ctf_field_class_option_destroy(fs_sink_ctf_field_class_as_option(fc)); + break; + case FS_SINK_CTF_FIELD_CLASS_TYPE_VARIANT: + _fs_sink_ctf_field_class_variant_destroy(fs_sink_ctf_field_class_as_variant(fc)); + break; + default: + bt_common_abort(); + } } -static inline -struct fs_sink_ctf_named_field_class * -fs_sink_ctf_field_class_struct_borrow_member_by_name( - struct fs_sink_ctf_field_class_struct *fc, const char *name) +static inline struct fs_sink_ctf_named_field_class * +fs_sink_ctf_field_class_struct_borrow_member_by_index(struct fs_sink_ctf_field_class_struct *fc, + uint64_t index) { - uint64_t i; - struct fs_sink_ctf_named_field_class *ret_named_fc = NULL; - - BT_ASSERT_DBG(fc); - BT_ASSERT_DBG(name); - - for (i = 0; i < fc->members->len; i++) { - struct fs_sink_ctf_named_field_class *named_fc = - fs_sink_ctf_field_class_struct_borrow_member_by_index( - fc, i); - - if (strcmp(name, named_fc->name->str) == 0) { - ret_named_fc = named_fc; - goto end; - } - } + BT_ASSERT_DBG(fc); + BT_ASSERT_DBG(index < fc->members->len); + return &g_array_index(fc->members, struct fs_sink_ctf_named_field_class, index); +} + +static inline struct fs_sink_ctf_named_field_class * +fs_sink_ctf_field_class_struct_borrow_member_by_name(struct fs_sink_ctf_field_class_struct *fc, + const char *name) +{ + uint64_t i; + struct fs_sink_ctf_named_field_class *ret_named_fc = NULL; + + BT_ASSERT_DBG(fc); + BT_ASSERT_DBG(name); + + for (i = 0; i < fc->members->len; i++) { + struct fs_sink_ctf_named_field_class *named_fc = + fs_sink_ctf_field_class_struct_borrow_member_by_index(fc, i); + + if (strcmp(name, named_fc->name->str) == 0) { + ret_named_fc = named_fc; + goto end; + } + } end: - return ret_named_fc; + return ret_named_fc; } -static inline -struct fs_sink_ctf_field_class * +static inline struct fs_sink_ctf_field_class * fs_sink_ctf_field_class_struct_borrow_member_field_class_by_name( - struct fs_sink_ctf_field_class_struct *struct_fc, const char *name) + struct fs_sink_ctf_field_class_struct *struct_fc, const char *name) { - struct fs_sink_ctf_named_field_class *named_fc = NULL; - struct fs_sink_ctf_field_class *fc = NULL; + struct fs_sink_ctf_named_field_class *named_fc = NULL; + struct fs_sink_ctf_field_class *fc = NULL; - if (!struct_fc) { - goto end; - } + if (!struct_fc) { + goto end; + } - named_fc = fs_sink_ctf_field_class_struct_borrow_member_by_name( - struct_fc, name); - if (!named_fc) { - goto end; - } + named_fc = fs_sink_ctf_field_class_struct_borrow_member_by_name(struct_fc, name); + if (!named_fc) { + goto end; + } - fc = named_fc->fc; + fc = named_fc->fc; end: - return fc; + return fc; } -static inline -struct fs_sink_ctf_field_class_int * +static inline struct fs_sink_ctf_field_class_int * fs_sink_ctf_field_class_struct_borrow_member_int_field_class_by_name( - struct fs_sink_ctf_field_class_struct *struct_fc, - const char *name) + struct fs_sink_ctf_field_class_struct *struct_fc, const char *name) { - struct fs_sink_ctf_field_class_int *int_fc = NULL; + struct fs_sink_ctf_field_class_int *int_fc = NULL; - int_fc = fs_sink_ctf_field_class_as_int( - fs_sink_ctf_field_class_struct_borrow_member_field_class_by_name( - struct_fc, name)); - if (!int_fc) { - goto end; - } + int_fc = fs_sink_ctf_field_class_as_int( + fs_sink_ctf_field_class_struct_borrow_member_field_class_by_name(struct_fc, name)); + if (!int_fc) { + goto end; + } - if (int_fc->base.base.type != FS_SINK_CTF_FIELD_CLASS_TYPE_INT) { - int_fc = NULL; - goto end; - } + if (int_fc->base.base.type != FS_SINK_CTF_FIELD_CLASS_TYPE_INT) { + int_fc = NULL; + goto end; + } end: - return int_fc; + return int_fc; } -static inline -void fs_sink_ctf_field_class_struct_align_at_least( - struct fs_sink_ctf_field_class_struct *fc, - unsigned int alignment) +static inline void +fs_sink_ctf_field_class_struct_align_at_least(struct fs_sink_ctf_field_class_struct *fc, + unsigned int alignment) { - if (alignment > fc->base.alignment) { - fc->base.alignment = alignment; - } + if (alignment > fc->base.alignment) { + fc->base.alignment = alignment; + } } -static inline -void fs_sink_ctf_field_class_struct_append_member( - struct fs_sink_ctf_field_class_struct *fc, - const char *name, struct fs_sink_ctf_field_class *member_fc) +static inline void +fs_sink_ctf_field_class_struct_append_member(struct fs_sink_ctf_field_class_struct *fc, + const char *name, + struct fs_sink_ctf_field_class *member_fc) { - struct fs_sink_ctf_named_field_class *named_fc; + struct fs_sink_ctf_named_field_class *named_fc; - BT_ASSERT(fc); - BT_ASSERT(name); - g_array_set_size(fc->members, fc->members->len + 1); + BT_ASSERT(fc); + BT_ASSERT(name); + g_array_set_size(fc->members, fc->members->len + 1); - named_fc = &g_array_index(fc->members, - struct fs_sink_ctf_named_field_class, fc->members->len - 1); - _fs_sink_ctf_named_field_class_init(named_fc); - g_string_assign(named_fc->name, name); - named_fc->fc = member_fc; - fs_sink_ctf_field_class_struct_align_at_least(fc, member_fc->alignment); + named_fc = + &g_array_index(fc->members, struct fs_sink_ctf_named_field_class, fc->members->len - 1); + _fs_sink_ctf_named_field_class_init(named_fc); + g_string_assign(named_fc->name, name); + named_fc->fc = member_fc; + fs_sink_ctf_field_class_struct_align_at_least(fc, member_fc->alignment); } -static inline -struct fs_sink_ctf_named_field_class * -fs_sink_ctf_field_class_variant_borrow_option_by_index( - struct fs_sink_ctf_field_class_variant *fc, uint64_t index) +static inline struct fs_sink_ctf_named_field_class * +fs_sink_ctf_field_class_variant_borrow_option_by_index(struct fs_sink_ctf_field_class_variant *fc, + uint64_t index) { - BT_ASSERT_DBG(fc); - BT_ASSERT_DBG(index < fc->options->len); - return &g_array_index(fc->options, struct fs_sink_ctf_named_field_class, - index); + BT_ASSERT_DBG(fc); + BT_ASSERT_DBG(index < fc->options->len); + return &g_array_index(fc->options, struct fs_sink_ctf_named_field_class, index); } -static inline -struct fs_sink_ctf_named_field_class * -fs_sink_ctf_field_class_variant_borrow_option_by_name( - struct fs_sink_ctf_field_class_variant *fc, const char *name) +static inline struct fs_sink_ctf_named_field_class * +fs_sink_ctf_field_class_variant_borrow_option_by_name(struct fs_sink_ctf_field_class_variant *fc, + const char *name) { - uint64_t i; - struct fs_sink_ctf_named_field_class *ret_named_fc = NULL; + uint64_t i; + struct fs_sink_ctf_named_field_class *ret_named_fc = NULL; - BT_ASSERT_DBG(fc); - BT_ASSERT_DBG(name); + BT_ASSERT_DBG(fc); + BT_ASSERT_DBG(name); - for (i = 0; i < fc->options->len; i++) { - struct fs_sink_ctf_named_field_class *named_fc = - fs_sink_ctf_field_class_variant_borrow_option_by_index( - fc, i); + for (i = 0; i < fc->options->len; i++) { + struct fs_sink_ctf_named_field_class *named_fc = + fs_sink_ctf_field_class_variant_borrow_option_by_index(fc, i); - if (strcmp(name, named_fc->name->str) == 0) { - ret_named_fc = named_fc; - goto end; - } - } + if (strcmp(name, named_fc->name->str) == 0) { + ret_named_fc = named_fc; + goto end; + } + } end: - return ret_named_fc; + return ret_named_fc; } -static inline -void fs_sink_ctf_field_class_variant_append_option( - struct fs_sink_ctf_field_class_variant *fc, - const char *name, struct fs_sink_ctf_field_class *option_fc) +static inline void +fs_sink_ctf_field_class_variant_append_option(struct fs_sink_ctf_field_class_variant *fc, + const char *name, + struct fs_sink_ctf_field_class *option_fc) { - struct fs_sink_ctf_named_field_class *named_fc; + struct fs_sink_ctf_named_field_class *named_fc; - BT_ASSERT(fc); - BT_ASSERT(name); - g_array_set_size(fc->options, fc->options->len + 1); + BT_ASSERT(fc); + BT_ASSERT(name); + g_array_set_size(fc->options, fc->options->len + 1); - named_fc = &g_array_index(fc->options, - struct fs_sink_ctf_named_field_class, fc->options->len - 1); - _fs_sink_ctf_named_field_class_init(named_fc); - g_string_assign(named_fc->name, name); - named_fc->fc = option_fc; + named_fc = + &g_array_index(fc->options, struct fs_sink_ctf_named_field_class, fc->options->len - 1); + _fs_sink_ctf_named_field_class_init(named_fc); + g_string_assign(named_fc->name, name); + named_fc->fc = option_fc; } -static inline -struct fs_sink_ctf_event_class *fs_sink_ctf_event_class_create( - struct fs_sink_ctf_stream_class *sc, - const bt_event_class *ir_ec) -{ - struct fs_sink_ctf_event_class *ec = - g_new0(struct fs_sink_ctf_event_class, 1); - - BT_ASSERT(sc); - BT_ASSERT(ir_ec); - BT_ASSERT(ec); - ec->ir_ec = ir_ec; - ec->sc = sc; - g_ptr_array_add(sc->event_classes, ec); - g_hash_table_insert(sc->event_classes_from_ir, (gpointer) ir_ec, ec); - return ec; +static inline struct fs_sink_ctf_event_class * +fs_sink_ctf_event_class_create(struct fs_sink_ctf_stream_class *sc, const bt_event_class *ir_ec) +{ + struct fs_sink_ctf_event_class *ec = g_new0(struct fs_sink_ctf_event_class, 1); + + BT_ASSERT(sc); + BT_ASSERT(ir_ec); + BT_ASSERT(ec); + ec->ir_ec = ir_ec; + ec->sc = sc; + g_ptr_array_add(sc->event_classes, ec); + g_hash_table_insert(sc->event_classes_from_ir, (gpointer) ir_ec, ec); + return ec; } -static inline -void fs_sink_ctf_event_class_destroy(struct fs_sink_ctf_event_class *ec) +static inline void fs_sink_ctf_event_class_destroy(struct fs_sink_ctf_event_class *ec) { - if (!ec) { - return; - } + if (!ec) { + return; + } - fs_sink_ctf_field_class_destroy(ec->spec_context_fc); - ec->spec_context_fc = NULL; - fs_sink_ctf_field_class_destroy(ec->payload_fc); - ec->payload_fc = NULL; - g_free(ec); + fs_sink_ctf_field_class_destroy(ec->spec_context_fc); + ec->spec_context_fc = NULL; + fs_sink_ctf_field_class_destroy(ec->payload_fc); + ec->payload_fc = NULL; + g_free(ec); } -static inline -struct fs_sink_ctf_stream_class *fs_sink_ctf_stream_class_create( - struct fs_sink_ctf_trace *trace, - const bt_stream_class *ir_sc) -{ - struct fs_sink_ctf_stream_class *sc = - g_new0(struct fs_sink_ctf_stream_class, 1); - - BT_ASSERT(trace); - BT_ASSERT(ir_sc); - BT_ASSERT(sc); - sc->trace = trace; - sc->ir_sc = ir_sc; - sc->default_clock_class = - bt_stream_class_borrow_default_clock_class_const(ir_sc); - sc->default_clock_class_name = g_string_new(NULL); - BT_ASSERT(sc->default_clock_class_name); - sc->event_classes = g_ptr_array_new_with_free_func( - (GDestroyNotify) fs_sink_ctf_event_class_destroy); - BT_ASSERT(sc->event_classes); - sc->event_classes_from_ir = g_hash_table_new(g_direct_hash, - g_direct_equal); - BT_ASSERT(sc->event_classes_from_ir); - sc->has_packets = bt_stream_class_supports_packets(ir_sc); - sc->packets_have_ts_begin = - bt_stream_class_packets_have_beginning_default_clock_snapshot( - ir_sc); - sc->packets_have_ts_end = - bt_stream_class_packets_have_end_default_clock_snapshot(ir_sc); - sc->has_discarded_events = - bt_stream_class_supports_discarded_events(ir_sc); - - if (sc->has_discarded_events) { - sc->discarded_events_has_ts = - bt_stream_class_discarded_events_have_default_clock_snapshots( - ir_sc); - } - - if (bt_stream_class_supports_discarded_packets(ir_sc)) { - sc->discarded_packets_has_ts = - bt_stream_class_discarded_packets_have_default_clock_snapshots( - ir_sc); - } - - g_ptr_array_add(trace->stream_classes, sc); - return sc; +static inline struct fs_sink_ctf_stream_class * +fs_sink_ctf_stream_class_create(struct fs_sink_ctf_trace *trace, const bt_stream_class *ir_sc) +{ + struct fs_sink_ctf_stream_class *sc = g_new0(struct fs_sink_ctf_stream_class, 1); + + BT_ASSERT(trace); + BT_ASSERT(ir_sc); + BT_ASSERT(sc); + sc->trace = trace; + sc->ir_sc = ir_sc; + sc->default_clock_class = bt_stream_class_borrow_default_clock_class_const(ir_sc); + sc->default_clock_class_name = g_string_new(NULL); + BT_ASSERT(sc->default_clock_class_name); + sc->event_classes = + g_ptr_array_new_with_free_func((GDestroyNotify) fs_sink_ctf_event_class_destroy); + BT_ASSERT(sc->event_classes); + sc->event_classes_from_ir = g_hash_table_new(g_direct_hash, g_direct_equal); + BT_ASSERT(sc->event_classes_from_ir); + sc->has_packets = bt_stream_class_supports_packets(ir_sc); + sc->packets_have_ts_begin = + bt_stream_class_packets_have_beginning_default_clock_snapshot(ir_sc); + sc->packets_have_ts_end = bt_stream_class_packets_have_end_default_clock_snapshot(ir_sc); + sc->has_discarded_events = bt_stream_class_supports_discarded_events(ir_sc); + + if (sc->has_discarded_events) { + sc->discarded_events_has_ts = + bt_stream_class_discarded_events_have_default_clock_snapshots(ir_sc); + } + + if (bt_stream_class_supports_discarded_packets(ir_sc)) { + sc->discarded_packets_has_ts = + bt_stream_class_discarded_packets_have_default_clock_snapshots(ir_sc); + } + + g_ptr_array_add(trace->stream_classes, sc); + return sc; } -static inline -void fs_sink_ctf_stream_class_destroy(struct fs_sink_ctf_stream_class *sc) -{ - if (!sc) { - return; - } - - if (sc->default_clock_class_name) { - g_string_free(sc->default_clock_class_name, TRUE); - sc->default_clock_class_name = NULL; - } - - if (sc->event_classes) { - g_ptr_array_free(sc->event_classes, TRUE); - sc->event_classes = NULL; - } - - if (sc->event_classes_from_ir) { - g_hash_table_destroy(sc->event_classes_from_ir); - sc->event_classes_from_ir = NULL; - } - - fs_sink_ctf_field_class_destroy(sc->packet_context_fc); - sc->packet_context_fc = NULL; - fs_sink_ctf_field_class_destroy(sc->event_common_context_fc); - sc->event_common_context_fc = NULL; - g_free(sc); +static inline void fs_sink_ctf_stream_class_destroy(struct fs_sink_ctf_stream_class *sc) +{ + if (!sc) { + return; + } + + if (sc->default_clock_class_name) { + g_string_free(sc->default_clock_class_name, TRUE); + sc->default_clock_class_name = NULL; + } + + if (sc->event_classes) { + g_ptr_array_free(sc->event_classes, TRUE); + sc->event_classes = NULL; + } + + if (sc->event_classes_from_ir) { + g_hash_table_destroy(sc->event_classes_from_ir); + sc->event_classes_from_ir = NULL; + } + + fs_sink_ctf_field_class_destroy(sc->packet_context_fc); + sc->packet_context_fc = NULL; + fs_sink_ctf_field_class_destroy(sc->event_common_context_fc); + sc->event_common_context_fc = NULL; + g_free(sc); } -static inline -void fs_sink_ctf_stream_class_append_event_class( - struct fs_sink_ctf_stream_class *sc, - struct fs_sink_ctf_event_class *ec) +static inline void fs_sink_ctf_stream_class_append_event_class(struct fs_sink_ctf_stream_class *sc, + struct fs_sink_ctf_event_class *ec) { - g_ptr_array_add(sc->event_classes, ec); + g_ptr_array_add(sc->event_classes, ec); } -static inline -void fs_sink_ctf_trace_destroy(struct fs_sink_ctf_trace *trace) +static inline void fs_sink_ctf_trace_destroy(struct fs_sink_ctf_trace *trace) { - if (!trace) { - return; - } + if (!trace) { + return; + } - if (trace->stream_classes) { - g_ptr_array_free(trace->stream_classes, TRUE); - trace->stream_classes = NULL; - } + if (trace->stream_classes) { + g_ptr_array_free(trace->stream_classes, TRUE); + trace->stream_classes = NULL; + } - g_free(trace); + g_free(trace); } -static inline -struct fs_sink_ctf_trace *fs_sink_ctf_trace_create(const bt_trace *ir_trace) +static inline struct fs_sink_ctf_trace *fs_sink_ctf_trace_create(const bt_trace *ir_trace) { - struct fs_sink_ctf_trace *trace = - g_new0(struct fs_sink_ctf_trace, 1); + struct fs_sink_ctf_trace *trace = g_new0(struct fs_sink_ctf_trace, 1); - BT_ASSERT(trace); + BT_ASSERT(trace); - bt_uuid_generate(trace->uuid); + bt_uuid_generate(trace->uuid); - trace->ir_trace = ir_trace; - trace->ir_tc = bt_trace_borrow_class_const(ir_trace); - trace->stream_classes = g_ptr_array_new_with_free_func( - (GDestroyNotify) fs_sink_ctf_stream_class_destroy); - BT_ASSERT(trace->stream_classes); + trace->ir_trace = ir_trace; + trace->ir_tc = bt_trace_borrow_class_const(ir_trace); + trace->stream_classes = + g_ptr_array_new_with_free_func((GDestroyNotify) fs_sink_ctf_stream_class_destroy); + BT_ASSERT(trace->stream_classes); - return trace; + return trace; } #endif /* BABELTRACE_PLUGIN_CTF_FS_SINK_FS_SINK_CTF_META_H */ diff --git a/src/plugins/ctf/fs-sink/fs-sink-stream.cpp b/src/plugins/ctf/fs-sink/fs-sink-stream.cpp index da0a6083..a90d587b 100644 --- a/src/plugins/ctf/fs-sink/fs-sink-stream.cpp +++ b/src/plugins/ctf/fs-sink/fs-sink-stream.cpp @@ -5,8 +5,8 @@ */ #define BT_COMP_LOG_SELF_COMP (stream->trace->fs_sink->self_comp) -#define BT_LOG_OUTPUT_LEVEL (stream->log_level) -#define BT_LOG_TAG "PLUGIN/SINK.CTF.FS/STREAM" +#define BT_LOG_OUTPUT_LEVEL (stream->log_level) +#define BT_LOG_TAG "PLUGIN/SINK.CTF.FS/STREAM" #include "logging/comp-logging.h" #include @@ -25,712 +25,653 @@ BT_HIDDEN void fs_sink_stream_destroy(struct fs_sink_stream *stream) { - if (!stream) { - goto end; - } + if (!stream) { + goto end; + } - bt_ctfser_fini(&stream->ctfser); + bt_ctfser_fini(&stream->ctfser); - if (stream->file_name) { - g_string_free(stream->file_name, TRUE); - stream->file_name = NULL; - } + if (stream->file_name) { + g_string_free(stream->file_name, TRUE); + stream->file_name = NULL; + } - bt_packet_put_ref(stream->packet_state.packet); - g_free(stream); + bt_packet_put_ref(stream->packet_state.packet); + g_free(stream); end: - return; + return; } -static -bool stream_file_name_exists(struct fs_sink_trace *trace, const char *name) +static bool stream_file_name_exists(struct fs_sink_trace *trace, const char *name) { - bool exists = false; - GHashTableIter iter; - gpointer key, value; + bool exists = false; + GHashTableIter iter; + gpointer key, value; - g_hash_table_iter_init(&iter, trace->streams); + g_hash_table_iter_init(&iter, trace->streams); - while (g_hash_table_iter_next(&iter, &key, &value)) { - struct fs_sink_stream *stream = (fs_sink_stream *) value; + while (g_hash_table_iter_next(&iter, &key, &value)) { + struct fs_sink_stream *stream = (fs_sink_stream *) value; - if (strcmp(name, stream->file_name->str) == 0) { - exists = true; - goto end; - } - } + if (strcmp(name, stream->file_name->str) == 0) { + exists = true; + goto end; + } + } end: - return exists; + return exists; } -static -GString *sanitize_stream_file_name(const char *file_name) +static GString *sanitize_stream_file_name(const char *file_name) { - GString *san_file_name = g_string_new(NULL); - const char *ch; - gchar *basename; - - BT_ASSERT(san_file_name); - BT_ASSERT(file_name); - basename = g_path_get_basename(file_name); - - for (ch = basename; *ch != '\0'; ch++) { - if (*ch == '/') { - g_string_append_c(san_file_name, '_'); - } else { - g_string_append_c(san_file_name, *ch); - } - } - - /* Do not allow `.` and `..` either */ - if (strcmp(san_file_name->str, ".") == 0 || - strcmp(san_file_name->str, "..") == 0) { - g_string_assign(san_file_name, "stream"); - } - - g_free(basename); - return san_file_name; + GString *san_file_name = g_string_new(NULL); + const char *ch; + gchar *basename; + + BT_ASSERT(san_file_name); + BT_ASSERT(file_name); + basename = g_path_get_basename(file_name); + + for (ch = basename; *ch != '\0'; ch++) { + if (*ch == '/') { + g_string_append_c(san_file_name, '_'); + } else { + g_string_append_c(san_file_name, *ch); + } + } + + /* Do not allow `.` and `..` either */ + if (strcmp(san_file_name->str, ".") == 0 || strcmp(san_file_name->str, "..") == 0) { + g_string_assign(san_file_name, "stream"); + } + + g_free(basename); + return san_file_name; } -static -GString *make_unique_stream_file_name(struct fs_sink_trace *trace, - const char *base) +static GString *make_unique_stream_file_name(struct fs_sink_trace *trace, const char *base) { - GString *san_base = sanitize_stream_file_name(base); - GString *name = g_string_new(san_base->str); - unsigned int suffix = 0; + GString *san_base = sanitize_stream_file_name(base); + GString *name = g_string_new(san_base->str); + unsigned int suffix = 0; - BT_ASSERT(name); + BT_ASSERT(name); - while (stream_file_name_exists(trace, name->str) || - strcmp(name->str, "metadata") == 0) { - g_string_printf(name, "%s-%u", san_base->str, suffix); - suffix++; - } + while (stream_file_name_exists(trace, name->str) || strcmp(name->str, "metadata") == 0) { + g_string_printf(name, "%s-%u", san_base->str, suffix); + suffix++; + } - g_string_free(san_base, TRUE); - return name; + g_string_free(san_base, TRUE); + return name; } -static -void set_stream_file_name(struct fs_sink_stream *stream) +static void set_stream_file_name(struct fs_sink_stream *stream) { - const char *base_name = bt_stream_get_name(stream->ir_stream); + const char *base_name = bt_stream_get_name(stream->ir_stream); - if (!base_name) { - base_name = "stream"; - } + if (!base_name) { + base_name = "stream"; + } - BT_ASSERT(!stream->file_name); - stream->file_name = make_unique_stream_file_name(stream->trace, - base_name); + BT_ASSERT(!stream->file_name); + stream->file_name = make_unique_stream_file_name(stream->trace, base_name); } BT_HIDDEN struct fs_sink_stream *fs_sink_stream_create(struct fs_sink_trace *trace, - const bt_stream *ir_stream) + const bt_stream *ir_stream) { - struct fs_sink_stream *stream = g_new0(struct fs_sink_stream, 1); - int ret; - GString *path = g_string_new(trace->path->str); - - if (!stream) { - goto end; - } - - stream->log_level = trace->log_level; - stream->trace = trace; - stream->ir_stream = ir_stream; - stream->packet_state.beginning_cs = UINT64_C(-1); - stream->packet_state.end_cs = UINT64_C(-1); - stream->prev_packet_state.end_cs = UINT64_C(-1); - stream->prev_packet_state.discarded_events_counter = UINT64_C(-1); - stream->prev_packet_state.seq_num = UINT64_C(-1); - ret = try_translate_stream_class_trace_ir_to_ctf_ir(trace->fs_sink, - trace->trace, bt_stream_borrow_class_const(ir_stream), - &stream->sc); - if (ret) { - goto error; - } - - set_stream_file_name(stream); - g_string_append_printf(path, "/%s", stream->file_name->str); - ret = bt_ctfser_init(&stream->ctfser, path->str, - stream->log_level); - if (ret) { - goto error; - } - - g_hash_table_insert(trace->streams, (gpointer) ir_stream, stream); - goto end; + struct fs_sink_stream *stream = g_new0(struct fs_sink_stream, 1); + int ret; + GString *path = g_string_new(trace->path->str); + + if (!stream) { + goto end; + } + + stream->log_level = trace->log_level; + stream->trace = trace; + stream->ir_stream = ir_stream; + stream->packet_state.beginning_cs = UINT64_C(-1); + stream->packet_state.end_cs = UINT64_C(-1); + stream->prev_packet_state.end_cs = UINT64_C(-1); + stream->prev_packet_state.discarded_events_counter = UINT64_C(-1); + stream->prev_packet_state.seq_num = UINT64_C(-1); + ret = try_translate_stream_class_trace_ir_to_ctf_ir( + trace->fs_sink, trace->trace, bt_stream_borrow_class_const(ir_stream), &stream->sc); + if (ret) { + goto error; + } + + set_stream_file_name(stream); + g_string_append_printf(path, "/%s", stream->file_name->str); + ret = bt_ctfser_init(&stream->ctfser, path->str, stream->log_level); + if (ret) { + goto error; + } + + g_hash_table_insert(trace->streams, (gpointer) ir_stream, stream); + goto end; error: - fs_sink_stream_destroy(stream); - stream = NULL; + fs_sink_stream_destroy(stream); + stream = NULL; end: - if (path) { - g_string_free(path, TRUE); - } + if (path) { + g_string_free(path, TRUE); + } - return stream; + return stream; } -static -int write_field(struct fs_sink_stream *stream, - struct fs_sink_ctf_field_class *fc, const bt_field *field); +static int write_field(struct fs_sink_stream *stream, struct fs_sink_ctf_field_class *fc, + const bt_field *field); -static inline -int write_bool_field(struct fs_sink_stream *stream, - struct fs_sink_ctf_field_class_bool *fc, const bt_field *field) +static inline int write_bool_field(struct fs_sink_stream *stream, + struct fs_sink_ctf_field_class_bool *fc, const bt_field *field) { - /* - * CTF 1.8 has no boolean field class type, so this component - * translates this boolean field to an 8-bit unsigned integer - * field which has the value 0 (false) or 1 (true). - */ - return bt_ctfser_write_unsigned_int(&stream->ctfser, - bt_field_bool_get_value(field) ? 1 : 0, - fc->base.base.alignment, fc->base.size, BYTE_ORDER); + /* + * CTF 1.8 has no boolean field class type, so this component + * translates this boolean field to an 8-bit unsigned integer + * field which has the value 0 (false) or 1 (true). + */ + return bt_ctfser_write_unsigned_int(&stream->ctfser, bt_field_bool_get_value(field) ? 1 : 0, + fc->base.base.alignment, fc->base.size, BYTE_ORDER); } -static inline -int write_bit_array_field(struct fs_sink_stream *stream, - struct fs_sink_ctf_field_class_bit_array *fc, - const bt_field *field) +static inline int write_bit_array_field(struct fs_sink_stream *stream, + struct fs_sink_ctf_field_class_bit_array *fc, + const bt_field *field) { - /* - * CTF 1.8 has no bit array field class type, so this component - * translates this bit array field to an unsigned integer field. - */ - return bt_ctfser_write_unsigned_int(&stream->ctfser, - bt_field_bit_array_get_value_as_integer(field), - fc->base.alignment, fc->size, BYTE_ORDER); + /* + * CTF 1.8 has no bit array field class type, so this component + * translates this bit array field to an unsigned integer field. + */ + return bt_ctfser_write_unsigned_int(&stream->ctfser, + bt_field_bit_array_get_value_as_integer(field), + fc->base.alignment, fc->size, BYTE_ORDER); } -static inline -int write_int_field(struct fs_sink_stream *stream, - struct fs_sink_ctf_field_class_int *fc, const bt_field *field) +static inline int write_int_field(struct fs_sink_stream *stream, + struct fs_sink_ctf_field_class_int *fc, const bt_field *field) { - int ret; - - if (fc->is_signed) { - ret = bt_ctfser_write_signed_int(&stream->ctfser, - bt_field_integer_signed_get_value(field), - fc->base.base.alignment, fc->base.size, BYTE_ORDER); - } else { - ret = bt_ctfser_write_unsigned_int(&stream->ctfser, - bt_field_integer_unsigned_get_value(field), - fc->base.base.alignment, fc->base.size, BYTE_ORDER); - } - - return ret; + int ret; + + if (fc->is_signed) { + ret = bt_ctfser_write_signed_int(&stream->ctfser, bt_field_integer_signed_get_value(field), + fc->base.base.alignment, fc->base.size, BYTE_ORDER); + } else { + ret = bt_ctfser_write_unsigned_int(&stream->ctfser, + bt_field_integer_unsigned_get_value(field), + fc->base.base.alignment, fc->base.size, BYTE_ORDER); + } + + return ret; } -static inline -int write_float_field(struct fs_sink_stream *stream, - struct fs_sink_ctf_field_class_float *fc, const bt_field *field) +static inline int write_float_field(struct fs_sink_stream *stream, + struct fs_sink_ctf_field_class_float *fc, const bt_field *field) { - int ret; - double val; - - if (fc->base.size == 32) { - val = (double) bt_field_real_single_precision_get_value(field); - ret = bt_ctfser_write_float32(&stream->ctfser, val, - fc->base.base.alignment, BYTE_ORDER); - } else { - val = bt_field_real_double_precision_get_value(field); - ret = bt_ctfser_write_float64(&stream->ctfser, val, - fc->base.base.alignment, BYTE_ORDER); - } - - return ret; + int ret; + double val; + + if (fc->base.size == 32) { + val = (double) bt_field_real_single_precision_get_value(field); + ret = bt_ctfser_write_float32(&stream->ctfser, val, fc->base.base.alignment, BYTE_ORDER); + } else { + val = bt_field_real_double_precision_get_value(field); + ret = bt_ctfser_write_float64(&stream->ctfser, val, fc->base.base.alignment, BYTE_ORDER); + } + + return ret; } -static inline -int write_string_field(struct fs_sink_stream *stream, - struct fs_sink_ctf_field_class_string *fc, const bt_field *field) +static inline int write_string_field(struct fs_sink_stream *stream, + struct fs_sink_ctf_field_class_string *fc, + const bt_field *field) { - return bt_ctfser_write_string(&stream->ctfser, - bt_field_string_get_value(field)); + return bt_ctfser_write_string(&stream->ctfser, bt_field_string_get_value(field)); } -static inline -int write_array_base_field_elements(struct fs_sink_stream *stream, - struct fs_sink_ctf_field_class_array_base *fc, - const bt_field *field) +static inline int write_array_base_field_elements(struct fs_sink_stream *stream, + struct fs_sink_ctf_field_class_array_base *fc, + const bt_field *field) { - uint64_t i; - uint64_t len = bt_field_array_get_length(field); - int ret = 0; - - for (i = 0; i < len; i++) { - const bt_field *elem_field = - bt_field_array_borrow_element_field_by_index_const( - field, i); - ret = write_field(stream, fc->elem_fc, elem_field); - if (G_UNLIKELY(ret)) { - goto end; - } - } + uint64_t i; + uint64_t len = bt_field_array_get_length(field); + int ret = 0; + + for (i = 0; i < len; i++) { + const bt_field *elem_field = bt_field_array_borrow_element_field_by_index_const(field, i); + ret = write_field(stream, fc->elem_fc, elem_field); + if (G_UNLIKELY(ret)) { + goto end; + } + } end: - return ret; + return ret; } -static inline -int write_sequence_field(struct fs_sink_stream *stream, - struct fs_sink_ctf_field_class_sequence *fc, - const bt_field *field) +static inline int write_sequence_field(struct fs_sink_stream *stream, + struct fs_sink_ctf_field_class_sequence *fc, + const bt_field *field) { - int ret; + int ret; - if (fc->length_is_before) { - ret = bt_ctfser_write_unsigned_int(&stream->ctfser, - bt_field_array_get_length(field), 8, 32, BYTE_ORDER); - if (G_UNLIKELY(ret)) { - goto end; - } - } + if (fc->length_is_before) { + ret = bt_ctfser_write_unsigned_int(&stream->ctfser, bt_field_array_get_length(field), 8, 32, + BYTE_ORDER); + if (G_UNLIKELY(ret)) { + goto end; + } + } - ret = write_array_base_field_elements(stream, &fc->base, field); + ret = write_array_base_field_elements(stream, &fc->base, field); end: - return ret; + return ret; } -static inline -int write_struct_field(struct fs_sink_stream *stream, - struct fs_sink_ctf_field_class_struct *fc, - const bt_field *field, bool align_struct) +static inline int write_struct_field(struct fs_sink_stream *stream, + struct fs_sink_ctf_field_class_struct *fc, + const bt_field *field, bool align_struct) { - int ret = 0; - uint64_t i; - - if (G_LIKELY(align_struct)) { - ret = bt_ctfser_align_offset_in_current_packet(&stream->ctfser, - fc->base.alignment); - if (G_UNLIKELY(ret)) { - goto end; - } - } - - for (i = 0; i < fc->members->len; i++) { - const bt_field *memb_field = - bt_field_structure_borrow_member_field_by_index_const( - field, i); - struct fs_sink_ctf_field_class *member_fc = - fs_sink_ctf_field_class_struct_borrow_member_by_index( - fc, i)->fc; - - ret = write_field(stream, member_fc, memb_field); - if (G_UNLIKELY(ret)) { - goto end; - } - } + int ret = 0; + uint64_t i; + + if (G_LIKELY(align_struct)) { + ret = bt_ctfser_align_offset_in_current_packet(&stream->ctfser, fc->base.alignment); + if (G_UNLIKELY(ret)) { + goto end; + } + } + + for (i = 0; i < fc->members->len; i++) { + const bt_field *memb_field = + bt_field_structure_borrow_member_field_by_index_const(field, i); + struct fs_sink_ctf_field_class *member_fc = + fs_sink_ctf_field_class_struct_borrow_member_by_index(fc, i)->fc; + + ret = write_field(stream, member_fc, memb_field); + if (G_UNLIKELY(ret)) { + goto end; + } + } end: - return ret; + return ret; } -static inline -int write_option_field(struct fs_sink_stream *stream, - struct fs_sink_ctf_field_class_option *fc, - const bt_field *field) +static inline int write_option_field(struct fs_sink_stream *stream, + struct fs_sink_ctf_field_class_option *fc, + const bt_field *field) { - int ret; - const bt_field *content_field = - bt_field_option_borrow_field_const(field); - - ret = bt_ctfser_write_unsigned_int(&stream->ctfser, - content_field ? 1 : 0, 8, 8, BYTE_ORDER); - if (G_UNLIKELY(ret)) { - goto end; - } - - /* - * CTF 1.8 has no option field class type, so this component - * translates the option field class to a variant field class - * where the options are: - * - * * An empty structure field class (field occupies 0 bits). - * * The optional field class itself. - * - * If `content_field` is `NULL`, do not write anything (empty - * structure). - */ - if (content_field) { - ret = write_field(stream, fc->content_fc, content_field); - } + int ret; + const bt_field *content_field = bt_field_option_borrow_field_const(field); + + ret = bt_ctfser_write_unsigned_int(&stream->ctfser, content_field ? 1 : 0, 8, 8, BYTE_ORDER); + if (G_UNLIKELY(ret)) { + goto end; + } + + /* + * CTF 1.8 has no option field class type, so this component + * translates the option field class to a variant field class + * where the options are: + * + * * An empty structure field class (field occupies 0 bits). + * * The optional field class itself. + * + * If `content_field` is `NULL`, do not write anything (empty + * structure). + */ + if (content_field) { + ret = write_field(stream, fc->content_fc, content_field); + } end: - return ret; + return ret; } -static inline -int write_variant_field(struct fs_sink_stream *stream, - struct fs_sink_ctf_field_class_variant *fc, - const bt_field *field) +static inline int write_variant_field(struct fs_sink_stream *stream, + struct fs_sink_ctf_field_class_variant *fc, + const bt_field *field) { - uint64_t opt_index = - bt_field_variant_get_selected_option_index(field); - int ret; - - if (fc->tag_is_before) { - ret = bt_ctfser_write_unsigned_int(&stream->ctfser, - opt_index, 8, 16, BYTE_ORDER); - if (G_UNLIKELY(ret)) { - goto end; - } - } - - ret = write_field(stream, - fs_sink_ctf_field_class_variant_borrow_option_by_index(fc, - opt_index)->fc, - bt_field_variant_borrow_selected_option_field_const(field)); + uint64_t opt_index = bt_field_variant_get_selected_option_index(field); + int ret; + + if (fc->tag_is_before) { + ret = bt_ctfser_write_unsigned_int(&stream->ctfser, opt_index, 8, 16, BYTE_ORDER); + if (G_UNLIKELY(ret)) { + goto end; + } + } + + ret = write_field(stream, + fs_sink_ctf_field_class_variant_borrow_option_by_index(fc, opt_index)->fc, + bt_field_variant_borrow_selected_option_field_const(field)); end: - return ret; + return ret; } -static -int write_field(struct fs_sink_stream *stream, - struct fs_sink_ctf_field_class *fc, const bt_field *field) +static int write_field(struct fs_sink_stream *stream, struct fs_sink_ctf_field_class *fc, + const bt_field *field) { - int ret; - - switch (fc->type) { - case FS_SINK_CTF_FIELD_CLASS_TYPE_BOOL: - ret = write_bool_field(stream, - fs_sink_ctf_field_class_as_bool(fc), field); - break; - case FS_SINK_CTF_FIELD_CLASS_TYPE_BIT_ARRAY: - ret = write_bit_array_field(stream, - fs_sink_ctf_field_class_as_bit_array(fc), field); - break; - case FS_SINK_CTF_FIELD_CLASS_TYPE_INT: - ret = write_int_field(stream, - fs_sink_ctf_field_class_as_int(fc), field); - break; - case FS_SINK_CTF_FIELD_CLASS_TYPE_FLOAT: - ret = write_float_field(stream, - fs_sink_ctf_field_class_as_float(fc), field); - break; - case FS_SINK_CTF_FIELD_CLASS_TYPE_STRING: - ret = write_string_field(stream, - fs_sink_ctf_field_class_as_string(fc), field); - break; - case FS_SINK_CTF_FIELD_CLASS_TYPE_STRUCT: - ret = write_struct_field(stream, - fs_sink_ctf_field_class_as_struct(fc), field, true); - break; - case FS_SINK_CTF_FIELD_CLASS_TYPE_ARRAY: - ret = write_array_base_field_elements(stream, - fs_sink_ctf_field_class_as_array_base(fc), field); - break; - case FS_SINK_CTF_FIELD_CLASS_TYPE_SEQUENCE: - ret = write_sequence_field(stream, - fs_sink_ctf_field_class_as_sequence(fc), field); - break; - case FS_SINK_CTF_FIELD_CLASS_TYPE_OPTION: - ret = write_option_field(stream, - fs_sink_ctf_field_class_as_option(fc), field); - break; - case FS_SINK_CTF_FIELD_CLASS_TYPE_VARIANT: - ret = write_variant_field(stream, - fs_sink_ctf_field_class_as_variant(fc), field); - break; - default: - bt_common_abort(); - } - - return ret; + int ret; + + switch (fc->type) { + case FS_SINK_CTF_FIELD_CLASS_TYPE_BOOL: + ret = write_bool_field(stream, fs_sink_ctf_field_class_as_bool(fc), field); + break; + case FS_SINK_CTF_FIELD_CLASS_TYPE_BIT_ARRAY: + ret = write_bit_array_field(stream, fs_sink_ctf_field_class_as_bit_array(fc), field); + break; + case FS_SINK_CTF_FIELD_CLASS_TYPE_INT: + ret = write_int_field(stream, fs_sink_ctf_field_class_as_int(fc), field); + break; + case FS_SINK_CTF_FIELD_CLASS_TYPE_FLOAT: + ret = write_float_field(stream, fs_sink_ctf_field_class_as_float(fc), field); + break; + case FS_SINK_CTF_FIELD_CLASS_TYPE_STRING: + ret = write_string_field(stream, fs_sink_ctf_field_class_as_string(fc), field); + break; + case FS_SINK_CTF_FIELD_CLASS_TYPE_STRUCT: + ret = write_struct_field(stream, fs_sink_ctf_field_class_as_struct(fc), field, true); + break; + case FS_SINK_CTF_FIELD_CLASS_TYPE_ARRAY: + ret = write_array_base_field_elements(stream, fs_sink_ctf_field_class_as_array_base(fc), + field); + break; + case FS_SINK_CTF_FIELD_CLASS_TYPE_SEQUENCE: + ret = write_sequence_field(stream, fs_sink_ctf_field_class_as_sequence(fc), field); + break; + case FS_SINK_CTF_FIELD_CLASS_TYPE_OPTION: + ret = write_option_field(stream, fs_sink_ctf_field_class_as_option(fc), field); + break; + case FS_SINK_CTF_FIELD_CLASS_TYPE_VARIANT: + ret = write_variant_field(stream, fs_sink_ctf_field_class_as_variant(fc), field); + break; + default: + bt_common_abort(); + } + + return ret; } -static inline -int write_event_header(struct fs_sink_stream *stream, - const bt_clock_snapshot *cs, struct fs_sink_ctf_event_class *ec) +static inline int write_event_header(struct fs_sink_stream *stream, const bt_clock_snapshot *cs, + struct fs_sink_ctf_event_class *ec) { - int ret; - - /* Event class ID */ - ret = bt_ctfser_write_byte_aligned_unsigned_int(&stream->ctfser, - bt_event_class_get_id(ec->ir_ec), 8, 64, BYTE_ORDER); - if (G_UNLIKELY(ret)) { - goto end; - } - - /* Time */ - if (stream->sc->default_clock_class) { - BT_ASSERT_DBG(cs); - ret = bt_ctfser_write_byte_aligned_unsigned_int(&stream->ctfser, - bt_clock_snapshot_get_value(cs), 8, 64, BYTE_ORDER); - if (G_UNLIKELY(ret)) { - goto end; - } - } + int ret; + + /* Event class ID */ + ret = bt_ctfser_write_byte_aligned_unsigned_int( + &stream->ctfser, bt_event_class_get_id(ec->ir_ec), 8, 64, BYTE_ORDER); + if (G_UNLIKELY(ret)) { + goto end; + } + + /* Time */ + if (stream->sc->default_clock_class) { + BT_ASSERT_DBG(cs); + ret = bt_ctfser_write_byte_aligned_unsigned_int( + &stream->ctfser, bt_clock_snapshot_get_value(cs), 8, 64, BYTE_ORDER); + if (G_UNLIKELY(ret)) { + goto end; + } + } end: - return ret; + return ret; } BT_HIDDEN -int fs_sink_stream_write_event(struct fs_sink_stream *stream, - const bt_clock_snapshot *cs, const bt_event *event, - struct fs_sink_ctf_event_class *ec) +int fs_sink_stream_write_event(struct fs_sink_stream *stream, const bt_clock_snapshot *cs, + const bt_event *event, struct fs_sink_ctf_event_class *ec) { - int ret; - const bt_field *field; - - /* Header */ - ret = write_event_header(stream, cs, ec); - if (G_UNLIKELY(ret)) { - goto end; - } - - /* Common context */ - if (stream->sc->event_common_context_fc) { - field = bt_event_borrow_common_context_field_const(event); - BT_ASSERT_DBG(field); - ret = write_struct_field(stream, - fs_sink_ctf_field_class_as_struct(stream->sc->event_common_context_fc), - field, true); - if (G_UNLIKELY(ret)) { - goto end; - } - } - - /* Specific context */ - if (ec->spec_context_fc) { - field = bt_event_borrow_specific_context_field_const(event); - BT_ASSERT_DBG(field); - ret = write_struct_field(stream, - fs_sink_ctf_field_class_as_struct(ec->spec_context_fc), - field, true); - if (G_UNLIKELY(ret)) { - goto end; - } - } - - /* Specific context */ - if (ec->payload_fc) { - field = bt_event_borrow_payload_field_const(event); - BT_ASSERT_DBG(field); - ret = write_struct_field(stream, - fs_sink_ctf_field_class_as_struct(ec->payload_fc), - field, true); - if (G_UNLIKELY(ret)) { - goto end; - } - } + int ret; + const bt_field *field; + + /* Header */ + ret = write_event_header(stream, cs, ec); + if (G_UNLIKELY(ret)) { + goto end; + } + + /* Common context */ + if (stream->sc->event_common_context_fc) { + field = bt_event_borrow_common_context_field_const(event); + BT_ASSERT_DBG(field); + ret = write_struct_field( + stream, fs_sink_ctf_field_class_as_struct(stream->sc->event_common_context_fc), field, + true); + if (G_UNLIKELY(ret)) { + goto end; + } + } + + /* Specific context */ + if (ec->spec_context_fc) { + field = bt_event_borrow_specific_context_field_const(event); + BT_ASSERT_DBG(field); + ret = write_struct_field(stream, fs_sink_ctf_field_class_as_struct(ec->spec_context_fc), + field, true); + if (G_UNLIKELY(ret)) { + goto end; + } + } + + /* Specific context */ + if (ec->payload_fc) { + field = bt_event_borrow_payload_field_const(event); + BT_ASSERT_DBG(field); + ret = write_struct_field(stream, fs_sink_ctf_field_class_as_struct(ec->payload_fc), field, + true); + if (G_UNLIKELY(ret)) { + goto end; + } + } end: - return ret; + return ret; } -static -int write_packet_context(struct fs_sink_stream *stream) +static int write_packet_context(struct fs_sink_stream *stream) { - int ret; - - /* Packet total size */ - ret = bt_ctfser_write_byte_aligned_unsigned_int(&stream->ctfser, - stream->packet_state.total_size, 8, 64, BYTE_ORDER); - if (ret) { - goto end; - } - - /* Packet content size */ - ret = bt_ctfser_write_byte_aligned_unsigned_int(&stream->ctfser, - stream->packet_state.content_size, 8, 64, BYTE_ORDER); - if (ret) { - goto end; - } - - if (stream->sc->packets_have_ts_begin) { - /* Beginning time */ - ret = bt_ctfser_write_byte_aligned_unsigned_int(&stream->ctfser, - stream->packet_state.beginning_cs, 8, 64, BYTE_ORDER); - if (ret) { - goto end; - } - } - - if (stream->sc->packets_have_ts_end) { - /* End time */ - ret = bt_ctfser_write_byte_aligned_unsigned_int(&stream->ctfser, - stream->packet_state.end_cs, 8, 64, BYTE_ORDER); - if (ret) { - goto end; - } - } - - if (stream->sc->has_discarded_events) { - /* Discarded event counter */ - ret = bt_ctfser_write_byte_aligned_unsigned_int(&stream->ctfser, - stream->packet_state.discarded_events_counter, 8, 64, - BYTE_ORDER); - if (ret) { - goto end; - } - } - - /* Sequence number */ - ret = bt_ctfser_write_byte_aligned_unsigned_int(&stream->ctfser, - stream->packet_state.seq_num, 8, 64, BYTE_ORDER); - if (ret) { - goto end; - } - - /* Other members */ - if (stream->sc->packet_context_fc) { - const bt_field *packet_context_field; - - BT_ASSERT(stream->packet_state.packet); - packet_context_field = bt_packet_borrow_context_field_const( - stream->packet_state.packet); - BT_ASSERT(packet_context_field); - ret = write_struct_field(stream, - fs_sink_ctf_field_class_as_struct(stream->sc->packet_context_fc), - packet_context_field, false); - if (ret) { - goto end; - } - } + int ret; + + /* Packet total size */ + ret = bt_ctfser_write_byte_aligned_unsigned_int( + &stream->ctfser, stream->packet_state.total_size, 8, 64, BYTE_ORDER); + if (ret) { + goto end; + } + + /* Packet content size */ + ret = bt_ctfser_write_byte_aligned_unsigned_int( + &stream->ctfser, stream->packet_state.content_size, 8, 64, BYTE_ORDER); + if (ret) { + goto end; + } + + if (stream->sc->packets_have_ts_begin) { + /* Beginning time */ + ret = bt_ctfser_write_byte_aligned_unsigned_int( + &stream->ctfser, stream->packet_state.beginning_cs, 8, 64, BYTE_ORDER); + if (ret) { + goto end; + } + } + + if (stream->sc->packets_have_ts_end) { + /* End time */ + ret = bt_ctfser_write_byte_aligned_unsigned_int( + &stream->ctfser, stream->packet_state.end_cs, 8, 64, BYTE_ORDER); + if (ret) { + goto end; + } + } + + if (stream->sc->has_discarded_events) { + /* Discarded event counter */ + ret = bt_ctfser_write_byte_aligned_unsigned_int( + &stream->ctfser, stream->packet_state.discarded_events_counter, 8, 64, BYTE_ORDER); + if (ret) { + goto end; + } + } + + /* Sequence number */ + ret = bt_ctfser_write_byte_aligned_unsigned_int(&stream->ctfser, stream->packet_state.seq_num, + 8, 64, BYTE_ORDER); + if (ret) { + goto end; + } + + /* Other members */ + if (stream->sc->packet_context_fc) { + const bt_field *packet_context_field; + + BT_ASSERT(stream->packet_state.packet); + packet_context_field = bt_packet_borrow_context_field_const(stream->packet_state.packet); + BT_ASSERT(packet_context_field); + ret = write_struct_field(stream, + fs_sink_ctf_field_class_as_struct(stream->sc->packet_context_fc), + packet_context_field, false); + if (ret) { + goto end; + } + } end: - return ret; + return ret; } BT_HIDDEN -int fs_sink_stream_open_packet(struct fs_sink_stream *stream, - const bt_clock_snapshot *cs, const bt_packet *packet) +int fs_sink_stream_open_packet(struct fs_sink_stream *stream, const bt_clock_snapshot *cs, + const bt_packet *packet) { - int ret; - uint64_t i; - - BT_ASSERT(!stream->packet_state.is_open); - bt_packet_put_ref(stream->packet_state.packet); - stream->packet_state.packet = packet; - bt_packet_get_ref(stream->packet_state.packet); - if (cs) { - stream->packet_state.beginning_cs = - bt_clock_snapshot_get_value(cs); - } - - /* Open packet */ - ret = bt_ctfser_open_packet(&stream->ctfser); - if (ret) { - /* bt_ctfser_open_packet() logs errors */ - goto end; - } - - /* Packet header: magic */ - ret = bt_ctfser_write_byte_aligned_unsigned_int(&stream->ctfser, - UINT64_C(0xc1fc1fc1), 8, 32, BYTE_ORDER); - if (ret) { - BT_COMP_LOGE("Error writing packet header magic: stream-file-name=%s", - stream->file_name->str); - goto end; - } - - /* Packet header: UUID */ - for (i = 0; i < BT_UUID_LEN; i++) { - ret = bt_ctfser_write_byte_aligned_unsigned_int(&stream->ctfser, - (uint64_t) stream->sc->trace->uuid[i], 8, 8, BYTE_ORDER); - if (ret) { - BT_COMP_LOGE("Error writing packet header UUID: stream-file-name=%s", - stream->file_name->str); - goto end; - } - } - - /* Packet header: stream class ID */ - ret = bt_ctfser_write_byte_aligned_unsigned_int(&stream->ctfser, - bt_stream_class_get_id(stream->sc->ir_sc), 8, 64, BYTE_ORDER); - if (ret) { - BT_COMP_LOGE("Error writing packet header stream class id: " - "stream-file-name=%s, stream-class-id=%" PRIu64, - stream->file_name->str, - bt_stream_class_get_id(stream->sc->ir_sc)); - goto end; - } - - /* Packet header: stream ID */ - ret = bt_ctfser_write_byte_aligned_unsigned_int(&stream->ctfser, - bt_stream_get_id(stream->ir_stream), 8, 64, BYTE_ORDER); - if (ret) { - BT_COMP_LOGE("Error writing packet header stream id: " - "stream-file-name=%s, stream-id=%" PRIu64, - stream->file_name->str, - bt_stream_get_id(stream->ir_stream)); - goto end; - } - - /* Save packet context's offset to rewrite it later */ - stream->packet_state.context_offset_bits = - bt_ctfser_get_offset_in_current_packet_bits(&stream->ctfser); - - /* Write packet context just to advance to content (first event) */ - ret = write_packet_context(stream); - if (ret) { - goto end; - } - - stream->packet_state.is_open = true; + int ret; + uint64_t i; + + BT_ASSERT(!stream->packet_state.is_open); + bt_packet_put_ref(stream->packet_state.packet); + stream->packet_state.packet = packet; + bt_packet_get_ref(stream->packet_state.packet); + if (cs) { + stream->packet_state.beginning_cs = bt_clock_snapshot_get_value(cs); + } + + /* Open packet */ + ret = bt_ctfser_open_packet(&stream->ctfser); + if (ret) { + /* bt_ctfser_open_packet() logs errors */ + goto end; + } + + /* Packet header: magic */ + ret = bt_ctfser_write_byte_aligned_unsigned_int(&stream->ctfser, UINT64_C(0xc1fc1fc1), 8, 32, + BYTE_ORDER); + if (ret) { + BT_COMP_LOGE("Error writing packet header magic: stream-file-name=%s", + stream->file_name->str); + goto end; + } + + /* Packet header: UUID */ + for (i = 0; i < BT_UUID_LEN; i++) { + ret = bt_ctfser_write_byte_aligned_unsigned_int( + &stream->ctfser, (uint64_t) stream->sc->trace->uuid[i], 8, 8, BYTE_ORDER); + if (ret) { + BT_COMP_LOGE("Error writing packet header UUID: stream-file-name=%s", + stream->file_name->str); + goto end; + } + } + + /* Packet header: stream class ID */ + ret = bt_ctfser_write_byte_aligned_unsigned_int( + &stream->ctfser, bt_stream_class_get_id(stream->sc->ir_sc), 8, 64, BYTE_ORDER); + if (ret) { + BT_COMP_LOGE("Error writing packet header stream class id: " + "stream-file-name=%s, stream-class-id=%" PRIu64, + stream->file_name->str, bt_stream_class_get_id(stream->sc->ir_sc)); + goto end; + } + + /* Packet header: stream ID */ + ret = bt_ctfser_write_byte_aligned_unsigned_int( + &stream->ctfser, bt_stream_get_id(stream->ir_stream), 8, 64, BYTE_ORDER); + if (ret) { + BT_COMP_LOGE("Error writing packet header stream id: " + "stream-file-name=%s, stream-id=%" PRIu64, + stream->file_name->str, bt_stream_get_id(stream->ir_stream)); + goto end; + } + + /* Save packet context's offset to rewrite it later */ + stream->packet_state.context_offset_bits = + bt_ctfser_get_offset_in_current_packet_bits(&stream->ctfser); + + /* Write packet context just to advance to content (first event) */ + ret = write_packet_context(stream); + if (ret) { + goto end; + } + + stream->packet_state.is_open = true; end: - return ret; + return ret; } BT_HIDDEN -int fs_sink_stream_close_packet(struct fs_sink_stream *stream, - const bt_clock_snapshot *cs) +int fs_sink_stream_close_packet(struct fs_sink_stream *stream, const bt_clock_snapshot *cs) { - int ret; - - BT_ASSERT(stream->packet_state.is_open); - - if (cs) { - stream->packet_state.end_cs = bt_clock_snapshot_get_value(cs); - } - - stream->packet_state.content_size = - bt_ctfser_get_offset_in_current_packet_bits(&stream->ctfser); - stream->packet_state.total_size = - (stream->packet_state.content_size + 7) & ~UINT64_C(7); - - /* Rewrite packet context */ - bt_ctfser_set_offset_in_current_packet_bits(&stream->ctfser, - stream->packet_state.context_offset_bits); - ret = write_packet_context(stream); - if (ret) { - goto end; - } - - /* Close packet */ - bt_ctfser_close_current_packet(&stream->ctfser, - stream->packet_state.total_size / 8); - - /* Partially copy current packet state to previous packet state */ - stream->prev_packet_state.end_cs = stream->packet_state.end_cs; - stream->prev_packet_state.discarded_events_counter = - stream->packet_state.discarded_events_counter; - stream->prev_packet_state.seq_num = - stream->packet_state.seq_num; - - /* Reset current packet state */ - stream->packet_state.beginning_cs = UINT64_C(-1); - stream->packet_state.end_cs = UINT64_C(-1); - stream->packet_state.content_size = 0; - stream->packet_state.total_size = 0; - stream->packet_state.seq_num += 1; - stream->packet_state.context_offset_bits = 0; - stream->packet_state.is_open = false; - BT_PACKET_PUT_REF_AND_RESET(stream->packet_state.packet); + int ret; + + BT_ASSERT(stream->packet_state.is_open); + + if (cs) { + stream->packet_state.end_cs = bt_clock_snapshot_get_value(cs); + } + + stream->packet_state.content_size = + bt_ctfser_get_offset_in_current_packet_bits(&stream->ctfser); + stream->packet_state.total_size = (stream->packet_state.content_size + 7) & ~UINT64_C(7); + + /* Rewrite packet context */ + bt_ctfser_set_offset_in_current_packet_bits(&stream->ctfser, + stream->packet_state.context_offset_bits); + ret = write_packet_context(stream); + if (ret) { + goto end; + } + + /* Close packet */ + bt_ctfser_close_current_packet(&stream->ctfser, stream->packet_state.total_size / 8); + + /* Partially copy current packet state to previous packet state */ + stream->prev_packet_state.end_cs = stream->packet_state.end_cs; + stream->prev_packet_state.discarded_events_counter = + stream->packet_state.discarded_events_counter; + stream->prev_packet_state.seq_num = stream->packet_state.seq_num; + + /* Reset current packet state */ + stream->packet_state.beginning_cs = UINT64_C(-1); + stream->packet_state.end_cs = UINT64_C(-1); + stream->packet_state.content_size = 0; + stream->packet_state.total_size = 0; + stream->packet_state.seq_num += 1; + stream->packet_state.context_offset_bits = 0; + stream->packet_state.is_open = false; + BT_PACKET_PUT_REF_AND_RESET(stream->packet_state.packet); end: - return ret; + return ret; } diff --git a/src/plugins/ctf/fs-sink/fs-sink-stream.hpp b/src/plugins/ctf/fs-sink/fs-sink-stream.hpp index 3a1e1707..54657fe7 100644 --- a/src/plugins/ctf/fs-sink/fs-sink-stream.hpp +++ b/src/plugins/ctf/fs-sink/fs-sink-stream.hpp @@ -18,162 +18,165 @@ struct fs_sink_trace; -struct fs_sink_stream { - bt_logging_level log_level; - struct fs_sink_trace *trace; - struct bt_ctfser ctfser; - - /* Stream's file name */ - GString *file_name; - - /* Weak */ - const bt_stream *ir_stream; - - struct fs_sink_ctf_stream_class *sc; - - /* Current packet's state */ - struct { - /* - * True if we're, for this stream, within an opened - * packet (got a packet beginning message, but no - * packet end message yet). - */ - bool is_open; - - /* - * Current beginning default clock snapshot for the - * current packet (`UINT64_C(-1)` if not set). - */ - uint64_t beginning_cs; - - /* - * Current end default clock snapshot for the current - * packet (`UINT64_C(-1)` if not set). - */ - uint64_t end_cs; - - /* - * Current packet's content size (bits) for the current - * packet. - */ - uint64_t content_size; - - /* - * Current packet's total size (bits) for the current - * packet. - */ - uint64_t total_size; - - /* - * Discarded events (free running) counter for the - * current packet. - */ - uint64_t discarded_events_counter; - - /* Sequence number (free running) of the current packet */ - uint64_t seq_num; - - /* - * Offset of the packet context structure within the - * current packet (bits). - */ - uint64_t context_offset_bits; - - /* - * Owned by this; `NULL` if the current packet is closed - * or if the trace IR stream does not support packets. - */ - const bt_packet *packet; - } packet_state; - - /* Previous packet's state */ - struct { - /* End default clock snapshot (`UINT64_C(-1)` if not set) */ - uint64_t end_cs; - - /* Discarded events (free running) counter */ - uint64_t discarded_events_counter; - - /* Sequence number (free running) */ - uint64_t seq_num; - } prev_packet_state; - - /* State to handle discarded events */ - struct { - /* - * True if we're in the time range given by a previously - * received discarded events message. In this case, - * `beginning_cs` and `end_cs` below contain the - * beginning and end clock snapshots for this range. - * - * This is used to validate that, when receiving a - * packet end message, the current discarded events time - * range matches what's expected for CTF 1.8, that is: - * - * * Its beginning time is the previous packet's end - * time (or the current packet's beginning time if - * this is the first packet). - * - * * Its end time is the current packet's end time. - */ - bool in_range; - - /* - * Beginning and end times of the time range given by a - * previously received discarded events message. - */ - uint64_t beginning_cs; - uint64_t end_cs; - } discarded_events_state; - - /* State to handle discarded packets */ - struct { - /* - * True if we're in the time range given by a previously - * received discarded packets message. In this case, - * `beginning_cs` and `end_cs` below contain the - * beginning and end clock snapshots for this range. - * - * This is used to validate that, when receiving a - * packet beginning message, the current discarded - * packets time range matches what's expected for CTF - * 1.8, that is: - * - * * Its beginning time is the previous packet's end - * time. - * - * * Its end time is the current packet's beginning - * time. - */ - bool in_range; - - /* - * Beginning and end times of the time range given by a - * previously received discarded packets message. - */ - uint64_t beginning_cs; - uint64_t end_cs; - } discarded_packets_state; +struct fs_sink_stream +{ + bt_logging_level log_level; + struct fs_sink_trace *trace; + struct bt_ctfser ctfser; + + /* Stream's file name */ + GString *file_name; + + /* Weak */ + const bt_stream *ir_stream; + + struct fs_sink_ctf_stream_class *sc; + + /* Current packet's state */ + struct + { + /* + * True if we're, for this stream, within an opened + * packet (got a packet beginning message, but no + * packet end message yet). + */ + bool is_open; + + /* + * Current beginning default clock snapshot for the + * current packet (`UINT64_C(-1)` if not set). + */ + uint64_t beginning_cs; + + /* + * Current end default clock snapshot for the current + * packet (`UINT64_C(-1)` if not set). + */ + uint64_t end_cs; + + /* + * Current packet's content size (bits) for the current + * packet. + */ + uint64_t content_size; + + /* + * Current packet's total size (bits) for the current + * packet. + */ + uint64_t total_size; + + /* + * Discarded events (free running) counter for the + * current packet. + */ + uint64_t discarded_events_counter; + + /* Sequence number (free running) of the current packet */ + uint64_t seq_num; + + /* + * Offset of the packet context structure within the + * current packet (bits). + */ + uint64_t context_offset_bits; + + /* + * Owned by this; `NULL` if the current packet is closed + * or if the trace IR stream does not support packets. + */ + const bt_packet *packet; + } packet_state; + + /* Previous packet's state */ + struct + { + /* End default clock snapshot (`UINT64_C(-1)` if not set) */ + uint64_t end_cs; + + /* Discarded events (free running) counter */ + uint64_t discarded_events_counter; + + /* Sequence number (free running) */ + uint64_t seq_num; + } prev_packet_state; + + /* State to handle discarded events */ + struct + { + /* + * True if we're in the time range given by a previously + * received discarded events message. In this case, + * `beginning_cs` and `end_cs` below contain the + * beginning and end clock snapshots for this range. + * + * This is used to validate that, when receiving a + * packet end message, the current discarded events time + * range matches what's expected for CTF 1.8, that is: + * + * * Its beginning time is the previous packet's end + * time (or the current packet's beginning time if + * this is the first packet). + * + * * Its end time is the current packet's end time. + */ + bool in_range; + + /* + * Beginning and end times of the time range given by a + * previously received discarded events message. + */ + uint64_t beginning_cs; + uint64_t end_cs; + } discarded_events_state; + + /* State to handle discarded packets */ + struct + { + /* + * True if we're in the time range given by a previously + * received discarded packets message. In this case, + * `beginning_cs` and `end_cs` below contain the + * beginning and end clock snapshots for this range. + * + * This is used to validate that, when receiving a + * packet beginning message, the current discarded + * packets time range matches what's expected for CTF + * 1.8, that is: + * + * * Its beginning time is the previous packet's end + * time. + * + * * Its end time is the current packet's beginning + * time. + */ + bool in_range; + + /* + * Beginning and end times of the time range given by a + * previously received discarded packets message. + */ + uint64_t beginning_cs; + uint64_t end_cs; + } discarded_packets_state; }; BT_HIDDEN struct fs_sink_stream *fs_sink_stream_create(struct fs_sink_trace *trace, - const bt_stream *ir_stream); + const bt_stream *ir_stream); BT_HIDDEN void fs_sink_stream_destroy(struct fs_sink_stream *stream); BT_HIDDEN -int fs_sink_stream_write_event(struct fs_sink_stream *stream, - const bt_clock_snapshot *cs, const bt_event *event, - struct fs_sink_ctf_event_class *ec); +int fs_sink_stream_write_event(struct fs_sink_stream *stream, const bt_clock_snapshot *cs, + const bt_event *event, struct fs_sink_ctf_event_class *ec); BT_HIDDEN -int fs_sink_stream_open_packet(struct fs_sink_stream *stream, - const bt_clock_snapshot *cs, const bt_packet *packet); +int fs_sink_stream_open_packet(struct fs_sink_stream *stream, const bt_clock_snapshot *cs, + const bt_packet *packet); BT_HIDDEN -int fs_sink_stream_close_packet(struct fs_sink_stream *stream, - const bt_clock_snapshot *cs); +int fs_sink_stream_close_packet(struct fs_sink_stream *stream, const bt_clock_snapshot *cs); #endif /* BABELTRACE_PLUGIN_CTF_FS_SINK_FS_SINK_STREAM_H */ diff --git a/src/plugins/ctf/fs-sink/fs-sink-trace.cpp b/src/plugins/ctf/fs-sink/fs-sink-trace.cpp index 2be7d5ef..e9dddc7b 100644 --- a/src/plugins/ctf/fs-sink/fs-sink-trace.cpp +++ b/src/plugins/ctf/fs-sink/fs-sink-trace.cpp @@ -5,8 +5,8 @@ */ #define BT_COMP_LOG_SELF_COMP (trace->fs_sink->self_comp) -#define BT_LOG_OUTPUT_LEVEL (trace->log_level) -#define BT_LOG_TAG "PLUGIN/SINK.CTF.FS/TRACE" +#define BT_LOG_OUTPUT_LEVEL (trace->log_level) +#define BT_LOG_TAG "PLUGIN/SINK.CTF.FS/TRACE" #include "logging/comp-logging.h" #include @@ -29,71 +29,69 @@ * * Replace `..` subdirectories with `__`. * * Remove trailing slashes. */ -static -GString *sanitize_trace_path(const char *path) +static GString *sanitize_trace_path(const char *path) { - GString *san_path = g_string_new(NULL); - const char *ch = path; - bool dir_start = true; - - BT_ASSERT(san_path); - BT_ASSERT(path); - - while (*ch != '\0') { - switch (*ch) { - case '/': - /* Start of directory */ - dir_start = true; - g_string_append_c(san_path, *ch); - ch++; - continue; - case '.': - if (dir_start) { - switch (ch[1]) { - case '\0': - case '/': - /* `.` -> `_` */ - g_string_append_c(san_path, '_'); - ch++; - continue; - case '.': - switch (ch[2]) { - case '\0': - case '/': - /* `..` -> `__` */ - g_string_append(san_path, "__"); - ch += 2; - continue; - default: - break; - } - default: - break; - } - } - default: - break; - } - - /* Not a special character */ - g_string_append_c(san_path, *ch); - ch++; - dir_start = false; - } - - /* Remove trailing slashes */ - while (san_path->len > 0 && - san_path->str[san_path->len - 1] == '/') { - /* Remove trailing slash */ - g_string_set_size(san_path, san_path->len - 1); - } - - if (san_path->len == 0) { - /* Looks like there's nothing left: just use `trace` */ - g_string_assign(san_path, "trace"); - } - - return san_path; + GString *san_path = g_string_new(NULL); + const char *ch = path; + bool dir_start = true; + + BT_ASSERT(san_path); + BT_ASSERT(path); + + while (*ch != '\0') { + switch (*ch) { + case '/': + /* Start of directory */ + dir_start = true; + g_string_append_c(san_path, *ch); + ch++; + continue; + case '.': + if (dir_start) { + switch (ch[1]) { + case '\0': + case '/': + /* `.` -> `_` */ + g_string_append_c(san_path, '_'); + ch++; + continue; + case '.': + switch (ch[2]) { + case '\0': + case '/': + /* `..` -> `__` */ + g_string_append(san_path, "__"); + ch += 2; + continue; + default: + break; + } + default: + break; + } + } + default: + break; + } + + /* Not a special character */ + g_string_append_c(san_path, *ch); + ch++; + dir_start = false; + } + + /* Remove trailing slashes */ + while (san_path->len > 0 && san_path->str[san_path->len - 1] == '/') { + /* Remove trailing slash */ + g_string_set_size(san_path, san_path->len - 1); + } + + if (san_path->len == 0) { + /* Looks like there's nothing left: just use `trace` */ + g_string_assign(san_path, "trace"); + } + + return san_path; } /* @@ -101,20 +99,19 @@ GString *sanitize_trace_path(const char *path) * itself, then try with incrementing suffixes. */ -static -GString *make_unique_trace_path(const char *path) +static GString *make_unique_trace_path(const char *path) { - GString *unique_path; - unsigned int suffix = 0; + GString *unique_path; + unsigned int suffix = 0; - unique_path = g_string_new(path); + unique_path = g_string_new(path); - while (g_file_test(unique_path->str, G_FILE_TEST_EXISTS)) { - g_string_printf(unique_path, "%s-%u", path, suffix); - suffix++; - } + while (g_file_test(unique_path->str, G_FILE_TEST_EXISTS)) { + g_string_printf(unique_path, "%s-%u", path, suffix); + suffix++; + } - return unique_path; + return unique_path; } /* @@ -131,490 +128,473 @@ GString *make_unique_trace_path(const char *path) * format used by LTTng in the metadata). */ -static -int lttng_validate_datetime(const struct fs_sink_trace *trace, - const char *datetime) +static int lttng_validate_datetime(const struct fs_sink_trace *trace, const char *datetime) { - GTimeVal tv; - int ret = -1; - - /* - * We are using g_time_val_from_iso8601, as the safer/more modern - * alternative, g_date_time_new_from_iso8601, is only available in - * glib >= 2.56, and this is sufficient for our use case of validating - * the format. - */ - if (!g_time_val_from_iso8601(datetime, &tv)) { - BT_COMP_LOGI("Couldn't parse datetime as ISO 8601: date=\"%s\"", datetime); - goto end; - } - - ret = 0; + GTimeVal tv; + int ret = -1; + + /* + * We are using g_time_val_from_iso8601, as the safer/more modern + * alternative, g_date_time_new_from_iso8601, is only available in + * glib >= 2.56, and this is sufficient for our use case of validating + * the format. + */ + if (!g_time_val_from_iso8601(datetime, &tv)) { + BT_COMP_LOGI("Couldn't parse datetime as ISO 8601: date=\"%s\"", datetime); + goto end; + } + + ret = 0; end: - return ret; + return ret; } #pragma GCC diagnostic pop -static -int append_lttng_trace_path_ust_uid(const struct fs_sink_trace *trace, - GString *path, const bt_trace *tc) +static int append_lttng_trace_path_ust_uid(const struct fs_sink_trace *trace, GString *path, + const bt_trace *tc) { - const bt_value *v; - int ret; + const bt_value *v; + int ret; - v = bt_trace_borrow_environment_entry_value_by_name_const(tc, "tracer_buffering_id"); - if (!v || !bt_value_is_signed_integer(v)) { - BT_COMP_LOGI_STR("Couldn't get environment value: name=\"tracer_buffering_id\""); - goto error; - } + v = bt_trace_borrow_environment_entry_value_by_name_const(tc, "tracer_buffering_id"); + if (!v || !bt_value_is_signed_integer(v)) { + BT_COMP_LOGI_STR("Couldn't get environment value: name=\"tracer_buffering_id\""); + goto error; + } - g_string_append_printf(path, G_DIR_SEPARATOR_S "%" PRId64, - bt_value_integer_signed_get(v)); + g_string_append_printf(path, G_DIR_SEPARATOR_S "%" PRId64, bt_value_integer_signed_get(v)); - v = bt_trace_borrow_environment_entry_value_by_name_const(tc, "architecture_bit_width"); - if (!v || !bt_value_is_signed_integer(v)) { - BT_COMP_LOGI_STR("Couldn't get environment value: name=\"architecture_bit_width\""); - goto error; - } + v = bt_trace_borrow_environment_entry_value_by_name_const(tc, "architecture_bit_width"); + if (!v || !bt_value_is_signed_integer(v)) { + BT_COMP_LOGI_STR("Couldn't get environment value: name=\"architecture_bit_width\""); + goto error; + } - g_string_append_printf(path, G_DIR_SEPARATOR_S "%" PRIu64 "-bit", - bt_value_integer_signed_get(v)); + g_string_append_printf(path, G_DIR_SEPARATOR_S "%" PRIu64 "-bit", + bt_value_integer_signed_get(v)); - ret = 0; - goto end; + ret = 0; + goto end; error: - ret = -1; + ret = -1; end: - return ret; + return ret; } -static -int append_lttng_trace_path_ust_pid(const struct fs_sink_trace *trace, - GString *path, const bt_trace *tc) +static int append_lttng_trace_path_ust_pid(const struct fs_sink_trace *trace, GString *path, + const bt_trace *tc) { - const bt_value *v; - const char *datetime; - int ret; + const bt_value *v; + const char *datetime; + int ret; - v = bt_trace_borrow_environment_entry_value_by_name_const(tc, "procname"); - if (!v || !bt_value_is_string(v)) { - BT_COMP_LOGI_STR("Couldn't get environment value: name=\"procname\""); - goto error; - } + v = bt_trace_borrow_environment_entry_value_by_name_const(tc, "procname"); + if (!v || !bt_value_is_string(v)) { + BT_COMP_LOGI_STR("Couldn't get environment value: name=\"procname\""); + goto error; + } - g_string_append_printf(path, G_DIR_SEPARATOR_S "%s", bt_value_string_get(v)); + g_string_append_printf(path, G_DIR_SEPARATOR_S "%s", bt_value_string_get(v)); - v = bt_trace_borrow_environment_entry_value_by_name_const(tc, "vpid"); - if (!v || !bt_value_is_signed_integer(v)) { - BT_COMP_LOGI_STR("Couldn't get environment value: name=\"vpid\""); - goto error; - } + v = bt_trace_borrow_environment_entry_value_by_name_const(tc, "vpid"); + if (!v || !bt_value_is_signed_integer(v)) { + BT_COMP_LOGI_STR("Couldn't get environment value: name=\"vpid\""); + goto error; + } - g_string_append_printf(path, "-%" PRId64, bt_value_integer_signed_get(v)); + g_string_append_printf(path, "-%" PRId64, bt_value_integer_signed_get(v)); - v = bt_trace_borrow_environment_entry_value_by_name_const(tc, "vpid_datetime"); - if (!v || !bt_value_is_string(v)) { - BT_COMP_LOGI_STR("Couldn't get environment value: name=\"vpid_datetime\""); - goto error; - } + v = bt_trace_borrow_environment_entry_value_by_name_const(tc, "vpid_datetime"); + if (!v || !bt_value_is_string(v)) { + BT_COMP_LOGI_STR("Couldn't get environment value: name=\"vpid_datetime\""); + goto error; + } - datetime = bt_value_string_get(v); + datetime = bt_value_string_get(v); - if (lttng_validate_datetime(trace, datetime)) { - goto error; - } + if (lttng_validate_datetime(trace, datetime)) { + goto error; + } - g_string_append_printf(path, "-%s", datetime); + g_string_append_printf(path, "-%s", datetime); - ret = 0; - goto end; + ret = 0; + goto end; error: - ret = -1; + ret = -1; end: - return ret; + return ret; } /* * Try to build a trace path based on environment values put in the trace * environment by the LTTng tracer, starting with version 2.11. */ -static -GString *make_lttng_trace_path_rel(const struct fs_sink_trace *trace) +static GString *make_lttng_trace_path_rel(const struct fs_sink_trace *trace) { - const bt_value *v; - const char *tracer_name, *domain, *datetime; - int64_t tracer_major, tracer_minor; - GString *path; - - path = g_string_new(NULL); - if (!path) { - goto error; - } - - v = bt_trace_borrow_environment_entry_value_by_name_const( - trace->ir_trace, "tracer_name"); - if (!v || !bt_value_is_string(v)) { - BT_COMP_LOGI_STR("Couldn't get environment value: name=\"tracer_name\""); - goto error; - } - - tracer_name = bt_value_string_get(v); - - if (!g_str_equal(tracer_name, "lttng-ust") - && !g_str_equal(tracer_name, "lttng-modules")) { - BT_COMP_LOGI("Unrecognized tracer name: name=\"%s\"", tracer_name); - goto error; - } - - v = bt_trace_borrow_environment_entry_value_by_name_const( - trace->ir_trace, "tracer_major"); - if (!v || !bt_value_is_signed_integer(v)) { - BT_COMP_LOGI_STR("Couldn't get environment value: name=\"tracer_major\""); - goto error; - } - - tracer_major = bt_value_integer_signed_get(v); - - v = bt_trace_borrow_environment_entry_value_by_name_const( - trace->ir_trace, "tracer_minor"); - if (!v || !bt_value_is_signed_integer(v)) { - BT_COMP_LOGI_STR("Couldn't get environment value: name=\"tracer_minor\""); - goto error; - } - - tracer_minor = bt_value_integer_signed_get(v); - - if (!(tracer_major >= 3 || (tracer_major == 2 && tracer_minor >= 11))) { - BT_COMP_LOGI("Unsupported LTTng version for automatic trace path: major=%" PRId64 ", minor=%" PRId64, - tracer_major, tracer_minor); - goto error; - } - - v = bt_trace_borrow_environment_entry_value_by_name_const( - trace->ir_trace, "hostname"); - if (!v || !bt_value_is_string(v)) { - BT_COMP_LOGI_STR("Couldn't get environment value: name=\"tracer_hostname\""); - goto error; - } - - g_string_assign(path, bt_value_string_get(v)); - - v = bt_trace_borrow_environment_entry_value_by_name_const( - trace->ir_trace, "trace_name"); - if (!v || !bt_value_is_string(v)) { - BT_COMP_LOGI_STR("Couldn't get environment value: name=\"trace_name\""); - goto error; - } - - g_string_append_printf(path, G_DIR_SEPARATOR_S "%s", bt_value_string_get(v)); - - v = bt_trace_borrow_environment_entry_value_by_name_const( - trace->ir_trace, "trace_creation_datetime"); - if (!v || !bt_value_is_string(v)) { - BT_COMP_LOGI_STR("Couldn't get environment value: name=\"trace_creation_datetime\""); - goto error; - } - - datetime = bt_value_string_get(v); - - if (lttng_validate_datetime(trace, datetime)) { - goto error; - } - - g_string_append_printf(path, "-%s", datetime); - - v = bt_trace_borrow_environment_entry_value_by_name_const( - trace->ir_trace, "domain"); - if (!v || !bt_value_is_string(v)) { - BT_COMP_LOGI_STR("Couldn't get environment value: name=\"domain\""); - goto error; - } - - domain = bt_value_string_get(v); - g_string_append_printf(path, G_DIR_SEPARATOR_S "%s", domain); - - if (g_str_equal(domain, "ust")) { - const char *tracer_buffering_scheme; - - v = bt_trace_borrow_environment_entry_value_by_name_const( - trace->ir_trace, "tracer_buffering_scheme"); - if (!v || !bt_value_is_string(v)) { - BT_COMP_LOGI_STR("Couldn't get environment value: name=\"tracer_buffering_scheme\""); - goto error; - } - - tracer_buffering_scheme = bt_value_string_get(v); - g_string_append_printf(path, G_DIR_SEPARATOR_S "%s", tracer_buffering_scheme); - - if (g_str_equal(tracer_buffering_scheme, "uid")) { - if (append_lttng_trace_path_ust_uid(trace, path, - trace->ir_trace)) { - goto error; - } - } else if (g_str_equal(tracer_buffering_scheme, "pid")){ - if (append_lttng_trace_path_ust_pid(trace, path, - trace->ir_trace)) { - goto error; - } - } else { - /* Unknown buffering scheme. */ - BT_COMP_LOGI("Unknown buffering scheme: tracer_buffering_scheme=\"%s\"", tracer_buffering_scheme); - goto error; - } - } else if (!g_str_equal(domain, "kernel")) { - /* Unknown domain. */ - BT_COMP_LOGI("Unknown domain: domain=\"%s\"", domain); - goto error; - } - - goto end; + const bt_value *v; + const char *tracer_name, *domain, *datetime; + int64_t tracer_major, tracer_minor; + GString *path; + + path = g_string_new(NULL); + if (!path) { + goto error; + } + + v = bt_trace_borrow_environment_entry_value_by_name_const(trace->ir_trace, "tracer_name"); + if (!v || !bt_value_is_string(v)) { + BT_COMP_LOGI_STR("Couldn't get environment value: name=\"tracer_name\""); + goto error; + } + + tracer_name = bt_value_string_get(v); + + if (!g_str_equal(tracer_name, "lttng-ust") && !g_str_equal(tracer_name, "lttng-modules")) { + BT_COMP_LOGI("Unrecognized tracer name: name=\"%s\"", tracer_name); + goto error; + } + + v = bt_trace_borrow_environment_entry_value_by_name_const(trace->ir_trace, "tracer_major"); + if (!v || !bt_value_is_signed_integer(v)) { + BT_COMP_LOGI_STR("Couldn't get environment value: name=\"tracer_major\""); + goto error; + } + + tracer_major = bt_value_integer_signed_get(v); + + v = bt_trace_borrow_environment_entry_value_by_name_const(trace->ir_trace, "tracer_minor"); + if (!v || !bt_value_is_signed_integer(v)) { + BT_COMP_LOGI_STR("Couldn't get environment value: name=\"tracer_minor\""); + goto error; + } + + tracer_minor = bt_value_integer_signed_get(v); + + if (!(tracer_major >= 3 || (tracer_major == 2 && tracer_minor >= 11))) { + BT_COMP_LOGI("Unsupported LTTng version for automatic trace path: major=%" PRId64 + ", minor=%" PRId64, + tracer_major, tracer_minor); + goto error; + } + + v = bt_trace_borrow_environment_entry_value_by_name_const(trace->ir_trace, "hostname"); + if (!v || !bt_value_is_string(v)) { + BT_COMP_LOGI_STR("Couldn't get environment value: name=\"tracer_hostname\""); + goto error; + } + + g_string_assign(path, bt_value_string_get(v)); + + v = bt_trace_borrow_environment_entry_value_by_name_const(trace->ir_trace, "trace_name"); + if (!v || !bt_value_is_string(v)) { + BT_COMP_LOGI_STR("Couldn't get environment value: name=\"trace_name\""); + goto error; + } + + g_string_append_printf(path, G_DIR_SEPARATOR_S "%s", bt_value_string_get(v)); + + v = bt_trace_borrow_environment_entry_value_by_name_const(trace->ir_trace, + "trace_creation_datetime"); + if (!v || !bt_value_is_string(v)) { + BT_COMP_LOGI_STR("Couldn't get environment value: name=\"trace_creation_datetime\""); + goto error; + } + + datetime = bt_value_string_get(v); + + if (lttng_validate_datetime(trace, datetime)) { + goto error; + } + + g_string_append_printf(path, "-%s", datetime); + + v = bt_trace_borrow_environment_entry_value_by_name_const(trace->ir_trace, "domain"); + if (!v || !bt_value_is_string(v)) { + BT_COMP_LOGI_STR("Couldn't get environment value: name=\"domain\""); + goto error; + } + + domain = bt_value_string_get(v); + g_string_append_printf(path, G_DIR_SEPARATOR_S "%s", domain); + + if (g_str_equal(domain, "ust")) { + const char *tracer_buffering_scheme; + + v = bt_trace_borrow_environment_entry_value_by_name_const(trace->ir_trace, + "tracer_buffering_scheme"); + if (!v || !bt_value_is_string(v)) { + BT_COMP_LOGI_STR("Couldn't get environment value: name=\"tracer_buffering_scheme\""); + goto error; + } + + tracer_buffering_scheme = bt_value_string_get(v); + g_string_append_printf(path, G_DIR_SEPARATOR_S "%s", tracer_buffering_scheme); + + if (g_str_equal(tracer_buffering_scheme, "uid")) { + if (append_lttng_trace_path_ust_uid(trace, path, trace->ir_trace)) { + goto error; + } + } else if (g_str_equal(tracer_buffering_scheme, "pid")) { + if (append_lttng_trace_path_ust_pid(trace, path, trace->ir_trace)) { + goto error; + } + } else { + /* Unknown buffering scheme. */ + BT_COMP_LOGI("Unknown buffering scheme: tracer_buffering_scheme=\"%s\"", + tracer_buffering_scheme); + goto error; + } + } else if (!g_str_equal(domain, "kernel")) { + /* Unknown domain. */ + BT_COMP_LOGI("Unknown domain: domain=\"%s\"", domain); + goto error; + } + + goto end; error: - if (path) { - g_string_free(path, TRUE); - path = NULL; - } + if (path) { + g_string_free(path, TRUE); + path = NULL; + } end: - return path; + return path; } /* Build the relative output path for `trace`. */ -static -GString *make_trace_path_rel(const struct fs_sink_trace *trace) +static GString *make_trace_path_rel(const struct fs_sink_trace *trace) { - GString *path = NULL; - const char *trace_name; + GString *path = NULL; + const char *trace_name; - BT_ASSERT(!trace->fs_sink->assume_single_trace); + BT_ASSERT(!trace->fs_sink->assume_single_trace); - /* First, try to build a path using environment fields written by LTTng. */ - path = make_lttng_trace_path_rel(trace); - if (path) { - goto end; - } + /* First, try to build a path using environment fields written by LTTng. */ + path = make_lttng_trace_path_rel(trace); + if (path) { + goto end; + } - /* Otherwise, use the trace name, if available. */ - trace_name = bt_trace_get_name(trace->ir_trace); - if (trace_name) { - path = g_string_new(trace_name); - goto end; - } + /* Otherwise, use the trace name, if available. */ + trace_name = bt_trace_get_name(trace->ir_trace); + if (trace_name) { + path = g_string_new(trace_name); + goto end; + } - /* Otherwise, use "trace". */ - path = g_string_new("trace"); + /* Otherwise, use "trace". */ + path = g_string_new("trace"); end: - return path; + return path; } /* * Compute the trace output path for `trace`, rooted at `output_base_directory`. */ -static -GString *make_trace_path(const struct fs_sink_trace *trace, const char *output_base_directory) +static GString *make_trace_path(const struct fs_sink_trace *trace, + const char *output_base_directory) { - GString *rel_path = NULL; - GString *rel_path_san = NULL; - GString *full_path = NULL; - GString *unique_full_path = NULL; - - if (trace->fs_sink->assume_single_trace) { - /* Use output directory directly */ - unique_full_path = g_string_new(output_base_directory); - if (!unique_full_path) { - goto end; - } - } else { - rel_path = make_trace_path_rel(trace); - if (!rel_path) { - goto end; - } - - rel_path_san = sanitize_trace_path(rel_path->str); - if (!rel_path_san) { - goto end; - } - - full_path = g_string_new(NULL); - if (!full_path) { - goto end; - } - - g_string_printf(full_path, "%s" G_DIR_SEPARATOR_S "%s", - output_base_directory, rel_path_san->str); - - unique_full_path = make_unique_trace_path(full_path->str); - } + GString *rel_path = NULL; + GString *rel_path_san = NULL; + GString *full_path = NULL; + GString *unique_full_path = NULL; + + if (trace->fs_sink->assume_single_trace) { + /* Use output directory directly */ + unique_full_path = g_string_new(output_base_directory); + if (!unique_full_path) { + goto end; + } + } else { + rel_path = make_trace_path_rel(trace); + if (!rel_path) { + goto end; + } + + rel_path_san = sanitize_trace_path(rel_path->str); + if (!rel_path_san) { + goto end; + } + + full_path = g_string_new(NULL); + if (!full_path) { + goto end; + } + + g_string_printf(full_path, "%s" G_DIR_SEPARATOR_S "%s", output_base_directory, + rel_path_san->str); + + unique_full_path = make_unique_trace_path(full_path->str); + } end: - if (rel_path) { - g_string_free(rel_path, TRUE); - } + if (rel_path) { + g_string_free(rel_path, TRUE); + } - if (rel_path_san) { - g_string_free(rel_path_san, TRUE); - } + if (rel_path_san) { + g_string_free(rel_path_san, TRUE); + } - if (full_path) { - g_string_free(full_path, TRUE); - } + if (full_path) { + g_string_free(full_path, TRUE); + } - return unique_full_path; + return unique_full_path; } BT_HIDDEN void fs_sink_trace_destroy(struct fs_sink_trace *trace) { - GString *tsdl = NULL; - FILE *fh = NULL; - size_t len; - - if (!trace) { - goto end; - } - - if (trace->ir_trace_destruction_listener_id != UINT64_C(-1)) { - /* - * Remove the destruction listener, otherwise it could - * be called in the future, and its private data is this - * CTF FS sink trace object which won't exist anymore. - */ - (void) bt_trace_remove_destruction_listener(trace->ir_trace, - trace->ir_trace_destruction_listener_id); - trace->ir_trace_destruction_listener_id = UINT64_C(-1); - } - - if (trace->streams) { - g_hash_table_destroy(trace->streams); - trace->streams = NULL; - } - - tsdl = g_string_new(NULL); - BT_ASSERT(tsdl); - translate_trace_ctf_ir_to_tsdl(trace->trace, tsdl); - - BT_ASSERT(trace->metadata_path); - fh = fopen(trace->metadata_path->str, "wb"); - if (!fh) { - BT_COMP_LOGF_ERRNO("In trace destruction listener: " - "cannot open metadata file for writing", - ": path=\"%s\"", trace->metadata_path->str); - bt_common_abort(); - } - - len = fwrite(tsdl->str, sizeof(*tsdl->str), tsdl->len, fh); - if (len != tsdl->len) { - BT_COMP_LOGF_ERRNO("In trace destruction listener: " - "cannot write metadata file", - ": path=\"%s\"", trace->metadata_path->str); - bt_common_abort(); - } - - if (!trace->fs_sink->quiet) { - printf("Created CTF trace `%s`.\n", trace->path->str); - } - - if (trace->path) { - g_string_free(trace->path, TRUE); - trace->path = NULL; - } - - if (fh) { - int ret = fclose(fh); - - if (ret != 0) { - BT_COMP_LOGW_ERRNO("In trace destruction listener: " - "cannot close metadata file", - ": path=\"%s\"", trace->metadata_path->str); - } - } - - g_string_free(trace->metadata_path, TRUE); - trace->metadata_path = NULL; - - fs_sink_ctf_trace_destroy(trace->trace); - trace->trace = NULL; - g_free(trace); - - g_string_free(tsdl, TRUE); + GString *tsdl = NULL; + FILE *fh = NULL; + size_t len; + + if (!trace) { + goto end; + } + + if (trace->ir_trace_destruction_listener_id != UINT64_C(-1)) { + /* + * Remove the destruction listener, otherwise it could + * be called in the future, and its private data is this + * CTF FS sink trace object which won't exist anymore. + */ + (void) bt_trace_remove_destruction_listener(trace->ir_trace, + trace->ir_trace_destruction_listener_id); + trace->ir_trace_destruction_listener_id = UINT64_C(-1); + } + + if (trace->streams) { + g_hash_table_destroy(trace->streams); + trace->streams = NULL; + } + + tsdl = g_string_new(NULL); + BT_ASSERT(tsdl); + translate_trace_ctf_ir_to_tsdl(trace->trace, tsdl); + + BT_ASSERT(trace->metadata_path); + fh = fopen(trace->metadata_path->str, "wb"); + if (!fh) { + BT_COMP_LOGF_ERRNO("In trace destruction listener: " + "cannot open metadata file for writing", + ": path=\"%s\"", trace->metadata_path->str); + bt_common_abort(); + } + + len = fwrite(tsdl->str, sizeof(*tsdl->str), tsdl->len, fh); + if (len != tsdl->len) { + BT_COMP_LOGF_ERRNO("In trace destruction listener: " + "cannot write metadata file", + ": path=\"%s\"", trace->metadata_path->str); + bt_common_abort(); + } + + if (!trace->fs_sink->quiet) { + printf("Created CTF trace `%s`.\n", trace->path->str); + } + + if (trace->path) { + g_string_free(trace->path, TRUE); + trace->path = NULL; + } + + if (fh) { + int ret = fclose(fh); + + if (ret != 0) { + BT_COMP_LOGW_ERRNO("In trace destruction listener: " + "cannot close metadata file", + ": path=\"%s\"", trace->metadata_path->str); + } + } + + g_string_free(trace->metadata_path, TRUE); + trace->metadata_path = NULL; + + fs_sink_ctf_trace_destroy(trace->trace); + trace->trace = NULL; + g_free(trace); + + g_string_free(tsdl, TRUE); end: - return; + return; } -static -void ir_trace_destruction_listener(const bt_trace *ir_trace, void *data) +static void ir_trace_destruction_listener(const bt_trace *ir_trace, void *data) { - struct fs_sink_trace *trace = (fs_sink_trace *) data; - - /* - * Prevent bt_trace_remove_destruction_listener() from being - * called in fs_sink_trace_destroy(), which is called by - * g_hash_table_remove() below. - */ - trace->ir_trace_destruction_listener_id = UINT64_C(-1); - g_hash_table_remove(trace->fs_sink->traces, ir_trace); + struct fs_sink_trace *trace = (fs_sink_trace *) data; + + /* + * Prevent bt_trace_remove_destruction_listener() from being + * called in fs_sink_trace_destroy(), which is called by + * g_hash_table_remove() below. + */ + trace->ir_trace_destruction_listener_id = UINT64_C(-1); + g_hash_table_remove(trace->fs_sink->traces, ir_trace); } BT_HIDDEN -struct fs_sink_trace *fs_sink_trace_create(struct fs_sink_comp *fs_sink, - const bt_trace *ir_trace) +struct fs_sink_trace *fs_sink_trace_create(struct fs_sink_comp *fs_sink, const bt_trace *ir_trace) { - int ret; - struct fs_sink_trace *trace = g_new0(struct fs_sink_trace, 1); - bt_trace_add_listener_status trace_status; - - if (!trace) { - goto end; - } - - trace->log_level = fs_sink->log_level; - trace->fs_sink = fs_sink; - trace->ir_trace = ir_trace; - trace->ir_trace_destruction_listener_id = UINT64_C(-1); - trace->trace = translate_trace_trace_ir_to_ctf_ir(fs_sink, ir_trace); - if (!trace->trace) { - goto error; - } - - trace->path = make_trace_path(trace, fs_sink->output_dir_path->str); - BT_ASSERT(trace->path); - ret = g_mkdir_with_parents(trace->path->str, 0755); - if (ret) { - BT_COMP_LOGE_ERRNO("Cannot create directories for trace directory", - ": path=\"%s\"", trace->path->str); - goto error; - } - - trace->metadata_path = g_string_new(trace->path->str); - BT_ASSERT(trace->metadata_path); - g_string_append(trace->metadata_path, "/metadata"); - trace->streams = g_hash_table_new_full(g_direct_hash, g_direct_equal, - NULL, (GDestroyNotify) fs_sink_stream_destroy); - BT_ASSERT(trace->streams); - trace_status = bt_trace_add_destruction_listener(ir_trace, - ir_trace_destruction_listener, trace, - &trace->ir_trace_destruction_listener_id); - if (trace_status) { - goto error; - } - - g_hash_table_insert(fs_sink->traces, (gpointer) ir_trace, trace); - goto end; + int ret; + struct fs_sink_trace *trace = g_new0(struct fs_sink_trace, 1); + bt_trace_add_listener_status trace_status; + + if (!trace) { + goto end; + } + + trace->log_level = fs_sink->log_level; + trace->fs_sink = fs_sink; + trace->ir_trace = ir_trace; + trace->ir_trace_destruction_listener_id = UINT64_C(-1); + trace->trace = translate_trace_trace_ir_to_ctf_ir(fs_sink, ir_trace); + if (!trace->trace) { + goto error; + } + + trace->path = make_trace_path(trace, fs_sink->output_dir_path->str); + BT_ASSERT(trace->path); + ret = g_mkdir_with_parents(trace->path->str, 0755); + if (ret) { + BT_COMP_LOGE_ERRNO("Cannot create directories for trace directory", ": path=\"%s\"", + trace->path->str); + goto error; + } + + trace->metadata_path = g_string_new(trace->path->str); + BT_ASSERT(trace->metadata_path); + g_string_append(trace->metadata_path, "/metadata"); + trace->streams = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, + (GDestroyNotify) fs_sink_stream_destroy); + BT_ASSERT(trace->streams); + trace_status = bt_trace_add_destruction_listener(ir_trace, ir_trace_destruction_listener, trace, + &trace->ir_trace_destruction_listener_id); + if (trace_status) { + goto error; + } + + g_hash_table_insert(fs_sink->traces, (gpointer) ir_trace, trace); + goto end; error: - fs_sink_trace_destroy(trace); - trace = NULL; + fs_sink_trace_destroy(trace); + trace = NULL; end: - return trace; + return trace; } diff --git a/src/plugins/ctf/fs-sink/fs-sink-trace.hpp b/src/plugins/ctf/fs-sink/fs-sink-trace.hpp index ae33573e..9fe48d08 100644 --- a/src/plugins/ctf/fs-sink/fs-sink-trace.hpp +++ b/src/plugins/ctf/fs-sink/fs-sink-trace.hpp @@ -17,45 +17,45 @@ struct fs_sink_comp; -struct fs_sink_trace { - bt_logging_level log_level; - struct fs_sink_comp *fs_sink; - - /* Owned by this */ - struct fs_sink_ctf_trace *trace; - - /* - * Weak reference: this object does not own it, and `trace` - * above does not own its trace IR trace and trace class either. - * Instead, we add a "trace destruction" listener (in - * create_trace()) so that this object gets destroyed when the - * trace object is destroyed. - * - * Otherwise (with a strong reference), we would keep this trace - * object alive until the upstream message iterator ends. This - * could "leak" resources (memory, file descriptors) associated - * to traces and streams which otherwise would not exist. - */ - const bt_trace *ir_trace; - - bt_listener_id ir_trace_destruction_listener_id; - - /* Trace's directory */ - GString *path; - - /* `metadata` file path */ - GString *metadata_path; - - /* - * Hash table of `const bt_stream *` (weak) to - * `struct fs_sink_stream *` (owned by hash table). - */ - GHashTable *streams; +struct fs_sink_trace +{ + bt_logging_level log_level; + struct fs_sink_comp *fs_sink; + + /* Owned by this */ + struct fs_sink_ctf_trace *trace; + + /* + * Weak reference: this object does not own it, and `trace` + * above does not own its trace IR trace and trace class either. + * Instead, we add a "trace destruction" listener (in + * create_trace()) so that this object gets destroyed when the + * trace object is destroyed. + * + * Otherwise (with a strong reference), we would keep this trace + * object alive until the upstream message iterator ends. This + * could "leak" resources (memory, file descriptors) associated + * to traces and streams which otherwise would not exist. + */ + const bt_trace *ir_trace; + + bt_listener_id ir_trace_destruction_listener_id; + + /* Trace's directory */ + GString *path; + + /* `metadata` file path */ + GString *metadata_path; + + /* + * Hash table of `const bt_stream *` (weak) to + * `struct fs_sink_stream *` (owned by hash table). + */ + GHashTable *streams; }; BT_HIDDEN -struct fs_sink_trace *fs_sink_trace_create(struct fs_sink_comp *fs_sink, - const bt_trace *ir_trace); +struct fs_sink_trace *fs_sink_trace_create(struct fs_sink_comp *fs_sink, const bt_trace *ir_trace); BT_HIDDEN void fs_sink_trace_destroy(struct fs_sink_trace *trace); diff --git a/src/plugins/ctf/fs-sink/fs-sink.cpp b/src/plugins/ctf/fs-sink/fs-sink.cpp index 42a616c9..5f5b2ac5 100644 --- a/src/plugins/ctf/fs-sink/fs-sink.cpp +++ b/src/plugins/ctf/fs-sink/fs-sink.cpp @@ -5,8 +5,8 @@ */ #define BT_COMP_LOG_SELF_COMP (fs_sink->self_comp) -#define BT_LOG_OUTPUT_LEVEL (fs_sink->log_level) -#define BT_LOG_TAG "PLUGIN/SINK.CTF.FS" +#define BT_LOG_OUTPUT_LEVEL (fs_sink->log_level) +#define BT_LOG_TAG "PLUGIN/SINK.CTF.FS" #include "logging/comp-logging.h" #include @@ -24,1124 +24,1027 @@ #include "translate-trace-ir-to-ctf-ir.hpp" #include "translate-ctf-ir-to-tsdl.hpp" -static -const char * const in_port_name = "in"; +static const char * const in_port_name = "in"; -static -bt_component_class_initialize_method_status ensure_output_dir_exists( - struct fs_sink_comp *fs_sink) +static bt_component_class_initialize_method_status +ensure_output_dir_exists(struct fs_sink_comp *fs_sink) { - bt_component_class_initialize_method_status status = - BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK; - int ret; - - ret = g_mkdir_with_parents(fs_sink->output_dir_path->str, 0755); - if (ret) { - BT_COMP_LOGE_APPEND_CAUSE_ERRNO(fs_sink->self_comp, - "Cannot create directories for output directory", - ": output-dir-path=\"%s\"", - fs_sink->output_dir_path->str); - status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_ERROR; - goto end; - } + bt_component_class_initialize_method_status status = + BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK; + int ret; + + ret = g_mkdir_with_parents(fs_sink->output_dir_path->str, 0755); + if (ret) { + BT_COMP_LOGE_APPEND_CAUSE_ERRNO(fs_sink->self_comp, + "Cannot create directories for output directory", + ": output-dir-path=\"%s\"", fs_sink->output_dir_path->str); + status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_ERROR; + goto end; + } end: - return status; + return status; } static bt_param_validation_map_value_entry_descr fs_sink_params_descr[] = { - { "path", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_MANDATORY, - { bt_param_validation_value_descr::string_t } }, - { "assume-single-trace", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_OPTIONAL, - { bt_param_validation_value_descr::bool_t } }, - { "ignore-discarded-events", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_OPTIONAL, - { bt_param_validation_value_descr::bool_t } }, - { "ignore-discarded-packets", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_OPTIONAL, - { bt_param_validation_value_descr::bool_t } }, - { "quiet", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_OPTIONAL, - { bt_param_validation_value_descr::bool_t } }, - BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_END -}; - -static -bt_component_class_initialize_method_status -configure_component(struct fs_sink_comp *fs_sink, const bt_value *params) + {"path", + BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_MANDATORY, + {bt_param_validation_value_descr::string_t}}, + {"assume-single-trace", + BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_OPTIONAL, + {bt_param_validation_value_descr::bool_t}}, + {"ignore-discarded-events", + BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_OPTIONAL, + {bt_param_validation_value_descr::bool_t}}, + {"ignore-discarded-packets", + BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_OPTIONAL, + {bt_param_validation_value_descr::bool_t}}, + {"quiet", + BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_OPTIONAL, + {bt_param_validation_value_descr::bool_t}}, + BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_END}; + +static bt_component_class_initialize_method_status configure_component(struct fs_sink_comp *fs_sink, + const bt_value *params) { - bt_component_class_initialize_method_status status; - const bt_value *value; - enum bt_param_validation_status validation_status; - gchar *validation_error; - - validation_status = bt_param_validation_validate(params, - fs_sink_params_descr, &validation_error); - if (validation_status == BT_PARAM_VALIDATION_STATUS_VALIDATION_ERROR) { - status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_ERROR; - BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, - "%s", validation_error); - goto end; - } else if (validation_status == BT_PARAM_VALIDATION_STATUS_MEMORY_ERROR) { - status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_MEMORY_ERROR; - goto end; - } - - value = bt_value_map_borrow_entry_value_const(params, "path"); - g_string_assign(fs_sink->output_dir_path, - bt_value_string_get(value)); - - value = bt_value_map_borrow_entry_value_const(params, - "assume-single-trace"); - if (value) { - fs_sink->assume_single_trace = (bool) bt_value_bool_get(value); - } - - value = bt_value_map_borrow_entry_value_const(params, - "ignore-discarded-events"); - if (value) { - fs_sink->ignore_discarded_events = - (bool) bt_value_bool_get(value); - } - - value = bt_value_map_borrow_entry_value_const(params, - "ignore-discarded-packets"); - if (value) { - fs_sink->ignore_discarded_packets = - (bool) bt_value_bool_get(value); - } - - value = bt_value_map_borrow_entry_value_const(params, - "quiet"); - if (value) { - fs_sink->quiet = (bool) bt_value_bool_get(value); - } - - status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK; + bt_component_class_initialize_method_status status; + const bt_value *value; + enum bt_param_validation_status validation_status; + gchar *validation_error; + + validation_status = + bt_param_validation_validate(params, fs_sink_params_descr, &validation_error); + if (validation_status == BT_PARAM_VALIDATION_STATUS_VALIDATION_ERROR) { + status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_ERROR; + BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, "%s", validation_error); + goto end; + } else if (validation_status == BT_PARAM_VALIDATION_STATUS_MEMORY_ERROR) { + status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_MEMORY_ERROR; + goto end; + } + + value = bt_value_map_borrow_entry_value_const(params, "path"); + g_string_assign(fs_sink->output_dir_path, bt_value_string_get(value)); + + value = bt_value_map_borrow_entry_value_const(params, "assume-single-trace"); + if (value) { + fs_sink->assume_single_trace = (bool) bt_value_bool_get(value); + } + + value = bt_value_map_borrow_entry_value_const(params, "ignore-discarded-events"); + if (value) { + fs_sink->ignore_discarded_events = (bool) bt_value_bool_get(value); + } + + value = bt_value_map_borrow_entry_value_const(params, "ignore-discarded-packets"); + if (value) { + fs_sink->ignore_discarded_packets = (bool) bt_value_bool_get(value); + } + + value = bt_value_map_borrow_entry_value_const(params, "quiet"); + if (value) { + fs_sink->quiet = (bool) bt_value_bool_get(value); + } + + status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK; end: - g_free(validation_error); - return status; + g_free(validation_error); + return status; } -static -void destroy_fs_sink_comp(struct fs_sink_comp *fs_sink) +static void destroy_fs_sink_comp(struct fs_sink_comp *fs_sink) { - if (!fs_sink) { - goto end; - } + if (!fs_sink) { + goto end; + } - if (fs_sink->output_dir_path) { - g_string_free(fs_sink->output_dir_path, TRUE); - fs_sink->output_dir_path = NULL; - } + if (fs_sink->output_dir_path) { + g_string_free(fs_sink->output_dir_path, TRUE); + fs_sink->output_dir_path = NULL; + } - if (fs_sink->traces) { - g_hash_table_destroy(fs_sink->traces); - fs_sink->traces = NULL; - } + if (fs_sink->traces) { + g_hash_table_destroy(fs_sink->traces); + fs_sink->traces = NULL; + } - BT_MESSAGE_ITERATOR_PUT_REF_AND_RESET( - fs_sink->upstream_iter); - g_free(fs_sink); + BT_MESSAGE_ITERATOR_PUT_REF_AND_RESET(fs_sink->upstream_iter); + g_free(fs_sink); end: - return; + return; } BT_HIDDEN -bt_component_class_initialize_method_status ctf_fs_sink_init( - bt_self_component_sink *self_comp_sink, - bt_self_component_sink_configuration *config, - const bt_value *params, - void *init_method_data) +bt_component_class_initialize_method_status +ctf_fs_sink_init(bt_self_component_sink *self_comp_sink, + bt_self_component_sink_configuration *config, const bt_value *params, + void *init_method_data) { - bt_component_class_initialize_method_status status; - bt_self_component_add_port_status add_port_status; - struct fs_sink_comp *fs_sink = NULL; - bt_self_component *self_comp = - bt_self_component_sink_as_self_component(self_comp_sink); - bt_logging_level log_level = bt_component_get_logging_level( - bt_self_component_as_component(self_comp)); - - fs_sink = g_new0(struct fs_sink_comp, 1); - if (!fs_sink) { - BT_COMP_LOG_CUR_LVL(BT_LOG_ERROR, log_level, self_comp, - "Failed to allocate one CTF FS sink structure."); - BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_COMPONENT( - self_comp, "Failed to allocate one CTF FS sink structure."); - status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_MEMORY_ERROR; - goto end; - } - - fs_sink->log_level = log_level; - fs_sink->self_comp = self_comp; - fs_sink->output_dir_path = g_string_new(NULL); - status = configure_component(fs_sink, params); - if (status != BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK) { - /* configure_component() logs errors */ - goto end; - } - - if (fs_sink->assume_single_trace && - g_file_test(fs_sink->output_dir_path->str, - G_FILE_TEST_EXISTS)) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Single trace mode, but output path exists: output-path=\"%s\"", - fs_sink->output_dir_path->str); - status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_ERROR; - goto end; - } - - status = ensure_output_dir_exists(fs_sink); - if (status != BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK) { - /* ensure_output_dir_exists() logs errors */ - goto end; - } - - fs_sink->traces = g_hash_table_new_full(g_direct_hash, g_direct_equal, - NULL, (GDestroyNotify) fs_sink_trace_destroy); - if (!fs_sink->traces) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Failed to allocate one GHashTable."); - status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_MEMORY_ERROR; - goto end; - } - - add_port_status = bt_self_component_sink_add_input_port( - self_comp_sink, in_port_name, NULL, NULL); - if (add_port_status != BT_SELF_COMPONENT_ADD_PORT_STATUS_OK) { - status = (bt_component_class_initialize_method_status) add_port_status; - BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Failed to add input port."); - goto end; - } - - bt_self_component_set_data(self_comp, fs_sink); + bt_component_class_initialize_method_status status; + bt_self_component_add_port_status add_port_status; + struct fs_sink_comp *fs_sink = NULL; + bt_self_component *self_comp = bt_self_component_sink_as_self_component(self_comp_sink); + bt_logging_level log_level = + bt_component_get_logging_level(bt_self_component_as_component(self_comp)); + + fs_sink = g_new0(struct fs_sink_comp, 1); + if (!fs_sink) { + BT_COMP_LOG_CUR_LVL(BT_LOG_ERROR, log_level, self_comp, + "Failed to allocate one CTF FS sink structure."); + BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_COMPONENT( + self_comp, "Failed to allocate one CTF FS sink structure."); + status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_MEMORY_ERROR; + goto end; + } + + fs_sink->log_level = log_level; + fs_sink->self_comp = self_comp; + fs_sink->output_dir_path = g_string_new(NULL); + status = configure_component(fs_sink, params); + if (status != BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK) { + /* configure_component() logs errors */ + goto end; + } + + if (fs_sink->assume_single_trace && + g_file_test(fs_sink->output_dir_path->str, G_FILE_TEST_EXISTS)) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, + "Single trace mode, but output path exists: output-path=\"%s\"", + fs_sink->output_dir_path->str); + status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_ERROR; + goto end; + } + + status = ensure_output_dir_exists(fs_sink); + if (status != BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK) { + /* ensure_output_dir_exists() logs errors */ + goto end; + } + + fs_sink->traces = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, + (GDestroyNotify) fs_sink_trace_destroy); + if (!fs_sink->traces) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Failed to allocate one GHashTable."); + status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_MEMORY_ERROR; + goto end; + } + + add_port_status = + bt_self_component_sink_add_input_port(self_comp_sink, in_port_name, NULL, NULL); + if (add_port_status != BT_SELF_COMPONENT_ADD_PORT_STATUS_OK) { + status = (bt_component_class_initialize_method_status) add_port_status; + BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Failed to add input port."); + goto end; + } + + bt_self_component_set_data(self_comp, fs_sink); end: - if (status != BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK) { - destroy_fs_sink_comp(fs_sink); - } + if (status != BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK) { + destroy_fs_sink_comp(fs_sink); + } - return status; + return status; } -static inline -struct fs_sink_stream *borrow_stream(struct fs_sink_comp *fs_sink, - const bt_stream *ir_stream) +static inline struct fs_sink_stream *borrow_stream(struct fs_sink_comp *fs_sink, + const bt_stream *ir_stream) { - const bt_trace *ir_trace = bt_stream_borrow_trace_const(ir_stream); - struct fs_sink_trace *trace; - struct fs_sink_stream *stream = NULL; - - trace = (fs_sink_trace *) g_hash_table_lookup(fs_sink->traces, ir_trace); - if (G_UNLIKELY(!trace)) { - if (fs_sink->assume_single_trace && - g_hash_table_size(fs_sink->traces) > 0) { - BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, - "Single trace mode, but getting more than one trace: " - "stream-name=\"%s\"", - bt_stream_get_name(ir_stream)); - goto end; - } - - trace = fs_sink_trace_create(fs_sink, ir_trace); - if (!trace) { - goto end; - } - } - - stream = (fs_sink_stream *) g_hash_table_lookup(trace->streams, ir_stream); - if (G_UNLIKELY(!stream)) { - stream = fs_sink_stream_create(trace, ir_stream); - if (!stream) { - goto end; - } - } + const bt_trace *ir_trace = bt_stream_borrow_trace_const(ir_stream); + struct fs_sink_trace *trace; + struct fs_sink_stream *stream = NULL; + + trace = (fs_sink_trace *) g_hash_table_lookup(fs_sink->traces, ir_trace); + if (G_UNLIKELY(!trace)) { + if (fs_sink->assume_single_trace && g_hash_table_size(fs_sink->traces) > 0) { + BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, + "Single trace mode, but getting more than one trace: " + "stream-name=\"%s\"", + bt_stream_get_name(ir_stream)); + goto end; + } + + trace = fs_sink_trace_create(fs_sink, ir_trace); + if (!trace) { + goto end; + } + } + + stream = (fs_sink_stream *) g_hash_table_lookup(trace->streams, ir_stream); + if (G_UNLIKELY(!stream)) { + stream = fs_sink_stream_create(trace, ir_stream); + if (!stream) { + goto end; + } + } end: - return stream; + return stream; } -static inline -bt_component_class_sink_consume_method_status handle_event_msg( - struct fs_sink_comp *fs_sink, const bt_message *msg) +static inline bt_component_class_sink_consume_method_status +handle_event_msg(struct fs_sink_comp *fs_sink, const bt_message *msg) { - int ret; - bt_component_class_sink_consume_method_status status = - BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_OK; - const bt_event *ir_event = bt_message_event_borrow_event_const(msg); - const bt_stream *ir_stream = bt_event_borrow_stream_const(ir_event); - struct fs_sink_stream *stream; - struct fs_sink_ctf_event_class *ec = NULL; - const bt_clock_snapshot *cs = NULL; - - stream = borrow_stream(fs_sink, ir_stream); - if (G_UNLIKELY(!stream)) { - BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, - "Failed to borrow stream."); - status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; - goto end; - } - - ret = try_translate_event_class_trace_ir_to_ctf_ir(fs_sink, - stream->sc, bt_event_borrow_class_const(ir_event), &ec); - if (ret) { - BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, - "Failed to translate event class to CTF IR."); - status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; - goto end; - } - - BT_ASSERT_DBG(ec); - - if (stream->sc->default_clock_class) { - cs = bt_message_event_borrow_default_clock_snapshot_const( - msg); - } - - /* - * If this event's stream does not support packets, then we - * lazily create artificial packets. - * - * The size of an artificial packet is arbitrarily at least - * 4 MiB (it usually is greater because we close it when - * comes the time to write a new event and the packet's content - * size is >= 4 MiB), except the last one which can be smaller. - */ - if (G_UNLIKELY(!stream->sc->has_packets)) { - if (stream->packet_state.is_open && - bt_ctfser_get_offset_in_current_packet_bits(&stream->ctfser) / 8 >= - 4 * 1024 * 1024) { - /* - * Stream's current packet is larger than 4 MiB: - * close it. A new packet will be opened just - * below. - */ - ret = fs_sink_stream_close_packet(stream, NULL); - if (ret) { - BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, - "Failed to close packet."); - status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; - goto end; - } - } - - if (!stream->packet_state.is_open) { - /* Stream's packet is not currently opened: open it */ - ret = fs_sink_stream_open_packet(stream, NULL, NULL); - if (ret) { - BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, - "Failed to open packet."); - status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; - goto end; - } - } - } - - BT_ASSERT_DBG(stream->packet_state.is_open); - ret = fs_sink_stream_write_event(stream, cs, ir_event, ec); - if (G_UNLIKELY(ret)) { - BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, - "Failed to write event."); - status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; - goto end; - } + int ret; + bt_component_class_sink_consume_method_status status = + BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_OK; + const bt_event *ir_event = bt_message_event_borrow_event_const(msg); + const bt_stream *ir_stream = bt_event_borrow_stream_const(ir_event); + struct fs_sink_stream *stream; + struct fs_sink_ctf_event_class *ec = NULL; + const bt_clock_snapshot *cs = NULL; + + stream = borrow_stream(fs_sink, ir_stream); + if (G_UNLIKELY(!stream)) { + BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, "Failed to borrow stream."); + status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; + goto end; + } + + ret = try_translate_event_class_trace_ir_to_ctf_ir(fs_sink, stream->sc, + bt_event_borrow_class_const(ir_event), &ec); + if (ret) { + BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, "Failed to translate event class to CTF IR."); + status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; + goto end; + } + + BT_ASSERT_DBG(ec); + + if (stream->sc->default_clock_class) { + cs = bt_message_event_borrow_default_clock_snapshot_const(msg); + } + + /* + * If this event's stream does not support packets, then we + * lazily create artificial packets. + * + * The size of an artificial packet is arbitrarily at least + * 4 MiB (it usually is greater because we close it when + * comes the time to write a new event and the packet's content + * size is >= 4 MiB), except the last one which can be smaller. + */ + if (G_UNLIKELY(!stream->sc->has_packets)) { + if (stream->packet_state.is_open && + bt_ctfser_get_offset_in_current_packet_bits(&stream->ctfser) / 8 >= 4 * 1024 * 1024) { + /* + * Stream's current packet is larger than 4 MiB: + * close it. A new packet will be opened just + * below. + */ + ret = fs_sink_stream_close_packet(stream, NULL); + if (ret) { + BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, "Failed to close packet."); + status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; + goto end; + } + } + + if (!stream->packet_state.is_open) { + /* Stream's packet is not currently opened: open it */ + ret = fs_sink_stream_open_packet(stream, NULL, NULL); + if (ret) { + BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, "Failed to open packet."); + status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; + goto end; + } + } + } + + BT_ASSERT_DBG(stream->packet_state.is_open); + ret = fs_sink_stream_write_event(stream, cs, ir_event, ec); + if (G_UNLIKELY(ret)) { + BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, "Failed to write event."); + status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; + goto end; + } end: - return status; + return status; } -static inline -bt_component_class_sink_consume_method_status handle_packet_beginning_msg( - struct fs_sink_comp *fs_sink, const bt_message *msg) +static inline bt_component_class_sink_consume_method_status +handle_packet_beginning_msg(struct fs_sink_comp *fs_sink, const bt_message *msg) { - int ret; - bt_component_class_sink_consume_method_status status = - BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_OK; - const bt_packet *ir_packet = - bt_message_packet_beginning_borrow_packet_const(msg); - const bt_stream *ir_stream = bt_packet_borrow_stream_const(ir_packet); - struct fs_sink_stream *stream; - const bt_clock_snapshot *cs = NULL; - - stream = borrow_stream(fs_sink, ir_stream); - if (G_UNLIKELY(!stream)) { - BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, - "Failed to borrow stream."); - status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; - goto end; - } - - if (stream->sc->packets_have_ts_begin) { - cs = bt_message_packet_beginning_borrow_default_clock_snapshot_const( - msg); - BT_ASSERT(cs); - } - - /* - * If we previously received a discarded events message with - * a time range, make sure that its beginning time matches what's - * expected for CTF 1.8, that is: - * - * * Its beginning time is the previous packet's end - * time (or the current packet's beginning time if - * this is the first packet). - * - * We check this here instead of in handle_packet_end_msg() - * because we want to catch any incompatible message as early as - * possible to report the error. - * - * Validation of the discarded events message's end time is - * performed in handle_packet_end_msg(). - */ - if (stream->discarded_events_state.in_range) { - uint64_t expected_cs; - - /* - * `stream->discarded_events_state.in_range` is only set - * when the stream class's discarded events have a time - * range. - * - * It is required that the packet beginning and end - * messages for this stream class have times when - * discarded events have a time range. - */ - BT_ASSERT(stream->sc->discarded_events_has_ts); - BT_ASSERT(stream->sc->packets_have_ts_begin); - BT_ASSERT(stream->sc->packets_have_ts_end); - - if (stream->prev_packet_state.end_cs == UINT64_C(-1)) { - /* We're opening the first packet */ - expected_cs = bt_clock_snapshot_get_value(cs); - } else { - expected_cs = stream->prev_packet_state.end_cs; - } - - if (stream->discarded_events_state.beginning_cs != - expected_cs) { - BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, - "Incompatible discarded events message: " - "unexpected beginning time: " - "beginning-cs-val=%" PRIu64 ", " - "expected-beginning-cs-val=%" PRIu64 ", " - "stream-id=%" PRIu64 ", stream-name=\"%s\", " - "trace-name=\"%s\", path=\"%s/%s\"", - stream->discarded_events_state.beginning_cs, - expected_cs, - bt_stream_get_id(ir_stream), - bt_stream_get_name(ir_stream), - bt_trace_get_name( - bt_stream_borrow_trace_const(ir_stream)), - stream->trace->path->str, stream->file_name->str); - status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; - goto end; - } - } - - /* - * If we previously received a discarded packets message with a - * time range, make sure that its beginning and end times match - * what's expected for CTF 1.8, that is: - * - * * Its beginning time is the previous packet's end time. - * - * * Its end time is the current packet's beginning time. - */ - if (stream->discarded_packets_state.in_range) { - uint64_t expected_end_cs; - - /* - * `stream->discarded_packets_state.in_range` is only - * set when the stream class's discarded packets have a - * time range. - * - * It is required that the packet beginning and end - * messages for this stream class have times when - * discarded packets have a time range. - */ - BT_ASSERT(stream->sc->discarded_packets_has_ts); - BT_ASSERT(stream->sc->packets_have_ts_begin); - BT_ASSERT(stream->sc->packets_have_ts_end); - - /* - * It is not supported to have a discarded packets - * message _before_ the first packet: we cannot validate - * that its beginning time is compatible with CTF 1.8 in - * this case. - */ - if (stream->prev_packet_state.end_cs == UINT64_C(-1)) { - BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, - "Incompatible discarded packets message " - "occurring before the stream's first packet: " - "stream-id=%" PRIu64 ", stream-name=\"%s\", " - "trace-name=\"%s\", path=\"%s/%s\"", - bt_stream_get_id(ir_stream), - bt_stream_get_name(ir_stream), - bt_trace_get_name( - bt_stream_borrow_trace_const(ir_stream)), - stream->trace->path->str, stream->file_name->str); - status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; - goto end; - } - - if (stream->discarded_packets_state.beginning_cs != - stream->prev_packet_state.end_cs) { - BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, - "Incompatible discarded packets message: " - "unexpected beginning time: " - "beginning-cs-val=%" PRIu64 ", " - "expected-beginning-cs-val=%" PRIu64 ", " - "stream-id=%" PRIu64 ", stream-name=\"%s\", " - "trace-name=\"%s\", path=\"%s/%s\"", - stream->discarded_packets_state.beginning_cs, - stream->prev_packet_state.end_cs, - bt_stream_get_id(ir_stream), - bt_stream_get_name(ir_stream), - bt_trace_get_name( - bt_stream_borrow_trace_const(ir_stream)), - stream->trace->path->str, stream->file_name->str); - status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; - goto end; - } - - expected_end_cs = bt_clock_snapshot_get_value(cs); - - if (stream->discarded_packets_state.end_cs != - expected_end_cs) { - BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, - "Incompatible discarded packets message: " - "unexpected end time: " - "end-cs-val=%" PRIu64 ", " - "expected-end-cs-val=%" PRIu64 ", " - "stream-id=%" PRIu64 ", stream-name=\"%s\", " - "trace-name=\"%s\", path=\"%s/%s\"", - stream->discarded_packets_state.end_cs, - expected_end_cs, - bt_stream_get_id(ir_stream), - bt_stream_get_name(ir_stream), - bt_trace_get_name( - bt_stream_borrow_trace_const(ir_stream)), - stream->trace->path->str, stream->file_name->str); - status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; - goto end; - } - } - - /* - * We're not in a discarded packets time range anymore since we - * require that the discarded packets time ranges go from one - * packet's end time to the next packet's beginning time, and - * we're handling a packet beginning message here. - */ - stream->discarded_packets_state.in_range = false; - - ret = fs_sink_stream_open_packet(stream, cs, ir_packet); - if (ret) { - BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, - "Failed to open packet."); - status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; - goto end; - } + int ret; + bt_component_class_sink_consume_method_status status = + BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_OK; + const bt_packet *ir_packet = bt_message_packet_beginning_borrow_packet_const(msg); + const bt_stream *ir_stream = bt_packet_borrow_stream_const(ir_packet); + struct fs_sink_stream *stream; + const bt_clock_snapshot *cs = NULL; + + stream = borrow_stream(fs_sink, ir_stream); + if (G_UNLIKELY(!stream)) { + BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, "Failed to borrow stream."); + status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; + goto end; + } + + if (stream->sc->packets_have_ts_begin) { + cs = bt_message_packet_beginning_borrow_default_clock_snapshot_const(msg); + BT_ASSERT(cs); + } + + /* + * If we previously received a discarded events message with + * a time range, make sure that its beginning time matches what's + * expected for CTF 1.8, that is: + * + * * Its beginning time is the previous packet's end + * time (or the current packet's beginning time if + * this is the first packet). + * + * We check this here instead of in handle_packet_end_msg() + * because we want to catch any incompatible message as early as + * possible to report the error. + * + * Validation of the discarded events message's end time is + * performed in handle_packet_end_msg(). + */ + if (stream->discarded_events_state.in_range) { + uint64_t expected_cs; + + /* + * `stream->discarded_events_state.in_range` is only set + * when the stream class's discarded events have a time + * range. + * + * It is required that the packet beginning and end + * messages for this stream class have times when + * discarded events have a time range. + */ + BT_ASSERT(stream->sc->discarded_events_has_ts); + BT_ASSERT(stream->sc->packets_have_ts_begin); + BT_ASSERT(stream->sc->packets_have_ts_end); + + if (stream->prev_packet_state.end_cs == UINT64_C(-1)) { + /* We're opening the first packet */ + expected_cs = bt_clock_snapshot_get_value(cs); + } else { + expected_cs = stream->prev_packet_state.end_cs; + } + + if (stream->discarded_events_state.beginning_cs != expected_cs) { + BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, + "Incompatible discarded events message: " + "unexpected beginning time: " + "beginning-cs-val=%" PRIu64 ", " + "expected-beginning-cs-val=%" PRIu64 ", " + "stream-id=%" PRIu64 ", stream-name=\"%s\", " + "trace-name=\"%s\", path=\"%s/%s\"", + stream->discarded_events_state.beginning_cs, expected_cs, + bt_stream_get_id(ir_stream), bt_stream_get_name(ir_stream), + bt_trace_get_name(bt_stream_borrow_trace_const(ir_stream)), + stream->trace->path->str, stream->file_name->str); + status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; + goto end; + } + } + + /* + * If we previously received a discarded packets message with a + * time range, make sure that its beginning and end times match + * what's expected for CTF 1.8, that is: + * + * * Its beginning time is the previous packet's end time. + * + * * Its end time is the current packet's beginning time. + */ + if (stream->discarded_packets_state.in_range) { + uint64_t expected_end_cs; + + /* + * `stream->discarded_packets_state.in_range` is only + * set when the stream class's discarded packets have a + * time range. + * + * It is required that the packet beginning and end + * messages for this stream class have times when + * discarded packets have a time range. + */ + BT_ASSERT(stream->sc->discarded_packets_has_ts); + BT_ASSERT(stream->sc->packets_have_ts_begin); + BT_ASSERT(stream->sc->packets_have_ts_end); + + /* + * It is not supported to have a discarded packets + * message _before_ the first packet: we cannot validate + * that its beginning time is compatible with CTF 1.8 in + * this case. + */ + if (stream->prev_packet_state.end_cs == UINT64_C(-1)) { + BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, + "Incompatible discarded packets message " + "occurring before the stream's first packet: " + "stream-id=%" PRIu64 ", stream-name=\"%s\", " + "trace-name=\"%s\", path=\"%s/%s\"", + bt_stream_get_id(ir_stream), bt_stream_get_name(ir_stream), + bt_trace_get_name(bt_stream_borrow_trace_const(ir_stream)), + stream->trace->path->str, stream->file_name->str); + status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; + goto end; + } + + if (stream->discarded_packets_state.beginning_cs != stream->prev_packet_state.end_cs) { + BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, + "Incompatible discarded packets message: " + "unexpected beginning time: " + "beginning-cs-val=%" PRIu64 ", " + "expected-beginning-cs-val=%" PRIu64 ", " + "stream-id=%" PRIu64 ", stream-name=\"%s\", " + "trace-name=\"%s\", path=\"%s/%s\"", + stream->discarded_packets_state.beginning_cs, + stream->prev_packet_state.end_cs, bt_stream_get_id(ir_stream), + bt_stream_get_name(ir_stream), + bt_trace_get_name(bt_stream_borrow_trace_const(ir_stream)), + stream->trace->path->str, stream->file_name->str); + status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; + goto end; + } + + expected_end_cs = bt_clock_snapshot_get_value(cs); + + if (stream->discarded_packets_state.end_cs != expected_end_cs) { + BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, + "Incompatible discarded packets message: " + "unexpected end time: " + "end-cs-val=%" PRIu64 ", " + "expected-end-cs-val=%" PRIu64 ", " + "stream-id=%" PRIu64 ", stream-name=\"%s\", " + "trace-name=\"%s\", path=\"%s/%s\"", + stream->discarded_packets_state.end_cs, expected_end_cs, + bt_stream_get_id(ir_stream), bt_stream_get_name(ir_stream), + bt_trace_get_name(bt_stream_borrow_trace_const(ir_stream)), + stream->trace->path->str, stream->file_name->str); + status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; + goto end; + } + } + + /* + * We're not in a discarded packets time range anymore since we + * require that the discarded packets time ranges go from one + * packet's end time to the next packet's beginning time, and + * we're handling a packet beginning message here. + */ + stream->discarded_packets_state.in_range = false; + + ret = fs_sink_stream_open_packet(stream, cs, ir_packet); + if (ret) { + BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, "Failed to open packet."); + status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; + goto end; + } end: - return status; + return status; } -static inline -bt_component_class_sink_consume_method_status handle_packet_end_msg( - struct fs_sink_comp *fs_sink, const bt_message *msg) +static inline bt_component_class_sink_consume_method_status +handle_packet_end_msg(struct fs_sink_comp *fs_sink, const bt_message *msg) { - int ret; - bt_component_class_sink_consume_method_status status = - BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_OK; - const bt_packet *ir_packet = - bt_message_packet_end_borrow_packet_const(msg); - const bt_stream *ir_stream = bt_packet_borrow_stream_const(ir_packet); - struct fs_sink_stream *stream; - const bt_clock_snapshot *cs = NULL; - - stream = borrow_stream(fs_sink, ir_stream); - if (G_UNLIKELY(!stream)) { - BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, - "Failed to borrow stream."); - status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; - goto end; - } - - if (stream->sc->packets_have_ts_end) { - cs = bt_message_packet_end_borrow_default_clock_snapshot_const( - msg); - BT_ASSERT(cs); - } - - /* - * If we previously received a discarded events message with - * a time range, make sure that its end time matches what's - * expected for CTF 1.8, that is: - * - * * Its end time is the current packet's end time. - * - * Validation of the discarded events message's beginning time - * is performed in handle_packet_beginning_msg(). - */ - if (stream->discarded_events_state.in_range) { - uint64_t expected_cs; - - /* - * `stream->discarded_events_state.in_range` is only set - * when the stream class's discarded events have a time - * range. - * - * It is required that the packet beginning and end - * messages for this stream class have times when - * discarded events have a time range. - */ - BT_ASSERT(stream->sc->discarded_events_has_ts); - BT_ASSERT(stream->sc->packets_have_ts_begin); - BT_ASSERT(stream->sc->packets_have_ts_end); - - expected_cs = bt_clock_snapshot_get_value(cs); - - if (stream->discarded_events_state.end_cs != expected_cs) { - BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, - "Incompatible discarded events message: " - "unexpected end time: " - "end-cs-val=%" PRIu64 ", " - "expected-end-cs-val=%" PRIu64 ", " - "stream-id=%" PRIu64 ", stream-name=\"%s\", " - "trace-name=\"%s\", path=\"%s/%s\"", - stream->discarded_events_state.end_cs, - expected_cs, - bt_stream_get_id(ir_stream), - bt_stream_get_name(ir_stream), - bt_trace_get_name( - bt_stream_borrow_trace_const(ir_stream)), - stream->trace->path->str, stream->file_name->str); - status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; - goto end; - } - } - - ret = fs_sink_stream_close_packet(stream, cs); - if (ret) { - BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, - "Failed to close packet."); - status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; - goto end; - } - - /* - * We're not in a discarded events time range anymore since we - * require that the discarded events time ranges go from one - * packet's end time to the next packet's end time, and we're - * handling a packet end message here. - */ - stream->discarded_events_state.in_range = false; + int ret; + bt_component_class_sink_consume_method_status status = + BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_OK; + const bt_packet *ir_packet = bt_message_packet_end_borrow_packet_const(msg); + const bt_stream *ir_stream = bt_packet_borrow_stream_const(ir_packet); + struct fs_sink_stream *stream; + const bt_clock_snapshot *cs = NULL; + + stream = borrow_stream(fs_sink, ir_stream); + if (G_UNLIKELY(!stream)) { + BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, "Failed to borrow stream."); + status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; + goto end; + } + + if (stream->sc->packets_have_ts_end) { + cs = bt_message_packet_end_borrow_default_clock_snapshot_const(msg); + BT_ASSERT(cs); + } + + /* + * If we previously received a discarded events message with + * a time range, make sure that its end time matches what's + * expected for CTF 1.8, that is: + * + * * Its end time is the current packet's end time. + * + * Validation of the discarded events message's beginning time + * is performed in handle_packet_beginning_msg(). + */ + if (stream->discarded_events_state.in_range) { + uint64_t expected_cs; + + /* + * `stream->discarded_events_state.in_range` is only set + * when the stream class's discarded events have a time + * range. + * + * It is required that the packet beginning and end + * messages for this stream class have times when + * discarded events have a time range. + */ + BT_ASSERT(stream->sc->discarded_events_has_ts); + BT_ASSERT(stream->sc->packets_have_ts_begin); + BT_ASSERT(stream->sc->packets_have_ts_end); + + expected_cs = bt_clock_snapshot_get_value(cs); + + if (stream->discarded_events_state.end_cs != expected_cs) { + BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, + "Incompatible discarded events message: " + "unexpected end time: " + "end-cs-val=%" PRIu64 ", " + "expected-end-cs-val=%" PRIu64 ", " + "stream-id=%" PRIu64 ", stream-name=\"%s\", " + "trace-name=\"%s\", path=\"%s/%s\"", + stream->discarded_events_state.end_cs, expected_cs, + bt_stream_get_id(ir_stream), bt_stream_get_name(ir_stream), + bt_trace_get_name(bt_stream_borrow_trace_const(ir_stream)), + stream->trace->path->str, stream->file_name->str); + status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; + goto end; + } + } + + ret = fs_sink_stream_close_packet(stream, cs); + if (ret) { + BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, "Failed to close packet."); + status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; + goto end; + } + + /* + * We're not in a discarded events time range anymore since we + * require that the discarded events time ranges go from one + * packet's end time to the next packet's end time, and we're + * handling a packet end message here. + */ + stream->discarded_events_state.in_range = false; end: - return status; + return status; } -static inline -bt_component_class_sink_consume_method_status handle_stream_beginning_msg( - struct fs_sink_comp *fs_sink, const bt_message *msg) +static inline bt_component_class_sink_consume_method_status +handle_stream_beginning_msg(struct fs_sink_comp *fs_sink, const bt_message *msg) { - bt_component_class_sink_consume_method_status status = - BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_OK; - const bt_stream *ir_stream = - bt_message_stream_beginning_borrow_stream_const(msg); - const bt_stream_class *ir_sc = - bt_stream_borrow_class_const(ir_stream); - struct fs_sink_stream *stream; - bool packets_have_beginning_end_cs = - bt_stream_class_packets_have_beginning_default_clock_snapshot(ir_sc) && - bt_stream_class_packets_have_end_default_clock_snapshot(ir_sc); - - /* - * Not supported: discarded events or discarded packets support - * without packets support. Packets are the way to know where - * discarded events/packets occurred in CTF 1.8. - */ - if (!bt_stream_class_supports_packets(ir_sc)) { - BT_ASSERT(!bt_stream_class_supports_discarded_packets(ir_sc)); - - if (!fs_sink->ignore_discarded_events && - bt_stream_class_supports_discarded_events(ir_sc)) { - BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, - "Unsupported stream: " - "stream does not support packets, " - "but supports discarded events: " - "stream-addr=%p, " - "stream-id=%" PRIu64 ", " - "stream-name=\"%s\"", - ir_stream, bt_stream_get_id(ir_stream), - bt_stream_get_name(ir_stream)); - status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; - goto end; - } - } - - /* - * Not supported: discarded events with default clock snapshots, - * but packet beginning/end without default clock snapshot. - */ - if (!fs_sink->ignore_discarded_events && - bt_stream_class_discarded_events_have_default_clock_snapshots(ir_sc) && - !packets_have_beginning_end_cs) { - BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, - "Unsupported stream: discarded events have " - "default clock snapshots, but packets have no " - "beginning and/or end default clock snapshots: " - "stream-addr=%p, " - "stream-id=%" PRIu64 ", " - "stream-name=\"%s\"", - ir_stream, bt_stream_get_id(ir_stream), - bt_stream_get_name(ir_stream)); - status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; - goto end; - } - - /* - * Not supported: discarded packets with default clock - * snapshots, but packet beginning/end without default clock - * snapshot. - */ - if (!fs_sink->ignore_discarded_packets && - bt_stream_class_discarded_packets_have_default_clock_snapshots(ir_sc) && - !packets_have_beginning_end_cs) { - BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, - "Unsupported stream: discarded packets have " - "default clock snapshots, but packets have no " - "beginning and/or end default clock snapshots: " - "stream-addr=%p, " - "stream-id=%" PRIu64 ", " - "stream-name=\"%s\"", - ir_stream, bt_stream_get_id(ir_stream), - bt_stream_get_name(ir_stream)); - status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; - goto end; - } - - stream = borrow_stream(fs_sink, ir_stream); - if (!stream) { - BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, - "Failed to borrow stream."); - status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; - goto end; - } - - BT_COMP_LOGI("Created new, empty stream file: " - "stream-id=%" PRIu64 ", stream-name=\"%s\", " - "trace-name=\"%s\", path=\"%s/%s\"", - bt_stream_get_id(ir_stream), bt_stream_get_name(ir_stream), - bt_trace_get_name(bt_stream_borrow_trace_const(ir_stream)), - stream->trace->path->str, stream->file_name->str); + bt_component_class_sink_consume_method_status status = + BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_OK; + const bt_stream *ir_stream = bt_message_stream_beginning_borrow_stream_const(msg); + const bt_stream_class *ir_sc = bt_stream_borrow_class_const(ir_stream); + struct fs_sink_stream *stream; + bool packets_have_beginning_end_cs = + bt_stream_class_packets_have_beginning_default_clock_snapshot(ir_sc) && + bt_stream_class_packets_have_end_default_clock_snapshot(ir_sc); + + /* + * Not supported: discarded events or discarded packets support + * without packets support. Packets are the way to know where + * discarded events/packets occurred in CTF 1.8. + */ + if (!bt_stream_class_supports_packets(ir_sc)) { + BT_ASSERT(!bt_stream_class_supports_discarded_packets(ir_sc)); + + if (!fs_sink->ignore_discarded_events && bt_stream_class_supports_discarded_events(ir_sc)) { + BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, + "Unsupported stream: " + "stream does not support packets, " + "but supports discarded events: " + "stream-addr=%p, " + "stream-id=%" PRIu64 ", " + "stream-name=\"%s\"", + ir_stream, bt_stream_get_id(ir_stream), + bt_stream_get_name(ir_stream)); + status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; + goto end; + } + } + + /* + * Not supported: discarded events with default clock snapshots, + * but packet beginning/end without default clock snapshot. + */ + if (!fs_sink->ignore_discarded_events && + bt_stream_class_discarded_events_have_default_clock_snapshots(ir_sc) && + !packets_have_beginning_end_cs) { + BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, + "Unsupported stream: discarded events have " + "default clock snapshots, but packets have no " + "beginning and/or end default clock snapshots: " + "stream-addr=%p, " + "stream-id=%" PRIu64 ", " + "stream-name=\"%s\"", + ir_stream, bt_stream_get_id(ir_stream), + bt_stream_get_name(ir_stream)); + status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; + goto end; + } + + /* + * Not supported: discarded packets with default clock + * snapshots, but packet beginning/end without default clock + * snapshot. + */ + if (!fs_sink->ignore_discarded_packets && + bt_stream_class_discarded_packets_have_default_clock_snapshots(ir_sc) && + !packets_have_beginning_end_cs) { + BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, + "Unsupported stream: discarded packets have " + "default clock snapshots, but packets have no " + "beginning and/or end default clock snapshots: " + "stream-addr=%p, " + "stream-id=%" PRIu64 ", " + "stream-name=\"%s\"", + ir_stream, bt_stream_get_id(ir_stream), + bt_stream_get_name(ir_stream)); + status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; + goto end; + } + + stream = borrow_stream(fs_sink, ir_stream); + if (!stream) { + BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, "Failed to borrow stream."); + status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; + goto end; + } + + BT_COMP_LOGI("Created new, empty stream file: " + "stream-id=%" PRIu64 ", stream-name=\"%s\", " + "trace-name=\"%s\", path=\"%s/%s\"", + bt_stream_get_id(ir_stream), bt_stream_get_name(ir_stream), + bt_trace_get_name(bt_stream_borrow_trace_const(ir_stream)), + stream->trace->path->str, stream->file_name->str); end: - return status; + return status; } -static inline -bt_component_class_sink_consume_method_status handle_stream_end_msg( - struct fs_sink_comp *fs_sink, const bt_message *msg) +static inline bt_component_class_sink_consume_method_status +handle_stream_end_msg(struct fs_sink_comp *fs_sink, const bt_message *msg) { - bt_component_class_sink_consume_method_status status = - BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_OK; - const bt_stream *ir_stream = - bt_message_stream_end_borrow_stream_const(msg); - struct fs_sink_stream *stream; - - stream = borrow_stream(fs_sink, ir_stream); - if (!stream) { - BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, - "Failed to borrow stream."); - status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; - goto end; - } - - if (G_UNLIKELY(!stream->sc->has_packets && - stream->packet_state.is_open)) { - /* Close stream's current artificial packet */ - int ret = fs_sink_stream_close_packet(stream, NULL); - - if (ret) { - BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, - "Failed to close packet."); - status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; - goto end; - } - } - - BT_COMP_LOGI("Closing stream file: " - "stream-id=%" PRIu64 ", stream-name=\"%s\", " - "trace-name=\"%s\", path=\"%s/%s\"", - bt_stream_get_id(ir_stream), bt_stream_get_name(ir_stream), - bt_trace_get_name(bt_stream_borrow_trace_const(ir_stream)), - stream->trace->path->str, stream->file_name->str); - - /* - * This destroys the stream object and frees all its resources, - * closing the stream file. - */ - g_hash_table_remove(stream->trace->streams, ir_stream); + bt_component_class_sink_consume_method_status status = + BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_OK; + const bt_stream *ir_stream = bt_message_stream_end_borrow_stream_const(msg); + struct fs_sink_stream *stream; + + stream = borrow_stream(fs_sink, ir_stream); + if (!stream) { + BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, "Failed to borrow stream."); + status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; + goto end; + } + + if (G_UNLIKELY(!stream->sc->has_packets && stream->packet_state.is_open)) { + /* Close stream's current artificial packet */ + int ret = fs_sink_stream_close_packet(stream, NULL); + + if (ret) { + BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, "Failed to close packet."); + status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; + goto end; + } + } + + BT_COMP_LOGI("Closing stream file: " + "stream-id=%" PRIu64 ", stream-name=\"%s\", " + "trace-name=\"%s\", path=\"%s/%s\"", + bt_stream_get_id(ir_stream), bt_stream_get_name(ir_stream), + bt_trace_get_name(bt_stream_borrow_trace_const(ir_stream)), + stream->trace->path->str, stream->file_name->str); + + /* + * This destroys the stream object and frees all its resources, + * closing the stream file. + */ + g_hash_table_remove(stream->trace->streams, ir_stream); end: - return status; + return status; } -static inline -bt_component_class_sink_consume_method_status handle_discarded_events_msg( - struct fs_sink_comp *fs_sink, const bt_message *msg) +static inline bt_component_class_sink_consume_method_status +handle_discarded_events_msg(struct fs_sink_comp *fs_sink, const bt_message *msg) { - bt_component_class_sink_consume_method_status status = - BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_OK; - const bt_stream *ir_stream = - bt_message_discarded_events_borrow_stream_const(msg); - struct fs_sink_stream *stream; - const bt_clock_snapshot *cs = NULL; - bt_property_availability avail; - uint64_t count; - - stream = borrow_stream(fs_sink, ir_stream); - if (!stream) { - BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, - "Failed to borrow stream."); - status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; - goto end; - } - - if (fs_sink->ignore_discarded_events) { - BT_COMP_LOGI("Ignoring discarded events message: " - "stream-id=%" PRIu64 ", stream-name=\"%s\", " - "trace-name=\"%s\", path=\"%s/%s\"", - bt_stream_get_id(ir_stream), - bt_stream_get_name(ir_stream), - bt_trace_get_name( - bt_stream_borrow_trace_const(ir_stream)), - stream->trace->path->str, stream->file_name->str); - goto end; - } - - if (stream->discarded_events_state.in_range) { - BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, - "Unsupported contiguous discarded events message: " - "stream-id=%" PRIu64 ", stream-name=\"%s\", " - "trace-name=\"%s\", path=\"%s/%s\"", - bt_stream_get_id(ir_stream), - bt_stream_get_name(ir_stream), - bt_trace_get_name( - bt_stream_borrow_trace_const(ir_stream)), - stream->trace->path->str, stream->file_name->str); - status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; - goto end; - } - - /* - * If we're currently in an opened packet (got a packet - * beginning message, but no packet end message yet), we do not - * support having a discarded events message with a time range - * because we require that the discarded events message's time - * range go from a packet's end time to the next packet's end - * time. - */ - if (stream->packet_state.is_open && - stream->sc->discarded_events_has_ts) { - BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, - "Unsupported discarded events message with " - "default clock snapshots occurring within a packet: " - "stream-id=%" PRIu64 ", stream-name=\"%s\", " - "trace-name=\"%s\", path=\"%s/%s\"", - bt_stream_get_id(ir_stream), - bt_stream_get_name(ir_stream), - bt_trace_get_name( - bt_stream_borrow_trace_const(ir_stream)), - stream->trace->path->str, stream->file_name->str); - status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; - goto end; - } - - if (stream->sc->discarded_events_has_ts) { - /* - * Make the stream's state be in the time range of a - * discarded events message since we have the message's - * time range (`stream->sc->discarded_events_has_ts`). - */ - stream->discarded_events_state.in_range = true; - - /* - * The clock snapshot values will be validated when - * handling the next packet beginning and end messages - * (next calls to handle_packet_beginning_msg() and - * handle_packet_end_msg()). - */ - cs = bt_message_discarded_events_borrow_beginning_default_clock_snapshot_const( - msg); - BT_ASSERT(cs); - stream->discarded_events_state.beginning_cs = - bt_clock_snapshot_get_value(cs); - cs = bt_message_discarded_events_borrow_end_default_clock_snapshot_const( - msg); - BT_ASSERT(cs); - stream->discarded_events_state.end_cs = bt_clock_snapshot_get_value(cs); - } - - avail = bt_message_discarded_events_get_count(msg, &count); - if (avail != BT_PROPERTY_AVAILABILITY_AVAILABLE) { - /* - * There's no specific count of discarded events: set it - * to 1 so that we know that we at least discarded - * something. - */ - count = 1; - } - - stream->packet_state.discarded_events_counter += count; + bt_component_class_sink_consume_method_status status = + BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_OK; + const bt_stream *ir_stream = bt_message_discarded_events_borrow_stream_const(msg); + struct fs_sink_stream *stream; + const bt_clock_snapshot *cs = NULL; + bt_property_availability avail; + uint64_t count; + + stream = borrow_stream(fs_sink, ir_stream); + if (!stream) { + BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, "Failed to borrow stream."); + status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; + goto end; + } + + if (fs_sink->ignore_discarded_events) { + BT_COMP_LOGI("Ignoring discarded events message: " + "stream-id=%" PRIu64 ", stream-name=\"%s\", " + "trace-name=\"%s\", path=\"%s/%s\"", + bt_stream_get_id(ir_stream), bt_stream_get_name(ir_stream), + bt_trace_get_name(bt_stream_borrow_trace_const(ir_stream)), + stream->trace->path->str, stream->file_name->str); + goto end; + } + + if (stream->discarded_events_state.in_range) { + BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, + "Unsupported contiguous discarded events message: " + "stream-id=%" PRIu64 ", stream-name=\"%s\", " + "trace-name=\"%s\", path=\"%s/%s\"", + bt_stream_get_id(ir_stream), bt_stream_get_name(ir_stream), + bt_trace_get_name(bt_stream_borrow_trace_const(ir_stream)), + stream->trace->path->str, stream->file_name->str); + status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; + goto end; + } + + /* + * If we're currently in an opened packet (got a packet + * beginning message, but no packet end message yet), we do not + * support having a discarded events message with a time range + * because we require that the discarded events message's time + * range go from a packet's end time to the next packet's end + * time. + */ + if (stream->packet_state.is_open && stream->sc->discarded_events_has_ts) { + BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, + "Unsupported discarded events message with " + "default clock snapshots occurring within a packet: " + "stream-id=%" PRIu64 ", stream-name=\"%s\", " + "trace-name=\"%s\", path=\"%s/%s\"", + bt_stream_get_id(ir_stream), bt_stream_get_name(ir_stream), + bt_trace_get_name(bt_stream_borrow_trace_const(ir_stream)), + stream->trace->path->str, stream->file_name->str); + status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; + goto end; + } + + if (stream->sc->discarded_events_has_ts) { + /* + * Make the stream's state be in the time range of a + * discarded events message since we have the message's + * time range (`stream->sc->discarded_events_has_ts`). + */ + stream->discarded_events_state.in_range = true; + + /* + * The clock snapshot values will be validated when + * handling the next packet beginning and end messages + * (next calls to handle_packet_beginning_msg() and + * handle_packet_end_msg()). + */ + cs = bt_message_discarded_events_borrow_beginning_default_clock_snapshot_const(msg); + BT_ASSERT(cs); + stream->discarded_events_state.beginning_cs = bt_clock_snapshot_get_value(cs); + cs = bt_message_discarded_events_borrow_end_default_clock_snapshot_const(msg); + BT_ASSERT(cs); + stream->discarded_events_state.end_cs = bt_clock_snapshot_get_value(cs); + } + + avail = bt_message_discarded_events_get_count(msg, &count); + if (avail != BT_PROPERTY_AVAILABILITY_AVAILABLE) { + /* + * There's no specific count of discarded events: set it + * to 1 so that we know that we at least discarded + * something. + */ + count = 1; + } + + stream->packet_state.discarded_events_counter += count; end: - return status; + return status; } -static inline -bt_component_class_sink_consume_method_status handle_discarded_packets_msg( - struct fs_sink_comp *fs_sink, const bt_message *msg) +static inline bt_component_class_sink_consume_method_status +handle_discarded_packets_msg(struct fs_sink_comp *fs_sink, const bt_message *msg) { - bt_component_class_sink_consume_method_status status = - BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_OK; - const bt_stream *ir_stream = - bt_message_discarded_packets_borrow_stream_const(msg); - struct fs_sink_stream *stream; - const bt_clock_snapshot *cs = NULL; - bt_property_availability avail; - uint64_t count; - - stream = borrow_stream(fs_sink, ir_stream); - if (!stream) { - BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, - "Failed to borrow stream."); - status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; - goto end; - } - - if (fs_sink->ignore_discarded_packets) { - BT_COMP_LOGI("Ignoring discarded packets message: " - "stream-id=%" PRIu64 ", stream-name=\"%s\", " - "trace-name=\"%s\", path=\"%s/%s\"", - bt_stream_get_id(ir_stream), - bt_stream_get_name(ir_stream), - bt_trace_get_name( - bt_stream_borrow_trace_const(ir_stream)), - stream->trace->path->str, stream->file_name->str); - goto end; - } - - if (stream->discarded_packets_state.in_range) { - BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, - "Unsupported contiguous discarded packets message: " - "stream-id=%" PRIu64 ", stream-name=\"%s\", " - "trace-name=\"%s\", path=\"%s/%s\"", - bt_stream_get_id(ir_stream), - bt_stream_get_name(ir_stream), - bt_trace_get_name( - bt_stream_borrow_trace_const(ir_stream)), - stream->trace->path->str, stream->file_name->str); - status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; - goto end; - } - - /* - * Discarded packets messages are guaranteed to occur between - * packets. - */ - BT_ASSERT(!stream->packet_state.is_open); - - if (stream->sc->discarded_packets_has_ts) { - /* - * Make the stream's state be in the time range of a - * discarded packets message since we have the message's - * time range (`stream->sc->discarded_packets_has_ts`). - */ - stream->discarded_packets_state.in_range = true; - - /* - * The clock snapshot values will be validated when - * handling the next packet beginning message (next call - * to handle_packet_beginning_msg()). - */ - cs = bt_message_discarded_packets_borrow_beginning_default_clock_snapshot_const( - msg); - BT_ASSERT(cs); - stream->discarded_packets_state.beginning_cs = - bt_clock_snapshot_get_value(cs); - cs = bt_message_discarded_packets_borrow_end_default_clock_snapshot_const( - msg); - BT_ASSERT(cs); - stream->discarded_packets_state.end_cs = - bt_clock_snapshot_get_value(cs); - } - - avail = bt_message_discarded_packets_get_count(msg, &count); - if (avail != BT_PROPERTY_AVAILABILITY_AVAILABLE) { - /* - * There's no specific count of discarded packets: set - * it to 1 so that we know that we at least discarded - * something. - */ - count = 1; - } - - stream->packet_state.seq_num += count; + bt_component_class_sink_consume_method_status status = + BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_OK; + const bt_stream *ir_stream = bt_message_discarded_packets_borrow_stream_const(msg); + struct fs_sink_stream *stream; + const bt_clock_snapshot *cs = NULL; + bt_property_availability avail; + uint64_t count; + + stream = borrow_stream(fs_sink, ir_stream); + if (!stream) { + BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, "Failed to borrow stream."); + status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; + goto end; + } + + if (fs_sink->ignore_discarded_packets) { + BT_COMP_LOGI("Ignoring discarded packets message: " + "stream-id=%" PRIu64 ", stream-name=\"%s\", " + "trace-name=\"%s\", path=\"%s/%s\"", + bt_stream_get_id(ir_stream), bt_stream_get_name(ir_stream), + bt_trace_get_name(bt_stream_borrow_trace_const(ir_stream)), + stream->trace->path->str, stream->file_name->str); + goto end; + } + + if (stream->discarded_packets_state.in_range) { + BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, + "Unsupported contiguous discarded packets message: " + "stream-id=%" PRIu64 ", stream-name=\"%s\", " + "trace-name=\"%s\", path=\"%s/%s\"", + bt_stream_get_id(ir_stream), bt_stream_get_name(ir_stream), + bt_trace_get_name(bt_stream_borrow_trace_const(ir_stream)), + stream->trace->path->str, stream->file_name->str); + status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; + goto end; + } + + /* + * Discarded packets messages are guaranteed to occur between + * packets. + */ + BT_ASSERT(!stream->packet_state.is_open); + + if (stream->sc->discarded_packets_has_ts) { + /* + * Make the stream's state be in the time range of a + * discarded packets message since we have the message's + * time range (`stream->sc->discarded_packets_has_ts`). + */ + stream->discarded_packets_state.in_range = true; + + /* + * The clock snapshot values will be validated when + * handling the next packet beginning message (next call + * to handle_packet_beginning_msg()). + */ + cs = bt_message_discarded_packets_borrow_beginning_default_clock_snapshot_const(msg); + BT_ASSERT(cs); + stream->discarded_packets_state.beginning_cs = bt_clock_snapshot_get_value(cs); + cs = bt_message_discarded_packets_borrow_end_default_clock_snapshot_const(msg); + BT_ASSERT(cs); + stream->discarded_packets_state.end_cs = bt_clock_snapshot_get_value(cs); + } + + avail = bt_message_discarded_packets_get_count(msg, &count); + if (avail != BT_PROPERTY_AVAILABILITY_AVAILABLE) { + /* + * There's no specific count of discarded packets: set + * it to 1 so that we know that we at least discarded + * something. + */ + count = 1; + } + + stream->packet_state.seq_num += count; end: - return status; + return status; } -static inline -void put_messages(bt_message_array_const msgs, uint64_t count) +static inline void put_messages(bt_message_array_const msgs, uint64_t count) { - uint64_t i; + uint64_t i; - for (i = 0; i < count; i++) { - BT_MESSAGE_PUT_REF_AND_RESET(msgs[i]); - } + for (i = 0; i < count; i++) { + BT_MESSAGE_PUT_REF_AND_RESET(msgs[i]); + } } BT_HIDDEN -bt_component_class_sink_consume_method_status ctf_fs_sink_consume( - bt_self_component_sink *self_comp) +bt_component_class_sink_consume_method_status ctf_fs_sink_consume(bt_self_component_sink *self_comp) { - bt_component_class_sink_consume_method_status status = - BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_OK; - struct fs_sink_comp *fs_sink; - bt_message_iterator_next_status next_status; - uint64_t msg_count = 0; - bt_message_array_const msgs; - - fs_sink = (fs_sink_comp *) bt_self_component_get_data( - bt_self_component_sink_as_self_component(self_comp)); - BT_ASSERT_DBG(fs_sink); - BT_ASSERT_DBG(fs_sink->upstream_iter); - - /* Consume messages */ - next_status = bt_message_iterator_next( - fs_sink->upstream_iter, &msgs, &msg_count); - if (next_status < 0) { - status = (bt_component_class_sink_consume_method_status) next_status; - BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, - "Failed to get next message from upstream iterator."); - goto end; - } - - switch (next_status) { - case BT_MESSAGE_ITERATOR_NEXT_STATUS_OK: - { - uint64_t i; - - for (i = 0; i < msg_count; i++) { - const bt_message *msg = msgs[i]; - - BT_ASSERT_DBG(msg); - - switch (bt_message_get_type(msg)) { - case BT_MESSAGE_TYPE_EVENT: - status = handle_event_msg(fs_sink, msg); - break; - case BT_MESSAGE_TYPE_PACKET_BEGINNING: - status = handle_packet_beginning_msg( - fs_sink, msg); - break; - case BT_MESSAGE_TYPE_PACKET_END: - status = handle_packet_end_msg( - fs_sink, msg); - break; - case BT_MESSAGE_TYPE_MESSAGE_ITERATOR_INACTIVITY: - /* Ignore */ - BT_COMP_LOGD_STR("Ignoring message iterator inactivity message."); - break; - case BT_MESSAGE_TYPE_STREAM_BEGINNING: - status = handle_stream_beginning_msg( - fs_sink, msg); - break; - case BT_MESSAGE_TYPE_STREAM_END: - status = handle_stream_end_msg( - fs_sink, msg); - break; - case BT_MESSAGE_TYPE_DISCARDED_EVENTS: - status = handle_discarded_events_msg( - fs_sink, msg); - break; - case BT_MESSAGE_TYPE_DISCARDED_PACKETS: - status = handle_discarded_packets_msg( - fs_sink, msg); - break; - default: - bt_common_abort(); - } - - BT_MESSAGE_PUT_REF_AND_RESET(msgs[i]); - - if (status != BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_OK) { - BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, - "Failed to handle message: " - "generated CTF traces could be incomplete: " - "output-dir-path=\"%s\"", - fs_sink->output_dir_path->str); - goto error; - } - } - - break; - } - case BT_MESSAGE_ITERATOR_NEXT_STATUS_AGAIN: - status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_AGAIN; - break; - case BT_MESSAGE_ITERATOR_NEXT_STATUS_END: - /* TODO: Finalize all traces (should already be done?) */ - status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_END; - break; - default: - break; - } - - goto end; + bt_component_class_sink_consume_method_status status = + BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_OK; + struct fs_sink_comp *fs_sink; + bt_message_iterator_next_status next_status; + uint64_t msg_count = 0; + bt_message_array_const msgs; + + fs_sink = (fs_sink_comp *) bt_self_component_get_data( + bt_self_component_sink_as_self_component(self_comp)); + BT_ASSERT_DBG(fs_sink); + BT_ASSERT_DBG(fs_sink->upstream_iter); + + /* Consume messages */ + next_status = bt_message_iterator_next(fs_sink->upstream_iter, &msgs, &msg_count); + if (next_status < 0) { + status = (bt_component_class_sink_consume_method_status) next_status; + BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, + "Failed to get next message from upstream iterator."); + goto end; + } + + switch (next_status) { + case BT_MESSAGE_ITERATOR_NEXT_STATUS_OK: + { + uint64_t i; + + for (i = 0; i < msg_count; i++) { + const bt_message *msg = msgs[i]; + + BT_ASSERT_DBG(msg); + + switch (bt_message_get_type(msg)) { + case BT_MESSAGE_TYPE_EVENT: + status = handle_event_msg(fs_sink, msg); + break; + case BT_MESSAGE_TYPE_PACKET_BEGINNING: + status = handle_packet_beginning_msg(fs_sink, msg); + break; + case BT_MESSAGE_TYPE_PACKET_END: + status = handle_packet_end_msg(fs_sink, msg); + break; + case BT_MESSAGE_TYPE_MESSAGE_ITERATOR_INACTIVITY: + /* Ignore */ + BT_COMP_LOGD_STR("Ignoring message iterator inactivity message."); + break; + case BT_MESSAGE_TYPE_STREAM_BEGINNING: + status = handle_stream_beginning_msg(fs_sink, msg); + break; + case BT_MESSAGE_TYPE_STREAM_END: + status = handle_stream_end_msg(fs_sink, msg); + break; + case BT_MESSAGE_TYPE_DISCARDED_EVENTS: + status = handle_discarded_events_msg(fs_sink, msg); + break; + case BT_MESSAGE_TYPE_DISCARDED_PACKETS: + status = handle_discarded_packets_msg(fs_sink, msg); + break; + default: + bt_common_abort(); + } + + BT_MESSAGE_PUT_REF_AND_RESET(msgs[i]); + + if (status != BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_OK) { + BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, + "Failed to handle message: " + "generated CTF traces could be incomplete: " + "output-dir-path=\"%s\"", + fs_sink->output_dir_path->str); + goto error; + } + } + + break; + } + case BT_MESSAGE_ITERATOR_NEXT_STATUS_AGAIN: + status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_AGAIN; + break; + case BT_MESSAGE_ITERATOR_NEXT_STATUS_END: + /* TODO: Finalize all traces (should already be done?) */ + status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_END; + break; + default: + break; + } + + goto end; error: - BT_ASSERT(status != BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_OK); - put_messages(msgs, msg_count); + BT_ASSERT(status != BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_OK); + put_messages(msgs, msg_count); end: - return status; + return status; } BT_HIDDEN bt_component_class_sink_graph_is_configured_method_status -ctf_fs_sink_graph_is_configured( - bt_self_component_sink *self_comp) +ctf_fs_sink_graph_is_configured(bt_self_component_sink *self_comp) { - bt_component_class_sink_graph_is_configured_method_status status; - bt_message_iterator_create_from_sink_component_status - msg_iter_status; - fs_sink_comp *fs_sink = (fs_sink_comp *) bt_self_component_get_data( - bt_self_component_sink_as_self_component(self_comp)); - - msg_iter_status = - bt_message_iterator_create_from_sink_component( - self_comp, - bt_self_component_sink_borrow_input_port_by_name( - self_comp, in_port_name), &fs_sink->upstream_iter); - if (msg_iter_status != BT_MESSAGE_ITERATOR_CREATE_FROM_SINK_COMPONENT_STATUS_OK) { - status = (bt_component_class_sink_graph_is_configured_method_status) msg_iter_status; - BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, - "Failed to create upstream iterator."); - goto end; - } - - status = BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_OK; + bt_component_class_sink_graph_is_configured_method_status status; + bt_message_iterator_create_from_sink_component_status msg_iter_status; + fs_sink_comp *fs_sink = (fs_sink_comp *) bt_self_component_get_data( + bt_self_component_sink_as_self_component(self_comp)); + + msg_iter_status = bt_message_iterator_create_from_sink_component( + self_comp, bt_self_component_sink_borrow_input_port_by_name(self_comp, in_port_name), + &fs_sink->upstream_iter); + if (msg_iter_status != BT_MESSAGE_ITERATOR_CREATE_FROM_SINK_COMPONENT_STATUS_OK) { + status = (bt_component_class_sink_graph_is_configured_method_status) msg_iter_status; + BT_COMP_LOGE_APPEND_CAUSE(fs_sink->self_comp, "Failed to create upstream iterator."); + goto end; + } + + status = BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_OK; end: - return status; + return status; } BT_HIDDEN void ctf_fs_sink_finalize(bt_self_component_sink *self_comp) { - fs_sink_comp *fs_sink = (fs_sink_comp *) bt_self_component_get_data( - bt_self_component_sink_as_self_component(self_comp)); + fs_sink_comp *fs_sink = (fs_sink_comp *) bt_self_component_get_data( + bt_self_component_sink_as_self_component(self_comp)); - destroy_fs_sink_comp(fs_sink); + destroy_fs_sink_comp(fs_sink); } diff --git a/src/plugins/ctf/fs-sink/fs-sink.hpp b/src/plugins/ctf/fs-sink/fs-sink.hpp index 983ca01d..d026cb29 100644 --- a/src/plugins/ctf/fs-sink/fs-sink.hpp +++ b/src/plugins/ctf/fs-sink/fs-sink.hpp @@ -12,57 +12,56 @@ #include #include -struct fs_sink_comp { - bt_logging_level log_level; - bt_self_component *self_comp; +struct fs_sink_comp +{ + bt_logging_level log_level; + bt_self_component *self_comp; - /* Owned by this */ - bt_message_iterator *upstream_iter; + /* Owned by this */ + bt_message_iterator *upstream_iter; - /* Base output directory path */ - GString *output_dir_path; + /* Base output directory path */ + GString *output_dir_path; - /* - * True if the component assumes that it will only write a - * single CTF trace (which can contain one or more data - * streams). This makes the component write the stream files - * directly in the output directory (`output_dir_path` above). - */ - bool assume_single_trace; + /* + * True if the component assumes that it will only write a + * single CTF trace (which can contain one or more data + * streams). This makes the component write the stream files + * directly in the output directory (`output_dir_path` above). + */ + bool assume_single_trace; - /* True to completely ignore discarded events messages */ - bool ignore_discarded_events; + /* True to completely ignore discarded events messages */ + bool ignore_discarded_events; - /* True to completely ignore discarded packets messages */ - bool ignore_discarded_packets; + /* True to completely ignore discarded packets messages */ + bool ignore_discarded_packets; - /* - * True to make the component quiet (nothing printed to the - * standard output). - */ - bool quiet; + /* + * True to make the component quiet (nothing printed to the + * standard output). + */ + bool quiet; - /* - * Hash table of `const bt_trace *` (weak) to - * `struct fs_sink_trace *` (owned by hash table). - */ - GHashTable *traces; + /* + * Hash table of `const bt_trace *` (weak) to + * `struct fs_sink_trace *` (owned by hash table). + */ + GHashTable *traces; }; BT_HIDDEN -bt_component_class_initialize_method_status ctf_fs_sink_init( - bt_self_component_sink *component, - bt_self_component_sink_configuration *config, - const bt_value *params, - void *init_method_data); +bt_component_class_initialize_method_status +ctf_fs_sink_init(bt_self_component_sink *component, bt_self_component_sink_configuration *config, + const bt_value *params, void *init_method_data); BT_HIDDEN -bt_component_class_sink_consume_method_status ctf_fs_sink_consume( - bt_self_component_sink *component); +bt_component_class_sink_consume_method_status +ctf_fs_sink_consume(bt_self_component_sink *component); BT_HIDDEN -bt_component_class_sink_graph_is_configured_method_status ctf_fs_sink_graph_is_configured( - bt_self_component_sink *component); +bt_component_class_sink_graph_is_configured_method_status +ctf_fs_sink_graph_is_configured(bt_self_component_sink *component); BT_HIDDEN void ctf_fs_sink_finalize(bt_self_component_sink *component); diff --git a/src/plugins/ctf/fs-sink/translate-ctf-ir-to-tsdl.cpp b/src/plugins/ctf/fs-sink/translate-ctf-ir-to-tsdl.cpp index c93db6a6..1d673820 100644 --- a/src/plugins/ctf/fs-sink/translate-ctf-ir-to-tsdl.cpp +++ b/src/plugins/ctf/fs-sink/translate-ctf-ir-to-tsdl.cpp @@ -17,962 +17,870 @@ #include "fs-sink-ctf-meta.hpp" -struct ctx { - unsigned int indent_level; - GString *tsdl; +struct ctx +{ + unsigned int indent_level; + GString *tsdl; }; -static inline -void append_indent(struct ctx *ctx) +static inline void append_indent(struct ctx *ctx) { - unsigned int i; + unsigned int i; - for (i = 0; i < ctx->indent_level; i++) { - g_string_append_c(ctx->tsdl, '\t'); - } + for (i = 0; i < ctx->indent_level; i++) { + g_string_append_c(ctx->tsdl, '\t'); + } } -static -void append_uuid(struct ctx *ctx, bt_uuid uuid) +static void append_uuid(struct ctx *ctx, bt_uuid uuid) { - g_string_append_printf(ctx->tsdl, - "\"" BT_UUID_FMT "\"", - BT_UUID_FMT_VALUES(uuid)); + g_string_append_printf(ctx->tsdl, "\"" BT_UUID_FMT "\"", BT_UUID_FMT_VALUES(uuid)); } -static -void append_quoted_string_content(struct ctx *ctx, const char *str) +static void append_quoted_string_content(struct ctx *ctx, const char *str) { - const char *ch; - - for (ch = str; *ch != '\0'; ch++) { - unsigned char uch = (unsigned char) *ch; - - if (uch < 32 || uch >= 127) { - switch (*ch) { - case '\a': - g_string_append(ctx->tsdl, "\\a"); - break; - case '\b': - g_string_append(ctx->tsdl, "\\b"); - break; - case '\f': - g_string_append(ctx->tsdl, "\\f"); - break; - case '\n': - g_string_append(ctx->tsdl, "\\n"); - break; - case '\r': - g_string_append(ctx->tsdl, "\\r"); - break; - case '\t': - g_string_append(ctx->tsdl, "\\t"); - break; - case '\v': - g_string_append(ctx->tsdl, "\\v"); - break; - default: - g_string_append_printf(ctx->tsdl, "\\x%02x", - (unsigned int) uch); - break; - } - } else if (*ch == '"' || *ch == '\\') { - g_string_append_c(ctx->tsdl, '\\'); - g_string_append_c(ctx->tsdl, *ch); - } else { - g_string_append_c(ctx->tsdl, *ch); - } - } + const char *ch; + + for (ch = str; *ch != '\0'; ch++) { + unsigned char uch = (unsigned char) *ch; + + if (uch < 32 || uch >= 127) { + switch (*ch) { + case '\a': + g_string_append(ctx->tsdl, "\\a"); + break; + case '\b': + g_string_append(ctx->tsdl, "\\b"); + break; + case '\f': + g_string_append(ctx->tsdl, "\\f"); + break; + case '\n': + g_string_append(ctx->tsdl, "\\n"); + break; + case '\r': + g_string_append(ctx->tsdl, "\\r"); + break; + case '\t': + g_string_append(ctx->tsdl, "\\t"); + break; + case '\v': + g_string_append(ctx->tsdl, "\\v"); + break; + default: + g_string_append_printf(ctx->tsdl, "\\x%02x", (unsigned int) uch); + break; + } + } else if (*ch == '"' || *ch == '\\') { + g_string_append_c(ctx->tsdl, '\\'); + g_string_append_c(ctx->tsdl, *ch); + } else { + g_string_append_c(ctx->tsdl, *ch); + } + } } -static -void append_quoted_string(struct ctx *ctx, const char *str) +static void append_quoted_string(struct ctx *ctx, const char *str) { - g_string_append_c(ctx->tsdl, '"'); - append_quoted_string_content(ctx, str); - g_string_append_c(ctx->tsdl, '"'); + g_string_append_c(ctx->tsdl, '"'); + append_quoted_string_content(ctx, str); + g_string_append_c(ctx->tsdl, '"'); } -static -void append_integer_field_class_from_props(struct ctx *ctx, unsigned int size, - unsigned int alignment, bool is_signed, - bt_field_class_integer_preferred_display_base disp_base, - const char *mapped_clock_class_name, const char *field_name, - bool end) +static void append_integer_field_class_from_props( + struct ctx *ctx, unsigned int size, unsigned int alignment, bool is_signed, + bt_field_class_integer_preferred_display_base disp_base, const char *mapped_clock_class_name, + const char *field_name, bool end) { - g_string_append_printf(ctx->tsdl, - "integer { size = %u; align = %u;", - size, alignment); - - if (is_signed) { - g_string_append(ctx->tsdl, " signed = true;"); - } - - if (disp_base != BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL) { - g_string_append(ctx->tsdl, " base = "); - - switch (disp_base) { - case BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_BINARY: - g_string_append(ctx->tsdl, "b"); - break; - case BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_OCTAL: - g_string_append(ctx->tsdl, "o"); - break; - case BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL: - g_string_append(ctx->tsdl, "x"); - break; - default: - bt_common_abort(); - } - - g_string_append_c(ctx->tsdl, ';'); - } - - if (mapped_clock_class_name) { - g_string_append_printf(ctx->tsdl, " map = clock.%s.value;", - mapped_clock_class_name); - } - - g_string_append(ctx->tsdl, " }"); - - if (field_name) { - g_string_append_printf(ctx->tsdl, " %s", field_name); - } - - if (end) { - g_string_append(ctx->tsdl, ";\n"); - } + g_string_append_printf(ctx->tsdl, "integer { size = %u; align = %u;", size, alignment); + + if (is_signed) { + g_string_append(ctx->tsdl, " signed = true;"); + } + + if (disp_base != BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL) { + g_string_append(ctx->tsdl, " base = "); + + switch (disp_base) { + case BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_BINARY: + g_string_append(ctx->tsdl, "b"); + break; + case BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_OCTAL: + g_string_append(ctx->tsdl, "o"); + break; + case BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL: + g_string_append(ctx->tsdl, "x"); + break; + default: + bt_common_abort(); + } + + g_string_append_c(ctx->tsdl, ';'); + } + + if (mapped_clock_class_name) { + g_string_append_printf(ctx->tsdl, " map = clock.%s.value;", mapped_clock_class_name); + } + + g_string_append(ctx->tsdl, " }"); + + if (field_name) { + g_string_append_printf(ctx->tsdl, " %s", field_name); + } + + if (end) { + g_string_append(ctx->tsdl, ";\n"); + } } -static -void append_end_block(struct ctx *ctx) +static void append_end_block(struct ctx *ctx) { - ctx->indent_level--; - append_indent(ctx); - g_string_append(ctx->tsdl, "}"); + ctx->indent_level--; + append_indent(ctx); + g_string_append(ctx->tsdl, "}"); } -static -void append_end_block_semi_nl(struct ctx *ctx) +static void append_end_block_semi_nl(struct ctx *ctx) { - ctx->indent_level--; - append_indent(ctx); - g_string_append(ctx->tsdl, "};\n"); + ctx->indent_level--; + append_indent(ctx); + g_string_append(ctx->tsdl, "};\n"); } -static -void append_end_block_semi_nl_nl(struct ctx *ctx) +static void append_end_block_semi_nl_nl(struct ctx *ctx) { - append_end_block_semi_nl(ctx); - g_string_append_c(ctx->tsdl, '\n'); + append_end_block_semi_nl(ctx); + g_string_append_c(ctx->tsdl, '\n'); } -static -void append_bool_field_class(struct ctx *ctx, - __attribute__((unused)) struct fs_sink_ctf_field_class_bool *fc) +static void append_bool_field_class(struct ctx *ctx, + __attribute__((unused)) struct fs_sink_ctf_field_class_bool *fc) { - /* - * CTF 1.8 has no boolean field class type, so this component - * translates it to an 8-bit unsigned integer field class. - */ - append_integer_field_class_from_props(ctx, fc->base.size, - fc->base.base.alignment, false, - BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL, - NULL, NULL, false); + /* + * CTF 1.8 has no boolean field class type, so this component + * translates it to an 8-bit unsigned integer field class. + */ + append_integer_field_class_from_props(ctx, fc->base.size, fc->base.base.alignment, false, + BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL, + NULL, NULL, false); } -static -void append_bit_array_field_class(struct ctx *ctx, - struct fs_sink_ctf_field_class_bit_array *fc) +static void append_bit_array_field_class(struct ctx *ctx, + struct fs_sink_ctf_field_class_bit_array *fc) { - /* - * CTF 1.8 has no bit array field class type, so this component - * translates it to an unsigned integer field class with an - * hexadecimal base. - */ - append_integer_field_class_from_props(ctx, fc->size, - fc->base.alignment, false, - BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL, - NULL, NULL, false); + /* + * CTF 1.8 has no bit array field class type, so this component + * translates it to an unsigned integer field class with an + * hexadecimal base. + */ + append_integer_field_class_from_props(ctx, fc->size, fc->base.alignment, false, + BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL, + NULL, NULL, false); } -static -void append_integer_field_class(struct ctx *ctx, - struct fs_sink_ctf_field_class_int *fc) +static void append_integer_field_class(struct ctx *ctx, struct fs_sink_ctf_field_class_int *fc) { - const bt_field_class *ir_fc = fc->base.base.ir_fc; - bt_field_class_type type = bt_field_class_get_type(ir_fc); - bool is_signed = bt_field_class_type_is(type, - BT_FIELD_CLASS_TYPE_SIGNED_INTEGER); - - if (bt_field_class_type_is(type, BT_FIELD_CLASS_TYPE_ENUMERATION)) { - g_string_append(ctx->tsdl, "enum : "); - } - - append_integer_field_class_from_props(ctx, fc->base.size, - fc->base.base.alignment, is_signed, - bt_field_class_integer_get_preferred_display_base(ir_fc), - NULL, NULL, false); - - if (bt_field_class_type_is(type, BT_FIELD_CLASS_TYPE_ENUMERATION)) { - uint64_t i; - - g_string_append(ctx->tsdl, " {\n"); - ctx->indent_level++; - - for (i = 0; i < bt_field_class_enumeration_get_mapping_count(ir_fc); i++) { - const char *label; - const bt_field_class_enumeration_mapping *mapping; - const bt_field_class_enumeration_unsigned_mapping *u_mapping; - const bt_field_class_enumeration_signed_mapping *s_mapping; - const bt_integer_range_set *ranges; - const bt_integer_range_set_unsigned *u_ranges; - const bt_integer_range_set_signed *s_ranges; - uint64_t range_count; - uint64_t range_i; - - if (is_signed) { - s_mapping = bt_field_class_enumeration_signed_borrow_mapping_by_index_const( - ir_fc, i); - mapping = bt_field_class_enumeration_signed_mapping_as_mapping_const( - s_mapping); - s_ranges = bt_field_class_enumeration_signed_mapping_borrow_ranges_const( - s_mapping); - ranges = bt_integer_range_set_signed_as_range_set_const( - s_ranges); - } else { - u_mapping = bt_field_class_enumeration_unsigned_borrow_mapping_by_index_const( - ir_fc, i); - mapping = bt_field_class_enumeration_unsigned_mapping_as_mapping_const( - u_mapping); - u_ranges = bt_field_class_enumeration_unsigned_mapping_borrow_ranges_const( - u_mapping); - ranges = bt_integer_range_set_unsigned_as_range_set_const( - u_ranges); - } - - label = bt_field_class_enumeration_mapping_get_label( - mapping); - range_count = bt_integer_range_set_get_range_count( - ranges); - - for (range_i = 0; range_i < range_count; range_i++) { - append_indent(ctx); - g_string_append(ctx->tsdl, "\""); - append_quoted_string_content(ctx, label); - g_string_append(ctx->tsdl, "\" = "); - - if (is_signed) { - const bt_integer_range_signed *range; - int64_t lower, upper; - - range = bt_integer_range_set_signed_borrow_range_by_index_const( - s_ranges, range_i); - lower = bt_integer_range_signed_get_lower( - range); - upper = bt_integer_range_signed_get_upper( - range); - - if (lower == upper) { - g_string_append_printf( - ctx->tsdl, "%" PRId64, - lower); - } else { - g_string_append_printf( - ctx->tsdl, "%" PRId64 " ... %" PRId64, - lower, upper); - } - } else { - const bt_integer_range_unsigned *range; - uint64_t lower, upper; - - range = bt_integer_range_set_unsigned_borrow_range_by_index_const( - u_ranges, range_i); - lower = bt_integer_range_unsigned_get_lower( - range); - upper = bt_integer_range_unsigned_get_upper( - range); - - if (lower == upper) { - g_string_append_printf( - ctx->tsdl, "%" PRIu64, - lower); - } else { - g_string_append_printf( - ctx->tsdl, "%" PRIu64 " ... %" PRIu64, - lower, upper); - } - } - - g_string_append(ctx->tsdl, ",\n"); - } - } - - append_end_block(ctx); - } + const bt_field_class *ir_fc = fc->base.base.ir_fc; + bt_field_class_type type = bt_field_class_get_type(ir_fc); + bool is_signed = bt_field_class_type_is(type, BT_FIELD_CLASS_TYPE_SIGNED_INTEGER); + + if (bt_field_class_type_is(type, BT_FIELD_CLASS_TYPE_ENUMERATION)) { + g_string_append(ctx->tsdl, "enum : "); + } + + append_integer_field_class_from_props(ctx, fc->base.size, fc->base.base.alignment, is_signed, + bt_field_class_integer_get_preferred_display_base(ir_fc), + NULL, NULL, false); + + if (bt_field_class_type_is(type, BT_FIELD_CLASS_TYPE_ENUMERATION)) { + uint64_t i; + + g_string_append(ctx->tsdl, " {\n"); + ctx->indent_level++; + + for (i = 0; i < bt_field_class_enumeration_get_mapping_count(ir_fc); i++) { + const char *label; + const bt_field_class_enumeration_mapping *mapping; + const bt_field_class_enumeration_unsigned_mapping *u_mapping; + const bt_field_class_enumeration_signed_mapping *s_mapping; + const bt_integer_range_set *ranges; + const bt_integer_range_set_unsigned *u_ranges; + const bt_integer_range_set_signed *s_ranges; + uint64_t range_count; + uint64_t range_i; + + if (is_signed) { + s_mapping = + bt_field_class_enumeration_signed_borrow_mapping_by_index_const(ir_fc, i); + mapping = bt_field_class_enumeration_signed_mapping_as_mapping_const(s_mapping); + s_ranges = bt_field_class_enumeration_signed_mapping_borrow_ranges_const(s_mapping); + ranges = bt_integer_range_set_signed_as_range_set_const(s_ranges); + } else { + u_mapping = + bt_field_class_enumeration_unsigned_borrow_mapping_by_index_const(ir_fc, i); + mapping = bt_field_class_enumeration_unsigned_mapping_as_mapping_const(u_mapping); + u_ranges = + bt_field_class_enumeration_unsigned_mapping_borrow_ranges_const(u_mapping); + ranges = bt_integer_range_set_unsigned_as_range_set_const(u_ranges); + } + + label = bt_field_class_enumeration_mapping_get_label(mapping); + range_count = bt_integer_range_set_get_range_count(ranges); + + for (range_i = 0; range_i < range_count; range_i++) { + append_indent(ctx); + g_string_append(ctx->tsdl, "\""); + append_quoted_string_content(ctx, label); + g_string_append(ctx->tsdl, "\" = "); + + if (is_signed) { + const bt_integer_range_signed *range; + int64_t lower, upper; + + range = + bt_integer_range_set_signed_borrow_range_by_index_const(s_ranges, range_i); + lower = bt_integer_range_signed_get_lower(range); + upper = bt_integer_range_signed_get_upper(range); + + if (lower == upper) { + g_string_append_printf(ctx->tsdl, "%" PRId64, lower); + } else { + g_string_append_printf(ctx->tsdl, "%" PRId64 " ... %" PRId64, lower, upper); + } + } else { + const bt_integer_range_unsigned *range; + uint64_t lower, upper; + + range = bt_integer_range_set_unsigned_borrow_range_by_index_const(u_ranges, + range_i); + lower = bt_integer_range_unsigned_get_lower(range); + upper = bt_integer_range_unsigned_get_upper(range); + + if (lower == upper) { + g_string_append_printf(ctx->tsdl, "%" PRIu64, lower); + } else { + g_string_append_printf(ctx->tsdl, "%" PRIu64 " ... %" PRIu64, lower, upper); + } + } + + g_string_append(ctx->tsdl, ",\n"); + } + } + + append_end_block(ctx); + } } -static -void append_float_field_class(struct ctx *ctx, - struct fs_sink_ctf_field_class_float *fc) +static void append_float_field_class(struct ctx *ctx, struct fs_sink_ctf_field_class_float *fc) { - unsigned int mant_dig, exp_dig; - - if (bt_field_class_get_type(fc->base.base.ir_fc) == - BT_FIELD_CLASS_TYPE_SINGLE_PRECISION_REAL) { - mant_dig = 24; - exp_dig = 8; - } else { - mant_dig = 53; - exp_dig = 11; - } - - g_string_append_printf(ctx->tsdl, - "floating_point { mant_dig = %u; exp_dig = %u; align = %u; }", - mant_dig, exp_dig, fc->base.base.alignment); + unsigned int mant_dig, exp_dig; + + if (bt_field_class_get_type(fc->base.base.ir_fc) == BT_FIELD_CLASS_TYPE_SINGLE_PRECISION_REAL) { + mant_dig = 24; + exp_dig = 8; + } else { + mant_dig = 53; + exp_dig = 11; + } + + g_string_append_printf(ctx->tsdl, "floating_point { mant_dig = %u; exp_dig = %u; align = %u; }", + mant_dig, exp_dig, fc->base.base.alignment); } -static -void append_string_field_class(struct ctx *ctx, - struct fs_sink_ctf_field_class_string *fc) +static void append_string_field_class(struct ctx *ctx, struct fs_sink_ctf_field_class_string *fc) { - g_string_append(ctx->tsdl, "string { encoding = UTF8; }"); + g_string_append(ctx->tsdl, "string { encoding = UTF8; }"); } -static -void append_field_class(struct ctx *ctx, struct fs_sink_ctf_field_class *fc); +static void append_field_class(struct ctx *ctx, struct fs_sink_ctf_field_class *fc); -static -void append_member(struct ctx *ctx, const char *name, - struct fs_sink_ctf_field_class *fc) +static void append_member(struct ctx *ctx, const char *name, struct fs_sink_ctf_field_class *fc) { - GString *lengths = NULL; - const char *lengths_str = ""; - - BT_ASSERT(fc); - - while (fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_ARRAY || - fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_SEQUENCE) { - if (!lengths) { - lengths = g_string_new(NULL); - BT_ASSERT(lengths); - } - - if (fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_ARRAY) { - struct fs_sink_ctf_field_class_array *array_fc = - fs_sink_ctf_field_class_as_array(fc); - - g_string_append_printf(lengths, "[%" PRIu64 "]", - array_fc->length); - fc = array_fc->base.elem_fc; - } else { - struct fs_sink_ctf_field_class_sequence *seq_fc = - fs_sink_ctf_field_class_as_sequence(fc); - - g_string_append_printf(lengths, "[%s]", - seq_fc->length_ref->str); - fc = seq_fc->base.elem_fc; - } - } - - append_field_class(ctx, fc); - - if (lengths) { - lengths_str = lengths->str; - } - - g_string_append_printf(ctx->tsdl, " %s%s;\n", name, lengths_str); - - if (lengths) { - g_string_free(lengths, TRUE); - } + GString *lengths = NULL; + const char *lengths_str = ""; + + BT_ASSERT(fc); + + while (fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_ARRAY || + fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_SEQUENCE) { + if (!lengths) { + lengths = g_string_new(NULL); + BT_ASSERT(lengths); + } + + if (fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_ARRAY) { + struct fs_sink_ctf_field_class_array *array_fc = fs_sink_ctf_field_class_as_array(fc); + + g_string_append_printf(lengths, "[%" PRIu64 "]", array_fc->length); + fc = array_fc->base.elem_fc; + } else { + struct fs_sink_ctf_field_class_sequence *seq_fc = + fs_sink_ctf_field_class_as_sequence(fc); + + g_string_append_printf(lengths, "[%s]", seq_fc->length_ref->str); + fc = seq_fc->base.elem_fc; + } + } + + append_field_class(ctx, fc); + + if (lengths) { + lengths_str = lengths->str; + } + + g_string_append_printf(ctx->tsdl, " %s%s;\n", name, lengths_str); + + if (lengths) { + g_string_free(lengths, TRUE); + } } -static -void append_struct_field_class_members(struct ctx *ctx, - struct fs_sink_ctf_field_class_struct *struct_fc) +static void append_struct_field_class_members(struct ctx *ctx, + struct fs_sink_ctf_field_class_struct *struct_fc) { - uint64_t i; - - for (i = 0; i < struct_fc->members->len; i++) { - struct fs_sink_ctf_named_field_class *named_fc = - fs_sink_ctf_field_class_struct_borrow_member_by_index( - struct_fc, i); - struct fs_sink_ctf_field_class *fc = named_fc->fc; - - /* - * For sequence, option, and variant field classes, if - * the length/tag field class is generated before, write - * it now before the dependent field class. - */ - if (fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_SEQUENCE) { - struct fs_sink_ctf_field_class_sequence *seq_fc = - fs_sink_ctf_field_class_as_sequence(fc); - - if (seq_fc->length_is_before) { - append_indent(ctx); - append_integer_field_class_from_props(ctx, - 32, 8, false, - BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL, - NULL, seq_fc->length_ref->str, true); - } - } else if (fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_OPTION) { - struct fs_sink_ctf_field_class_option *opt_fc = - fs_sink_ctf_field_class_as_option(fc); - - /* - * CTF 1.8 does not support the option field - * class type. To write something anyway, this - * component translates this type to a variant - * field class where the options are: - * - * * An empty structure field class. - * * The optional field class itself. - * - * The "tag" is always generated/before in that - * case (an 8-bit unsigned enumeration field - * class). - */ - append_indent(ctx); - g_string_append(ctx->tsdl, - "/* The enumeration and variant field classes " - "below were a trace IR option field class. */\n"); - append_indent(ctx); - g_string_append(ctx->tsdl, "enum : "); - append_integer_field_class_from_props(ctx, - 8, 8, false, - BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL, - NULL, NULL, false); - g_string_append(ctx->tsdl, " {\n"); - ctx->indent_level++; - append_indent(ctx); - g_string_append(ctx->tsdl, "none = 0,\n"); - append_indent(ctx); - g_string_append(ctx->tsdl, "content = 1,\n"); - append_end_block(ctx); - g_string_append_printf(ctx->tsdl, " %s;\n", - opt_fc->tag_ref->str); - } else if (fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_VARIANT) { - struct fs_sink_ctf_field_class_variant *var_fc = - fs_sink_ctf_field_class_as_variant(fc); - - if (var_fc->tag_is_before) { - append_indent(ctx); - g_string_append(ctx->tsdl, "enum : "); - append_integer_field_class_from_props(ctx, - 16, 8, false, - BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL, - NULL, NULL, false); - g_string_append(ctx->tsdl, " {\n"); - ctx->indent_level++; - - for (i = 0; i < var_fc->options->len; i++) { - struct fs_sink_ctf_named_field_class *option_named_fc = - fs_sink_ctf_field_class_variant_borrow_option_by_index( - var_fc, i); - - append_indent(ctx); - g_string_append_printf(ctx->tsdl, - "\"%s\" = %" PRIu64 ",\n", - option_named_fc->name->str, i); - } - - append_end_block(ctx); - g_string_append_printf(ctx->tsdl, " %s;\n", - var_fc->tag_ref->str); - } - } else if (fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_BOOL) { - append_indent(ctx); - g_string_append(ctx->tsdl, - "/* The integer field class below was a trace IR boolean field class. */\n"); - } else if (fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_BIT_ARRAY) { - append_indent(ctx); - g_string_append(ctx->tsdl, - "/* The integer field class below was a trace IR bit array field class. */\n"); - } - - append_indent(ctx); - append_member(ctx, named_fc->name->str, fc); - } + uint64_t i; + + for (i = 0; i < struct_fc->members->len; i++) { + struct fs_sink_ctf_named_field_class *named_fc = + fs_sink_ctf_field_class_struct_borrow_member_by_index(struct_fc, i); + struct fs_sink_ctf_field_class *fc = named_fc->fc; + + /* + * For sequence, option, and variant field classes, if + * the length/tag field class is generated before, write + * it now before the dependent field class. + */ + if (fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_SEQUENCE) { + struct fs_sink_ctf_field_class_sequence *seq_fc = + fs_sink_ctf_field_class_as_sequence(fc); + + if (seq_fc->length_is_before) { + append_indent(ctx); + append_integer_field_class_from_props( + ctx, 32, 8, false, BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL, NULL, + seq_fc->length_ref->str, true); + } + } else if (fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_OPTION) { + struct fs_sink_ctf_field_class_option *opt_fc = fs_sink_ctf_field_class_as_option(fc); + + /* + * CTF 1.8 does not support the option field + * class type. To write something anyway, this + * component translates this type to a variant + * field class where the options are: + * + * * An empty structure field class. + * * The optional field class itself. + * + * The "tag" is always generated/before in that + * case (an 8-bit unsigned enumeration field + * class). + */ + append_indent(ctx); + g_string_append(ctx->tsdl, "/* The enumeration and variant field classes " + "below were a trace IR option field class. */\n"); + append_indent(ctx); + g_string_append(ctx->tsdl, "enum : "); + append_integer_field_class_from_props( + ctx, 8, 8, false, BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL, NULL, NULL, + false); + g_string_append(ctx->tsdl, " {\n"); + ctx->indent_level++; + append_indent(ctx); + g_string_append(ctx->tsdl, "none = 0,\n"); + append_indent(ctx); + g_string_append(ctx->tsdl, "content = 1,\n"); + append_end_block(ctx); + g_string_append_printf(ctx->tsdl, " %s;\n", opt_fc->tag_ref->str); + } else if (fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_VARIANT) { + struct fs_sink_ctf_field_class_variant *var_fc = fs_sink_ctf_field_class_as_variant(fc); + + if (var_fc->tag_is_before) { + append_indent(ctx); + g_string_append(ctx->tsdl, "enum : "); + append_integer_field_class_from_props( + ctx, 16, 8, false, BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL, NULL, + NULL, false); + g_string_append(ctx->tsdl, " {\n"); + ctx->indent_level++; + + for (i = 0; i < var_fc->options->len; i++) { + struct fs_sink_ctf_named_field_class *option_named_fc = + fs_sink_ctf_field_class_variant_borrow_option_by_index(var_fc, i); + + append_indent(ctx); + g_string_append_printf(ctx->tsdl, "\"%s\" = %" PRIu64 ",\n", + option_named_fc->name->str, i); + } + + append_end_block(ctx); + g_string_append_printf(ctx->tsdl, " %s;\n", var_fc->tag_ref->str); + } + } else if (fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_BOOL) { + append_indent(ctx); + g_string_append( + ctx->tsdl, + "/* The integer field class below was a trace IR boolean field class. */\n"); + } else if (fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_BIT_ARRAY) { + append_indent(ctx); + g_string_append( + ctx->tsdl, + "/* The integer field class below was a trace IR bit array field class. */\n"); + } + + append_indent(ctx); + append_member(ctx, named_fc->name->str, fc); + } } -static -void append_struct_field_class(struct ctx *ctx, - struct fs_sink_ctf_field_class_struct *fc) +static void append_struct_field_class(struct ctx *ctx, struct fs_sink_ctf_field_class_struct *fc) { - g_string_append(ctx->tsdl, "struct {\n"); - ctx->indent_level++; - append_struct_field_class_members(ctx, fc); - append_end_block(ctx); - g_string_append_printf(ctx->tsdl, " align(%u)", - fc->base.alignment); + g_string_append(ctx->tsdl, "struct {\n"); + ctx->indent_level++; + append_struct_field_class_members(ctx, fc); + append_end_block(ctx); + g_string_append_printf(ctx->tsdl, " align(%u)", fc->base.alignment); } -static -void append_option_field_class(struct ctx *ctx, - struct fs_sink_ctf_field_class_option *opt_fc) +static void append_option_field_class(struct ctx *ctx, + struct fs_sink_ctf_field_class_option *opt_fc) { - g_string_append_printf(ctx->tsdl, "variant <%s> {\n", - opt_fc->tag_ref->str); - ctx->indent_level++; - append_indent(ctx); - g_string_append(ctx->tsdl, "struct { } none;\n"); - append_indent(ctx); - append_member(ctx, "content", opt_fc->content_fc); - append_end_block(ctx); + g_string_append_printf(ctx->tsdl, "variant <%s> {\n", opt_fc->tag_ref->str); + ctx->indent_level++; + append_indent(ctx); + g_string_append(ctx->tsdl, "struct { } none;\n"); + append_indent(ctx); + append_member(ctx, "content", opt_fc->content_fc); + append_end_block(ctx); } -static -void append_variant_field_class(struct ctx *ctx, - struct fs_sink_ctf_field_class_variant *var_fc) +static void append_variant_field_class(struct ctx *ctx, + struct fs_sink_ctf_field_class_variant *var_fc) { - uint64_t i; + uint64_t i; - g_string_append_printf(ctx->tsdl, "variant <%s> {\n", - var_fc->tag_ref->str); - ctx->indent_level++; + g_string_append_printf(ctx->tsdl, "variant <%s> {\n", var_fc->tag_ref->str); + ctx->indent_level++; - for (i = 0; i < var_fc->options->len; i++) { - struct fs_sink_ctf_named_field_class *named_fc = - fs_sink_ctf_field_class_variant_borrow_option_by_index( - var_fc, i); + for (i = 0; i < var_fc->options->len; i++) { + struct fs_sink_ctf_named_field_class *named_fc = + fs_sink_ctf_field_class_variant_borrow_option_by_index(var_fc, i); - append_indent(ctx); - append_member(ctx, named_fc->name->str, named_fc->fc); - } + append_indent(ctx); + append_member(ctx, named_fc->name->str, named_fc->fc); + } - append_end_block(ctx); + append_end_block(ctx); } -static -void append_field_class(struct ctx *ctx, struct fs_sink_ctf_field_class *fc) +static void append_field_class(struct ctx *ctx, struct fs_sink_ctf_field_class *fc) { - switch (fc->type) { - case FS_SINK_CTF_FIELD_CLASS_TYPE_BOOL: - append_bool_field_class(ctx, fs_sink_ctf_field_class_as_bool(fc)); - break; - case FS_SINK_CTF_FIELD_CLASS_TYPE_BIT_ARRAY: - append_bit_array_field_class(ctx, fs_sink_ctf_field_class_as_bit_array(fc)); - break; - case FS_SINK_CTF_FIELD_CLASS_TYPE_INT: - append_integer_field_class(ctx, fs_sink_ctf_field_class_as_int(fc)); - break; - case FS_SINK_CTF_FIELD_CLASS_TYPE_FLOAT: - append_float_field_class(ctx, fs_sink_ctf_field_class_as_float(fc)); - break; - case FS_SINK_CTF_FIELD_CLASS_TYPE_STRING: - append_string_field_class(ctx, fs_sink_ctf_field_class_as_string(fc)); - break; - case FS_SINK_CTF_FIELD_CLASS_TYPE_STRUCT: - append_struct_field_class(ctx, fs_sink_ctf_field_class_as_struct(fc)); - break; - case FS_SINK_CTF_FIELD_CLASS_TYPE_OPTION: - append_option_field_class(ctx, fs_sink_ctf_field_class_as_option(fc)); - break; - case FS_SINK_CTF_FIELD_CLASS_TYPE_VARIANT: - append_variant_field_class(ctx, fs_sink_ctf_field_class_as_variant(fc)); - break; - default: - bt_common_abort(); - } + switch (fc->type) { + case FS_SINK_CTF_FIELD_CLASS_TYPE_BOOL: + append_bool_field_class(ctx, fs_sink_ctf_field_class_as_bool(fc)); + break; + case FS_SINK_CTF_FIELD_CLASS_TYPE_BIT_ARRAY: + append_bit_array_field_class(ctx, fs_sink_ctf_field_class_as_bit_array(fc)); + break; + case FS_SINK_CTF_FIELD_CLASS_TYPE_INT: + append_integer_field_class(ctx, fs_sink_ctf_field_class_as_int(fc)); + break; + case FS_SINK_CTF_FIELD_CLASS_TYPE_FLOAT: + append_float_field_class(ctx, fs_sink_ctf_field_class_as_float(fc)); + break; + case FS_SINK_CTF_FIELD_CLASS_TYPE_STRING: + append_string_field_class(ctx, fs_sink_ctf_field_class_as_string(fc)); + break; + case FS_SINK_CTF_FIELD_CLASS_TYPE_STRUCT: + append_struct_field_class(ctx, fs_sink_ctf_field_class_as_struct(fc)); + break; + case FS_SINK_CTF_FIELD_CLASS_TYPE_OPTION: + append_option_field_class(ctx, fs_sink_ctf_field_class_as_option(fc)); + break; + case FS_SINK_CTF_FIELD_CLASS_TYPE_VARIANT: + append_variant_field_class(ctx, fs_sink_ctf_field_class_as_variant(fc)); + break; + default: + bt_common_abort(); + } } -static -void append_event_class(struct ctx *ctx, struct fs_sink_ctf_event_class *ec) +static void append_event_class(struct ctx *ctx, struct fs_sink_ctf_event_class *ec) { - const char *str; - bt_event_class_log_level log_level; - - /* Event class */ - append_indent(ctx); - g_string_append(ctx->tsdl, "event {\n"); - ctx->indent_level++; - - /* Event class properties */ - append_indent(ctx); - g_string_append(ctx->tsdl, "name = "); - str = bt_event_class_get_name(ec->ir_ec); - if (!str) { - str = "unknown"; - } - - append_quoted_string(ctx, str); - g_string_append(ctx->tsdl, ";\n"); - append_indent(ctx); - g_string_append_printf(ctx->tsdl, "stream_id = %" PRIu64 ";\n", - bt_stream_class_get_id(ec->sc->ir_sc)); - append_indent(ctx); - g_string_append_printf(ctx->tsdl, "id = %" PRIu64 ";\n", - bt_event_class_get_id(ec->ir_ec)); - - str = bt_event_class_get_emf_uri(ec->ir_ec); - if (str) { - append_indent(ctx); - g_string_append(ctx->tsdl, "model.emf.uri = "); - append_quoted_string(ctx, str); - g_string_append(ctx->tsdl, ";\n"); - } - - if (bt_event_class_get_log_level(ec->ir_ec, &log_level) == - BT_PROPERTY_AVAILABILITY_AVAILABLE) { - unsigned int level; - - append_indent(ctx); - g_string_append(ctx->tsdl, "loglevel = "); - - switch (log_level) { - case BT_EVENT_CLASS_LOG_LEVEL_EMERGENCY: - level = 0; - break; - case BT_EVENT_CLASS_LOG_LEVEL_ALERT: - level = 1; - break; - case BT_EVENT_CLASS_LOG_LEVEL_CRITICAL: - level = 2; - break; - case BT_EVENT_CLASS_LOG_LEVEL_ERROR: - level = 3; - break; - case BT_EVENT_CLASS_LOG_LEVEL_WARNING: - level = 4; - break; - case BT_EVENT_CLASS_LOG_LEVEL_NOTICE: - level = 5; - break; - case BT_EVENT_CLASS_LOG_LEVEL_INFO: - level = 6; - break; - case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_SYSTEM: - level = 7; - break; - case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROGRAM: - level = 8; - break; - case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROCESS: - level = 9; - break; - case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_MODULE: - level = 10; - break; - case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_UNIT: - level = 11; - break; - case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_FUNCTION: - level = 12; - break; - case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_LINE: - level = 13; - break; - case BT_EVENT_CLASS_LOG_LEVEL_DEBUG: - level = 14; - break; - default: - bt_common_abort(); - } - - g_string_append_printf(ctx->tsdl, "%u;\n", level); - } - - /* Event specific context field class */ - if (ec->spec_context_fc) { - append_indent(ctx); - g_string_append(ctx->tsdl, "context := "); - append_field_class(ctx, ec->spec_context_fc); - g_string_append(ctx->tsdl, ";\n"); - } - - /* Event payload field class */ - if (ec->payload_fc) { - append_indent(ctx); - g_string_append(ctx->tsdl, "fields := "); - append_field_class(ctx, ec->payload_fc); - g_string_append(ctx->tsdl, ";\n"); - } - - append_end_block_semi_nl_nl(ctx); + const char *str; + bt_event_class_log_level log_level; + + /* Event class */ + append_indent(ctx); + g_string_append(ctx->tsdl, "event {\n"); + ctx->indent_level++; + + /* Event class properties */ + append_indent(ctx); + g_string_append(ctx->tsdl, "name = "); + str = bt_event_class_get_name(ec->ir_ec); + if (!str) { + str = "unknown"; + } + + append_quoted_string(ctx, str); + g_string_append(ctx->tsdl, ";\n"); + append_indent(ctx); + g_string_append_printf(ctx->tsdl, "stream_id = %" PRIu64 ";\n", + bt_stream_class_get_id(ec->sc->ir_sc)); + append_indent(ctx); + g_string_append_printf(ctx->tsdl, "id = %" PRIu64 ";\n", bt_event_class_get_id(ec->ir_ec)); + + str = bt_event_class_get_emf_uri(ec->ir_ec); + if (str) { + append_indent(ctx); + g_string_append(ctx->tsdl, "model.emf.uri = "); + append_quoted_string(ctx, str); + g_string_append(ctx->tsdl, ";\n"); + } + + if (bt_event_class_get_log_level(ec->ir_ec, &log_level) == BT_PROPERTY_AVAILABILITY_AVAILABLE) { + unsigned int level; + + append_indent(ctx); + g_string_append(ctx->tsdl, "loglevel = "); + + switch (log_level) { + case BT_EVENT_CLASS_LOG_LEVEL_EMERGENCY: + level = 0; + break; + case BT_EVENT_CLASS_LOG_LEVEL_ALERT: + level = 1; + break; + case BT_EVENT_CLASS_LOG_LEVEL_CRITICAL: + level = 2; + break; + case BT_EVENT_CLASS_LOG_LEVEL_ERROR: + level = 3; + break; + case BT_EVENT_CLASS_LOG_LEVEL_WARNING: + level = 4; + break; + case BT_EVENT_CLASS_LOG_LEVEL_NOTICE: + level = 5; + break; + case BT_EVENT_CLASS_LOG_LEVEL_INFO: + level = 6; + break; + case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_SYSTEM: + level = 7; + break; + case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROGRAM: + level = 8; + break; + case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROCESS: + level = 9; + break; + case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_MODULE: + level = 10; + break; + case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_UNIT: + level = 11; + break; + case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_FUNCTION: + level = 12; + break; + case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_LINE: + level = 13; + break; + case BT_EVENT_CLASS_LOG_LEVEL_DEBUG: + level = 14; + break; + default: + bt_common_abort(); + } + + g_string_append_printf(ctx->tsdl, "%u;\n", level); + } + + /* Event specific context field class */ + if (ec->spec_context_fc) { + append_indent(ctx); + g_string_append(ctx->tsdl, "context := "); + append_field_class(ctx, ec->spec_context_fc); + g_string_append(ctx->tsdl, ";\n"); + } + + /* Event payload field class */ + if (ec->payload_fc) { + append_indent(ctx); + g_string_append(ctx->tsdl, "fields := "); + append_field_class(ctx, ec->payload_fc); + g_string_append(ctx->tsdl, ";\n"); + } + + append_end_block_semi_nl_nl(ctx); } -static -void append_stream_class(struct ctx *ctx, - struct fs_sink_ctf_stream_class *sc) +static void append_stream_class(struct ctx *ctx, struct fs_sink_ctf_stream_class *sc) { - uint64_t i; - - /* Default clock class */ - if (sc->default_clock_class) { - const char *descr; - int64_t offset_seconds; - uint64_t offset_cycles; - bt_uuid uuid; - - append_indent(ctx); - g_string_append(ctx->tsdl, "clock {\n"); - ctx->indent_level++; - BT_ASSERT(sc->default_clock_class_name->len > 0); - append_indent(ctx); - g_string_append_printf(ctx->tsdl, "name = %s;\n", - sc->default_clock_class_name->str); - descr = bt_clock_class_get_description(sc->default_clock_class); - if (descr) { - append_indent(ctx); - g_string_append(ctx->tsdl, "description = "); - append_quoted_string(ctx, descr); - g_string_append(ctx->tsdl, ";\n"); - } - - append_indent(ctx); - g_string_append_printf(ctx->tsdl, "freq = %" PRIu64 ";\n", - bt_clock_class_get_frequency(sc->default_clock_class)); - append_indent(ctx); - g_string_append_printf(ctx->tsdl, "precision = %" PRIu64 ";\n", - bt_clock_class_get_precision(sc->default_clock_class)); - bt_clock_class_get_offset(sc->default_clock_class, - &offset_seconds, &offset_cycles); - append_indent(ctx); - g_string_append_printf(ctx->tsdl, "offset_s = %" PRId64 ";\n", - offset_seconds); - append_indent(ctx); - g_string_append_printf(ctx->tsdl, "offset = %" PRIu64 ";\n", - offset_cycles); - append_indent(ctx); - g_string_append(ctx->tsdl, "absolute = "); - - if (bt_clock_class_origin_is_unix_epoch( - sc->default_clock_class)) { - g_string_append(ctx->tsdl, "true"); - } else { - g_string_append(ctx->tsdl, "false"); - } - - g_string_append(ctx->tsdl, ";\n"); - uuid = bt_clock_class_get_uuid(sc->default_clock_class); - if (uuid) { - append_indent(ctx); - g_string_append(ctx->tsdl, "uuid = "); - append_uuid(ctx, uuid); - g_string_append(ctx->tsdl, ";\n"); - } - - /* End clock class */ - append_end_block_semi_nl_nl(ctx); - } - - /* Stream class */ - append_indent(ctx); - g_string_append(ctx->tsdl, "stream {\n"); - ctx->indent_level++; - - /* Stream class properties */ - append_indent(ctx); - g_string_append_printf(ctx->tsdl, "id = %" PRIu64 ";\n", - bt_stream_class_get_id(sc->ir_sc)); - - /* Packet context field class */ - append_indent(ctx); - g_string_append(ctx->tsdl, "packet.context := struct {\n"); - ctx->indent_level++; - append_indent(ctx); - append_integer_field_class_from_props(ctx, 64, 8, false, - BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL, - NULL, "packet_size", true); - append_indent(ctx); - append_integer_field_class_from_props(ctx, 64, 8, false, - BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL, - NULL, "content_size", true); - - if (sc->packets_have_ts_begin) { - append_indent(ctx); - append_integer_field_class_from_props(ctx, 64, 8, false, - BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL, - sc->default_clock_class_name->str, - "timestamp_begin", true); - } - - if (sc->packets_have_ts_end) { - append_indent(ctx); - append_integer_field_class_from_props(ctx, 64, 8, false, - BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL, - sc->default_clock_class_name->str, - "timestamp_end", true); - } - - if (sc->has_discarded_events) { - append_indent(ctx); - append_integer_field_class_from_props(ctx, 64, 8, false, - BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL, - NULL, "events_discarded", true); - } - - /* - * Unconditionnally write the packet sequence number as, even if - * there's no possible discarded packets message, it's still - * useful information to have. - */ - append_indent(ctx); - append_integer_field_class_from_props(ctx, 64, 8, false, - BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL, - NULL, "packet_seq_num", true); - - if (sc->packet_context_fc) { - append_struct_field_class_members(ctx, - fs_sink_ctf_field_class_as_struct(sc->packet_context_fc)); - fs_sink_ctf_field_class_struct_align_at_least( - fs_sink_ctf_field_class_as_struct(sc->packet_context_fc), 8); - } - - /* End packet context field class */ - append_end_block(ctx); - g_string_append_printf(ctx->tsdl, " align(%u);\n\n", - sc->packet_context_fc ? sc->packet_context_fc->alignment : 8); - - /* Event header field class */ - append_indent(ctx); - g_string_append(ctx->tsdl, "event.header := struct {\n"); - ctx->indent_level++; - append_indent(ctx); - append_integer_field_class_from_props(ctx, 64, 8, false, - BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL, - NULL, "id", true); - - if (sc->default_clock_class) { - append_indent(ctx); - append_integer_field_class_from_props(ctx, 64, 8, false, - BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL, - sc->default_clock_class_name->str, - "timestamp", true); - } - - /* End event header field class */ - append_end_block(ctx); - g_string_append(ctx->tsdl, " align(8);\n"); - - /* Event common context field class */ - if (sc->event_common_context_fc) { - append_indent(ctx); - g_string_append(ctx->tsdl, "event.context := "); - append_field_class(ctx, sc->event_common_context_fc); - g_string_append(ctx->tsdl, ";\n"); - } - - /* End stream class */ - append_end_block_semi_nl_nl(ctx); - - /* Event classes */ - for (i = 0; i < sc->event_classes->len; i++) { - append_event_class(ctx, - (fs_sink_ctf_event_class *) sc->event_classes->pdata[i]); - } + uint64_t i; + + /* Default clock class */ + if (sc->default_clock_class) { + const char *descr; + int64_t offset_seconds; + uint64_t offset_cycles; + bt_uuid uuid; + + append_indent(ctx); + g_string_append(ctx->tsdl, "clock {\n"); + ctx->indent_level++; + BT_ASSERT(sc->default_clock_class_name->len > 0); + append_indent(ctx); + g_string_append_printf(ctx->tsdl, "name = %s;\n", sc->default_clock_class_name->str); + descr = bt_clock_class_get_description(sc->default_clock_class); + if (descr) { + append_indent(ctx); + g_string_append(ctx->tsdl, "description = "); + append_quoted_string(ctx, descr); + g_string_append(ctx->tsdl, ";\n"); + } + + append_indent(ctx); + g_string_append_printf(ctx->tsdl, "freq = %" PRIu64 ";\n", + bt_clock_class_get_frequency(sc->default_clock_class)); + append_indent(ctx); + g_string_append_printf(ctx->tsdl, "precision = %" PRIu64 ";\n", + bt_clock_class_get_precision(sc->default_clock_class)); + bt_clock_class_get_offset(sc->default_clock_class, &offset_seconds, &offset_cycles); + append_indent(ctx); + g_string_append_printf(ctx->tsdl, "offset_s = %" PRId64 ";\n", offset_seconds); + append_indent(ctx); + g_string_append_printf(ctx->tsdl, "offset = %" PRIu64 ";\n", offset_cycles); + append_indent(ctx); + g_string_append(ctx->tsdl, "absolute = "); + + if (bt_clock_class_origin_is_unix_epoch(sc->default_clock_class)) { + g_string_append(ctx->tsdl, "true"); + } else { + g_string_append(ctx->tsdl, "false"); + } + + g_string_append(ctx->tsdl, ";\n"); + uuid = bt_clock_class_get_uuid(sc->default_clock_class); + if (uuid) { + append_indent(ctx); + g_string_append(ctx->tsdl, "uuid = "); + append_uuid(ctx, uuid); + g_string_append(ctx->tsdl, ";\n"); + } + + /* End clock class */ + append_end_block_semi_nl_nl(ctx); + } + + /* Stream class */ + append_indent(ctx); + g_string_append(ctx->tsdl, "stream {\n"); + ctx->indent_level++; + + /* Stream class properties */ + append_indent(ctx); + g_string_append_printf(ctx->tsdl, "id = %" PRIu64 ";\n", bt_stream_class_get_id(sc->ir_sc)); + + /* Packet context field class */ + append_indent(ctx); + g_string_append(ctx->tsdl, "packet.context := struct {\n"); + ctx->indent_level++; + append_indent(ctx); + append_integer_field_class_from_props(ctx, 64, 8, false, + BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL, + NULL, "packet_size", true); + append_indent(ctx); + append_integer_field_class_from_props(ctx, 64, 8, false, + BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL, + NULL, "content_size", true); + + if (sc->packets_have_ts_begin) { + append_indent(ctx); + append_integer_field_class_from_props( + ctx, 64, 8, false, BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL, + sc->default_clock_class_name->str, "timestamp_begin", true); + } + + if (sc->packets_have_ts_end) { + append_indent(ctx); + append_integer_field_class_from_props( + ctx, 64, 8, false, BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL, + sc->default_clock_class_name->str, "timestamp_end", true); + } + + if (sc->has_discarded_events) { + append_indent(ctx); + append_integer_field_class_from_props(ctx, 64, 8, false, + BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL, + NULL, "events_discarded", true); + } + + /* + * Unconditionnally write the packet sequence number as, even if + * there's no possible discarded packets message, it's still + * useful information to have. + */ + append_indent(ctx); + append_integer_field_class_from_props(ctx, 64, 8, false, + BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL, + NULL, "packet_seq_num", true); + + if (sc->packet_context_fc) { + append_struct_field_class_members(ctx, + fs_sink_ctf_field_class_as_struct(sc->packet_context_fc)); + fs_sink_ctf_field_class_struct_align_at_least( + fs_sink_ctf_field_class_as_struct(sc->packet_context_fc), 8); + } + + /* End packet context field class */ + append_end_block(ctx); + g_string_append_printf(ctx->tsdl, " align(%u);\n\n", + sc->packet_context_fc ? sc->packet_context_fc->alignment : 8); + + /* Event header field class */ + append_indent(ctx); + g_string_append(ctx->tsdl, "event.header := struct {\n"); + ctx->indent_level++; + append_indent(ctx); + append_integer_field_class_from_props( + ctx, 64, 8, false, BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL, NULL, "id", true); + + if (sc->default_clock_class) { + append_indent(ctx); + append_integer_field_class_from_props(ctx, 64, 8, false, + BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL, + sc->default_clock_class_name->str, "timestamp", true); + } + + /* End event header field class */ + append_end_block(ctx); + g_string_append(ctx->tsdl, " align(8);\n"); + + /* Event common context field class */ + if (sc->event_common_context_fc) { + append_indent(ctx); + g_string_append(ctx->tsdl, "event.context := "); + append_field_class(ctx, sc->event_common_context_fc); + g_string_append(ctx->tsdl, ";\n"); + } + + /* End stream class */ + append_end_block_semi_nl_nl(ctx); + + /* Event classes */ + for (i = 0; i < sc->event_classes->len; i++) { + append_event_class(ctx, (fs_sink_ctf_event_class *) sc->event_classes->pdata[i]); + } } BT_HIDDEN -void translate_trace_ctf_ir_to_tsdl(struct fs_sink_ctf_trace *trace, - GString *tsdl) +void translate_trace_ctf_ir_to_tsdl(struct fs_sink_ctf_trace *trace, GString *tsdl) { - struct ctx ctx = { - .indent_level = 0, - .tsdl = tsdl, - }; - uint64_t i; - uint64_t count; - - g_string_assign(tsdl, "/* CTF 1.8 */\n\n"); - g_string_append(tsdl, "/* This was generated by a Babeltrace `sink.ctf.fs` component. */\n\n"); - - /* Trace class */ - append_indent(&ctx); - g_string_append(tsdl, "trace {\n"); - ctx.indent_level++; - - /* Trace class properties */ - append_indent(&ctx); - g_string_append(tsdl, "major = 1;\n"); - append_indent(&ctx); - g_string_append(tsdl, "minor = 8;\n"); - append_indent(&ctx); - g_string_append(tsdl, "uuid = "); - append_uuid(&ctx, trace->uuid); - g_string_append(tsdl, ";\n"); - append_indent(&ctx); - g_string_append(tsdl, "byte_order = "); - - if (BYTE_ORDER == LITTLE_ENDIAN) { - g_string_append(tsdl, "le"); - } else { - g_string_append(tsdl, "be"); - } - - g_string_append(tsdl, ";\n"); - - /* Packet header field class */ - append_indent(&ctx); - g_string_append(tsdl, "packet.header := struct {\n"); - ctx.indent_level++; - append_indent(&ctx); - append_integer_field_class_from_props(&ctx, 32, 8, false, - BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL, - NULL, "magic", true); - append_indent(&ctx); - append_integer_field_class_from_props(&ctx, 8, 8, false, - BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL, - NULL, "uuid[16]", true); - append_indent(&ctx); - append_integer_field_class_from_props(&ctx, 64, 8, false, - BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL, - NULL, "stream_id", true); - append_indent(&ctx); - append_integer_field_class_from_props(&ctx, 64, 8, false, - BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL, - NULL, "stream_instance_id", true); - - /* End packet header field class */ - append_end_block(&ctx); - g_string_append(ctx.tsdl, " align(8);\n"); - - /* End trace class */ - append_end_block_semi_nl_nl(&ctx); - - /* Trace environment */ - count = bt_trace_get_environment_entry_count(trace->ir_trace); - if (count > 0) { - append_indent(&ctx); - g_string_append(tsdl, "env {\n"); - ctx.indent_level++; - - for (i = 0; i < count; i++) { - const char *name; - const bt_value *val; - - bt_trace_borrow_environment_entry_by_index_const( - trace->ir_trace, i, &name, &val); - append_indent(&ctx); - g_string_append_printf(tsdl, "%s = ", name); - - switch (bt_value_get_type(val)) { - case BT_VALUE_TYPE_SIGNED_INTEGER: - g_string_append_printf(tsdl, "%" PRId64, - bt_value_integer_signed_get(val)); - break; - case BT_VALUE_TYPE_STRING: - append_quoted_string(&ctx, bt_value_string_get(val)); - break; - default: - /* - * This is checked in - * translate_trace_trace_ir_to_ctf_ir(). - */ - bt_common_abort(); - } - - g_string_append(tsdl, ";\n"); - } - - /* End trace class environment */ - append_end_block_semi_nl_nl(&ctx); - } - - /* Stream classes and their event classes */ - for (i = 0; i < trace->stream_classes->len; i++) { - append_stream_class(&ctx, - (fs_sink_ctf_stream_class *) trace->stream_classes->pdata[i]); - } + struct ctx ctx = { + .indent_level = 0, + .tsdl = tsdl, + }; + uint64_t i; + uint64_t count; + + g_string_assign(tsdl, "/* CTF 1.8 */\n\n"); + g_string_append(tsdl, "/* This was generated by a Babeltrace `sink.ctf.fs` component. */\n\n"); + + /* Trace class */ + append_indent(&ctx); + g_string_append(tsdl, "trace {\n"); + ctx.indent_level++; + + /* Trace class properties */ + append_indent(&ctx); + g_string_append(tsdl, "major = 1;\n"); + append_indent(&ctx); + g_string_append(tsdl, "minor = 8;\n"); + append_indent(&ctx); + g_string_append(tsdl, "uuid = "); + append_uuid(&ctx, trace->uuid); + g_string_append(tsdl, ";\n"); + append_indent(&ctx); + g_string_append(tsdl, "byte_order = "); + + if (BYTE_ORDER == LITTLE_ENDIAN) { + g_string_append(tsdl, "le"); + } else { + g_string_append(tsdl, "be"); + } + + g_string_append(tsdl, ";\n"); + + /* Packet header field class */ + append_indent(&ctx); + g_string_append(tsdl, "packet.header := struct {\n"); + ctx.indent_level++; + append_indent(&ctx); + append_integer_field_class_from_props(&ctx, 32, 8, false, + BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL, + NULL, "magic", true); + append_indent(&ctx); + append_integer_field_class_from_props(&ctx, 8, 8, false, + BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL, + NULL, "uuid[16]", true); + append_indent(&ctx); + append_integer_field_class_from_props(&ctx, 64, 8, false, + BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL, + NULL, "stream_id", true); + append_indent(&ctx); + append_integer_field_class_from_props(&ctx, 64, 8, false, + BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL, + NULL, "stream_instance_id", true); + + /* End packet header field class */ + append_end_block(&ctx); + g_string_append(ctx.tsdl, " align(8);\n"); + + /* End trace class */ + append_end_block_semi_nl_nl(&ctx); + + /* Trace environment */ + count = bt_trace_get_environment_entry_count(trace->ir_trace); + if (count > 0) { + append_indent(&ctx); + g_string_append(tsdl, "env {\n"); + ctx.indent_level++; + + for (i = 0; i < count; i++) { + const char *name; + const bt_value *val; + + bt_trace_borrow_environment_entry_by_index_const(trace->ir_trace, i, &name, &val); + append_indent(&ctx); + g_string_append_printf(tsdl, "%s = ", name); + + switch (bt_value_get_type(val)) { + case BT_VALUE_TYPE_SIGNED_INTEGER: + g_string_append_printf(tsdl, "%" PRId64, bt_value_integer_signed_get(val)); + break; + case BT_VALUE_TYPE_STRING: + append_quoted_string(&ctx, bt_value_string_get(val)); + break; + default: + /* + * This is checked in + * translate_trace_trace_ir_to_ctf_ir(). + */ + bt_common_abort(); + } + + g_string_append(tsdl, ";\n"); + } + + /* End trace class environment */ + append_end_block_semi_nl_nl(&ctx); + } + + /* Stream classes and their event classes */ + for (i = 0; i < trace->stream_classes->len; i++) { + append_stream_class(&ctx, (fs_sink_ctf_stream_class *) trace->stream_classes->pdata[i]); + } } diff --git a/src/plugins/ctf/fs-sink/translate-ctf-ir-to-tsdl.hpp b/src/plugins/ctf/fs-sink/translate-ctf-ir-to-tsdl.hpp index b8a73e74..c980e9f9 100644 --- a/src/plugins/ctf/fs-sink/translate-ctf-ir-to-tsdl.hpp +++ b/src/plugins/ctf/fs-sink/translate-ctf-ir-to-tsdl.hpp @@ -13,7 +13,6 @@ #include "fs-sink-ctf-meta.hpp" BT_HIDDEN -void translate_trace_ctf_ir_to_tsdl(struct fs_sink_ctf_trace *trace, - GString *tsdl); +void translate_trace_ctf_ir_to_tsdl(struct fs_sink_ctf_trace *trace, GString *tsdl); #endif /* BABELTRACE_PLUGIN_CTF_FS_SINK_TRANSLATE_CTF_IR_TO_TSDL_H */ diff --git a/src/plugins/ctf/fs-sink/translate-trace-ir-to-ctf-ir.cpp b/src/plugins/ctf/fs-sink/translate-trace-ir-to-ctf-ir.cpp index a2009949..d7ff260f 100644 --- a/src/plugins/ctf/fs-sink/translate-trace-ir-to-ctf-ir.cpp +++ b/src/plugins/ctf/fs-sink/translate-trace-ir-to-ctf-ir.cpp @@ -5,8 +5,8 @@ */ #define BT_COMP_LOG_SELF_COMP (ctx->self_comp) -#define BT_LOG_OUTPUT_LEVEL (ctx->log_level) -#define BT_LOG_TAG "PLUGIN/SINK.CTF.FS/TRANSLATE-TRACE-IR-TO-CTF-IR" +#define BT_LOG_OUTPUT_LEVEL (ctx->log_level) +#define BT_LOG_TAG "PLUGIN/SINK.CTF.FS/TRANSLATE-TRACE-IR-TO-CTF-IR" #include "logging/comp-logging.h" #include "translate-trace-ir-to-ctf-ir.hpp" @@ -23,229 +23,197 @@ #include "fs-sink.hpp" #include "fs-sink-ctf-meta.hpp" -struct field_path_elem { - uint64_t index_in_parent; - GString *name; +struct field_path_elem +{ + uint64_t index_in_parent; + GString *name; - /* Weak */ - const bt_field_class *ir_fc; + /* Weak */ + const bt_field_class *ir_fc; - /* Weak */ - struct fs_sink_ctf_field_class *parent_fc; + /* Weak */ + struct fs_sink_ctf_field_class *parent_fc; }; -struct ctx { - bt_logging_level log_level; - bt_self_component *self_comp; +struct ctx +{ + bt_logging_level log_level; + bt_self_component *self_comp; - /* Weak */ - struct fs_sink_ctf_stream_class *cur_sc; + /* Weak */ + struct fs_sink_ctf_stream_class *cur_sc; - /* Weak */ - struct fs_sink_ctf_event_class *cur_ec; + /* Weak */ + struct fs_sink_ctf_event_class *cur_ec; - bt_field_path_scope cur_scope; + bt_field_path_scope cur_scope; - /* - * Array of `struct field_path_elem` */ - GArray *cur_path; + /* + * Array of `struct field_path_elem` */ + GArray *cur_path; }; -static inline -struct field_path_elem *cur_path_stack_at(struct ctx *ctx, uint64_t i) +static inline struct field_path_elem *cur_path_stack_at(struct ctx *ctx, uint64_t i) { - BT_ASSERT(i < ctx->cur_path->len); - return &g_array_index(ctx->cur_path, struct field_path_elem, i); + BT_ASSERT(i < ctx->cur_path->len); + return &g_array_index(ctx->cur_path, struct field_path_elem, i); } -static inline -struct field_path_elem *cur_path_stack_top(struct ctx *ctx) +static inline struct field_path_elem *cur_path_stack_top(struct ctx *ctx) { - BT_ASSERT(ctx->cur_path->len > 0); - return cur_path_stack_at(ctx, ctx->cur_path->len - 1); + BT_ASSERT(ctx->cur_path->len > 0); + return cur_path_stack_at(ctx, ctx->cur_path->len - 1); } -static inline -bool is_reserved_member_name(const char *name, const char *reserved_name) +static inline bool is_reserved_member_name(const char *name, const char *reserved_name) { - bool is_reserved = false; + bool is_reserved = false; - if (strcmp(name, reserved_name) == 0) { - is_reserved = true; - goto end; - } + if (strcmp(name, reserved_name) == 0) { + is_reserved = true; + goto end; + } - if (name[0] == '_' && strcmp(&name[1], reserved_name) == 0) { - is_reserved = true; - goto end; - } + if (name[0] == '_' && strcmp(&name[1], reserved_name) == 0) { + is_reserved = true; + goto end; + } end: - return is_reserved; + return is_reserved; } static const char *reserved_tsdl_keywords[] = { - "align", - "callsite", - "const", - "char", - "clock", - "double", - "enum", - "env", - "event", - "floating_point", - "float", - "integer", - "int", - "long", - "short", - "signed", - "stream", - "string", - "struct", - "trace", - "typealias", - "typedef", - "unsigned", - "variant", - "void", - "_Bool", - "_Complex", - "_Imaginary", + "align", "callsite", "const", "char", "clock", "double", "enum", + "env", "event", "floating_point", "float", "integer", "int", "long", + "short", "signed", "stream", "string", "struct", "trace", "typealias", + "typedef", "unsigned", "variant", "void", "_Bool", "_Complex", "_Imaginary", }; -static inline -bool ist_valid_identifier(const char *name) +static inline bool ist_valid_identifier(const char *name) { - const char *at; - uint64_t i; - bool ist_valid = true; - - /* Make sure the name is not a reserved keyword */ - for (i = 0; i < sizeof(reserved_tsdl_keywords) / sizeof(*reserved_tsdl_keywords); - i++) { - if (strcmp(name, reserved_tsdl_keywords[i]) == 0) { - ist_valid = false; - goto end; - } - } - - /* Make sure the name is not an empty string */ - if (strlen(name) == 0) { - ist_valid = false; - goto end; - } - - /* Make sure the name starts with a letter or `_` */ - if (!isalpha((unsigned char) name[0]) && name[0] != '_') { - ist_valid = false; - goto end; - } - - /* Make sure the name only contains letters, digits, and `_` */ - for (at = name; *at != '\0'; at++) { - if (!isalnum((unsigned char) *at) && *at != '_') { - ist_valid = false; - goto end; - } - } + const char *at; + uint64_t i; + bool ist_valid = true; + + /* Make sure the name is not a reserved keyword */ + for (i = 0; i < sizeof(reserved_tsdl_keywords) / sizeof(*reserved_tsdl_keywords); i++) { + if (strcmp(name, reserved_tsdl_keywords[i]) == 0) { + ist_valid = false; + goto end; + } + } + + /* Make sure the name is not an empty string */ + if (strlen(name) == 0) { + ist_valid = false; + goto end; + } + + /* Make sure the name starts with a letter or `_` */ + if (!isalpha((unsigned char) name[0]) && name[0] != '_') { + ist_valid = false; + goto end; + } + + /* Make sure the name only contains letters, digits, and `_` */ + for (at = name; *at != '\0'; at++) { + if (!isalnum((unsigned char) *at) && *at != '_') { + ist_valid = false; + goto end; + } + } end: - return ist_valid; + return ist_valid; } -static inline -bool must_protect_identifier(const char *name) +static inline bool must_protect_identifier(const char *name) { - uint64_t i; - bool must_protect = false; - - /* Protect a reserved keyword */ - for (i = 0; i < sizeof(reserved_tsdl_keywords) / sizeof(*reserved_tsdl_keywords); - i++) { - if (strcmp(name, reserved_tsdl_keywords[i]) == 0) { - must_protect = true; - goto end; - } - } - - /* Protect an identifier which already starts with `_` */ - if (name[0] == '_') { - must_protect = true; - goto end; - } + uint64_t i; + bool must_protect = false; + + /* Protect a reserved keyword */ + for (i = 0; i < sizeof(reserved_tsdl_keywords) / sizeof(*reserved_tsdl_keywords); i++) { + if (strcmp(name, reserved_tsdl_keywords[i]) == 0) { + must_protect = true; + goto end; + } + } + + /* Protect an identifier which already starts with `_` */ + if (name[0] == '_') { + must_protect = true; + goto end; + } end: - return must_protect; + return must_protect; } -static inline -int cur_path_stack_push(struct ctx *ctx, - uint64_t index_in_parent, const char *name, - bool force_protect_name, const bt_field_class *ir_fc, - struct fs_sink_ctf_field_class *parent_fc) +static inline int cur_path_stack_push(struct ctx *ctx, uint64_t index_in_parent, const char *name, + bool force_protect_name, const bt_field_class *ir_fc, + struct fs_sink_ctf_field_class *parent_fc) { - int ret = 0; - struct field_path_elem *field_path_elem; - - g_array_set_size(ctx->cur_path, ctx->cur_path->len + 1); - field_path_elem = cur_path_stack_top(ctx); - field_path_elem->index_in_parent = index_in_parent; - field_path_elem->name = g_string_new(NULL); - - if (name) { - if (force_protect_name) { - g_string_assign(field_path_elem->name, "_"); - } - - g_string_append(field_path_elem->name, name); - - if (ctx->cur_scope == BT_FIELD_PATH_SCOPE_PACKET_CONTEXT) { - if (is_reserved_member_name(name, "packet_size") || - is_reserved_member_name(name, "content_size") || - is_reserved_member_name(name, "timestamp_begin") || - is_reserved_member_name(name, "timestamp_end") || - is_reserved_member_name(name, "events_discarded") || - is_reserved_member_name(name, "packet_seq_num")) { - BT_COMP_LOGE("Unsupported reserved TSDL structure field class member " - "or variant field class option name: name=\"%s\"", - name); - ret = -1; - goto end; - } - } - - if (!ist_valid_identifier(field_path_elem->name->str)) { - ret = -1; - BT_COMP_LOGE("Unsupported non-TSDL structure field class member " - "or variant field class option name: name=\"%s\"", - field_path_elem->name->str); - goto end; - } - } - - field_path_elem->ir_fc = ir_fc; - field_path_elem->parent_fc = parent_fc; + int ret = 0; + struct field_path_elem *field_path_elem; + + g_array_set_size(ctx->cur_path, ctx->cur_path->len + 1); + field_path_elem = cur_path_stack_top(ctx); + field_path_elem->index_in_parent = index_in_parent; + field_path_elem->name = g_string_new(NULL); + + if (name) { + if (force_protect_name) { + g_string_assign(field_path_elem->name, "_"); + } + + g_string_append(field_path_elem->name, name); + + if (ctx->cur_scope == BT_FIELD_PATH_SCOPE_PACKET_CONTEXT) { + if (is_reserved_member_name(name, "packet_size") || + is_reserved_member_name(name, "content_size") || + is_reserved_member_name(name, "timestamp_begin") || + is_reserved_member_name(name, "timestamp_end") || + is_reserved_member_name(name, "events_discarded") || + is_reserved_member_name(name, "packet_seq_num")) { + BT_COMP_LOGE("Unsupported reserved TSDL structure field class member " + "or variant field class option name: name=\"%s\"", + name); + ret = -1; + goto end; + } + } + + if (!ist_valid_identifier(field_path_elem->name->str)) { + ret = -1; + BT_COMP_LOGE("Unsupported non-TSDL structure field class member " + "or variant field class option name: name=\"%s\"", + field_path_elem->name->str); + goto end; + } + } + + field_path_elem->ir_fc = ir_fc; + field_path_elem->parent_fc = parent_fc; end: - return ret; + return ret; } -static inline -void cur_path_stack_pop(struct ctx *ctx) +static inline void cur_path_stack_pop(struct ctx *ctx) { - struct field_path_elem *field_path_elem; + struct field_path_elem *field_path_elem; - BT_ASSERT(ctx->cur_path->len > 0); - field_path_elem = cur_path_stack_top(ctx); + BT_ASSERT(ctx->cur_path->len > 0); + field_path_elem = cur_path_stack_top(ctx); - if (field_path_elem->name) { - g_string_free(field_path_elem->name, TRUE); - field_path_elem->name = NULL; - } + if (field_path_elem->name) { + g_string_free(field_path_elem->name, TRUE); + field_path_elem->name = NULL; + } - g_array_set_size(ctx->cur_path, ctx->cur_path->len - 1); + g_array_set_size(ctx->cur_path, ctx->cur_path->len - 1); } /* @@ -260,171 +228,164 @@ void cur_path_stack_pop(struct ctx *ctx) * * Returns a negative value if this resolving operation failed. */ -static -int create_relative_field_ref(struct ctx *ctx, - const bt_field_path *tgt_ir_field_path, GString *tgt_field_ref, - struct fs_sink_ctf_field_class **user_tgt_fc) +static int create_relative_field_ref(struct ctx *ctx, const bt_field_path *tgt_ir_field_path, + GString *tgt_field_ref, + struct fs_sink_ctf_field_class **user_tgt_fc) { - int ret = 0; - struct fs_sink_ctf_field_class *tgt_fc = NULL; - uint64_t i; - int64_t si; - const char *tgt_fc_name = NULL; - struct field_path_elem *field_path_elem; - - /* Get target field class's name */ - switch (bt_field_path_get_root_scope(tgt_ir_field_path)) { - case BT_FIELD_PATH_SCOPE_PACKET_CONTEXT: - BT_ASSERT(ctx->cur_sc); - tgt_fc = ctx->cur_sc->packet_context_fc; - break; - case BT_FIELD_PATH_SCOPE_EVENT_COMMON_CONTEXT: - BT_ASSERT(ctx->cur_sc); - tgt_fc = ctx->cur_sc->event_common_context_fc; - break; - case BT_FIELD_PATH_SCOPE_EVENT_SPECIFIC_CONTEXT: - BT_ASSERT(ctx->cur_ec); - tgt_fc = ctx->cur_ec->spec_context_fc; - break; - case BT_FIELD_PATH_SCOPE_EVENT_PAYLOAD: - BT_ASSERT(ctx->cur_ec); - tgt_fc = ctx->cur_ec->payload_fc; - break; - default: - bt_common_abort(); - } - - i = 0; - - while (i < bt_field_path_get_item_count(tgt_ir_field_path)) { - const bt_field_path_item *fp_item = - bt_field_path_borrow_item_by_index_const( - tgt_ir_field_path, i); - struct fs_sink_ctf_named_field_class *named_fc = NULL; - - BT_ASSERT(tgt_fc); - BT_ASSERT(fp_item); - - if (bt_field_path_item_get_type(fp_item) == - BT_FIELD_PATH_ITEM_TYPE_CURRENT_OPTION_CONTENT) { - /* Not supported by CTF 1.8 */ - ret = -1; - goto end; - } - - switch (tgt_fc->type) { - case FS_SINK_CTF_FIELD_CLASS_TYPE_STRUCT: - BT_ASSERT(bt_field_path_item_get_type(fp_item) == - BT_FIELD_PATH_ITEM_TYPE_INDEX); - named_fc = fs_sink_ctf_field_class_struct_borrow_member_by_index( - fs_sink_ctf_field_class_as_struct(tgt_fc), - bt_field_path_item_index_get_index(fp_item)); - break; - case FS_SINK_CTF_FIELD_CLASS_TYPE_VARIANT: - BT_ASSERT(bt_field_path_item_get_type(fp_item) == - BT_FIELD_PATH_ITEM_TYPE_INDEX); - named_fc = fs_sink_ctf_field_class_variant_borrow_option_by_index( - fs_sink_ctf_field_class_as_variant(tgt_fc), - bt_field_path_item_index_get_index(fp_item)); - break; - case FS_SINK_CTF_FIELD_CLASS_TYPE_ARRAY: - case FS_SINK_CTF_FIELD_CLASS_TYPE_SEQUENCE: - { - struct fs_sink_ctf_field_class_array_base *array_base_fc = - fs_sink_ctf_field_class_as_array_base(tgt_fc); - - BT_ASSERT(bt_field_path_item_get_type(fp_item) == - BT_FIELD_PATH_ITEM_TYPE_CURRENT_ARRAY_ELEMENT); - tgt_fc = array_base_fc->elem_fc; - break; - } - default: - bt_common_abort(); - } - - if (named_fc) { - tgt_fc = named_fc->fc; - tgt_fc_name = named_fc->name->str; - i++; - } - } - - BT_ASSERT(tgt_fc); - BT_ASSERT(tgt_fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_INT); - BT_ASSERT(tgt_fc_name); - - /* Find target field class having this name in current context */ - for (si = ctx->cur_path->len - 1; si >= 0; si--) { - struct fs_sink_ctf_field_class *fc; - struct fs_sink_ctf_field_class_struct *struct_fc = NULL; - struct fs_sink_ctf_field_class_variant *var_fc = NULL; - struct fs_sink_ctf_named_field_class *named_fc; - uint64_t len; - - field_path_elem = cur_path_stack_at(ctx, (uint64_t) si); - fc = field_path_elem->parent_fc; - if (!fc) { - /* Reached stack's bottom */ - ret = -1; - goto end; - } - - switch (fc->type) { - case FS_SINK_CTF_FIELD_CLASS_TYPE_STRUCT: - case FS_SINK_CTF_FIELD_CLASS_TYPE_VARIANT: - break; - case FS_SINK_CTF_FIELD_CLASS_TYPE_ARRAY: - case FS_SINK_CTF_FIELD_CLASS_TYPE_SEQUENCE: - continue; - default: - /* Not supported by TSDL 1.8 */ - ret = -1; - goto end; - } - - if (fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_STRUCT) { - struct_fc = fs_sink_ctf_field_class_as_struct(fc); - len = struct_fc->members->len; - } else { - var_fc = fs_sink_ctf_field_class_as_variant(fc); - len = var_fc->options->len; - } - - for (i = 0; i < len; i++) { - if (fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_STRUCT) { - named_fc = fs_sink_ctf_field_class_struct_borrow_member_by_index( - struct_fc, i); - } else { - named_fc = fs_sink_ctf_field_class_variant_borrow_option_by_index( - var_fc, i); - } - - if (strcmp(named_fc->name->str, tgt_fc_name) == 0) { - if (named_fc->fc == tgt_fc) { - g_string_assign(tgt_field_ref, - tgt_fc_name); - - if (user_tgt_fc) { - *user_tgt_fc = tgt_fc; - } - } else { - /* - * Using only the target field - * class's name, we're not - * reaching the target field - * class. This is not supported - * by TSDL 1.8. - */ - ret = -1; - } - - goto end; - } - } - } + int ret = 0; + struct fs_sink_ctf_field_class *tgt_fc = NULL; + uint64_t i; + int64_t si; + const char *tgt_fc_name = NULL; + struct field_path_elem *field_path_elem; + + /* Get target field class's name */ + switch (bt_field_path_get_root_scope(tgt_ir_field_path)) { + case BT_FIELD_PATH_SCOPE_PACKET_CONTEXT: + BT_ASSERT(ctx->cur_sc); + tgt_fc = ctx->cur_sc->packet_context_fc; + break; + case BT_FIELD_PATH_SCOPE_EVENT_COMMON_CONTEXT: + BT_ASSERT(ctx->cur_sc); + tgt_fc = ctx->cur_sc->event_common_context_fc; + break; + case BT_FIELD_PATH_SCOPE_EVENT_SPECIFIC_CONTEXT: + BT_ASSERT(ctx->cur_ec); + tgt_fc = ctx->cur_ec->spec_context_fc; + break; + case BT_FIELD_PATH_SCOPE_EVENT_PAYLOAD: + BT_ASSERT(ctx->cur_ec); + tgt_fc = ctx->cur_ec->payload_fc; + break; + default: + bt_common_abort(); + } + + i = 0; + + while (i < bt_field_path_get_item_count(tgt_ir_field_path)) { + const bt_field_path_item *fp_item = + bt_field_path_borrow_item_by_index_const(tgt_ir_field_path, i); + struct fs_sink_ctf_named_field_class *named_fc = NULL; + + BT_ASSERT(tgt_fc); + BT_ASSERT(fp_item); + + if (bt_field_path_item_get_type(fp_item) == + BT_FIELD_PATH_ITEM_TYPE_CURRENT_OPTION_CONTENT) { + /* Not supported by CTF 1.8 */ + ret = -1; + goto end; + } + + switch (tgt_fc->type) { + case FS_SINK_CTF_FIELD_CLASS_TYPE_STRUCT: + BT_ASSERT(bt_field_path_item_get_type(fp_item) == BT_FIELD_PATH_ITEM_TYPE_INDEX); + named_fc = fs_sink_ctf_field_class_struct_borrow_member_by_index( + fs_sink_ctf_field_class_as_struct(tgt_fc), + bt_field_path_item_index_get_index(fp_item)); + break; + case FS_SINK_CTF_FIELD_CLASS_TYPE_VARIANT: + BT_ASSERT(bt_field_path_item_get_type(fp_item) == BT_FIELD_PATH_ITEM_TYPE_INDEX); + named_fc = fs_sink_ctf_field_class_variant_borrow_option_by_index( + fs_sink_ctf_field_class_as_variant(tgt_fc), + bt_field_path_item_index_get_index(fp_item)); + break; + case FS_SINK_CTF_FIELD_CLASS_TYPE_ARRAY: + case FS_SINK_CTF_FIELD_CLASS_TYPE_SEQUENCE: + { + struct fs_sink_ctf_field_class_array_base *array_base_fc = + fs_sink_ctf_field_class_as_array_base(tgt_fc); + + BT_ASSERT(bt_field_path_item_get_type(fp_item) == + BT_FIELD_PATH_ITEM_TYPE_CURRENT_ARRAY_ELEMENT); + tgt_fc = array_base_fc->elem_fc; + break; + } + default: + bt_common_abort(); + } + + if (named_fc) { + tgt_fc = named_fc->fc; + tgt_fc_name = named_fc->name->str; + i++; + } + } + + BT_ASSERT(tgt_fc); + BT_ASSERT(tgt_fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_INT); + BT_ASSERT(tgt_fc_name); + + /* Find target field class having this name in current context */ + for (si = ctx->cur_path->len - 1; si >= 0; si--) { + struct fs_sink_ctf_field_class *fc; + struct fs_sink_ctf_field_class_struct *struct_fc = NULL; + struct fs_sink_ctf_field_class_variant *var_fc = NULL; + struct fs_sink_ctf_named_field_class *named_fc; + uint64_t len; + + field_path_elem = cur_path_stack_at(ctx, (uint64_t) si); + fc = field_path_elem->parent_fc; + if (!fc) { + /* Reached stack's bottom */ + ret = -1; + goto end; + } + + switch (fc->type) { + case FS_SINK_CTF_FIELD_CLASS_TYPE_STRUCT: + case FS_SINK_CTF_FIELD_CLASS_TYPE_VARIANT: + break; + case FS_SINK_CTF_FIELD_CLASS_TYPE_ARRAY: + case FS_SINK_CTF_FIELD_CLASS_TYPE_SEQUENCE: + continue; + default: + /* Not supported by TSDL 1.8 */ + ret = -1; + goto end; + } + + if (fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_STRUCT) { + struct_fc = fs_sink_ctf_field_class_as_struct(fc); + len = struct_fc->members->len; + } else { + var_fc = fs_sink_ctf_field_class_as_variant(fc); + len = var_fc->options->len; + } + + for (i = 0; i < len; i++) { + if (fc->type == FS_SINK_CTF_FIELD_CLASS_TYPE_STRUCT) { + named_fc = fs_sink_ctf_field_class_struct_borrow_member_by_index(struct_fc, i); + } else { + named_fc = fs_sink_ctf_field_class_variant_borrow_option_by_index(var_fc, i); + } + + if (strcmp(named_fc->name->str, tgt_fc_name) == 0) { + if (named_fc->fc == tgt_fc) { + g_string_assign(tgt_field_ref, tgt_fc_name); + + if (user_tgt_fc) { + *user_tgt_fc = tgt_fc; + } + } else { + /* + * Using only the target field + * class's name, we're not + * reaching the target field + * class. This is not supported + * by TSDL 1.8. + */ + ret = -1; + } + + goto end; + } + } + } end: - return ret; + return ret; } /* @@ -432,86 +393,80 @@ end: * * Returns a negative value if this resolving operation failed. */ -static -int create_absolute_field_ref(struct ctx *ctx, - const bt_field_path *tgt_ir_field_path, GString *tgt_field_ref, - struct fs_sink_ctf_field_class **user_tgt_fc) +static int create_absolute_field_ref(struct ctx *ctx, const bt_field_path *tgt_ir_field_path, + GString *tgt_field_ref, + struct fs_sink_ctf_field_class **user_tgt_fc) { - int ret = 0; - struct fs_sink_ctf_field_class *fc = NULL; - uint64_t i; - - switch (bt_field_path_get_root_scope(tgt_ir_field_path)) { - case BT_FIELD_PATH_SCOPE_PACKET_CONTEXT: - BT_ASSERT(ctx->cur_sc); - fc = ctx->cur_sc->packet_context_fc; - g_string_assign(tgt_field_ref, "stream.packet.context"); - break; - case BT_FIELD_PATH_SCOPE_EVENT_COMMON_CONTEXT: - BT_ASSERT(ctx->cur_sc); - fc = ctx->cur_sc->event_common_context_fc; - g_string_assign(tgt_field_ref, "stream.event.context"); - break; - case BT_FIELD_PATH_SCOPE_EVENT_SPECIFIC_CONTEXT: - BT_ASSERT(ctx->cur_ec); - fc = ctx->cur_ec->spec_context_fc; - g_string_assign(tgt_field_ref, "event.context"); - break; - case BT_FIELD_PATH_SCOPE_EVENT_PAYLOAD: - BT_ASSERT(ctx->cur_ec); - fc = ctx->cur_ec->payload_fc; - g_string_assign(tgt_field_ref, "event.fields"); - break; - default: - bt_common_abort(); - } - - BT_ASSERT(fc); - - for (i = 0; i < bt_field_path_get_item_count(tgt_ir_field_path); i++) { - const bt_field_path_item *fp_item = - bt_field_path_borrow_item_by_index_const( - tgt_ir_field_path, i); - struct fs_sink_ctf_named_field_class *named_fc = NULL; - - if (bt_field_path_item_get_type(fp_item) != - BT_FIELD_PATH_ITEM_TYPE_INDEX) { - /* Not supported by TSDL 1.8 */ - ret = -1; - goto end; - } - - switch (fc->type) { - case FS_SINK_CTF_FIELD_CLASS_TYPE_STRUCT: - BT_ASSERT(bt_field_path_item_get_type(fp_item) == - BT_FIELD_PATH_ITEM_TYPE_INDEX); - named_fc = fs_sink_ctf_field_class_struct_borrow_member_by_index( - fs_sink_ctf_field_class_as_struct(fc), - bt_field_path_item_index_get_index(fp_item)); - break; - case FS_SINK_CTF_FIELD_CLASS_TYPE_VARIANT: - BT_ASSERT(bt_field_path_item_get_type(fp_item) == - BT_FIELD_PATH_ITEM_TYPE_INDEX); - named_fc = fs_sink_ctf_field_class_variant_borrow_option_by_index( - fs_sink_ctf_field_class_as_variant(fc), - bt_field_path_item_index_get_index(fp_item)); - break; - default: - bt_common_abort(); - } - - BT_ASSERT(named_fc); - g_string_append_c(tgt_field_ref, '.'); - g_string_append(tgt_field_ref, named_fc->name->str); - fc = named_fc->fc; - } - - if (user_tgt_fc) { - *user_tgt_fc = fc; - } + int ret = 0; + struct fs_sink_ctf_field_class *fc = NULL; + uint64_t i; + + switch (bt_field_path_get_root_scope(tgt_ir_field_path)) { + case BT_FIELD_PATH_SCOPE_PACKET_CONTEXT: + BT_ASSERT(ctx->cur_sc); + fc = ctx->cur_sc->packet_context_fc; + g_string_assign(tgt_field_ref, "stream.packet.context"); + break; + case BT_FIELD_PATH_SCOPE_EVENT_COMMON_CONTEXT: + BT_ASSERT(ctx->cur_sc); + fc = ctx->cur_sc->event_common_context_fc; + g_string_assign(tgt_field_ref, "stream.event.context"); + break; + case BT_FIELD_PATH_SCOPE_EVENT_SPECIFIC_CONTEXT: + BT_ASSERT(ctx->cur_ec); + fc = ctx->cur_ec->spec_context_fc; + g_string_assign(tgt_field_ref, "event.context"); + break; + case BT_FIELD_PATH_SCOPE_EVENT_PAYLOAD: + BT_ASSERT(ctx->cur_ec); + fc = ctx->cur_ec->payload_fc; + g_string_assign(tgt_field_ref, "event.fields"); + break; + default: + bt_common_abort(); + } + + BT_ASSERT(fc); + + for (i = 0; i < bt_field_path_get_item_count(tgt_ir_field_path); i++) { + const bt_field_path_item *fp_item = + bt_field_path_borrow_item_by_index_const(tgt_ir_field_path, i); + struct fs_sink_ctf_named_field_class *named_fc = NULL; + + if (bt_field_path_item_get_type(fp_item) != BT_FIELD_PATH_ITEM_TYPE_INDEX) { + /* Not supported by TSDL 1.8 */ + ret = -1; + goto end; + } + + switch (fc->type) { + case FS_SINK_CTF_FIELD_CLASS_TYPE_STRUCT: + BT_ASSERT(bt_field_path_item_get_type(fp_item) == BT_FIELD_PATH_ITEM_TYPE_INDEX); + named_fc = fs_sink_ctf_field_class_struct_borrow_member_by_index( + fs_sink_ctf_field_class_as_struct(fc), bt_field_path_item_index_get_index(fp_item)); + break; + case FS_SINK_CTF_FIELD_CLASS_TYPE_VARIANT: + BT_ASSERT(bt_field_path_item_get_type(fp_item) == BT_FIELD_PATH_ITEM_TYPE_INDEX); + named_fc = fs_sink_ctf_field_class_variant_borrow_option_by_index( + fs_sink_ctf_field_class_as_variant(fc), + bt_field_path_item_index_get_index(fp_item)); + break; + default: + bt_common_abort(); + } + + BT_ASSERT(named_fc); + g_string_append_c(tgt_field_ref, '.'); + g_string_append(tgt_field_ref, named_fc->name->str); + fc = named_fc->fc; + } + + if (user_tgt_fc) { + *user_tgt_fc = fc; + } end: - return ret; + return ret; } /* @@ -521,196 +476,174 @@ end: * created immediately before (in which case `tgt_field_ref` is * irrelevant). */ -static -void resolve_field_class(struct ctx *ctx, - const bt_field_path *tgt_ir_field_path, - GString *tgt_field_ref, bool *create_before, - struct fs_sink_ctf_field_class **user_tgt_fc) +static void resolve_field_class(struct ctx *ctx, const bt_field_path *tgt_ir_field_path, + GString *tgt_field_ref, bool *create_before, + struct fs_sink_ctf_field_class **user_tgt_fc) { - int ret; - bt_field_path_scope tgt_scope; - - *create_before = false; - - if (!tgt_ir_field_path) { - *create_before = true; - goto end; - } - - tgt_scope = bt_field_path_get_root_scope(tgt_ir_field_path); - - if (tgt_scope == ctx->cur_scope) { - /* - * Try, in this order: - * - * 1. Use a relative path, using only the target field - * class's name. This is what is the most commonly - * supported by popular CTF reading tools. - * - * 2. Use an absolute path. This could fail if there's - * an array field class from the current root's field - * class to the target field class. - * - * 3. Create the target field class before the - * requesting field class (fallback). - */ - ret = create_relative_field_ref(ctx, tgt_ir_field_path, - tgt_field_ref, user_tgt_fc); - if (ret) { - ret = create_absolute_field_ref(ctx, tgt_ir_field_path, - tgt_field_ref, user_tgt_fc); - if (ret) { - *create_before = true; - goto end; - } - } - } else { - ret = create_absolute_field_ref(ctx, tgt_ir_field_path, - tgt_field_ref, user_tgt_fc); - - /* It must always work in previous scopes */ - BT_ASSERT(ret == 0); - } + int ret; + bt_field_path_scope tgt_scope; + + *create_before = false; + + if (!tgt_ir_field_path) { + *create_before = true; + goto end; + } + + tgt_scope = bt_field_path_get_root_scope(tgt_ir_field_path); + + if (tgt_scope == ctx->cur_scope) { + /* + * Try, in this order: + * + * 1. Use a relative path, using only the target field + * class's name. This is what is the most commonly + * supported by popular CTF reading tools. + * + * 2. Use an absolute path. This could fail if there's + * an array field class from the current root's field + * class to the target field class. + * + * 3. Create the target field class before the + * requesting field class (fallback). + */ + ret = create_relative_field_ref(ctx, tgt_ir_field_path, tgt_field_ref, user_tgt_fc); + if (ret) { + ret = create_absolute_field_ref(ctx, tgt_ir_field_path, tgt_field_ref, user_tgt_fc); + if (ret) { + *create_before = true; + goto end; + } + } + } else { + ret = create_absolute_field_ref(ctx, tgt_ir_field_path, tgt_field_ref, user_tgt_fc); + + /* It must always work in previous scopes */ + BT_ASSERT(ret == 0); + } end: - return; + return; } -static -int translate_field_class(struct ctx *ctx); +static int translate_field_class(struct ctx *ctx); -static inline -void append_to_parent_field_class(struct ctx *ctx, - struct fs_sink_ctf_field_class *fc) +static inline void append_to_parent_field_class(struct ctx *ctx, struct fs_sink_ctf_field_class *fc) { - struct fs_sink_ctf_field_class *parent_fc = - cur_path_stack_top(ctx)->parent_fc; - - switch (parent_fc->type) { - case FS_SINK_CTF_FIELD_CLASS_TYPE_STRUCT: - fs_sink_ctf_field_class_struct_append_member( - fs_sink_ctf_field_class_as_struct(parent_fc), - cur_path_stack_top(ctx)->name->str, fc); - break; - case FS_SINK_CTF_FIELD_CLASS_TYPE_OPTION: - { - struct fs_sink_ctf_field_class_option *opt_fc = - fs_sink_ctf_field_class_as_option(parent_fc); - - BT_ASSERT(!opt_fc->content_fc); - opt_fc->content_fc = fc; - opt_fc->base.alignment = fc->alignment; - break; - } - case FS_SINK_CTF_FIELD_CLASS_TYPE_VARIANT: - fs_sink_ctf_field_class_variant_append_option( - fs_sink_ctf_field_class_as_variant(parent_fc), - cur_path_stack_top(ctx)->name->str, fc); - break; - case FS_SINK_CTF_FIELD_CLASS_TYPE_ARRAY: - case FS_SINK_CTF_FIELD_CLASS_TYPE_SEQUENCE: - { - struct fs_sink_ctf_field_class_array_base *array_base_fc = - fs_sink_ctf_field_class_as_array_base(parent_fc); - - BT_ASSERT(!array_base_fc->elem_fc); - array_base_fc->elem_fc = fc; - array_base_fc->base.alignment = fc->alignment; - break; - } - default: - bt_common_abort(); - } + struct fs_sink_ctf_field_class *parent_fc = cur_path_stack_top(ctx)->parent_fc; + + switch (parent_fc->type) { + case FS_SINK_CTF_FIELD_CLASS_TYPE_STRUCT: + fs_sink_ctf_field_class_struct_append_member(fs_sink_ctf_field_class_as_struct(parent_fc), + cur_path_stack_top(ctx)->name->str, fc); + break; + case FS_SINK_CTF_FIELD_CLASS_TYPE_OPTION: + { + struct fs_sink_ctf_field_class_option *opt_fc = + fs_sink_ctf_field_class_as_option(parent_fc); + + BT_ASSERT(!opt_fc->content_fc); + opt_fc->content_fc = fc; + opt_fc->base.alignment = fc->alignment; + break; + } + case FS_SINK_CTF_FIELD_CLASS_TYPE_VARIANT: + fs_sink_ctf_field_class_variant_append_option(fs_sink_ctf_field_class_as_variant(parent_fc), + cur_path_stack_top(ctx)->name->str, fc); + break; + case FS_SINK_CTF_FIELD_CLASS_TYPE_ARRAY: + case FS_SINK_CTF_FIELD_CLASS_TYPE_SEQUENCE: + { + struct fs_sink_ctf_field_class_array_base *array_base_fc = + fs_sink_ctf_field_class_as_array_base(parent_fc); + + BT_ASSERT(!array_base_fc->elem_fc); + array_base_fc->elem_fc = fc; + array_base_fc->base.alignment = fc->alignment; + break; + } + default: + bt_common_abort(); + } } -static inline -void update_parent_field_class_alignment(struct ctx *ctx, - unsigned int alignment) +static inline void update_parent_field_class_alignment(struct ctx *ctx, unsigned int alignment) { - struct fs_sink_ctf_field_class *parent_fc = - cur_path_stack_top(ctx)->parent_fc; - - switch (parent_fc->type) { - case FS_SINK_CTF_FIELD_CLASS_TYPE_STRUCT: - fs_sink_ctf_field_class_struct_align_at_least( - fs_sink_ctf_field_class_as_struct(parent_fc), - alignment); - break; - case FS_SINK_CTF_FIELD_CLASS_TYPE_ARRAY: - case FS_SINK_CTF_FIELD_CLASS_TYPE_SEQUENCE: - { - struct fs_sink_ctf_field_class_array_base *array_base_fc = - fs_sink_ctf_field_class_as_array_base(parent_fc); - - array_base_fc->base.alignment = alignment; - break; - } - default: - break; - } + struct fs_sink_ctf_field_class *parent_fc = cur_path_stack_top(ctx)->parent_fc; + + switch (parent_fc->type) { + case FS_SINK_CTF_FIELD_CLASS_TYPE_STRUCT: + fs_sink_ctf_field_class_struct_align_at_least(fs_sink_ctf_field_class_as_struct(parent_fc), + alignment); + break; + case FS_SINK_CTF_FIELD_CLASS_TYPE_ARRAY: + case FS_SINK_CTF_FIELD_CLASS_TYPE_SEQUENCE: + { + struct fs_sink_ctf_field_class_array_base *array_base_fc = + fs_sink_ctf_field_class_as_array_base(parent_fc); + + array_base_fc->base.alignment = alignment; + break; + } + default: + break; + } } -static inline -int translate_structure_field_class_members(struct ctx *ctx, - struct fs_sink_ctf_field_class_struct *struct_fc, - const bt_field_class *ir_fc) +static inline int translate_structure_field_class_members( + struct ctx *ctx, struct fs_sink_ctf_field_class_struct *struct_fc, const bt_field_class *ir_fc) { - int ret = 0; - uint64_t i; - - for (i = 0; i < bt_field_class_structure_get_member_count(ir_fc); i++) { - const bt_field_class_structure_member *member; - const char *name; - const bt_field_class *memb_ir_fc; - - member = - bt_field_class_structure_borrow_member_by_index_const( - ir_fc, i); - name = bt_field_class_structure_member_get_name(member); - memb_ir_fc = bt_field_class_structure_member_borrow_field_class_const( - member); - ret = cur_path_stack_push(ctx, i, name, true, memb_ir_fc, - &struct_fc->base); - if (ret) { - BT_COMP_LOGE("Cannot translate structure field class member: " - "name=\"%s\"", name); - goto end; - } - - ret = translate_field_class(ctx); - if (ret) { - BT_COMP_LOGE("Cannot translate structure field class member: " - "name=\"%s\"", name); - goto end; - } - - cur_path_stack_pop(ctx); - } + int ret = 0; + uint64_t i; + + for (i = 0; i < bt_field_class_structure_get_member_count(ir_fc); i++) { + const bt_field_class_structure_member *member; + const char *name; + const bt_field_class *memb_ir_fc; + + member = bt_field_class_structure_borrow_member_by_index_const(ir_fc, i); + name = bt_field_class_structure_member_get_name(member); + memb_ir_fc = bt_field_class_structure_member_borrow_field_class_const(member); + ret = cur_path_stack_push(ctx, i, name, true, memb_ir_fc, &struct_fc->base); + if (ret) { + BT_COMP_LOGE("Cannot translate structure field class member: " + "name=\"%s\"", + name); + goto end; + } + + ret = translate_field_class(ctx); + if (ret) { + BT_COMP_LOGE("Cannot translate structure field class member: " + "name=\"%s\"", + name); + goto end; + } + + cur_path_stack_pop(ctx); + } end: - return ret; + return ret; } -static inline -int translate_structure_field_class(struct ctx *ctx) +static inline int translate_structure_field_class(struct ctx *ctx) { - int ret; - struct fs_sink_ctf_field_class_struct *fc = - fs_sink_ctf_field_class_struct_create_empty( - cur_path_stack_top(ctx)->ir_fc, - cur_path_stack_top(ctx)->index_in_parent); + int ret; + struct fs_sink_ctf_field_class_struct *fc = fs_sink_ctf_field_class_struct_create_empty( + cur_path_stack_top(ctx)->ir_fc, cur_path_stack_top(ctx)->index_in_parent); - BT_ASSERT(fc); - append_to_parent_field_class(ctx, &fc->base); - ret = translate_structure_field_class_members(ctx, fc, fc->base.ir_fc); - if (ret) { - goto end; - } + BT_ASSERT(fc); + append_to_parent_field_class(ctx, &fc->base); + ret = translate_structure_field_class_members(ctx, fc, fc->base.ir_fc); + if (ret) { + goto end; + } - update_parent_field_class_alignment(ctx, fc->base.alignment); + update_parent_field_class_alignment(ctx, fc->base.alignment); end: - return ret; + return ret; } /* @@ -782,507 +715,450 @@ end: * fact to find the original variant FC option names by matching variant * FC options and enumeration FC mappings by range set. */ -static -int maybe_protect_variant_option_name(const bt_field_class *ir_var_fc, - const bt_field_class *ir_tag_fc, uint64_t opt_i, - GString *name_buf) +static int maybe_protect_variant_option_name(const bt_field_class *ir_var_fc, + const bt_field_class *ir_tag_fc, uint64_t opt_i, + GString *name_buf) { - int ret = 0; - uint64_t i; - bt_field_class_type ir_var_fc_type; - const bt_integer_range_set_unsigned *opt_ranges_unsigned = NULL; - const bt_integer_range_set_signed *opt_ranges_signed = NULL; - const char *mapping_label = NULL; - const char *ir_opt_name; - const bt_field_class_variant_option *base_var_opt; - bool force_protect = false; - - ir_var_fc_type = bt_field_class_get_type(ir_var_fc); - base_var_opt = bt_field_class_variant_borrow_option_by_index_const( - ir_var_fc, opt_i); - BT_ASSERT(base_var_opt); - ir_opt_name = bt_field_class_variant_option_get_name(base_var_opt); - BT_ASSERT(ir_opt_name); - - /* - * Check if the variant FC option name is required to be - * protected (reserved TSDL keyword or starts with `_`). In that - * case, the name of the selector FC mapping we find must match - * exactly the protected name. - */ - force_protect = must_protect_identifier(ir_opt_name); - if (force_protect) { - g_string_assign(name_buf, "_"); - g_string_append(name_buf, ir_opt_name); - } else { - g_string_assign(name_buf, ir_opt_name); - } - - /* Borrow option's ranges */ - if (ir_var_fc_type == BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR_FIELD) { - /* No ranges: we're done */ - goto end; - } if (ir_var_fc_type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD) { - const bt_field_class_variant_with_selector_field_integer_unsigned_option *var_opt = - bt_field_class_variant_with_selector_field_integer_unsigned_borrow_option_by_index_const( - ir_var_fc, opt_i); - opt_ranges_unsigned = - bt_field_class_variant_with_selector_field_integer_unsigned_option_borrow_ranges_const( - var_opt); - } else { - const bt_field_class_variant_with_selector_field_integer_signed_option *var_opt = - bt_field_class_variant_with_selector_field_integer_signed_borrow_option_by_index_const( - ir_var_fc, opt_i); - opt_ranges_signed = - bt_field_class_variant_with_selector_field_integer_signed_option_borrow_ranges_const( - var_opt); - } - - /* Find corresponding mapping by range set in selector FC */ - for (i = 0; i < bt_field_class_enumeration_get_mapping_count(ir_tag_fc); - i++) { - if (ir_var_fc_type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD) { - const bt_field_class_enumeration_mapping *mapping_base; - const bt_field_class_enumeration_unsigned_mapping *mapping; - const bt_integer_range_set_unsigned *mapping_ranges; - - mapping = bt_field_class_enumeration_unsigned_borrow_mapping_by_index_const( - ir_tag_fc, i); - mapping_ranges = bt_field_class_enumeration_unsigned_mapping_borrow_ranges_const( - mapping); - - if (bt_integer_range_set_unsigned_is_equal(opt_ranges_unsigned, - mapping_ranges)) { - /* We have a winner */ - mapping_base = - bt_field_class_enumeration_unsigned_mapping_as_mapping_const( - mapping); - mapping_label = - bt_field_class_enumeration_mapping_get_label( - mapping_base); - break; - } - } else { - const bt_field_class_enumeration_mapping *mapping_base; - const bt_field_class_enumeration_signed_mapping *mapping; - const bt_integer_range_set_signed *mapping_ranges; - - mapping = bt_field_class_enumeration_signed_borrow_mapping_by_index_const( - ir_tag_fc, i); - mapping_ranges = bt_field_class_enumeration_signed_mapping_borrow_ranges_const( - mapping); - - if (bt_integer_range_set_signed_is_equal(opt_ranges_signed, - mapping_ranges)) { - /* We have a winner */ - mapping_base = - bt_field_class_enumeration_signed_mapping_as_mapping_const( - mapping); - mapping_label = - bt_field_class_enumeration_mapping_get_label( - mapping_base); - break; - } - } - } - - if (!mapping_label) { - /* Range set not found: invalid selector for CTF 1.8 */ - ret = -1; - goto end; - } - - /* - * If the enumeration FC mapping name is not the same as the - * variant FC option name and we didn't protect already, try - * protecting the option name and check again. - */ - if (strcmp(mapping_label, name_buf->str) != 0) { - if (force_protect) { - ret = -1; - goto end; - } - - if (mapping_label[0] == '\0') { - ret = -1; - goto end; - } - - g_string_assign(name_buf, "_"); - g_string_append(name_buf, ir_opt_name); - - if (strcmp(mapping_label, name_buf->str) != 0) { - ret = -1; - goto end; - } - } + int ret = 0; + uint64_t i; + bt_field_class_type ir_var_fc_type; + const bt_integer_range_set_unsigned *opt_ranges_unsigned = NULL; + const bt_integer_range_set_signed *opt_ranges_signed = NULL; + const char *mapping_label = NULL; + const char *ir_opt_name; + const bt_field_class_variant_option *base_var_opt; + bool force_protect = false; + + ir_var_fc_type = bt_field_class_get_type(ir_var_fc); + base_var_opt = bt_field_class_variant_borrow_option_by_index_const(ir_var_fc, opt_i); + BT_ASSERT(base_var_opt); + ir_opt_name = bt_field_class_variant_option_get_name(base_var_opt); + BT_ASSERT(ir_opt_name); + + /* + * Check if the variant FC option name is required to be + * protected (reserved TSDL keyword or starts with `_`). In that + * case, the name of the selector FC mapping we find must match + * exactly the protected name. + */ + force_protect = must_protect_identifier(ir_opt_name); + if (force_protect) { + g_string_assign(name_buf, "_"); + g_string_append(name_buf, ir_opt_name); + } else { + g_string_assign(name_buf, ir_opt_name); + } + + /* Borrow option's ranges */ + if (ir_var_fc_type == BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR_FIELD) { + /* No ranges: we're done */ + goto end; + } + if (ir_var_fc_type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD) { + const bt_field_class_variant_with_selector_field_integer_unsigned_option *var_opt = + bt_field_class_variant_with_selector_field_integer_unsigned_borrow_option_by_index_const( + ir_var_fc, opt_i); + opt_ranges_unsigned = + bt_field_class_variant_with_selector_field_integer_unsigned_option_borrow_ranges_const( + var_opt); + } else { + const bt_field_class_variant_with_selector_field_integer_signed_option *var_opt = + bt_field_class_variant_with_selector_field_integer_signed_borrow_option_by_index_const( + ir_var_fc, opt_i); + opt_ranges_signed = + bt_field_class_variant_with_selector_field_integer_signed_option_borrow_ranges_const( + var_opt); + } + + /* Find corresponding mapping by range set in selector FC */ + for (i = 0; i < bt_field_class_enumeration_get_mapping_count(ir_tag_fc); i++) { + if (ir_var_fc_type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD) { + const bt_field_class_enumeration_mapping *mapping_base; + const bt_field_class_enumeration_unsigned_mapping *mapping; + const bt_integer_range_set_unsigned *mapping_ranges; + + mapping = + bt_field_class_enumeration_unsigned_borrow_mapping_by_index_const(ir_tag_fc, i); + mapping_ranges = + bt_field_class_enumeration_unsigned_mapping_borrow_ranges_const(mapping); + + if (bt_integer_range_set_unsigned_is_equal(opt_ranges_unsigned, mapping_ranges)) { + /* We have a winner */ + mapping_base = + bt_field_class_enumeration_unsigned_mapping_as_mapping_const(mapping); + mapping_label = bt_field_class_enumeration_mapping_get_label(mapping_base); + break; + } + } else { + const bt_field_class_enumeration_mapping *mapping_base; + const bt_field_class_enumeration_signed_mapping *mapping; + const bt_integer_range_set_signed *mapping_ranges; + + mapping = bt_field_class_enumeration_signed_borrow_mapping_by_index_const(ir_tag_fc, i); + mapping_ranges = bt_field_class_enumeration_signed_mapping_borrow_ranges_const(mapping); + + if (bt_integer_range_set_signed_is_equal(opt_ranges_signed, mapping_ranges)) { + /* We have a winner */ + mapping_base = bt_field_class_enumeration_signed_mapping_as_mapping_const(mapping); + mapping_label = bt_field_class_enumeration_mapping_get_label(mapping_base); + break; + } + } + } + + if (!mapping_label) { + /* Range set not found: invalid selector for CTF 1.8 */ + ret = -1; + goto end; + } + + /* + * If the enumeration FC mapping name is not the same as the + * variant FC option name and we didn't protect already, try + * protecting the option name and check again. + */ + if (strcmp(mapping_label, name_buf->str) != 0) { + if (force_protect) { + ret = -1; + goto end; + } + + if (mapping_label[0] == '\0') { + ret = -1; + goto end; + } + + g_string_assign(name_buf, "_"); + g_string_append(name_buf, ir_opt_name); + + if (strcmp(mapping_label, name_buf->str) != 0) { + ret = -1; + goto end; + } + } end: - return ret; + return ret; } -static inline -int translate_option_field_class(struct ctx *ctx) +static inline int translate_option_field_class(struct ctx *ctx) { - struct fs_sink_ctf_field_class_option *fc = - fs_sink_ctf_field_class_option_create_empty( - cur_path_stack_top(ctx)->ir_fc, - cur_path_stack_top(ctx)->index_in_parent); - const bt_field_class *content_ir_fc = - bt_field_class_option_borrow_field_class_const(fc->base.ir_fc); - int ret; - - BT_ASSERT(fc); - - /* - * CTF 1.8 does not support the option field class type. To - * write something anyway, this component translates this type - * to a variant field class where the options are: - * - * * An empty structure field class. - * * The optional field class itself. - * - * The "tag" is always generated/before in that case (an 8-bit - * unsigned enumeration field class). - */ - append_to_parent_field_class(ctx, &fc->base); - ret = cur_path_stack_push(ctx, UINT64_C(-1), NULL, false, content_ir_fc, - &fc->base); - if (ret) { - BT_COMP_LOGE_STR("Cannot translate option field class content."); - goto end; - } - - ret = translate_field_class(ctx); - if (ret) { - BT_COMP_LOGE_STR("Cannot translate option field class content."); - goto end; - } - - cur_path_stack_pop(ctx); - update_parent_field_class_alignment(ctx, fc->base.alignment); + struct fs_sink_ctf_field_class_option *fc = fs_sink_ctf_field_class_option_create_empty( + cur_path_stack_top(ctx)->ir_fc, cur_path_stack_top(ctx)->index_in_parent); + const bt_field_class *content_ir_fc = + bt_field_class_option_borrow_field_class_const(fc->base.ir_fc); + int ret; + + BT_ASSERT(fc); + + /* + * CTF 1.8 does not support the option field class type. To + * write something anyway, this component translates this type + * to a variant field class where the options are: + * + * * An empty structure field class. + * * The optional field class itself. + * + * The "tag" is always generated/before in that case (an 8-bit + * unsigned enumeration field class). + */ + append_to_parent_field_class(ctx, &fc->base); + ret = cur_path_stack_push(ctx, UINT64_C(-1), NULL, false, content_ir_fc, &fc->base); + if (ret) { + BT_COMP_LOGE_STR("Cannot translate option field class content."); + goto end; + } + + ret = translate_field_class(ctx); + if (ret) { + BT_COMP_LOGE_STR("Cannot translate option field class content."); + goto end; + } + + cur_path_stack_pop(ctx); + update_parent_field_class_alignment(ctx, fc->base.alignment); end: - return ret; + return ret; } -static inline -int translate_variant_field_class(struct ctx *ctx) +static inline int translate_variant_field_class(struct ctx *ctx) { - int ret = 0; - uint64_t i; - struct fs_sink_ctf_field_class_variant *fc = - fs_sink_ctf_field_class_variant_create_empty( - cur_path_stack_top(ctx)->ir_fc, - cur_path_stack_top(ctx)->index_in_parent); - bt_field_class_type ir_fc_type; - const bt_field_path *ir_selector_field_path = NULL; - struct fs_sink_ctf_field_class *tgt_fc = NULL; - GString *name_buf = g_string_new(NULL); - bt_value *prot_opt_names = bt_value_array_create(); - uint64_t opt_count; - - BT_ASSERT(fc); - BT_ASSERT(name_buf); - BT_ASSERT(prot_opt_names); - ir_fc_type = bt_field_class_get_type(fc->base.ir_fc); - opt_count = bt_field_class_variant_get_option_count(fc->base.ir_fc); - - if (bt_field_class_type_is(ir_fc_type, - BT_FIELD_CLASS_TYPE_VARIANT_WITH_SELECTOR_FIELD)) { - ir_selector_field_path = bt_field_class_variant_with_selector_field_borrow_selector_field_path_const( - fc->base.ir_fc); - BT_ASSERT(ir_selector_field_path); - } - - /* Resolve tag field class before appending to parent */ - resolve_field_class(ctx, ir_selector_field_path, fc->tag_ref, - &fc->tag_is_before, &tgt_fc); - - if (ir_selector_field_path && tgt_fc) { - uint64_t mapping_count; - uint64_t option_count; - - /* CTF 1.8: selector FC must be an enumeration FC */ - bt_field_class_type type = bt_field_class_get_type( - tgt_fc->ir_fc); - - if (!bt_field_class_type_is(type, - BT_FIELD_CLASS_TYPE_ENUMERATION)) { - fc->tag_is_before = true; - goto validate_opts; - } - - /* - * Call maybe_protect_variant_option_name() for each - * option below. In that case we also want selector FC - * to contain as many mappings as the variant FC has - * options. - */ - mapping_count = bt_field_class_enumeration_get_mapping_count( - tgt_fc->ir_fc); - option_count = bt_field_class_variant_get_option_count( - fc->base.ir_fc); - - if (mapping_count != option_count) { - fc->tag_is_before = true; - goto validate_opts; - } - } else { - /* - * No compatible selector field class for CTF 1.8: - * create the appropriate selector field class. - */ - fc->tag_is_before = true; - goto validate_opts; - } + int ret = 0; + uint64_t i; + struct fs_sink_ctf_field_class_variant *fc = fs_sink_ctf_field_class_variant_create_empty( + cur_path_stack_top(ctx)->ir_fc, cur_path_stack_top(ctx)->index_in_parent); + bt_field_class_type ir_fc_type; + const bt_field_path *ir_selector_field_path = NULL; + struct fs_sink_ctf_field_class *tgt_fc = NULL; + GString *name_buf = g_string_new(NULL); + bt_value *prot_opt_names = bt_value_array_create(); + uint64_t opt_count; + + BT_ASSERT(fc); + BT_ASSERT(name_buf); + BT_ASSERT(prot_opt_names); + ir_fc_type = bt_field_class_get_type(fc->base.ir_fc); + opt_count = bt_field_class_variant_get_option_count(fc->base.ir_fc); + + if (bt_field_class_type_is(ir_fc_type, BT_FIELD_CLASS_TYPE_VARIANT_WITH_SELECTOR_FIELD)) { + ir_selector_field_path = + bt_field_class_variant_with_selector_field_borrow_selector_field_path_const( + fc->base.ir_fc); + BT_ASSERT(ir_selector_field_path); + } + + /* Resolve tag field class before appending to parent */ + resolve_field_class(ctx, ir_selector_field_path, fc->tag_ref, &fc->tag_is_before, &tgt_fc); + + if (ir_selector_field_path && tgt_fc) { + uint64_t mapping_count; + uint64_t option_count; + + /* CTF 1.8: selector FC must be an enumeration FC */ + bt_field_class_type type = bt_field_class_get_type(tgt_fc->ir_fc); + + if (!bt_field_class_type_is(type, BT_FIELD_CLASS_TYPE_ENUMERATION)) { + fc->tag_is_before = true; + goto validate_opts; + } + + /* + * Call maybe_protect_variant_option_name() for each + * option below. In that case we also want selector FC + * to contain as many mappings as the variant FC has + * options. + */ + mapping_count = bt_field_class_enumeration_get_mapping_count(tgt_fc->ir_fc); + option_count = bt_field_class_variant_get_option_count(fc->base.ir_fc); + + if (mapping_count != option_count) { + fc->tag_is_before = true; + goto validate_opts; + } + } else { + /* + * No compatible selector field class for CTF 1.8: + * create the appropriate selector field class. + */ + fc->tag_is_before = true; + goto validate_opts; + } validate_opts: - /* - * First pass: detect any option name clash with option name - * protection. In that case, we don't fail: just create the - * selector field class before the variant field class. - * - * After this, `prot_opt_names` contains the final option names, - * potentially protected if needed. They can still be invalid - * TSDL identifiers however; this will be checked by - * cur_path_stack_push(). - */ - for (i = 0; i < opt_count; i++) { - if (!fc->tag_is_before) { - BT_ASSERT(tgt_fc->ir_fc); - ret = maybe_protect_variant_option_name(fc->base.ir_fc, - tgt_fc->ir_fc, i, name_buf); - if (ret) { - fc->tag_is_before = true; - } - } - - ret = bt_value_array_append_string_element(prot_opt_names, - name_buf->str); - if (ret) { - goto end; - } - } - - for (i = 0; i < opt_count; i++) { - uint64_t j; - const bt_value *opt_name_a = - bt_value_array_borrow_element_by_index_const( - prot_opt_names, i); - - for (j = 0; j < opt_count; j++) { - const bt_value *opt_name_b; - - if (i == j) { - continue; - } - - opt_name_b = - bt_value_array_borrow_element_by_index_const( - prot_opt_names, j); - if (bt_value_is_equal(opt_name_a, opt_name_b)) { - /* - * Variant FC option names are not - * unique when protected. - */ - fc->tag_is_before = true; - goto append_to_parent; - } - } - } + /* + * First pass: detect any option name clash with option name + * protection. In that case, we don't fail: just create the + * selector field class before the variant field class. + * + * After this, `prot_opt_names` contains the final option names, + * potentially protected if needed. They can still be invalid + * TSDL identifiers however; this will be checked by + * cur_path_stack_push(). + */ + for (i = 0; i < opt_count; i++) { + if (!fc->tag_is_before) { + BT_ASSERT(tgt_fc->ir_fc); + ret = maybe_protect_variant_option_name(fc->base.ir_fc, tgt_fc->ir_fc, i, name_buf); + if (ret) { + fc->tag_is_before = true; + } + } + + ret = bt_value_array_append_string_element(prot_opt_names, name_buf->str); + if (ret) { + goto end; + } + } + + for (i = 0; i < opt_count; i++) { + uint64_t j; + const bt_value *opt_name_a = + bt_value_array_borrow_element_by_index_const(prot_opt_names, i); + + for (j = 0; j < opt_count; j++) { + const bt_value *opt_name_b; + + if (i == j) { + continue; + } + + opt_name_b = bt_value_array_borrow_element_by_index_const(prot_opt_names, j); + if (bt_value_is_equal(opt_name_a, opt_name_b)) { + /* + * Variant FC option names are not + * unique when protected. + */ + fc->tag_is_before = true; + goto append_to_parent; + } + } + } append_to_parent: - append_to_parent_field_class(ctx, &fc->base); - - for (i = 0; i < opt_count; i++) { - const bt_field_class_variant_option *opt; - const bt_field_class *opt_ir_fc; - const bt_value *prot_opt_name_val = - bt_value_array_borrow_element_by_index_const( - prot_opt_names, i); - const char *prot_opt_name = bt_value_string_get( - prot_opt_name_val); - - BT_ASSERT(prot_opt_name); - opt = bt_field_class_variant_borrow_option_by_index_const( - fc->base.ir_fc, i); - opt_ir_fc = bt_field_class_variant_option_borrow_field_class_const( - opt); - - /* - * We don't ask cur_path_stack_push() to protect the - * option name because it's already protected at this - * point. - */ - ret = cur_path_stack_push(ctx, i, prot_opt_name, false, - opt_ir_fc, &fc->base); - if (ret) { - BT_COMP_LOGE("Cannot translate variant field class option: " - "name=\"%s\"", prot_opt_name); - goto end; - } - - ret = translate_field_class(ctx); - if (ret) { - BT_COMP_LOGE("Cannot translate variant field class option: " - "name=\"%s\"", prot_opt_name); - goto end; - } - - cur_path_stack_pop(ctx); - } + append_to_parent_field_class(ctx, &fc->base); + + for (i = 0; i < opt_count; i++) { + const bt_field_class_variant_option *opt; + const bt_field_class *opt_ir_fc; + const bt_value *prot_opt_name_val = + bt_value_array_borrow_element_by_index_const(prot_opt_names, i); + const char *prot_opt_name = bt_value_string_get(prot_opt_name_val); + + BT_ASSERT(prot_opt_name); + opt = bt_field_class_variant_borrow_option_by_index_const(fc->base.ir_fc, i); + opt_ir_fc = bt_field_class_variant_option_borrow_field_class_const(opt); + + /* + * We don't ask cur_path_stack_push() to protect the + * option name because it's already protected at this + * point. + */ + ret = cur_path_stack_push(ctx, i, prot_opt_name, false, opt_ir_fc, &fc->base); + if (ret) { + BT_COMP_LOGE("Cannot translate variant field class option: " + "name=\"%s\"", + prot_opt_name); + goto end; + } + + ret = translate_field_class(ctx); + if (ret) { + BT_COMP_LOGE("Cannot translate variant field class option: " + "name=\"%s\"", + prot_opt_name); + goto end; + } + + cur_path_stack_pop(ctx); + } end: - if (name_buf) { - g_string_free(name_buf, TRUE); - } + if (name_buf) { + g_string_free(name_buf, TRUE); + } - bt_value_put_ref(prot_opt_names); - return ret; + bt_value_put_ref(prot_opt_names); + return ret; } -static inline -int translate_static_array_field_class(struct ctx *ctx) +static inline int translate_static_array_field_class(struct ctx *ctx) { - struct fs_sink_ctf_field_class_array *fc = - fs_sink_ctf_field_class_array_create_empty( - cur_path_stack_top(ctx)->ir_fc, - cur_path_stack_top(ctx)->index_in_parent); - const bt_field_class *elem_ir_fc = - bt_field_class_array_borrow_element_field_class_const( - fc->base.base.ir_fc); - int ret; - - BT_ASSERT(fc); - append_to_parent_field_class(ctx, &fc->base.base); - ret = cur_path_stack_push(ctx, UINT64_C(-1), NULL, false, elem_ir_fc, - &fc->base.base); - if (ret) { - BT_COMP_LOGE_STR("Cannot translate static array field class element."); - goto end; - } - - ret = translate_field_class(ctx); - if (ret) { - BT_COMP_LOGE_STR("Cannot translate static array field class element."); - goto end; - } - - cur_path_stack_pop(ctx); - update_parent_field_class_alignment(ctx, fc->base.base.alignment); + struct fs_sink_ctf_field_class_array *fc = fs_sink_ctf_field_class_array_create_empty( + cur_path_stack_top(ctx)->ir_fc, cur_path_stack_top(ctx)->index_in_parent); + const bt_field_class *elem_ir_fc = + bt_field_class_array_borrow_element_field_class_const(fc->base.base.ir_fc); + int ret; + + BT_ASSERT(fc); + append_to_parent_field_class(ctx, &fc->base.base); + ret = cur_path_stack_push(ctx, UINT64_C(-1), NULL, false, elem_ir_fc, &fc->base.base); + if (ret) { + BT_COMP_LOGE_STR("Cannot translate static array field class element."); + goto end; + } + + ret = translate_field_class(ctx); + if (ret) { + BT_COMP_LOGE_STR("Cannot translate static array field class element."); + goto end; + } + + cur_path_stack_pop(ctx); + update_parent_field_class_alignment(ctx, fc->base.base.alignment); end: - return ret; + return ret; } -static inline -int translate_dynamic_array_field_class(struct ctx *ctx) +static inline int translate_dynamic_array_field_class(struct ctx *ctx) { - struct fs_sink_ctf_field_class_sequence *fc = - fs_sink_ctf_field_class_sequence_create_empty( - cur_path_stack_top(ctx)->ir_fc, - cur_path_stack_top(ctx)->index_in_parent); - const bt_field_class *elem_ir_fc = - bt_field_class_array_borrow_element_field_class_const( - fc->base.base.ir_fc); - int ret; - - BT_ASSERT(fc); - - /* Resolve length field class before appending to parent */ - if (bt_field_class_get_type(cur_path_stack_top(ctx)->ir_fc) == - BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITH_LENGTH_FIELD) { - resolve_field_class(ctx, - bt_field_class_array_dynamic_with_length_field_borrow_length_field_path_const( - fc->base.base.ir_fc), - fc->length_ref, &fc->length_is_before, NULL); - } - - append_to_parent_field_class(ctx, &fc->base.base); - ret = cur_path_stack_push(ctx, UINT64_C(-1), NULL, false, elem_ir_fc, - &fc->base.base); - if (ret) { - BT_COMP_LOGE_STR("Cannot translate dynamic array field class element."); - goto end; - } - - ret = translate_field_class(ctx); - if (ret) { - BT_COMP_LOGE_STR("Cannot translate dynamic array field class element."); - goto end; - } - - cur_path_stack_pop(ctx); - update_parent_field_class_alignment(ctx, fc->base.base.alignment); + struct fs_sink_ctf_field_class_sequence *fc = fs_sink_ctf_field_class_sequence_create_empty( + cur_path_stack_top(ctx)->ir_fc, cur_path_stack_top(ctx)->index_in_parent); + const bt_field_class *elem_ir_fc = + bt_field_class_array_borrow_element_field_class_const(fc->base.base.ir_fc); + int ret; + + BT_ASSERT(fc); + + /* Resolve length field class before appending to parent */ + if (bt_field_class_get_type(cur_path_stack_top(ctx)->ir_fc) == + BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITH_LENGTH_FIELD) { + resolve_field_class( + ctx, + bt_field_class_array_dynamic_with_length_field_borrow_length_field_path_const( + fc->base.base.ir_fc), + fc->length_ref, &fc->length_is_before, NULL); + } + + append_to_parent_field_class(ctx, &fc->base.base); + ret = cur_path_stack_push(ctx, UINT64_C(-1), NULL, false, elem_ir_fc, &fc->base.base); + if (ret) { + BT_COMP_LOGE_STR("Cannot translate dynamic array field class element."); + goto end; + } + + ret = translate_field_class(ctx); + if (ret) { + BT_COMP_LOGE_STR("Cannot translate dynamic array field class element."); + goto end; + } + + cur_path_stack_pop(ctx); + update_parent_field_class_alignment(ctx, fc->base.base.alignment); end: - return ret; + return ret; } -static inline -int translate_bool_field_class(struct ctx *ctx) +static inline int translate_bool_field_class(struct ctx *ctx) { - struct fs_sink_ctf_field_class_bool *fc = - fs_sink_ctf_field_class_bool_create( - cur_path_stack_top(ctx)->ir_fc, - cur_path_stack_top(ctx)->index_in_parent); - - BT_ASSERT(fc); - append_to_parent_field_class(ctx, &fc->base.base); - return 0; + struct fs_sink_ctf_field_class_bool *fc = fs_sink_ctf_field_class_bool_create( + cur_path_stack_top(ctx)->ir_fc, cur_path_stack_top(ctx)->index_in_parent); + + BT_ASSERT(fc); + append_to_parent_field_class(ctx, &fc->base.base); + return 0; } -static inline -int translate_bit_array_field_class(struct ctx *ctx) +static inline int translate_bit_array_field_class(struct ctx *ctx) { - struct fs_sink_ctf_field_class_bit_array *fc = - fs_sink_ctf_field_class_bit_array_create( - cur_path_stack_top(ctx)->ir_fc, - cur_path_stack_top(ctx)->index_in_parent); - - BT_ASSERT(fc); - append_to_parent_field_class(ctx, &fc->base); - return 0; + struct fs_sink_ctf_field_class_bit_array *fc = fs_sink_ctf_field_class_bit_array_create( + cur_path_stack_top(ctx)->ir_fc, cur_path_stack_top(ctx)->index_in_parent); + + BT_ASSERT(fc); + append_to_parent_field_class(ctx, &fc->base); + return 0; } -static inline -int translate_integer_field_class(struct ctx *ctx) +static inline int translate_integer_field_class(struct ctx *ctx) { - struct fs_sink_ctf_field_class_int *fc = - fs_sink_ctf_field_class_int_create( - cur_path_stack_top(ctx)->ir_fc, - cur_path_stack_top(ctx)->index_in_parent); - - BT_ASSERT(fc); - append_to_parent_field_class(ctx, &fc->base.base); - return 0; + struct fs_sink_ctf_field_class_int *fc = fs_sink_ctf_field_class_int_create( + cur_path_stack_top(ctx)->ir_fc, cur_path_stack_top(ctx)->index_in_parent); + + BT_ASSERT(fc); + append_to_parent_field_class(ctx, &fc->base.base); + return 0; } -static inline -int translate_real_field_class(struct ctx *ctx) +static inline int translate_real_field_class(struct ctx *ctx) { - struct fs_sink_ctf_field_class_float *fc = - fs_sink_ctf_field_class_float_create( - cur_path_stack_top(ctx)->ir_fc, - cur_path_stack_top(ctx)->index_in_parent); - - BT_ASSERT(fc); - append_to_parent_field_class(ctx, &fc->base.base); - return 0; + struct fs_sink_ctf_field_class_float *fc = fs_sink_ctf_field_class_float_create( + cur_path_stack_top(ctx)->ir_fc, cur_path_stack_top(ctx)->index_in_parent); + + BT_ASSERT(fc); + append_to_parent_field_class(ctx, &fc->base.base); + return 0; } -static inline -int translate_string_field_class(struct ctx *ctx) +static inline int translate_string_field_class(struct ctx *ctx) { - struct fs_sink_ctf_field_class_string *fc = - fs_sink_ctf_field_class_string_create( - cur_path_stack_top(ctx)->ir_fc, - cur_path_stack_top(ctx)->index_in_parent); - - BT_ASSERT(fc); - append_to_parent_field_class(ctx, &fc->base); - return 0; + struct fs_sink_ctf_field_class_string *fc = fs_sink_ctf_field_class_string_create( + cur_path_stack_top(ctx)->ir_fc, cur_path_stack_top(ctx)->index_in_parent); + + BT_ASSERT(fc); + append_to_parent_field_class(ctx, &fc->base); + return 0; } /* @@ -1292,156 +1168,142 @@ int translate_string_field_class(struct ctx *ctx) * within its parent are in the context's current path's top element * (cur_path_stack_top()). */ -static -int translate_field_class(struct ctx *ctx) +static int translate_field_class(struct ctx *ctx) { - int ret; - bt_field_class_type ir_fc_type = - bt_field_class_get_type(cur_path_stack_top(ctx)->ir_fc); - - if (ir_fc_type == BT_FIELD_CLASS_TYPE_BOOL) { - ret = translate_bool_field_class(ctx); - } else if (ir_fc_type == BT_FIELD_CLASS_TYPE_BIT_ARRAY) { - ret = translate_bit_array_field_class(ctx); - } else if (bt_field_class_type_is(ir_fc_type, - BT_FIELD_CLASS_TYPE_INTEGER)) { - ret = translate_integer_field_class(ctx); - } else if (bt_field_class_type_is(ir_fc_type, - BT_FIELD_CLASS_TYPE_REAL)) { - ret = translate_real_field_class(ctx); - } else if (ir_fc_type == BT_FIELD_CLASS_TYPE_STRING) { - ret = translate_string_field_class(ctx); - } else if (ir_fc_type == BT_FIELD_CLASS_TYPE_STRUCTURE) { - ret = translate_structure_field_class(ctx); - } else if (ir_fc_type == BT_FIELD_CLASS_TYPE_STATIC_ARRAY) { - ret = translate_static_array_field_class(ctx); - } else if (bt_field_class_type_is(ir_fc_type, - BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY)) { - ret = translate_dynamic_array_field_class(ctx); - } else if (bt_field_class_type_is(ir_fc_type, - BT_FIELD_CLASS_TYPE_OPTION)) { - ret = translate_option_field_class(ctx); - } else if (bt_field_class_type_is(ir_fc_type, - BT_FIELD_CLASS_TYPE_VARIANT)) { - ret = translate_variant_field_class(ctx); - } else { - bt_common_abort(); - } - - return ret; + int ret; + bt_field_class_type ir_fc_type = bt_field_class_get_type(cur_path_stack_top(ctx)->ir_fc); + + if (ir_fc_type == BT_FIELD_CLASS_TYPE_BOOL) { + ret = translate_bool_field_class(ctx); + } else if (ir_fc_type == BT_FIELD_CLASS_TYPE_BIT_ARRAY) { + ret = translate_bit_array_field_class(ctx); + } else if (bt_field_class_type_is(ir_fc_type, BT_FIELD_CLASS_TYPE_INTEGER)) { + ret = translate_integer_field_class(ctx); + } else if (bt_field_class_type_is(ir_fc_type, BT_FIELD_CLASS_TYPE_REAL)) { + ret = translate_real_field_class(ctx); + } else if (ir_fc_type == BT_FIELD_CLASS_TYPE_STRING) { + ret = translate_string_field_class(ctx); + } else if (ir_fc_type == BT_FIELD_CLASS_TYPE_STRUCTURE) { + ret = translate_structure_field_class(ctx); + } else if (ir_fc_type == BT_FIELD_CLASS_TYPE_STATIC_ARRAY) { + ret = translate_static_array_field_class(ctx); + } else if (bt_field_class_type_is(ir_fc_type, BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY)) { + ret = translate_dynamic_array_field_class(ctx); + } else if (bt_field_class_type_is(ir_fc_type, BT_FIELD_CLASS_TYPE_OPTION)) { + ret = translate_option_field_class(ctx); + } else if (bt_field_class_type_is(ir_fc_type, BT_FIELD_CLASS_TYPE_VARIANT)) { + ret = translate_variant_field_class(ctx); + } else { + bt_common_abort(); + } + + return ret; } -static -int set_field_ref(struct fs_sink_ctf_field_class *fc, const char *fc_name, - struct fs_sink_ctf_field_class *parent_fc) +static int set_field_ref(struct fs_sink_ctf_field_class *fc, const char *fc_name, + struct fs_sink_ctf_field_class *parent_fc) { - int ret = 0; - GString *field_ref = NULL; - bool is_before; - const char *tgt_type; - struct fs_sink_ctf_field_class_struct *parent_struct_fc = - fs_sink_ctf_field_class_as_struct(parent_fc); - uint64_t i; - unsigned int suffix = 0; - - if (!fc_name || !parent_fc || - parent_fc->type != FS_SINK_CTF_FIELD_CLASS_TYPE_STRUCT) { - /* Not supported */ - ret = -1; - goto end; - } - - switch (fc->type) { - case FS_SINK_CTF_FIELD_CLASS_TYPE_OPTION: - { - /* - * CTF 1.8 does not support the option field class type. - * To write something anyway, this component translates - * this type to a variant field class where the options - * are: - * - * * An empty structure field class. - * * The optional field class itself. - * - * Because the option field class becomes a CTF variant - * field class, we use the term "tag" too here. - * - * The "tag" is always generated/before in that case (an - * 8-bit unsigned enumeration field class). - */ - struct fs_sink_ctf_field_class_option *opt_fc = - fs_sink_ctf_field_class_as_option(fc); - - field_ref = opt_fc->tag_ref; - is_before = true; - tgt_type = "tag"; - break; - } - case FS_SINK_CTF_FIELD_CLASS_TYPE_SEQUENCE: - { - struct fs_sink_ctf_field_class_sequence *seq_fc = - fs_sink_ctf_field_class_as_sequence(fc); - - field_ref = seq_fc->length_ref; - is_before = seq_fc->length_is_before; - tgt_type = "len"; - break; - } - case FS_SINK_CTF_FIELD_CLASS_TYPE_VARIANT: - { - struct fs_sink_ctf_field_class_variant *var_fc = - fs_sink_ctf_field_class_as_variant(fc); - - field_ref = var_fc->tag_ref; - is_before = var_fc->tag_is_before; - tgt_type = "tag"; - break; - } - default: - bt_common_abort(); - } - - BT_ASSERT(field_ref); - - if (!is_before) { - goto end; - } - - /* Initial field ref */ - g_string_printf(field_ref, "__%s_%s", fc_name, tgt_type); - - /* - * Make sure field ref does not clash with an existing field - * class name within the same parent structure field class. - */ - while (true) { - bool name_ok = true; - - for (i = 0; i < parent_struct_fc->members->len; i++) { - struct fs_sink_ctf_named_field_class *named_fc = - fs_sink_ctf_field_class_struct_borrow_member_by_index( - parent_struct_fc, i); - - if (strcmp(field_ref->str, named_fc->name->str) == 0) { - /* Name clash */ - name_ok = false; - break; - } - } - - if (name_ok) { - /* No clash: we're done */ - break; - } - - /* Append suffix and try again */ - g_string_printf(field_ref, "__%s_%s_%u", fc_name, tgt_type, - suffix); - suffix++; - } + int ret = 0; + GString *field_ref = NULL; + bool is_before; + const char *tgt_type; + struct fs_sink_ctf_field_class_struct *parent_struct_fc = + fs_sink_ctf_field_class_as_struct(parent_fc); + uint64_t i; + unsigned int suffix = 0; + + if (!fc_name || !parent_fc || parent_fc->type != FS_SINK_CTF_FIELD_CLASS_TYPE_STRUCT) { + /* Not supported */ + ret = -1; + goto end; + } + + switch (fc->type) { + case FS_SINK_CTF_FIELD_CLASS_TYPE_OPTION: + { + /* + * CTF 1.8 does not support the option field class type. + * To write something anyway, this component translates + * this type to a variant field class where the options + * are: + * + * * An empty structure field class. + * * The optional field class itself. + * + * Because the option field class becomes a CTF variant + * field class, we use the term "tag" too here. + * + * The "tag" is always generated/before in that case (an + * 8-bit unsigned enumeration field class). + */ + struct fs_sink_ctf_field_class_option *opt_fc = fs_sink_ctf_field_class_as_option(fc); + + field_ref = opt_fc->tag_ref; + is_before = true; + tgt_type = "tag"; + break; + } + case FS_SINK_CTF_FIELD_CLASS_TYPE_SEQUENCE: + { + struct fs_sink_ctf_field_class_sequence *seq_fc = fs_sink_ctf_field_class_as_sequence(fc); + + field_ref = seq_fc->length_ref; + is_before = seq_fc->length_is_before; + tgt_type = "len"; + break; + } + case FS_SINK_CTF_FIELD_CLASS_TYPE_VARIANT: + { + struct fs_sink_ctf_field_class_variant *var_fc = fs_sink_ctf_field_class_as_variant(fc); + + field_ref = var_fc->tag_ref; + is_before = var_fc->tag_is_before; + tgt_type = "tag"; + break; + } + default: + bt_common_abort(); + } + + BT_ASSERT(field_ref); + + if (!is_before) { + goto end; + } + + /* Initial field ref */ + g_string_printf(field_ref, "__%s_%s", fc_name, tgt_type); + + /* + * Make sure field ref does not clash with an existing field + * class name within the same parent structure field class. + */ + while (true) { + bool name_ok = true; + + for (i = 0; i < parent_struct_fc->members->len; i++) { + struct fs_sink_ctf_named_field_class *named_fc = + fs_sink_ctf_field_class_struct_borrow_member_by_index(parent_struct_fc, i); + + if (strcmp(field_ref->str, named_fc->name->str) == 0) { + /* Name clash */ + name_ok = false; + break; + } + } + + if (name_ok) { + /* No clash: we're done */ + break; + } + + /* Append suffix and try again */ + g_string_printf(field_ref, "__%s_%s_%u", fc_name, tgt_type, suffix); + suffix++; + } end: - return ret; + return ret; } /* @@ -1455,99 +1317,94 @@ end: * location to place the length field class immediately before the * sequence field class. */ -static -int set_field_refs(struct fs_sink_ctf_field_class * const fc, - const char *fc_name, struct fs_sink_ctf_field_class *parent_fc) +static int set_field_refs(struct fs_sink_ctf_field_class * const fc, const char *fc_name, + struct fs_sink_ctf_field_class *parent_fc) { - int ret = 0; - enum fs_sink_ctf_field_class_type fc_type; - BT_ASSERT(fc); - - fc_type = fc->type; - - switch (fc_type) { - case FS_SINK_CTF_FIELD_CLASS_TYPE_OPTION: - { - struct fs_sink_ctf_field_class_option *opt_fc = - fs_sink_ctf_field_class_as_option(fc); - - ret = set_field_ref(fc, fc_name, parent_fc); - if (ret) { - goto end; - } - - ret = set_field_refs(opt_fc->content_fc, NULL, fc); - if (ret) { - goto end; - } - - break; - } - case FS_SINK_CTF_FIELD_CLASS_TYPE_STRUCT: - case FS_SINK_CTF_FIELD_CLASS_TYPE_VARIANT: - { - uint64_t i; - uint64_t len; - struct fs_sink_ctf_field_class_struct *struct_fc = NULL; - struct fs_sink_ctf_field_class_variant *var_fc = NULL; - struct fs_sink_ctf_named_field_class *named_fc; - - if (fc_type == FS_SINK_CTF_FIELD_CLASS_TYPE_STRUCT) { - struct_fc = fs_sink_ctf_field_class_as_struct(fc); - len = struct_fc->members->len; - } else { - var_fc = fs_sink_ctf_field_class_as_variant(fc); - len = var_fc->options->len; - ret = set_field_ref(fc, fc_name, parent_fc); - if (ret) { - goto end; - } - } - - for (i = 0; i < len; i++) { - if (fc_type == FS_SINK_CTF_FIELD_CLASS_TYPE_STRUCT) { - named_fc = fs_sink_ctf_field_class_struct_borrow_member_by_index( - struct_fc, i); - } else { - named_fc = fs_sink_ctf_field_class_variant_borrow_option_by_index( - var_fc, i); - } - - ret = set_field_refs(named_fc->fc, named_fc->name->str, - fc); - if (ret) { - goto end; - } - } - - break; - } - case FS_SINK_CTF_FIELD_CLASS_TYPE_ARRAY: - case FS_SINK_CTF_FIELD_CLASS_TYPE_SEQUENCE: - { - struct fs_sink_ctf_field_class_array_base *array_base_fc = - fs_sink_ctf_field_class_as_array_base(fc); - - if (fc_type == FS_SINK_CTF_FIELD_CLASS_TYPE_SEQUENCE) { - ret = set_field_ref(fc, fc_name, parent_fc); - if (ret) { - goto end; - } - } - - ret = set_field_refs(array_base_fc->elem_fc, NULL, fc); - if (ret) { - goto end; - } - - break; - } - default: - break; - } + int ret = 0; + enum fs_sink_ctf_field_class_type fc_type; + BT_ASSERT(fc); + + fc_type = fc->type; + + switch (fc_type) { + case FS_SINK_CTF_FIELD_CLASS_TYPE_OPTION: + { + struct fs_sink_ctf_field_class_option *opt_fc = fs_sink_ctf_field_class_as_option(fc); + + ret = set_field_ref(fc, fc_name, parent_fc); + if (ret) { + goto end; + } + + ret = set_field_refs(opt_fc->content_fc, NULL, fc); + if (ret) { + goto end; + } + + break; + } + case FS_SINK_CTF_FIELD_CLASS_TYPE_STRUCT: + case FS_SINK_CTF_FIELD_CLASS_TYPE_VARIANT: + { + uint64_t i; + uint64_t len; + struct fs_sink_ctf_field_class_struct *struct_fc = NULL; + struct fs_sink_ctf_field_class_variant *var_fc = NULL; + struct fs_sink_ctf_named_field_class *named_fc; + + if (fc_type == FS_SINK_CTF_FIELD_CLASS_TYPE_STRUCT) { + struct_fc = fs_sink_ctf_field_class_as_struct(fc); + len = struct_fc->members->len; + } else { + var_fc = fs_sink_ctf_field_class_as_variant(fc); + len = var_fc->options->len; + ret = set_field_ref(fc, fc_name, parent_fc); + if (ret) { + goto end; + } + } + + for (i = 0; i < len; i++) { + if (fc_type == FS_SINK_CTF_FIELD_CLASS_TYPE_STRUCT) { + named_fc = fs_sink_ctf_field_class_struct_borrow_member_by_index(struct_fc, i); + } else { + named_fc = fs_sink_ctf_field_class_variant_borrow_option_by_index(var_fc, i); + } + + ret = set_field_refs(named_fc->fc, named_fc->name->str, fc); + if (ret) { + goto end; + } + } + + break; + } + case FS_SINK_CTF_FIELD_CLASS_TYPE_ARRAY: + case FS_SINK_CTF_FIELD_CLASS_TYPE_SEQUENCE: + { + struct fs_sink_ctf_field_class_array_base *array_base_fc = + fs_sink_ctf_field_class_as_array_base(fc); + + if (fc_type == FS_SINK_CTF_FIELD_CLASS_TYPE_SEQUENCE) { + ret = set_field_ref(fc, fc_name, parent_fc); + if (ret) { + goto end; + } + } + + ret = set_field_refs(array_base_fc->elem_fc, NULL, fc); + if (ret) { + goto end; + } + + break; + } + default: + break; + } end: - return ret; + return ret; } /* @@ -1561,327 +1418,301 @@ end: * class and then calls translate_structure_field_class_members() to * fill it. */ -static -int translate_scope_field_class(struct ctx *ctx, bt_field_path_scope scope, - struct fs_sink_ctf_field_class **fc, - const bt_field_class *ir_fc) +static int translate_scope_field_class(struct ctx *ctx, bt_field_path_scope scope, + struct fs_sink_ctf_field_class **fc, + const bt_field_class *ir_fc) { - int ret = 0; - - if (!ir_fc) { - goto end; - } - - BT_ASSERT(bt_field_class_get_type(ir_fc) == - BT_FIELD_CLASS_TYPE_STRUCTURE); - BT_ASSERT(fc); - *fc = &fs_sink_ctf_field_class_struct_create_empty( - ir_fc, UINT64_C(-1))->base; - BT_ASSERT(*fc); - ctx->cur_scope = scope; - BT_ASSERT(ctx->cur_path->len == 0); - ret = cur_path_stack_push(ctx, UINT64_C(-1), NULL, false, ir_fc, NULL); - if (ret) { - BT_COMP_LOGE("Cannot translate scope structure field class: " - "scope=%d", scope); - goto end; - } - - ret = translate_structure_field_class_members(ctx, - fs_sink_ctf_field_class_as_struct(*fc), ir_fc); - if (ret) { - BT_COMP_LOGE("Cannot translate scope structure field class: " - "scope=%d", scope); - goto end; - } - - cur_path_stack_pop(ctx); - - /* Set field refs for preceding targets */ - ret = set_field_refs(*fc, NULL, NULL); + int ret = 0; + + if (!ir_fc) { + goto end; + } + + BT_ASSERT(bt_field_class_get_type(ir_fc) == BT_FIELD_CLASS_TYPE_STRUCTURE); + BT_ASSERT(fc); + *fc = &fs_sink_ctf_field_class_struct_create_empty(ir_fc, UINT64_C(-1))->base; + BT_ASSERT(*fc); + ctx->cur_scope = scope; + BT_ASSERT(ctx->cur_path->len == 0); + ret = cur_path_stack_push(ctx, UINT64_C(-1), NULL, false, ir_fc, NULL); + if (ret) { + BT_COMP_LOGE("Cannot translate scope structure field class: " + "scope=%d", + scope); + goto end; + } + + ret = + translate_structure_field_class_members(ctx, fs_sink_ctf_field_class_as_struct(*fc), ir_fc); + if (ret) { + BT_COMP_LOGE("Cannot translate scope structure field class: " + "scope=%d", + scope); + goto end; + } + + cur_path_stack_pop(ctx); + + /* Set field refs for preceding targets */ + ret = set_field_refs(*fc, NULL, NULL); end: - return ret; + return ret; } -static inline -void ctx_init(struct ctx *ctx, struct fs_sink_comp *fs_sink) +static inline void ctx_init(struct ctx *ctx, struct fs_sink_comp *fs_sink) { - memset(ctx, 0, sizeof(struct ctx)); - ctx->cur_path = g_array_new(FALSE, TRUE, - sizeof(struct field_path_elem)); - BT_ASSERT(ctx->cur_path); - ctx->log_level = fs_sink->log_level; - ctx->self_comp = fs_sink->self_comp; + memset(ctx, 0, sizeof(struct ctx)); + ctx->cur_path = g_array_new(FALSE, TRUE, sizeof(struct field_path_elem)); + BT_ASSERT(ctx->cur_path); + ctx->log_level = fs_sink->log_level; + ctx->self_comp = fs_sink->self_comp; } -static inline -void ctx_fini(struct ctx *ctx) +static inline void ctx_fini(struct ctx *ctx) { - if (ctx->cur_path) { - g_array_free(ctx->cur_path, TRUE); - ctx->cur_path = NULL; - } + if (ctx->cur_path) { + g_array_free(ctx->cur_path, TRUE); + ctx->cur_path = NULL; + } } -static -int translate_event_class(struct fs_sink_comp *fs_sink, - struct fs_sink_ctf_stream_class *sc, - const bt_event_class *ir_ec, - struct fs_sink_ctf_event_class **out_ec) +static int translate_event_class(struct fs_sink_comp *fs_sink, struct fs_sink_ctf_stream_class *sc, + const bt_event_class *ir_ec, + struct fs_sink_ctf_event_class **out_ec) { - int ret = 0; - struct ctx ctx; - struct fs_sink_ctf_event_class *ec; - - BT_ASSERT(sc); - BT_ASSERT(ir_ec); - - ctx_init(&ctx, fs_sink); - ec = fs_sink_ctf_event_class_create(sc, ir_ec); - BT_ASSERT(ec); - ctx.cur_sc = sc; - ctx.cur_ec = ec; - ret = translate_scope_field_class(&ctx, BT_FIELD_PATH_SCOPE_EVENT_SPECIFIC_CONTEXT, - &ec->spec_context_fc, - bt_event_class_borrow_specific_context_field_class_const( - ir_ec)); - if (ret) { - goto end; - } - - ret = translate_scope_field_class(&ctx, BT_FIELD_PATH_SCOPE_EVENT_PAYLOAD, - &ec->payload_fc, - bt_event_class_borrow_payload_field_class_const(ir_ec)); - if (ret) { - goto end; - } + int ret = 0; + struct ctx ctx; + struct fs_sink_ctf_event_class *ec; + + BT_ASSERT(sc); + BT_ASSERT(ir_ec); + + ctx_init(&ctx, fs_sink); + ec = fs_sink_ctf_event_class_create(sc, ir_ec); + BT_ASSERT(ec); + ctx.cur_sc = sc; + ctx.cur_ec = ec; + ret = translate_scope_field_class( + &ctx, BT_FIELD_PATH_SCOPE_EVENT_SPECIFIC_CONTEXT, &ec->spec_context_fc, + bt_event_class_borrow_specific_context_field_class_const(ir_ec)); + if (ret) { + goto end; + } + + ret = translate_scope_field_class(&ctx, BT_FIELD_PATH_SCOPE_EVENT_PAYLOAD, &ec->payload_fc, + bt_event_class_borrow_payload_field_class_const(ir_ec)); + if (ret) { + goto end; + } end: - ctx_fini(&ctx); - *out_ec = ec; - return ret; + ctx_fini(&ctx); + *out_ec = ec; + return ret; } BT_HIDDEN -int try_translate_event_class_trace_ir_to_ctf_ir( - struct fs_sink_comp *fs_sink, - struct fs_sink_ctf_stream_class *sc, - const bt_event_class *ir_ec, - struct fs_sink_ctf_event_class **out_ec) +int try_translate_event_class_trace_ir_to_ctf_ir(struct fs_sink_comp *fs_sink, + struct fs_sink_ctf_stream_class *sc, + const bt_event_class *ir_ec, + struct fs_sink_ctf_event_class **out_ec) { - int ret = 0; + int ret = 0; - BT_ASSERT(sc); - BT_ASSERT(ir_ec); + BT_ASSERT(sc); + BT_ASSERT(ir_ec); - /* Check in hash table first */ - *out_ec = (fs_sink_ctf_event_class *) g_hash_table_lookup( - sc->event_classes_from_ir, ir_ec); - if (G_LIKELY(*out_ec)) { - goto end; - } + /* Check in hash table first */ + *out_ec = (fs_sink_ctf_event_class *) g_hash_table_lookup(sc->event_classes_from_ir, ir_ec); + if (G_LIKELY(*out_ec)) { + goto end; + } - ret = translate_event_class(fs_sink, sc, ir_ec, out_ec); + ret = translate_event_class(fs_sink, sc, ir_ec, out_ec); end: - return ret; + return ret; } -static -bool default_clock_class_name_exists(struct fs_sink_ctf_trace *trace, - const char *name) +static bool default_clock_class_name_exists(struct fs_sink_ctf_trace *trace, const char *name) { - bool exists = false; - uint64_t i; + bool exists = false; + uint64_t i; - for (i = 0; i < trace->stream_classes->len; i++) { - struct fs_sink_ctf_stream_class *sc = - (fs_sink_ctf_stream_class *) trace->stream_classes->pdata[i]; + for (i = 0; i < trace->stream_classes->len; i++) { + struct fs_sink_ctf_stream_class *sc = + (fs_sink_ctf_stream_class *) trace->stream_classes->pdata[i]; - if (sc->default_clock_class_name->len == 0) { - /* No default clock class */ - continue; - } + if (sc->default_clock_class_name->len == 0) { + /* No default clock class */ + continue; + } - if (strcmp(sc->default_clock_class_name->str, name) == 0) { - exists = true; - goto end; - } - } + if (strcmp(sc->default_clock_class_name->str, name) == 0) { + exists = true; + goto end; + } + } end: - return exists; + return exists; } -static -void make_unique_default_clock_class_name(struct fs_sink_ctf_stream_class *sc) +static void make_unique_default_clock_class_name(struct fs_sink_ctf_stream_class *sc) { - unsigned int suffix = 0; - char buf[16]; + unsigned int suffix = 0; + char buf[16]; - g_string_assign(sc->default_clock_class_name, ""); - sprintf(buf, "default"); + g_string_assign(sc->default_clock_class_name, ""); + sprintf(buf, "default"); - while (default_clock_class_name_exists(sc->trace, buf)) { - sprintf(buf, "default%u", suffix); - suffix++; - } + while (default_clock_class_name_exists(sc->trace, buf)) { + sprintf(buf, "default%u", suffix); + suffix++; + } - g_string_assign(sc->default_clock_class_name, buf); + g_string_assign(sc->default_clock_class_name, buf); } -static -int translate_stream_class(struct fs_sink_comp *fs_sink, - struct fs_sink_ctf_trace *trace, - const bt_stream_class *ir_sc, - struct fs_sink_ctf_stream_class **out_sc) +static int translate_stream_class(struct fs_sink_comp *fs_sink, struct fs_sink_ctf_trace *trace, + const bt_stream_class *ir_sc, + struct fs_sink_ctf_stream_class **out_sc) { - int ret = 0; - struct ctx ctx; - - BT_ASSERT(trace); - BT_ASSERT(ir_sc); - ctx_init(&ctx, fs_sink); - *out_sc = fs_sink_ctf_stream_class_create(trace, ir_sc); - BT_ASSERT(*out_sc); - - /* Set default clock class's protected name, if any */ - if ((*out_sc)->default_clock_class) { - const char *name = bt_clock_class_get_name( - (*out_sc)->default_clock_class); - - if (name) { - /* Try original name, protected */ - g_string_assign((*out_sc)->default_clock_class_name, - ""); - - if (must_protect_identifier(name)) { - g_string_assign( - (*out_sc)->default_clock_class_name, - "_"); - } - - g_string_assign((*out_sc)->default_clock_class_name, - name); - if (!ist_valid_identifier( - (*out_sc)->default_clock_class_name->str)) { - /* Invalid: create a new name */ - make_unique_default_clock_class_name(*out_sc); - } - } else { - /* No name: create a name */ - make_unique_default_clock_class_name(*out_sc); - } - } - - ctx.cur_sc = *out_sc; - ret = translate_scope_field_class(&ctx, BT_FIELD_PATH_SCOPE_PACKET_CONTEXT, - &(*out_sc)->packet_context_fc, - bt_stream_class_borrow_packet_context_field_class_const(ir_sc)); - if (ret) { - goto error; - } - - if ((*out_sc)->packet_context_fc) { - /* - * Make sure the structure field class's alignment is - * enough: 8 is what we use for our own special members - * in the packet context. - */ - fs_sink_ctf_field_class_struct_align_at_least( - fs_sink_ctf_field_class_as_struct((*out_sc)->packet_context_fc), 8); - } - - ret = translate_scope_field_class(&ctx, BT_FIELD_PATH_SCOPE_EVENT_COMMON_CONTEXT, - &(*out_sc)->event_common_context_fc, - bt_stream_class_borrow_event_common_context_field_class_const( - ir_sc)); - if (ret) { - goto error; - } - - goto end; + int ret = 0; + struct ctx ctx; + + BT_ASSERT(trace); + BT_ASSERT(ir_sc); + ctx_init(&ctx, fs_sink); + *out_sc = fs_sink_ctf_stream_class_create(trace, ir_sc); + BT_ASSERT(*out_sc); + + /* Set default clock class's protected name, if any */ + if ((*out_sc)->default_clock_class) { + const char *name = bt_clock_class_get_name((*out_sc)->default_clock_class); + + if (name) { + /* Try original name, protected */ + g_string_assign((*out_sc)->default_clock_class_name, ""); + + if (must_protect_identifier(name)) { + g_string_assign((*out_sc)->default_clock_class_name, "_"); + } + + g_string_assign((*out_sc)->default_clock_class_name, name); + if (!ist_valid_identifier((*out_sc)->default_clock_class_name->str)) { + /* Invalid: create a new name */ + make_unique_default_clock_class_name(*out_sc); + } + } else { + /* No name: create a name */ + make_unique_default_clock_class_name(*out_sc); + } + } + + ctx.cur_sc = *out_sc; + ret = translate_scope_field_class( + &ctx, BT_FIELD_PATH_SCOPE_PACKET_CONTEXT, &(*out_sc)->packet_context_fc, + bt_stream_class_borrow_packet_context_field_class_const(ir_sc)); + if (ret) { + goto error; + } + + if ((*out_sc)->packet_context_fc) { + /* + * Make sure the structure field class's alignment is + * enough: 8 is what we use for our own special members + * in the packet context. + */ + fs_sink_ctf_field_class_struct_align_at_least( + fs_sink_ctf_field_class_as_struct((*out_sc)->packet_context_fc), 8); + } + + ret = translate_scope_field_class( + &ctx, BT_FIELD_PATH_SCOPE_EVENT_COMMON_CONTEXT, &(*out_sc)->event_common_context_fc, + bt_stream_class_borrow_event_common_context_field_class_const(ir_sc)); + if (ret) { + goto error; + } + + goto end; error: - fs_sink_ctf_stream_class_destroy(*out_sc); - *out_sc = NULL; + fs_sink_ctf_stream_class_destroy(*out_sc); + *out_sc = NULL; end: - ctx_fini(&ctx); - return ret; + ctx_fini(&ctx); + return ret; } BT_HIDDEN -int try_translate_stream_class_trace_ir_to_ctf_ir( - struct fs_sink_comp *fs_sink, - struct fs_sink_ctf_trace *trace, - const bt_stream_class *ir_sc, - struct fs_sink_ctf_stream_class **out_sc) +int try_translate_stream_class_trace_ir_to_ctf_ir(struct fs_sink_comp *fs_sink, + struct fs_sink_ctf_trace *trace, + const bt_stream_class *ir_sc, + struct fs_sink_ctf_stream_class **out_sc) { - int ret = 0; - uint64_t i; + int ret = 0; + uint64_t i; - BT_ASSERT(trace); - BT_ASSERT(ir_sc); + BT_ASSERT(trace); + BT_ASSERT(ir_sc); - for (i = 0; i < trace->stream_classes->len; i++) { - *out_sc = (fs_sink_ctf_stream_class *) trace->stream_classes->pdata[i]; + for (i = 0; i < trace->stream_classes->len; i++) { + *out_sc = (fs_sink_ctf_stream_class *) trace->stream_classes->pdata[i]; - if ((*out_sc)->ir_sc == ir_sc) { - goto end; - } - } + if ((*out_sc)->ir_sc == ir_sc) { + goto end; + } + } - ret = translate_stream_class(fs_sink, trace, ir_sc, out_sc); + ret = translate_stream_class(fs_sink, trace, ir_sc, out_sc); end: - return ret; + return ret; } BT_HIDDEN -struct fs_sink_ctf_trace *translate_trace_trace_ir_to_ctf_ir( - struct fs_sink_comp *fs_sink, const bt_trace *ir_trace) +struct fs_sink_ctf_trace *translate_trace_trace_ir_to_ctf_ir(struct fs_sink_comp *fs_sink, + const bt_trace *ir_trace) { - uint64_t count; - uint64_t i; - struct fs_sink_ctf_trace *trace = NULL; - - /* Check that trace's environment is TSDL-compatible */ - count = bt_trace_get_environment_entry_count(ir_trace); - for (i = 0; i < count; i++) { - const char *name; - const bt_value *val; - - bt_trace_borrow_environment_entry_by_index_const( - ir_trace, i, &name, &val); - - if (!ist_valid_identifier(name)) { - BT_COMP_LOG_CUR_LVL(BT_LOG_ERROR, fs_sink->log_level, - fs_sink->self_comp, - "Unsupported trace class's environment entry name: " - "name=\"%s\"", name); - goto end; - } - - switch (bt_value_get_type(val)) { - case BT_VALUE_TYPE_SIGNED_INTEGER: - case BT_VALUE_TYPE_STRING: - break; - default: - BT_COMP_LOG_CUR_LVL(BT_LOG_ERROR, fs_sink->log_level, - fs_sink->self_comp, - "Unsupported trace class's environment entry value type: " - "type=%s", - bt_common_value_type_string( - bt_value_get_type(val))); - goto end; - } - } - - trace = fs_sink_ctf_trace_create(ir_trace); - BT_ASSERT(trace); + uint64_t count; + uint64_t i; + struct fs_sink_ctf_trace *trace = NULL; + + /* Check that trace's environment is TSDL-compatible */ + count = bt_trace_get_environment_entry_count(ir_trace); + for (i = 0; i < count; i++) { + const char *name; + const bt_value *val; + + bt_trace_borrow_environment_entry_by_index_const(ir_trace, i, &name, &val); + + if (!ist_valid_identifier(name)) { + BT_COMP_LOG_CUR_LVL(BT_LOG_ERROR, fs_sink->log_level, fs_sink->self_comp, + "Unsupported trace class's environment entry name: " + "name=\"%s\"", + name); + goto end; + } + + switch (bt_value_get_type(val)) { + case BT_VALUE_TYPE_SIGNED_INTEGER: + case BT_VALUE_TYPE_STRING: + break; + default: + BT_COMP_LOG_CUR_LVL(BT_LOG_ERROR, fs_sink->log_level, fs_sink->self_comp, + "Unsupported trace class's environment entry value type: " + "type=%s", + bt_common_value_type_string(bt_value_get_type(val))); + goto end; + } + } + + trace = fs_sink_ctf_trace_create(ir_trace); + BT_ASSERT(trace); end: - return trace; + return trace; } diff --git a/src/plugins/ctf/fs-sink/translate-trace-ir-to-ctf-ir.hpp b/src/plugins/ctf/fs-sink/translate-trace-ir-to-ctf-ir.hpp index 76213de1..a1c7312a 100644 --- a/src/plugins/ctf/fs-sink/translate-trace-ir-to-ctf-ir.hpp +++ b/src/plugins/ctf/fs-sink/translate-trace-ir-to-ctf-ir.hpp @@ -14,21 +14,19 @@ #include "fs-sink-ctf-meta.hpp" BT_HIDDEN -int try_translate_event_class_trace_ir_to_ctf_ir( - struct fs_sink_comp *fs_sink, - struct fs_sink_ctf_stream_class *sc, - const bt_event_class *ir_ec, - struct fs_sink_ctf_event_class **out_ec); +int try_translate_event_class_trace_ir_to_ctf_ir(struct fs_sink_comp *fs_sink, + struct fs_sink_ctf_stream_class *sc, + const bt_event_class *ir_ec, + struct fs_sink_ctf_event_class **out_ec); BT_HIDDEN -int try_translate_stream_class_trace_ir_to_ctf_ir( - struct fs_sink_comp *fs_sink, - struct fs_sink_ctf_trace *trace, - const bt_stream_class *ir_sc, - struct fs_sink_ctf_stream_class **out_sc); +int try_translate_stream_class_trace_ir_to_ctf_ir(struct fs_sink_comp *fs_sink, + struct fs_sink_ctf_trace *trace, + const bt_stream_class *ir_sc, + struct fs_sink_ctf_stream_class **out_sc); BT_HIDDEN -struct fs_sink_ctf_trace *translate_trace_trace_ir_to_ctf_ir( - struct fs_sink_comp *fs_sink, const bt_trace *ir_trace); +struct fs_sink_ctf_trace *translate_trace_trace_ir_to_ctf_ir(struct fs_sink_comp *fs_sink, + const bt_trace *ir_trace); #endif /* BABELTRACE_PLUGIN_CTF_FS_SINK_TRANSLATE_TRACE_IR_TO_CTF_IR_H */ diff --git a/src/plugins/ctf/fs-src/data-stream-file.cpp b/src/plugins/ctf/fs-src/data-stream-file.cpp index 8608ff71..f545cefc 100644 --- a/src/plugins/ctf/fs-src/data-stream-file.cpp +++ b/src/plugins/ctf/fs-src/data-stream-file.cpp @@ -7,8 +7,8 @@ */ #define BT_COMP_LOG_SELF_COMP (self_comp) -#define BT_LOG_OUTPUT_LEVEL (log_level) -#define BT_LOG_TAG "PLUGIN/SRC.CTF.FS/DS" +#define BT_LOG_OUTPUT_LEVEL (log_level) +#define BT_LOG_TAG "PLUGIN/SRC.CTF.FS/DS" #include "logging/comp-logging.h" #include @@ -28,54 +28,49 @@ #include "data-stream-file.hpp" #include -static inline -size_t remaining_mmap_bytes(struct ctf_fs_ds_file *ds_file) +static inline size_t remaining_mmap_bytes(struct ctf_fs_ds_file *ds_file) { - BT_ASSERT_DBG(ds_file->mmap_len >= ds_file->request_offset_in_mapping); - return ds_file->mmap_len - ds_file->request_offset_in_mapping; + BT_ASSERT_DBG(ds_file->mmap_len >= ds_file->request_offset_in_mapping); + return ds_file->mmap_len - ds_file->request_offset_in_mapping; } /* * Return true if `offset_in_file` is in the current mapping. */ -static -bool offset_ist_mapped(struct ctf_fs_ds_file *ds_file, off_t offset_in_file) +static bool offset_ist_mapped(struct ctf_fs_ds_file *ds_file, off_t offset_in_file) { - return offset_in_file >= ds_file->mmap_offset_in_file && - offset_in_file < (ds_file->mmap_offset_in_file + ds_file->mmap_len); + return offset_in_file >= ds_file->mmap_offset_in_file && + offset_in_file < (ds_file->mmap_offset_in_file + ds_file->mmap_len); } -static -enum ctf_msg_iter_medium_status ds_file_munmap( - struct ctf_fs_ds_file *ds_file) +static enum ctf_msg_iter_medium_status ds_file_munmap(struct ctf_fs_ds_file *ds_file) { - enum ctf_msg_iter_medium_status status; - bt_self_component *self_comp = ds_file->self_comp; - bt_logging_level log_level = ds_file->log_level; - - BT_ASSERT(ds_file); - - if (!ds_file->mmap_addr) { - status = CTF_MSG_ITER_MEDIUM_STATUS_OK; - goto end; - } - - if (bt_munmap(ds_file->mmap_addr, ds_file->mmap_len)) { - BT_COMP_LOGE_ERRNO("Cannot memory-unmap file", - ": address=%p, size=%zu, file_path=\"%s\", file=%p", - ds_file->mmap_addr, ds_file->mmap_len, - ds_file->file ? ds_file->file->path->str : "NULL", - ds_file->file ? ds_file->file->fp : NULL); - status = CTF_MSG_ITER_MEDIUM_STATUS_ERROR; - goto end; - } - - ds_file->mmap_addr = NULL; - - status = CTF_MSG_ITER_MEDIUM_STATUS_OK; + enum ctf_msg_iter_medium_status status; + bt_self_component *self_comp = ds_file->self_comp; + bt_logging_level log_level = ds_file->log_level; + + BT_ASSERT(ds_file); + + if (!ds_file->mmap_addr) { + status = CTF_MSG_ITER_MEDIUM_STATUS_OK; + goto end; + } + + if (bt_munmap(ds_file->mmap_addr, ds_file->mmap_len)) { + BT_COMP_LOGE_ERRNO("Cannot memory-unmap file", + ": address=%p, size=%zu, file_path=\"%s\", file=%p", ds_file->mmap_addr, + ds_file->mmap_len, ds_file->file ? ds_file->file->path->str : "NULL", + ds_file->file ? ds_file->file->fp : NULL); + status = CTF_MSG_ITER_MEDIUM_STATUS_ERROR; + goto end; + } + + ds_file->mmap_addr = NULL; + + status = CTF_MSG_ITER_MEDIUM_STATUS_OK; end: - return status; + return status; } /* @@ -89,64 +84,61 @@ end: * * `requested_offset_in_file` must be a valid offset in the file. */ -static -enum ctf_msg_iter_medium_status ds_file_mmap( - struct ctf_fs_ds_file *ds_file, off_t requested_offset_in_file) +static enum ctf_msg_iter_medium_status ds_file_mmap(struct ctf_fs_ds_file *ds_file, + off_t requested_offset_in_file) { - enum ctf_msg_iter_medium_status status; - bt_self_component *self_comp = ds_file->self_comp; - bt_logging_level log_level = ds_file->log_level; - - /* Ensure the requested offset is in the file range. */ - BT_ASSERT(requested_offset_in_file >= 0); - BT_ASSERT(requested_offset_in_file < ds_file->file->size); - - /* - * If the mapping already contains the requested offset, just adjust - * requested_offset_in_mapping. - */ - if (offset_ist_mapped(ds_file, requested_offset_in_file)) { - ds_file->request_offset_in_mapping = - requested_offset_in_file - ds_file->mmap_offset_in_file; - status = CTF_MSG_ITER_MEDIUM_STATUS_OK; - goto end; - } - - /* Unmap old region */ - status = ds_file_munmap(ds_file); - if (status != CTF_MSG_ITER_MEDIUM_STATUS_OK) { - goto end; - } - - /* - * Compute a mapping that has the required alignment properties and - * contains `requested_offset_in_file`. - */ - ds_file->request_offset_in_mapping = - requested_offset_in_file % bt_mmap_get_offset_align_size(ds_file->log_level); - ds_file->mmap_offset_in_file = - requested_offset_in_file - ds_file->request_offset_in_mapping; - ds_file->mmap_len = MIN(ds_file->file->size - ds_file->mmap_offset_in_file, - ds_file->mmap_max_len); - - BT_ASSERT(ds_file->mmap_len > 0); - - ds_file->mmap_addr = bt_mmap((void *) 0, ds_file->mmap_len, - PROT_READ, MAP_PRIVATE, fileno(ds_file->file->fp), - ds_file->mmap_offset_in_file, ds_file->log_level); - if (ds_file->mmap_addr == MAP_FAILED) { - BT_COMP_LOGE("Cannot memory-map address (size %zu) of file \"%s\" (%p) at offset %jd: %s", - ds_file->mmap_len, ds_file->file->path->str, - ds_file->file->fp, (intmax_t) ds_file->mmap_offset_in_file, - strerror(errno)); - status = CTF_MSG_ITER_MEDIUM_STATUS_ERROR; - goto end; - } - - status = CTF_MSG_ITER_MEDIUM_STATUS_OK; + enum ctf_msg_iter_medium_status status; + bt_self_component *self_comp = ds_file->self_comp; + bt_logging_level log_level = ds_file->log_level; + + /* Ensure the requested offset is in the file range. */ + BT_ASSERT(requested_offset_in_file >= 0); + BT_ASSERT(requested_offset_in_file < ds_file->file->size); + + /* + * If the mapping already contains the requested offset, just adjust + * requested_offset_in_mapping. + */ + if (offset_ist_mapped(ds_file, requested_offset_in_file)) { + ds_file->request_offset_in_mapping = + requested_offset_in_file - ds_file->mmap_offset_in_file; + status = CTF_MSG_ITER_MEDIUM_STATUS_OK; + goto end; + } + + /* Unmap old region */ + status = ds_file_munmap(ds_file); + if (status != CTF_MSG_ITER_MEDIUM_STATUS_OK) { + goto end; + } + + /* + * Compute a mapping that has the required alignment properties and + * contains `requested_offset_in_file`. + */ + ds_file->request_offset_in_mapping = + requested_offset_in_file % bt_mmap_get_offset_align_size(ds_file->log_level); + ds_file->mmap_offset_in_file = requested_offset_in_file - ds_file->request_offset_in_mapping; + ds_file->mmap_len = + MIN(ds_file->file->size - ds_file->mmap_offset_in_file, ds_file->mmap_max_len); + + BT_ASSERT(ds_file->mmap_len > 0); + + ds_file->mmap_addr = + bt_mmap((void *) 0, ds_file->mmap_len, PROT_READ, MAP_PRIVATE, fileno(ds_file->file->fp), + ds_file->mmap_offset_in_file, ds_file->log_level); + if (ds_file->mmap_addr == MAP_FAILED) { + BT_COMP_LOGE("Cannot memory-map address (size %zu) of file \"%s\" (%p) at offset %jd: %s", + ds_file->mmap_len, ds_file->file->path->str, ds_file->file->fp, + (intmax_t) ds_file->mmap_offset_in_file, strerror(errno)); + status = CTF_MSG_ITER_MEDIUM_STATUS_ERROR; + goto end; + } + + status = CTF_MSG_ITER_MEDIUM_STATUS_OK; end: - return status; + return status; } /* @@ -160,180 +152,164 @@ end: * return _EOF if the current mapping is the end of the file. */ -static -enum ctf_msg_iter_medium_status ds_file_mmap_next( - struct ctf_fs_ds_file *ds_file) +static enum ctf_msg_iter_medium_status ds_file_mmap_next(struct ctf_fs_ds_file *ds_file) { - enum ctf_msg_iter_medium_status status; - - /* - * If we're called, it's because more bytes are requested but we have - * given all the bytes of the current mapping. - */ - BT_ASSERT(ds_file->request_offset_in_mapping == ds_file->mmap_len); - - /* - * If the current mapping coincides with the end of the file, there is - * no next mapping. - */ - if (ds_file->mmap_offset_in_file + ds_file->mmap_len == ds_file->file->size) { - status = CTF_MSG_ITER_MEDIUM_STATUS_EOF; - goto end; - } - - status = ds_file_mmap(ds_file, - ds_file->mmap_offset_in_file + ds_file->mmap_len); + enum ctf_msg_iter_medium_status status; + + /* + * If we're called, it's because more bytes are requested but we have + * given all the bytes of the current mapping. + */ + BT_ASSERT(ds_file->request_offset_in_mapping == ds_file->mmap_len); + + /* + * If the current mapping coincides with the end of the file, there is + * no next mapping. + */ + if (ds_file->mmap_offset_in_file + ds_file->mmap_len == ds_file->file->size) { + status = CTF_MSG_ITER_MEDIUM_STATUS_EOF; + goto end; + } + + status = ds_file_mmap(ds_file, ds_file->mmap_offset_in_file + ds_file->mmap_len); end: - return status; + return status; } -static -enum ctf_msg_iter_medium_status medop_request_bytes( - size_t request_sz, uint8_t **buffer_addr, - size_t *buffer_sz, void *data) +static enum ctf_msg_iter_medium_status medop_request_bytes(size_t request_sz, uint8_t **buffer_addr, + size_t *buffer_sz, void *data) { - enum ctf_msg_iter_medium_status status = - CTF_MSG_ITER_MEDIUM_STATUS_OK; - struct ctf_fs_ds_file *ds_file = (struct ctf_fs_ds_file *) data; - bt_self_component *self_comp = ds_file->self_comp; - bt_logging_level log_level = ds_file->log_level; - - BT_ASSERT(request_sz > 0); - - /* - * Check if we have at least one memory-mapped byte left. If we don't, - * mmap the next file. - */ - if (remaining_mmap_bytes(ds_file) == 0) { - /* Are we at the end of the file? */ - if (ds_file->mmap_offset_in_file >= ds_file->file->size) { - BT_COMP_LOGD("Reached end of file \"%s\" (%p)", - ds_file->file->path->str, ds_file->file->fp); - status = CTF_MSG_ITER_MEDIUM_STATUS_EOF; - goto end; - } - - status = ds_file_mmap_next(ds_file); - switch (status) { - case CTF_MSG_ITER_MEDIUM_STATUS_OK: - break; - case CTF_MSG_ITER_MEDIUM_STATUS_EOF: - goto end; - default: - BT_COMP_LOGE("Cannot memory-map next region of file \"%s\" (%p)", - ds_file->file->path->str, - ds_file->file->fp); - goto error; - } - } - - BT_ASSERT(remaining_mmap_bytes(ds_file) > 0); - *buffer_sz = MIN(remaining_mmap_bytes(ds_file), request_sz); - - BT_ASSERT(ds_file->mmap_addr); - *buffer_addr = ((uint8_t *) ds_file->mmap_addr) + ds_file->request_offset_in_mapping; - - ds_file->request_offset_in_mapping += *buffer_sz; - goto end; + enum ctf_msg_iter_medium_status status = CTF_MSG_ITER_MEDIUM_STATUS_OK; + struct ctf_fs_ds_file *ds_file = (struct ctf_fs_ds_file *) data; + bt_self_component *self_comp = ds_file->self_comp; + bt_logging_level log_level = ds_file->log_level; + + BT_ASSERT(request_sz > 0); + + /* + * Check if we have at least one memory-mapped byte left. If we don't, + * mmap the next file. + */ + if (remaining_mmap_bytes(ds_file) == 0) { + /* Are we at the end of the file? */ + if (ds_file->mmap_offset_in_file >= ds_file->file->size) { + BT_COMP_LOGD("Reached end of file \"%s\" (%p)", ds_file->file->path->str, + ds_file->file->fp); + status = CTF_MSG_ITER_MEDIUM_STATUS_EOF; + goto end; + } + + status = ds_file_mmap_next(ds_file); + switch (status) { + case CTF_MSG_ITER_MEDIUM_STATUS_OK: + break; + case CTF_MSG_ITER_MEDIUM_STATUS_EOF: + goto end; + default: + BT_COMP_LOGE("Cannot memory-map next region of file \"%s\" (%p)", + ds_file->file->path->str, ds_file->file->fp); + goto error; + } + } + + BT_ASSERT(remaining_mmap_bytes(ds_file) > 0); + *buffer_sz = MIN(remaining_mmap_bytes(ds_file), request_sz); + + BT_ASSERT(ds_file->mmap_addr); + *buffer_addr = ((uint8_t *) ds_file->mmap_addr) + ds_file->request_offset_in_mapping; + + ds_file->request_offset_in_mapping += *buffer_sz; + goto end; error: - status = CTF_MSG_ITER_MEDIUM_STATUS_ERROR; + status = CTF_MSG_ITER_MEDIUM_STATUS_ERROR; end: - return status; + return status; } -static -bt_stream *medop_borrow_stream(bt_stream_class *stream_class, int64_t stream_id, - void *data) +static bt_stream *medop_borrow_stream(bt_stream_class *stream_class, int64_t stream_id, void *data) { - struct ctf_fs_ds_file *ds_file = (struct ctf_fs_ds_file *) data; - bt_stream_class *ds_file_stream_class; - bt_stream *stream = NULL; + struct ctf_fs_ds_file *ds_file = (struct ctf_fs_ds_file *) data; + bt_stream_class *ds_file_stream_class; + bt_stream *stream = NULL; - ds_file_stream_class = bt_stream_borrow_class( - ds_file->stream); + ds_file_stream_class = bt_stream_borrow_class(ds_file->stream); - if (stream_class != ds_file_stream_class) { - /* - * Not supported: two packets described by two different - * stream classes within the same data stream file. - */ - goto end; - } + if (stream_class != ds_file_stream_class) { + /* + * Not supported: two packets described by two different + * stream classes within the same data stream file. + */ + goto end; + } - stream = ds_file->stream; + stream = ds_file->stream; end: - return stream; + return stream; } -static -enum ctf_msg_iter_medium_status medop_seek(off_t offset, void *data) +static enum ctf_msg_iter_medium_status medop_seek(off_t offset, void *data) { - struct ctf_fs_ds_file *ds_file = (struct ctf_fs_ds_file *) data; + struct ctf_fs_ds_file *ds_file = (struct ctf_fs_ds_file *) data; - BT_ASSERT(offset >= 0); - BT_ASSERT(offset < ds_file->file->size); + BT_ASSERT(offset >= 0); + BT_ASSERT(offset < ds_file->file->size); - return ds_file_mmap(ds_file, offset); + return ds_file_mmap(ds_file, offset); } BT_HIDDEN struct ctf_msg_iter_medium_ops ctf_fs_ds_file_medops = { - medop_request_bytes, - medop_seek, - nullptr, - medop_borrow_stream, + medop_request_bytes, + medop_seek, + nullptr, + medop_borrow_stream, }; -struct ctf_fs_ds_group_medops_data { - /* Weak, set once at creation time. */ - struct ctf_fs_ds_file_group *ds_file_group; - - /* - * Index (as in element rank) of the index entry of ds_file_groups' - * index we will read next (so, the one after the one we are reading - * right now). - */ - guint next_index_entry_index; - - /* - * File we are currently reading. Changes whenever we switch to - * reading another data file. - * - * Owned by this. - */ - struct ctf_fs_ds_file *file; - - /* Weak, for context / logging / appending causes. */ - bt_self_message_iterator *self_msg_iter; - bt_logging_level log_level; +struct ctf_fs_ds_group_medops_data +{ + /* Weak, set once at creation time. */ + struct ctf_fs_ds_file_group *ds_file_group; + + /* + * Index (as in element rank) of the index entry of ds_file_groups' + * index we will read next (so, the one after the one we are reading + * right now). + */ + guint next_index_entry_index; + + /* + * File we are currently reading. Changes whenever we switch to + * reading another data file. + * + * Owned by this. + */ + struct ctf_fs_ds_file *file; + + /* Weak, for context / logging / appending causes. */ + bt_self_message_iterator *self_msg_iter; + bt_logging_level log_level; }; -static -enum ctf_msg_iter_medium_status medop_group_request_bytes( - size_t request_sz, - uint8_t **buffer_addr, - size_t *buffer_sz, - void *void_data) +static enum ctf_msg_iter_medium_status medop_group_request_bytes(size_t request_sz, + uint8_t **buffer_addr, + size_t *buffer_sz, void *void_data) { - struct ctf_fs_ds_group_medops_data *data = (struct ctf_fs_ds_group_medops_data *) void_data; + struct ctf_fs_ds_group_medops_data *data = (struct ctf_fs_ds_group_medops_data *) void_data; - /* Return bytes from the current file. */ - return medop_request_bytes(request_sz, buffer_addr, buffer_sz, data->file); + /* Return bytes from the current file. */ + return medop_request_bytes(request_sz, buffer_addr, buffer_sz, data->file); } -static -bt_stream *medop_group_borrow_stream( - bt_stream_class *stream_class, - int64_t stream_id, - void *void_data) +static bt_stream *medop_group_borrow_stream(bt_stream_class *stream_class, int64_t stream_id, + void *void_data) { - struct ctf_fs_ds_group_medops_data *data = (struct ctf_fs_ds_group_medops_data *) void_data; + struct ctf_fs_ds_group_medops_data *data = (struct ctf_fs_ds_group_medops_data *) void_data; - return medop_borrow_stream(stream_class, stream_id, data->file); + return medop_borrow_stream(stream_class, stream_id, data->file); } /* @@ -341,697 +317,656 @@ bt_stream *medop_group_borrow_stream( * by `index_entry`. */ -static -enum ctf_msg_iter_medium_status ctf_fs_ds_group_medops_set_file( - struct ctf_fs_ds_group_medops_data *data, - struct ctf_fs_ds_index_entry *index_entry, - bt_self_message_iterator *self_msg_iter, - bt_logging_level log_level) +static enum ctf_msg_iter_medium_status +ctf_fs_ds_group_medops_set_file(struct ctf_fs_ds_group_medops_data *data, + struct ctf_fs_ds_index_entry *index_entry, + bt_self_message_iterator *self_msg_iter, bt_logging_level log_level) { - enum ctf_msg_iter_medium_status status; - - BT_ASSERT(data); - BT_ASSERT(index_entry); - - /* Check if that file is already the one mapped. */ - if (!data->file || strcmp(index_entry->path, data->file->file->path->str) != 0) { - /* Destroy the previously used file. */ - ctf_fs_ds_file_destroy(data->file); - - /* Create the new file. */ - data->file = ctf_fs_ds_file_create( - data->ds_file_group->ctf_fs_trace, - self_msg_iter, - data->ds_file_group->stream, - index_entry->path, - log_level); - if (!data->file) { - BT_MSG_ITER_LOGE_APPEND_CAUSE(self_msg_iter, - "failed to create ctf_fs_ds_file."); - status = CTF_MSG_ITER_MEDIUM_STATUS_ERROR; - goto end; - } - } - - /* - * Ensure the right portion of the file will be returned on the next - * request_bytes call. - */ - status = ds_file_mmap(data->file, index_entry->offset); - if (status != CTF_MSG_ITER_MEDIUM_STATUS_OK) { - goto end; - } - - status = CTF_MSG_ITER_MEDIUM_STATUS_OK; + enum ctf_msg_iter_medium_status status; + + BT_ASSERT(data); + BT_ASSERT(index_entry); + + /* Check if that file is already the one mapped. */ + if (!data->file || strcmp(index_entry->path, data->file->file->path->str) != 0) { + /* Destroy the previously used file. */ + ctf_fs_ds_file_destroy(data->file); + + /* Create the new file. */ + data->file = + ctf_fs_ds_file_create(data->ds_file_group->ctf_fs_trace, self_msg_iter, + data->ds_file_group->stream, index_entry->path, log_level); + if (!data->file) { + BT_MSG_ITER_LOGE_APPEND_CAUSE(self_msg_iter, "failed to create ctf_fs_ds_file."); + status = CTF_MSG_ITER_MEDIUM_STATUS_ERROR; + goto end; + } + } + + /* + * Ensure the right portion of the file will be returned on the next + * request_bytes call. + */ + status = ds_file_mmap(data->file, index_entry->offset); + if (status != CTF_MSG_ITER_MEDIUM_STATUS_OK) { + goto end; + } + + status = CTF_MSG_ITER_MEDIUM_STATUS_OK; end: - return status; + return status; } -static -enum ctf_msg_iter_medium_status medop_group_switch_packet(void *void_data) +static enum ctf_msg_iter_medium_status medop_group_switch_packet(void *void_data) { - struct ctf_fs_ds_group_medops_data *data = (struct ctf_fs_ds_group_medops_data *) void_data; - struct ctf_fs_ds_index_entry *index_entry; - enum ctf_msg_iter_medium_status status; - - /* If we have gone through all index entries, we are done. */ - if (data->next_index_entry_index >= - data->ds_file_group->index->entries->len) { - status = CTF_MSG_ITER_MEDIUM_STATUS_EOF; - goto end; - } - - /* - * Otherwise, look up the next index entry / packet and prepare it - * for reading. - */ - index_entry = (struct ctf_fs_ds_index_entry *) g_ptr_array_index( - data->ds_file_group->index->entries, - data->next_index_entry_index); - - status = ctf_fs_ds_group_medops_set_file( - data, index_entry, data->self_msg_iter, data->log_level); - if (status != CTF_MSG_ITER_MEDIUM_STATUS_OK) { - goto end; - } - - data->next_index_entry_index++; - - status = CTF_MSG_ITER_MEDIUM_STATUS_OK; + struct ctf_fs_ds_group_medops_data *data = (struct ctf_fs_ds_group_medops_data *) void_data; + struct ctf_fs_ds_index_entry *index_entry; + enum ctf_msg_iter_medium_status status; + + /* If we have gone through all index entries, we are done. */ + if (data->next_index_entry_index >= data->ds_file_group->index->entries->len) { + status = CTF_MSG_ITER_MEDIUM_STATUS_EOF; + goto end; + } + + /* + * Otherwise, look up the next index entry / packet and prepare it + * for reading. + */ + index_entry = (struct ctf_fs_ds_index_entry *) g_ptr_array_index( + data->ds_file_group->index->entries, data->next_index_entry_index); + + status = + ctf_fs_ds_group_medops_set_file(data, index_entry, data->self_msg_iter, data->log_level); + if (status != CTF_MSG_ITER_MEDIUM_STATUS_OK) { + goto end; + } + + data->next_index_entry_index++; + + status = CTF_MSG_ITER_MEDIUM_STATUS_OK; end: - return status; + return status; } BT_HIDDEN -void ctf_fs_ds_group_medops_data_destroy( - struct ctf_fs_ds_group_medops_data *data) +void ctf_fs_ds_group_medops_data_destroy(struct ctf_fs_ds_group_medops_data *data) { - if (!data) { - goto end; - } + if (!data) { + goto end; + } - ctf_fs_ds_file_destroy(data->file); + ctf_fs_ds_file_destroy(data->file); - g_free(data); + g_free(data); end: - return; + return; } enum ctf_msg_iter_medium_status ctf_fs_ds_group_medops_data_create( - struct ctf_fs_ds_file_group *ds_file_group, - bt_self_message_iterator *self_msg_iter, - bt_logging_level log_level, - struct ctf_fs_ds_group_medops_data **out) + struct ctf_fs_ds_file_group *ds_file_group, bt_self_message_iterator *self_msg_iter, + bt_logging_level log_level, struct ctf_fs_ds_group_medops_data **out) { - struct ctf_fs_ds_group_medops_data *data; - enum ctf_msg_iter_medium_status status; - - BT_ASSERT(self_msg_iter); - BT_ASSERT(ds_file_group); - BT_ASSERT(ds_file_group->index); - BT_ASSERT(ds_file_group->index->entries->len > 0); - - data = g_new0(struct ctf_fs_ds_group_medops_data, 1); - if (!data) { - BT_MSG_ITER_LOGE_APPEND_CAUSE(self_msg_iter, - "Failed to allocate a struct ctf_fs_ds_group_medops_data"); - status = CTF_MSG_ITER_MEDIUM_STATUS_MEMORY_ERROR; - goto error; - } - - data->ds_file_group = ds_file_group; - data->self_msg_iter = self_msg_iter; - data->log_level = log_level; - - /* - * No need to prepare the first file. ctf_msg_iter will call - * switch_packet before reading the first packet, it will be - * done then. - */ - - *out = data; - status = CTF_MSG_ITER_MEDIUM_STATUS_OK; - goto end; + struct ctf_fs_ds_group_medops_data *data; + enum ctf_msg_iter_medium_status status; + + BT_ASSERT(self_msg_iter); + BT_ASSERT(ds_file_group); + BT_ASSERT(ds_file_group->index); + BT_ASSERT(ds_file_group->index->entries->len > 0); + + data = g_new0(struct ctf_fs_ds_group_medops_data, 1); + if (!data) { + BT_MSG_ITER_LOGE_APPEND_CAUSE(self_msg_iter, + "Failed to allocate a struct ctf_fs_ds_group_medops_data"); + status = CTF_MSG_ITER_MEDIUM_STATUS_MEMORY_ERROR; + goto error; + } + + data->ds_file_group = ds_file_group; + data->self_msg_iter = self_msg_iter; + data->log_level = log_level; + + /* + * No need to prepare the first file. ctf_msg_iter will call + * switch_packet before reading the first packet, it will be + * done then. + */ + + *out = data; + status = CTF_MSG_ITER_MEDIUM_STATUS_OK; + goto end; error: - ctf_fs_ds_group_medops_data_destroy(data); + ctf_fs_ds_group_medops_data_destroy(data); end: - return status; + return status; } void ctf_fs_ds_group_medops_data_reset(struct ctf_fs_ds_group_medops_data *data) { - data->next_index_entry_index = 0; + data->next_index_entry_index = 0; } struct ctf_msg_iter_medium_ops ctf_fs_ds_group_medops = { - .request_bytes = medop_group_request_bytes, + .request_bytes = medop_group_request_bytes, - /* - * We don't support seeking using this medops. It would probably be - * possible, but it's not needed at the moment. - */ - .seek = NULL, + /* + * We don't support seeking using this medops. It would probably be + * possible, but it's not needed at the moment. + */ + .seek = NULL, - .switch_packet = medop_group_switch_packet, - .borrow_stream = medop_group_borrow_stream, + .switch_packet = medop_group_switch_packet, + .borrow_stream = medop_group_borrow_stream, }; -static -struct ctf_fs_ds_index_entry *ctf_fs_ds_index_entry_create( - bt_self_component *self_comp, bt_logging_level log_level) +static struct ctf_fs_ds_index_entry *ctf_fs_ds_index_entry_create(bt_self_component *self_comp, + bt_logging_level log_level) { - struct ctf_fs_ds_index_entry *entry; + struct ctf_fs_ds_index_entry *entry; - entry = g_new0(struct ctf_fs_ds_index_entry, 1); - if (!entry) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Failed to allocate a ctf_fs_ds_index_entry."); - goto end; - } + entry = g_new0(struct ctf_fs_ds_index_entry, 1); + if (!entry) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Failed to allocate a ctf_fs_ds_index_entry."); + goto end; + } - entry->packet_seq_num = UINT64_MAX; + entry->packet_seq_num = UINT64_MAX; end: - return entry; + return entry; } -static -int convert_cycles_to_ns(struct ctf_clock_class *clock_class, - uint64_t cycles, int64_t *ns) +static int convert_cycles_to_ns(struct ctf_clock_class *clock_class, uint64_t cycles, int64_t *ns) { - return bt_util_clock_cycles_to_ns_from_origin(cycles, - clock_class->frequency, clock_class->offset_seconds, - clock_class->offset_cycles, ns); + return bt_util_clock_cycles_to_ns_from_origin(cycles, clock_class->frequency, + clock_class->offset_seconds, + clock_class->offset_cycles, ns); } -static -struct ctf_fs_ds_index *build_index_from_idx_file( - struct ctf_fs_ds_file *ds_file, - struct ctf_fs_ds_file_info *file_info, - struct ctf_msg_iter *msg_iter) +static struct ctf_fs_ds_index *build_index_from_idx_file(struct ctf_fs_ds_file *ds_file, + struct ctf_fs_ds_file_info *file_info, + struct ctf_msg_iter *msg_iter) { - int ret; - gchar *directory = NULL; - gchar *basename = NULL; - GString *index_basename = NULL; - gchar *index_file_path = NULL; - GMappedFile *mapped_file = NULL; - gsize filesize; - const char *mmap_begin = NULL, *file_pos = NULL; - const struct ctf_packet_index_file_hdr *header = NULL; - struct ctf_fs_ds_index *index = NULL; - struct ctf_fs_ds_index_entry *index_entry = NULL, *prev_index_entry = NULL; - uint64_t total_packets_size = 0; - size_t file_index_entry_size; - size_t file_entry_count; - size_t i; - struct ctf_stream_class *sc; - struct ctf_msg_iter_packet_properties props; - uint32_t version_major, version_minor; - bt_self_component *self_comp = ds_file->self_comp; - bt_logging_level log_level = ds_file->log_level; - - BT_COMP_LOGI("Building index from .idx file of stream file %s", - ds_file->file->path->str); - ret = ctf_msg_iter_get_packet_properties(msg_iter, &props); - if (ret) { - BT_COMP_LOGI_STR("Cannot read first packet's header and context fields."); - goto error; - } - - sc = ctf_trace_class_borrow_stream_class_by_id(ds_file->metadata->tc, - props.stream_class_id); - BT_ASSERT(sc); - if (!sc->default_clock_class) { - BT_COMP_LOGI_STR("Cannot find stream class's default clock class."); - goto error; - } - - /* Look for index file in relative path index/name.idx. */ - basename = g_path_get_basename(ds_file->file->path->str); - if (!basename) { - BT_COMP_LOGE("Cannot get the basename of datastream file %s", - ds_file->file->path->str); - goto error; - } - - directory = g_path_get_dirname(ds_file->file->path->str); - if (!directory) { - BT_COMP_LOGE("Cannot get dirname of datastream file %s", - ds_file->file->path->str); - goto error; - } - - index_basename = g_string_new(basename); - if (!index_basename) { - BT_COMP_LOGE_STR("Cannot allocate index file basename string"); - goto error; - } - - g_string_append(index_basename, ".idx"); - index_file_path = g_build_filename(directory, "index", - index_basename->str, NULL); - mapped_file = g_mapped_file_new(index_file_path, FALSE, NULL); - if (!mapped_file) { - BT_COMP_LOGD("Cannot create new mapped file %s", - index_file_path); - goto error; - } - - /* - * The g_mapped_file API limits us to 4GB files on 32-bit. - * Traces with such large indexes have never been seen in the wild, - * but this would need to be adjusted to support them. - */ - filesize = g_mapped_file_get_length(mapped_file); - if (filesize < sizeof(*header)) { - BT_COMP_LOGW("Invalid LTTng trace index file: " - "file size (%zu bytes) < header size (%zu bytes)", - filesize, sizeof(*header)); - goto error; - } - - mmap_begin = g_mapped_file_get_contents(mapped_file); - header = (struct ctf_packet_index_file_hdr *) mmap_begin; - - file_pos = g_mapped_file_get_contents(mapped_file) + sizeof(*header); - if (be32toh(header->magic) != CTF_INDEX_MAGIC) { - BT_COMP_LOGW_STR("Invalid LTTng trace index: \"magic\" field validation failed"); - goto error; - } - - version_major = be32toh(header->index_major); - version_minor = be32toh(header->index_minor); - if (version_major != 1) { - BT_COMP_LOGW( - "Unknown LTTng trace index version: " - "major=%" PRIu32 ", minor=%" PRIu32, - version_major, version_minor); - goto error; - } - - file_index_entry_size = be32toh(header->packet_index_len); - if (file_index_entry_size < CTF_INDEX_1_0_SIZE) { - BT_COMP_LOGW("Invalid `packet_index_len` in LTTng trace index file (`packet_index_len` < CTF index 1.0 index entry size): " - "packet_index_len=%zu, CTF_INDEX_1_0_SIZE=%zu", - file_index_entry_size, CTF_INDEX_1_0_SIZE); - goto error; - } - - file_entry_count = (filesize - sizeof(*header)) / file_index_entry_size; - if ((filesize - sizeof(*header)) % file_index_entry_size) { - BT_COMP_LOGW("Invalid LTTng trace index: the index's size after the header " - "(%zu bytes) is not a multiple of the index entry size " - "(%zu bytes)", (filesize - sizeof(*header)), - sizeof(*header)); - goto error; - } - - index = ctf_fs_ds_index_create(ds_file->log_level, ds_file->self_comp); - if (!index) { - goto error; - } - - for (i = 0; i < file_entry_count; i++) { - struct ctf_packet_index *file_index = - (struct ctf_packet_index *) file_pos; - uint64_t packet_size = be64toh(file_index->packet_size); - - if (packet_size % CHAR_BIT) { - BT_COMP_LOGW("Invalid packet size encountered in LTTng trace index file"); - goto error; - } - - index_entry = ctf_fs_ds_index_entry_create( - ds_file->self_comp, ds_file->log_level); - if (!index_entry) { - BT_COMP_LOGE_APPEND_CAUSE(ds_file->self_comp, - "Failed to create a ctf_fs_ds_index_entry."); - goto error; - } - - /* Set path to stream file. */ - index_entry->path = file_info->path->str; - - /* Convert size in bits to bytes. */ - packet_size /= CHAR_BIT; - index_entry->packet_size = packet_size; - - index_entry->offset = be64toh(file_index->offset); - if (i != 0 && index_entry->offset < prev_index_entry->offset) { - BT_COMP_LOGW("Invalid, non-monotonic, packet offset encountered in LTTng trace index file: " - "previous offset=%" PRIu64 ", current offset=%" PRIu64, - prev_index_entry->offset, index_entry->offset); - goto error; - } - - index_entry->timestamp_begin = be64toh(file_index->timestamp_begin); - index_entry->timestamp_end = be64toh(file_index->timestamp_end); - if (index_entry->timestamp_end < index_entry->timestamp_begin) { - BT_COMP_LOGW("Invalid packet time bounds encountered in LTTng trace index file (begin > end): " - "timestamp_begin=%" PRIu64 "timestamp_end=%" PRIu64, - index_entry->timestamp_begin, - index_entry->timestamp_end); - goto error; - } - - /* Convert the packet's bound to nanoseconds since Epoch. */ - ret = convert_cycles_to_ns(sc->default_clock_class, - index_entry->timestamp_begin, - &index_entry->timestamp_begin_ns); - if (ret) { - BT_COMP_LOGI_STR("Failed to convert raw timestamp to nanoseconds since Epoch during index parsing"); - goto error; - } - ret = convert_cycles_to_ns(sc->default_clock_class, - index_entry->timestamp_end, - &index_entry->timestamp_end_ns); - if (ret) { - BT_COMP_LOGI_STR("Failed to convert raw timestamp to nanoseconds since Epoch during LTTng trace index parsing"); - goto error; - } - - if (version_minor >= 1) { - index_entry->packet_seq_num = be64toh(file_index->packet_seq_num); - } - - total_packets_size += packet_size; - file_pos += file_index_entry_size; - - prev_index_entry = index_entry; - - /* Give ownership of `index_entry` to `index->entries`. */ - g_ptr_array_add(index->entries, index_entry); - index_entry = NULL; - } - - /* Validate that the index addresses the complete stream. */ - if (ds_file->file->size != total_packets_size) { - BT_COMP_LOGW("Invalid LTTng trace index file; indexed size != stream file size: " - "file-size=%" PRIu64 ", total-packets-size=%" PRIu64, - ds_file->file->size, total_packets_size); - goto error; - } + int ret; + gchar *directory = NULL; + gchar *basename = NULL; + GString *index_basename = NULL; + gchar *index_file_path = NULL; + GMappedFile *mapped_file = NULL; + gsize filesize; + const char *mmap_begin = NULL, *file_pos = NULL; + const struct ctf_packet_index_file_hdr *header = NULL; + struct ctf_fs_ds_index *index = NULL; + struct ctf_fs_ds_index_entry *index_entry = NULL, *prev_index_entry = NULL; + uint64_t total_packets_size = 0; + size_t file_index_entry_size; + size_t file_entry_count; + size_t i; + struct ctf_stream_class *sc; + struct ctf_msg_iter_packet_properties props; + uint32_t version_major, version_minor; + bt_self_component *self_comp = ds_file->self_comp; + bt_logging_level log_level = ds_file->log_level; + + BT_COMP_LOGI("Building index from .idx file of stream file %s", ds_file->file->path->str); + ret = ctf_msg_iter_get_packet_properties(msg_iter, &props); + if (ret) { + BT_COMP_LOGI_STR("Cannot read first packet's header and context fields."); + goto error; + } + + sc = ctf_trace_class_borrow_stream_class_by_id(ds_file->metadata->tc, props.stream_class_id); + BT_ASSERT(sc); + if (!sc->default_clock_class) { + BT_COMP_LOGI_STR("Cannot find stream class's default clock class."); + goto error; + } + + /* Look for index file in relative path index/name.idx. */ + basename = g_path_get_basename(ds_file->file->path->str); + if (!basename) { + BT_COMP_LOGE("Cannot get the basename of datastream file %s", ds_file->file->path->str); + goto error; + } + + directory = g_path_get_dirname(ds_file->file->path->str); + if (!directory) { + BT_COMP_LOGE("Cannot get dirname of datastream file %s", ds_file->file->path->str); + goto error; + } + + index_basename = g_string_new(basename); + if (!index_basename) { + BT_COMP_LOGE_STR("Cannot allocate index file basename string"); + goto error; + } + + g_string_append(index_basename, ".idx"); + index_file_path = g_build_filename(directory, "index", index_basename->str, NULL); + mapped_file = g_mapped_file_new(index_file_path, FALSE, NULL); + if (!mapped_file) { + BT_COMP_LOGD("Cannot create new mapped file %s", index_file_path); + goto error; + } + + /* + * The g_mapped_file API limits us to 4GB files on 32-bit. + * Traces with such large indexes have never been seen in the wild, + * but this would need to be adjusted to support them. + */ + filesize = g_mapped_file_get_length(mapped_file); + if (filesize < sizeof(*header)) { + BT_COMP_LOGW("Invalid LTTng trace index file: " + "file size (%zu bytes) < header size (%zu bytes)", + filesize, sizeof(*header)); + goto error; + } + + mmap_begin = g_mapped_file_get_contents(mapped_file); + header = (struct ctf_packet_index_file_hdr *) mmap_begin; + + file_pos = g_mapped_file_get_contents(mapped_file) + sizeof(*header); + if (be32toh(header->magic) != CTF_INDEX_MAGIC) { + BT_COMP_LOGW_STR("Invalid LTTng trace index: \"magic\" field validation failed"); + goto error; + } + + version_major = be32toh(header->index_major); + version_minor = be32toh(header->index_minor); + if (version_major != 1) { + BT_COMP_LOGW("Unknown LTTng trace index version: " + "major=%" PRIu32 ", minor=%" PRIu32, + version_major, version_minor); + goto error; + } + + file_index_entry_size = be32toh(header->packet_index_len); + if (file_index_entry_size < CTF_INDEX_1_0_SIZE) { + BT_COMP_LOGW( + "Invalid `packet_index_len` in LTTng trace index file (`packet_index_len` < CTF index 1.0 index entry size): " + "packet_index_len=%zu, CTF_INDEX_1_0_SIZE=%zu", + file_index_entry_size, CTF_INDEX_1_0_SIZE); + goto error; + } + + file_entry_count = (filesize - sizeof(*header)) / file_index_entry_size; + if ((filesize - sizeof(*header)) % file_index_entry_size) { + BT_COMP_LOGW("Invalid LTTng trace index: the index's size after the header " + "(%zu bytes) is not a multiple of the index entry size " + "(%zu bytes)", + (filesize - sizeof(*header)), sizeof(*header)); + goto error; + } + + index = ctf_fs_ds_index_create(ds_file->log_level, ds_file->self_comp); + if (!index) { + goto error; + } + + for (i = 0; i < file_entry_count; i++) { + struct ctf_packet_index *file_index = (struct ctf_packet_index *) file_pos; + uint64_t packet_size = be64toh(file_index->packet_size); + + if (packet_size % CHAR_BIT) { + BT_COMP_LOGW("Invalid packet size encountered in LTTng trace index file"); + goto error; + } + + index_entry = ctf_fs_ds_index_entry_create(ds_file->self_comp, ds_file->log_level); + if (!index_entry) { + BT_COMP_LOGE_APPEND_CAUSE(ds_file->self_comp, + "Failed to create a ctf_fs_ds_index_entry."); + goto error; + } + + /* Set path to stream file. */ + index_entry->path = file_info->path->str; + + /* Convert size in bits to bytes. */ + packet_size /= CHAR_BIT; + index_entry->packet_size = packet_size; + + index_entry->offset = be64toh(file_index->offset); + if (i != 0 && index_entry->offset < prev_index_entry->offset) { + BT_COMP_LOGW( + "Invalid, non-monotonic, packet offset encountered in LTTng trace index file: " + "previous offset=%" PRIu64 ", current offset=%" PRIu64, + prev_index_entry->offset, index_entry->offset); + goto error; + } + + index_entry->timestamp_begin = be64toh(file_index->timestamp_begin); + index_entry->timestamp_end = be64toh(file_index->timestamp_end); + if (index_entry->timestamp_end < index_entry->timestamp_begin) { + BT_COMP_LOGW( + "Invalid packet time bounds encountered in LTTng trace index file (begin > end): " + "timestamp_begin=%" PRIu64 "timestamp_end=%" PRIu64, + index_entry->timestamp_begin, index_entry->timestamp_end); + goto error; + } + + /* Convert the packet's bound to nanoseconds since Epoch. */ + ret = convert_cycles_to_ns(sc->default_clock_class, index_entry->timestamp_begin, + &index_entry->timestamp_begin_ns); + if (ret) { + BT_COMP_LOGI_STR( + "Failed to convert raw timestamp to nanoseconds since Epoch during index parsing"); + goto error; + } + ret = convert_cycles_to_ns(sc->default_clock_class, index_entry->timestamp_end, + &index_entry->timestamp_end_ns); + if (ret) { + BT_COMP_LOGI_STR( + "Failed to convert raw timestamp to nanoseconds since Epoch during LTTng trace index parsing"); + goto error; + } + + if (version_minor >= 1) { + index_entry->packet_seq_num = be64toh(file_index->packet_seq_num); + } + + total_packets_size += packet_size; + file_pos += file_index_entry_size; + + prev_index_entry = index_entry; + + /* Give ownership of `index_entry` to `index->entries`. */ + g_ptr_array_add(index->entries, index_entry); + index_entry = NULL; + } + + /* Validate that the index addresses the complete stream. */ + if (ds_file->file->size != total_packets_size) { + BT_COMP_LOGW("Invalid LTTng trace index file; indexed size != stream file size: " + "file-size=%" PRIu64 ", total-packets-size=%" PRIu64, + ds_file->file->size, total_packets_size); + goto error; + } end: - g_free(directory); - g_free(basename); - g_free(index_file_path); - if (index_basename) { - g_string_free(index_basename, TRUE); - } - if (mapped_file) { - g_mapped_file_unref(mapped_file); - } - return index; + g_free(directory); + g_free(basename); + g_free(index_file_path); + if (index_basename) { + g_string_free(index_basename, TRUE); + } + if (mapped_file) { + g_mapped_file_unref(mapped_file); + } + return index; error: - ctf_fs_ds_index_destroy(index); - g_free(index_entry); - index = NULL; - goto end; + ctf_fs_ds_index_destroy(index); + g_free(index_entry); + index = NULL; + goto end; } -static -int init_index_entry(struct ctf_fs_ds_index_entry *entry, - struct ctf_fs_ds_file *ds_file, - struct ctf_msg_iter_packet_properties *props, - off_t packet_size, off_t packet_offset) +static int init_index_entry(struct ctf_fs_ds_index_entry *entry, struct ctf_fs_ds_file *ds_file, + struct ctf_msg_iter_packet_properties *props, off_t packet_size, + off_t packet_offset) { - int ret = 0; - struct ctf_stream_class *sc; - bt_self_component *self_comp = ds_file->self_comp; - bt_logging_level log_level = ds_file->log_level; - - sc = ctf_trace_class_borrow_stream_class_by_id(ds_file->metadata->tc, - props->stream_class_id); - BT_ASSERT(sc); - BT_ASSERT(packet_offset >= 0); - entry->offset = packet_offset; - BT_ASSERT(packet_size >= 0); - entry->packet_size = packet_size; - - if (props->snapshots.beginning_clock != UINT64_C(-1)) { - entry->timestamp_begin = props->snapshots.beginning_clock; - - /* Convert the packet's bound to nanoseconds since Epoch. */ - ret = convert_cycles_to_ns(sc->default_clock_class, - props->snapshots.beginning_clock, - &entry->timestamp_begin_ns); - if (ret) { - BT_COMP_LOGI_STR("Failed to convert raw timestamp to nanoseconds since Epoch."); - goto end; - } - } else { - entry->timestamp_begin = UINT64_C(-1); - entry->timestamp_begin_ns = UINT64_C(-1); - } - - if (props->snapshots.end_clock != UINT64_C(-1)) { - entry->timestamp_end = props->snapshots.end_clock; - - /* Convert the packet's bound to nanoseconds since Epoch. */ - ret = convert_cycles_to_ns(sc->default_clock_class, - props->snapshots.end_clock, - &entry->timestamp_end_ns); - if (ret) { - BT_COMP_LOGI_STR("Failed to convert raw timestamp to nanoseconds since Epoch."); - goto end; - } - } else { - entry->timestamp_end = UINT64_C(-1); - entry->timestamp_end_ns = UINT64_C(-1); - } + int ret = 0; + struct ctf_stream_class *sc; + bt_self_component *self_comp = ds_file->self_comp; + bt_logging_level log_level = ds_file->log_level; + + sc = ctf_trace_class_borrow_stream_class_by_id(ds_file->metadata->tc, props->stream_class_id); + BT_ASSERT(sc); + BT_ASSERT(packet_offset >= 0); + entry->offset = packet_offset; + BT_ASSERT(packet_size >= 0); + entry->packet_size = packet_size; + + if (props->snapshots.beginning_clock != UINT64_C(-1)) { + entry->timestamp_begin = props->snapshots.beginning_clock; + + /* Convert the packet's bound to nanoseconds since Epoch. */ + ret = convert_cycles_to_ns(sc->default_clock_class, props->snapshots.beginning_clock, + &entry->timestamp_begin_ns); + if (ret) { + BT_COMP_LOGI_STR("Failed to convert raw timestamp to nanoseconds since Epoch."); + goto end; + } + } else { + entry->timestamp_begin = UINT64_C(-1); + entry->timestamp_begin_ns = UINT64_C(-1); + } + + if (props->snapshots.end_clock != UINT64_C(-1)) { + entry->timestamp_end = props->snapshots.end_clock; + + /* Convert the packet's bound to nanoseconds since Epoch. */ + ret = convert_cycles_to_ns(sc->default_clock_class, props->snapshots.end_clock, + &entry->timestamp_end_ns); + if (ret) { + BT_COMP_LOGI_STR("Failed to convert raw timestamp to nanoseconds since Epoch."); + goto end; + } + } else { + entry->timestamp_end = UINT64_C(-1); + entry->timestamp_end_ns = UINT64_C(-1); + } end: - return ret; + return ret; } -static -struct ctf_fs_ds_index *build_index_from_stream_file( - struct ctf_fs_ds_file *ds_file, - struct ctf_fs_ds_file_info *file_info, - struct ctf_msg_iter *msg_iter) +static struct ctf_fs_ds_index *build_index_from_stream_file(struct ctf_fs_ds_file *ds_file, + struct ctf_fs_ds_file_info *file_info, + struct ctf_msg_iter *msg_iter) { - int ret; - struct ctf_fs_ds_index *index = NULL; - enum ctf_msg_iter_status iter_status = CTF_MSG_ITER_STATUS_OK; - off_t current_packet_offset_bytes = 0; - bt_self_component *self_comp = ds_file->self_comp; - bt_logging_level log_level = ds_file->log_level; - - BT_COMP_LOGI("Indexing stream file %s", ds_file->file->path->str); - - index = ctf_fs_ds_index_create(ds_file->log_level, ds_file->self_comp); - if (!index) { - goto error; - } - - while (true) { - off_t current_packet_size_bytes; - struct ctf_fs_ds_index_entry *index_entry; - struct ctf_msg_iter_packet_properties props; - - if (current_packet_offset_bytes < 0) { - BT_COMP_LOGE_STR("Cannot get the current packet's offset."); - goto error; - } else if (current_packet_offset_bytes > ds_file->file->size) { - BT_COMP_LOGE_STR("Unexpected current packet's offset (larger than file)."); - goto error; - } else if (current_packet_offset_bytes == ds_file->file->size) { - /* No more data */ - break; - } - - iter_status = ctf_msg_iter_seek(msg_iter, - current_packet_offset_bytes); - if (iter_status != CTF_MSG_ITER_STATUS_OK) { - goto error; - } - - iter_status = ctf_msg_iter_get_packet_properties( - msg_iter, &props); - if (iter_status != CTF_MSG_ITER_STATUS_OK) { - goto error; - } - - if (props.exp_packet_total_size >= 0) { - current_packet_size_bytes = - (uint64_t) props.exp_packet_total_size / 8; - } else { - current_packet_size_bytes = ds_file->file->size; - } - - if (current_packet_offset_bytes + current_packet_size_bytes > - ds_file->file->size) { - BT_COMP_LOGW("Invalid packet size reported in file: stream=\"%s\", " - "packet-offset=%jd, packet-size-bytes=%jd, " - "file-size=%jd", - ds_file->file->path->str, - (intmax_t) current_packet_offset_bytes, - (intmax_t) current_packet_size_bytes, - (intmax_t) ds_file->file->size); - goto error; - } - - index_entry = ctf_fs_ds_index_entry_create( - ds_file->self_comp, ds_file->log_level); - if (!index_entry) { - BT_COMP_LOGE_APPEND_CAUSE(ds_file->self_comp, - "Failed to create a ctf_fs_ds_index_entry."); - goto error; - } - - /* Set path to stream file. */ - index_entry->path = file_info->path->str; - - ret = init_index_entry(index_entry, ds_file, &props, - current_packet_size_bytes, current_packet_offset_bytes); - if (ret) { - g_free(index_entry); - goto error; - } - - g_ptr_array_add(index->entries, index_entry); - - current_packet_offset_bytes += current_packet_size_bytes; - BT_COMP_LOGD("Seeking to next packet: current-packet-offset=%jd, " - "next-packet-offset=%jd", - (intmax_t) (current_packet_offset_bytes - current_packet_size_bytes), - (intmax_t) current_packet_offset_bytes); - } + int ret; + struct ctf_fs_ds_index *index = NULL; + enum ctf_msg_iter_status iter_status = CTF_MSG_ITER_STATUS_OK; + off_t current_packet_offset_bytes = 0; + bt_self_component *self_comp = ds_file->self_comp; + bt_logging_level log_level = ds_file->log_level; + + BT_COMP_LOGI("Indexing stream file %s", ds_file->file->path->str); + + index = ctf_fs_ds_index_create(ds_file->log_level, ds_file->self_comp); + if (!index) { + goto error; + } + + while (true) { + off_t current_packet_size_bytes; + struct ctf_fs_ds_index_entry *index_entry; + struct ctf_msg_iter_packet_properties props; + + if (current_packet_offset_bytes < 0) { + BT_COMP_LOGE_STR("Cannot get the current packet's offset."); + goto error; + } else if (current_packet_offset_bytes > ds_file->file->size) { + BT_COMP_LOGE_STR("Unexpected current packet's offset (larger than file)."); + goto error; + } else if (current_packet_offset_bytes == ds_file->file->size) { + /* No more data */ + break; + } + + iter_status = ctf_msg_iter_seek(msg_iter, current_packet_offset_bytes); + if (iter_status != CTF_MSG_ITER_STATUS_OK) { + goto error; + } + + iter_status = ctf_msg_iter_get_packet_properties(msg_iter, &props); + if (iter_status != CTF_MSG_ITER_STATUS_OK) { + goto error; + } + + if (props.exp_packet_total_size >= 0) { + current_packet_size_bytes = (uint64_t) props.exp_packet_total_size / 8; + } else { + current_packet_size_bytes = ds_file->file->size; + } + + if (current_packet_offset_bytes + current_packet_size_bytes > ds_file->file->size) { + BT_COMP_LOGW("Invalid packet size reported in file: stream=\"%s\", " + "packet-offset=%jd, packet-size-bytes=%jd, " + "file-size=%jd", + ds_file->file->path->str, (intmax_t) current_packet_offset_bytes, + (intmax_t) current_packet_size_bytes, (intmax_t) ds_file->file->size); + goto error; + } + + index_entry = ctf_fs_ds_index_entry_create(ds_file->self_comp, ds_file->log_level); + if (!index_entry) { + BT_COMP_LOGE_APPEND_CAUSE(ds_file->self_comp, + "Failed to create a ctf_fs_ds_index_entry."); + goto error; + } + + /* Set path to stream file. */ + index_entry->path = file_info->path->str; + + ret = init_index_entry(index_entry, ds_file, &props, current_packet_size_bytes, + current_packet_offset_bytes); + if (ret) { + g_free(index_entry); + goto error; + } + + g_ptr_array_add(index->entries, index_entry); + + current_packet_offset_bytes += current_packet_size_bytes; + BT_COMP_LOGD("Seeking to next packet: current-packet-offset=%jd, " + "next-packet-offset=%jd", + (intmax_t) (current_packet_offset_bytes - current_packet_size_bytes), + (intmax_t) current_packet_offset_bytes); + } end: - return index; + return index; error: - ctf_fs_ds_index_destroy(index); - index = NULL; - goto end; + ctf_fs_ds_index_destroy(index); + index = NULL; + goto end; } BT_HIDDEN -struct ctf_fs_ds_file *ctf_fs_ds_file_create( - struct ctf_fs_trace *ctf_fs_trace, - bt_self_message_iterator *self_msg_iter, - bt_stream *stream, const char *path, - bt_logging_level log_level) +struct ctf_fs_ds_file *ctf_fs_ds_file_create(struct ctf_fs_trace *ctf_fs_trace, + bt_self_message_iterator *self_msg_iter, + bt_stream *stream, const char *path, + bt_logging_level log_level) { - int ret; - const size_t offset_align = bt_mmap_get_offset_align_size(log_level); - struct ctf_fs_ds_file *ds_file = g_new0(struct ctf_fs_ds_file, 1); - - if (!ds_file) { - goto error; - } - - ds_file->log_level = log_level; - ds_file->self_comp = ctf_fs_trace->self_comp; - ds_file->self_msg_iter = self_msg_iter; - ds_file->file = ctf_fs_file_create(log_level, ds_file->self_comp); - if (!ds_file->file) { - goto error; - } - - ds_file->stream = stream; - bt_stream_get_ref(ds_file->stream); - ds_file->metadata = ctf_fs_trace->metadata; - g_string_assign(ds_file->file->path, path); - ret = ctf_fs_file_open(ds_file->file, "rb"); - if (ret) { - goto error; - } - - ds_file->mmap_max_len = offset_align * 2048; - - goto end; + int ret; + const size_t offset_align = bt_mmap_get_offset_align_size(log_level); + struct ctf_fs_ds_file *ds_file = g_new0(struct ctf_fs_ds_file, 1); + + if (!ds_file) { + goto error; + } + + ds_file->log_level = log_level; + ds_file->self_comp = ctf_fs_trace->self_comp; + ds_file->self_msg_iter = self_msg_iter; + ds_file->file = ctf_fs_file_create(log_level, ds_file->self_comp); + if (!ds_file->file) { + goto error; + } + + ds_file->stream = stream; + bt_stream_get_ref(ds_file->stream); + ds_file->metadata = ctf_fs_trace->metadata; + g_string_assign(ds_file->file->path, path); + ret = ctf_fs_file_open(ds_file->file, "rb"); + if (ret) { + goto error; + } + + ds_file->mmap_max_len = offset_align * 2048; + + goto end; error: - /* Do not touch "borrowed" file. */ - ctf_fs_ds_file_destroy(ds_file); - ds_file = NULL; + /* Do not touch "borrowed" file. */ + ctf_fs_ds_file_destroy(ds_file); + ds_file = NULL; end: - return ds_file; + return ds_file; } BT_HIDDEN -struct ctf_fs_ds_index *ctf_fs_ds_file_build_index( - struct ctf_fs_ds_file *ds_file, - struct ctf_fs_ds_file_info *file_info, - struct ctf_msg_iter *msg_iter) +struct ctf_fs_ds_index *ctf_fs_ds_file_build_index(struct ctf_fs_ds_file *ds_file, + struct ctf_fs_ds_file_info *file_info, + struct ctf_msg_iter *msg_iter) { - struct ctf_fs_ds_index *index; - bt_self_component *self_comp = ds_file->self_comp; - bt_logging_level log_level = ds_file->log_level; - - index = build_index_from_idx_file(ds_file, file_info, msg_iter); - if (index) { - goto end; - } - - BT_COMP_LOGI("Failed to build index from .index file; " - "falling back to stream indexing."); - index = build_index_from_stream_file(ds_file, file_info, msg_iter); + struct ctf_fs_ds_index *index; + bt_self_component *self_comp = ds_file->self_comp; + bt_logging_level log_level = ds_file->log_level; + + index = build_index_from_idx_file(ds_file, file_info, msg_iter); + if (index) { + goto end; + } + + BT_COMP_LOGI("Failed to build index from .index file; " + "falling back to stream indexing."); + index = build_index_from_stream_file(ds_file, file_info, msg_iter); end: - return index; + return index; } BT_HIDDEN struct ctf_fs_ds_index *ctf_fs_ds_index_create(bt_logging_level log_level, - bt_self_component *self_comp) + bt_self_component *self_comp) { - struct ctf_fs_ds_index *index = g_new0(struct ctf_fs_ds_index, 1); + struct ctf_fs_ds_index *index = g_new0(struct ctf_fs_ds_index, 1); - if (!index) { - BT_COMP_LOG_CUR_LVL(BT_LOG_ERROR, log_level, self_comp, - "Failed to allocate index"); - goto error; - } + if (!index) { + BT_COMP_LOG_CUR_LVL(BT_LOG_ERROR, log_level, self_comp, "Failed to allocate index"); + goto error; + } - index->entries = g_ptr_array_new_with_free_func((GDestroyNotify) g_free); - if (!index->entries) { - BT_COMP_LOG_CUR_LVL(BT_LOG_ERROR, log_level, self_comp, - "Failed to allocate index entries."); - goto error; - } + index->entries = g_ptr_array_new_with_free_func((GDestroyNotify) g_free); + if (!index->entries) { + BT_COMP_LOG_CUR_LVL(BT_LOG_ERROR, log_level, self_comp, + "Failed to allocate index entries."); + goto error; + } - goto end; + goto end; error: - ctf_fs_ds_index_destroy(index); - index = NULL; + ctf_fs_ds_index_destroy(index); + index = NULL; end: - return index; + return index; } BT_HIDDEN void ctf_fs_ds_file_destroy(struct ctf_fs_ds_file *ds_file) { - if (!ds_file) { - return; - } + if (!ds_file) { + return; + } - bt_stream_put_ref(ds_file->stream); - (void) ds_file_munmap(ds_file); + bt_stream_put_ref(ds_file->stream); + (void) ds_file_munmap(ds_file); - if (ds_file->file) { - ctf_fs_file_destroy(ds_file->file); - } + if (ds_file->file) { + ctf_fs_file_destroy(ds_file->file); + } - g_free(ds_file); + g_free(ds_file); } BT_HIDDEN void ctf_fs_ds_index_destroy(struct ctf_fs_ds_index *index) { - if (!index) { - return; - } - - if (index->entries) { - g_ptr_array_free(index->entries, TRUE); - } - g_free(index); + if (!index) { + return; + } + + if (index->entries) { + g_ptr_array_free(index->entries, TRUE); + } + g_free(index); } diff --git a/src/plugins/ctf/fs-src/data-stream-file.hpp b/src/plugins/ctf/fs-src/data-stream-file.hpp index 9bd1e501..7ed41c2a 100644 --- a/src/plugins/ctf/fs-src/data-stream-file.hpp +++ b/src/plugins/ctf/fs-src/data-stream-file.hpp @@ -23,74 +23,74 @@ struct ctf_fs_ds_file; struct ctf_fs_ds_file_group; struct ctf_fs_ds_group_medops_data; -struct ctf_fs_ds_file_info { - /* Owned by this. */ - GString *path; +struct ctf_fs_ds_file_info +{ + /* Owned by this. */ + GString *path; - /* Guaranteed to be set, as opposed to the index. */ - int64_t begin_ns; + /* Guaranteed to be set, as opposed to the index. */ + int64_t begin_ns; }; struct ctf_fs_metadata; -struct ctf_fs_ds_file { - bt_logging_level log_level; +struct ctf_fs_ds_file +{ + bt_logging_level log_level; - /* Weak */ - bt_self_component *self_comp; + /* Weak */ + bt_self_component *self_comp; - /* Weak */ - bt_self_message_iterator *self_msg_iter; + /* Weak */ + bt_self_message_iterator *self_msg_iter; - /* Weak */ - struct ctf_fs_metadata *metadata; + /* Weak */ + struct ctf_fs_metadata *metadata; - /* Owned by this */ - struct ctf_fs_file *file; + /* Owned by this */ + struct ctf_fs_file *file; - /* Owned by this */ - bt_stream *stream; + /* Owned by this */ + bt_stream *stream; - void *mmap_addr; + void *mmap_addr; - /* - * Max length of chunk to mmap() when updating the current mapping. - * This value must be page-aligned. - */ - size_t mmap_max_len; + /* + * Max length of chunk to mmap() when updating the current mapping. + * This value must be page-aligned. + */ + size_t mmap_max_len; - /* Length of the current mapping. Never exceeds the file's length. */ - size_t mmap_len; + /* Length of the current mapping. Never exceeds the file's length. */ + size_t mmap_len; - /* Offset in the file where the current mapping starts. */ - off_t mmap_offset_in_file; + /* Offset in the file where the current mapping starts. */ + off_t mmap_offset_in_file; - /* - * Offset, in the current mapping, of the address to return on the next - * request. - */ - off_t request_offset_in_mapping; + /* + * Offset, in the current mapping, of the address to return on the next + * request. + */ + off_t request_offset_in_mapping; }; BT_HIDDEN -struct ctf_fs_ds_file *ctf_fs_ds_file_create( - struct ctf_fs_trace *ctf_fs_trace, - bt_self_message_iterator *self_msg_iter, - bt_stream *stream, const char *path, - bt_logging_level log_level); +struct ctf_fs_ds_file *ctf_fs_ds_file_create(struct ctf_fs_trace *ctf_fs_trace, + bt_self_message_iterator *self_msg_iter, + bt_stream *stream, const char *path, + bt_logging_level log_level); BT_HIDDEN void ctf_fs_ds_file_destroy(struct ctf_fs_ds_file *stream); BT_HIDDEN -struct ctf_fs_ds_index *ctf_fs_ds_file_build_index( - struct ctf_fs_ds_file *ds_file, - struct ctf_fs_ds_file_info *ds_file_info, - struct ctf_msg_iter *msg_iter); +struct ctf_fs_ds_index *ctf_fs_ds_file_build_index(struct ctf_fs_ds_file *ds_file, + struct ctf_fs_ds_file_info *ds_file_info, + struct ctf_msg_iter *msg_iter); BT_HIDDEN struct ctf_fs_ds_index *ctf_fs_ds_index_create(bt_logging_level log_level, - bt_self_component *self_comp); + bt_self_component *self_comp); BT_HIDDEN void ctf_fs_ds_index_destroy(struct ctf_fs_ds_index *index); @@ -115,16 +115,13 @@ extern struct ctf_msg_iter_medium_ops ctf_fs_ds_group_medops; BT_HIDDEN enum ctf_msg_iter_medium_status ctf_fs_ds_group_medops_data_create( - struct ctf_fs_ds_file_group *ds_file_group, - bt_self_message_iterator *self_msg_iter, - bt_logging_level log_level, - struct ctf_fs_ds_group_medops_data **out); + struct ctf_fs_ds_file_group *ds_file_group, bt_self_message_iterator *self_msg_iter, + bt_logging_level log_level, struct ctf_fs_ds_group_medops_data **out); BT_HIDDEN void ctf_fs_ds_group_medops_data_reset(struct ctf_fs_ds_group_medops_data *data); BT_HIDDEN -void ctf_fs_ds_group_medops_data_destroy( - struct ctf_fs_ds_group_medops_data *data); +void ctf_fs_ds_group_medops_data_destroy(struct ctf_fs_ds_group_medops_data *data); #endif /* CTF_FS_DS_FILE_H */ diff --git a/src/plugins/ctf/fs-src/file.cpp b/src/plugins/ctf/fs-src/file.cpp index 42b865a8..6361123c 100644 --- a/src/plugins/ctf/fs-src/file.cpp +++ b/src/plugins/ctf/fs-src/file.cpp @@ -5,8 +5,8 @@ */ #define BT_COMP_LOG_SELF_COMP (file->self_comp) -#define BT_LOG_OUTPUT_LEVEL (file->log_level) -#define BT_LOG_TAG "PLUGIN/SRC.CTF.FS/FILE" +#define BT_LOG_OUTPUT_LEVEL (file->log_level) +#define BT_LOG_TAG "PLUGIN/SRC.CTF.FS/FILE" #include "logging/comp-logging.h" #include @@ -19,93 +19,87 @@ BT_HIDDEN void ctf_fs_file_destroy(struct ctf_fs_file *file) { - if (!file) { - return; - } - - if (file->fp) { - BT_COMP_LOGD("Closing file \"%s\" (%p)", - file->path ? file->path->str : NULL, file->fp); - - if (fclose(file->fp)) { - BT_COMP_LOGE("Cannot close file \"%s\": %s", - file->path ? file->path->str : "NULL", - strerror(errno)); - } - } - - if (file->path) { - g_string_free(file->path, TRUE); - } - - g_free(file); + if (!file) { + return; + } + + if (file->fp) { + BT_COMP_LOGD("Closing file \"%s\" (%p)", file->path ? file->path->str : NULL, file->fp); + + if (fclose(file->fp)) { + BT_COMP_LOGE("Cannot close file \"%s\": %s", file->path ? file->path->str : "NULL", + strerror(errno)); + } + } + + if (file->path) { + g_string_free(file->path, TRUE); + } + + g_free(file); } BT_HIDDEN -struct ctf_fs_file *ctf_fs_file_create(bt_logging_level log_level, - bt_self_component *self_comp) +struct ctf_fs_file *ctf_fs_file_create(bt_logging_level log_level, bt_self_component *self_comp) { - struct ctf_fs_file *file = g_new0(struct ctf_fs_file, 1); + struct ctf_fs_file *file = g_new0(struct ctf_fs_file, 1); - if (!file) { - goto error; - } + if (!file) { + goto error; + } - file->log_level = log_level; - file->self_comp = self_comp; - file->path = g_string_new(NULL); - if (!file->path) { - goto error; - } + file->log_level = log_level; + file->self_comp = self_comp; + file->path = g_string_new(NULL); + if (!file->path) { + goto error; + } - goto end; + goto end; error: - ctf_fs_file_destroy(file); - file = NULL; + ctf_fs_file_destroy(file); + file = NULL; end: - return file; + return file; } BT_HIDDEN int ctf_fs_file_open(struct ctf_fs_file *file, const char *mode) { - int ret = 0; - struct stat stat; - - BT_COMP_LOGI("Opening file \"%s\" with mode \"%s\"", file->path->str, mode); - file->fp = fopen(file->path->str, mode); - if (!file->fp) { - BT_COMP_LOGE_APPEND_CAUSE_ERRNO(file->self_comp, - "Cannot open file", ": path=%s, mode=%s", - file->path->str, mode); - goto error; - } - - BT_COMP_LOGI("Opened file: %p", file->fp); - - if (fstat(fileno(file->fp), &stat)) { - BT_COMP_LOGE_APPEND_CAUSE_ERRNO(file->self_comp, - "Cannot get file information", - ": path=%s", file->path->str); - goto error; - } - - file->size = stat.st_size; - BT_COMP_LOGI("File is %jd bytes", (intmax_t) file->size); - goto end; + int ret = 0; + struct stat stat; + + BT_COMP_LOGI("Opening file \"%s\" with mode \"%s\"", file->path->str, mode); + file->fp = fopen(file->path->str, mode); + if (!file->fp) { + BT_COMP_LOGE_APPEND_CAUSE_ERRNO(file->self_comp, "Cannot open file", ": path=%s, mode=%s", + file->path->str, mode); + goto error; + } + + BT_COMP_LOGI("Opened file: %p", file->fp); + + if (fstat(fileno(file->fp), &stat)) { + BT_COMP_LOGE_APPEND_CAUSE_ERRNO(file->self_comp, "Cannot get file information", ": path=%s", + file->path->str); + goto error; + } + + file->size = stat.st_size; + BT_COMP_LOGI("File is %jd bytes", (intmax_t) file->size); + goto end; error: - ret = -1; + ret = -1; - if (file->fp) { - if (fclose(file->fp)) { - BT_COMP_LOGE("Cannot close file \"%s\": %s", file->path->str, - strerror(errno)); - } - } + if (file->fp) { + if (fclose(file->fp)) { + BT_COMP_LOGE("Cannot close file \"%s\": %s", file->path->str, strerror(errno)); + } + } end: - return ret; + return ret; } diff --git a/src/plugins/ctf/fs-src/file.hpp b/src/plugins/ctf/fs-src/file.hpp index e828423d..59fdd487 100644 --- a/src/plugins/ctf/fs-src/file.hpp +++ b/src/plugins/ctf/fs-src/file.hpp @@ -16,8 +16,7 @@ BT_HIDDEN void ctf_fs_file_destroy(struct ctf_fs_file *file); BT_HIDDEN -struct ctf_fs_file *ctf_fs_file_create(bt_logging_level log_level, - bt_self_component *self_comp); +struct ctf_fs_file *ctf_fs_file_create(bt_logging_level log_level, bt_self_component *self_comp); BT_HIDDEN int ctf_fs_file_open(struct ctf_fs_file *file, const char *mode); diff --git a/src/plugins/ctf/fs-src/fs.cpp b/src/plugins/ctf/fs-src/fs.cpp index 0e6e96e2..cd408e34 100644 --- a/src/plugins/ctf/fs-src/fs.cpp +++ b/src/plugins/ctf/fs-src/fs.cpp @@ -8,8 +8,8 @@ */ #define BT_COMP_LOG_SELF_COMP self_comp -#define BT_LOG_OUTPUT_LEVEL log_level -#define BT_LOG_TAG "PLUGIN/SRC.CTF.FS" +#define BT_LOG_OUTPUT_LEVEL log_level +#define BT_LOG_TAG "PLUGIN/SRC.CTF.FS" #include "logging/comp-logging.h" #include "common/common.h" @@ -29,592 +29,556 @@ #include "query.hpp" #include "plugins/common/param-validation/param-validation.h" -struct tracer_info { - const char *name; - int64_t major; - int64_t minor; - int64_t patch; +struct tracer_info +{ + const char *name; + int64_t major; + int64_t minor; + int64_t patch; }; -static -void ctf_fs_msg_iter_data_destroy( - struct ctf_fs_msg_iter_data *msg_iter_data) +static void ctf_fs_msg_iter_data_destroy(struct ctf_fs_msg_iter_data *msg_iter_data) { - if (!msg_iter_data) { - return; - } + if (!msg_iter_data) { + return; + } - if (msg_iter_data->msg_iter) { - ctf_msg_iter_destroy(msg_iter_data->msg_iter); - } + if (msg_iter_data->msg_iter) { + ctf_msg_iter_destroy(msg_iter_data->msg_iter); + } - if (msg_iter_data->msg_iter_medops_data) { - ctf_fs_ds_group_medops_data_destroy( - msg_iter_data->msg_iter_medops_data); - } + if (msg_iter_data->msg_iter_medops_data) { + ctf_fs_ds_group_medops_data_destroy(msg_iter_data->msg_iter_medops_data); + } - g_free(msg_iter_data); + g_free(msg_iter_data); } -static -bt_message_iterator_class_next_method_status ctf_fs_iterator_next_one( - struct ctf_fs_msg_iter_data *msg_iter_data, - const bt_message **out_msg) +static bt_message_iterator_class_next_method_status +ctf_fs_iterator_next_one(struct ctf_fs_msg_iter_data *msg_iter_data, const bt_message **out_msg) { - bt_message_iterator_class_next_method_status status; - enum ctf_msg_iter_status msg_iter_status; - bt_logging_level log_level = msg_iter_data->log_level; - - msg_iter_status = ctf_msg_iter_get_next_message( - msg_iter_data->msg_iter, out_msg); - - switch (msg_iter_status) { - case CTF_MSG_ITER_STATUS_OK: - /* Cool, message has been written to *out_msg. */ - status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_OK; - break; - - case CTF_MSG_ITER_STATUS_EOF: - status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_END; - break; - - case CTF_MSG_ITER_STATUS_AGAIN: - /* - * Should not make it this far as this is - * medium-specific; there is nothing for the user to do - * and it should have been handled upstream. - */ - bt_common_abort(); - - case CTF_MSG_ITER_STATUS_ERROR: - BT_MSG_ITER_LOGE_APPEND_CAUSE(msg_iter_data->self_msg_iter, - "Failed to get next message from CTF message iterator."); - status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_ERROR; - break; - - case CTF_MSG_ITER_STATUS_MEMORY_ERROR: - BT_MSG_ITER_LOGE_APPEND_CAUSE(msg_iter_data->self_msg_iter, - "Failed to get next message from CTF message iterator."); - status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_MEMORY_ERROR; - break; - - default: - bt_common_abort(); - } - - return status; + bt_message_iterator_class_next_method_status status; + enum ctf_msg_iter_status msg_iter_status; + bt_logging_level log_level = msg_iter_data->log_level; + + msg_iter_status = ctf_msg_iter_get_next_message(msg_iter_data->msg_iter, out_msg); + + switch (msg_iter_status) { + case CTF_MSG_ITER_STATUS_OK: + /* Cool, message has been written to *out_msg. */ + status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_OK; + break; + + case CTF_MSG_ITER_STATUS_EOF: + status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_END; + break; + + case CTF_MSG_ITER_STATUS_AGAIN: + /* + * Should not make it this far as this is + * medium-specific; there is nothing for the user to do + * and it should have been handled upstream. + */ + bt_common_abort(); + + case CTF_MSG_ITER_STATUS_ERROR: + BT_MSG_ITER_LOGE_APPEND_CAUSE(msg_iter_data->self_msg_iter, + "Failed to get next message from CTF message iterator."); + status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_ERROR; + break; + + case CTF_MSG_ITER_STATUS_MEMORY_ERROR: + BT_MSG_ITER_LOGE_APPEND_CAUSE(msg_iter_data->self_msg_iter, + "Failed to get next message from CTF message iterator."); + status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_MEMORY_ERROR; + break; + + default: + bt_common_abort(); + } + + return status; } BT_HIDDEN -bt_message_iterator_class_next_method_status ctf_fs_iterator_next( - bt_self_message_iterator *iterator, - bt_message_array_const msgs, uint64_t capacity, - uint64_t *count) +bt_message_iterator_class_next_method_status +ctf_fs_iterator_next(bt_self_message_iterator *iterator, bt_message_array_const msgs, + uint64_t capacity, uint64_t *count) { - bt_message_iterator_class_next_method_status status; - struct ctf_fs_msg_iter_data *msg_iter_data = - (struct ctf_fs_msg_iter_data *) bt_self_message_iterator_get_data(iterator); - uint64_t i = 0; - - if (G_UNLIKELY(msg_iter_data->next_saved_error)) { - /* - * Last time we were called, we hit an error but had some - * messages to deliver, so we stashed the error here. Return - * it now. - */ - BT_CURRENT_THREAD_MOVE_ERROR_AND_RESET(msg_iter_data->next_saved_error); - status = msg_iter_data->next_saved_status; - goto end; - } - - do { - status = ctf_fs_iterator_next_one(msg_iter_data, &msgs[i]); - if (status == BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_OK) { - i++; - } - } while (i < capacity && - status == BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_OK); - - if (i > 0) { - /* - * Even if ctf_fs_iterator_next_one() returned something - * else than BT_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_OK, we - * accumulated message objects in the output - * message array, so we need to return - * BT_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_OK so that they are - * transfered to downstream. This other status occurs - * again the next time muxer_msg_iter_do_next() is - * called, possibly without any accumulated - * message, in which case we'll return it. - */ - if (status < 0) { - /* - * Save this error for the next _next call. Assume that - * this component always appends error causes when - * returning an error status code, which will cause the - * current thread error to be non-NULL. - */ - msg_iter_data->next_saved_error = bt_current_thread_take_error(); - BT_ASSERT(msg_iter_data->next_saved_error); - msg_iter_data->next_saved_status = status; - } - - *count = i; - status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_OK; - } + bt_message_iterator_class_next_method_status status; + struct ctf_fs_msg_iter_data *msg_iter_data = + (struct ctf_fs_msg_iter_data *) bt_self_message_iterator_get_data(iterator); + uint64_t i = 0; + + if (G_UNLIKELY(msg_iter_data->next_saved_error)) { + /* + * Last time we were called, we hit an error but had some + * messages to deliver, so we stashed the error here. Return + * it now. + */ + BT_CURRENT_THREAD_MOVE_ERROR_AND_RESET(msg_iter_data->next_saved_error); + status = msg_iter_data->next_saved_status; + goto end; + } + + do { + status = ctf_fs_iterator_next_one(msg_iter_data, &msgs[i]); + if (status == BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_OK) { + i++; + } + } while (i < capacity && status == BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_OK); + + if (i > 0) { + /* + * Even if ctf_fs_iterator_next_one() returned something + * else than BT_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_OK, we + * accumulated message objects in the output + * message array, so we need to return + * BT_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_OK so that they are + * transfered to downstream. This other status occurs + * again the next time muxer_msg_iter_do_next() is + * called, possibly without any accumulated + * message, in which case we'll return it. + */ + if (status < 0) { + /* + * Save this error for the next _next call. Assume that + * this component always appends error causes when + * returning an error status code, which will cause the + * current thread error to be non-NULL. + */ + msg_iter_data->next_saved_error = bt_current_thread_take_error(); + BT_ASSERT(msg_iter_data->next_saved_error); + msg_iter_data->next_saved_status = status; + } + + *count = i; + status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_OK; + } end: - return status; + return status; } BT_HIDDEN bt_message_iterator_class_seek_beginning_method_status ctf_fs_iterator_seek_beginning(bt_self_message_iterator *it) { - struct ctf_fs_msg_iter_data *msg_iter_data = - (struct ctf_fs_msg_iter_data *) bt_self_message_iterator_get_data(it); + struct ctf_fs_msg_iter_data *msg_iter_data = + (struct ctf_fs_msg_iter_data *) bt_self_message_iterator_get_data(it); - BT_ASSERT(msg_iter_data); + BT_ASSERT(msg_iter_data); - ctf_msg_iter_reset(msg_iter_data->msg_iter); - ctf_fs_ds_group_medops_data_reset(msg_iter_data->msg_iter_medops_data); + ctf_msg_iter_reset(msg_iter_data->msg_iter); + ctf_fs_ds_group_medops_data_reset(msg_iter_data->msg_iter_medops_data); - return BT_MESSAGE_ITERATOR_CLASS_SEEK_BEGINNING_METHOD_STATUS_OK; + return BT_MESSAGE_ITERATOR_CLASS_SEEK_BEGINNING_METHOD_STATUS_OK; } BT_HIDDEN void ctf_fs_iterator_finalize(bt_self_message_iterator *it) { - ctf_fs_msg_iter_data_destroy( - (struct ctf_fs_msg_iter_data *) bt_self_message_iterator_get_data(it)); + ctf_fs_msg_iter_data_destroy( + (struct ctf_fs_msg_iter_data *) bt_self_message_iterator_get_data(it)); } -static -bt_message_iterator_class_initialize_method_status -ctf_msg_iter_medium_status_to_msg_iter_initialize_status - (enum ctf_msg_iter_medium_status status) +static bt_message_iterator_class_initialize_method_status +ctf_msg_iter_medium_status_to_msg_iter_initialize_status(enum ctf_msg_iter_medium_status status) { - switch (status) { - case CTF_MSG_ITER_MEDIUM_STATUS_EOF: - case CTF_MSG_ITER_MEDIUM_STATUS_AGAIN: - case CTF_MSG_ITER_MEDIUM_STATUS_ERROR: - return BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_ERROR; - case CTF_MSG_ITER_MEDIUM_STATUS_MEMORY_ERROR: - return BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_MEMORY_ERROR; - case CTF_MSG_ITER_MEDIUM_STATUS_OK: - return BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_OK; - } - - bt_common_abort(); + switch (status) { + case CTF_MSG_ITER_MEDIUM_STATUS_EOF: + case CTF_MSG_ITER_MEDIUM_STATUS_AGAIN: + case CTF_MSG_ITER_MEDIUM_STATUS_ERROR: + return BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_ERROR; + case CTF_MSG_ITER_MEDIUM_STATUS_MEMORY_ERROR: + return BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_MEMORY_ERROR; + case CTF_MSG_ITER_MEDIUM_STATUS_OK: + return BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_OK; + } + + bt_common_abort(); } BT_HIDDEN -bt_message_iterator_class_initialize_method_status ctf_fs_iterator_init( - bt_self_message_iterator *self_msg_iter, - bt_self_message_iterator_configuration *config, - bt_self_component_port_output *self_port) +bt_message_iterator_class_initialize_method_status +ctf_fs_iterator_init(bt_self_message_iterator *self_msg_iter, + bt_self_message_iterator_configuration *config, + bt_self_component_port_output *self_port) { - struct ctf_fs_port_data *port_data; - struct ctf_fs_msg_iter_data *msg_iter_data = NULL; - bt_message_iterator_class_initialize_method_status status; - bt_logging_level log_level; - enum ctf_msg_iter_medium_status medium_status; - bt_self_component *self_comp = - bt_self_message_iterator_borrow_component(self_msg_iter); - - port_data = (struct ctf_fs_port_data *) bt_self_component_port_get_data( - bt_self_component_port_output_as_self_component_port( - self_port)); - BT_ASSERT(port_data); - log_level = port_data->ctf_fs->log_level; - msg_iter_data = g_new0(struct ctf_fs_msg_iter_data, 1); - if (!msg_iter_data) { - status = BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_MEMORY_ERROR; - goto error; - } - - msg_iter_data->log_level = log_level; - msg_iter_data->self_comp = self_comp; - msg_iter_data->self_msg_iter = self_msg_iter; - msg_iter_data->ds_file_group = port_data->ds_file_group; - - medium_status = ctf_fs_ds_group_medops_data_create( - msg_iter_data->ds_file_group, self_msg_iter, log_level, - &msg_iter_data->msg_iter_medops_data); - BT_ASSERT( - medium_status == CTF_MSG_ITER_MEDIUM_STATUS_OK || - medium_status == CTF_MSG_ITER_MEDIUM_STATUS_ERROR || - medium_status == CTF_MSG_ITER_MEDIUM_STATUS_MEMORY_ERROR); - if (medium_status != CTF_MSG_ITER_MEDIUM_STATUS_OK) { - BT_MSG_ITER_LOGE_APPEND_CAUSE(self_msg_iter, - "Failed to create ctf_fs_ds_group_medops"); - status = ctf_msg_iter_medium_status_to_msg_iter_initialize_status(medium_status); - goto error; - } - - msg_iter_data->msg_iter = ctf_msg_iter_create( - msg_iter_data->ds_file_group->ctf_fs_trace->metadata->tc, - bt_common_get_page_size(msg_iter_data->log_level) * 8, - ctf_fs_ds_group_medops, - msg_iter_data->msg_iter_medops_data, - msg_iter_data->log_level, - self_comp, self_msg_iter); - if (!msg_iter_data->msg_iter) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Cannot create a CTF message iterator."); - status = BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_MEMORY_ERROR; - goto error; - } - - /* - * This iterator can seek forward if its stream class has a default - * clock class. - */ - if (msg_iter_data->ds_file_group->sc->default_clock_class) { - bt_self_message_iterator_configuration_set_can_seek_forward( - config, true); - } - - bt_self_message_iterator_set_data(self_msg_iter, - msg_iter_data); - msg_iter_data = NULL; - - status = BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_OK; - goto end; + struct ctf_fs_port_data *port_data; + struct ctf_fs_msg_iter_data *msg_iter_data = NULL; + bt_message_iterator_class_initialize_method_status status; + bt_logging_level log_level; + enum ctf_msg_iter_medium_status medium_status; + bt_self_component *self_comp = bt_self_message_iterator_borrow_component(self_msg_iter); + + port_data = (struct ctf_fs_port_data *) bt_self_component_port_get_data( + bt_self_component_port_output_as_self_component_port(self_port)); + BT_ASSERT(port_data); + log_level = port_data->ctf_fs->log_level; + msg_iter_data = g_new0(struct ctf_fs_msg_iter_data, 1); + if (!msg_iter_data) { + status = BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_MEMORY_ERROR; + goto error; + } + + msg_iter_data->log_level = log_level; + msg_iter_data->self_comp = self_comp; + msg_iter_data->self_msg_iter = self_msg_iter; + msg_iter_data->ds_file_group = port_data->ds_file_group; + + medium_status = + ctf_fs_ds_group_medops_data_create(msg_iter_data->ds_file_group, self_msg_iter, log_level, + &msg_iter_data->msg_iter_medops_data); + BT_ASSERT(medium_status == CTF_MSG_ITER_MEDIUM_STATUS_OK || + medium_status == CTF_MSG_ITER_MEDIUM_STATUS_ERROR || + medium_status == CTF_MSG_ITER_MEDIUM_STATUS_MEMORY_ERROR); + if (medium_status != CTF_MSG_ITER_MEDIUM_STATUS_OK) { + BT_MSG_ITER_LOGE_APPEND_CAUSE(self_msg_iter, "Failed to create ctf_fs_ds_group_medops"); + status = ctf_msg_iter_medium_status_to_msg_iter_initialize_status(medium_status); + goto error; + } + + msg_iter_data->msg_iter = ctf_msg_iter_create( + msg_iter_data->ds_file_group->ctf_fs_trace->metadata->tc, + bt_common_get_page_size(msg_iter_data->log_level) * 8, ctf_fs_ds_group_medops, + msg_iter_data->msg_iter_medops_data, msg_iter_data->log_level, self_comp, self_msg_iter); + if (!msg_iter_data->msg_iter) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Cannot create a CTF message iterator."); + status = BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_MEMORY_ERROR; + goto error; + } + + /* + * This iterator can seek forward if its stream class has a default + * clock class. + */ + if (msg_iter_data->ds_file_group->sc->default_clock_class) { + bt_self_message_iterator_configuration_set_can_seek_forward(config, true); + } + + bt_self_message_iterator_set_data(self_msg_iter, msg_iter_data); + msg_iter_data = NULL; + + status = BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_OK; + goto end; error: - bt_self_message_iterator_set_data(self_msg_iter, NULL); + bt_self_message_iterator_set_data(self_msg_iter, NULL); end: - ctf_fs_msg_iter_data_destroy(msg_iter_data); - return status; + ctf_fs_msg_iter_data_destroy(msg_iter_data); + return status; } -static -void ctf_fs_trace_destroy(struct ctf_fs_trace *ctf_fs_trace) +static void ctf_fs_trace_destroy(struct ctf_fs_trace *ctf_fs_trace) { - if (!ctf_fs_trace) { - return; - } + if (!ctf_fs_trace) { + return; + } - if (ctf_fs_trace->ds_file_groups) { - g_ptr_array_free(ctf_fs_trace->ds_file_groups, TRUE); - } + if (ctf_fs_trace->ds_file_groups) { + g_ptr_array_free(ctf_fs_trace->ds_file_groups, TRUE); + } - BT_TRACE_PUT_REF_AND_RESET(ctf_fs_trace->trace); + BT_TRACE_PUT_REF_AND_RESET(ctf_fs_trace->trace); - if (ctf_fs_trace->path) { - g_string_free(ctf_fs_trace->path, TRUE); - } + if (ctf_fs_trace->path) { + g_string_free(ctf_fs_trace->path, TRUE); + } - if (ctf_fs_trace->metadata) { - ctf_fs_metadata_fini(ctf_fs_trace->metadata); - g_free(ctf_fs_trace->metadata); - } + if (ctf_fs_trace->metadata) { + ctf_fs_metadata_fini(ctf_fs_trace->metadata); + g_free(ctf_fs_trace->metadata); + } - g_free(ctf_fs_trace); + g_free(ctf_fs_trace); } BT_HIDDEN void ctf_fs_destroy(struct ctf_fs_component *ctf_fs) { - if (!ctf_fs) { - return; - } + if (!ctf_fs) { + return; + } - ctf_fs_trace_destroy(ctf_fs->trace); + ctf_fs_trace_destroy(ctf_fs->trace); - if (ctf_fs->port_data) { - g_ptr_array_free(ctf_fs->port_data, TRUE); - } + if (ctf_fs->port_data) { + g_ptr_array_free(ctf_fs->port_data, TRUE); + } - g_free(ctf_fs); + g_free(ctf_fs); } -static -void port_data_destroy(struct ctf_fs_port_data *port_data) +static void port_data_destroy(struct ctf_fs_port_data *port_data) { - if (!port_data) { - return; - } + if (!port_data) { + return; + } - g_free(port_data); + g_free(port_data); } -static -void port_data_destroy_notifier(void *data) { - port_data_destroy((struct ctf_fs_port_data *) data); +static void port_data_destroy_notifier(void *data) +{ + port_data_destroy((struct ctf_fs_port_data *) data); } -static -void ctf_fs_trace_destroy_notifier(void *data) +static void ctf_fs_trace_destroy_notifier(void *data) { - struct ctf_fs_trace *trace = (struct ctf_fs_trace *) data; - ctf_fs_trace_destroy(trace); + struct ctf_fs_trace *trace = (struct ctf_fs_trace *) data; + ctf_fs_trace_destroy(trace); } struct ctf_fs_component *ctf_fs_component_create(bt_logging_level log_level, - bt_self_component *self_comp) + bt_self_component *self_comp) { - struct ctf_fs_component *ctf_fs; + struct ctf_fs_component *ctf_fs; - ctf_fs = g_new0(struct ctf_fs_component, 1); - if (!ctf_fs) { - goto error; - } + ctf_fs = g_new0(struct ctf_fs_component, 1); + if (!ctf_fs) { + goto error; + } - ctf_fs->log_level = log_level; - ctf_fs->port_data = - g_ptr_array_new_with_free_func(port_data_destroy_notifier); - if (!ctf_fs->port_data) { - goto error; - } + ctf_fs->log_level = log_level; + ctf_fs->port_data = g_ptr_array_new_with_free_func(port_data_destroy_notifier); + if (!ctf_fs->port_data) { + goto error; + } - goto end; + goto end; error: - ctf_fs_destroy(ctf_fs); - ctf_fs = NULL; + ctf_fs_destroy(ctf_fs); + ctf_fs = NULL; end: - return ctf_fs; + return ctf_fs; } void ctf_fs_finalize(bt_self_component_source *component) { - ctf_fs_destroy((struct ctf_fs_component *) bt_self_component_get_data( - bt_self_component_source_as_self_component(component))); + ctf_fs_destroy((struct ctf_fs_component *) bt_self_component_get_data( + bt_self_component_source_as_self_component(component))); } gchar *ctf_fs_make_port_name(struct ctf_fs_ds_file_group *ds_file_group) { - GString *name = g_string_new(NULL); - - /* - * The unique port name is generated by concatenating unique identifiers - * for: - * - * - the trace - * - the stream class - * - the stream - */ - - /* For the trace, use the uuid if present, else the path. */ - if (ds_file_group->ctf_fs_trace->metadata->tc->is_uuid_set) { - char uuid_str[BT_UUID_STR_LEN + 1]; - - bt_uuid_to_str(ds_file_group->ctf_fs_trace->metadata->tc->uuid, uuid_str); - g_string_assign(name, uuid_str); - } else { - g_string_assign(name, ds_file_group->ctf_fs_trace->path->str); - } - - /* - * For the stream class, use the id if present. We can omit this field - * otherwise, as there will only be a single stream class. - */ - if (ds_file_group->sc->id != UINT64_C(-1)) { - g_string_append_printf(name, " | %" PRIu64, ds_file_group->sc->id); - } - - /* For the stream, use the id if present, else, use the path. */ - if (ds_file_group->stream_id != UINT64_C(-1)) { - g_string_append_printf(name, " | %" PRIu64, ds_file_group->stream_id); - } else { - BT_ASSERT(ds_file_group->ds_file_infos->len == 1); - struct ctf_fs_ds_file_info *ds_file_info = - (struct ctf_fs_ds_file_info *) g_ptr_array_index(ds_file_group->ds_file_infos, 0); - g_string_append_printf(name, " | %s", ds_file_info->path->str); - } - - return g_string_free(name, FALSE); + GString *name = g_string_new(NULL); + + /* + * The unique port name is generated by concatenating unique identifiers + * for: + * + * - the trace + * - the stream class + * - the stream + */ + + /* For the trace, use the uuid if present, else the path. */ + if (ds_file_group->ctf_fs_trace->metadata->tc->is_uuid_set) { + char uuid_str[BT_UUID_STR_LEN + 1]; + + bt_uuid_to_str(ds_file_group->ctf_fs_trace->metadata->tc->uuid, uuid_str); + g_string_assign(name, uuid_str); + } else { + g_string_assign(name, ds_file_group->ctf_fs_trace->path->str); + } + + /* + * For the stream class, use the id if present. We can omit this field + * otherwise, as there will only be a single stream class. + */ + if (ds_file_group->sc->id != UINT64_C(-1)) { + g_string_append_printf(name, " | %" PRIu64, ds_file_group->sc->id); + } + + /* For the stream, use the id if present, else, use the path. */ + if (ds_file_group->stream_id != UINT64_C(-1)) { + g_string_append_printf(name, " | %" PRIu64, ds_file_group->stream_id); + } else { + BT_ASSERT(ds_file_group->ds_file_infos->len == 1); + struct ctf_fs_ds_file_info *ds_file_info = + (struct ctf_fs_ds_file_info *) g_ptr_array_index(ds_file_group->ds_file_infos, 0); + g_string_append_printf(name, " | %s", ds_file_info->path->str); + } + + return g_string_free(name, FALSE); } -static -int create_one_port_for_trace(struct ctf_fs_component *ctf_fs, - struct ctf_fs_trace *ctf_fs_trace, - struct ctf_fs_ds_file_group *ds_file_group, - bt_self_component_source *self_comp_src) +static int create_one_port_for_trace(struct ctf_fs_component *ctf_fs, + struct ctf_fs_trace *ctf_fs_trace, + struct ctf_fs_ds_file_group *ds_file_group, + bt_self_component_source *self_comp_src) { - int ret = 0; - struct ctf_fs_port_data *port_data = NULL; - gchar *port_name; - bt_logging_level log_level = ctf_fs->log_level; - bt_self_component *self_comp = - bt_self_component_source_as_self_component(self_comp_src); - - port_name = ctf_fs_make_port_name(ds_file_group); - if (!port_name) { - goto error; - } - - BT_COMP_LOGI("Creating one port named `%s`", port_name); - - /* Create output port for this file */ - port_data = g_new0(struct ctf_fs_port_data, 1); - if (!port_data) { - goto error; - } - - port_data->ctf_fs = ctf_fs; - port_data->ds_file_group = ds_file_group; - ret = bt_self_component_source_add_output_port( - self_comp_src, port_name, port_data, NULL); - if (ret) { - goto error; - } - - g_ptr_array_add(ctf_fs->port_data, port_data); - port_data = NULL; - goto end; + int ret = 0; + struct ctf_fs_port_data *port_data = NULL; + gchar *port_name; + bt_logging_level log_level = ctf_fs->log_level; + bt_self_component *self_comp = bt_self_component_source_as_self_component(self_comp_src); + + port_name = ctf_fs_make_port_name(ds_file_group); + if (!port_name) { + goto error; + } + + BT_COMP_LOGI("Creating one port named `%s`", port_name); + + /* Create output port for this file */ + port_data = g_new0(struct ctf_fs_port_data, 1); + if (!port_data) { + goto error; + } + + port_data->ctf_fs = ctf_fs; + port_data->ds_file_group = ds_file_group; + ret = bt_self_component_source_add_output_port(self_comp_src, port_name, port_data, NULL); + if (ret) { + goto error; + } + + g_ptr_array_add(ctf_fs->port_data, port_data); + port_data = NULL; + goto end; error: - ret = -1; + ret = -1; end: - g_free(port_name); + g_free(port_name); - port_data_destroy(port_data); - return ret; + port_data_destroy(port_data); + return ret; } -static -int create_ports_for_trace(struct ctf_fs_component *ctf_fs, - struct ctf_fs_trace *ctf_fs_trace, - bt_self_component_source *self_comp_src) +static int create_ports_for_trace(struct ctf_fs_component *ctf_fs, + struct ctf_fs_trace *ctf_fs_trace, + bt_self_component_source *self_comp_src) { - int ret = 0; - size_t i; - bt_logging_level log_level = ctf_fs_trace->log_level; - bt_self_component *self_comp = - bt_self_component_source_as_self_component(self_comp_src); - - /* Create one output port for each stream file group */ - for (i = 0; i < ctf_fs_trace->ds_file_groups->len; i++) { - struct ctf_fs_ds_file_group *ds_file_group = - (struct ctf_fs_ds_file_group *) g_ptr_array_index(ctf_fs_trace->ds_file_groups, i); - - ret = create_one_port_for_trace(ctf_fs, ctf_fs_trace, - ds_file_group, self_comp_src); - if (ret) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Cannot create output port."); - goto end; - } - } + int ret = 0; + size_t i; + bt_logging_level log_level = ctf_fs_trace->log_level; + bt_self_component *self_comp = bt_self_component_source_as_self_component(self_comp_src); + + /* Create one output port for each stream file group */ + for (i = 0; i < ctf_fs_trace->ds_file_groups->len; i++) { + struct ctf_fs_ds_file_group *ds_file_group = + (struct ctf_fs_ds_file_group *) g_ptr_array_index(ctf_fs_trace->ds_file_groups, i); + + ret = create_one_port_for_trace(ctf_fs, ctf_fs_trace, ds_file_group, self_comp_src); + if (ret) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Cannot create output port."); + goto end; + } + } end: - return ret; + return ret; } -static -void ctf_fs_ds_file_info_destroy(struct ctf_fs_ds_file_info *ds_file_info) +static void ctf_fs_ds_file_info_destroy(struct ctf_fs_ds_file_info *ds_file_info) { - if (!ds_file_info) { - return; - } + if (!ds_file_info) { + return; + } - if (ds_file_info->path) { - g_string_free(ds_file_info->path, TRUE); - } + if (ds_file_info->path) { + g_string_free(ds_file_info->path, TRUE); + } - g_free(ds_file_info); + g_free(ds_file_info); } -static -struct ctf_fs_ds_file_info *ctf_fs_ds_file_info_create(const char *path, - int64_t begin_ns) +static struct ctf_fs_ds_file_info *ctf_fs_ds_file_info_create(const char *path, int64_t begin_ns) { - struct ctf_fs_ds_file_info *ds_file_info; + struct ctf_fs_ds_file_info *ds_file_info; - ds_file_info = g_new0(struct ctf_fs_ds_file_info, 1); - if (!ds_file_info) { - goto end; - } + ds_file_info = g_new0(struct ctf_fs_ds_file_info, 1); + if (!ds_file_info) { + goto end; + } - ds_file_info->path = g_string_new(path); - if (!ds_file_info->path) { - ctf_fs_ds_file_info_destroy(ds_file_info); - ds_file_info = NULL; - goto end; - } + ds_file_info->path = g_string_new(path); + if (!ds_file_info->path) { + ctf_fs_ds_file_info_destroy(ds_file_info); + ds_file_info = NULL; + goto end; + } - ds_file_info->begin_ns = begin_ns; + ds_file_info->begin_ns = begin_ns; end: - return ds_file_info; + return ds_file_info; } -static -void ctf_fs_ds_file_group_destroy(struct ctf_fs_ds_file_group *ds_file_group) +static void ctf_fs_ds_file_group_destroy(struct ctf_fs_ds_file_group *ds_file_group) { - if (!ds_file_group) { - return; - } + if (!ds_file_group) { + return; + } - if (ds_file_group->ds_file_infos) { - g_ptr_array_free(ds_file_group->ds_file_infos, TRUE); - } + if (ds_file_group->ds_file_infos) { + g_ptr_array_free(ds_file_group->ds_file_infos, TRUE); + } - ctf_fs_ds_index_destroy(ds_file_group->index); + ctf_fs_ds_index_destroy(ds_file_group->index); - bt_stream_put_ref(ds_file_group->stream); - g_free(ds_file_group); + bt_stream_put_ref(ds_file_group->stream); + g_free(ds_file_group); } -static -struct ctf_fs_ds_file_group *ctf_fs_ds_file_group_create( - struct ctf_fs_trace *ctf_fs_trace, - struct ctf_stream_class *sc, - uint64_t stream_instance_id, - struct ctf_fs_ds_index *index) +static struct ctf_fs_ds_file_group *ctf_fs_ds_file_group_create(struct ctf_fs_trace *ctf_fs_trace, + struct ctf_stream_class *sc, + uint64_t stream_instance_id, + struct ctf_fs_ds_index *index) { - struct ctf_fs_ds_file_group *ds_file_group; + struct ctf_fs_ds_file_group *ds_file_group; - ds_file_group = g_new0(struct ctf_fs_ds_file_group, 1); - if (!ds_file_group) { - goto error; - } + ds_file_group = g_new0(struct ctf_fs_ds_file_group, 1); + if (!ds_file_group) { + goto error; + } - ds_file_group->ds_file_infos = g_ptr_array_new_with_free_func( - (GDestroyNotify) ctf_fs_ds_file_info_destroy); - if (!ds_file_group->ds_file_infos) { - goto error; - } + ds_file_group->ds_file_infos = + g_ptr_array_new_with_free_func((GDestroyNotify) ctf_fs_ds_file_info_destroy); + if (!ds_file_group->ds_file_infos) { + goto error; + } - ds_file_group->index = index; + ds_file_group->index = index; - ds_file_group->stream_id = stream_instance_id; - BT_ASSERT(sc); - ds_file_group->sc = sc; - ds_file_group->ctf_fs_trace = ctf_fs_trace; - goto end; + ds_file_group->stream_id = stream_instance_id; + BT_ASSERT(sc); + ds_file_group->sc = sc; + ds_file_group->ctf_fs_trace = ctf_fs_trace; + goto end; error: - ctf_fs_ds_file_group_destroy(ds_file_group); - ctf_fs_ds_index_destroy(index); - ds_file_group = NULL; + ctf_fs_ds_file_group_destroy(ds_file_group); + ctf_fs_ds_index_destroy(index); + ds_file_group = NULL; end: - return ds_file_group; + return ds_file_group; } /* Replace by g_ptr_array_insert when we depend on glib >= 2.40. */ -static -void array_insert(GPtrArray *array, gpointer element, size_t pos) +static void array_insert(GPtrArray *array, gpointer element, size_t pos) { - size_t original_array_len = array->len; + size_t original_array_len = array->len; - /* Allocate an unused element at the end of the array. */ - g_ptr_array_add(array, NULL); + /* Allocate an unused element at the end of the array. */ + g_ptr_array_add(array, NULL); - /* If we are not inserting at the end, move the elements by one. */ - if (pos < original_array_len) { - memmove(&(array->pdata[pos + 1]), - &(array->pdata[pos]), - (original_array_len - pos) * sizeof(gpointer)); - } + /* If we are not inserting at the end, move the elements by one. */ + if (pos < original_array_len) { + memmove(&(array->pdata[pos + 1]), &(array->pdata[pos]), + (original_array_len - pos) * sizeof(gpointer)); + } - /* Insert the value. */ - array->pdata[pos] = element; + /* Insert the value. */ + array->pdata[pos] = element; } /* @@ -622,48 +586,44 @@ void array_insert(GPtrArray *array, gpointer element, size_t pos) * place to keep it sorted. */ -static -void ds_file_group_insert_ds_file_info_sorted( - struct ctf_fs_ds_file_group *ds_file_group, - struct ctf_fs_ds_file_info *ds_file_info) +static void ds_file_group_insert_ds_file_info_sorted(struct ctf_fs_ds_file_group *ds_file_group, + struct ctf_fs_ds_file_info *ds_file_info) { - guint i; + guint i; - /* Find the spot where to insert this ds_file_info. */ - for (i = 0; i < ds_file_group->ds_file_infos->len; i++) { - struct ctf_fs_ds_file_info *other_ds_file_info = - (struct ctf_fs_ds_file_info *) g_ptr_array_index(ds_file_group->ds_file_infos, i); + /* Find the spot where to insert this ds_file_info. */ + for (i = 0; i < ds_file_group->ds_file_infos->len; i++) { + struct ctf_fs_ds_file_info *other_ds_file_info = + (struct ctf_fs_ds_file_info *) g_ptr_array_index(ds_file_group->ds_file_infos, i); - if (ds_file_info->begin_ns < other_ds_file_info->begin_ns) { - break; - } - } + if (ds_file_info->begin_ns < other_ds_file_info->begin_ns) { + break; + } + } - array_insert(ds_file_group->ds_file_infos, ds_file_info, i); + array_insert(ds_file_group->ds_file_infos, ds_file_info, i); } -static -bool ds_index_entries_equal( - const struct ctf_fs_ds_index_entry *left, - const struct ctf_fs_ds_index_entry *right) +static bool ds_index_entries_equal(const struct ctf_fs_ds_index_entry *left, + const struct ctf_fs_ds_index_entry *right) { - if (left->packet_size != right->packet_size) { - return false; - } + if (left->packet_size != right->packet_size) { + return false; + } - if (left->timestamp_begin != right->timestamp_begin) { - return false; - } + if (left->timestamp_begin != right->timestamp_begin) { + return false; + } - if (left->timestamp_end != right->timestamp_end) { - return false; - } + if (left->timestamp_end != right->timestamp_end) { + return false; + } - if (left->packet_seq_num != right->packet_seq_num) { - return false; - } + if (left->packet_seq_num != right->packet_seq_num) { + return false; + } - return true; + return true; } /* @@ -675,554 +635,520 @@ bool ds_index_entries_equal( * the entry is not inserted, it is freed. */ -static -void ds_index_insert_ds_index_entry_sorted( - struct ctf_fs_ds_index *index, - struct ctf_fs_ds_index_entry *entry) +static void ds_index_insert_ds_index_entry_sorted(struct ctf_fs_ds_index *index, + struct ctf_fs_ds_index_entry *entry) { - guint i; - struct ctf_fs_ds_index_entry *other_entry = NULL; - - /* Find the spot where to insert this index entry. */ - for (i = 0; i < index->entries->len; i++) { - other_entry = (struct ctf_fs_ds_index_entry *) g_ptr_array_index(index->entries, i); - - if (entry->timestamp_begin_ns <= other_entry->timestamp_begin_ns) { - break; - } - } - - /* - * Insert the entry only if a duplicate doesn't already exist. - * - * There can be duplicate packets if reading multiple overlapping - * snapshots of the same trace. We then want the index to contain - * a reference to only one copy of that packet. - */ - if (i == index->entries->len || - !ds_index_entries_equal(entry, other_entry)) { - array_insert(index->entries, entry, i); - } else { - g_free(entry); - } + guint i; + struct ctf_fs_ds_index_entry *other_entry = NULL; + + /* Find the spot where to insert this index entry. */ + for (i = 0; i < index->entries->len; i++) { + other_entry = (struct ctf_fs_ds_index_entry *) g_ptr_array_index(index->entries, i); + + if (entry->timestamp_begin_ns <= other_entry->timestamp_begin_ns) { + break; + } + } + + /* + * Insert the entry only if a duplicate doesn't already exist. + * + * There can be duplicate packets if reading multiple overlapping + * snapshots of the same trace. We then want the index to contain + * a reference to only one copy of that packet. + */ + if (i == index->entries->len || !ds_index_entries_equal(entry, other_entry)) { + array_insert(index->entries, entry, i); + } else { + g_free(entry); + } } -static -void merge_ctf_fs_ds_indexes(struct ctf_fs_ds_index *dest, struct ctf_fs_ds_index *src) +static void merge_ctf_fs_ds_indexes(struct ctf_fs_ds_index *dest, struct ctf_fs_ds_index *src) { - guint i; + guint i; - for (i = 0; i < src->entries->len; i++) { - struct ctf_fs_ds_index_entry *entry = - (struct ctf_fs_ds_index_entry *) g_ptr_array_index(src->entries, i); + for (i = 0; i < src->entries->len; i++) { + struct ctf_fs_ds_index_entry *entry = + (struct ctf_fs_ds_index_entry *) g_ptr_array_index(src->entries, i); - /* + /* * Ownership of the ctf_fs_ds_index_entry is transferred to * ds_index_insert_ds_index_entry_sorted. */ - g_ptr_array_index(src->entries, i) = NULL; - ds_index_insert_ds_index_entry_sorted(dest, entry); - } + g_ptr_array_index(src->entries, i) = NULL; + ds_index_insert_ds_index_entry_sorted(dest, entry); + } } -static -int add_ds_file_to_ds_file_group(struct ctf_fs_trace *ctf_fs_trace, - const char *path) +static int add_ds_file_to_ds_file_group(struct ctf_fs_trace *ctf_fs_trace, const char *path) { - int64_t stream_instance_id = -1; - int64_t begin_ns = -1; - struct ctf_fs_ds_file_group *ds_file_group = NULL; - bool add_group = false; - int ret; - size_t i; - struct ctf_fs_ds_file *ds_file = NULL; - struct ctf_fs_ds_file_info *ds_file_info = NULL; - struct ctf_fs_ds_index *index = NULL; - struct ctf_msg_iter *msg_iter = NULL; - struct ctf_stream_class *sc = NULL; - struct ctf_msg_iter_packet_properties props; - bt_logging_level log_level = ctf_fs_trace->log_level; - bt_self_component *self_comp = ctf_fs_trace->self_comp; - bt_self_component_class *self_comp_class = ctf_fs_trace->self_comp_class; - - /* - * Create a temporary ds_file to read some properties about the data - * stream file. - */ - ds_file = ctf_fs_ds_file_create(ctf_fs_trace, NULL, NULL, path, - log_level); - if (!ds_file) { - goto error; - } - - /* Create a temporary iterator to read the ds_file. */ - msg_iter = ctf_msg_iter_create(ctf_fs_trace->metadata->tc, - bt_common_get_page_size(log_level) * 8, - ctf_fs_ds_file_medops, ds_file, log_level, self_comp, NULL); - if (!msg_iter) { - BT_COMP_LOGE_STR("Cannot create a CTF message iterator."); - goto error; - } - - ctf_msg_iter_set_dry_run(msg_iter, true); - - ret = ctf_msg_iter_get_packet_properties(msg_iter, &props); - if (ret) { - BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class, - "Cannot get stream file's first packet's header and context fields (`%s`).", - path); - goto error; - } - - sc = ctf_trace_class_borrow_stream_class_by_id(ds_file->metadata->tc, - props.stream_class_id); - BT_ASSERT(sc); - stream_instance_id = props.data_stream_id; - - if (props.snapshots.beginning_clock != UINT64_C(-1)) { - BT_ASSERT(sc->default_clock_class); - ret = bt_util_clock_cycles_to_ns_from_origin( - props.snapshots.beginning_clock, - sc->default_clock_class->frequency, - sc->default_clock_class->offset_seconds, - sc->default_clock_class->offset_cycles, &begin_ns); - if (ret) { - BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class, - "Cannot convert clock cycles to nanoseconds from origin (`%s`).", - path); - goto error; - } - } - - ds_file_info = ctf_fs_ds_file_info_create(path, begin_ns); - if (!ds_file_info) { - goto error; - } - - index = ctf_fs_ds_file_build_index(ds_file, ds_file_info, msg_iter); - if (!index) { - BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( - self_comp, self_comp_class, - "Failed to index CTF stream file \'%s\'", - ds_file->file->path->str); - goto error; - } - - if (begin_ns == -1) { - /* - * No beginning timestamp to sort the stream files - * within a stream file group, so consider that this - * file must be the only one within its group. - */ - stream_instance_id = -1; - } - - if (stream_instance_id == -1) { - /* - * No stream instance ID or no beginning timestamp: - * create a unique stream file group for this stream - * file because, even if there's a stream instance ID, - * there's no timestamp to order the file within its - * group. - */ - ds_file_group = ctf_fs_ds_file_group_create(ctf_fs_trace, - sc, UINT64_C(-1), index); - /* Ownership of index is transferred. */ - index = NULL; - - if (!ds_file_group) { - goto error; - } - - ds_file_group_insert_ds_file_info_sorted(ds_file_group, - BT_MOVE_REF(ds_file_info)); - - add_group = true; - goto end; - } - - BT_ASSERT(stream_instance_id != -1); - BT_ASSERT(begin_ns != -1); - - /* Find an existing stream file group with this ID */ - for (i = 0; i < ctf_fs_trace->ds_file_groups->len; i++) { - ds_file_group = (struct ctf_fs_ds_file_group *) g_ptr_array_index( - ctf_fs_trace->ds_file_groups, i); - - if (ds_file_group->sc == sc && - ds_file_group->stream_id == - stream_instance_id) { - break; - } - - ds_file_group = NULL; - } - - if (!ds_file_group) { - ds_file_group = ctf_fs_ds_file_group_create(ctf_fs_trace, - sc, stream_instance_id, index); - /* Ownership of index is transferred. */ - index = NULL; - if (!ds_file_group) { - goto error; - } - - add_group = true; - } else { - merge_ctf_fs_ds_indexes(ds_file_group->index, index); - } - - ds_file_group_insert_ds_file_info_sorted(ds_file_group, - BT_MOVE_REF(ds_file_info)); - - goto end; + int64_t stream_instance_id = -1; + int64_t begin_ns = -1; + struct ctf_fs_ds_file_group *ds_file_group = NULL; + bool add_group = false; + int ret; + size_t i; + struct ctf_fs_ds_file *ds_file = NULL; + struct ctf_fs_ds_file_info *ds_file_info = NULL; + struct ctf_fs_ds_index *index = NULL; + struct ctf_msg_iter *msg_iter = NULL; + struct ctf_stream_class *sc = NULL; + struct ctf_msg_iter_packet_properties props; + bt_logging_level log_level = ctf_fs_trace->log_level; + bt_self_component *self_comp = ctf_fs_trace->self_comp; + bt_self_component_class *self_comp_class = ctf_fs_trace->self_comp_class; + + /* + * Create a temporary ds_file to read some properties about the data + * stream file. + */ + ds_file = ctf_fs_ds_file_create(ctf_fs_trace, NULL, NULL, path, log_level); + if (!ds_file) { + goto error; + } + + /* Create a temporary iterator to read the ds_file. */ + msg_iter = + ctf_msg_iter_create(ctf_fs_trace->metadata->tc, bt_common_get_page_size(log_level) * 8, + ctf_fs_ds_file_medops, ds_file, log_level, self_comp, NULL); + if (!msg_iter) { + BT_COMP_LOGE_STR("Cannot create a CTF message iterator."); + goto error; + } + + ctf_msg_iter_set_dry_run(msg_iter, true); + + ret = ctf_msg_iter_get_packet_properties(msg_iter, &props); + if (ret) { + BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + self_comp, self_comp_class, + "Cannot get stream file's first packet's header and context fields (`%s`).", path); + goto error; + } + + sc = ctf_trace_class_borrow_stream_class_by_id(ds_file->metadata->tc, props.stream_class_id); + BT_ASSERT(sc); + stream_instance_id = props.data_stream_id; + + if (props.snapshots.beginning_clock != UINT64_C(-1)) { + BT_ASSERT(sc->default_clock_class); + ret = bt_util_clock_cycles_to_ns_from_origin( + props.snapshots.beginning_clock, sc->default_clock_class->frequency, + sc->default_clock_class->offset_seconds, sc->default_clock_class->offset_cycles, + &begin_ns); + if (ret) { + BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + self_comp, self_comp_class, + "Cannot convert clock cycles to nanoseconds from origin (`%s`).", path); + goto error; + } + } + + ds_file_info = ctf_fs_ds_file_info_create(path, begin_ns); + if (!ds_file_info) { + goto error; + } + + index = ctf_fs_ds_file_build_index(ds_file, ds_file_info, msg_iter); + if (!index) { + BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class, + "Failed to index CTF stream file \'%s\'", + ds_file->file->path->str); + goto error; + } + + if (begin_ns == -1) { + /* + * No beginning timestamp to sort the stream files + * within a stream file group, so consider that this + * file must be the only one within its group. + */ + stream_instance_id = -1; + } + + if (stream_instance_id == -1) { + /* + * No stream instance ID or no beginning timestamp: + * create a unique stream file group for this stream + * file because, even if there's a stream instance ID, + * there's no timestamp to order the file within its + * group. + */ + ds_file_group = ctf_fs_ds_file_group_create(ctf_fs_trace, sc, UINT64_C(-1), index); + /* Ownership of index is transferred. */ + index = NULL; + + if (!ds_file_group) { + goto error; + } + + ds_file_group_insert_ds_file_info_sorted(ds_file_group, BT_MOVE_REF(ds_file_info)); + + add_group = true; + goto end; + } + + BT_ASSERT(stream_instance_id != -1); + BT_ASSERT(begin_ns != -1); + + /* Find an existing stream file group with this ID */ + for (i = 0; i < ctf_fs_trace->ds_file_groups->len; i++) { + ds_file_group = + (struct ctf_fs_ds_file_group *) g_ptr_array_index(ctf_fs_trace->ds_file_groups, i); + + if (ds_file_group->sc == sc && ds_file_group->stream_id == stream_instance_id) { + break; + } + + ds_file_group = NULL; + } + + if (!ds_file_group) { + ds_file_group = ctf_fs_ds_file_group_create(ctf_fs_trace, sc, stream_instance_id, index); + /* Ownership of index is transferred. */ + index = NULL; + if (!ds_file_group) { + goto error; + } + + add_group = true; + } else { + merge_ctf_fs_ds_indexes(ds_file_group->index, index); + } + + ds_file_group_insert_ds_file_info_sorted(ds_file_group, BT_MOVE_REF(ds_file_info)); + + goto end; error: - ctf_fs_ds_file_group_destroy(ds_file_group); - ds_file_group = NULL; - ret = -1; + ctf_fs_ds_file_group_destroy(ds_file_group); + ds_file_group = NULL; + ret = -1; end: - if (add_group && ds_file_group) { - g_ptr_array_add(ctf_fs_trace->ds_file_groups, ds_file_group); - } + if (add_group && ds_file_group) { + g_ptr_array_add(ctf_fs_trace->ds_file_groups, ds_file_group); + } - ctf_fs_ds_file_destroy(ds_file); - ctf_fs_ds_file_info_destroy(ds_file_info); + ctf_fs_ds_file_destroy(ds_file); + ctf_fs_ds_file_info_destroy(ds_file_info); - if (msg_iter) { - ctf_msg_iter_destroy(msg_iter); - } + if (msg_iter) { + ctf_msg_iter_destroy(msg_iter); + } - ctf_fs_ds_index_destroy(index); - return ret; + ctf_fs_ds_index_destroy(index); + return ret; } -static -int create_ds_file_groups(struct ctf_fs_trace *ctf_fs_trace) +static int create_ds_file_groups(struct ctf_fs_trace *ctf_fs_trace) { - int ret = 0; - const char *basename; - GError *error = NULL; - GDir *dir = NULL; - bt_logging_level log_level = ctf_fs_trace->log_level; - bt_self_component *self_comp = ctf_fs_trace->self_comp; - bt_self_component_class *self_comp_class = ctf_fs_trace->self_comp_class; - - /* Check each file in the path directory, except specific ones */ - dir = g_dir_open(ctf_fs_trace->path->str, 0, &error); - if (!dir) { - BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class, - "Cannot open directory `%s`: %s (code %d)", - ctf_fs_trace->path->str, error->message, - error->code); - goto error; - } - - while ((basename = g_dir_read_name(dir))) { - struct ctf_fs_file *file; - - if (strcmp(basename, CTF_FS_METADATA_FILENAME) == 0) { - /* Ignore the metadata stream. */ - BT_COMP_LOGI("Ignoring metadata file `%s" G_DIR_SEPARATOR_S "%s`", - ctf_fs_trace->path->str, basename); - continue; - } - - if (basename[0] == '.') { - BT_COMP_LOGI("Ignoring hidden file `%s" G_DIR_SEPARATOR_S "%s`", - ctf_fs_trace->path->str, basename); - continue; - } - - /* Create the file. */ - file = ctf_fs_file_create(log_level, self_comp); - if (!file) { - BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class, - "Cannot create stream file object for file `%s" G_DIR_SEPARATOR_S "%s`", - ctf_fs_trace->path->str, basename); - goto error; - } - - /* Create full path string. */ - g_string_append_printf(file->path, "%s" G_DIR_SEPARATOR_S "%s", - ctf_fs_trace->path->str, basename); - if (!g_file_test(file->path->str, G_FILE_TEST_IS_REGULAR)) { - BT_COMP_LOGI("Ignoring non-regular file `%s`", - file->path->str); - ctf_fs_file_destroy(file); - file = NULL; - continue; - } - - ret = ctf_fs_file_open(file, "rb"); - if (ret) { - BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class, - "Cannot open stream file `%s`", - file->path->str); - goto error; - } - - if (file->size == 0) { - /* Skip empty stream. */ - BT_COMP_LOGI("Ignoring empty file `%s`", file->path->str); - ctf_fs_file_destroy(file); - continue; - } - - ret = add_ds_file_to_ds_file_group(ctf_fs_trace, - file->path->str); - if (ret) { - BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class, - "Cannot add stream file `%s` to stream file group", - file->path->str); - ctf_fs_file_destroy(file); - goto error; - } - - ctf_fs_file_destroy(file); - } - - goto end; + int ret = 0; + const char *basename; + GError *error = NULL; + GDir *dir = NULL; + bt_logging_level log_level = ctf_fs_trace->log_level; + bt_self_component *self_comp = ctf_fs_trace->self_comp; + bt_self_component_class *self_comp_class = ctf_fs_trace->self_comp_class; + + /* Check each file in the path directory, except specific ones */ + dir = g_dir_open(ctf_fs_trace->path->str, 0, &error); + if (!dir) { + BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + self_comp, self_comp_class, "Cannot open directory `%s`: %s (code %d)", + ctf_fs_trace->path->str, error->message, error->code); + goto error; + } + + while ((basename = g_dir_read_name(dir))) { + struct ctf_fs_file *file; + + if (strcmp(basename, CTF_FS_METADATA_FILENAME) == 0) { + /* Ignore the metadata stream. */ + BT_COMP_LOGI("Ignoring metadata file `%s" G_DIR_SEPARATOR_S "%s`", + ctf_fs_trace->path->str, basename); + continue; + } + + if (basename[0] == '.') { + BT_COMP_LOGI("Ignoring hidden file `%s" G_DIR_SEPARATOR_S "%s`", + ctf_fs_trace->path->str, basename); + continue; + } + + /* Create the file. */ + file = ctf_fs_file_create(log_level, self_comp); + if (!file) { + BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + self_comp, self_comp_class, + "Cannot create stream file object for file `%s" G_DIR_SEPARATOR_S "%s`", + ctf_fs_trace->path->str, basename); + goto error; + } + + /* Create full path string. */ + g_string_append_printf(file->path, "%s" G_DIR_SEPARATOR_S "%s", ctf_fs_trace->path->str, + basename); + if (!g_file_test(file->path->str, G_FILE_TEST_IS_REGULAR)) { + BT_COMP_LOGI("Ignoring non-regular file `%s`", file->path->str); + ctf_fs_file_destroy(file); + file = NULL; + continue; + } + + ret = ctf_fs_file_open(file, "rb"); + if (ret) { + BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + self_comp, self_comp_class, "Cannot open stream file `%s`", file->path->str); + goto error; + } + + if (file->size == 0) { + /* Skip empty stream. */ + BT_COMP_LOGI("Ignoring empty file `%s`", file->path->str); + ctf_fs_file_destroy(file); + continue; + } + + ret = add_ds_file_to_ds_file_group(ctf_fs_trace, file->path->str); + if (ret) { + BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + self_comp, self_comp_class, "Cannot add stream file `%s` to stream file group", + file->path->str); + ctf_fs_file_destroy(file); + goto error; + } + + ctf_fs_file_destroy(file); + } + + goto end; error: - ret = -1; + ret = -1; end: - if (dir) { - g_dir_close(dir); - dir = NULL; - } + if (dir) { + g_dir_close(dir); + dir = NULL; + } - if (error) { - g_error_free(error); - } + if (error) { + g_error_free(error); + } - return ret; + return ret; } -static -int set_trace_name(bt_trace *trace, const char *name_suffix, - bt_logging_level log_level, bt_self_component *self_comp) +static int set_trace_name(bt_trace *trace, const char *name_suffix, bt_logging_level log_level, + bt_self_component *self_comp) { - int ret = 0; - const bt_value *val; - GString *name; - - name = g_string_new(NULL); - if (!name) { - BT_COMP_LOGE_STR("Failed to allocate a GString."); - ret = -1; - goto end; - } - - /* - * Check if we have a trace environment string value named `hostname`. - * If so, use it as the trace name's prefix. - */ - val = bt_trace_borrow_environment_entry_value_by_name_const( - trace, "hostname"); - if (val && bt_value_is_string(val)) { - g_string_append(name, bt_value_string_get(val)); - - if (name_suffix) { - g_string_append_c(name, G_DIR_SEPARATOR); - } - } - - if (name_suffix) { - g_string_append(name, name_suffix); - } - - ret = bt_trace_set_name(trace, name->str); - if (ret) { - goto end; - } - - goto end; + int ret = 0; + const bt_value *val; + GString *name; + + name = g_string_new(NULL); + if (!name) { + BT_COMP_LOGE_STR("Failed to allocate a GString."); + ret = -1; + goto end; + } + + /* + * Check if we have a trace environment string value named `hostname`. + * If so, use it as the trace name's prefix. + */ + val = bt_trace_borrow_environment_entry_value_by_name_const(trace, "hostname"); + if (val && bt_value_is_string(val)) { + g_string_append(name, bt_value_string_get(val)); + + if (name_suffix) { + g_string_append_c(name, G_DIR_SEPARATOR); + } + } + + if (name_suffix) { + g_string_append(name, name_suffix); + } + + ret = bt_trace_set_name(trace, name->str); + if (ret) { + goto end; + } + + goto end; end: - if (name) { - g_string_free(name, TRUE); - } + if (name) { + g_string_free(name, TRUE); + } - return ret; + return ret; } -static -struct ctf_fs_trace *ctf_fs_trace_create( - bt_self_component *self_comp, - bt_self_component_class *self_comp_class, - const char *path, const char *name, - struct ctf_fs_metadata_config *metadata_config, - bt_logging_level log_level) +static struct ctf_fs_trace *ctf_fs_trace_create(bt_self_component *self_comp, + bt_self_component_class *self_comp_class, + const char *path, const char *name, + struct ctf_fs_metadata_config *metadata_config, + bt_logging_level log_level) { - struct ctf_fs_trace *ctf_fs_trace; - int ret; - - /* Only one of them must be set. */ - BT_ASSERT(!self_comp != !self_comp_class); - - ctf_fs_trace = g_new0(struct ctf_fs_trace, 1); - if (!ctf_fs_trace) { - goto end; - } - - ctf_fs_trace->log_level = log_level; - ctf_fs_trace->self_comp = self_comp; - ctf_fs_trace->self_comp_class = self_comp_class; - ctf_fs_trace->path = g_string_new(path); - if (!ctf_fs_trace->path) { - goto error; - } - - ctf_fs_trace->metadata = g_new0(struct ctf_fs_metadata, 1); - if (!ctf_fs_trace->metadata) { - goto error; - } - - ctf_fs_metadata_init(ctf_fs_trace->metadata); - ctf_fs_trace->ds_file_groups = g_ptr_array_new_with_free_func( - (GDestroyNotify) ctf_fs_ds_file_group_destroy); - if (!ctf_fs_trace->ds_file_groups) { - goto error; - } - - ret = ctf_fs_metadata_set_trace_class(self_comp, ctf_fs_trace, - metadata_config); - if (ret) { - goto error; - } - - if (ctf_fs_trace->metadata->trace_class) { - ctf_fs_trace->trace = - bt_trace_create(ctf_fs_trace->metadata->trace_class); - if (!ctf_fs_trace->trace) { - goto error; - } - } - - if (ctf_fs_trace->trace) { - ret = ctf_trace_class_configure_ir_trace( - ctf_fs_trace->metadata->tc, ctf_fs_trace->trace); - if (ret) { - goto error; - } - - ret = set_trace_name(ctf_fs_trace->trace, name, log_level, - self_comp); - if (ret) { - goto error; - } - } - - ret = create_ds_file_groups(ctf_fs_trace); - if (ret) { - goto error; - } - - goto end; + struct ctf_fs_trace *ctf_fs_trace; + int ret; + + /* Only one of them must be set. */ + BT_ASSERT(!self_comp != !self_comp_class); + + ctf_fs_trace = g_new0(struct ctf_fs_trace, 1); + if (!ctf_fs_trace) { + goto end; + } + + ctf_fs_trace->log_level = log_level; + ctf_fs_trace->self_comp = self_comp; + ctf_fs_trace->self_comp_class = self_comp_class; + ctf_fs_trace->path = g_string_new(path); + if (!ctf_fs_trace->path) { + goto error; + } + + ctf_fs_trace->metadata = g_new0(struct ctf_fs_metadata, 1); + if (!ctf_fs_trace->metadata) { + goto error; + } + + ctf_fs_metadata_init(ctf_fs_trace->metadata); + ctf_fs_trace->ds_file_groups = + g_ptr_array_new_with_free_func((GDestroyNotify) ctf_fs_ds_file_group_destroy); + if (!ctf_fs_trace->ds_file_groups) { + goto error; + } + + ret = ctf_fs_metadata_set_trace_class(self_comp, ctf_fs_trace, metadata_config); + if (ret) { + goto error; + } + + if (ctf_fs_trace->metadata->trace_class) { + ctf_fs_trace->trace = bt_trace_create(ctf_fs_trace->metadata->trace_class); + if (!ctf_fs_trace->trace) { + goto error; + } + } + + if (ctf_fs_trace->trace) { + ret = ctf_trace_class_configure_ir_trace(ctf_fs_trace->metadata->tc, ctf_fs_trace->trace); + if (ret) { + goto error; + } + + ret = set_trace_name(ctf_fs_trace->trace, name, log_level, self_comp); + if (ret) { + goto error; + } + } + + ret = create_ds_file_groups(ctf_fs_trace); + if (ret) { + goto error; + } + + goto end; error: - ctf_fs_trace_destroy(ctf_fs_trace); - ctf_fs_trace = NULL; + ctf_fs_trace_destroy(ctf_fs_trace); + ctf_fs_trace = NULL; end: - return ctf_fs_trace; + return ctf_fs_trace; } -static -int path_is_ctf_trace(const char *path) +static int path_is_ctf_trace(const char *path) { - GString *metadata_path = g_string_new(NULL); - int ret = 0; + GString *metadata_path = g_string_new(NULL); + int ret = 0; - if (!metadata_path) { - ret = -1; - goto end; - } + if (!metadata_path) { + ret = -1; + goto end; + } - g_string_printf(metadata_path, "%s" G_DIR_SEPARATOR_S "%s", path, CTF_FS_METADATA_FILENAME); + g_string_printf(metadata_path, "%s" G_DIR_SEPARATOR_S "%s", path, CTF_FS_METADATA_FILENAME); - if (g_file_test(metadata_path->str, G_FILE_TEST_IS_REGULAR)) { - ret = 1; - goto end; - } + if (g_file_test(metadata_path->str, G_FILE_TEST_IS_REGULAR)) { + ret = 1; + goto end; + } end: - g_string_free(metadata_path, TRUE); - return ret; + g_string_free(metadata_path, TRUE); + return ret; } /* Helper for ctf_fs_component_create_ctf_fs_trace, to handle a single path. */ -static -int ctf_fs_component_create_ctf_fs_trace_one_path( - struct ctf_fs_component *ctf_fs, - const char *path_param, - const char *trace_name, - GPtrArray *traces, - bt_self_component *self_comp, - bt_self_component_class *self_comp_class) +static int ctf_fs_component_create_ctf_fs_trace_one_path(struct ctf_fs_component *ctf_fs, + const char *path_param, + const char *trace_name, GPtrArray *traces, + bt_self_component *self_comp, + bt_self_component_class *self_comp_class) { - struct ctf_fs_trace *ctf_fs_trace; - int ret; - GString *norm_path; - bt_logging_level log_level = ctf_fs->log_level; - - norm_path = bt_common_normalize_path(path_param, NULL); - if (!norm_path) { - BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class, - "Failed to normalize path: `%s`.", - path_param); - goto error; - } - - ret = path_is_ctf_trace(norm_path->str); - if (ret < 0) { - BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class, - "Failed to check if path is a CTF trace: path=%s", - norm_path->str); - goto error; - } else if (ret == 0) { - BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class, - "Path is not a CTF trace (does not contain a metadata file): `%s`.", - norm_path->str); - goto error; - } - - // FIXME: Remove or ifdef for __MINGW32__ - if (strcmp(norm_path->str, "/") == 0) { - BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class, - "Opening a trace in `/` is not supported."); - ret = -1; - goto end; - } - - ctf_fs_trace = ctf_fs_trace_create(self_comp, self_comp_class, norm_path->str, - trace_name, &ctf_fs->metadata_config, log_level); - if (!ctf_fs_trace) { - BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class, - "Cannot create trace for `%s`.", - norm_path->str); - goto error; - } - - g_ptr_array_add(traces, ctf_fs_trace); - ctf_fs_trace = NULL; - - ret = 0; - goto end; + struct ctf_fs_trace *ctf_fs_trace; + int ret; + GString *norm_path; + bt_logging_level log_level = ctf_fs->log_level; + + norm_path = bt_common_normalize_path(path_param, NULL); + if (!norm_path) { + BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class, + "Failed to normalize path: `%s`.", path_param); + goto error; + } + + ret = path_is_ctf_trace(norm_path->str); + if (ret < 0) { + BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class, + "Failed to check if path is a CTF trace: path=%s", + norm_path->str); + goto error; + } else if (ret == 0) { + BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + self_comp, self_comp_class, + "Path is not a CTF trace (does not contain a metadata file): `%s`.", norm_path->str); + goto error; + } + + // FIXME: Remove or ifdef for __MINGW32__ + if (strcmp(norm_path->str, "/") == 0) { + BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class, + "Opening a trace in `/` is not supported."); + ret = -1; + goto end; + } + + ctf_fs_trace = ctf_fs_trace_create(self_comp, self_comp_class, norm_path->str, trace_name, + &ctf_fs->metadata_config, log_level); + if (!ctf_fs_trace) { + BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class, + "Cannot create trace for `%s`.", norm_path->str); + goto error; + } + + g_ptr_array_add(traces, ctf_fs_trace); + ctf_fs_trace = NULL; + + ret = 0; + goto end; error: - ret = -1; + ret = -1; end: - if (norm_path) { - g_string_free(norm_path, TRUE); - } + if (norm_path) { + g_string_free(norm_path, TRUE); + } - return ret; + return ret; } /* @@ -1234,19 +1160,18 @@ end: * enough to just count the classes. */ -static -unsigned int metadata_count_stream_and_event_classes(struct ctf_fs_trace *trace) +static unsigned int metadata_count_stream_and_event_classes(struct ctf_fs_trace *trace) { - unsigned int num = trace->metadata->tc->stream_classes->len; - guint i; + unsigned int num = trace->metadata->tc->stream_classes->len; + guint i; - for (i = 0; i < trace->metadata->tc->stream_classes->len; i++) { - struct ctf_stream_class *sc = - (struct ctf_stream_class *) trace->metadata->tc->stream_classes->pdata[i]; - num += sc->event_classes->len; - } + for (i = 0; i < trace->metadata->tc->stream_classes->len; i++) { + struct ctf_stream_class *sc = + (struct ctf_stream_class *) trace->metadata->tc->stream_classes->pdata[i]; + num += sc->event_classes->len; + } - return num; + return num; } /* @@ -1254,117 +1179,112 @@ unsigned int metadata_count_stream_and_event_classes(struct ctf_fs_trace *trace) * ds_file_infos, making sure to keep the result sorted. */ -static -void merge_ctf_fs_ds_file_groups(struct ctf_fs_ds_file_group *dest, struct ctf_fs_ds_file_group *src) +static void merge_ctf_fs_ds_file_groups(struct ctf_fs_ds_file_group *dest, + struct ctf_fs_ds_file_group *src) { - guint i; + guint i; - for (i = 0; i < src->ds_file_infos->len; i++) { - struct ctf_fs_ds_file_info *ds_file_info = - (struct ctf_fs_ds_file_info *) g_ptr_array_index(src->ds_file_infos, i); + for (i = 0; i < src->ds_file_infos->len; i++) { + struct ctf_fs_ds_file_info *ds_file_info = + (struct ctf_fs_ds_file_info *) g_ptr_array_index(src->ds_file_infos, i); - /* Ownership of the ds_file_info is transferred to dest. */ - g_ptr_array_index(src->ds_file_infos, i) = NULL; + /* Ownership of the ds_file_info is transferred to dest. */ + g_ptr_array_index(src->ds_file_infos, i) = NULL; - ds_file_group_insert_ds_file_info_sorted(dest, ds_file_info); - } + ds_file_group_insert_ds_file_info_sorted(dest, ds_file_info); + } - /* Merge both indexes. */ - merge_ctf_fs_ds_indexes(dest->index, src->index); + /* Merge both indexes. */ + merge_ctf_fs_ds_indexes(dest->index, src->index); } /* Merge src_trace's data stream file groups into dest_trace's. */ -static -int merge_matching_ctf_fs_ds_file_groups( - struct ctf_fs_trace *dest_trace, - struct ctf_fs_trace *src_trace) +static int merge_matching_ctf_fs_ds_file_groups(struct ctf_fs_trace *dest_trace, + struct ctf_fs_trace *src_trace) { - - GPtrArray *dest = dest_trace->ds_file_groups; - GPtrArray *src = src_trace->ds_file_groups; - guint s_i; - int ret = 0; - - /* - * Save the initial length of dest: we only want to check against the - * original elements in the inner loop. - */ - const guint dest_len = dest->len; - - for (s_i = 0; s_i < src->len; s_i++) { - struct ctf_fs_ds_file_group *src_group = - (struct ctf_fs_ds_file_group *) g_ptr_array_index(src, s_i); - struct ctf_fs_ds_file_group *dest_group = NULL; - - /* A stream instance without ID can't match a stream in the other trace. */ - if (src_group->stream_id != -1) { - guint d_i; - - /* Let's search for a matching ds_file_group in the destination. */ - for (d_i = 0; d_i < dest_len; d_i++) { - struct ctf_fs_ds_file_group *candidate_dest = - (struct ctf_fs_ds_file_group *) g_ptr_array_index(dest, d_i); - - /* Can't match a stream instance without ID. */ - if (candidate_dest->stream_id == -1) { - continue; - } - - /* - * If the two groups have the same stream instance id - * and belong to the same stream class (stream instance - * ids are per-stream class), they represent the same - * stream instance. - */ - if (candidate_dest->stream_id != src_group->stream_id || - candidate_dest->sc->id != src_group->sc->id) { - continue; - } - - dest_group = candidate_dest; - break; - } - } - - /* - * Didn't find a friend in dest to merge our src_group into? - * Create a new empty one. This can happen if a stream was - * active in the source trace chunk but not in the destination - * trace chunk. - */ - if (!dest_group) { - struct ctf_stream_class *sc; - struct ctf_fs_ds_index *index; - - sc = ctf_trace_class_borrow_stream_class_by_id( - dest_trace->metadata->tc, src_group->sc->id); - BT_ASSERT(sc); - - index = ctf_fs_ds_index_create(dest_trace->log_level, - dest_trace->self_comp); - if (!index) { - ret = -1; - goto end; - } - - dest_group = ctf_fs_ds_file_group_create(dest_trace, sc, - src_group->stream_id, index); - /* Ownership of index is transferred. */ - index = NULL; - if (!dest_group) { - ret = -1; - goto end; - } - - g_ptr_array_add(dest_trace->ds_file_groups, dest_group); - } - - BT_ASSERT(dest_group); - merge_ctf_fs_ds_file_groups(dest_group, src_group); - } + GPtrArray *dest = dest_trace->ds_file_groups; + GPtrArray *src = src_trace->ds_file_groups; + guint s_i; + int ret = 0; + + /* + * Save the initial length of dest: we only want to check against the + * original elements in the inner loop. + */ + const guint dest_len = dest->len; + + for (s_i = 0; s_i < src->len; s_i++) { + struct ctf_fs_ds_file_group *src_group = + (struct ctf_fs_ds_file_group *) g_ptr_array_index(src, s_i); + struct ctf_fs_ds_file_group *dest_group = NULL; + + /* A stream instance without ID can't match a stream in the other trace. */ + if (src_group->stream_id != -1) { + guint d_i; + + /* Let's search for a matching ds_file_group in the destination. */ + for (d_i = 0; d_i < dest_len; d_i++) { + struct ctf_fs_ds_file_group *candidate_dest = + (struct ctf_fs_ds_file_group *) g_ptr_array_index(dest, d_i); + + /* Can't match a stream instance without ID. */ + if (candidate_dest->stream_id == -1) { + continue; + } + + /* + * If the two groups have the same stream instance id + * and belong to the same stream class (stream instance + * ids are per-stream class), they represent the same + * stream instance. + */ + if (candidate_dest->stream_id != src_group->stream_id || + candidate_dest->sc->id != src_group->sc->id) { + continue; + } + + dest_group = candidate_dest; + break; + } + } + + /* + * Didn't find a friend in dest to merge our src_group into? + * Create a new empty one. This can happen if a stream was + * active in the source trace chunk but not in the destination + * trace chunk. + */ + if (!dest_group) { + struct ctf_stream_class *sc; + struct ctf_fs_ds_index *index; + + sc = ctf_trace_class_borrow_stream_class_by_id(dest_trace->metadata->tc, + src_group->sc->id); + BT_ASSERT(sc); + + index = ctf_fs_ds_index_create(dest_trace->log_level, dest_trace->self_comp); + if (!index) { + ret = -1; + goto end; + } + + dest_group = ctf_fs_ds_file_group_create(dest_trace, sc, src_group->stream_id, index); + /* Ownership of index is transferred. */ + index = NULL; + if (!dest_group) { + ret = -1; + goto end; + } + + g_ptr_array_add(dest_trace->ds_file_groups, dest_group); + } + + BT_ASSERT(dest_group); + merge_ctf_fs_ds_file_groups(dest_group, src_group); + } end: - return ret; + return ret; } /* @@ -1377,182 +1297,177 @@ end: * remains non-NULL. */ -static -int merge_ctf_fs_traces(struct ctf_fs_trace **traces, unsigned int num_traces, - struct ctf_fs_trace **out_trace) +static int merge_ctf_fs_traces(struct ctf_fs_trace **traces, unsigned int num_traces, + struct ctf_fs_trace **out_trace) { - unsigned int winner_count; - struct ctf_fs_trace *winner; - guint i, winner_i; - int ret = 0; - - BT_ASSERT(num_traces >= 2); - - winner_count = metadata_count_stream_and_event_classes(traces[0]); - winner = traces[0]; - winner_i = 0; - - /* Find the trace with the largest metadata. */ - for (i = 1; i < num_traces; i++) { - struct ctf_fs_trace *candidate; - unsigned int candidate_count; - - candidate = traces[i]; - - /* A bit of sanity check. */ - BT_ASSERT(bt_uuid_compare(winner->metadata->tc->uuid, candidate->metadata->tc->uuid) == 0); - - candidate_count = metadata_count_stream_and_event_classes(candidate); - - if (candidate_count > winner_count) { - winner_count = candidate_count; - winner = candidate; - winner_i = i; - } - } - - /* Merge all the other traces in the winning trace. */ - for (i = 0; i < num_traces; i++) { - struct ctf_fs_trace *trace = traces[i]; - - /* Don't merge the winner into itself. */ - if (trace == winner) { - continue; - } - - /* Merge trace's data stream file groups into winner's. */ - ret = merge_matching_ctf_fs_ds_file_groups(winner, trace); - if (ret) { - goto end; - } - } - - /* - * Move the winner out of the array, into `*out_trace`. - */ - *out_trace = winner; - traces[winner_i] = NULL; + unsigned int winner_count; + struct ctf_fs_trace *winner; + guint i, winner_i; + int ret = 0; + + BT_ASSERT(num_traces >= 2); + + winner_count = metadata_count_stream_and_event_classes(traces[0]); + winner = traces[0]; + winner_i = 0; + + /* Find the trace with the largest metadata. */ + for (i = 1; i < num_traces; i++) { + struct ctf_fs_trace *candidate; + unsigned int candidate_count; + + candidate = traces[i]; + + /* A bit of sanity check. */ + BT_ASSERT(bt_uuid_compare(winner->metadata->tc->uuid, candidate->metadata->tc->uuid) == 0); + + candidate_count = metadata_count_stream_and_event_classes(candidate); + + if (candidate_count > winner_count) { + winner_count = candidate_count; + winner = candidate; + winner_i = i; + } + } + + /* Merge all the other traces in the winning trace. */ + for (i = 0; i < num_traces; i++) { + struct ctf_fs_trace *trace = traces[i]; + + /* Don't merge the winner into itself. */ + if (trace == winner) { + continue; + } + + /* Merge trace's data stream file groups into winner's. */ + ret = merge_matching_ctf_fs_ds_file_groups(winner, trace); + if (ret) { + goto end; + } + } + + /* + * Move the winner out of the array, into `*out_trace`. + */ + *out_trace = winner; + traces[winner_i] = NULL; end: - return ret; + return ret; } -enum target_event { - FIRST_EVENT, - LAST_EVENT, +enum target_event +{ + FIRST_EVENT, + LAST_EVENT, }; -static -int decode_clock_snapshot_after_event(struct ctf_fs_trace *ctf_fs_trace, - struct ctf_clock_class *default_cc, - struct ctf_fs_ds_index_entry *index_entry, - enum target_event target_event, uint64_t *cs, int64_t *ts_ns) +static int decode_clock_snapshot_after_event(struct ctf_fs_trace *ctf_fs_trace, + struct ctf_clock_class *default_cc, + struct ctf_fs_ds_index_entry *index_entry, + enum target_event target_event, uint64_t *cs, + int64_t *ts_ns) { - enum ctf_msg_iter_status iter_status = CTF_MSG_ITER_STATUS_OK; - struct ctf_fs_ds_file *ds_file = NULL; - struct ctf_msg_iter *msg_iter = NULL; - bt_logging_level log_level = ctf_fs_trace->log_level; - bt_self_component *self_comp = ctf_fs_trace->self_comp; - int ret = 0; - - BT_ASSERT(ctf_fs_trace); - BT_ASSERT(index_entry); - BT_ASSERT(index_entry->path); - - ds_file = ctf_fs_ds_file_create(ctf_fs_trace, NULL, - NULL, index_entry->path, log_level); - if (!ds_file) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Failed to create a ctf_fs_ds_file"); - ret = -1; - goto end; - } - - BT_ASSERT(ctf_fs_trace->metadata); - BT_ASSERT(ctf_fs_trace->metadata->tc); - - msg_iter = ctf_msg_iter_create(ctf_fs_trace->metadata->tc, - bt_common_get_page_size(log_level) * 8, ctf_fs_ds_file_medops, - ds_file, log_level, self_comp, NULL); - if (!msg_iter) { - /* ctf_msg_iter_create() logs errors. */ - ret = -1; - goto end; - } - - /* - * Turn on dry run mode to prevent the creation and usage of Babeltrace - * library objects (bt_field, bt_message_*, etc.). - */ - ctf_msg_iter_set_dry_run(msg_iter, true); - - /* Seek to the beginning of the target packet. */ - iter_status = ctf_msg_iter_seek(msg_iter, index_entry->offset); - if (iter_status) { - /* ctf_msg_iter_seek() logs errors. */ - ret = -1; - goto end; - } - - switch (target_event) { - case FIRST_EVENT: - /* - * Start to decode the packet until we reach the end of - * the first event. To extract the first event's clock - * snapshot. - */ - iter_status = ctf_msg_iter_curr_packet_first_event_clock_snapshot( - msg_iter, cs); - break; - case LAST_EVENT: - /* Decode the packet to extract the last event's clock snapshot. */ - iter_status = ctf_msg_iter_curr_packet_last_event_clock_snapshot( - msg_iter, cs); - break; - default: - bt_common_abort(); - } - if (iter_status) { - ret = -1; - goto end; - } - - /* Convert clock snapshot to timestamp. */ - ret = bt_util_clock_cycles_to_ns_from_origin(*cs, - default_cc->frequency, default_cc->offset_seconds, - default_cc->offset_cycles, ts_ns); - if (ret) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Failed to convert clock snapshot to timestamp"); - goto end; - } + enum ctf_msg_iter_status iter_status = CTF_MSG_ITER_STATUS_OK; + struct ctf_fs_ds_file *ds_file = NULL; + struct ctf_msg_iter *msg_iter = NULL; + bt_logging_level log_level = ctf_fs_trace->log_level; + bt_self_component *self_comp = ctf_fs_trace->self_comp; + int ret = 0; + + BT_ASSERT(ctf_fs_trace); + BT_ASSERT(index_entry); + BT_ASSERT(index_entry->path); + + ds_file = ctf_fs_ds_file_create(ctf_fs_trace, NULL, NULL, index_entry->path, log_level); + if (!ds_file) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Failed to create a ctf_fs_ds_file"); + ret = -1; + goto end; + } + + BT_ASSERT(ctf_fs_trace->metadata); + BT_ASSERT(ctf_fs_trace->metadata->tc); + + msg_iter = + ctf_msg_iter_create(ctf_fs_trace->metadata->tc, bt_common_get_page_size(log_level) * 8, + ctf_fs_ds_file_medops, ds_file, log_level, self_comp, NULL); + if (!msg_iter) { + /* ctf_msg_iter_create() logs errors. */ + ret = -1; + goto end; + } + + /* + * Turn on dry run mode to prevent the creation and usage of Babeltrace + * library objects (bt_field, bt_message_*, etc.). + */ + ctf_msg_iter_set_dry_run(msg_iter, true); + + /* Seek to the beginning of the target packet. */ + iter_status = ctf_msg_iter_seek(msg_iter, index_entry->offset); + if (iter_status) { + /* ctf_msg_iter_seek() logs errors. */ + ret = -1; + goto end; + } + + switch (target_event) { + case FIRST_EVENT: + /* + * Start to decode the packet until we reach the end of + * the first event. To extract the first event's clock + * snapshot. + */ + iter_status = ctf_msg_iter_curr_packet_first_event_clock_snapshot(msg_iter, cs); + break; + case LAST_EVENT: + /* Decode the packet to extract the last event's clock snapshot. */ + iter_status = ctf_msg_iter_curr_packet_last_event_clock_snapshot(msg_iter, cs); + break; + default: + bt_common_abort(); + } + if (iter_status) { + ret = -1; + goto end; + } + + /* Convert clock snapshot to timestamp. */ + ret = bt_util_clock_cycles_to_ns_from_origin( + *cs, default_cc->frequency, default_cc->offset_seconds, default_cc->offset_cycles, ts_ns); + if (ret) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Failed to convert clock snapshot to timestamp"); + goto end; + } end: - if (ds_file) { - ctf_fs_ds_file_destroy(ds_file); - } - if (msg_iter) { - ctf_msg_iter_destroy(msg_iter); - } - - return ret; + if (ds_file) { + ctf_fs_ds_file_destroy(ds_file); + } + if (msg_iter) { + ctf_msg_iter_destroy(msg_iter); + } + + return ret; } -static -int decode_packet_first_event_timestamp(struct ctf_fs_trace *ctf_fs_trace, - struct ctf_clock_class *default_cc, - struct ctf_fs_ds_index_entry *index_entry, uint64_t *cs, int64_t *ts_ns) +static int decode_packet_first_event_timestamp(struct ctf_fs_trace *ctf_fs_trace, + struct ctf_clock_class *default_cc, + struct ctf_fs_ds_index_entry *index_entry, + uint64_t *cs, int64_t *ts_ns) { - return decode_clock_snapshot_after_event(ctf_fs_trace, default_cc, - index_entry, FIRST_EVENT, cs, ts_ns); + return decode_clock_snapshot_after_event(ctf_fs_trace, default_cc, index_entry, FIRST_EVENT, cs, + ts_ns); } -static -int decode_packet_last_event_timestamp(struct ctf_fs_trace *ctf_fs_trace, - struct ctf_clock_class *default_cc, - struct ctf_fs_ds_index_entry *index_entry, uint64_t *cs, int64_t *ts_ns) +static int decode_packet_last_event_timestamp(struct ctf_fs_trace *ctf_fs_trace, + struct ctf_clock_class *default_cc, + struct ctf_fs_ds_index_entry *index_entry, + uint64_t *cs, int64_t *ts_ns) { - return decode_clock_snapshot_after_event(ctf_fs_trace, default_cc, - index_entry, LAST_EVENT, cs, ts_ns); + return decode_clock_snapshot_after_event(ctf_fs_trace, default_cc, index_entry, LAST_EVENT, cs, + ts_ns); } /* @@ -1573,77 +1488,75 @@ int decode_packet_last_event_timestamp(struct ctf_fs_trace *ctf_fs_trace, * - before lttng-module 2.10.10 * - before lttng-module 2.9.13 */ -static -int fix_index_lttng_event_after_packet_bug(struct ctf_fs_trace *trace) +static int fix_index_lttng_event_after_packet_bug(struct ctf_fs_trace *trace) { - int ret = 0; - guint ds_file_group_i; - GPtrArray *ds_file_groups = trace->ds_file_groups; - bt_logging_level log_level = trace->log_level; - - for (ds_file_group_i = 0; ds_file_group_i < ds_file_groups->len; - ds_file_group_i++) { - guint entry_i; - struct ctf_clock_class *default_cc; - struct ctf_fs_ds_index_entry *last_entry; - struct ctf_fs_ds_index *index; - - struct ctf_fs_ds_file_group *ds_file_group = - (struct ctf_fs_ds_file_group *) g_ptr_array_index(ds_file_groups, ds_file_group_i); - - BT_ASSERT(ds_file_group); - index = ds_file_group->index; - - BT_ASSERT(index); - BT_ASSERT(index->entries); - BT_ASSERT(index->entries->len > 0); - - /* - * Iterate over all entries but the last one. The last one is - * fixed differently after. - */ - for (entry_i = 0; entry_i < index->entries->len - 1; - entry_i++) { - struct ctf_fs_ds_index_entry *curr_entry, *next_entry; - - curr_entry = (ctf_fs_ds_index_entry *) g_ptr_array_index(index->entries, entry_i); - next_entry = (ctf_fs_ds_index_entry *) g_ptr_array_index(index->entries, entry_i + 1); - - /* - * 1. Set the current index entry `end` timestamp to - * the next index entry `begin` timestamp. - */ - curr_entry->timestamp_end = next_entry->timestamp_begin; - curr_entry->timestamp_end_ns = next_entry->timestamp_begin_ns; - } - - /* - * 2. Fix the last entry by decoding the last event of the last - * packet. - */ - last_entry = (ctf_fs_ds_index_entry *) g_ptr_array_index(index->entries, - index->entries->len - 1); - BT_ASSERT(last_entry); - - BT_ASSERT(ds_file_group->sc->default_clock_class); - default_cc = ds_file_group->sc->default_clock_class; - - /* - * Decode packet to read the timestamp of the last event of the - * entry. - */ - ret = decode_packet_last_event_timestamp(trace, default_cc, - last_entry, &last_entry->timestamp_end, - &last_entry->timestamp_end_ns); - if (ret) { - BT_COMP_LOGE_APPEND_CAUSE(trace->self_comp, - "Failed to decode stream's last packet to get its last event's clock snapshot."); - goto end; - } - } + int ret = 0; + guint ds_file_group_i; + GPtrArray *ds_file_groups = trace->ds_file_groups; + bt_logging_level log_level = trace->log_level; + + for (ds_file_group_i = 0; ds_file_group_i < ds_file_groups->len; ds_file_group_i++) { + guint entry_i; + struct ctf_clock_class *default_cc; + struct ctf_fs_ds_index_entry *last_entry; + struct ctf_fs_ds_index *index; + + struct ctf_fs_ds_file_group *ds_file_group = + (struct ctf_fs_ds_file_group *) g_ptr_array_index(ds_file_groups, ds_file_group_i); + + BT_ASSERT(ds_file_group); + index = ds_file_group->index; + + BT_ASSERT(index); + BT_ASSERT(index->entries); + BT_ASSERT(index->entries->len > 0); + + /* + * Iterate over all entries but the last one. The last one is + * fixed differently after. + */ + for (entry_i = 0; entry_i < index->entries->len - 1; entry_i++) { + struct ctf_fs_ds_index_entry *curr_entry, *next_entry; + + curr_entry = (ctf_fs_ds_index_entry *) g_ptr_array_index(index->entries, entry_i); + next_entry = (ctf_fs_ds_index_entry *) g_ptr_array_index(index->entries, entry_i + 1); + + /* + * 1. Set the current index entry `end` timestamp to + * the next index entry `begin` timestamp. + */ + curr_entry->timestamp_end = next_entry->timestamp_begin; + curr_entry->timestamp_end_ns = next_entry->timestamp_begin_ns; + } + + /* + * 2. Fix the last entry by decoding the last event of the last + * packet. + */ + last_entry = + (ctf_fs_ds_index_entry *) g_ptr_array_index(index->entries, index->entries->len - 1); + BT_ASSERT(last_entry); + + BT_ASSERT(ds_file_group->sc->default_clock_class); + default_cc = ds_file_group->sc->default_clock_class; + + /* + * Decode packet to read the timestamp of the last event of the + * entry. + */ + ret = decode_packet_last_event_timestamp(trace, default_cc, last_entry, + &last_entry->timestamp_end, + &last_entry->timestamp_end_ns); + if (ret) { + BT_COMP_LOGE_APPEND_CAUSE( + trace->self_comp, + "Failed to decode stream's last packet to get its last event's clock snapshot."); + goto end; + } + } end: - return ret; + return ret; } /* @@ -1660,63 +1573,60 @@ end: * Known buggy tracer versions: * - before barectf 2.3.1 */ -static -int fix_index_barectf_event_before_packet_bug(struct ctf_fs_trace *trace) +static int fix_index_barectf_event_before_packet_bug(struct ctf_fs_trace *trace) { - int ret = 0; - guint ds_file_group_i; - GPtrArray *ds_file_groups = trace->ds_file_groups; - bt_logging_level log_level = trace->log_level; - - for (ds_file_group_i = 0; ds_file_group_i < ds_file_groups->len; - ds_file_group_i++) { - guint entry_i; - struct ctf_clock_class *default_cc; - ctf_fs_ds_file_group *ds_file_group = - (ctf_fs_ds_file_group *) g_ptr_array_index(ds_file_groups, ds_file_group_i); - - struct ctf_fs_ds_index *index = ds_file_group->index; - - BT_ASSERT(index); - BT_ASSERT(index->entries); - BT_ASSERT(index->entries->len > 0); - - BT_ASSERT(ds_file_group->sc->default_clock_class); - default_cc = ds_file_group->sc->default_clock_class; - - /* - * 1. Iterate over the index, starting from the second entry - * (index = 1). - */ - for (entry_i = 1; entry_i < index->entries->len; - entry_i++) { - ctf_fs_ds_index_entry *prev_entry = - (ctf_fs_ds_index_entry *) g_ptr_array_index(index->entries, entry_i - 1); - ctf_fs_ds_index_entry *curr_entry = - (ctf_fs_ds_index_entry *) g_ptr_array_index(index->entries, entry_i); - /* - * 2. Set the current entry `begin` timestamp to the - * timestamp of the first event of the current packet. - */ - ret = decode_packet_first_event_timestamp(trace, default_cc, - curr_entry, &curr_entry->timestamp_begin, - &curr_entry->timestamp_begin_ns); - if (ret) { - BT_COMP_LOGE_APPEND_CAUSE(trace->self_comp, - "Failed to decode first event's clock snapshot"); - goto end; - } - - /* - * 3. Set the previous entry `end` timestamp to the - * timestamp of the first event of the current packet. - */ - prev_entry->timestamp_end = curr_entry->timestamp_begin; - prev_entry->timestamp_end_ns = curr_entry->timestamp_begin_ns; - } - } + int ret = 0; + guint ds_file_group_i; + GPtrArray *ds_file_groups = trace->ds_file_groups; + bt_logging_level log_level = trace->log_level; + + for (ds_file_group_i = 0; ds_file_group_i < ds_file_groups->len; ds_file_group_i++) { + guint entry_i; + struct ctf_clock_class *default_cc; + ctf_fs_ds_file_group *ds_file_group = + (ctf_fs_ds_file_group *) g_ptr_array_index(ds_file_groups, ds_file_group_i); + + struct ctf_fs_ds_index *index = ds_file_group->index; + + BT_ASSERT(index); + BT_ASSERT(index->entries); + BT_ASSERT(index->entries->len > 0); + + BT_ASSERT(ds_file_group->sc->default_clock_class); + default_cc = ds_file_group->sc->default_clock_class; + + /* + * 1. Iterate over the index, starting from the second entry + * (index = 1). + */ + for (entry_i = 1; entry_i < index->entries->len; entry_i++) { + ctf_fs_ds_index_entry *prev_entry = + (ctf_fs_ds_index_entry *) g_ptr_array_index(index->entries, entry_i - 1); + ctf_fs_ds_index_entry *curr_entry = + (ctf_fs_ds_index_entry *) g_ptr_array_index(index->entries, entry_i); + /* + * 2. Set the current entry `begin` timestamp to the + * timestamp of the first event of the current packet. + */ + ret = decode_packet_first_event_timestamp(trace, default_cc, curr_entry, + &curr_entry->timestamp_begin, + &curr_entry->timestamp_begin_ns); + if (ret) { + BT_COMP_LOGE_APPEND_CAUSE(trace->self_comp, + "Failed to decode first event's clock snapshot"); + goto end; + } + + /* + * 3. Set the previous entry `end` timestamp to the + * timestamp of the first event of the current packet. + */ + prev_entry->timestamp_end = curr_entry->timestamp_begin; + prev_entry->timestamp_end_ns = curr_entry->timestamp_begin_ns; + } + } end: - return ret; + return ret; } /* @@ -1736,79 +1646,71 @@ end: * Affected versions: * - All current and future lttng-ust and lttng-modules versions. */ -static -int fix_index_lttng_crash_quirk(struct ctf_fs_trace *trace) +static int fix_index_lttng_crash_quirk(struct ctf_fs_trace *trace) { - int ret = 0; - guint ds_file_group_idx; - GPtrArray *ds_file_groups = trace->ds_file_groups; - bt_logging_level log_level = trace->log_level; - - for (ds_file_group_idx = 0; ds_file_group_idx < ds_file_groups->len; - ds_file_group_idx++) { - guint entry_idx; - struct ctf_clock_class *default_cc; - struct ctf_fs_ds_index *index; - - ctf_fs_ds_file_group *ds_file_group = - (ctf_fs_ds_file_group *) g_ptr_array_index(ds_file_groups, ds_file_group_idx); - - BT_ASSERT(ds_file_group); - index = ds_file_group->index; - - BT_ASSERT(ds_file_group->sc->default_clock_class); - default_cc = ds_file_group->sc->default_clock_class; - - BT_ASSERT(index); - BT_ASSERT(index->entries); - BT_ASSERT(index->entries->len > 0); - - ctf_fs_ds_index_entry *last_entry = - (ctf_fs_ds_index_entry *) g_ptr_array_index(index->entries, - index->entries->len - 1); - BT_ASSERT(last_entry); - - - /* 1. Fix the last entry first. */ - if (last_entry->timestamp_end == 0 && - last_entry->timestamp_begin != 0) { - /* - * Decode packet to read the timestamp of the - * last event of the stream file. - */ - ret = decode_packet_last_event_timestamp(trace, - default_cc, last_entry, - &last_entry->timestamp_end, - &last_entry->timestamp_end_ns); - if (ret) { - BT_COMP_LOGE_APPEND_CAUSE(trace->self_comp, - "Failed to decode last event's clock snapshot"); - goto end; - } - } - - /* Iterate over all entries but the last one. */ - for (entry_idx = 0; entry_idx < index->entries->len - 1; - entry_idx++) { - ctf_fs_ds_index_entry *curr_entry = - (ctf_fs_ds_index_entry *) g_ptr_array_index(index->entries, entry_idx); - ctf_fs_ds_index_entry *next_entry = - (ctf_fs_ds_index_entry *) g_ptr_array_index(index->entries, entry_idx + 1); - - if (curr_entry->timestamp_end == 0 && - curr_entry->timestamp_begin != 0) { - /* - * 2. Set the current index entry `end` timestamp to - * the next index entry `begin` timestamp. - */ - curr_entry->timestamp_end = next_entry->timestamp_begin; - curr_entry->timestamp_end_ns = next_entry->timestamp_begin_ns; - } - } - } + int ret = 0; + guint ds_file_group_idx; + GPtrArray *ds_file_groups = trace->ds_file_groups; + bt_logging_level log_level = trace->log_level; + + for (ds_file_group_idx = 0; ds_file_group_idx < ds_file_groups->len; ds_file_group_idx++) { + guint entry_idx; + struct ctf_clock_class *default_cc; + struct ctf_fs_ds_index *index; + + ctf_fs_ds_file_group *ds_file_group = + (ctf_fs_ds_file_group *) g_ptr_array_index(ds_file_groups, ds_file_group_idx); + + BT_ASSERT(ds_file_group); + index = ds_file_group->index; + + BT_ASSERT(ds_file_group->sc->default_clock_class); + default_cc = ds_file_group->sc->default_clock_class; + + BT_ASSERT(index); + BT_ASSERT(index->entries); + BT_ASSERT(index->entries->len > 0); + + ctf_fs_ds_index_entry *last_entry = + (ctf_fs_ds_index_entry *) g_ptr_array_index(index->entries, index->entries->len - 1); + BT_ASSERT(last_entry); + + /* 1. Fix the last entry first. */ + if (last_entry->timestamp_end == 0 && last_entry->timestamp_begin != 0) { + /* + * Decode packet to read the timestamp of the + * last event of the stream file. + */ + ret = decode_packet_last_event_timestamp(trace, default_cc, last_entry, + &last_entry->timestamp_end, + &last_entry->timestamp_end_ns); + if (ret) { + BT_COMP_LOGE_APPEND_CAUSE(trace->self_comp, + "Failed to decode last event's clock snapshot"); + goto end; + } + } + + /* Iterate over all entries but the last one. */ + for (entry_idx = 0; entry_idx < index->entries->len - 1; entry_idx++) { + ctf_fs_ds_index_entry *curr_entry = + (ctf_fs_ds_index_entry *) g_ptr_array_index(index->entries, entry_idx); + ctf_fs_ds_index_entry *next_entry = + (ctf_fs_ds_index_entry *) g_ptr_array_index(index->entries, entry_idx + 1); + + if (curr_entry->timestamp_end == 0 && curr_entry->timestamp_begin != 0) { + /* + * 2. Set the current index entry `end` timestamp to + * the next index entry `begin` timestamp. + */ + curr_entry->timestamp_end = next_entry->timestamp_begin; + curr_entry->timestamp_end_ns = next_entry->timestamp_begin_ns; + } + } + } end: - return ret; + return ret; } /* @@ -1816,681 +1718,631 @@ end: * Returns 0 on success, and -1 if the extraction is not successful because the * necessary fields are absents in the trace metadata. */ -static -int extract_tracer_info(struct ctf_fs_trace *trace, - struct tracer_info *current_tracer_info) +static int extract_tracer_info(struct ctf_fs_trace *trace, struct tracer_info *current_tracer_info) { - int ret = 0; - struct ctf_trace_class_env_entry *entry; - - /* Clear the current_tracer_info struct */ - memset(current_tracer_info, 0, sizeof(*current_tracer_info)); - - /* - * To compare 2 tracer versions, at least the tracer name and it's - * major version are needed. If one of these is missing, consider it an - * extraction failure. - */ - entry = ctf_trace_class_borrow_env_entry_by_name( - trace->metadata->tc, "tracer_name"); - if (!entry || entry->type != CTF_TRACE_CLASS_ENV_ENTRY_TYPE_STR) { - goto missing_bare_minimum; - } - - /* Set tracer name. */ - current_tracer_info->name = entry->value.str->str; - - entry = ctf_trace_class_borrow_env_entry_by_name( - trace->metadata->tc, "tracer_major"); - if (!entry || entry->type != CTF_TRACE_CLASS_ENV_ENTRY_TYPE_INT) { - goto missing_bare_minimum; - } - - /* Set major version number. */ - current_tracer_info->major = entry->value.i; - - entry = ctf_trace_class_borrow_env_entry_by_name( - trace->metadata->tc, "tracer_minor"); - if (!entry || entry->type != CTF_TRACE_CLASS_ENV_ENTRY_TYPE_INT) { - goto end; - } - - /* Set minor version number. */ - current_tracer_info->minor = entry->value.i; - - entry = ctf_trace_class_borrow_env_entry_by_name( - trace->metadata->tc, "tracer_patch"); - if (!entry) { - /* - * If `tracer_patch` doesn't exist `tracer_patchlevel` might. - * For example, `lttng-modules` uses entry name - * `tracer_patchlevel`. - */ - entry = ctf_trace_class_borrow_env_entry_by_name( - trace->metadata->tc, "tracer_patchlevel"); - } - - if (!entry || entry->type != CTF_TRACE_CLASS_ENV_ENTRY_TYPE_INT) { - goto end; - } - - /* Set patch version number. */ - current_tracer_info->patch = entry->value.i; - - goto end; + int ret = 0; + struct ctf_trace_class_env_entry *entry; + + /* Clear the current_tracer_info struct */ + memset(current_tracer_info, 0, sizeof(*current_tracer_info)); + + /* + * To compare 2 tracer versions, at least the tracer name and it's + * major version are needed. If one of these is missing, consider it an + * extraction failure. + */ + entry = ctf_trace_class_borrow_env_entry_by_name(trace->metadata->tc, "tracer_name"); + if (!entry || entry->type != CTF_TRACE_CLASS_ENV_ENTRY_TYPE_STR) { + goto missing_bare_minimum; + } + + /* Set tracer name. */ + current_tracer_info->name = entry->value.str->str; + + entry = ctf_trace_class_borrow_env_entry_by_name(trace->metadata->tc, "tracer_major"); + if (!entry || entry->type != CTF_TRACE_CLASS_ENV_ENTRY_TYPE_INT) { + goto missing_bare_minimum; + } + + /* Set major version number. */ + current_tracer_info->major = entry->value.i; + + entry = ctf_trace_class_borrow_env_entry_by_name(trace->metadata->tc, "tracer_minor"); + if (!entry || entry->type != CTF_TRACE_CLASS_ENV_ENTRY_TYPE_INT) { + goto end; + } + + /* Set minor version number. */ + current_tracer_info->minor = entry->value.i; + + entry = ctf_trace_class_borrow_env_entry_by_name(trace->metadata->tc, "tracer_patch"); + if (!entry) { + /* + * If `tracer_patch` doesn't exist `tracer_patchlevel` might. + * For example, `lttng-modules` uses entry name + * `tracer_patchlevel`. + */ + entry = ctf_trace_class_borrow_env_entry_by_name(trace->metadata->tc, "tracer_patchlevel"); + } + + if (!entry || entry->type != CTF_TRACE_CLASS_ENV_ENTRY_TYPE_INT) { + goto end; + } + + /* Set patch version number. */ + current_tracer_info->patch = entry->value.i; + + goto end; missing_bare_minimum: - ret = -1; + ret = -1; end: - return ret; + return ret; } -static -bool is_tracer_affected_by_lttng_event_after_packet_bug( - struct tracer_info *curr_tracer_info) +static bool is_tracer_affected_by_lttng_event_after_packet_bug(struct tracer_info *curr_tracer_info) { - bool is_affected = false; - - if (strcmp(curr_tracer_info->name, "lttng-ust") == 0) { - if (curr_tracer_info->major < 2) { - is_affected = true; - } else if (curr_tracer_info->major == 2) { - /* fixed in lttng-ust 2.11.0 */ - if (curr_tracer_info->minor < 11) { - is_affected = true; - } - } - } else if (strcmp(curr_tracer_info->name, "lttng-modules") == 0) { - if (curr_tracer_info->major < 2) { - is_affected = true; - } else if (curr_tracer_info->major == 2) { - /* fixed in lttng-modules 2.11.0 */ - if (curr_tracer_info->minor == 10) { - /* fixed in lttng-modules 2.10.10 */ - if (curr_tracer_info->patch < 10) { - is_affected = true; - } - } else if (curr_tracer_info->minor == 9) { - /* fixed in lttng-modules 2.9.13 */ - if (curr_tracer_info->patch < 13) { - is_affected = true; - } - } else if (curr_tracer_info->minor < 9) { - is_affected = true; - } - } - } - - return is_affected; + bool is_affected = false; + + if (strcmp(curr_tracer_info->name, "lttng-ust") == 0) { + if (curr_tracer_info->major < 2) { + is_affected = true; + } else if (curr_tracer_info->major == 2) { + /* fixed in lttng-ust 2.11.0 */ + if (curr_tracer_info->minor < 11) { + is_affected = true; + } + } + } else if (strcmp(curr_tracer_info->name, "lttng-modules") == 0) { + if (curr_tracer_info->major < 2) { + is_affected = true; + } else if (curr_tracer_info->major == 2) { + /* fixed in lttng-modules 2.11.0 */ + if (curr_tracer_info->minor == 10) { + /* fixed in lttng-modules 2.10.10 */ + if (curr_tracer_info->patch < 10) { + is_affected = true; + } + } else if (curr_tracer_info->minor == 9) { + /* fixed in lttng-modules 2.9.13 */ + if (curr_tracer_info->patch < 13) { + is_affected = true; + } + } else if (curr_tracer_info->minor < 9) { + is_affected = true; + } + } + } + + return is_affected; } -static -bool is_tracer_affected_by_barectf_event_before_packet_bug( - struct tracer_info *curr_tracer_info) +static bool +is_tracer_affected_by_barectf_event_before_packet_bug(struct tracer_info *curr_tracer_info) { - bool is_affected = false; - - if (strcmp(curr_tracer_info->name, "barectf") == 0) { - if (curr_tracer_info->major < 2) { - is_affected = true; - } else if (curr_tracer_info->major == 2) { - if (curr_tracer_info->minor < 3) { - is_affected = true; - } else if (curr_tracer_info->minor == 3) { - /* fixed in barectf 2.3.1 */ - if (curr_tracer_info->patch < 1) { - is_affected = true; - } - } - } - } - - return is_affected; + bool is_affected = false; + + if (strcmp(curr_tracer_info->name, "barectf") == 0) { + if (curr_tracer_info->major < 2) { + is_affected = true; + } else if (curr_tracer_info->major == 2) { + if (curr_tracer_info->minor < 3) { + is_affected = true; + } else if (curr_tracer_info->minor == 3) { + /* fixed in barectf 2.3.1 */ + if (curr_tracer_info->patch < 1) { + is_affected = true; + } + } + } + } + + return is_affected; } -static -bool is_tracer_affected_by_lttng_crash_quirk( - struct tracer_info *curr_tracer_info) +static bool is_tracer_affected_by_lttng_crash_quirk(struct tracer_info *curr_tracer_info) { - bool is_affected = false; + bool is_affected = false; - /* All LTTng tracer may be affected by this lttng crash quirk. */ - if (strcmp(curr_tracer_info->name, "lttng-ust") == 0) { - is_affected = true; - } else if (strcmp(curr_tracer_info->name, "lttng-modules") == 0) { - is_affected = true; - } + /* All LTTng tracer may be affected by this lttng crash quirk. */ + if (strcmp(curr_tracer_info->name, "lttng-ust") == 0) { + is_affected = true; + } else if (strcmp(curr_tracer_info->name, "lttng-modules") == 0) { + is_affected = true; + } - return is_affected; + return is_affected; } /* * Looks for trace produced by known buggy tracers and fix up the index * produced earlier. */ -static -int fix_packet_index_tracer_bugs(struct ctf_fs_component *ctf_fs, - bt_self_component *self_comp, - bt_self_component_class *self_comp_class) +static int fix_packet_index_tracer_bugs(struct ctf_fs_component *ctf_fs, + bt_self_component *self_comp, + bt_self_component_class *self_comp_class) { - int ret = 0; - struct tracer_info current_tracer_info; - bt_logging_level log_level = ctf_fs->log_level; - - ret = extract_tracer_info(ctf_fs->trace, ¤t_tracer_info); - if (ret) { - /* - * A trace may not have all the necessary environment - * entries to do the tracer version comparison. - * At least, the tracer name and major version number - * are needed. Failing to extract these entries is not - * an error. - */ - ret = 0; - BT_LOGI_STR("Cannot extract tracer information necessary to compare with buggy versions."); - goto end;; - } - - /* Check if the trace may be affected by old tracer bugs. */ - if (is_tracer_affected_by_lttng_event_after_packet_bug( - ¤t_tracer_info)) { - BT_LOGI_STR("Trace may be affected by LTTng tracer packet timestamp bug. Fixing up."); - ret = fix_index_lttng_event_after_packet_bug(ctf_fs->trace); - if (ret) { - BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( - self_comp, self_comp_class, - "Failed to fix LTTng event-after-packet bug."); - goto end; - } - ctf_fs->trace->metadata->tc->quirks.lttng_event_after_packet = true; - } - - if (is_tracer_affected_by_barectf_event_before_packet_bug( - ¤t_tracer_info)) { - BT_LOGI_STR("Trace may be affected by barectf tracer packet timestamp bug. Fixing up."); - ret = fix_index_barectf_event_before_packet_bug(ctf_fs->trace); - if (ret) { - BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( - self_comp, self_comp_class, - "Failed to fix barectf event-before-packet bug."); - goto end; - } - ctf_fs->trace->metadata->tc->quirks.barectf_event_before_packet = true; - } - - if (is_tracer_affected_by_lttng_crash_quirk( - ¤t_tracer_info)) { - ret = fix_index_lttng_crash_quirk(ctf_fs->trace); - if (ret) { - BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( - self_comp, self_comp_class, - "Failed to fix lttng-crash timestamp quirks."); - goto end; - } - ctf_fs->trace->metadata->tc->quirks.lttng_crash = true; - } + int ret = 0; + struct tracer_info current_tracer_info; + bt_logging_level log_level = ctf_fs->log_level; + + ret = extract_tracer_info(ctf_fs->trace, ¤t_tracer_info); + if (ret) { + /* + * A trace may not have all the necessary environment + * entries to do the tracer version comparison. + * At least, the tracer name and major version number + * are needed. Failing to extract these entries is not + * an error. + */ + ret = 0; + BT_LOGI_STR("Cannot extract tracer information necessary to compare with buggy versions."); + goto end; + ; + } + + /* Check if the trace may be affected by old tracer bugs. */ + if (is_tracer_affected_by_lttng_event_after_packet_bug(¤t_tracer_info)) { + BT_LOGI_STR("Trace may be affected by LTTng tracer packet timestamp bug. Fixing up."); + ret = fix_index_lttng_event_after_packet_bug(ctf_fs->trace); + if (ret) { + BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class, + "Failed to fix LTTng event-after-packet bug."); + goto end; + } + ctf_fs->trace->metadata->tc->quirks.lttng_event_after_packet = true; + } + + if (is_tracer_affected_by_barectf_event_before_packet_bug(¤t_tracer_info)) { + BT_LOGI_STR("Trace may be affected by barectf tracer packet timestamp bug. Fixing up."); + ret = fix_index_barectf_event_before_packet_bug(ctf_fs->trace); + if (ret) { + BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + self_comp, self_comp_class, "Failed to fix barectf event-before-packet bug."); + goto end; + } + ctf_fs->trace->metadata->tc->quirks.barectf_event_before_packet = true; + } + + if (is_tracer_affected_by_lttng_crash_quirk(¤t_tracer_info)) { + ret = fix_index_lttng_crash_quirk(ctf_fs->trace); + if (ret) { + BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class, + "Failed to fix lttng-crash timestamp quirks."); + goto end; + } + ctf_fs->trace->metadata->tc->quirks.lttng_crash = true; + } end: - return ret; + return ret; } -static -gint compare_ds_file_groups_by_first_path(gconstpointer a, gconstpointer b) +static gint compare_ds_file_groups_by_first_path(gconstpointer a, gconstpointer b) { - ctf_fs_ds_file_group * const *ds_file_group_a = - (ctf_fs_ds_file_group **) a; - ctf_fs_ds_file_group * const *ds_file_group_b = - (ctf_fs_ds_file_group **) b; + ctf_fs_ds_file_group * const *ds_file_group_a = (ctf_fs_ds_file_group **) a; + ctf_fs_ds_file_group * const *ds_file_group_b = (ctf_fs_ds_file_group **) b; - BT_ASSERT((*ds_file_group_a)->ds_file_infos->len > 0); - BT_ASSERT((*ds_file_group_b)->ds_file_infos->len > 0); + BT_ASSERT((*ds_file_group_a)->ds_file_infos->len > 0); + BT_ASSERT((*ds_file_group_b)->ds_file_infos->len > 0); - const ctf_fs_ds_file_info *first_ds_file_info_a = - (const ctf_fs_ds_file_info *) (*ds_file_group_a)->ds_file_infos->pdata[0]; - const ctf_fs_ds_file_info *first_ds_file_info_b = - (const ctf_fs_ds_file_info *) (*ds_file_group_b)->ds_file_infos->pdata[0]; + const ctf_fs_ds_file_info *first_ds_file_info_a = + (const ctf_fs_ds_file_info *) (*ds_file_group_a)->ds_file_infos->pdata[0]; + const ctf_fs_ds_file_info *first_ds_file_info_b = + (const ctf_fs_ds_file_info *) (*ds_file_group_b)->ds_file_infos->pdata[0]; - return strcmp(first_ds_file_info_a->path->str, - first_ds_file_info_b->path->str); + return strcmp(first_ds_file_info_a->path->str, first_ds_file_info_b->path->str); } -static -gint compare_strings(gconstpointer p_a, gconstpointer p_b) +static gint compare_strings(gconstpointer p_a, gconstpointer p_b) { - const char *a = *((const char **) p_a); - const char *b = *((const char **) p_b); + const char *a = *((const char **) p_a); + const char *b = *((const char **) p_b); - return strcmp(a, b); + return strcmp(a, b); } -int ctf_fs_component_create_ctf_fs_trace( - struct ctf_fs_component *ctf_fs, - const bt_value *paths_value, - const bt_value *trace_name_value, - bt_self_component *self_comp, - bt_self_component_class *self_comp_class) +int ctf_fs_component_create_ctf_fs_trace(struct ctf_fs_component *ctf_fs, + const bt_value *paths_value, + const bt_value *trace_name_value, + bt_self_component *self_comp, + bt_self_component_class *self_comp_class) { - int ret = 0; - uint64_t i; - bt_logging_level log_level = ctf_fs->log_level; - GPtrArray *paths = NULL; - GPtrArray *traces; - const char *trace_name; - - BT_ASSERT(bt_value_get_type(paths_value) == BT_VALUE_TYPE_ARRAY); - BT_ASSERT(!bt_value_array_is_empty(paths_value)); - - traces = g_ptr_array_new_with_free_func(ctf_fs_trace_destroy_notifier); - if (!traces) { - BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class, - "Failed to allocate a GPtrArray."); - goto error; - } - - paths = g_ptr_array_new_with_free_func(g_free); - if (!paths) { - BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class, - "Failed to allocate a GPtrArray."); - goto error; - } - - trace_name = trace_name_value ? bt_value_string_get(trace_name_value) : NULL; - - /* - * Create a sorted array of the paths, to make the execution of this - * component deterministic. - */ - for (i = 0; i < bt_value_array_get_length(paths_value); i++) { - const bt_value *path_value = - bt_value_array_borrow_element_by_index_const(paths_value, i); - const char *input = bt_value_string_get(path_value); - gchar *input_copy; - - input_copy = g_strdup(input); - if (!input_copy) { - BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class, - "Failed to copy a string."); - goto error; - } - - g_ptr_array_add(paths, input_copy); - } - - g_ptr_array_sort(paths, compare_strings); - - /* Create a separate ctf_fs_trace object for each path. */ - for (i = 0; i < paths->len; i++) { - const char *path = (const char *) g_ptr_array_index(paths, i); - - ret = ctf_fs_component_create_ctf_fs_trace_one_path(ctf_fs, - path, trace_name, traces, self_comp, self_comp_class); - if (ret) { - goto end; - } - } - - if (traces->len > 1) { - struct ctf_fs_trace *first_trace = (struct ctf_fs_trace *) traces->pdata[0]; - const uint8_t *first_trace_uuid = first_trace->metadata->tc->uuid; - struct ctf_fs_trace *trace; - - /* - * We have more than one trace, they must all share the same - * UUID, verify that. - */ - for (i = 0; i < traces->len; i++) { - struct ctf_fs_trace *this_trace = - (struct ctf_fs_trace *) traces->pdata[i]; - const uint8_t *this_trace_uuid = this_trace->metadata->tc->uuid; - - if (!this_trace->metadata->tc->is_uuid_set) { - BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class, - "Multiple traces given, but a trace does not have a UUID: path=%s", - this_trace->path->str); - goto error; - } - - if (bt_uuid_compare(first_trace_uuid, this_trace_uuid) != 0) { - char first_trace_uuid_str[BT_UUID_STR_LEN + 1]; - char this_trace_uuid_str[BT_UUID_STR_LEN + 1]; - - bt_uuid_to_str(first_trace_uuid, first_trace_uuid_str); - bt_uuid_to_str(this_trace_uuid, this_trace_uuid_str); - - BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class, - "Multiple traces given, but UUIDs don't match: " - "first-trace-uuid=%s, first-trace-path=%s, " - "trace-uuid=%s, trace-path=%s", - first_trace_uuid_str, first_trace->path->str, - this_trace_uuid_str, this_trace->path->str); - goto error; - } - } - - ret = merge_ctf_fs_traces((struct ctf_fs_trace **) traces->pdata, - traces->len, &trace); - if (ret) { - BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class, - "Failed to merge traces with the same UUID."); - goto error; - } - - ctf_fs->trace = trace; - } else { - /* Just one trace, it may or may not have a UUID, both are fine. */ - ctf_fs->trace = (ctf_fs_trace *) traces->pdata[0]; - traces->pdata[0] = NULL; - } - - ret = fix_packet_index_tracer_bugs(ctf_fs, self_comp, self_comp_class); - if (ret) { - BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class, - "Failed to fix packet index tracer bugs."); - } - - /* - * Sort data stream file groups by first data stream file info - * path to get a deterministic order. This order influences the - * order of the output ports. It also influences the order of - * the automatic stream IDs if the trace's packet headers do not - * contain a `stream_instance_id` field, in which case the data - * stream file to stream ID association is always the same, - * whatever the build and the system. - * - * Having a deterministic order here can help debugging and - * testing. - */ - g_ptr_array_sort(ctf_fs->trace->ds_file_groups, - compare_ds_file_groups_by_first_path); - goto end; + int ret = 0; + uint64_t i; + bt_logging_level log_level = ctf_fs->log_level; + GPtrArray *paths = NULL; + GPtrArray *traces; + const char *trace_name; + + BT_ASSERT(bt_value_get_type(paths_value) == BT_VALUE_TYPE_ARRAY); + BT_ASSERT(!bt_value_array_is_empty(paths_value)); + + traces = g_ptr_array_new_with_free_func(ctf_fs_trace_destroy_notifier); + if (!traces) { + BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class, + "Failed to allocate a GPtrArray."); + goto error; + } + + paths = g_ptr_array_new_with_free_func(g_free); + if (!paths) { + BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class, + "Failed to allocate a GPtrArray."); + goto error; + } + + trace_name = trace_name_value ? bt_value_string_get(trace_name_value) : NULL; + + /* + * Create a sorted array of the paths, to make the execution of this + * component deterministic. + */ + for (i = 0; i < bt_value_array_get_length(paths_value); i++) { + const bt_value *path_value = bt_value_array_borrow_element_by_index_const(paths_value, i); + const char *input = bt_value_string_get(path_value); + gchar *input_copy; + + input_copy = g_strdup(input); + if (!input_copy) { + BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class, + "Failed to copy a string."); + goto error; + } + + g_ptr_array_add(paths, input_copy); + } + + g_ptr_array_sort(paths, compare_strings); + + /* Create a separate ctf_fs_trace object for each path. */ + for (i = 0; i < paths->len; i++) { + const char *path = (const char *) g_ptr_array_index(paths, i); + + ret = ctf_fs_component_create_ctf_fs_trace_one_path(ctf_fs, path, trace_name, traces, + self_comp, self_comp_class); + if (ret) { + goto end; + } + } + + if (traces->len > 1) { + struct ctf_fs_trace *first_trace = (struct ctf_fs_trace *) traces->pdata[0]; + const uint8_t *first_trace_uuid = first_trace->metadata->tc->uuid; + struct ctf_fs_trace *trace; + + /* + * We have more than one trace, they must all share the same + * UUID, verify that. + */ + for (i = 0; i < traces->len; i++) { + struct ctf_fs_trace *this_trace = (struct ctf_fs_trace *) traces->pdata[i]; + const uint8_t *this_trace_uuid = this_trace->metadata->tc->uuid; + + if (!this_trace->metadata->tc->is_uuid_set) { + BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + self_comp, self_comp_class, + "Multiple traces given, but a trace does not have a UUID: path=%s", + this_trace->path->str); + goto error; + } + + if (bt_uuid_compare(first_trace_uuid, this_trace_uuid) != 0) { + char first_trace_uuid_str[BT_UUID_STR_LEN + 1]; + char this_trace_uuid_str[BT_UUID_STR_LEN + 1]; + + bt_uuid_to_str(first_trace_uuid, first_trace_uuid_str); + bt_uuid_to_str(this_trace_uuid, this_trace_uuid_str); + + BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + self_comp, self_comp_class, + "Multiple traces given, but UUIDs don't match: " + "first-trace-uuid=%s, first-trace-path=%s, " + "trace-uuid=%s, trace-path=%s", + first_trace_uuid_str, first_trace->path->str, this_trace_uuid_str, + this_trace->path->str); + goto error; + } + } + + ret = merge_ctf_fs_traces((struct ctf_fs_trace **) traces->pdata, traces->len, &trace); + if (ret) { + BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class, + "Failed to merge traces with the same UUID."); + goto error; + } + + ctf_fs->trace = trace; + } else { + /* Just one trace, it may or may not have a UUID, both are fine. */ + ctf_fs->trace = (ctf_fs_trace *) traces->pdata[0]; + traces->pdata[0] = NULL; + } + + ret = fix_packet_index_tracer_bugs(ctf_fs, self_comp, self_comp_class); + if (ret) { + BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class, + "Failed to fix packet index tracer bugs."); + } + + /* + * Sort data stream file groups by first data stream file info + * path to get a deterministic order. This order influences the + * order of the output ports. It also influences the order of + * the automatic stream IDs if the trace's packet headers do not + * contain a `stream_instance_id` field, in which case the data + * stream file to stream ID association is always the same, + * whatever the build and the system. + * + * Having a deterministic order here can help debugging and + * testing. + */ + g_ptr_array_sort(ctf_fs->trace->ds_file_groups, compare_ds_file_groups_by_first_path); + goto end; error: - ret = -1; + ret = -1; end: - if (traces) { - g_ptr_array_free(traces, TRUE); - } + if (traces) { + g_ptr_array_free(traces, TRUE); + } - if (paths) { - g_ptr_array_free(paths, TRUE); - } + if (paths) { + g_ptr_array_free(paths, TRUE); + } - return ret; + return ret; } -static -GString *get_stream_instance_unique_name( - struct ctf_fs_ds_file_group *ds_file_group) +static GString *get_stream_instance_unique_name(struct ctf_fs_ds_file_group *ds_file_group) { - GString *name; - struct ctf_fs_ds_file_info *ds_file_info; - - name = g_string_new(NULL); - if (!name) { - goto end; - } - - /* - * If there's more than one stream file in the stream file - * group, the first (earliest) stream file's path is used as - * the stream's unique name. - */ - BT_ASSERT(ds_file_group->ds_file_infos->len > 0); - ds_file_info = (ctf_fs_ds_file_info *) g_ptr_array_index(ds_file_group->ds_file_infos, 0); - g_string_assign(name, ds_file_info->path->str); + GString *name; + struct ctf_fs_ds_file_info *ds_file_info; + + name = g_string_new(NULL); + if (!name) { + goto end; + } + + /* + * If there's more than one stream file in the stream file + * group, the first (earliest) stream file's path is used as + * the stream's unique name. + */ + BT_ASSERT(ds_file_group->ds_file_infos->len > 0); + ds_file_info = (ctf_fs_ds_file_info *) g_ptr_array_index(ds_file_group->ds_file_infos, 0); + g_string_assign(name, ds_file_info->path->str); end: - return name; + return name; } /* Create the IR stream objects for ctf_fs_trace. */ -static -int create_streams_for_trace(struct ctf_fs_trace *ctf_fs_trace) +static int create_streams_for_trace(struct ctf_fs_trace *ctf_fs_trace) { - int ret; - GString *name = NULL; - guint i; - bt_logging_level log_level = ctf_fs_trace->log_level; - bt_self_component *self_comp = ctf_fs_trace->self_comp; - - for (i = 0; i < ctf_fs_trace->ds_file_groups->len; i++) { - ctf_fs_ds_file_group *ds_file_group = - (ctf_fs_ds_file_group *) g_ptr_array_index(ctf_fs_trace->ds_file_groups, i); - name = get_stream_instance_unique_name(ds_file_group); - - if (!name) { - goto error; - } - - if (ds_file_group->sc->ir_sc) { - BT_ASSERT(ctf_fs_trace->trace); - - if (ds_file_group->stream_id == UINT64_C(-1)) { - /* No stream ID: use 0 */ - ds_file_group->stream = bt_stream_create_with_id( - ds_file_group->sc->ir_sc, - ctf_fs_trace->trace, - ctf_fs_trace->next_stream_id); - ctf_fs_trace->next_stream_id++; - } else { - /* Specific stream ID */ - ds_file_group->stream = bt_stream_create_with_id( - ds_file_group->sc->ir_sc, - ctf_fs_trace->trace, - (uint64_t) ds_file_group->stream_id); - } - } else { - ds_file_group->stream = NULL; - } - - if (!ds_file_group->stream) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Cannot create stream for DS file group: " - "addr=%p, stream-name=\"%s\"", - ds_file_group, name->str); - goto error; - } - - ret = bt_stream_set_name(ds_file_group->stream, - name->str); - if (ret) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Cannot set stream's name: " - "addr=%p, stream-name=\"%s\"", - ds_file_group->stream, name->str); - goto error; - } - - g_string_free(name, TRUE); - name = NULL; - } - - ret = 0; - goto end; + int ret; + GString *name = NULL; + guint i; + bt_logging_level log_level = ctf_fs_trace->log_level; + bt_self_component *self_comp = ctf_fs_trace->self_comp; + + for (i = 0; i < ctf_fs_trace->ds_file_groups->len; i++) { + ctf_fs_ds_file_group *ds_file_group = + (ctf_fs_ds_file_group *) g_ptr_array_index(ctf_fs_trace->ds_file_groups, i); + name = get_stream_instance_unique_name(ds_file_group); + + if (!name) { + goto error; + } + + if (ds_file_group->sc->ir_sc) { + BT_ASSERT(ctf_fs_trace->trace); + + if (ds_file_group->stream_id == UINT64_C(-1)) { + /* No stream ID: use 0 */ + ds_file_group->stream = bt_stream_create_with_id( + ds_file_group->sc->ir_sc, ctf_fs_trace->trace, ctf_fs_trace->next_stream_id); + ctf_fs_trace->next_stream_id++; + } else { + /* Specific stream ID */ + ds_file_group->stream = + bt_stream_create_with_id(ds_file_group->sc->ir_sc, ctf_fs_trace->trace, + (uint64_t) ds_file_group->stream_id); + } + } else { + ds_file_group->stream = NULL; + } + + if (!ds_file_group->stream) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, + "Cannot create stream for DS file group: " + "addr=%p, stream-name=\"%s\"", + ds_file_group, name->str); + goto error; + } + + ret = bt_stream_set_name(ds_file_group->stream, name->str); + if (ret) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, + "Cannot set stream's name: " + "addr=%p, stream-name=\"%s\"", + ds_file_group->stream, name->str); + goto error; + } + + g_string_free(name, TRUE); + name = NULL; + } + + ret = 0; + goto end; error: - ret = -1; + ret = -1; end: - if (name) { - g_string_free(name, TRUE); - } - return ret; + if (name) { + g_string_free(name, TRUE); + } + return ret; } -static const bt_param_validation_value_descr inputs_elem_descr{ - bt_param_validation_value_descr::string_t -}; - +static const bt_param_validation_value_descr inputs_elem_descr { + bt_param_validation_value_descr::string_t}; static bt_param_validation_map_value_entry_descr fs_params_entries_descr[] = { - {"inputs", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_MANDATORY, - {bt_param_validation_value_descr::array_t, 1, - BT_PARAM_VALIDATION_INFINITE, inputs_elem_descr}}, - {"trace-name", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_OPTIONAL, - {bt_param_validation_value_descr::string_t}}, - { "clock-class-offset-s", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_OPTIONAL, - { bt_param_validation_value_descr::signed_integer_t }}, - { "clock-class-offset-ns", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_OPTIONAL, - { bt_param_validation_value_descr::signed_integer_t }}, - { "force-clock-class-origin-unix-epoch", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_OPTIONAL, - { bt_param_validation_value_descr::bool_t }}, - BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_END -}; - - -bool read_src_fs_parameters(const bt_value *params, - const bt_value **inputs, - const bt_value **trace_name, - struct ctf_fs_component *ctf_fs, - bt_self_component *self_comp, - bt_self_component_class *self_comp_class) { - bool ret; - const bt_value *value; - bt_logging_level log_level = ctf_fs->log_level; - enum bt_param_validation_status validate_value_status; - gchar *error = NULL; - - validate_value_status = bt_param_validation_validate(params, - fs_params_entries_descr, &error); - if (validate_value_status != BT_PARAM_VALIDATION_STATUS_OK) { - BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class, - "%s", error); - ret = false; - goto end; - } - - /* inputs parameter */ - *inputs = bt_value_map_borrow_entry_value_const(params, "inputs"); - - /* clock-class-offset-s parameter */ - value = bt_value_map_borrow_entry_value_const(params, - "clock-class-offset-s"); - if (value) { - ctf_fs->metadata_config.clock_class_offset_s = - bt_value_integer_signed_get(value); - } - - /* clock-class-offset-ns parameter */ - value = bt_value_map_borrow_entry_value_const(params, - "clock-class-offset-ns"); - if (value) { - ctf_fs->metadata_config.clock_class_offset_ns = - bt_value_integer_signed_get(value); - } - - /* force-clock-class-origin-unix-epoch parameter */ - value = bt_value_map_borrow_entry_value_const(params, - "force-clock-class-origin-unix-epoch"); - if (value) { - ctf_fs->metadata_config.force_clock_class_origin_unix_epoch = - bt_value_bool_get(value); - } - - /* trace-name parameter */ - *trace_name = bt_value_map_borrow_entry_value_const(params, "trace-name"); - - ret = true; + {"inputs", + BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_MANDATORY, + {bt_param_validation_value_descr::array_t, 1, BT_PARAM_VALIDATION_INFINITE, + inputs_elem_descr}}, + {"trace-name", + BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_OPTIONAL, + {bt_param_validation_value_descr::string_t}}, + {"clock-class-offset-s", + BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_OPTIONAL, + {bt_param_validation_value_descr::signed_integer_t}}, + {"clock-class-offset-ns", + BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_OPTIONAL, + {bt_param_validation_value_descr::signed_integer_t}}, + {"force-clock-class-origin-unix-epoch", + BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_OPTIONAL, + {bt_param_validation_value_descr::bool_t}}, + BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_END}; + +bool read_src_fs_parameters(const bt_value *params, const bt_value **inputs, + const bt_value **trace_name, struct ctf_fs_component *ctf_fs, + bt_self_component *self_comp, bt_self_component_class *self_comp_class) +{ + bool ret; + const bt_value *value; + bt_logging_level log_level = ctf_fs->log_level; + enum bt_param_validation_status validate_value_status; + gchar *error = NULL; + + validate_value_status = bt_param_validation_validate(params, fs_params_entries_descr, &error); + if (validate_value_status != BT_PARAM_VALIDATION_STATUS_OK) { + BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class, "%s", error); + ret = false; + goto end; + } + + /* inputs parameter */ + *inputs = bt_value_map_borrow_entry_value_const(params, "inputs"); + + /* clock-class-offset-s parameter */ + value = bt_value_map_borrow_entry_value_const(params, "clock-class-offset-s"); + if (value) { + ctf_fs->metadata_config.clock_class_offset_s = bt_value_integer_signed_get(value); + } + + /* clock-class-offset-ns parameter */ + value = bt_value_map_borrow_entry_value_const(params, "clock-class-offset-ns"); + if (value) { + ctf_fs->metadata_config.clock_class_offset_ns = bt_value_integer_signed_get(value); + } + + /* force-clock-class-origin-unix-epoch parameter */ + value = bt_value_map_borrow_entry_value_const(params, "force-clock-class-origin-unix-epoch"); + if (value) { + ctf_fs->metadata_config.force_clock_class_origin_unix_epoch = bt_value_bool_get(value); + } + + /* trace-name parameter */ + *trace_name = bt_value_map_borrow_entry_value_const(params, "trace-name"); + + ret = true; end: - g_free(error); - return ret; + g_free(error); + return ret; } -static -struct ctf_fs_component *ctf_fs_create( - const bt_value *params, - bt_self_component_source *self_comp_src) +static struct ctf_fs_component *ctf_fs_create(const bt_value *params, + bt_self_component_source *self_comp_src) { - struct ctf_fs_component *ctf_fs = NULL; - const bt_value *inputs_value; - const bt_value *trace_name_value; - bt_self_component *self_comp = - bt_self_component_source_as_self_component(self_comp_src); + struct ctf_fs_component *ctf_fs = NULL; + const bt_value *inputs_value; + const bt_value *trace_name_value; + bt_self_component *self_comp = bt_self_component_source_as_self_component(self_comp_src); - ctf_fs = ctf_fs_component_create(bt_component_get_logging_level( - bt_self_component_as_component(self_comp)), self_comp); - if (!ctf_fs) { - goto error; - } + ctf_fs = ctf_fs_component_create( + bt_component_get_logging_level(bt_self_component_as_component(self_comp)), self_comp); + if (!ctf_fs) { + goto error; + } - if (!read_src_fs_parameters(params, &inputs_value, &trace_name_value, - ctf_fs, self_comp, NULL)) { - goto error; - } + if (!read_src_fs_parameters(params, &inputs_value, &trace_name_value, ctf_fs, self_comp, + NULL)) { + goto error; + } - bt_self_component_set_data(self_comp, ctf_fs); + bt_self_component_set_data(self_comp, ctf_fs); - if (ctf_fs_component_create_ctf_fs_trace(ctf_fs, inputs_value, - trace_name_value, self_comp, NULL)) { - goto error; - } + if (ctf_fs_component_create_ctf_fs_trace(ctf_fs, inputs_value, trace_name_value, self_comp, + NULL)) { + goto error; + } - if (create_streams_for_trace(ctf_fs->trace)) { - goto error; - } + if (create_streams_for_trace(ctf_fs->trace)) { + goto error; + } - if (create_ports_for_trace(ctf_fs, ctf_fs->trace, self_comp_src)) { - goto error; - } + if (create_ports_for_trace(ctf_fs, ctf_fs->trace, self_comp_src)) { + goto error; + } - goto end; + goto end; error: - ctf_fs_destroy(ctf_fs); - ctf_fs = NULL; - bt_self_component_set_data(self_comp, NULL); + ctf_fs_destroy(ctf_fs); + ctf_fs = NULL; + bt_self_component_set_data(self_comp, NULL); end: - return ctf_fs; + return ctf_fs; } BT_HIDDEN -bt_component_class_initialize_method_status ctf_fs_init( - bt_self_component_source *self_comp_src, - bt_self_component_source_configuration *config, - const bt_value *params, __attribute__((unused)) void *init_method_data) +bt_component_class_initialize_method_status +ctf_fs_init(bt_self_component_source *self_comp_src, bt_self_component_source_configuration *config, + const bt_value *params, __attribute__((unused)) void *init_method_data) { - struct ctf_fs_component *ctf_fs; - bt_component_class_initialize_method_status ret = - BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK; + struct ctf_fs_component *ctf_fs; + bt_component_class_initialize_method_status ret = + BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK; - ctf_fs = ctf_fs_create(params, self_comp_src); - if (!ctf_fs) { - ret = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_ERROR; - } + ctf_fs = ctf_fs_create(params, self_comp_src); + if (!ctf_fs) { + ret = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_ERROR; + } - return ret; + return ret; } BT_HIDDEN -bt_component_class_query_method_status ctf_fs_query( - bt_self_component_class_source *comp_class, - bt_private_query_executor *priv_query_exec, - const char *object, const bt_value *params, - __attribute__((unused)) void *method_data, - const bt_value **result) +bt_component_class_query_method_status ctf_fs_query(bt_self_component_class_source *comp_class, + bt_private_query_executor *priv_query_exec, + const char *object, const bt_value *params, + __attribute__((unused)) void *method_data, + const bt_value **result) { - bt_component_class_query_method_status status = - BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_OK; - bt_logging_level log_level = bt_query_executor_get_logging_level( - bt_private_query_executor_as_query_executor_const( - priv_query_exec)); - - if (strcmp(object, "metadata-info") == 0) { - status = metadata_info_query(comp_class, params, log_level, - result); - } else if (strcmp(object, "babeltrace.trace-infos") == 0) { - status = trace_infos_query(comp_class, params, log_level, - result); - } else if (!strcmp(object, "babeltrace.support-info")) { - status = support_info_query(comp_class, params, log_level, result); - } else { - BT_LOGE("Unknown query object `%s`", object); - status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_UNKNOWN_OBJECT; - goto end; - } + bt_component_class_query_method_status status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_OK; + bt_logging_level log_level = bt_query_executor_get_logging_level( + bt_private_query_executor_as_query_executor_const(priv_query_exec)); + + if (strcmp(object, "metadata-info") == 0) { + status = metadata_info_query(comp_class, params, log_level, result); + } else if (strcmp(object, "babeltrace.trace-infos") == 0) { + status = trace_infos_query(comp_class, params, log_level, result); + } else if (!strcmp(object, "babeltrace.support-info")) { + status = support_info_query(comp_class, params, log_level, result); + } else { + BT_LOGE("Unknown query object `%s`", object); + status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_UNKNOWN_OBJECT; + goto end; + } end: - return status; + return status; } diff --git a/src/plugins/ctf/fs-src/fs.hpp b/src/plugins/ctf/fs-src/fs.hpp index da8a3cbc..fe8f0507 100644 --- a/src/plugins/ctf/fs-src/fs.hpp +++ b/src/plugins/ctf/fs-src/fs.hpp @@ -20,213 +20,219 @@ BT_HIDDEN extern bool ctf_fs_debug; -struct ctf_fs_file { - bt_logging_level log_level; +struct ctf_fs_file +{ + bt_logging_level log_level; - /* Weak */ - bt_self_component *self_comp; + /* Weak */ + bt_self_component *self_comp; - /* Owned by this */ - GString *path; + /* Owned by this */ + GString *path; - /* Owned by this */ - FILE *fp; + /* Owned by this */ + FILE *fp; - off_t size; + off_t size; }; -struct ctf_fs_metadata { - /* Owned by this */ - struct ctf_metadata_decoder *decoder; +struct ctf_fs_metadata +{ + /* Owned by this */ + struct ctf_metadata_decoder *decoder; - /* Owned by this */ - bt_trace_class *trace_class; + /* Owned by this */ + bt_trace_class *trace_class; - /* Weak (owned by `decoder` above) */ - struct ctf_trace_class *tc; + /* Weak (owned by `decoder` above) */ + struct ctf_trace_class *tc; - /* Owned by this */ - char *text; + /* Owned by this */ + char *text; - int bo; + int bo; }; -struct ctf_fs_component { - bt_logging_level log_level; +struct ctf_fs_component +{ + bt_logging_level log_level; - /* Array of struct ctf_fs_port_data *, owned by this */ - GPtrArray *port_data; + /* Array of struct ctf_fs_port_data *, owned by this */ + GPtrArray *port_data; - /* Owned by this */ - struct ctf_fs_trace *trace; + /* Owned by this */ + struct ctf_fs_trace *trace; - struct ctf_fs_metadata_config metadata_config; + struct ctf_fs_metadata_config metadata_config; }; -struct ctf_fs_trace { - bt_logging_level log_level; +struct ctf_fs_trace +{ + bt_logging_level log_level; - /* - * Weak. These are mostly used to generate log messages or to append - * error causes. They are mutually exclusive, only one of them must be - * set. - */ - bt_self_component *self_comp; - bt_self_component_class *self_comp_class; + /* + * Weak. These are mostly used to generate log messages or to append + * error causes. They are mutually exclusive, only one of them must be + * set. + */ + bt_self_component *self_comp; + bt_self_component_class *self_comp_class; - /* Owned by this */ - struct ctf_fs_metadata *metadata; + /* Owned by this */ + struct ctf_fs_metadata *metadata; - /* Owned by this */ - bt_trace *trace; + /* Owned by this */ + bt_trace *trace; - /* Array of struct ctf_fs_ds_file_group *, owned by this */ - GPtrArray *ds_file_groups; + /* Array of struct ctf_fs_ds_file_group *, owned by this */ + GPtrArray *ds_file_groups; - /* Owned by this */ - GString *path; + /* Owned by this */ + GString *path; - /* Next automatic stream ID when not provided by packet header */ - uint64_t next_stream_id; + /* Next automatic stream ID when not provided by packet header */ + uint64_t next_stream_id; }; -struct ctf_fs_ds_index_entry { - /* Weak, belongs to ctf_fs_ds_file_info. */ - const char *path; - - /* Position, in bytes, of the packet from the beginning of the file. */ - uint64_t offset; - - /* Size of the packet, in bytes. */ - uint64_t packet_size; - - /* - * Extracted from the packet context, relative to the respective fields' - * mapped clock classes (in cycles). - */ - uint64_t timestamp_begin, timestamp_end; - - /* - * Converted from the packet context, relative to the trace's EPOCH - * (in ns since EPOCH). - */ - int64_t timestamp_begin_ns, timestamp_end_ns; - - /* - * Packet sequence number, or UINT64_MAX if not present in the index. - */ - uint64_t packet_seq_num; +struct ctf_fs_ds_index_entry +{ + /* Weak, belongs to ctf_fs_ds_file_info. */ + const char *path; + + /* Position, in bytes, of the packet from the beginning of the file. */ + uint64_t offset; + + /* Size of the packet, in bytes. */ + uint64_t packet_size; + + /* + * Extracted from the packet context, relative to the respective fields' + * mapped clock classes (in cycles). + */ + uint64_t timestamp_begin, timestamp_end; + + /* + * Converted from the packet context, relative to the trace's EPOCH + * (in ns since EPOCH). + */ + int64_t timestamp_begin_ns, timestamp_end_ns; + + /* + * Packet sequence number, or UINT64_MAX if not present in the index. + */ + uint64_t packet_seq_num; }; -struct ctf_fs_ds_index { - /* Array of pointer to struct ctf_fs_ds_index_entry. */ - GPtrArray *entries; +struct ctf_fs_ds_index +{ + /* Array of pointer to struct ctf_fs_ds_index_entry. */ + GPtrArray *entries; }; -struct ctf_fs_ds_file_group { - /* - * Array of struct ctf_fs_ds_file_info, owned by this. - * - * This is an _ordered_ array of data stream file infos which - * belong to this group (a single stream instance). - * - * You can call ctf_fs_ds_file_create() with one of those paths - * and the trace IR stream below. - */ - GPtrArray *ds_file_infos; - - /* Owned by this */ - struct ctf_stream_class *sc; - - /* Owned by this */ - bt_stream *stream; - - /* Stream (instance) ID; -1ULL means none */ - uint64_t stream_id; - - /* Weak, belongs to component */ - struct ctf_fs_trace *ctf_fs_trace; - - /* - * Owned by this. - */ - struct ctf_fs_ds_index *index; +struct ctf_fs_ds_file_group +{ + /* + * Array of struct ctf_fs_ds_file_info, owned by this. + * + * This is an _ordered_ array of data stream file infos which + * belong to this group (a single stream instance). + * + * You can call ctf_fs_ds_file_create() with one of those paths + * and the trace IR stream below. + */ + GPtrArray *ds_file_infos; + + /* Owned by this */ + struct ctf_stream_class *sc; + + /* Owned by this */ + bt_stream *stream; + + /* Stream (instance) ID; -1ULL means none */ + uint64_t stream_id; + + /* Weak, belongs to component */ + struct ctf_fs_trace *ctf_fs_trace; + + /* + * Owned by this. + */ + struct ctf_fs_ds_index *index; }; -struct ctf_fs_port_data { - /* Weak, belongs to ctf_fs_trace */ - struct ctf_fs_ds_file_group *ds_file_group; +struct ctf_fs_port_data +{ + /* Weak, belongs to ctf_fs_trace */ + struct ctf_fs_ds_file_group *ds_file_group; - /* Weak */ - struct ctf_fs_component *ctf_fs; + /* Weak */ + struct ctf_fs_component *ctf_fs; }; -struct ctf_fs_msg_iter_data { - bt_logging_level log_level; +struct ctf_fs_msg_iter_data +{ + bt_logging_level log_level; - /* Weak */ - bt_self_component *self_comp; + /* Weak */ + bt_self_component *self_comp; - /* Weak */ - bt_self_message_iterator *self_msg_iter; + /* Weak */ + bt_self_message_iterator *self_msg_iter; - /* Weak, belongs to ctf_fs_trace */ - struct ctf_fs_ds_file_group *ds_file_group; + /* Weak, belongs to ctf_fs_trace */ + struct ctf_fs_ds_file_group *ds_file_group; - /* Owned by this */ - struct ctf_msg_iter *msg_iter; + /* Owned by this */ + struct ctf_msg_iter *msg_iter; - /* - * Saved error. If we hit an error in the _next method, but have some - * messages ready to return, we save the error here and return it on - * the next _next call. - */ - bt_message_iterator_class_next_method_status next_saved_status; - const struct bt_error *next_saved_error; + /* + * Saved error. If we hit an error in the _next method, but have some + * messages ready to return, we save the error here and return it on + * the next _next call. + */ + bt_message_iterator_class_next_method_status next_saved_status; + const struct bt_error *next_saved_error; - struct ctf_fs_ds_group_medops_data *msg_iter_medops_data; + struct ctf_fs_ds_group_medops_data *msg_iter_medops_data; }; BT_HIDDEN -bt_component_class_initialize_method_status ctf_fs_init( - bt_self_component_source *source, - bt_self_component_source_configuration *config, - const bt_value *params, void *init_method_data); +bt_component_class_initialize_method_status +ctf_fs_init(bt_self_component_source *source, bt_self_component_source_configuration *config, + const bt_value *params, void *init_method_data); BT_HIDDEN void ctf_fs_finalize(bt_self_component_source *component); BT_HIDDEN -bt_component_class_query_method_status ctf_fs_query( - bt_self_component_class_source *comp_class, - bt_private_query_executor *priv_query_exec, - const char *object, const bt_value *params, - void *method_data, const bt_value **result); +bt_component_class_query_method_status ctf_fs_query(bt_self_component_class_source *comp_class, + bt_private_query_executor *priv_query_exec, + const char *object, const bt_value *params, + void *method_data, const bt_value **result); BT_HIDDEN -bt_message_iterator_class_initialize_method_status ctf_fs_iterator_init( - bt_self_message_iterator *self_msg_iter, - bt_self_message_iterator_configuration *config, - bt_self_component_port_output *self_port); +bt_message_iterator_class_initialize_method_status +ctf_fs_iterator_init(bt_self_message_iterator *self_msg_iter, + bt_self_message_iterator_configuration *config, + bt_self_component_port_output *self_port); BT_HIDDEN void ctf_fs_iterator_finalize(bt_self_message_iterator *it); BT_HIDDEN -bt_message_iterator_class_next_method_status ctf_fs_iterator_next( - bt_self_message_iterator *iterator, - bt_message_array_const msgs, uint64_t capacity, - uint64_t *count); +bt_message_iterator_class_next_method_status +ctf_fs_iterator_next(bt_self_message_iterator *iterator, bt_message_array_const msgs, + uint64_t capacity, uint64_t *count); BT_HIDDEN -bt_message_iterator_class_seek_beginning_method_status ctf_fs_iterator_seek_beginning( - bt_self_message_iterator *message_iterator); +bt_message_iterator_class_seek_beginning_method_status +ctf_fs_iterator_seek_beginning(bt_self_message_iterator *message_iterator); /* Create and initialize a new, empty ctf_fs_component. */ BT_HIDDEN struct ctf_fs_component *ctf_fs_component_create(bt_logging_level log_level, - bt_self_component *self_comp); + bt_self_component *self_comp); /* * Create one `struct ctf_fs_trace` from one trace, or multiple traces sharing @@ -241,12 +247,11 @@ struct ctf_fs_component *ctf_fs_component_create(bt_logging_level log_level, */ BT_HIDDEN -int ctf_fs_component_create_ctf_fs_trace( - struct ctf_fs_component *ctf_fs, - const bt_value *paths_value, - const bt_value *trace_name_value, - bt_self_component *self_comp, - bt_self_component_class *self_comp_class); +int ctf_fs_component_create_ctf_fs_trace(struct ctf_fs_component *ctf_fs, + const bt_value *paths_value, + const bt_value *trace_name_value, + bt_self_component *self_comp, + bt_self_component_class *self_comp_class); /* Free `ctf_fs` and everything it owns. */ @@ -269,12 +274,9 @@ void ctf_fs_destroy(struct ctf_fs_component *ctf_fs); */ BT_HIDDEN -bool read_src_fs_parameters(const bt_value *params, - const bt_value **paths, - const bt_value **trace_name, - struct ctf_fs_component *ctf_fs, - bt_self_component *self_comp, - bt_self_component_class *self_comp_class); +bool read_src_fs_parameters(const bt_value *params, const bt_value **paths, + const bt_value **trace_name, struct ctf_fs_component *ctf_fs, + bt_self_component *self_comp, bt_self_component_class *self_comp_class); /* * Generate the port name to be used for a given data stream file group. diff --git a/src/plugins/ctf/fs-src/lttng-index.hpp b/src/plugins/ctf/fs-src/lttng-index.hpp index 46eafa6b..644f57de 100644 --- a/src/plugins/ctf/fs-src/lttng-index.hpp +++ b/src/plugins/ctf/fs-src/lttng-index.hpp @@ -12,38 +12,40 @@ #include #include "compat/limits.h" -#define CTF_INDEX_MAGIC 0xC1F1DCC1 -#define CTF_INDEX_MAJOR 1 -#define CTF_INDEX_MINOR 1 +#define CTF_INDEX_MAGIC 0xC1F1DCC1 +#define CTF_INDEX_MAJOR 1 +#define CTF_INDEX_MINOR 1 #define CTF_INDEX_1_0_SIZE offsetof(struct ctf_packet_index, stream_instance_id) /* * Header at the beginning of each index file. * All integer fields are stored in big endian. */ -struct ctf_packet_index_file_hdr { - uint32_t magic; - uint32_t index_major; - uint32_t index_minor; - /* size of struct ctf_packet_index, in bytes. */ - uint32_t packet_index_len; +struct ctf_packet_index_file_hdr +{ + uint32_t magic; + uint32_t index_major; + uint32_t index_minor; + /* size of struct ctf_packet_index, in bytes. */ + uint32_t packet_index_len; } __attribute__((__packed__)); /* * Packet index generated for each trace packet store in a trace file. * All integer fields are stored in big endian. */ -struct ctf_packet_index { - uint64_t offset; /* offset of the packet in the file, in bytes */ - uint64_t packet_size; /* packet size, in bits */ - uint64_t content_size; /* content size, in bits */ - uint64_t timestamp_begin; - uint64_t timestamp_end; - uint64_t events_discarded; - uint64_t stream_id; - /* CTF_INDEX 1.0 limit */ - uint64_t stream_instance_id; /* ID of the channel instance */ - uint64_t packet_seq_num; /* packet sequence number */ +struct ctf_packet_index +{ + uint64_t offset; /* offset of the packet in the file, in bytes */ + uint64_t packet_size; /* packet size, in bits */ + uint64_t content_size; /* content size, in bits */ + uint64_t timestamp_begin; + uint64_t timestamp_end; + uint64_t events_discarded; + uint64_t stream_id; + /* CTF_INDEX 1.0 limit */ + uint64_t stream_instance_id; /* ID of the channel instance */ + uint64_t packet_seq_num; /* packet sequence number */ } __attribute__((__packed__)); #endif /* LTTNG_INDEX_H */ diff --git a/src/plugins/ctf/fs-src/metadata.cpp b/src/plugins/ctf/fs-src/metadata.cpp index 51bd5b96..d7c89e5e 100644 --- a/src/plugins/ctf/fs-src/metadata.cpp +++ b/src/plugins/ctf/fs-src/metadata.cpp @@ -6,8 +6,8 @@ */ #define BT_COMP_LOG_SELF_COMP self_comp -#define BT_LOG_OUTPUT_LEVEL log_level -#define BT_LOG_TAG "PLUGIN/SRC.CTF.FS/META" +#define BT_LOG_OUTPUT_LEVEL log_level +#define BT_LOG_TAG "PLUGIN/SRC.CTF.FS/META" #include "logging/comp-logging.h" #include @@ -27,121 +27,114 @@ BT_HIDDEN FILE *ctf_fs_metadata_open_file(const char *trace_path) { - GString *metadata_path; - FILE *fp = NULL; + GString *metadata_path; + FILE *fp = NULL; - metadata_path = g_string_new(trace_path); - if (!metadata_path) { - goto end; - } + metadata_path = g_string_new(trace_path); + if (!metadata_path) { + goto end; + } - g_string_append(metadata_path, G_DIR_SEPARATOR_S CTF_FS_METADATA_FILENAME); - fp = fopen(metadata_path->str, "rb"); - g_string_free(metadata_path, TRUE); + g_string_append(metadata_path, G_DIR_SEPARATOR_S CTF_FS_METADATA_FILENAME); + fp = fopen(metadata_path->str, "rb"); + g_string_free(metadata_path, TRUE); end: - return fp; + return fp; } -static struct ctf_fs_file *get_file(const char *trace_path, - bt_logging_level log_level, bt_self_component *self_comp) +static struct ctf_fs_file *get_file(const char *trace_path, bt_logging_level log_level, + bt_self_component *self_comp) { - struct ctf_fs_file *file = ctf_fs_file_create(log_level, self_comp); + struct ctf_fs_file *file = ctf_fs_file_create(log_level, self_comp); - if (!file) { - goto error; - } + if (!file) { + goto error; + } - g_string_append(file->path, trace_path); - g_string_append(file->path, G_DIR_SEPARATOR_S CTF_FS_METADATA_FILENAME); + g_string_append(file->path, trace_path); + g_string_append(file->path, G_DIR_SEPARATOR_S CTF_FS_METADATA_FILENAME); - if (ctf_fs_file_open(file, "rb")) { - goto error; - } + if (ctf_fs_file_open(file, "rb")) { + goto error; + } - goto end; + goto end; error: - if (file) { - ctf_fs_file_destroy(file); - file = NULL; - } + if (file) { + ctf_fs_file_destroy(file); + file = NULL; + } end: - return file; + return file; } BT_HIDDEN -int ctf_fs_metadata_set_trace_class( - bt_self_component *self_comp, - struct ctf_fs_trace *ctf_fs_trace, - struct ctf_fs_metadata_config *config) +int ctf_fs_metadata_set_trace_class(bt_self_component *self_comp, struct ctf_fs_trace *ctf_fs_trace, + struct ctf_fs_metadata_config *config) { - int ret = 0; - struct ctf_fs_file *file = NULL; - bt_logging_level log_level = ctf_fs_trace->log_level; - - ctf_metadata_decoder_config decoder_config{}; - decoder_config.log_level = ctf_fs_trace->log_level, - decoder_config.self_comp = self_comp, - decoder_config.clock_class_offset_s = config ? config->clock_class_offset_s : 0, - decoder_config.clock_class_offset_ns = config ? config->clock_class_offset_ns : 0, - decoder_config.force_clock_class_origin_unix_epoch = - config ? config->force_clock_class_origin_unix_epoch : false, - decoder_config.create_trace_class = true, - - file = get_file(ctf_fs_trace->path->str, log_level, self_comp); - if (!file) { - BT_COMP_LOGE("Cannot create metadata file object."); - ret = -1; - goto end; - } - - ctf_fs_trace->metadata->decoder = ctf_metadata_decoder_create( - &decoder_config); - if (!ctf_fs_trace->metadata->decoder) { - BT_COMP_LOGE("Cannot create metadata decoder object."); - ret = -1; - goto end; - } - - ret = ctf_metadata_decoder_append_content( - ctf_fs_trace->metadata->decoder, file->fp); - if (ret) { - BT_COMP_LOGE("Cannot update metadata decoder's content."); - goto end; - } - - ctf_fs_trace->metadata->trace_class = - ctf_metadata_decoder_get_ir_trace_class( - ctf_fs_trace->metadata->decoder); - BT_ASSERT(!self_comp || ctf_fs_trace->metadata->trace_class); - ctf_fs_trace->metadata->tc = - ctf_metadata_decoder_borrow_ctf_trace_class( - ctf_fs_trace->metadata->decoder); - BT_ASSERT(ctf_fs_trace->metadata->tc); + int ret = 0; + struct ctf_fs_file *file = NULL; + bt_logging_level log_level = ctf_fs_trace->log_level; + + ctf_metadata_decoder_config decoder_config {}; + decoder_config.log_level = ctf_fs_trace->log_level, decoder_config.self_comp = self_comp, + decoder_config.clock_class_offset_s = config ? config->clock_class_offset_s : 0, + decoder_config.clock_class_offset_ns = config ? config->clock_class_offset_ns : 0, + decoder_config.force_clock_class_origin_unix_epoch = + config ? config->force_clock_class_origin_unix_epoch : false, + decoder_config.create_trace_class = true, + + file = get_file(ctf_fs_trace->path->str, log_level, self_comp); + if (!file) { + BT_COMP_LOGE("Cannot create metadata file object."); + ret = -1; + goto end; + } + + ctf_fs_trace->metadata->decoder = ctf_metadata_decoder_create(&decoder_config); + if (!ctf_fs_trace->metadata->decoder) { + BT_COMP_LOGE("Cannot create metadata decoder object."); + ret = -1; + goto end; + } + + ret = ctf_metadata_decoder_append_content(ctf_fs_trace->metadata->decoder, file->fp); + if (ret) { + BT_COMP_LOGE("Cannot update metadata decoder's content."); + goto end; + } + + ctf_fs_trace->metadata->trace_class = + ctf_metadata_decoder_get_ir_trace_class(ctf_fs_trace->metadata->decoder); + BT_ASSERT(!self_comp || ctf_fs_trace->metadata->trace_class); + ctf_fs_trace->metadata->tc = + ctf_metadata_decoder_borrow_ctf_trace_class(ctf_fs_trace->metadata->decoder); + BT_ASSERT(ctf_fs_trace->metadata->tc); end: - ctf_fs_file_destroy(file); - return ret; + ctf_fs_file_destroy(file); + return ret; } BT_HIDDEN int ctf_fs_metadata_init(struct ctf_fs_metadata *metadata) { - /* Nothing to initialize for the moment. */ - return 0; + /* Nothing to initialize for the moment. */ + return 0; } BT_HIDDEN void ctf_fs_metadata_fini(struct ctf_fs_metadata *metadata) { - free(metadata->text); + free(metadata->text); - if (metadata->trace_class) { - BT_TRACE_CLASS_PUT_REF_AND_RESET(metadata->trace_class); - } + if (metadata->trace_class) { + BT_TRACE_CLASS_PUT_REF_AND_RESET(metadata->trace_class); + } - if (metadata->decoder) { - ctf_metadata_decoder_destroy(metadata->decoder); - } + if (metadata->decoder) { + ctf_metadata_decoder_destroy(metadata->decoder); + } } diff --git a/src/plugins/ctf/fs-src/metadata.hpp b/src/plugins/ctf/fs-src/metadata.hpp index 63dc3053..c04628f0 100644 --- a/src/plugins/ctf/fs-src/metadata.hpp +++ b/src/plugins/ctf/fs-src/metadata.hpp @@ -13,15 +13,16 @@ #include "common/macros.h" #include -#define CTF_FS_METADATA_FILENAME "metadata" +#define CTF_FS_METADATA_FILENAME "metadata" struct ctf_fs_trace; struct ctf_fs_metadata; -struct ctf_fs_metadata_config { - bool force_clock_class_origin_unix_epoch; - int64_t clock_class_offset_s; - int64_t clock_class_offset_ns; +struct ctf_fs_metadata_config +{ + bool force_clock_class_origin_unix_epoch; + int64_t clock_class_offset_s; + int64_t clock_class_offset_ns; }; BT_HIDDEN @@ -31,9 +32,8 @@ BT_HIDDEN void ctf_fs_metadata_fini(struct ctf_fs_metadata *metadata); BT_HIDDEN -int ctf_fs_metadata_set_trace_class(bt_self_component *self_comp, - struct ctf_fs_trace *ctf_fs_trace, - struct ctf_fs_metadata_config *config); +int ctf_fs_metadata_set_trace_class(bt_self_component *self_comp, struct ctf_fs_trace *ctf_fs_trace, + struct ctf_fs_metadata_config *config); BT_HIDDEN FILE *ctf_fs_metadata_open_file(const char *trace_path); diff --git a/src/plugins/ctf/fs-src/query.cpp b/src/plugins/ctf/fs-src/query.cpp index 04d5aab8..846dde6b 100644 --- a/src/plugins/ctf/fs-src/query.cpp +++ b/src/plugins/ctf/fs-src/query.cpp @@ -7,7 +7,7 @@ */ #define BT_LOG_OUTPUT_LEVEL log_level -#define BT_LOG_TAG "PLUGIN/SRC.CTF.FS/QUERY" +#define BT_LOG_TAG "PLUGIN/SRC.CTF.FS/QUERY" #include "logging/log.h" #include "query.hpp" @@ -26,490 +26,460 @@ #include "fs.hpp" #include "logging/comp-logging.h" -#define METADATA_TEXT_SIG "/* CTF 1.8" +#define METADATA_TEXT_SIG "/* CTF 1.8" -struct range { - int64_t begin_ns = 0; - int64_t end_ns = 0; - bool set = false; +struct range +{ + int64_t begin_ns = 0; + int64_t end_ns = 0; + bool set = false; }; BT_HIDDEN -bt_component_class_query_method_status metadata_info_query( - bt_self_component_class_source *self_comp_class_src, - const bt_value *params, bt_logging_level log_level, - const bt_value **user_result) +bt_component_class_query_method_status +metadata_info_query(bt_self_component_class_source *self_comp_class_src, const bt_value *params, + bt_logging_level log_level, const bt_value **user_result) { - bt_component_class_query_method_status status = - BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_OK; - bt_self_component_class *self_comp_class = - bt_self_component_class_source_as_self_component_class(self_comp_class_src); - bt_value *result = NULL; - const bt_value *path_value = NULL; - FILE *metadata_fp = NULL; - int ret; - int bo; - const char *path; - bool is_packetized; - struct ctf_metadata_decoder *decoder = NULL; - ctf_metadata_decoder_config decoder_cfg{}; - enum ctf_metadata_decoder_status decoder_status; - - result = bt_value_map_create(); - if (!result) { - status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_MEMORY_ERROR; - goto error; - } - - BT_ASSERT(params); - - if (!bt_value_is_map(params)) { - BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, - "Query parameters is not a map value object."); - status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; - goto error; - } - - path_value = bt_value_map_borrow_entry_value_const(params, "path"); - if (!path_value) { - BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, - "Mandatory `path` parameter missing"); - status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; - goto error; - } - - if (!bt_value_is_string(path_value)) { - BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, - "`path` parameter is required to be a string value"); - status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; - goto error; - } - - path = bt_value_string_get(path_value); - - BT_ASSERT(path); - metadata_fp = ctf_fs_metadata_open_file(path); - if (!metadata_fp) { - BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, - "Cannot open trace metadata: path=\"%s\".", path); - goto error; - } - - ret = ctf_metadata_decoder_is_packetized(metadata_fp, &is_packetized, - &bo, log_level, NULL); - if (ret) { - BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, - "Cannot check whether or not the metadata stream is packetized: path=\"%s\".", - path); - goto error; - } - - decoder_cfg.log_level = log_level; - decoder_cfg.self_comp_class = self_comp_class; - decoder_cfg.keep_plain_text = true; - decoder = ctf_metadata_decoder_create(&decoder_cfg); - if (!decoder) { - BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, - "Cannot create metadata decoder: path=\"%s\".", path); - goto error; - } - - rewind(metadata_fp); - decoder_status = ctf_metadata_decoder_append_content(decoder, - metadata_fp); - if (decoder_status) { - BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, - "Cannot update metadata decoder's content: path=\"%s\".", - path); - goto error; - } - - ret = bt_value_map_insert_string_entry(result, "text", - ctf_metadata_decoder_get_text(decoder)); - if (ret) { - BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, - "Cannot insert metadata text into query result."); - goto error; - } - - ret = bt_value_map_insert_bool_entry(result, "is-packetized", - is_packetized); - if (ret) { - BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, - "Cannot insert \"is-packetized\" attribute into query result."); - goto error; - } - - goto end; + bt_component_class_query_method_status status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_OK; + bt_self_component_class *self_comp_class = + bt_self_component_class_source_as_self_component_class(self_comp_class_src); + bt_value *result = NULL; + const bt_value *path_value = NULL; + FILE *metadata_fp = NULL; + int ret; + int bo; + const char *path; + bool is_packetized; + struct ctf_metadata_decoder *decoder = NULL; + ctf_metadata_decoder_config decoder_cfg {}; + enum ctf_metadata_decoder_status decoder_status; + + result = bt_value_map_create(); + if (!result) { + status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_MEMORY_ERROR; + goto error; + } + + BT_ASSERT(params); + + if (!bt_value_is_map(params)) { + BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, + "Query parameters is not a map value object."); + status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; + goto error; + } + + path_value = bt_value_map_borrow_entry_value_const(params, "path"); + if (!path_value) { + BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, "Mandatory `path` parameter missing"); + status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; + goto error; + } + + if (!bt_value_is_string(path_value)) { + BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, + "`path` parameter is required to be a string value"); + status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; + goto error; + } + + path = bt_value_string_get(path_value); + + BT_ASSERT(path); + metadata_fp = ctf_fs_metadata_open_file(path); + if (!metadata_fp) { + BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, "Cannot open trace metadata: path=\"%s\".", + path); + goto error; + } + + ret = ctf_metadata_decoder_is_packetized(metadata_fp, &is_packetized, &bo, log_level, NULL); + if (ret) { + BT_COMP_CLASS_LOGE_APPEND_CAUSE( + self_comp_class, + "Cannot check whether or not the metadata stream is packetized: path=\"%s\".", path); + goto error; + } + + decoder_cfg.log_level = log_level; + decoder_cfg.self_comp_class = self_comp_class; + decoder_cfg.keep_plain_text = true; + decoder = ctf_metadata_decoder_create(&decoder_cfg); + if (!decoder) { + BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, + "Cannot create metadata decoder: path=\"%s\".", path); + goto error; + } + + rewind(metadata_fp); + decoder_status = ctf_metadata_decoder_append_content(decoder, metadata_fp); + if (decoder_status) { + BT_COMP_CLASS_LOGE_APPEND_CAUSE( + self_comp_class, "Cannot update metadata decoder's content: path=\"%s\".", path); + goto error; + } + + ret = bt_value_map_insert_string_entry(result, "text", ctf_metadata_decoder_get_text(decoder)); + if (ret) { + BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, + "Cannot insert metadata text into query result."); + goto error; + } + + ret = bt_value_map_insert_bool_entry(result, "is-packetized", is_packetized); + if (ret) { + BT_COMP_CLASS_LOGE_APPEND_CAUSE( + self_comp_class, "Cannot insert \"is-packetized\" attribute into query result."); + goto error; + } + + goto end; error: - BT_VALUE_PUT_REF_AND_RESET(result); - result = NULL; + BT_VALUE_PUT_REF_AND_RESET(result); + result = NULL; - if (status >= 0) { - status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; - } + if (status >= 0) { + status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; + } end: - ctf_metadata_decoder_destroy(decoder); - - if (metadata_fp) { - ret = fclose(metadata_fp); - if (ret) { - BT_LOGE_ERRNO("Cannot close metatada file stream", - ": path=\"%s\"", path); - } - } - - *user_result = result; - return status; + ctf_metadata_decoder_destroy(decoder); + + if (metadata_fp) { + ret = fclose(metadata_fp); + if (ret) { + BT_LOGE_ERRNO("Cannot close metatada file stream", ": path=\"%s\"", path); + } + } + + *user_result = result; + return status; } -static -int add_range(bt_value *info, struct range *range, - const char *range_name) +static int add_range(bt_value *info, struct range *range, const char *range_name) { - int ret = 0; - bt_value_map_insert_entry_status status; - bt_value *range_map; - - if (!range->set) { - /* Not an error. */ - goto end; - } - - status = bt_value_map_insert_empty_map_entry(info, range_name, - &range_map); - if (status != BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) { - ret = -1; - goto end; - } - - status = bt_value_map_insert_signed_integer_entry(range_map, "begin", - range->begin_ns); - if (status != BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) { - ret = -1; - goto end; - } - - status = bt_value_map_insert_signed_integer_entry(range_map, "end", - range->end_ns); - if (status != BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) { - ret = -1; - goto end; - } + int ret = 0; + bt_value_map_insert_entry_status status; + bt_value *range_map; + + if (!range->set) { + /* Not an error. */ + goto end; + } + + status = bt_value_map_insert_empty_map_entry(info, range_name, &range_map); + if (status != BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) { + ret = -1; + goto end; + } + + status = bt_value_map_insert_signed_integer_entry(range_map, "begin", range->begin_ns); + if (status != BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) { + ret = -1; + goto end; + } + + status = bt_value_map_insert_signed_integer_entry(range_map, "end", range->end_ns); + if (status != BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) { + ret = -1; + goto end; + } end: - return ret; + return ret; } -static -int populate_stream_info(struct ctf_fs_ds_file_group *group, - bt_value *group_info, struct range *stream_range) +static int populate_stream_info(struct ctf_fs_ds_file_group *group, bt_value *group_info, + struct range *stream_range) { - int ret = 0; - bt_value_map_insert_entry_status insert_status; - struct ctf_fs_ds_index_entry *first_ds_index_entry, *last_ds_index_entry; - gchar *port_name = NULL; - - /* - * Since each `struct ctf_fs_ds_file_group` has a sorted array of - * `struct ctf_fs_ds_index_entry`, we can compute the stream range from - * the timestamp_begin of the first index entry and the timestamp_end - * of the last index entry. - */ - BT_ASSERT(group->index); - BT_ASSERT(group->index->entries); - BT_ASSERT(group->index->entries->len > 0); - - /* First entry. */ - first_ds_index_entry = (struct ctf_fs_ds_index_entry *) g_ptr_array_index( - group->index->entries, 0); - - /* Last entry. */ - last_ds_index_entry = (struct ctf_fs_ds_index_entry *) g_ptr_array_index( - group->index->entries, group->index->entries->len - 1); - - stream_range->begin_ns = first_ds_index_entry->timestamp_begin_ns; - stream_range->end_ns = last_ds_index_entry->timestamp_end_ns; - - /* - * If any of the begin and end timestamps is not set it means that - * packets don't include `timestamp_begin` _and_ `timestamp_end` fields - * in their packet context so we can't set the range. - */ - stream_range->set = stream_range->begin_ns != UINT64_C(-1) && - stream_range->end_ns != UINT64_C(-1); - - ret = add_range(group_info, stream_range, "range-ns"); - if (ret) { - goto end; - } - - port_name = ctf_fs_make_port_name(group); - if (!port_name) { - ret = -1; - goto end; - } - - insert_status = bt_value_map_insert_string_entry(group_info, - "port-name", port_name); - if (insert_status != BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) { - ret = -1; - goto end; - } + int ret = 0; + bt_value_map_insert_entry_status insert_status; + struct ctf_fs_ds_index_entry *first_ds_index_entry, *last_ds_index_entry; + gchar *port_name = NULL; + + /* + * Since each `struct ctf_fs_ds_file_group` has a sorted array of + * `struct ctf_fs_ds_index_entry`, we can compute the stream range from + * the timestamp_begin of the first index entry and the timestamp_end + * of the last index entry. + */ + BT_ASSERT(group->index); + BT_ASSERT(group->index->entries); + BT_ASSERT(group->index->entries->len > 0); + + /* First entry. */ + first_ds_index_entry = + (struct ctf_fs_ds_index_entry *) g_ptr_array_index(group->index->entries, 0); + + /* Last entry. */ + last_ds_index_entry = (struct ctf_fs_ds_index_entry *) g_ptr_array_index( + group->index->entries, group->index->entries->len - 1); + + stream_range->begin_ns = first_ds_index_entry->timestamp_begin_ns; + stream_range->end_ns = last_ds_index_entry->timestamp_end_ns; + + /* + * If any of the begin and end timestamps is not set it means that + * packets don't include `timestamp_begin` _and_ `timestamp_end` fields + * in their packet context so we can't set the range. + */ + stream_range->set = + stream_range->begin_ns != UINT64_C(-1) && stream_range->end_ns != UINT64_C(-1); + + ret = add_range(group_info, stream_range, "range-ns"); + if (ret) { + goto end; + } + + port_name = ctf_fs_make_port_name(group); + if (!port_name) { + ret = -1; + goto end; + } + + insert_status = bt_value_map_insert_string_entry(group_info, "port-name", port_name); + if (insert_status != BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) { + ret = -1; + goto end; + } end: - g_free(port_name); - return ret; + g_free(port_name); + return ret; } -static -int populate_trace_info(const struct ctf_fs_trace *trace, bt_value *trace_info, - bt_logging_level log_level, - bt_self_component_class *self_comp_class) +static int populate_trace_info(const struct ctf_fs_trace *trace, bt_value *trace_info, + bt_logging_level log_level, bt_self_component_class *self_comp_class) { - int ret = 0; - size_t group_idx; - bt_value_map_insert_entry_status insert_status; - bt_value_array_append_element_status append_status; - bt_value *file_groups = NULL; - - BT_ASSERT(trace->ds_file_groups); - /* Add trace range info only if it contains streams. */ - if (trace->ds_file_groups->len == 0) { - ret = -1; - BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, - "Trace has no streams: trace-path=%s", trace->path->str); - goto end; - } - - insert_status = bt_value_map_insert_empty_array_entry(trace_info, - "stream-infos", &file_groups); - if (insert_status != BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) { - ret = -1; - goto end; - } - - /* Find range of all stream groups, and of the trace. */ - for (group_idx = 0; group_idx < trace->ds_file_groups->len; - group_idx++) { - bt_value *group_info; - range group_range; - ctf_fs_ds_file_group *group = - (ctf_fs_ds_file_group *) g_ptr_array_index(trace->ds_file_groups, group_idx); - - append_status = bt_value_array_append_empty_map_element( - file_groups, &group_info); - if (append_status != BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_OK) { - ret = -1; - goto end; - } - - ret = populate_stream_info(group, group_info, &group_range); - if (ret) { - goto end; - } - } + int ret = 0; + size_t group_idx; + bt_value_map_insert_entry_status insert_status; + bt_value_array_append_element_status append_status; + bt_value *file_groups = NULL; + + BT_ASSERT(trace->ds_file_groups); + /* Add trace range info only if it contains streams. */ + if (trace->ds_file_groups->len == 0) { + ret = -1; + BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, "Trace has no streams: trace-path=%s", + trace->path->str); + goto end; + } + + insert_status = bt_value_map_insert_empty_array_entry(trace_info, "stream-infos", &file_groups); + if (insert_status != BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) { + ret = -1; + goto end; + } + + /* Find range of all stream groups, and of the trace. */ + for (group_idx = 0; group_idx < trace->ds_file_groups->len; group_idx++) { + bt_value *group_info; + range group_range; + ctf_fs_ds_file_group *group = + (ctf_fs_ds_file_group *) g_ptr_array_index(trace->ds_file_groups, group_idx); + + append_status = bt_value_array_append_empty_map_element(file_groups, &group_info); + if (append_status != BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_OK) { + ret = -1; + goto end; + } + + ret = populate_stream_info(group, group_info, &group_range); + if (ret) { + goto end; + } + } end: - return ret; + return ret; } BT_HIDDEN -bt_component_class_query_method_status trace_infos_query( - bt_self_component_class_source *self_comp_class_src, - const bt_value *params, bt_logging_level log_level, - const bt_value **user_result) +bt_component_class_query_method_status +trace_infos_query(bt_self_component_class_source *self_comp_class_src, const bt_value *params, + bt_logging_level log_level, const bt_value **user_result) { - struct ctf_fs_component *ctf_fs = NULL; - bt_component_class_query_method_status status = - BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_OK; - bt_self_component_class *self_comp_class = - bt_self_component_class_source_as_self_component_class( - self_comp_class_src); - bt_value *result = NULL; - const bt_value *inputs_value = NULL; - const bt_value *trace_name_value; - int ret = 0; - bt_value *trace_info = NULL; - bt_value_array_append_element_status append_status; - - BT_ASSERT(params); - - if (!bt_value_is_map(params)) { - BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, - "Query parameters is not a map value object."); - status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; - goto error; - } - - ctf_fs = ctf_fs_component_create(log_level, NULL); - if (!ctf_fs) { - goto error; - } - - if (!read_src_fs_parameters(params, &inputs_value, &trace_name_value, - ctf_fs, NULL, self_comp_class)) { - status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; - goto error; - } - - if (ctf_fs_component_create_ctf_fs_trace(ctf_fs, inputs_value, - trace_name_value, NULL, self_comp_class)) { - goto error; - } - - result = bt_value_array_create(); - if (!result) { - status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_MEMORY_ERROR; - goto error; - } - - append_status = bt_value_array_append_empty_map_element(result, - &trace_info); - if (append_status != BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_OK) { - BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, - "Failed to create trace info map."); - goto error; - } - - ret = populate_trace_info(ctf_fs->trace, trace_info, log_level, - self_comp_class); - if (ret) { - goto error; - } - - goto end; + struct ctf_fs_component *ctf_fs = NULL; + bt_component_class_query_method_status status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_OK; + bt_self_component_class *self_comp_class = + bt_self_component_class_source_as_self_component_class(self_comp_class_src); + bt_value *result = NULL; + const bt_value *inputs_value = NULL; + const bt_value *trace_name_value; + int ret = 0; + bt_value *trace_info = NULL; + bt_value_array_append_element_status append_status; + + BT_ASSERT(params); + + if (!bt_value_is_map(params)) { + BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, + "Query parameters is not a map value object."); + status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; + goto error; + } + + ctf_fs = ctf_fs_component_create(log_level, NULL); + if (!ctf_fs) { + goto error; + } + + if (!read_src_fs_parameters(params, &inputs_value, &trace_name_value, ctf_fs, NULL, + self_comp_class)) { + status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; + goto error; + } + + if (ctf_fs_component_create_ctf_fs_trace(ctf_fs, inputs_value, trace_name_value, NULL, + self_comp_class)) { + goto error; + } + + result = bt_value_array_create(); + if (!result) { + status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_MEMORY_ERROR; + goto error; + } + + append_status = bt_value_array_append_empty_map_element(result, &trace_info); + if (append_status != BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_OK) { + BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, "Failed to create trace info map."); + goto error; + } + + ret = populate_trace_info(ctf_fs->trace, trace_info, log_level, self_comp_class); + if (ret) { + goto error; + } + + goto end; error: - BT_VALUE_PUT_REF_AND_RESET(result); + BT_VALUE_PUT_REF_AND_RESET(result); - if (status >= 0) { - status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; - } + if (status >= 0) { + status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; + } end: - if (ctf_fs) { - ctf_fs_destroy(ctf_fs); - ctf_fs = NULL; - } + if (ctf_fs) { + ctf_fs_destroy(ctf_fs); + ctf_fs = NULL; + } - *user_result = result; - return status; + *user_result = result; + return status; } BT_HIDDEN -bt_component_class_query_method_status support_info_query( - bt_self_component_class_source *comp_class, - const bt_value *params, bt_logging_level log_level, - const bt_value **user_result) +bt_component_class_query_method_status +support_info_query(bt_self_component_class_source *comp_class, const bt_value *params, + bt_logging_level log_level, const bt_value **user_result) { - const bt_value *input_type_value; - const char *input_type; - bt_component_class_query_method_status status; - bt_value_map_insert_entry_status insert_entry_status; - double weight = 0; - gchar *metadata_path = NULL; - bt_value *result = NULL; - struct ctf_metadata_decoder *metadata_decoder = NULL; - FILE *metadata_file = NULL; - char uuid_str[BT_UUID_STR_LEN + 1]; - bool has_uuid = false; - const bt_value *input_value; - const char *input; - - input_type_value = bt_value_map_borrow_entry_value_const(params, "type"); - BT_ASSERT(input_type_value); - BT_ASSERT(bt_value_get_type(input_type_value) == BT_VALUE_TYPE_STRING); - input_type = bt_value_string_get(input_type_value); - - if (strcmp(input_type, "directory") != 0) { - goto create_result; - } - - input_value = bt_value_map_borrow_entry_value_const(params, "input"); - BT_ASSERT(input_value); - BT_ASSERT(bt_value_get_type(input_value) == BT_VALUE_TYPE_STRING); - input = bt_value_string_get(input_value); - - metadata_path = g_build_filename(input, CTF_FS_METADATA_FILENAME, NULL); - if (!metadata_path) { - status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_MEMORY_ERROR; - goto end; - } - - metadata_file = g_fopen(metadata_path, "rb"); - if (metadata_file) { - ctf_metadata_decoder_config metadata_decoder_config{}; - enum ctf_metadata_decoder_status decoder_status; - bt_uuid_t uuid; - - metadata_decoder_config.log_level = log_level; - metadata_decoder_config.self_comp_class = - bt_self_component_class_source_as_self_component_class(comp_class); - - metadata_decoder = ctf_metadata_decoder_create( - &metadata_decoder_config); - if (!metadata_decoder) { - status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; - goto end; - } - - decoder_status = ctf_metadata_decoder_append_content( - metadata_decoder, metadata_file); - if (decoder_status != CTF_METADATA_DECODER_STATUS_OK) { - BT_LOGW("cannot append metadata content: metadata-decoder-status=%d", - decoder_status); - status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; - goto end; - } - - /* - * We were able to parse the metadata file, so we are - * confident it's a CTF trace. - */ - weight = 0.75; - - /* If the trace has a UUID, return the stringified UUID as the group. */ - if (ctf_metadata_decoder_get_trace_class_uuid(metadata_decoder, uuid) == 0) { - bt_uuid_to_str(uuid, uuid_str); - has_uuid = true; - } - } + const bt_value *input_type_value; + const char *input_type; + bt_component_class_query_method_status status; + bt_value_map_insert_entry_status insert_entry_status; + double weight = 0; + gchar *metadata_path = NULL; + bt_value *result = NULL; + struct ctf_metadata_decoder *metadata_decoder = NULL; + FILE *metadata_file = NULL; + char uuid_str[BT_UUID_STR_LEN + 1]; + bool has_uuid = false; + const bt_value *input_value; + const char *input; + + input_type_value = bt_value_map_borrow_entry_value_const(params, "type"); + BT_ASSERT(input_type_value); + BT_ASSERT(bt_value_get_type(input_type_value) == BT_VALUE_TYPE_STRING); + input_type = bt_value_string_get(input_type_value); + + if (strcmp(input_type, "directory") != 0) { + goto create_result; + } + + input_value = bt_value_map_borrow_entry_value_const(params, "input"); + BT_ASSERT(input_value); + BT_ASSERT(bt_value_get_type(input_value) == BT_VALUE_TYPE_STRING); + input = bt_value_string_get(input_value); + + metadata_path = g_build_filename(input, CTF_FS_METADATA_FILENAME, NULL); + if (!metadata_path) { + status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_MEMORY_ERROR; + goto end; + } + + metadata_file = g_fopen(metadata_path, "rb"); + if (metadata_file) { + ctf_metadata_decoder_config metadata_decoder_config {}; + enum ctf_metadata_decoder_status decoder_status; + bt_uuid_t uuid; + + metadata_decoder_config.log_level = log_level; + metadata_decoder_config.self_comp_class = + bt_self_component_class_source_as_self_component_class(comp_class); + + metadata_decoder = ctf_metadata_decoder_create(&metadata_decoder_config); + if (!metadata_decoder) { + status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; + goto end; + } + + decoder_status = ctf_metadata_decoder_append_content(metadata_decoder, metadata_file); + if (decoder_status != CTF_METADATA_DECODER_STATUS_OK) { + BT_LOGW("cannot append metadata content: metadata-decoder-status=%d", decoder_status); + status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; + goto end; + } + + /* + * We were able to parse the metadata file, so we are + * confident it's a CTF trace. + */ + weight = 0.75; + + /* If the trace has a UUID, return the stringified UUID as the group. */ + if (ctf_metadata_decoder_get_trace_class_uuid(metadata_decoder, uuid) == 0) { + bt_uuid_to_str(uuid, uuid_str); + has_uuid = true; + } + } create_result: - result = bt_value_map_create(); - if (!result) { - status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_MEMORY_ERROR; - goto end; - } - - insert_entry_status = bt_value_map_insert_real_entry(result, "weight", weight); - if (insert_entry_status != BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) { - status = (bt_component_class_query_method_status) insert_entry_status; - goto end; - } - - /* We are not supposed to have weight == 0 and a UUID. */ - BT_ASSERT(weight > 0 || !has_uuid); - - if (weight > 0 && has_uuid) { - insert_entry_status = bt_value_map_insert_string_entry(result, "group", uuid_str); - if (insert_entry_status != BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) { - status = (bt_component_class_query_method_status) insert_entry_status; - goto end; - } - } - - *user_result = result; - result = NULL; - status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_OK; + result = bt_value_map_create(); + if (!result) { + status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_MEMORY_ERROR; + goto end; + } + + insert_entry_status = bt_value_map_insert_real_entry(result, "weight", weight); + if (insert_entry_status != BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) { + status = (bt_component_class_query_method_status) insert_entry_status; + goto end; + } + + /* We are not supposed to have weight == 0 and a UUID. */ + BT_ASSERT(weight > 0 || !has_uuid); + + if (weight > 0 && has_uuid) { + insert_entry_status = bt_value_map_insert_string_entry(result, "group", uuid_str); + if (insert_entry_status != BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) { + status = (bt_component_class_query_method_status) insert_entry_status; + goto end; + } + } + + *user_result = result; + result = NULL; + status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_OK; end: - g_free(metadata_path); - bt_value_put_ref(result); - ctf_metadata_decoder_destroy(metadata_decoder); + g_free(metadata_path); + bt_value_put_ref(result); + ctf_metadata_decoder_destroy(metadata_decoder); - return status; + return status; } diff --git a/src/plugins/ctf/fs-src/query.hpp b/src/plugins/ctf/fs-src/query.hpp index bfeebad6..7bdca136 100644 --- a/src/plugins/ctf/fs-src/query.hpp +++ b/src/plugins/ctf/fs-src/query.hpp @@ -13,21 +13,19 @@ #include BT_HIDDEN -bt_component_class_query_method_status metadata_info_query( - bt_self_component_class_source *comp_class, - const bt_value *params, - bt_logging_level log_level, const bt_value **result); +bt_component_class_query_method_status +metadata_info_query(bt_self_component_class_source *comp_class, const bt_value *params, + bt_logging_level log_level, const bt_value **result); BT_HIDDEN -bt_component_class_query_method_status trace_infos_query( - bt_self_component_class_source *comp_class, - const bt_value *params, bt_logging_level log_level, - const bt_value **result); +bt_component_class_query_method_status trace_infos_query(bt_self_component_class_source *comp_class, + const bt_value *params, + bt_logging_level log_level, + const bt_value **result); BT_HIDDEN -bt_component_class_query_method_status support_info_query( - bt_self_component_class_source *comp_class, - const bt_value *params, bt_logging_level log_level, - const bt_value **result); +bt_component_class_query_method_status +support_info_query(bt_self_component_class_source *comp_class, const bt_value *params, + bt_logging_level log_level, const bt_value **result); #endif /* BABELTRACE_PLUGIN_CTF_FS_QUERY_H */ diff --git a/src/plugins/ctf/lttng-live/data-stream.cpp b/src/plugins/ctf/lttng-live/data-stream.cpp index 50071a09..7dd29dfc 100644 --- a/src/plugins/ctf/lttng-live/data-stream.cpp +++ b/src/plugins/ctf/lttng-live/data-stream.cpp @@ -8,8 +8,8 @@ */ #define BT_COMP_LOG_SELF_COMP self_comp -#define BT_LOG_OUTPUT_LEVEL log_level -#define BT_LOG_TAG "PLUGIN/SRC.CTF.LTTNG-LIVE/DS" +#define BT_LOG_OUTPUT_LEVEL log_level +#define BT_LOG_TAG "PLUGIN/SRC.CTF.LTTNG-LIVE/DS" #include "logging/comp-logging.h" #include @@ -25,279 +25,255 @@ #include "compat/mman.h" #include "data-stream.hpp" -#define STREAM_NAME_PREFIX "stream-" +#define STREAM_NAME_PREFIX "stream-" -static -enum ctf_msg_iter_medium_status medop_request_bytes( - size_t request_sz, uint8_t **buffer_addr, - size_t *buffer_sz, void *data) +static enum ctf_msg_iter_medium_status medop_request_bytes(size_t request_sz, uint8_t **buffer_addr, + size_t *buffer_sz, void *data) { - enum ctf_msg_iter_medium_status status = - CTF_MSG_ITER_MEDIUM_STATUS_OK; - lttng_live_stream_iterator *stream = (lttng_live_stream_iterator *) data; - struct lttng_live_trace *trace = stream->trace; - struct lttng_live_session *session = trace->session; - struct lttng_live_msg_iter *live_msg_iter = session->lttng_live_msg_iter; - uint64_t recv_len = 0; - uint64_t len_left; - uint64_t read_len; - - BT_ASSERT(request_sz); - - if (stream->has_stream_hung_up) { - status = CTF_MSG_ITER_MEDIUM_STATUS_EOF; - goto end; - } - - len_left = stream->base_offset + stream->len - stream->offset; - if (!len_left) { - lttng_live_stream_iterator_set_state(stream, - LTTNG_LIVE_STREAM_ACTIVE_NO_DATA); - status = CTF_MSG_ITER_MEDIUM_STATUS_AGAIN; - goto end; - } - - read_len = MIN(request_sz, stream->buflen); - read_len = MIN(read_len, len_left); - status = lttng_live_get_stream_bytes(live_msg_iter, - stream, stream->buf, stream->offset, - read_len, &recv_len); - *buffer_addr = stream->buf; - *buffer_sz = recv_len; - stream->offset += recv_len; + enum ctf_msg_iter_medium_status status = CTF_MSG_ITER_MEDIUM_STATUS_OK; + lttng_live_stream_iterator *stream = (lttng_live_stream_iterator *) data; + struct lttng_live_trace *trace = stream->trace; + struct lttng_live_session *session = trace->session; + struct lttng_live_msg_iter *live_msg_iter = session->lttng_live_msg_iter; + uint64_t recv_len = 0; + uint64_t len_left; + uint64_t read_len; + + BT_ASSERT(request_sz); + + if (stream->has_stream_hung_up) { + status = CTF_MSG_ITER_MEDIUM_STATUS_EOF; + goto end; + } + + len_left = stream->base_offset + stream->len - stream->offset; + if (!len_left) { + lttng_live_stream_iterator_set_state(stream, LTTNG_LIVE_STREAM_ACTIVE_NO_DATA); + status = CTF_MSG_ITER_MEDIUM_STATUS_AGAIN; + goto end; + } + + read_len = MIN(request_sz, stream->buflen); + read_len = MIN(read_len, len_left); + status = lttng_live_get_stream_bytes(live_msg_iter, stream, stream->buf, stream->offset, + read_len, &recv_len); + *buffer_addr = stream->buf; + *buffer_sz = recv_len; + stream->offset += recv_len; end: - return status; + return status; } -static -bt_stream *medop_borrow_stream(bt_stream_class *stream_class, - int64_t stream_id, void *data) +static bt_stream *medop_borrow_stream(bt_stream_class *stream_class, int64_t stream_id, void *data) { - lttng_live_stream_iterator *lttng_live_stream = (lttng_live_stream_iterator *) data; - bt_logging_level log_level = lttng_live_stream->log_level; - bt_self_component *self_comp = lttng_live_stream->self_comp; - - if (!lttng_live_stream->stream) { - uint64_t stream_class_id = bt_stream_class_get_id(stream_class); - - BT_COMP_LOGI("Creating stream %s (ID: %" PRIu64 ") out of stream " - "class %" PRId64, lttng_live_stream->name->str, - stream_id, stream_class_id); - - if (stream_id < 0) { - /* - * No stream instance ID in the stream. It's possible - * to encounter this situation with older version of - * LTTng. In these cases, use the viewer_stream_id that - * is unique for a live viewer session. - */ - lttng_live_stream->stream = bt_stream_create_with_id( - stream_class, lttng_live_stream->trace->trace, - lttng_live_stream->viewer_stream_id); - } else { - lttng_live_stream->stream = bt_stream_create_with_id( - stream_class, lttng_live_stream->trace->trace, - (uint64_t) stream_id); - } - - if (!lttng_live_stream->stream) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Cannot create stream %s (stream class ID " - "%" PRId64 ", stream ID %" PRIu64 ")", - lttng_live_stream->name->str, - stream_class_id, stream_id); - goto end; - } - - bt_stream_set_name(lttng_live_stream->stream, - lttng_live_stream->name->str); - } + lttng_live_stream_iterator *lttng_live_stream = (lttng_live_stream_iterator *) data; + bt_logging_level log_level = lttng_live_stream->log_level; + bt_self_component *self_comp = lttng_live_stream->self_comp; + + if (!lttng_live_stream->stream) { + uint64_t stream_class_id = bt_stream_class_get_id(stream_class); + + BT_COMP_LOGI("Creating stream %s (ID: %" PRIu64 ") out of stream " + "class %" PRId64, + lttng_live_stream->name->str, stream_id, stream_class_id); + + if (stream_id < 0) { + /* + * No stream instance ID in the stream. It's possible + * to encounter this situation with older version of + * LTTng. In these cases, use the viewer_stream_id that + * is unique for a live viewer session. + */ + lttng_live_stream->stream = bt_stream_create_with_id( + stream_class, lttng_live_stream->trace->trace, lttng_live_stream->viewer_stream_id); + } else { + lttng_live_stream->stream = bt_stream_create_with_id( + stream_class, lttng_live_stream->trace->trace, (uint64_t) stream_id); + } + + if (!lttng_live_stream->stream) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, + "Cannot create stream %s (stream class ID " + "%" PRId64 ", stream ID %" PRIu64 ")", + lttng_live_stream->name->str, stream_class_id, stream_id); + goto end; + } + + bt_stream_set_name(lttng_live_stream->stream, lttng_live_stream->name->str); + } end: - return lttng_live_stream->stream; + return lttng_live_stream->stream; } static struct ctf_msg_iter_medium_ops medops = { - medop_request_bytes, - nullptr, - nullptr, - medop_borrow_stream, + medop_request_bytes, + nullptr, + nullptr, + medop_borrow_stream, }; BT_HIDDEN -enum lttng_live_iterator_status lttng_live_lazy_msg_init( - struct lttng_live_session *session, - bt_self_message_iterator *self_msg_iter) +enum lttng_live_iterator_status lttng_live_lazy_msg_init(struct lttng_live_session *session, + bt_self_message_iterator *self_msg_iter) { - struct lttng_live_component *lttng_live = - session->lttng_live_msg_iter->lttng_live_comp; - uint64_t trace_idx, stream_iter_idx; - bt_logging_level log_level = session->log_level; - bt_self_component *self_comp = session->self_comp; - - if (!session->lazy_stream_msg_init) { - return LTTNG_LIVE_ITERATOR_STATUS_OK; - } - - BT_COMP_LOGD("Lazily initializing self message iterator for live session: " - "session-id=%" PRIu64 ", self-msg-iter-addr=%p", session->id, - self_msg_iter); - - for (trace_idx = 0; trace_idx < session->traces->len; trace_idx++) { - struct lttng_live_trace *trace = - (lttng_live_trace *) g_ptr_array_index(session->traces, trace_idx); - - for (stream_iter_idx = 0; - stream_iter_idx < trace->stream_iterators->len; - stream_iter_idx++) { - struct ctf_trace_class *ctf_tc; - struct lttng_live_stream_iterator *stream_iter = - (lttng_live_stream_iterator *) g_ptr_array_index(trace->stream_iterators, - stream_iter_idx); - - if (stream_iter->msg_iter) { - continue; - } - ctf_tc = ctf_metadata_decoder_borrow_ctf_trace_class( - trace->metadata->decoder); - BT_COMP_LOGD("Creating CTF message iterator: " - "session-id=%" PRIu64 ", ctf-tc-addr=%p, " - "stream-iter-name=%s, self-msg-iter-addr=%p", - session->id, ctf_tc, stream_iter->name->str, self_msg_iter); - stream_iter->msg_iter = ctf_msg_iter_create(ctf_tc, - lttng_live->max_query_size, medops, stream_iter, - log_level, self_comp, self_msg_iter); - if (!stream_iter->msg_iter) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Failed to create CTF message iterator"); - goto error; - } - } - } - - session->lazy_stream_msg_init = false; - - return LTTNG_LIVE_ITERATOR_STATUS_OK; + struct lttng_live_component *lttng_live = session->lttng_live_msg_iter->lttng_live_comp; + uint64_t trace_idx, stream_iter_idx; + bt_logging_level log_level = session->log_level; + bt_self_component *self_comp = session->self_comp; + + if (!session->lazy_stream_msg_init) { + return LTTNG_LIVE_ITERATOR_STATUS_OK; + } + + BT_COMP_LOGD("Lazily initializing self message iterator for live session: " + "session-id=%" PRIu64 ", self-msg-iter-addr=%p", + session->id, self_msg_iter); + + for (trace_idx = 0; trace_idx < session->traces->len; trace_idx++) { + struct lttng_live_trace *trace = + (lttng_live_trace *) g_ptr_array_index(session->traces, trace_idx); + + for (stream_iter_idx = 0; stream_iter_idx < trace->stream_iterators->len; + stream_iter_idx++) { + struct ctf_trace_class *ctf_tc; + struct lttng_live_stream_iterator *stream_iter = + (lttng_live_stream_iterator *) g_ptr_array_index(trace->stream_iterators, + stream_iter_idx); + + if (stream_iter->msg_iter) { + continue; + } + ctf_tc = ctf_metadata_decoder_borrow_ctf_trace_class(trace->metadata->decoder); + BT_COMP_LOGD("Creating CTF message iterator: " + "session-id=%" PRIu64 ", ctf-tc-addr=%p, " + "stream-iter-name=%s, self-msg-iter-addr=%p", + session->id, ctf_tc, stream_iter->name->str, self_msg_iter); + stream_iter->msg_iter = + ctf_msg_iter_create(ctf_tc, lttng_live->max_query_size, medops, stream_iter, + log_level, self_comp, self_msg_iter); + if (!stream_iter->msg_iter) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Failed to create CTF message iterator"); + goto error; + } + } + } + + session->lazy_stream_msg_init = false; + + return LTTNG_LIVE_ITERATOR_STATUS_OK; error: - return LTTNG_LIVE_ITERATOR_STATUS_ERROR; + return LTTNG_LIVE_ITERATOR_STATUS_ERROR; } BT_HIDDEN -struct lttng_live_stream_iterator *lttng_live_stream_iterator_create( - struct lttng_live_session *session, - uint64_t ctf_trace_id, - uint64_t stream_id, - bt_self_message_iterator *self_msg_iter) +struct lttng_live_stream_iterator * +lttng_live_stream_iterator_create(struct lttng_live_session *session, uint64_t ctf_trace_id, + uint64_t stream_id, bt_self_message_iterator *self_msg_iter) { - struct lttng_live_stream_iterator *stream_iter; - struct lttng_live_component *lttng_live; - struct lttng_live_trace *trace; - bt_logging_level log_level; - bt_self_component *self_comp; - - BT_ASSERT(session); - BT_ASSERT(session->lttng_live_msg_iter); - BT_ASSERT(session->lttng_live_msg_iter->lttng_live_comp); - log_level = session->log_level; - self_comp = session->self_comp; - - lttng_live = session->lttng_live_msg_iter->lttng_live_comp; - - stream_iter = g_new0(struct lttng_live_stream_iterator, 1); - if (!stream_iter) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Failed to allocate struct lttng_live_stream_iterator"); - goto error; - } - - stream_iter->log_level = log_level; - stream_iter->self_comp = self_comp; - trace = lttng_live_session_borrow_or_create_trace_by_id(session, ctf_trace_id); - if (!trace) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Failed to borrow CTF trace."); - goto error; - } - - stream_iter->trace = trace; - stream_iter->state = LTTNG_LIVE_STREAM_ACTIVE_NO_DATA; - stream_iter->viewer_stream_id = stream_id; - - stream_iter->ctf_stream_class_id.is_set = false; - stream_iter->ctf_stream_class_id.value = UINT64_MAX; - - stream_iter->last_inactivity_ts.is_set = false; - stream_iter->last_inactivity_ts.value = 0; - - if (trace->trace) { - struct ctf_trace_class *ctf_tc = - ctf_metadata_decoder_borrow_ctf_trace_class( - trace->metadata->decoder); - BT_ASSERT(!stream_iter->msg_iter); - stream_iter->msg_iter = ctf_msg_iter_create(ctf_tc, - lttng_live->max_query_size, medops, stream_iter, - log_level, self_comp, self_msg_iter); - if (!stream_iter->msg_iter) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Failed to create CTF message iterator"); - goto error; - } - } - stream_iter->buf = g_new0(uint8_t, lttng_live->max_query_size); - if (!stream_iter->buf) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Failed to allocate live stream iterator buffer"); - goto error; - } - - stream_iter->buflen = lttng_live->max_query_size; - stream_iter->name = g_string_new(NULL); - if (!stream_iter->name) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Failed to allocate live stream iterator name buffer"); - goto error; - } - - g_string_printf(stream_iter->name, STREAM_NAME_PREFIX "%" PRIu64, - stream_iter->viewer_stream_id); - g_ptr_array_add(trace->stream_iterators, stream_iter); - - /* Track the number of active stream iterator. */ - session->lttng_live_msg_iter->active_stream_iter++; - - goto end; + struct lttng_live_stream_iterator *stream_iter; + struct lttng_live_component *lttng_live; + struct lttng_live_trace *trace; + bt_logging_level log_level; + bt_self_component *self_comp; + + BT_ASSERT(session); + BT_ASSERT(session->lttng_live_msg_iter); + BT_ASSERT(session->lttng_live_msg_iter->lttng_live_comp); + log_level = session->log_level; + self_comp = session->self_comp; + + lttng_live = session->lttng_live_msg_iter->lttng_live_comp; + + stream_iter = g_new0(struct lttng_live_stream_iterator, 1); + if (!stream_iter) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, + "Failed to allocate struct lttng_live_stream_iterator"); + goto error; + } + + stream_iter->log_level = log_level; + stream_iter->self_comp = self_comp; + trace = lttng_live_session_borrow_or_create_trace_by_id(session, ctf_trace_id); + if (!trace) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Failed to borrow CTF trace."); + goto error; + } + + stream_iter->trace = trace; + stream_iter->state = LTTNG_LIVE_STREAM_ACTIVE_NO_DATA; + stream_iter->viewer_stream_id = stream_id; + + stream_iter->ctf_stream_class_id.is_set = false; + stream_iter->ctf_stream_class_id.value = UINT64_MAX; + + stream_iter->last_inactivity_ts.is_set = false; + stream_iter->last_inactivity_ts.value = 0; + + if (trace->trace) { + struct ctf_trace_class *ctf_tc = + ctf_metadata_decoder_borrow_ctf_trace_class(trace->metadata->decoder); + BT_ASSERT(!stream_iter->msg_iter); + stream_iter->msg_iter = + ctf_msg_iter_create(ctf_tc, lttng_live->max_query_size, medops, stream_iter, log_level, + self_comp, self_msg_iter); + if (!stream_iter->msg_iter) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Failed to create CTF message iterator"); + goto error; + } + } + stream_iter->buf = g_new0(uint8_t, lttng_live->max_query_size); + if (!stream_iter->buf) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Failed to allocate live stream iterator buffer"); + goto error; + } + + stream_iter->buflen = lttng_live->max_query_size; + stream_iter->name = g_string_new(NULL); + if (!stream_iter->name) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Failed to allocate live stream iterator name buffer"); + goto error; + } + + g_string_printf(stream_iter->name, STREAM_NAME_PREFIX "%" PRIu64, + stream_iter->viewer_stream_id); + g_ptr_array_add(trace->stream_iterators, stream_iter); + + /* Track the number of active stream iterator. */ + session->lttng_live_msg_iter->active_stream_iter++; + + goto end; error: - lttng_live_stream_iterator_destroy(stream_iter); - stream_iter = NULL; + lttng_live_stream_iterator_destroy(stream_iter); + stream_iter = NULL; end: - return stream_iter; + return stream_iter; } BT_HIDDEN -void lttng_live_stream_iterator_destroy( - struct lttng_live_stream_iterator *stream_iter) +void lttng_live_stream_iterator_destroy(struct lttng_live_stream_iterator *stream_iter) { - if (!stream_iter) { - return; - } + if (!stream_iter) { + return; + } - if (stream_iter->stream) { - BT_STREAM_PUT_REF_AND_RESET(stream_iter->stream); - } + if (stream_iter->stream) { + BT_STREAM_PUT_REF_AND_RESET(stream_iter->stream); + } - if (stream_iter->msg_iter) { - ctf_msg_iter_destroy(stream_iter->msg_iter); - } - g_free(stream_iter->buf); - if (stream_iter->name) { - g_string_free(stream_iter->name, TRUE); - } + if (stream_iter->msg_iter) { + ctf_msg_iter_destroy(stream_iter->msg_iter); + } + g_free(stream_iter->buf); + if (stream_iter->name) { + g_string_free(stream_iter->name, TRUE); + } - bt_message_put_ref(stream_iter->current_msg); + bt_message_put_ref(stream_iter->current_msg); - /* Track the number of active stream iterator. */ - stream_iter->trace->session->lttng_live_msg_iter->active_stream_iter--; + /* Track the number of active stream iterator. */ + stream_iter->trace->session->lttng_live_msg_iter->active_stream_iter--; - g_free(stream_iter); + g_free(stream_iter); } diff --git a/src/plugins/ctf/lttng-live/data-stream.hpp b/src/plugins/ctf/lttng-live/data-stream.hpp index 5c9e9a69..c16eae87 100644 --- a/src/plugins/ctf/lttng-live/data-stream.hpp +++ b/src/plugins/ctf/lttng-live/data-stream.hpp @@ -15,17 +15,13 @@ #include "../common/msg-iter/msg-iter.hpp" #include "lttng-live.hpp" -enum lttng_live_iterator_status lttng_live_lazy_msg_init( - struct lttng_live_session *session, - bt_self_message_iterator *self_msg_iter); - -struct lttng_live_stream_iterator *lttng_live_stream_iterator_create( - struct lttng_live_session *session, - uint64_t ctf_trace_id, - uint64_t stream_id, - bt_self_message_iterator *self_msg_iter); - -void lttng_live_stream_iterator_destroy( - struct lttng_live_stream_iterator *stream); +enum lttng_live_iterator_status lttng_live_lazy_msg_init(struct lttng_live_session *session, + bt_self_message_iterator *self_msg_iter); + +struct lttng_live_stream_iterator * +lttng_live_stream_iterator_create(struct lttng_live_session *session, uint64_t ctf_trace_id, + uint64_t stream_id, bt_self_message_iterator *self_msg_iter); + +void lttng_live_stream_iterator_destroy(struct lttng_live_stream_iterator *stream); #endif /* LTTNG_LIVE_DATA_STREAM_H */ diff --git a/src/plugins/ctf/lttng-live/lttng-live.cpp b/src/plugins/ctf/lttng-live/lttng-live.cpp index 79875326..3a882b88 100644 --- a/src/plugins/ctf/lttng-live/lttng-live.cpp +++ b/src/plugins/ctf/lttng-live/lttng-live.cpp @@ -9,8 +9,8 @@ */ #define BT_COMP_LOG_SELF_COMP self_comp -#define BT_LOG_OUTPUT_LEVEL log_level -#define BT_LOG_TAG "PLUGIN/SRC.CTF.LTTNG-LIVE" +#define BT_LOG_OUTPUT_LEVEL log_level +#define BT_LOG_TAG "PLUGIN/SRC.CTF.LTTNG-LIVE" #include "logging/comp-logging.h" #include @@ -31,347 +31,331 @@ #include "metadata.hpp" #include "lttng-live.hpp" -#define MAX_QUERY_SIZE (256*1024) -#define URL_PARAM "url" -#define INPUTS_PARAM "inputs" -#define SESS_NOT_FOUND_ACTION_PARAM "session-not-found-action" -#define SESS_NOT_FOUND_ACTION_CONTINUE_STR "continue" -#define SESS_NOT_FOUND_ACTION_FAIL_STR "fail" -#define SESS_NOT_FOUND_ACTION_END_STR "end" +#define MAX_QUERY_SIZE (256 * 1024) +#define URL_PARAM "url" +#define INPUTS_PARAM "inputs" +#define SESS_NOT_FOUND_ACTION_PARAM "session-not-found-action" +#define SESS_NOT_FOUND_ACTION_CONTINUE_STR "continue" +#define SESS_NOT_FOUND_ACTION_FAIL_STR "fail" +#define SESS_NOT_FOUND_ACTION_END_STR "end" -#define print_dbg(fmt, ...) BT_COMP_LOGD(fmt, ## __VA_ARGS__) +#define print_dbg(fmt, ...) BT_COMP_LOGD(fmt, ##__VA_ARGS__) -static -const char *lttng_live_iterator_status_string( - enum lttng_live_iterator_status status) +static const char *lttng_live_iterator_status_string(enum lttng_live_iterator_status status) { - switch (status) { - case LTTNG_LIVE_ITERATOR_STATUS_CONTINUE: - return "LTTNG_LIVE_ITERATOR_STATUS_CONTINUE"; - case LTTNG_LIVE_ITERATOR_STATUS_AGAIN: - return "LTTNG_LIVE_ITERATOR_STATUS_AGAIN"; - case LTTNG_LIVE_ITERATOR_STATUS_END: - return "LTTNG_LIVE_ITERATOR_STATUS_END"; - case LTTNG_LIVE_ITERATOR_STATUS_OK: - return "LTTNG_LIVE_ITERATOR_STATUS_OK"; - case LTTNG_LIVE_ITERATOR_STATUS_INVAL: - return "LTTNG_LIVE_ITERATOR_STATUS_INVAL"; - case LTTNG_LIVE_ITERATOR_STATUS_ERROR: - return "LTTNG_LIVE_ITERATOR_STATUS_ERROR"; - case LTTNG_LIVE_ITERATOR_STATUS_NOMEM: - return "LTTNG_LIVE_ITERATOR_STATUS_NOMEM"; - case LTTNG_LIVE_ITERATOR_STATUS_UNSUPPORTED: - return "LTTNG_LIVE_ITERATOR_STATUS_UNSUPPORTED"; - default: - bt_common_abort(); - } + switch (status) { + case LTTNG_LIVE_ITERATOR_STATUS_CONTINUE: + return "LTTNG_LIVE_ITERATOR_STATUS_CONTINUE"; + case LTTNG_LIVE_ITERATOR_STATUS_AGAIN: + return "LTTNG_LIVE_ITERATOR_STATUS_AGAIN"; + case LTTNG_LIVE_ITERATOR_STATUS_END: + return "LTTNG_LIVE_ITERATOR_STATUS_END"; + case LTTNG_LIVE_ITERATOR_STATUS_OK: + return "LTTNG_LIVE_ITERATOR_STATUS_OK"; + case LTTNG_LIVE_ITERATOR_STATUS_INVAL: + return "LTTNG_LIVE_ITERATOR_STATUS_INVAL"; + case LTTNG_LIVE_ITERATOR_STATUS_ERROR: + return "LTTNG_LIVE_ITERATOR_STATUS_ERROR"; + case LTTNG_LIVE_ITERATOR_STATUS_NOMEM: + return "LTTNG_LIVE_ITERATOR_STATUS_NOMEM"; + case LTTNG_LIVE_ITERATOR_STATUS_UNSUPPORTED: + return "LTTNG_LIVE_ITERATOR_STATUS_UNSUPPORTED"; + default: + bt_common_abort(); + } } -static -const char *lttng_live_stream_state_string(enum lttng_live_stream_state state) +static const char *lttng_live_stream_state_string(enum lttng_live_stream_state state) { - switch (state) { - case LTTNG_LIVE_STREAM_ACTIVE_NO_DATA: - return "ACTIVE_NO_DATA"; - case LTTNG_LIVE_STREAM_QUIESCENT_NO_DATA: - return "QUIESCENT_NO_DATA"; - case LTTNG_LIVE_STREAM_QUIESCENT: - return "QUIESCENT"; - case LTTNG_LIVE_STREAM_ACTIVE_DATA: - return "ACTIVE_DATA"; - case LTTNG_LIVE_STREAM_EOF: - return "EOF"; - default: - return "ERROR"; - } + switch (state) { + case LTTNG_LIVE_STREAM_ACTIVE_NO_DATA: + return "ACTIVE_NO_DATA"; + case LTTNG_LIVE_STREAM_QUIESCENT_NO_DATA: + return "QUIESCENT_NO_DATA"; + case LTTNG_LIVE_STREAM_QUIESCENT: + return "QUIESCENT"; + case LTTNG_LIVE_STREAM_ACTIVE_DATA: + return "ACTIVE_DATA"; + case LTTNG_LIVE_STREAM_EOF: + return "EOF"; + default: + return "ERROR"; + } } void lttng_live_stream_iterator_set_state(struct lttng_live_stream_iterator *stream_iter, - enum lttng_live_stream_state new_state) + enum lttng_live_stream_state new_state) { - bt_self_component *self_comp = stream_iter->self_comp; - bt_logging_level log_level = stream_iter->log_level; + bt_self_component *self_comp = stream_iter->self_comp; + bt_logging_level log_level = stream_iter->log_level; - BT_COMP_LOGD("Setting live stream iterator state: viewer-stream-id=%" PRIu64 - ", old-state=%s, new-state=%s", - stream_iter->viewer_stream_id, - lttng_live_stream_state_string(stream_iter->state), - lttng_live_stream_state_string(new_state)); + BT_COMP_LOGD("Setting live stream iterator state: viewer-stream-id=%" PRIu64 + ", old-state=%s, new-state=%s", + stream_iter->viewer_stream_id, lttng_live_stream_state_string(stream_iter->state), + lttng_live_stream_state_string(new_state)); - stream_iter->state = new_state; + stream_iter->state = new_state; } -#define LTTNG_LIVE_LOGD_STREAM_ITER(live_stream_iter) \ - do { \ - BT_COMP_LOGD("Live stream iterator state=%s, " \ - "last-inact-ts-is-set=%d, last-inact-ts-value=%" PRId64 ", " \ - "curr-inact-ts=%" PRId64, \ - lttng_live_stream_state_string(live_stream_iter->state), \ - live_stream_iter->last_inactivity_ts.is_set, \ - live_stream_iter->last_inactivity_ts.value, \ - live_stream_iter->current_inactivity_ts); \ - } while (0); +#define LTTNG_LIVE_LOGD_STREAM_ITER(live_stream_iter) \ + do { \ + BT_COMP_LOGD("Live stream iterator state=%s, " \ + "last-inact-ts-is-set=%d, last-inact-ts-value=%" PRId64 ", " \ + "curr-inact-ts=%" PRId64, \ + lttng_live_stream_state_string(live_stream_iter->state), \ + live_stream_iter->last_inactivity_ts.is_set, \ + live_stream_iter->last_inactivity_ts.value, \ + live_stream_iter->current_inactivity_ts); \ + } while (0); BT_HIDDEN bool lttng_live_graph_is_canceled(struct lttng_live_msg_iter *msg_iter) { - bool ret; + bool ret; - if (!msg_iter) { - ret = false; - goto end; - } + if (!msg_iter) { + ret = false; + goto end; + } - ret = bt_self_message_iterator_is_interrupted( - msg_iter->self_msg_iter); + ret = bt_self_message_iterator_is_interrupted(msg_iter->self_msg_iter); end: - return ret; + return ret; } -static -struct lttng_live_trace *lttng_live_session_borrow_trace_by_id(struct lttng_live_session *session, - uint64_t trace_id) +static struct lttng_live_trace * +lttng_live_session_borrow_trace_by_id(struct lttng_live_session *session, uint64_t trace_id) { - uint64_t trace_idx; - struct lttng_live_trace *ret_trace = NULL; - - for (trace_idx = 0; trace_idx < session->traces->len; trace_idx++) { - struct lttng_live_trace *trace = - (lttng_live_trace *) g_ptr_array_index(session->traces, trace_idx); - if (trace->id == trace_id) { - ret_trace = trace; - goto end; - } - } + uint64_t trace_idx; + struct lttng_live_trace *ret_trace = NULL; + + for (trace_idx = 0; trace_idx < session->traces->len; trace_idx++) { + struct lttng_live_trace *trace = + (lttng_live_trace *) g_ptr_array_index(session->traces, trace_idx); + if (trace->id == trace_id) { + ret_trace = trace; + goto end; + } + } end: - return ret_trace; + return ret_trace; } -static -void lttng_live_destroy_trace(struct lttng_live_trace *trace) +static void lttng_live_destroy_trace(struct lttng_live_trace *trace) { - bt_logging_level log_level = trace->log_level; - bt_self_component *self_comp = trace->self_comp; + bt_logging_level log_level = trace->log_level; + bt_self_component *self_comp = trace->self_comp; - BT_COMP_LOGD("Destroying live trace: trace-id=%" PRIu64, trace->id); + BT_COMP_LOGD("Destroying live trace: trace-id=%" PRIu64, trace->id); - BT_ASSERT(trace->stream_iterators); - g_ptr_array_free(trace->stream_iterators, TRUE); + BT_ASSERT(trace->stream_iterators); + g_ptr_array_free(trace->stream_iterators, TRUE); - BT_TRACE_PUT_REF_AND_RESET(trace->trace); - BT_TRACE_CLASS_PUT_REF_AND_RESET(trace->trace_class); + BT_TRACE_PUT_REF_AND_RESET(trace->trace); + BT_TRACE_CLASS_PUT_REF_AND_RESET(trace->trace_class); - lttng_live_metadata_fini(trace); - g_free(trace); + lttng_live_metadata_fini(trace); + g_free(trace); } -static -struct lttng_live_trace *lttng_live_create_trace(struct lttng_live_session *session, - uint64_t trace_id) +static struct lttng_live_trace *lttng_live_create_trace(struct lttng_live_session *session, + uint64_t trace_id) { - struct lttng_live_trace *trace = NULL; - bt_logging_level log_level = session->log_level; - bt_self_component *self_comp = session->self_comp; - - BT_COMP_LOGD("Creating live trace: " - "session-id=%" PRIu64 ", trace-id=%" PRIu64, - session->id, trace_id); - trace = g_new0(struct lttng_live_trace, 1); - if (!trace) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Failed to allocate live trace"); - goto error; - } - trace->log_level = session->log_level; - trace->self_comp = session->self_comp; - trace->session = session; - trace->id = trace_id; - trace->trace_class = NULL; - trace->trace = NULL; - trace->stream_iterators = g_ptr_array_new_with_free_func( - (GDestroyNotify) lttng_live_stream_iterator_destroy); - BT_ASSERT(trace->stream_iterators); - trace->metadata_stream_state = LTTNG_LIVE_METADATA_STREAM_STATE_NEEDED; - g_ptr_array_add(session->traces, trace); - - goto end; + struct lttng_live_trace *trace = NULL; + bt_logging_level log_level = session->log_level; + bt_self_component *self_comp = session->self_comp; + + BT_COMP_LOGD("Creating live trace: " + "session-id=%" PRIu64 ", trace-id=%" PRIu64, + session->id, trace_id); + trace = g_new0(struct lttng_live_trace, 1); + if (!trace) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Failed to allocate live trace"); + goto error; + } + trace->log_level = session->log_level; + trace->self_comp = session->self_comp; + trace->session = session; + trace->id = trace_id; + trace->trace_class = NULL; + trace->trace = NULL; + trace->stream_iterators = + g_ptr_array_new_with_free_func((GDestroyNotify) lttng_live_stream_iterator_destroy); + BT_ASSERT(trace->stream_iterators); + trace->metadata_stream_state = LTTNG_LIVE_METADATA_STREAM_STATE_NEEDED; + g_ptr_array_add(session->traces, trace); + + goto end; error: - g_free(trace); - trace = NULL; + g_free(trace); + trace = NULL; end: - return trace; + return trace; } BT_HIDDEN -struct lttng_live_trace *lttng_live_session_borrow_or_create_trace_by_id( - struct lttng_live_session *session, uint64_t trace_id) +struct lttng_live_trace * +lttng_live_session_borrow_or_create_trace_by_id(struct lttng_live_session *session, + uint64_t trace_id) { - struct lttng_live_trace *trace; + struct lttng_live_trace *trace; - trace = lttng_live_session_borrow_trace_by_id(session, trace_id); - if (trace) { - goto end; - } + trace = lttng_live_session_borrow_trace_by_id(session, trace_id); + if (trace) { + goto end; + } - /* The session is the owner of the newly created trace. */ - trace = lttng_live_create_trace(session, trace_id); + /* The session is the owner of the newly created trace. */ + trace = lttng_live_create_trace(session, trace_id); end: - return trace; + return trace; } BT_HIDDEN -int lttng_live_add_session(struct lttng_live_msg_iter *lttng_live_msg_iter, - uint64_t session_id, const char *hostname, - const char *session_name) +int lttng_live_add_session(struct lttng_live_msg_iter *lttng_live_msg_iter, uint64_t session_id, + const char *hostname, const char *session_name) { - int ret = 0; - struct lttng_live_session *session; - bt_logging_level log_level = lttng_live_msg_iter->log_level; - bt_self_component *self_comp = lttng_live_msg_iter->self_comp; - - BT_COMP_LOGD("Adding live session: " - "session-id=%" PRIu64 ", hostname=\"%s\" session-name=\"%s\"", - session_id, hostname, session_name); - - session = g_new0(struct lttng_live_session, 1); - if (!session) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Failed to allocate live session"); - goto error; - } - - session->log_level = lttng_live_msg_iter->log_level; - session->self_comp = lttng_live_msg_iter->self_comp; - session->id = session_id; - session->traces = g_ptr_array_new_with_free_func( - (GDestroyNotify) lttng_live_destroy_trace); - BT_ASSERT(session->traces); - session->lttng_live_msg_iter = lttng_live_msg_iter; - session->new_streams_needed = true; - session->hostname = g_string_new(hostname); - BT_ASSERT(session->hostname); - - session->session_name = g_string_new(session_name); - BT_ASSERT(session->session_name); - - g_ptr_array_add(lttng_live_msg_iter->sessions, session); - goto end; + int ret = 0; + struct lttng_live_session *session; + bt_logging_level log_level = lttng_live_msg_iter->log_level; + bt_self_component *self_comp = lttng_live_msg_iter->self_comp; + + BT_COMP_LOGD("Adding live session: " + "session-id=%" PRIu64 ", hostname=\"%s\" session-name=\"%s\"", + session_id, hostname, session_name); + + session = g_new0(struct lttng_live_session, 1); + if (!session) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Failed to allocate live session"); + goto error; + } + + session->log_level = lttng_live_msg_iter->log_level; + session->self_comp = lttng_live_msg_iter->self_comp; + session->id = session_id; + session->traces = g_ptr_array_new_with_free_func((GDestroyNotify) lttng_live_destroy_trace); + BT_ASSERT(session->traces); + session->lttng_live_msg_iter = lttng_live_msg_iter; + session->new_streams_needed = true; + session->hostname = g_string_new(hostname); + BT_ASSERT(session->hostname); + + session->session_name = g_string_new(session_name); + BT_ASSERT(session->session_name); + + g_ptr_array_add(lttng_live_msg_iter->sessions, session); + goto end; error: - g_free(session); - ret = -1; + g_free(session); + ret = -1; end: - return ret; + return ret; } -static -void lttng_live_destroy_session(struct lttng_live_session *session) +static void lttng_live_destroy_session(struct lttng_live_session *session) { - bt_logging_level log_level; - bt_self_component *self_comp; - - if (!session) { - goto end; - } - - log_level = session->log_level; - self_comp = session->self_comp; - BT_COMP_LOGD("Destroying live session: " - "session-id=%" PRIu64 ", session-name=\"%s\"", - session->id, session->session_name->str); - if (session->id != -1ULL) { - if (lttng_live_session_detach(session)) { - if (!lttng_live_graph_is_canceled( - session->lttng_live_msg_iter)) { - /* Old relayd cannot detach sessions. */ - BT_COMP_LOGD("Unable to detach lttng live session %" PRIu64, - session->id); - } - } - session->id = -1ULL; - } - - if (session->traces) { - g_ptr_array_free(session->traces, TRUE); - } - - if (session->hostname) { - g_string_free(session->hostname, TRUE); - } - if (session->session_name) { - g_string_free(session->session_name, TRUE); - } - g_free(session); + bt_logging_level log_level; + bt_self_component *self_comp; + + if (!session) { + goto end; + } + + log_level = session->log_level; + self_comp = session->self_comp; + BT_COMP_LOGD("Destroying live session: " + "session-id=%" PRIu64 ", session-name=\"%s\"", + session->id, session->session_name->str); + if (session->id != -1ULL) { + if (lttng_live_session_detach(session)) { + if (!lttng_live_graph_is_canceled(session->lttng_live_msg_iter)) { + /* Old relayd cannot detach sessions. */ + BT_COMP_LOGD("Unable to detach lttng live session %" PRIu64, session->id); + } + } + session->id = -1ULL; + } + + if (session->traces) { + g_ptr_array_free(session->traces, TRUE); + } + + if (session->hostname) { + g_string_free(session->hostname, TRUE); + } + if (session->session_name) { + g_string_free(session->session_name, TRUE); + } + g_free(session); end: - return; + return; } -static -void lttng_live_msg_iter_destroy(struct lttng_live_msg_iter *lttng_live_msg_iter) +static void lttng_live_msg_iter_destroy(struct lttng_live_msg_iter *lttng_live_msg_iter) { - if (!lttng_live_msg_iter) { - goto end; - } + if (!lttng_live_msg_iter) { + goto end; + } - if (lttng_live_msg_iter->sessions) { - g_ptr_array_free(lttng_live_msg_iter->sessions, TRUE); - } + if (lttng_live_msg_iter->sessions) { + g_ptr_array_free(lttng_live_msg_iter->sessions, TRUE); + } - if (lttng_live_msg_iter->viewer_connection) { - live_viewer_connection_destroy(lttng_live_msg_iter->viewer_connection); - } - BT_ASSERT(lttng_live_msg_iter->lttng_live_comp); - BT_ASSERT(lttng_live_msg_iter->lttng_live_comp->has_msg_iter); + if (lttng_live_msg_iter->viewer_connection) { + live_viewer_connection_destroy(lttng_live_msg_iter->viewer_connection); + } + BT_ASSERT(lttng_live_msg_iter->lttng_live_comp); + BT_ASSERT(lttng_live_msg_iter->lttng_live_comp->has_msg_iter); - /* All stream iterators must be destroyed at this point. */ - BT_ASSERT(lttng_live_msg_iter->active_stream_iter == 0); - lttng_live_msg_iter->lttng_live_comp->has_msg_iter = false; + /* All stream iterators must be destroyed at this point. */ + BT_ASSERT(lttng_live_msg_iter->active_stream_iter == 0); + lttng_live_msg_iter->lttng_live_comp->has_msg_iter = false; - g_free(lttng_live_msg_iter); + g_free(lttng_live_msg_iter); end: - return; + return; } BT_HIDDEN void lttng_live_msg_iter_finalize(bt_self_message_iterator *self_msg_iter) { - struct lttng_live_msg_iter *lttng_live_msg_iter; + struct lttng_live_msg_iter *lttng_live_msg_iter; - BT_ASSERT(self_msg_iter); + BT_ASSERT(self_msg_iter); - lttng_live_msg_iter = (struct lttng_live_msg_iter *) - bt_self_message_iterator_get_data(self_msg_iter); - BT_ASSERT(lttng_live_msg_iter); - lttng_live_msg_iter_destroy(lttng_live_msg_iter); + lttng_live_msg_iter = + (struct lttng_live_msg_iter *) bt_self_message_iterator_get_data(self_msg_iter); + BT_ASSERT(lttng_live_msg_iter); + lttng_live_msg_iter_destroy(lttng_live_msg_iter); } -static -enum lttng_live_iterator_status lttng_live_iterator_next_check_stream_state( - struct lttng_live_stream_iterator *lttng_live_stream) +static enum lttng_live_iterator_status +lttng_live_iterator_next_check_stream_state(struct lttng_live_stream_iterator *lttng_live_stream) { - bt_logging_level log_level = lttng_live_stream->log_level; - bt_self_component *self_comp = lttng_live_stream->self_comp; - - switch (lttng_live_stream->state) { - case LTTNG_LIVE_STREAM_QUIESCENT: - case LTTNG_LIVE_STREAM_ACTIVE_DATA: - break; - case LTTNG_LIVE_STREAM_ACTIVE_NO_DATA: - /* Invalid state. */ - BT_COMP_LOGF("Unexpected stream state \"ACTIVE_NO_DATA\""); - bt_common_abort(); - case LTTNG_LIVE_STREAM_QUIESCENT_NO_DATA: - /* Invalid state. */ - BT_COMP_LOGF("Unexpected stream state \"QUIESCENT_NO_DATA\""); - bt_common_abort(); - case LTTNG_LIVE_STREAM_EOF: - break; - } - return LTTNG_LIVE_ITERATOR_STATUS_OK; + bt_logging_level log_level = lttng_live_stream->log_level; + bt_self_component *self_comp = lttng_live_stream->self_comp; + + switch (lttng_live_stream->state) { + case LTTNG_LIVE_STREAM_QUIESCENT: + case LTTNG_LIVE_STREAM_ACTIVE_DATA: + break; + case LTTNG_LIVE_STREAM_ACTIVE_NO_DATA: + /* Invalid state. */ + BT_COMP_LOGF("Unexpected stream state \"ACTIVE_NO_DATA\""); + bt_common_abort(); + case LTTNG_LIVE_STREAM_QUIESCENT_NO_DATA: + /* Invalid state. */ + BT_COMP_LOGF("Unexpected stream state \"QUIESCENT_NO_DATA\""); + bt_common_abort(); + case LTTNG_LIVE_STREAM_EOF: + break; + } + return LTTNG_LIVE_ITERATOR_STATUS_OK; } /* @@ -382,82 +366,81 @@ enum lttng_live_iterator_status lttng_live_iterator_next_check_stream_state( * - have no data on this stream at this point: need to retry (AGAIN) or return * EOF. */ -static -enum lttng_live_iterator_status lttng_live_iterator_next_handle_one_no_data_stream( - struct lttng_live_msg_iter *lttng_live_msg_iter, - struct lttng_live_stream_iterator *lttng_live_stream) +static enum lttng_live_iterator_status lttng_live_iterator_next_handle_one_no_data_stream( + struct lttng_live_msg_iter *lttng_live_msg_iter, + struct lttng_live_stream_iterator *lttng_live_stream) { - bt_logging_level log_level = lttng_live_msg_iter->log_level; - bt_self_component *self_comp = lttng_live_msg_iter->self_comp; - enum lttng_live_iterator_status ret = LTTNG_LIVE_ITERATOR_STATUS_OK; - enum lttng_live_stream_state orig_state = lttng_live_stream->state; - struct packet_index index; - - if (lttng_live_stream->trace->metadata_stream_state == - LTTNG_LIVE_METADATA_STREAM_STATE_NEEDED) { - BT_COMP_LOGD("Need to get an update for the metadata stream before proceeding further with this stream: " - "stream-name=\"%s\"", lttng_live_stream->name->str); - ret = LTTNG_LIVE_ITERATOR_STATUS_CONTINUE; - goto end; - } - - if (lttng_live_stream->trace->session->new_streams_needed) { - BT_COMP_LOGD("Need to get an update of all streams before proceeding further with this stream: " - "stream-name=\"%s\"", lttng_live_stream->name->str); - ret = LTTNG_LIVE_ITERATOR_STATUS_CONTINUE; - goto end; - } - - if (lttng_live_stream->state != LTTNG_LIVE_STREAM_ACTIVE_NO_DATA && - lttng_live_stream->state != LTTNG_LIVE_STREAM_QUIESCENT_NO_DATA) { - goto end; - } - ret = lttng_live_get_next_index(lttng_live_msg_iter, lttng_live_stream, - &index); - if (ret != LTTNG_LIVE_ITERATOR_STATUS_OK) { - goto end; - } - - BT_ASSERT_DBG(lttng_live_stream->state != LTTNG_LIVE_STREAM_EOF); - - if (lttng_live_stream->state == LTTNG_LIVE_STREAM_QUIESCENT) { - uint64_t last_inact_ts = lttng_live_stream->last_inactivity_ts.value, - curr_inact_ts = lttng_live_stream->current_inactivity_ts; - - if (orig_state == LTTNG_LIVE_STREAM_QUIESCENT_NO_DATA && - last_inact_ts == curr_inact_ts) { - /* + bt_logging_level log_level = lttng_live_msg_iter->log_level; + bt_self_component *self_comp = lttng_live_msg_iter->self_comp; + enum lttng_live_iterator_status ret = LTTNG_LIVE_ITERATOR_STATUS_OK; + enum lttng_live_stream_state orig_state = lttng_live_stream->state; + struct packet_index index; + + if (lttng_live_stream->trace->metadata_stream_state == + LTTNG_LIVE_METADATA_STREAM_STATE_NEEDED) { + BT_COMP_LOGD( + "Need to get an update for the metadata stream before proceeding further with this stream: " + "stream-name=\"%s\"", + lttng_live_stream->name->str); + ret = LTTNG_LIVE_ITERATOR_STATUS_CONTINUE; + goto end; + } + + if (lttng_live_stream->trace->session->new_streams_needed) { + BT_COMP_LOGD( + "Need to get an update of all streams before proceeding further with this stream: " + "stream-name=\"%s\"", + lttng_live_stream->name->str); + ret = LTTNG_LIVE_ITERATOR_STATUS_CONTINUE; + goto end; + } + + if (lttng_live_stream->state != LTTNG_LIVE_STREAM_ACTIVE_NO_DATA && + lttng_live_stream->state != LTTNG_LIVE_STREAM_QUIESCENT_NO_DATA) { + goto end; + } + ret = lttng_live_get_next_index(lttng_live_msg_iter, lttng_live_stream, &index); + if (ret != LTTNG_LIVE_ITERATOR_STATUS_OK) { + goto end; + } + + BT_ASSERT_DBG(lttng_live_stream->state != LTTNG_LIVE_STREAM_EOF); + + if (lttng_live_stream->state == LTTNG_LIVE_STREAM_QUIESCENT) { + uint64_t last_inact_ts = lttng_live_stream->last_inactivity_ts.value, + curr_inact_ts = lttng_live_stream->current_inactivity_ts; + + if (orig_state == LTTNG_LIVE_STREAM_QUIESCENT_NO_DATA && last_inact_ts == curr_inact_ts) { + /* * Because the stream is in the QUIESCENT_NO_DATA * state, we can assert that the last_inactivity_ts was * set and can be safely used in the `if` above. */ - BT_ASSERT(lttng_live_stream->last_inactivity_ts.is_set); - - ret = LTTNG_LIVE_ITERATOR_STATUS_AGAIN; - LTTNG_LIVE_LOGD_STREAM_ITER(lttng_live_stream); - } else { - ret = LTTNG_LIVE_ITERATOR_STATUS_CONTINUE; - } - goto end; - } - - lttng_live_stream->base_offset = index.offset; - lttng_live_stream->offset = index.offset; - lttng_live_stream->len = index.packet_size / CHAR_BIT; - - BT_COMP_LOGD("Setting live stream reading info: stream-name=\"%s\", " - "viewer-stream-id=%" PRIu64 ", stream-base-offset=%" PRIu64 - ", stream-offset=%" PRIu64 ", stream-len=%" PRIu64, - lttng_live_stream->name->str, - lttng_live_stream->viewer_stream_id, - lttng_live_stream->base_offset, - lttng_live_stream->offset, lttng_live_stream->len); + BT_ASSERT(lttng_live_stream->last_inactivity_ts.is_set); + + ret = LTTNG_LIVE_ITERATOR_STATUS_AGAIN; + LTTNG_LIVE_LOGD_STREAM_ITER(lttng_live_stream); + } else { + ret = LTTNG_LIVE_ITERATOR_STATUS_CONTINUE; + } + goto end; + } + + lttng_live_stream->base_offset = index.offset; + lttng_live_stream->offset = index.offset; + lttng_live_stream->len = index.packet_size / CHAR_BIT; + + BT_COMP_LOGD("Setting live stream reading info: stream-name=\"%s\", " + "viewer-stream-id=%" PRIu64 ", stream-base-offset=%" PRIu64 + ", stream-offset=%" PRIu64 ", stream-len=%" PRIu64, + lttng_live_stream->name->str, lttng_live_stream->viewer_stream_id, + lttng_live_stream->base_offset, lttng_live_stream->offset, lttng_live_stream->len); end: - if (ret == LTTNG_LIVE_ITERATOR_STATUS_OK) { - ret = lttng_live_iterator_next_check_stream_state(lttng_live_stream); - } - return ret; + if (ret == LTTNG_LIVE_ITERATOR_STATUS_OK) { + ret = lttng_live_iterator_next_check_stream_state(lttng_live_stream); + } + return ret; } /* @@ -467,483 +450,450 @@ end: * (which creates the ctf trace class), and then creating the per-stream * messages. */ -static -enum lttng_live_iterator_status lttng_live_get_session( - struct lttng_live_msg_iter *lttng_live_msg_iter, - struct lttng_live_session *session) +static enum lttng_live_iterator_status +lttng_live_get_session(struct lttng_live_msg_iter *lttng_live_msg_iter, + struct lttng_live_session *session) { - bt_logging_level log_level = lttng_live_msg_iter->log_level; - bt_self_component *self_comp = lttng_live_msg_iter->self_comp; - enum lttng_live_iterator_status status; - uint64_t trace_idx; - - if (!session->attached) { - BT_COMP_LOGD("Attach to session: session-id=%" PRIu64, - session->id); - enum lttng_live_viewer_status attach_status = - lttng_live_session_attach(session, - lttng_live_msg_iter->self_msg_iter); - if (attach_status != LTTNG_LIVE_VIEWER_STATUS_OK) { - if (lttng_live_graph_is_canceled(lttng_live_msg_iter)) { - /* - * Clear any causes appended in - * `lttng_live_attach_session()` as we want to - * return gracefully since the graph was - * cancelled. - */ - bt_current_thread_clear_error(); - status = LTTNG_LIVE_ITERATOR_STATUS_AGAIN; - } else { - status = LTTNG_LIVE_ITERATOR_STATUS_ERROR; - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Error attaching to LTTng live session"); - } - goto end; - } - } - - BT_COMP_LOGD("Updating all streams and metadata for session: " - "session-id=%" PRIu64 ", session-name=\"%s\"", - session->id, session->session_name->str); - - status = lttng_live_session_get_new_streams(session, - lttng_live_msg_iter->self_msg_iter); - if (status != LTTNG_LIVE_ITERATOR_STATUS_OK && - status != LTTNG_LIVE_ITERATOR_STATUS_END) { - goto end; - } - - trace_idx = 0; - while (trace_idx < session->traces->len) { - struct lttng_live_trace *trace = - (lttng_live_trace *) g_ptr_array_index(session->traces, trace_idx); - - status = lttng_live_metadata_update(trace); - switch (status) { - case LTTNG_LIVE_ITERATOR_STATUS_END: - case LTTNG_LIVE_ITERATOR_STATUS_OK: - trace_idx++; - break; - case LTTNG_LIVE_ITERATOR_STATUS_CONTINUE: - case LTTNG_LIVE_ITERATOR_STATUS_AGAIN: - goto end; - default: - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Error updating trace metadata: " - "stream-iter-status=%s, trace-id=%" PRIu64, - lttng_live_iterator_status_string(status), - trace->id); - goto end; - } - } - - /* - * Now that we have the metadata we can initialize the downstream - * iterator. - */ - status = lttng_live_lazy_msg_init(session, - lttng_live_msg_iter->self_msg_iter); + bt_logging_level log_level = lttng_live_msg_iter->log_level; + bt_self_component *self_comp = lttng_live_msg_iter->self_comp; + enum lttng_live_iterator_status status; + uint64_t trace_idx; + + if (!session->attached) { + BT_COMP_LOGD("Attach to session: session-id=%" PRIu64, session->id); + enum lttng_live_viewer_status attach_status = + lttng_live_session_attach(session, lttng_live_msg_iter->self_msg_iter); + if (attach_status != LTTNG_LIVE_VIEWER_STATUS_OK) { + if (lttng_live_graph_is_canceled(lttng_live_msg_iter)) { + /* + * Clear any causes appended in + * `lttng_live_attach_session()` as we want to + * return gracefully since the graph was + * cancelled. + */ + bt_current_thread_clear_error(); + status = LTTNG_LIVE_ITERATOR_STATUS_AGAIN; + } else { + status = LTTNG_LIVE_ITERATOR_STATUS_ERROR; + BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Error attaching to LTTng live session"); + } + goto end; + } + } + + BT_COMP_LOGD("Updating all streams and metadata for session: " + "session-id=%" PRIu64 ", session-name=\"%s\"", + session->id, session->session_name->str); + + status = lttng_live_session_get_new_streams(session, lttng_live_msg_iter->self_msg_iter); + if (status != LTTNG_LIVE_ITERATOR_STATUS_OK && status != LTTNG_LIVE_ITERATOR_STATUS_END) { + goto end; + } + + trace_idx = 0; + while (trace_idx < session->traces->len) { + struct lttng_live_trace *trace = + (lttng_live_trace *) g_ptr_array_index(session->traces, trace_idx); + + status = lttng_live_metadata_update(trace); + switch (status) { + case LTTNG_LIVE_ITERATOR_STATUS_END: + case LTTNG_LIVE_ITERATOR_STATUS_OK: + trace_idx++; + break; + case LTTNG_LIVE_ITERATOR_STATUS_CONTINUE: + case LTTNG_LIVE_ITERATOR_STATUS_AGAIN: + goto end; + default: + BT_COMP_LOGE_APPEND_CAUSE(self_comp, + "Error updating trace metadata: " + "stream-iter-status=%s, trace-id=%" PRIu64, + lttng_live_iterator_status_string(status), trace->id); + goto end; + } + } + + /* + * Now that we have the metadata we can initialize the downstream + * iterator. + */ + status = lttng_live_lazy_msg_init(session, lttng_live_msg_iter->self_msg_iter); end: - return status; + return status; } -static -void lttng_live_force_new_streams_and_metadata(struct lttng_live_msg_iter *lttng_live_msg_iter) +static void +lttng_live_force_new_streams_and_metadata(struct lttng_live_msg_iter *lttng_live_msg_iter) { - uint64_t session_idx, trace_idx; - bt_logging_level log_level = lttng_live_msg_iter->log_level; - bt_self_component *self_comp = lttng_live_msg_iter->self_comp; - - for (session_idx = 0; session_idx < lttng_live_msg_iter->sessions->len; - session_idx++) { - struct lttng_live_session *session = - (lttng_live_session *) g_ptr_array_index(lttng_live_msg_iter->sessions, session_idx); - BT_COMP_LOGD("Force marking session as needing new streams: " - "session-id=%" PRIu64, session->id); - session->new_streams_needed = true; - for (trace_idx = 0; trace_idx < session->traces->len; - trace_idx++) { - struct lttng_live_trace *trace = - (lttng_live_trace *) g_ptr_array_index(session->traces, trace_idx); - BT_COMP_LOGD("Force marking trace metadata state as needing an update: " - "session-id=%" PRIu64 ", trace-id=%" PRIu64, - session->id, trace->id); - - BT_ASSERT(trace->metadata_stream_state != - LTTNG_LIVE_METADATA_STREAM_STATE_CLOSED); - - trace->metadata_stream_state = LTTNG_LIVE_METADATA_STREAM_STATE_NEEDED; - } - } + uint64_t session_idx, trace_idx; + bt_logging_level log_level = lttng_live_msg_iter->log_level; + bt_self_component *self_comp = lttng_live_msg_iter->self_comp; + + for (session_idx = 0; session_idx < lttng_live_msg_iter->sessions->len; session_idx++) { + struct lttng_live_session *session = + (lttng_live_session *) g_ptr_array_index(lttng_live_msg_iter->sessions, session_idx); + BT_COMP_LOGD("Force marking session as needing new streams: " + "session-id=%" PRIu64, + session->id); + session->new_streams_needed = true; + for (trace_idx = 0; trace_idx < session->traces->len; trace_idx++) { + struct lttng_live_trace *trace = + (lttng_live_trace *) g_ptr_array_index(session->traces, trace_idx); + BT_COMP_LOGD("Force marking trace metadata state as needing an update: " + "session-id=%" PRIu64 ", trace-id=%" PRIu64, + session->id, trace->id); + + BT_ASSERT(trace->metadata_stream_state != LTTNG_LIVE_METADATA_STREAM_STATE_CLOSED); + + trace->metadata_stream_state = LTTNG_LIVE_METADATA_STREAM_STATE_NEEDED; + } + } } -static -enum lttng_live_iterator_status -lttng_live_iterator_handle_new_streams_and_metadata( - struct lttng_live_msg_iter *lttng_live_msg_iter) +static enum lttng_live_iterator_status +lttng_live_iterator_handle_new_streams_and_metadata(struct lttng_live_msg_iter *lttng_live_msg_iter) { - enum lttng_live_iterator_status status; - enum lttng_live_viewer_status viewer_status; - bt_logging_level log_level = lttng_live_msg_iter->log_level; - bt_self_component *self_comp = lttng_live_msg_iter->self_comp; - uint64_t session_idx = 0, nr_sessions_opened = 0; - struct lttng_live_session *session; - enum session_not_found_action sess_not_found_act = - lttng_live_msg_iter->lttng_live_comp->params.sess_not_found_act; - - BT_COMP_LOGD("Update data and metadata of all sessions: " - "live-msg-iter-addr=%p", lttng_live_msg_iter); - /* - * In a remotely distant future, we could add a "new - * session" flag to the protocol, which would tell us that we - * need to query for new sessions even though we have sessions - * currently ongoing. - */ - if (lttng_live_msg_iter->sessions->len == 0) { - if (sess_not_found_act != SESSION_NOT_FOUND_ACTION_CONTINUE) { - BT_COMP_LOGD("No session found. Exiting in accordance with the `session-not-found-action` parameter"); - status = LTTNG_LIVE_ITERATOR_STATUS_END; - goto end; - } else { - BT_COMP_LOGD("No session found. Try creating a new one in accordance with the `session-not-found-action` parameter"); - /* - * Retry to create a viewer session for the requested - * session name. - */ - viewer_status = lttng_live_create_viewer_session(lttng_live_msg_iter); - if (viewer_status != LTTNG_LIVE_VIEWER_STATUS_OK) { - if (viewer_status == LTTNG_LIVE_VIEWER_STATUS_ERROR) { - status = LTTNG_LIVE_ITERATOR_STATUS_ERROR; - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Error creating LTTng live viewer session"); - } else if (viewer_status == LTTNG_LIVE_VIEWER_STATUS_INTERRUPTED) { - status = LTTNG_LIVE_ITERATOR_STATUS_AGAIN; - } else { - bt_common_abort(); - } - goto end; - } - } - } - - for (session_idx = 0; session_idx < lttng_live_msg_iter->sessions->len; - session_idx++) { - session = (lttng_live_session *) g_ptr_array_index(lttng_live_msg_iter->sessions, - session_idx); - status = lttng_live_get_session(lttng_live_msg_iter, session); - switch (status) { - case LTTNG_LIVE_ITERATOR_STATUS_OK: - break; - case LTTNG_LIVE_ITERATOR_STATUS_END: - status = LTTNG_LIVE_ITERATOR_STATUS_OK; - break; - default: - goto end; - } - if (!session->closed) { - nr_sessions_opened++; - } - } - - if (sess_not_found_act != SESSION_NOT_FOUND_ACTION_CONTINUE && - nr_sessions_opened == 0) { - status = LTTNG_LIVE_ITERATOR_STATUS_END; - } else { - status = LTTNG_LIVE_ITERATOR_STATUS_OK; - } + enum lttng_live_iterator_status status; + enum lttng_live_viewer_status viewer_status; + bt_logging_level log_level = lttng_live_msg_iter->log_level; + bt_self_component *self_comp = lttng_live_msg_iter->self_comp; + uint64_t session_idx = 0, nr_sessions_opened = 0; + struct lttng_live_session *session; + enum session_not_found_action sess_not_found_act = + lttng_live_msg_iter->lttng_live_comp->params.sess_not_found_act; + + BT_COMP_LOGD("Update data and metadata of all sessions: " + "live-msg-iter-addr=%p", + lttng_live_msg_iter); + /* + * In a remotely distant future, we could add a "new + * session" flag to the protocol, which would tell us that we + * need to query for new sessions even though we have sessions + * currently ongoing. + */ + if (lttng_live_msg_iter->sessions->len == 0) { + if (sess_not_found_act != SESSION_NOT_FOUND_ACTION_CONTINUE) { + BT_COMP_LOGD( + "No session found. Exiting in accordance with the `session-not-found-action` parameter"); + status = LTTNG_LIVE_ITERATOR_STATUS_END; + goto end; + } else { + BT_COMP_LOGD( + "No session found. Try creating a new one in accordance with the `session-not-found-action` parameter"); + /* + * Retry to create a viewer session for the requested + * session name. + */ + viewer_status = lttng_live_create_viewer_session(lttng_live_msg_iter); + if (viewer_status != LTTNG_LIVE_VIEWER_STATUS_OK) { + if (viewer_status == LTTNG_LIVE_VIEWER_STATUS_ERROR) { + status = LTTNG_LIVE_ITERATOR_STATUS_ERROR; + BT_COMP_LOGE_APPEND_CAUSE(self_comp, + "Error creating LTTng live viewer session"); + } else if (viewer_status == LTTNG_LIVE_VIEWER_STATUS_INTERRUPTED) { + status = LTTNG_LIVE_ITERATOR_STATUS_AGAIN; + } else { + bt_common_abort(); + } + goto end; + } + } + } + + for (session_idx = 0; session_idx < lttng_live_msg_iter->sessions->len; session_idx++) { + session = + (lttng_live_session *) g_ptr_array_index(lttng_live_msg_iter->sessions, session_idx); + status = lttng_live_get_session(lttng_live_msg_iter, session); + switch (status) { + case LTTNG_LIVE_ITERATOR_STATUS_OK: + break; + case LTTNG_LIVE_ITERATOR_STATUS_END: + status = LTTNG_LIVE_ITERATOR_STATUS_OK; + break; + default: + goto end; + } + if (!session->closed) { + nr_sessions_opened++; + } + } + + if (sess_not_found_act != SESSION_NOT_FOUND_ACTION_CONTINUE && nr_sessions_opened == 0) { + status = LTTNG_LIVE_ITERATOR_STATUS_END; + } else { + status = LTTNG_LIVE_ITERATOR_STATUS_OK; + } end: - return status; + return status; } -static -enum lttng_live_iterator_status emit_inactivity_message( - struct lttng_live_msg_iter *lttng_live_msg_iter, - struct lttng_live_stream_iterator *stream_iter, - const bt_message **message, uint64_t timestamp) +static enum lttng_live_iterator_status +emit_inactivity_message(struct lttng_live_msg_iter *lttng_live_msg_iter, + struct lttng_live_stream_iterator *stream_iter, const bt_message **message, + uint64_t timestamp) { - enum lttng_live_iterator_status ret = LTTNG_LIVE_ITERATOR_STATUS_OK; - bt_logging_level log_level = lttng_live_msg_iter->log_level; - bt_self_component *self_comp = lttng_live_msg_iter->self_comp; - bt_message *msg = NULL; - - BT_ASSERT(stream_iter->trace->clock_class); - - BT_COMP_LOGD("Emitting inactivity message for stream: ctf-stream-id=%" PRIu64 - ", viewer-stream-id=%" PRIu64 ", timestamp=%" PRIu64, - stream_iter->ctf_stream_class_id.value, - stream_iter->viewer_stream_id, timestamp); - - msg = bt_message_message_iterator_inactivity_create( - lttng_live_msg_iter->self_msg_iter, - stream_iter->trace->clock_class, timestamp); - if (!msg) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Error emitting message iterator inactivity message"); - goto error; - } - - *message = msg; + enum lttng_live_iterator_status ret = LTTNG_LIVE_ITERATOR_STATUS_OK; + bt_logging_level log_level = lttng_live_msg_iter->log_level; + bt_self_component *self_comp = lttng_live_msg_iter->self_comp; + bt_message *msg = NULL; + + BT_ASSERT(stream_iter->trace->clock_class); + + BT_COMP_LOGD("Emitting inactivity message for stream: ctf-stream-id=%" PRIu64 + ", viewer-stream-id=%" PRIu64 ", timestamp=%" PRIu64, + stream_iter->ctf_stream_class_id.value, stream_iter->viewer_stream_id, timestamp); + + msg = bt_message_message_iterator_inactivity_create(lttng_live_msg_iter->self_msg_iter, + stream_iter->trace->clock_class, timestamp); + if (!msg) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Error emitting message iterator inactivity message"); + goto error; + } + + *message = msg; end: - return ret; + return ret; error: - ret = LTTNG_LIVE_ITERATOR_STATUS_ERROR; - bt_message_put_ref(msg); - goto end; + ret = LTTNG_LIVE_ITERATOR_STATUS_ERROR; + bt_message_put_ref(msg); + goto end; } -static -enum lttng_live_iterator_status lttng_live_iterator_next_handle_one_quiescent_stream( - struct lttng_live_msg_iter *lttng_live_msg_iter, - struct lttng_live_stream_iterator *lttng_live_stream, - const bt_message **message) +static enum lttng_live_iterator_status lttng_live_iterator_next_handle_one_quiescent_stream( + struct lttng_live_msg_iter *lttng_live_msg_iter, + struct lttng_live_stream_iterator *lttng_live_stream, const bt_message **message) { - enum lttng_live_iterator_status ret = LTTNG_LIVE_ITERATOR_STATUS_OK; - - if (lttng_live_stream->state != LTTNG_LIVE_STREAM_QUIESCENT) { - return LTTNG_LIVE_ITERATOR_STATUS_OK; - } - - /* - * Check if we already sent an inactivty message downstream for this - * `current_inactivity_ts` value. - */ - if (lttng_live_stream->last_inactivity_ts.is_set && - lttng_live_stream->current_inactivity_ts == - lttng_live_stream->last_inactivity_ts.value) { - lttng_live_stream_iterator_set_state(lttng_live_stream, - LTTNG_LIVE_STREAM_QUIESCENT_NO_DATA); - - ret = LTTNG_LIVE_ITERATOR_STATUS_CONTINUE; - goto end; - } - - ret = emit_inactivity_message(lttng_live_msg_iter, lttng_live_stream, - message, lttng_live_stream->current_inactivity_ts); - - lttng_live_stream->last_inactivity_ts.value = - lttng_live_stream->current_inactivity_ts; - lttng_live_stream->last_inactivity_ts.is_set = true; + enum lttng_live_iterator_status ret = LTTNG_LIVE_ITERATOR_STATUS_OK; + + if (lttng_live_stream->state != LTTNG_LIVE_STREAM_QUIESCENT) { + return LTTNG_LIVE_ITERATOR_STATUS_OK; + } + + /* + * Check if we already sent an inactivty message downstream for this + * `current_inactivity_ts` value. + */ + if (lttng_live_stream->last_inactivity_ts.is_set && + lttng_live_stream->current_inactivity_ts == lttng_live_stream->last_inactivity_ts.value) { + lttng_live_stream_iterator_set_state(lttng_live_stream, + LTTNG_LIVE_STREAM_QUIESCENT_NO_DATA); + + ret = LTTNG_LIVE_ITERATOR_STATUS_CONTINUE; + goto end; + } + + ret = emit_inactivity_message(lttng_live_msg_iter, lttng_live_stream, message, + lttng_live_stream->current_inactivity_ts); + + lttng_live_stream->last_inactivity_ts.value = lttng_live_stream->current_inactivity_ts; + lttng_live_stream->last_inactivity_ts.is_set = true; end: - return ret; + return ret; } -static -int live_get_msg_ts_ns(struct lttng_live_stream_iterator *stream_iter, - struct lttng_live_msg_iter *lttng_live_msg_iter, - const bt_message *msg, int64_t last_msg_ts_ns, - int64_t *ts_ns) +static int live_get_msg_ts_ns(struct lttng_live_stream_iterator *stream_iter, + struct lttng_live_msg_iter *lttng_live_msg_iter, + const bt_message *msg, int64_t last_msg_ts_ns, int64_t *ts_ns) { - const bt_clock_class *clock_class = NULL; - const bt_clock_snapshot *clock_snapshot = NULL; - int ret = 0; - bt_logging_level log_level = lttng_live_msg_iter->log_level; - bt_self_component *self_comp = lttng_live_msg_iter->self_comp; - - BT_ASSERT_DBG(msg); - BT_ASSERT_DBG(ts_ns); - - BT_COMP_LOGD("Getting message's timestamp: iter-data-addr=%p, msg-addr=%p, " - "last-msg-ts=%" PRId64, lttng_live_msg_iter, msg, - last_msg_ts_ns); - - switch (bt_message_get_type(msg)) { - case BT_MESSAGE_TYPE_EVENT: - clock_class = bt_message_event_borrow_stream_class_default_clock_class_const( - msg); - BT_ASSERT_DBG(clock_class); - - clock_snapshot = bt_message_event_borrow_default_clock_snapshot_const( - msg); - break; - case BT_MESSAGE_TYPE_PACKET_BEGINNING: - clock_class = bt_message_packet_beginning_borrow_stream_class_default_clock_class_const( - msg); - BT_ASSERT(clock_class); - - clock_snapshot = bt_message_packet_beginning_borrow_default_clock_snapshot_const( - msg); - break; - case BT_MESSAGE_TYPE_PACKET_END: - clock_class = bt_message_packet_end_borrow_stream_class_default_clock_class_const( - msg); - BT_ASSERT(clock_class); - - clock_snapshot = bt_message_packet_end_borrow_default_clock_snapshot_const( - msg); - break; - case BT_MESSAGE_TYPE_DISCARDED_EVENTS: - clock_class = bt_message_discarded_events_borrow_stream_class_default_clock_class_const( - msg); - BT_ASSERT(clock_class); - - clock_snapshot = bt_message_discarded_events_borrow_beginning_default_clock_snapshot_const( - msg); - break; - case BT_MESSAGE_TYPE_DISCARDED_PACKETS: - clock_class = bt_message_discarded_packets_borrow_stream_class_default_clock_class_const( - msg); - BT_ASSERT(clock_class); - - clock_snapshot = bt_message_discarded_packets_borrow_beginning_default_clock_snapshot_const( - msg); - break; - case BT_MESSAGE_TYPE_MESSAGE_ITERATOR_INACTIVITY: - clock_snapshot = bt_message_message_iterator_inactivity_borrow_clock_snapshot_const( - msg); - break; - default: - /* All the other messages have a higher priority */ - BT_COMP_LOGD_STR("Message has no timestamp: using the last message timestamp."); - *ts_ns = last_msg_ts_ns; - goto end; - } - - clock_class = bt_clock_snapshot_borrow_clock_class_const(clock_snapshot); - BT_ASSERT_DBG(clock_class); - - ret = bt_clock_snapshot_get_ns_from_origin(clock_snapshot, ts_ns); - if (ret) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Cannot get nanoseconds from Epoch of clock snapshot: " - "clock-snapshot-addr=%p", clock_snapshot); - goto error; - } - - goto end; + const bt_clock_class *clock_class = NULL; + const bt_clock_snapshot *clock_snapshot = NULL; + int ret = 0; + bt_logging_level log_level = lttng_live_msg_iter->log_level; + bt_self_component *self_comp = lttng_live_msg_iter->self_comp; + + BT_ASSERT_DBG(msg); + BT_ASSERT_DBG(ts_ns); + + BT_COMP_LOGD("Getting message's timestamp: iter-data-addr=%p, msg-addr=%p, " + "last-msg-ts=%" PRId64, + lttng_live_msg_iter, msg, last_msg_ts_ns); + + switch (bt_message_get_type(msg)) { + case BT_MESSAGE_TYPE_EVENT: + clock_class = bt_message_event_borrow_stream_class_default_clock_class_const(msg); + BT_ASSERT_DBG(clock_class); + + clock_snapshot = bt_message_event_borrow_default_clock_snapshot_const(msg); + break; + case BT_MESSAGE_TYPE_PACKET_BEGINNING: + clock_class = + bt_message_packet_beginning_borrow_stream_class_default_clock_class_const(msg); + BT_ASSERT(clock_class); + + clock_snapshot = bt_message_packet_beginning_borrow_default_clock_snapshot_const(msg); + break; + case BT_MESSAGE_TYPE_PACKET_END: + clock_class = bt_message_packet_end_borrow_stream_class_default_clock_class_const(msg); + BT_ASSERT(clock_class); + + clock_snapshot = bt_message_packet_end_borrow_default_clock_snapshot_const(msg); + break; + case BT_MESSAGE_TYPE_DISCARDED_EVENTS: + clock_class = + bt_message_discarded_events_borrow_stream_class_default_clock_class_const(msg); + BT_ASSERT(clock_class); + + clock_snapshot = + bt_message_discarded_events_borrow_beginning_default_clock_snapshot_const(msg); + break; + case BT_MESSAGE_TYPE_DISCARDED_PACKETS: + clock_class = + bt_message_discarded_packets_borrow_stream_class_default_clock_class_const(msg); + BT_ASSERT(clock_class); + + clock_snapshot = + bt_message_discarded_packets_borrow_beginning_default_clock_snapshot_const(msg); + break; + case BT_MESSAGE_TYPE_MESSAGE_ITERATOR_INACTIVITY: + clock_snapshot = bt_message_message_iterator_inactivity_borrow_clock_snapshot_const(msg); + break; + default: + /* All the other messages have a higher priority */ + BT_COMP_LOGD_STR("Message has no timestamp: using the last message timestamp."); + *ts_ns = last_msg_ts_ns; + goto end; + } + + clock_class = bt_clock_snapshot_borrow_clock_class_const(clock_snapshot); + BT_ASSERT_DBG(clock_class); + + ret = bt_clock_snapshot_get_ns_from_origin(clock_snapshot, ts_ns); + if (ret) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, + "Cannot get nanoseconds from Epoch of clock snapshot: " + "clock-snapshot-addr=%p", + clock_snapshot); + goto error; + } + + goto end; error: - ret = -1; + ret = -1; end: - if (ret == 0) { - BT_COMP_LOGD("Found message's timestamp: " - "iter-data-addr=%p, msg-addr=%p, " - "last-msg-ts=%" PRId64 ", ts=%" PRId64, - lttng_live_msg_iter, msg, last_msg_ts_ns, *ts_ns); - } - - return ret; + if (ret == 0) { + BT_COMP_LOGD("Found message's timestamp: " + "iter-data-addr=%p, msg-addr=%p, " + "last-msg-ts=%" PRId64 ", ts=%" PRId64, + lttng_live_msg_iter, msg, last_msg_ts_ns, *ts_ns); + } + + return ret; } -static -enum lttng_live_iterator_status lttng_live_iterator_next_handle_one_active_data_stream( - struct lttng_live_msg_iter *lttng_live_msg_iter, - struct lttng_live_stream_iterator *lttng_live_stream, - const bt_message **message) +static enum lttng_live_iterator_status lttng_live_iterator_next_handle_one_active_data_stream( + struct lttng_live_msg_iter *lttng_live_msg_iter, + struct lttng_live_stream_iterator *lttng_live_stream, const bt_message **message) { - enum lttng_live_iterator_status ret = LTTNG_LIVE_ITERATOR_STATUS_OK; - bt_logging_level log_level = lttng_live_msg_iter->log_level; - bt_self_component *self_comp = lttng_live_msg_iter->self_comp; - enum ctf_msg_iter_status status; - uint64_t session_idx, trace_idx; - - for (session_idx = 0; session_idx < lttng_live_msg_iter->sessions->len; - session_idx++) { - struct lttng_live_session *session = - (lttng_live_session *) g_ptr_array_index(lttng_live_msg_iter->sessions, session_idx); - - if (session->new_streams_needed) { - BT_COMP_LOGD("Need an update for streams: " - "session-id=%" PRIu64, session->id); - ret = LTTNG_LIVE_ITERATOR_STATUS_CONTINUE; - goto end; - } - for (trace_idx = 0; trace_idx < session->traces->len; - trace_idx++) { - struct lttng_live_trace *trace = - (lttng_live_trace *) g_ptr_array_index(session->traces, trace_idx); - if (trace->metadata_stream_state == LTTNG_LIVE_METADATA_STREAM_STATE_NEEDED) { - BT_COMP_LOGD("Need an update for metadata stream: " - "session-id=%" PRIu64 ", trace-id=%" PRIu64, - session->id, trace->id); - ret = LTTNG_LIVE_ITERATOR_STATUS_CONTINUE; - goto end; - } - } - } - - if (lttng_live_stream->state != LTTNG_LIVE_STREAM_ACTIVE_DATA) { - ret = LTTNG_LIVE_ITERATOR_STATUS_ERROR; - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Invalid state of live stream iterator" - "stream-iter-status=%s", - lttng_live_stream_state_string(lttng_live_stream->state)); - goto end; - } - - status = ctf_msg_iter_get_next_message( - lttng_live_stream->msg_iter, message); - switch (status) { - case CTF_MSG_ITER_STATUS_EOF: - ret = LTTNG_LIVE_ITERATOR_STATUS_END; - break; - case CTF_MSG_ITER_STATUS_OK: - ret = LTTNG_LIVE_ITERATOR_STATUS_OK; - break; - case CTF_MSG_ITER_STATUS_AGAIN: - /* - * Continue immediately (end of packet). The next - * get_index may return AGAIN to delay the following - * attempt. - */ - ret = LTTNG_LIVE_ITERATOR_STATUS_CONTINUE; - break; - case CTF_MSG_ITER_STATUS_ERROR: - default: - ret = LTTNG_LIVE_ITERATOR_STATUS_ERROR; - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "CTF message iterator failed to get next message: " - "msg-iter=%p, msg-iter-status=%s", - lttng_live_stream->msg_iter, - ctf_msg_iter_status_string(status)); - break; - } + enum lttng_live_iterator_status ret = LTTNG_LIVE_ITERATOR_STATUS_OK; + bt_logging_level log_level = lttng_live_msg_iter->log_level; + bt_self_component *self_comp = lttng_live_msg_iter->self_comp; + enum ctf_msg_iter_status status; + uint64_t session_idx, trace_idx; + + for (session_idx = 0; session_idx < lttng_live_msg_iter->sessions->len; session_idx++) { + struct lttng_live_session *session = + (lttng_live_session *) g_ptr_array_index(lttng_live_msg_iter->sessions, session_idx); + + if (session->new_streams_needed) { + BT_COMP_LOGD("Need an update for streams: " + "session-id=%" PRIu64, + session->id); + ret = LTTNG_LIVE_ITERATOR_STATUS_CONTINUE; + goto end; + } + for (trace_idx = 0; trace_idx < session->traces->len; trace_idx++) { + struct lttng_live_trace *trace = + (lttng_live_trace *) g_ptr_array_index(session->traces, trace_idx); + if (trace->metadata_stream_state == LTTNG_LIVE_METADATA_STREAM_STATE_NEEDED) { + BT_COMP_LOGD("Need an update for metadata stream: " + "session-id=%" PRIu64 ", trace-id=%" PRIu64, + session->id, trace->id); + ret = LTTNG_LIVE_ITERATOR_STATUS_CONTINUE; + goto end; + } + } + } + + if (lttng_live_stream->state != LTTNG_LIVE_STREAM_ACTIVE_DATA) { + ret = LTTNG_LIVE_ITERATOR_STATUS_ERROR; + BT_COMP_LOGE_APPEND_CAUSE(self_comp, + "Invalid state of live stream iterator" + "stream-iter-status=%s", + lttng_live_stream_state_string(lttng_live_stream->state)); + goto end; + } + + status = ctf_msg_iter_get_next_message(lttng_live_stream->msg_iter, message); + switch (status) { + case CTF_MSG_ITER_STATUS_EOF: + ret = LTTNG_LIVE_ITERATOR_STATUS_END; + break; + case CTF_MSG_ITER_STATUS_OK: + ret = LTTNG_LIVE_ITERATOR_STATUS_OK; + break; + case CTF_MSG_ITER_STATUS_AGAIN: + /* + * Continue immediately (end of packet). The next + * get_index may return AGAIN to delay the following + * attempt. + */ + ret = LTTNG_LIVE_ITERATOR_STATUS_CONTINUE; + break; + case CTF_MSG_ITER_STATUS_ERROR: + default: + ret = LTTNG_LIVE_ITERATOR_STATUS_ERROR; + BT_COMP_LOGE_APPEND_CAUSE(self_comp, + "CTF message iterator failed to get next message: " + "msg-iter=%p, msg-iter-status=%s", + lttng_live_stream->msg_iter, ctf_msg_iter_status_string(status)); + break; + } end: - return ret; + return ret; } -static -enum lttng_live_iterator_status lttng_live_iterator_close_stream( - struct lttng_live_msg_iter *lttng_live_msg_iter, - struct lttng_live_stream_iterator *stream_iter, - const bt_message **curr_msg) +static enum lttng_live_iterator_status +lttng_live_iterator_close_stream(struct lttng_live_msg_iter *lttng_live_msg_iter, + struct lttng_live_stream_iterator *stream_iter, + const bt_message **curr_msg) { - enum lttng_live_iterator_status live_status = - LTTNG_LIVE_ITERATOR_STATUS_OK; - bt_logging_level log_level = lttng_live_msg_iter->log_level; - bt_self_component *self_comp = lttng_live_msg_iter->self_comp; - - BT_COMP_LOGD("Closing live stream iterator: stream-name=\"%s\", " - "viewer-stream-id=%" PRIu64, stream_iter->name->str, - stream_iter->viewer_stream_id); - - /* - * The viewer has hung up on us so we are closing the stream. The - * `ctf_msg_iter` should simply realize that it needs to close the - * stream properly by emitting the necessary stream end message. - */ - enum ctf_msg_iter_status status = ctf_msg_iter_get_next_message( - stream_iter->msg_iter, curr_msg); - - if (status == CTF_MSG_ITER_STATUS_ERROR) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Error getting the next message from CTF message iterator"); - live_status = LTTNG_LIVE_ITERATOR_STATUS_ERROR; - goto end; - } else if (status == CTF_MSG_ITER_STATUS_EOF) { - BT_COMP_LOGI("Reached the end of the live stream iterator."); - live_status = LTTNG_LIVE_ITERATOR_STATUS_END; - goto end; - } - - BT_ASSERT(status == CTF_MSG_ITER_STATUS_OK); + enum lttng_live_iterator_status live_status = LTTNG_LIVE_ITERATOR_STATUS_OK; + bt_logging_level log_level = lttng_live_msg_iter->log_level; + bt_self_component *self_comp = lttng_live_msg_iter->self_comp; + + BT_COMP_LOGD("Closing live stream iterator: stream-name=\"%s\", " + "viewer-stream-id=%" PRIu64, + stream_iter->name->str, stream_iter->viewer_stream_id); + + /* + * The viewer has hung up on us so we are closing the stream. The + * `ctf_msg_iter` should simply realize that it needs to close the + * stream properly by emitting the necessary stream end message. + */ + enum ctf_msg_iter_status status = + ctf_msg_iter_get_next_message(stream_iter->msg_iter, curr_msg); + + if (status == CTF_MSG_ITER_STATUS_ERROR) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, + "Error getting the next message from CTF message iterator"); + live_status = LTTNG_LIVE_ITERATOR_STATUS_ERROR; + goto end; + } else if (status == CTF_MSG_ITER_STATUS_EOF) { + BT_COMP_LOGI("Reached the end of the live stream iterator."); + live_status = LTTNG_LIVE_ITERATOR_STATUS_END; + goto end; + } + + BT_ASSERT(status == CTF_MSG_ITER_STATUS_OK); end: - return live_status; + return live_status; } /* @@ -994,1332 +944,1263 @@ end: * * When disconnected from relayd: try to re-connect endlessly. */ -static -enum lttng_live_iterator_status lttng_live_iterator_next_msg_on_stream( - struct lttng_live_msg_iter *lttng_live_msg_iter, - struct lttng_live_stream_iterator *stream_iter, - const bt_message **curr_msg) +static enum lttng_live_iterator_status +lttng_live_iterator_next_msg_on_stream(struct lttng_live_msg_iter *lttng_live_msg_iter, + struct lttng_live_stream_iterator *stream_iter, + const bt_message **curr_msg) { - bt_logging_level log_level = lttng_live_msg_iter->log_level; - bt_self_component *self_comp = lttng_live_msg_iter->self_comp; - enum lttng_live_iterator_status live_status; - - BT_COMP_LOGD("Advancing live stream iterator until next message if possible: " - "stream-name=\"%s\", viewer-stream-id=%" PRIu64, - stream_iter->name->str, stream_iter->viewer_stream_id); - - if (stream_iter->has_stream_hung_up) { - /* - * The stream has hung up and the stream was properly closed - * during the last call to the current function. Return _END - * status now so that this stream iterator is removed for the - * stream iterator list. - */ - live_status = LTTNG_LIVE_ITERATOR_STATUS_END; - goto end; - } + bt_logging_level log_level = lttng_live_msg_iter->log_level; + bt_self_component *self_comp = lttng_live_msg_iter->self_comp; + enum lttng_live_iterator_status live_status; + + BT_COMP_LOGD("Advancing live stream iterator until next message if possible: " + "stream-name=\"%s\", viewer-stream-id=%" PRIu64, + stream_iter->name->str, stream_iter->viewer_stream_id); + + if (stream_iter->has_stream_hung_up) { + /* + * The stream has hung up and the stream was properly closed + * during the last call to the current function. Return _END + * status now so that this stream iterator is removed for the + * stream iterator list. + */ + live_status = LTTNG_LIVE_ITERATOR_STATUS_END; + goto end; + } retry: - LTTNG_LIVE_LOGD_STREAM_ITER(stream_iter); - - /* - * Make sure we have the most recent metadata and possibly some new - * streams. - */ - live_status = lttng_live_iterator_handle_new_streams_and_metadata( - lttng_live_msg_iter); - if (live_status != LTTNG_LIVE_ITERATOR_STATUS_OK) { - goto end; - } - - live_status = lttng_live_iterator_next_handle_one_no_data_stream( - lttng_live_msg_iter, stream_iter); - if (live_status != LTTNG_LIVE_ITERATOR_STATUS_OK) { - if (live_status == LTTNG_LIVE_ITERATOR_STATUS_END) { - /* - * We overwrite `live_status` since `curr_msg` is - * likely set to a valid message in this function. - */ - live_status = lttng_live_iterator_close_stream( - lttng_live_msg_iter, stream_iter, curr_msg); - } - goto end; - } - - live_status = lttng_live_iterator_next_handle_one_quiescent_stream( - lttng_live_msg_iter, stream_iter, curr_msg); - if (live_status != LTTNG_LIVE_ITERATOR_STATUS_OK) { - BT_ASSERT(!*curr_msg); - goto end; - } - if (*curr_msg) { - goto end; - } - live_status = lttng_live_iterator_next_handle_one_active_data_stream( - lttng_live_msg_iter, stream_iter, curr_msg); - if (live_status != LTTNG_LIVE_ITERATOR_STATUS_OK) { - BT_ASSERT(!*curr_msg); - } + LTTNG_LIVE_LOGD_STREAM_ITER(stream_iter); + + /* + * Make sure we have the most recent metadata and possibly some new + * streams. + */ + live_status = lttng_live_iterator_handle_new_streams_and_metadata(lttng_live_msg_iter); + if (live_status != LTTNG_LIVE_ITERATOR_STATUS_OK) { + goto end; + } + + live_status = + lttng_live_iterator_next_handle_one_no_data_stream(lttng_live_msg_iter, stream_iter); + if (live_status != LTTNG_LIVE_ITERATOR_STATUS_OK) { + if (live_status == LTTNG_LIVE_ITERATOR_STATUS_END) { + /* + * We overwrite `live_status` since `curr_msg` is + * likely set to a valid message in this function. + */ + live_status = + lttng_live_iterator_close_stream(lttng_live_msg_iter, stream_iter, curr_msg); + } + goto end; + } + + live_status = lttng_live_iterator_next_handle_one_quiescent_stream(lttng_live_msg_iter, + stream_iter, curr_msg); + if (live_status != LTTNG_LIVE_ITERATOR_STATUS_OK) { + BT_ASSERT(!*curr_msg); + goto end; + } + if (*curr_msg) { + goto end; + } + live_status = lttng_live_iterator_next_handle_one_active_data_stream(lttng_live_msg_iter, + stream_iter, curr_msg); + if (live_status != LTTNG_LIVE_ITERATOR_STATUS_OK) { + BT_ASSERT(!*curr_msg); + } end: - if (live_status == LTTNG_LIVE_ITERATOR_STATUS_CONTINUE) { - BT_COMP_LOGD("Ask the relay daemon for an updated view of the data and metadata streams"); - goto retry; - } + if (live_status == LTTNG_LIVE_ITERATOR_STATUS_CONTINUE) { + BT_COMP_LOGD("Ask the relay daemon for an updated view of the data and metadata streams"); + goto retry; + } - BT_COMP_LOGD("Returning from advancing live stream iterator: status=%s, " - "stream-name=\"%s\", viewer-stream-id=%" PRIu64, - lttng_live_iterator_status_string(live_status), - stream_iter->name->str, stream_iter->viewer_stream_id); + BT_COMP_LOGD("Returning from advancing live stream iterator: status=%s, " + "stream-name=\"%s\", viewer-stream-id=%" PRIu64, + lttng_live_iterator_status_string(live_status), stream_iter->name->str, + stream_iter->viewer_stream_id); - return live_status; + return live_status; } -static -bool is_discarded_packet_or_event_message(const bt_message *msg) +static bool is_discarded_packet_or_event_message(const bt_message *msg) { - const enum bt_message_type msg_type = bt_message_get_type(msg); + const enum bt_message_type msg_type = bt_message_get_type(msg); - return msg_type == BT_MESSAGE_TYPE_DISCARDED_EVENTS || - msg_type == BT_MESSAGE_TYPE_DISCARDED_PACKETS; + return msg_type == BT_MESSAGE_TYPE_DISCARDED_EVENTS || + msg_type == BT_MESSAGE_TYPE_DISCARDED_PACKETS; } -static -enum lttng_live_iterator_status adjust_discarded_packets_message( - bt_self_message_iterator *iter, - const bt_stream *stream, - const bt_message *msg_in, bt_message **msg_out, - uint64_t new_begin_ts) +static enum lttng_live_iterator_status +adjust_discarded_packets_message(bt_self_message_iterator *iter, const bt_stream *stream, + const bt_message *msg_in, bt_message **msg_out, + uint64_t new_begin_ts) { - enum lttng_live_iterator_status status = LTTNG_LIVE_ITERATOR_STATUS_OK; - enum bt_property_availability availability; - const bt_clock_snapshot *clock_snapshot; - uint64_t end_ts; - uint64_t count; - - clock_snapshot = bt_message_discarded_packets_borrow_end_default_clock_snapshot_const(msg_in); - end_ts = bt_clock_snapshot_get_value(clock_snapshot); - - availability = bt_message_discarded_packets_get_count(msg_in, &count); - BT_ASSERT_DBG(availability == BT_PROPERTY_AVAILABILITY_AVAILABLE); - - *msg_out = bt_message_discarded_packets_create_with_default_clock_snapshots( - iter, stream, new_begin_ts, end_ts); - if (!*msg_out) { - status = LTTNG_LIVE_ITERATOR_STATUS_NOMEM; - goto end; - } - - bt_message_discarded_packets_set_count(*msg_out, count); + enum lttng_live_iterator_status status = LTTNG_LIVE_ITERATOR_STATUS_OK; + enum bt_property_availability availability; + const bt_clock_snapshot *clock_snapshot; + uint64_t end_ts; + uint64_t count; + + clock_snapshot = bt_message_discarded_packets_borrow_end_default_clock_snapshot_const(msg_in); + end_ts = bt_clock_snapshot_get_value(clock_snapshot); + + availability = bt_message_discarded_packets_get_count(msg_in, &count); + BT_ASSERT_DBG(availability == BT_PROPERTY_AVAILABILITY_AVAILABLE); + + *msg_out = bt_message_discarded_packets_create_with_default_clock_snapshots( + iter, stream, new_begin_ts, end_ts); + if (!*msg_out) { + status = LTTNG_LIVE_ITERATOR_STATUS_NOMEM; + goto end; + } + + bt_message_discarded_packets_set_count(*msg_out, count); end: - return status; + return status; } -static -enum lttng_live_iterator_status adjust_discarded_events_message( - bt_self_message_iterator *iter, - const bt_stream *stream, - const bt_message *msg_in, bt_message **msg_out, - uint64_t new_begin_ts) +static enum lttng_live_iterator_status +adjust_discarded_events_message(bt_self_message_iterator *iter, const bt_stream *stream, + const bt_message *msg_in, bt_message **msg_out, + uint64_t new_begin_ts) { - enum lttng_live_iterator_status status = LTTNG_LIVE_ITERATOR_STATUS_OK; - enum bt_property_availability availability; - const bt_clock_snapshot *clock_snapshot; - uint64_t end_ts; - uint64_t count; - - clock_snapshot = bt_message_discarded_events_borrow_end_default_clock_snapshot_const(msg_in); - end_ts = bt_clock_snapshot_get_value(clock_snapshot); - - availability = bt_message_discarded_events_get_count(msg_in, &count); - BT_ASSERT_DBG(availability == BT_PROPERTY_AVAILABILITY_AVAILABLE); - - *msg_out = bt_message_discarded_events_create_with_default_clock_snapshots( - iter, stream, new_begin_ts, end_ts); - if (!*msg_out) { - status = LTTNG_LIVE_ITERATOR_STATUS_NOMEM; - goto end; - } - - bt_message_discarded_events_set_count(*msg_out, count); + enum lttng_live_iterator_status status = LTTNG_LIVE_ITERATOR_STATUS_OK; + enum bt_property_availability availability; + const bt_clock_snapshot *clock_snapshot; + uint64_t end_ts; + uint64_t count; + + clock_snapshot = bt_message_discarded_events_borrow_end_default_clock_snapshot_const(msg_in); + end_ts = bt_clock_snapshot_get_value(clock_snapshot); + + availability = bt_message_discarded_events_get_count(msg_in, &count); + BT_ASSERT_DBG(availability == BT_PROPERTY_AVAILABILITY_AVAILABLE); + + *msg_out = bt_message_discarded_events_create_with_default_clock_snapshots( + iter, stream, new_begin_ts, end_ts); + if (!*msg_out) { + status = LTTNG_LIVE_ITERATOR_STATUS_NOMEM; + goto end; + } + + bt_message_discarded_events_set_count(*msg_out, count); end: - return status; + return status; } -static -enum lttng_live_iterator_status handle_late_message( - struct lttng_live_msg_iter *lttng_live_msg_iter, - struct lttng_live_stream_iterator *stream_iter, - int64_t late_msg_ts_ns, const bt_message *late_msg) +static enum lttng_live_iterator_status +handle_late_message(struct lttng_live_msg_iter *lttng_live_msg_iter, + struct lttng_live_stream_iterator *stream_iter, int64_t late_msg_ts_ns, + const bt_message *late_msg) { - bt_self_component *self_comp = lttng_live_msg_iter->self_comp; - bt_logging_level log_level = lttng_live_msg_iter->log_level; - const bt_clock_class *clock_class; - const bt_stream_class *stream_class; - enum bt_clock_class_cycles_to_ns_from_origin_status ts_ns_status; - int64_t last_inactivity_ts_ns; - enum lttng_live_iterator_status stream_iter_status = LTTNG_LIVE_ITERATOR_STATUS_OK; - enum lttng_live_iterator_status adjust_status; - bt_message *adjusted_message; - - /* - * The timestamp of the current message is before the last message sent - * by this component. We CANNOT send it as is. - * - * The only expected scenario in which that could happen is the - * following, everything else is a bug in this component, relay deamon, - * or CTF parser. - * - * Expected scenario: The CTF message iterator emitted discarded - * packets and discarded events with synthesized beginning and end - * timestamps from the bounds of the last known packet and the newly - * decoded packet header. The CTF message iterator is not aware of - * stream inactivity beacons. Hence, we have to adjust the beginning - * timestamp of those types of messages if a stream signalled its - * inactivity up until _after_ the last known packet's beginning - * timestamp. - * - * Otherwise, the monotonicity guarantee of message timestamps would - * not be preserved. - * - * In short, the only scenario in which it's okay and fixable to - * received a late message is when: - * 1. the late message is a discarded packets or discarded events - * message, - * 2. this stream produced an inactivity message downstream, and - * 3. the timestamp of the late message is within the inactivity - * timespan we sent downstream through the inactivity message. - */ - - BT_COMP_LOGD("Handling late message on live stream iterator: " - "stream-name=\"%s\", viewer-stream-id=%" PRIu64, - stream_iter->name->str, stream_iter->viewer_stream_id); - - if (!stream_iter->last_inactivity_ts.is_set) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Invalid live stream state: " - "have a late message when no inactivity message " - "was ever sent for that stream."); - stream_iter_status = LTTNG_LIVE_ITERATOR_STATUS_ERROR; - goto end; - } - - if (!is_discarded_packet_or_event_message(late_msg)) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Invalid live stream state: " - "have a late message that is not a packet discarded or " - "event discarded message: late-msg-type=%s", - bt_common_message_type_string(bt_message_get_type(late_msg))); - stream_iter_status = LTTNG_LIVE_ITERATOR_STATUS_ERROR; - goto end; - } - - stream_class = bt_stream_borrow_class_const(stream_iter->stream); - clock_class = bt_stream_class_borrow_default_clock_class_const(stream_class); - - ts_ns_status = bt_clock_class_cycles_to_ns_from_origin(clock_class, - stream_iter->last_inactivity_ts.value, &last_inactivity_ts_ns); - if (ts_ns_status != BT_CLOCK_CLASS_CYCLES_TO_NS_FROM_ORIGIN_STATUS_OK) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp,"Error converting last " - "inactivity message timestamp to nanoseconds"); - stream_iter_status = LTTNG_LIVE_ITERATOR_STATUS_ERROR; - goto end; - } - - if (last_inactivity_ts_ns <= late_msg_ts_ns) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Invalid live stream state: " - "have a late message that is none included in a stream " - "inactivity timespan: last-inactivity-ts-ns=%" PRIu64 - "late-msg-ts-ns=%" PRIu64, last_inactivity_ts_ns, late_msg_ts_ns); - stream_iter_status = LTTNG_LIVE_ITERATOR_STATUS_ERROR; - goto end; - } - - /* - * We now know that it's okay for this message to be late, we can now - * adjust its timestamp to ensure monotonicity. - */ - BT_COMP_LOGD("Adjusting the timestamp of late message: late-msg-type=%s, " - "msg-new-ts-ns=%" PRIu64, - bt_common_message_type_string(bt_message_get_type(late_msg)), - stream_iter->last_inactivity_ts.value); - switch (bt_message_get_type(late_msg)) { - case BT_MESSAGE_TYPE_DISCARDED_EVENTS: - adjust_status = adjust_discarded_events_message( - lttng_live_msg_iter->self_msg_iter, - stream_iter->stream, - late_msg, &adjusted_message, - stream_iter->last_inactivity_ts.value); - break; - case BT_MESSAGE_TYPE_DISCARDED_PACKETS: - adjust_status = adjust_discarded_packets_message( - lttng_live_msg_iter->self_msg_iter, - stream_iter->stream, - late_msg, &adjusted_message, - stream_iter->last_inactivity_ts.value); - break; - default: - bt_common_abort(); - } - - if (adjust_status != LTTNG_LIVE_ITERATOR_STATUS_OK) { - stream_iter_status = adjust_status; - goto end; - } - - BT_ASSERT_DBG(adjusted_message); - stream_iter->current_msg = adjusted_message; - stream_iter->current_msg_ts_ns = last_inactivity_ts_ns; - bt_message_put_ref(late_msg); + bt_self_component *self_comp = lttng_live_msg_iter->self_comp; + bt_logging_level log_level = lttng_live_msg_iter->log_level; + const bt_clock_class *clock_class; + const bt_stream_class *stream_class; + enum bt_clock_class_cycles_to_ns_from_origin_status ts_ns_status; + int64_t last_inactivity_ts_ns; + enum lttng_live_iterator_status stream_iter_status = LTTNG_LIVE_ITERATOR_STATUS_OK; + enum lttng_live_iterator_status adjust_status; + bt_message *adjusted_message; + + /* + * The timestamp of the current message is before the last message sent + * by this component. We CANNOT send it as is. + * + * The only expected scenario in which that could happen is the + * following, everything else is a bug in this component, relay deamon, + * or CTF parser. + * + * Expected scenario: The CTF message iterator emitted discarded + * packets and discarded events with synthesized beginning and end + * timestamps from the bounds of the last known packet and the newly + * decoded packet header. The CTF message iterator is not aware of + * stream inactivity beacons. Hence, we have to adjust the beginning + * timestamp of those types of messages if a stream signalled its + * inactivity up until _after_ the last known packet's beginning + * timestamp. + * + * Otherwise, the monotonicity guarantee of message timestamps would + * not be preserved. + * + * In short, the only scenario in which it's okay and fixable to + * received a late message is when: + * 1. the late message is a discarded packets or discarded events + * message, + * 2. this stream produced an inactivity message downstream, and + * 3. the timestamp of the late message is within the inactivity + * timespan we sent downstream through the inactivity message. + */ + + BT_COMP_LOGD("Handling late message on live stream iterator: " + "stream-name=\"%s\", viewer-stream-id=%" PRIu64, + stream_iter->name->str, stream_iter->viewer_stream_id); + + if (!stream_iter->last_inactivity_ts.is_set) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Invalid live stream state: " + "have a late message when no inactivity message " + "was ever sent for that stream."); + stream_iter_status = LTTNG_LIVE_ITERATOR_STATUS_ERROR; + goto end; + } + + if (!is_discarded_packet_or_event_message(late_msg)) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, + "Invalid live stream state: " + "have a late message that is not a packet discarded or " + "event discarded message: late-msg-type=%s", + bt_common_message_type_string(bt_message_get_type(late_msg))); + stream_iter_status = LTTNG_LIVE_ITERATOR_STATUS_ERROR; + goto end; + } + + stream_class = bt_stream_borrow_class_const(stream_iter->stream); + clock_class = bt_stream_class_borrow_default_clock_class_const(stream_class); + + ts_ns_status = bt_clock_class_cycles_to_ns_from_origin( + clock_class, stream_iter->last_inactivity_ts.value, &last_inactivity_ts_ns); + if (ts_ns_status != BT_CLOCK_CLASS_CYCLES_TO_NS_FROM_ORIGIN_STATUS_OK) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Error converting last " + "inactivity message timestamp to nanoseconds"); + stream_iter_status = LTTNG_LIVE_ITERATOR_STATUS_ERROR; + goto end; + } + + if (last_inactivity_ts_ns <= late_msg_ts_ns) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, + "Invalid live stream state: " + "have a late message that is none included in a stream " + "inactivity timespan: last-inactivity-ts-ns=%" PRIu64 + "late-msg-ts-ns=%" PRIu64, + last_inactivity_ts_ns, late_msg_ts_ns); + stream_iter_status = LTTNG_LIVE_ITERATOR_STATUS_ERROR; + goto end; + } + + /* + * We now know that it's okay for this message to be late, we can now + * adjust its timestamp to ensure monotonicity. + */ + BT_COMP_LOGD("Adjusting the timestamp of late message: late-msg-type=%s, " + "msg-new-ts-ns=%" PRIu64, + bt_common_message_type_string(bt_message_get_type(late_msg)), + stream_iter->last_inactivity_ts.value); + switch (bt_message_get_type(late_msg)) { + case BT_MESSAGE_TYPE_DISCARDED_EVENTS: + adjust_status = adjust_discarded_events_message( + lttng_live_msg_iter->self_msg_iter, stream_iter->stream, late_msg, &adjusted_message, + stream_iter->last_inactivity_ts.value); + break; + case BT_MESSAGE_TYPE_DISCARDED_PACKETS: + adjust_status = adjust_discarded_packets_message( + lttng_live_msg_iter->self_msg_iter, stream_iter->stream, late_msg, &adjusted_message, + stream_iter->last_inactivity_ts.value); + break; + default: + bt_common_abort(); + } + + if (adjust_status != LTTNG_LIVE_ITERATOR_STATUS_OK) { + stream_iter_status = adjust_status; + goto end; + } + + BT_ASSERT_DBG(adjusted_message); + stream_iter->current_msg = adjusted_message; + stream_iter->current_msg_ts_ns = last_inactivity_ts_ns; + bt_message_put_ref(late_msg); end: - return stream_iter_status; + return stream_iter_status; } -static -enum lttng_live_iterator_status next_stream_iterator_for_trace( - struct lttng_live_msg_iter *lttng_live_msg_iter, - struct lttng_live_trace *live_trace, - struct lttng_live_stream_iterator **youngest_trace_stream_iter) +static enum lttng_live_iterator_status +next_stream_iterator_for_trace(struct lttng_live_msg_iter *lttng_live_msg_iter, + struct lttng_live_trace *live_trace, + struct lttng_live_stream_iterator **youngest_trace_stream_iter) { - struct lttng_live_stream_iterator *youngest_candidate_stream_iter = NULL; - bt_logging_level log_level = lttng_live_msg_iter->log_level; - bt_self_component *self_comp = lttng_live_msg_iter->self_comp; - enum lttng_live_iterator_status stream_iter_status;; - int64_t youngest_candidate_msg_ts = INT64_MAX; - uint64_t stream_iter_idx; - - BT_ASSERT_DBG(live_trace); - BT_ASSERT_DBG(live_trace->stream_iterators); - - BT_COMP_LOGD("Finding the next stream iterator for trace: " - "trace-id=%" PRIu64, live_trace->id); - /* - * Update the current message of every stream iterators of this trace. - * The current msg of every stream must have a timestamp equal or - * larger than the last message returned by this iterator. We must - * ensure monotonicity. - */ - stream_iter_idx = 0; - while (stream_iter_idx < live_trace->stream_iterators->len) { - bool stream_iter_is_ended = false; - struct lttng_live_stream_iterator *stream_iter = - (lttng_live_stream_iterator *) g_ptr_array_index(live_trace->stream_iterators, - stream_iter_idx); - - /* - * If there is no current message for this stream, go fetch - * one. - */ - while (!stream_iter->current_msg) { - const bt_message *msg = NULL; - int64_t curr_msg_ts_ns = INT64_MAX; - - stream_iter_status = lttng_live_iterator_next_msg_on_stream( - lttng_live_msg_iter, stream_iter, &msg); - - if (stream_iter_status == LTTNG_LIVE_ITERATOR_STATUS_END) { - stream_iter_is_ended = true; - break; - } - - if (stream_iter_status != LTTNG_LIVE_ITERATOR_STATUS_OK) { - goto end; - } - - BT_ASSERT_DBG(msg); - - BT_COMP_LOGD("Live stream iterator returned message: msg-type=%s, " - "stream-name=\"%s\", viewer-stream-id=%" PRIu64, - bt_common_message_type_string(bt_message_get_type(msg)), - stream_iter->name->str, stream_iter->viewer_stream_id); - - /* - * Get the timestamp in nanoseconds from origin of this - * messsage. - */ - live_get_msg_ts_ns(stream_iter, lttng_live_msg_iter, - msg, lttng_live_msg_iter->last_msg_ts_ns, - &curr_msg_ts_ns); - - /* - * Check if the message of the current live stream - * iterator occurred at the exact same time or after the - * last message returned by this component's message - * iterator. If not, we need to handle it with care. - */ - if (curr_msg_ts_ns >= lttng_live_msg_iter->last_msg_ts_ns) { - stream_iter->current_msg = msg; - stream_iter->current_msg_ts_ns = curr_msg_ts_ns; - } else { - /* - * We received a message from the past. This - * may be fixable but it can also be an error. - */ - stream_iter_status = handle_late_message( - lttng_live_msg_iter, stream_iter, - curr_msg_ts_ns, msg); - if (stream_iter_status != LTTNG_LIVE_ITERATOR_STATUS_OK) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Late message could not be handled correctly: " - "lttng-live-msg-iter-addr=%p, " - "stream-name=\"%s\", " - "curr-msg-ts=%" PRId64 - ", last-msg-ts=%" PRId64, - lttng_live_msg_iter, - stream_iter->name->str, - curr_msg_ts_ns, - lttng_live_msg_iter->last_msg_ts_ns); - stream_iter_status = LTTNG_LIVE_ITERATOR_STATUS_ERROR; - goto end; - } - } - } - - BT_ASSERT_DBG(stream_iter != youngest_candidate_stream_iter); - - if (!stream_iter_is_ended) { - if (G_UNLIKELY(youngest_candidate_stream_iter == NULL) || - stream_iter->current_msg_ts_ns < youngest_candidate_msg_ts) { - /* - * Update the current best candidate message - * for the stream iterator of this live trace - * to be forwarded downstream. - */ - youngest_candidate_msg_ts = stream_iter->current_msg_ts_ns; - youngest_candidate_stream_iter = stream_iter; - } else if (stream_iter->current_msg_ts_ns == youngest_candidate_msg_ts) { - /* - * Order the messages in an arbitrary but - * deterministic way. - */ - BT_ASSERT_DBG(stream_iter != youngest_candidate_stream_iter); - int ret = common_muxing_compare_messages( - stream_iter->current_msg, - youngest_candidate_stream_iter->current_msg); - if (ret < 0) { - /* - * The `youngest_candidate_stream_iter->current_msg` - * should go first. Update the next - * iterator and the current timestamp. - */ - youngest_candidate_msg_ts = stream_iter->current_msg_ts_ns; - youngest_candidate_stream_iter = stream_iter; - } else if (ret == 0) { - /* - * Unable to pick which one should go - * first. - */ - BT_COMP_LOGW("Cannot deterministically pick next live stream message iterator because they have identical next messages: " - "stream-iter-addr=%p" - "stream-iter-addr=%p", - stream_iter, - youngest_candidate_stream_iter); - } - } - - stream_iter_idx++; - } else { - /* - * The live stream iterator has ended. That - * iterator is removed from the array, but - * there is no need to increment - * stream_iter_idx as - * g_ptr_array_remove_index_fast replaces the - * removed element with the array's last - * element. - */ - g_ptr_array_remove_index_fast( - live_trace->stream_iterators, - stream_iter_idx); - } - } - - if (youngest_candidate_stream_iter) { - *youngest_trace_stream_iter = youngest_candidate_stream_iter; - stream_iter_status = LTTNG_LIVE_ITERATOR_STATUS_OK; - } else { - /* - * The only case where we don't have a candidate for this trace - * is if we reached the end of all the iterators. - */ - BT_ASSERT(live_trace->stream_iterators->len == 0); - stream_iter_status = LTTNG_LIVE_ITERATOR_STATUS_END; - } + struct lttng_live_stream_iterator *youngest_candidate_stream_iter = NULL; + bt_logging_level log_level = lttng_live_msg_iter->log_level; + bt_self_component *self_comp = lttng_live_msg_iter->self_comp; + enum lttng_live_iterator_status stream_iter_status; + ; + int64_t youngest_candidate_msg_ts = INT64_MAX; + uint64_t stream_iter_idx; + + BT_ASSERT_DBG(live_trace); + BT_ASSERT_DBG(live_trace->stream_iterators); + + BT_COMP_LOGD("Finding the next stream iterator for trace: " + "trace-id=%" PRIu64, + live_trace->id); + /* + * Update the current message of every stream iterators of this trace. + * The current msg of every stream must have a timestamp equal or + * larger than the last message returned by this iterator. We must + * ensure monotonicity. + */ + stream_iter_idx = 0; + while (stream_iter_idx < live_trace->stream_iterators->len) { + bool stream_iter_is_ended = false; + struct lttng_live_stream_iterator *stream_iter = + (lttng_live_stream_iterator *) g_ptr_array_index(live_trace->stream_iterators, + stream_iter_idx); + + /* + * If there is no current message for this stream, go fetch + * one. + */ + while (!stream_iter->current_msg) { + const bt_message *msg = NULL; + int64_t curr_msg_ts_ns = INT64_MAX; + + stream_iter_status = + lttng_live_iterator_next_msg_on_stream(lttng_live_msg_iter, stream_iter, &msg); + + if (stream_iter_status == LTTNG_LIVE_ITERATOR_STATUS_END) { + stream_iter_is_ended = true; + break; + } + + if (stream_iter_status != LTTNG_LIVE_ITERATOR_STATUS_OK) { + goto end; + } + + BT_ASSERT_DBG(msg); + + BT_COMP_LOGD("Live stream iterator returned message: msg-type=%s, " + "stream-name=\"%s\", viewer-stream-id=%" PRIu64, + bt_common_message_type_string(bt_message_get_type(msg)), + stream_iter->name->str, stream_iter->viewer_stream_id); + + /* + * Get the timestamp in nanoseconds from origin of this + * messsage. + */ + live_get_msg_ts_ns(stream_iter, lttng_live_msg_iter, msg, + lttng_live_msg_iter->last_msg_ts_ns, &curr_msg_ts_ns); + + /* + * Check if the message of the current live stream + * iterator occurred at the exact same time or after the + * last message returned by this component's message + * iterator. If not, we need to handle it with care. + */ + if (curr_msg_ts_ns >= lttng_live_msg_iter->last_msg_ts_ns) { + stream_iter->current_msg = msg; + stream_iter->current_msg_ts_ns = curr_msg_ts_ns; + } else { + /* + * We received a message from the past. This + * may be fixable but it can also be an error. + */ + stream_iter_status = + handle_late_message(lttng_live_msg_iter, stream_iter, curr_msg_ts_ns, msg); + if (stream_iter_status != LTTNG_LIVE_ITERATOR_STATUS_OK) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, + "Late message could not be handled correctly: " + "lttng-live-msg-iter-addr=%p, " + "stream-name=\"%s\", " + "curr-msg-ts=%" PRId64 ", last-msg-ts=%" PRId64, + lttng_live_msg_iter, stream_iter->name->str, + curr_msg_ts_ns, lttng_live_msg_iter->last_msg_ts_ns); + stream_iter_status = LTTNG_LIVE_ITERATOR_STATUS_ERROR; + goto end; + } + } + } + + BT_ASSERT_DBG(stream_iter != youngest_candidate_stream_iter); + + if (!stream_iter_is_ended) { + if (G_UNLIKELY(youngest_candidate_stream_iter == NULL) || + stream_iter->current_msg_ts_ns < youngest_candidate_msg_ts) { + /* + * Update the current best candidate message + * for the stream iterator of this live trace + * to be forwarded downstream. + */ + youngest_candidate_msg_ts = stream_iter->current_msg_ts_ns; + youngest_candidate_stream_iter = stream_iter; + } else if (stream_iter->current_msg_ts_ns == youngest_candidate_msg_ts) { + /* + * Order the messages in an arbitrary but + * deterministic way. + */ + BT_ASSERT_DBG(stream_iter != youngest_candidate_stream_iter); + int ret = common_muxing_compare_messages( + stream_iter->current_msg, youngest_candidate_stream_iter->current_msg); + if (ret < 0) { + /* + * The `youngest_candidate_stream_iter->current_msg` + * should go first. Update the next + * iterator and the current timestamp. + */ + youngest_candidate_msg_ts = stream_iter->current_msg_ts_ns; + youngest_candidate_stream_iter = stream_iter; + } else if (ret == 0) { + /* + * Unable to pick which one should go + * first. + */ + BT_COMP_LOGW( + "Cannot deterministically pick next live stream message iterator because they have identical next messages: " + "stream-iter-addr=%p" + "stream-iter-addr=%p", + stream_iter, youngest_candidate_stream_iter); + } + } + + stream_iter_idx++; + } else { + /* + * The live stream iterator has ended. That + * iterator is removed from the array, but + * there is no need to increment + * stream_iter_idx as + * g_ptr_array_remove_index_fast replaces the + * removed element with the array's last + * element. + */ + g_ptr_array_remove_index_fast(live_trace->stream_iterators, stream_iter_idx); + } + } + + if (youngest_candidate_stream_iter) { + *youngest_trace_stream_iter = youngest_candidate_stream_iter; + stream_iter_status = LTTNG_LIVE_ITERATOR_STATUS_OK; + } else { + /* + * The only case where we don't have a candidate for this trace + * is if we reached the end of all the iterators. + */ + BT_ASSERT(live_trace->stream_iterators->len == 0); + stream_iter_status = LTTNG_LIVE_ITERATOR_STATUS_END; + } end: - return stream_iter_status; + return stream_iter_status; } -static -enum lttng_live_iterator_status next_stream_iterator_for_session( - struct lttng_live_msg_iter *lttng_live_msg_iter, - struct lttng_live_session *session, - struct lttng_live_stream_iterator **youngest_session_stream_iter) +static enum lttng_live_iterator_status +next_stream_iterator_for_session(struct lttng_live_msg_iter *lttng_live_msg_iter, + struct lttng_live_session *session, + struct lttng_live_stream_iterator **youngest_session_stream_iter) { - bt_self_component *self_comp = lttng_live_msg_iter->self_comp; - bt_logging_level log_level = lttng_live_msg_iter->log_level; - enum lttng_live_iterator_status stream_iter_status; - uint64_t trace_idx = 0; - int64_t youngest_candidate_msg_ts = INT64_MAX; - struct lttng_live_stream_iterator *youngest_candidate_stream_iter = NULL; - - BT_COMP_LOGD("Finding the next stream iterator for session: " - "session-id=%" PRIu64, session->id); - /* - * Make sure we are attached to the session and look for new streams - * and metadata. - */ - stream_iter_status = lttng_live_get_session(lttng_live_msg_iter, session); - if (stream_iter_status != LTTNG_LIVE_ITERATOR_STATUS_OK && - stream_iter_status != LTTNG_LIVE_ITERATOR_STATUS_CONTINUE && - stream_iter_status != LTTNG_LIVE_ITERATOR_STATUS_END) { - goto end; - } - - BT_ASSERT_DBG(session->traces); - - while (trace_idx < session->traces->len) { - bool trace_is_ended = false; - struct lttng_live_stream_iterator *stream_iter; - struct lttng_live_trace *trace = - (lttng_live_trace *) g_ptr_array_index(session->traces, trace_idx); - - stream_iter_status = next_stream_iterator_for_trace( - lttng_live_msg_iter, trace, &stream_iter); - if (stream_iter_status == LTTNG_LIVE_ITERATOR_STATUS_END) { - /* - * All the live stream iterators for this trace are - * ENDed. Remove the trace from this session. - */ - trace_is_ended = true; - } else if (stream_iter_status != LTTNG_LIVE_ITERATOR_STATUS_OK) { - goto end; - } - - if (!trace_is_ended) { - BT_ASSERT_DBG(stream_iter); - - if (G_UNLIKELY(youngest_candidate_stream_iter == NULL) || - stream_iter->current_msg_ts_ns < youngest_candidate_msg_ts) { - youngest_candidate_msg_ts = stream_iter->current_msg_ts_ns; - youngest_candidate_stream_iter = stream_iter; - } else if (stream_iter->current_msg_ts_ns == youngest_candidate_msg_ts) { - /* - * Order the messages in an arbitrary but - * deterministic way. - */ - int ret = common_muxing_compare_messages( - stream_iter->current_msg, - youngest_candidate_stream_iter->current_msg); - if (ret < 0) { - /* - * The `youngest_candidate_stream_iter->current_msg` - * should go first. Update the next iterator - * and the current timestamp. - */ - youngest_candidate_msg_ts = stream_iter->current_msg_ts_ns; - youngest_candidate_stream_iter = stream_iter; - } else if (ret == 0) { - /* Unable to pick which one should go first. */ - BT_COMP_LOGW("Cannot deterministically pick next live stream message iterator because they have identical next messages: " - "stream-iter-addr=%p" "stream-iter-addr=%p", - stream_iter, youngest_candidate_stream_iter); - } - } - trace_idx++; - } else { - /* - * trace_idx is not incremented since - * g_ptr_array_remove_index_fast replaces the - * element at trace_idx with the array's last element. - */ - g_ptr_array_remove_index_fast(session->traces, - trace_idx); - } - } - if (youngest_candidate_stream_iter) { - *youngest_session_stream_iter = youngest_candidate_stream_iter; - stream_iter_status = LTTNG_LIVE_ITERATOR_STATUS_OK; - } else { - /* - * The only cases where we don't have a candidate for this - * trace is: - * 1. if we reached the end of all the iterators of all the - * traces of this session, - * 2. if we never had live stream iterator in the first place. - * - * In either cases, we return END. - */ - BT_ASSERT(session->traces->len == 0); - stream_iter_status = LTTNG_LIVE_ITERATOR_STATUS_END; - } + bt_self_component *self_comp = lttng_live_msg_iter->self_comp; + bt_logging_level log_level = lttng_live_msg_iter->log_level; + enum lttng_live_iterator_status stream_iter_status; + uint64_t trace_idx = 0; + int64_t youngest_candidate_msg_ts = INT64_MAX; + struct lttng_live_stream_iterator *youngest_candidate_stream_iter = NULL; + + BT_COMP_LOGD("Finding the next stream iterator for session: " + "session-id=%" PRIu64, + session->id); + /* + * Make sure we are attached to the session and look for new streams + * and metadata. + */ + stream_iter_status = lttng_live_get_session(lttng_live_msg_iter, session); + if (stream_iter_status != LTTNG_LIVE_ITERATOR_STATUS_OK && + stream_iter_status != LTTNG_LIVE_ITERATOR_STATUS_CONTINUE && + stream_iter_status != LTTNG_LIVE_ITERATOR_STATUS_END) { + goto end; + } + + BT_ASSERT_DBG(session->traces); + + while (trace_idx < session->traces->len) { + bool trace_is_ended = false; + struct lttng_live_stream_iterator *stream_iter; + struct lttng_live_trace *trace = + (lttng_live_trace *) g_ptr_array_index(session->traces, trace_idx); + + stream_iter_status = + next_stream_iterator_for_trace(lttng_live_msg_iter, trace, &stream_iter); + if (stream_iter_status == LTTNG_LIVE_ITERATOR_STATUS_END) { + /* + * All the live stream iterators for this trace are + * ENDed. Remove the trace from this session. + */ + trace_is_ended = true; + } else if (stream_iter_status != LTTNG_LIVE_ITERATOR_STATUS_OK) { + goto end; + } + + if (!trace_is_ended) { + BT_ASSERT_DBG(stream_iter); + + if (G_UNLIKELY(youngest_candidate_stream_iter == NULL) || + stream_iter->current_msg_ts_ns < youngest_candidate_msg_ts) { + youngest_candidate_msg_ts = stream_iter->current_msg_ts_ns; + youngest_candidate_stream_iter = stream_iter; + } else if (stream_iter->current_msg_ts_ns == youngest_candidate_msg_ts) { + /* + * Order the messages in an arbitrary but + * deterministic way. + */ + int ret = common_muxing_compare_messages( + stream_iter->current_msg, youngest_candidate_stream_iter->current_msg); + if (ret < 0) { + /* + * The `youngest_candidate_stream_iter->current_msg` + * should go first. Update the next iterator + * and the current timestamp. + */ + youngest_candidate_msg_ts = stream_iter->current_msg_ts_ns; + youngest_candidate_stream_iter = stream_iter; + } else if (ret == 0) { + /* Unable to pick which one should go first. */ + BT_COMP_LOGW( + "Cannot deterministically pick next live stream message iterator because they have identical next messages: " + "stream-iter-addr=%p" + "stream-iter-addr=%p", + stream_iter, youngest_candidate_stream_iter); + } + } + trace_idx++; + } else { + /* + * trace_idx is not incremented since + * g_ptr_array_remove_index_fast replaces the + * element at trace_idx with the array's last element. + */ + g_ptr_array_remove_index_fast(session->traces, trace_idx); + } + } + if (youngest_candidate_stream_iter) { + *youngest_session_stream_iter = youngest_candidate_stream_iter; + stream_iter_status = LTTNG_LIVE_ITERATOR_STATUS_OK; + } else { + /* + * The only cases where we don't have a candidate for this + * trace is: + * 1. if we reached the end of all the iterators of all the + * traces of this session, + * 2. if we never had live stream iterator in the first place. + * + * In either cases, we return END. + */ + BT_ASSERT(session->traces->len == 0); + stream_iter_status = LTTNG_LIVE_ITERATOR_STATUS_END; + } end: - return stream_iter_status; + return stream_iter_status; } -static inline -void put_messages(bt_message_array_const msgs, uint64_t count) +static inline void put_messages(bt_message_array_const msgs, uint64_t count) { - uint64_t i; + uint64_t i; - for (i = 0; i < count; i++) { - BT_MESSAGE_PUT_REF_AND_RESET(msgs[i]); - } + for (i = 0; i < count; i++) { + BT_MESSAGE_PUT_REF_AND_RESET(msgs[i]); + } } BT_HIDDEN -bt_message_iterator_class_next_method_status lttng_live_msg_iter_next( - bt_self_message_iterator *self_msg_it, - bt_message_array_const msgs, uint64_t capacity, - uint64_t *count) +bt_message_iterator_class_next_method_status +lttng_live_msg_iter_next(bt_self_message_iterator *self_msg_it, bt_message_array_const msgs, + uint64_t capacity, uint64_t *count) { - bt_message_iterator_class_next_method_status status; - enum lttng_live_viewer_status viewer_status; - struct lttng_live_msg_iter *lttng_live_msg_iter = - (struct lttng_live_msg_iter *) bt_self_message_iterator_get_data(self_msg_it); - struct lttng_live_component *lttng_live = - lttng_live_msg_iter->lttng_live_comp; - bt_self_component *self_comp = lttng_live_msg_iter->self_comp; - bt_logging_level log_level = lttng_live_msg_iter->log_level; - enum lttng_live_iterator_status stream_iter_status; - uint64_t session_idx; - - *count = 0; - - BT_ASSERT_DBG(lttng_live_msg_iter); - - if (G_UNLIKELY(lttng_live_msg_iter->was_interrupted)) { - /* - * The iterator was interrupted in a previous call to the - * `_next()` method. We currently do not support generating - * messages after such event. The babeltrace2 CLI should never - * be running the graph after being interrupted. So this check - * is to prevent other graph users from using this live - * iterator in an messed up internal state. - */ - status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_ERROR; - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Message iterator was interrupted during a previous call to the `next()` and currently does not support continuing after such event."); - goto end; - } - - /* - * Clear all the invalid message reference that might be left over in - * the output array. - */ - memset(msgs, 0, capacity * sizeof(*msgs)); - - /* - * If no session are exposed on the relay found at the url provided by - * the user, session count will be 0. In this case, we return status - * end to return gracefully. - */ - if (lttng_live_msg_iter->sessions->len == 0) { - if (lttng_live->params.sess_not_found_act != - SESSION_NOT_FOUND_ACTION_CONTINUE) { - status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_END; - goto end; - } else { - /* - * The are no more active session for this session - * name. Retry to create a viewer session for the - * requested session name. - */ - viewer_status = lttng_live_create_viewer_session(lttng_live_msg_iter); - if (viewer_status != LTTNG_LIVE_VIEWER_STATUS_OK) { - if (viewer_status == LTTNG_LIVE_VIEWER_STATUS_ERROR) { - status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_ERROR; - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Error creating LTTng live viewer session"); - } else if (viewer_status == LTTNG_LIVE_VIEWER_STATUS_INTERRUPTED) { - status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_AGAIN; - } else { - bt_common_abort(); - } - goto end; - } - } - } - - if (lttng_live_msg_iter->active_stream_iter == 0) { - lttng_live_force_new_streams_and_metadata(lttng_live_msg_iter); - } - - /* - * Here the muxing of message is done. - * - * We need to iterate over all the streams of all the traces of all the - * viewer sessions in order to get the message with the smallest - * timestamp. In this case, a session is a viewer session and there is - * one viewer session per consumer daemon. (UST 32bit, UST 64bit and/or - * kernel). Each viewer session can have multiple traces, for example, - * 64bit UST viewer sessions could have multiple per-pid traces. - * - * We iterate over the streams of each traces to update and see what is - * their next message's timestamp. From those timestamps, we select the - * message with the smallest timestamp as the best candidate message - * for that trace and do the same thing across all the sessions. - * - * We then compare the timestamp of best candidate message of all the - * sessions to pick the message with the smallest timestamp and we - * return it. - */ - while (*count < capacity) { - struct lttng_live_stream_iterator *youngest_stream_iter = NULL, - *candidate_stream_iter = NULL; - int64_t youngest_msg_ts_ns = INT64_MAX; - - BT_ASSERT_DBG(lttng_live_msg_iter->sessions); - session_idx = 0; - while (session_idx < lttng_live_msg_iter->sessions->len) { - struct lttng_live_session *session = - (lttng_live_session *) g_ptr_array_index(lttng_live_msg_iter->sessions, - session_idx); - - /* Find the best candidate message to send downstream. */ - stream_iter_status = next_stream_iterator_for_session( - lttng_live_msg_iter, session, - &candidate_stream_iter); - - /* If we receive an END status, it means that either: - * - Those traces never had active streams (UST with no - * data produced yet), - * - All live stream iterators have ENDed.*/ - if (stream_iter_status == LTTNG_LIVE_ITERATOR_STATUS_END) { - if (session->closed && session->traces->len == 0) { - /* - * Remove the session from the list. - * session_idx is not modified since - * g_ptr_array_remove_index_fast - * replaces the the removed element with - * the array's last element. - */ - g_ptr_array_remove_index_fast( - lttng_live_msg_iter->sessions, - session_idx); - } else { - session_idx++; - } - continue; - } - - if (stream_iter_status != LTTNG_LIVE_ITERATOR_STATUS_OK) { - goto return_status; - } - - if (G_UNLIKELY(youngest_stream_iter == NULL) || - candidate_stream_iter->current_msg_ts_ns < youngest_msg_ts_ns) { - youngest_msg_ts_ns = candidate_stream_iter->current_msg_ts_ns; - youngest_stream_iter = candidate_stream_iter; - } else if (candidate_stream_iter->current_msg_ts_ns == youngest_msg_ts_ns) { - /* - * The currently selected message to be sent - * downstream next has the exact same timestamp - * that of the current candidate message. We - * must break the tie in a predictable manner. - */ - BT_COMP_LOGD_STR("Two of the next message candidates have the same timestamps, pick one deterministically."); - /* - * Order the messages in an arbitrary but - * deterministic way. - */ - int ret = common_muxing_compare_messages( - candidate_stream_iter->current_msg, - youngest_stream_iter->current_msg); - if (ret < 0) { - /* - * The `candidate_stream_iter->current_msg` - * should go first. Update the next - * iterator and the current timestamp. - */ - youngest_msg_ts_ns = candidate_stream_iter->current_msg_ts_ns; - youngest_stream_iter = candidate_stream_iter; - } else if (ret == 0) { - /* Unable to pick which one should go first. */ - BT_COMP_LOGW("Cannot deterministically pick next live stream message iterator because they have identical next messages: " - "next-stream-iter-addr=%p" "candidate-stream-iter-addr=%p", - youngest_stream_iter, candidate_stream_iter); - } - } - - session_idx++; - } - - if (!youngest_stream_iter) { - stream_iter_status = LTTNG_LIVE_ITERATOR_STATUS_AGAIN; - goto return_status; - } - - BT_ASSERT_DBG(youngest_stream_iter->current_msg); - /* Ensure monotonicity. */ - BT_ASSERT_DBG(lttng_live_msg_iter->last_msg_ts_ns <= - youngest_stream_iter->current_msg_ts_ns); - - /* - * Insert the next message to the message batch. This will set - * stream iterator current messsage to NULL so that next time - * we fetch the next message of that stream iterator - */ - BT_MESSAGE_MOVE_REF(msgs[*count], youngest_stream_iter->current_msg); - (*count)++; - - /* Update the last timestamp in nanoseconds sent downstream. */ - lttng_live_msg_iter->last_msg_ts_ns = youngest_msg_ts_ns; - youngest_stream_iter->current_msg_ts_ns = INT64_MAX; - - stream_iter_status = LTTNG_LIVE_ITERATOR_STATUS_OK; - } + bt_message_iterator_class_next_method_status status; + enum lttng_live_viewer_status viewer_status; + struct lttng_live_msg_iter *lttng_live_msg_iter = + (struct lttng_live_msg_iter *) bt_self_message_iterator_get_data(self_msg_it); + struct lttng_live_component *lttng_live = lttng_live_msg_iter->lttng_live_comp; + bt_self_component *self_comp = lttng_live_msg_iter->self_comp; + bt_logging_level log_level = lttng_live_msg_iter->log_level; + enum lttng_live_iterator_status stream_iter_status; + uint64_t session_idx; + + *count = 0; + + BT_ASSERT_DBG(lttng_live_msg_iter); + + if (G_UNLIKELY(lttng_live_msg_iter->was_interrupted)) { + /* + * The iterator was interrupted in a previous call to the + * `_next()` method. We currently do not support generating + * messages after such event. The babeltrace2 CLI should never + * be running the graph after being interrupted. So this check + * is to prevent other graph users from using this live + * iterator in an messed up internal state. + */ + status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_ERROR; + BT_COMP_LOGE_APPEND_CAUSE( + self_comp, + "Message iterator was interrupted during a previous call to the `next()` and currently does not support continuing after such event."); + goto end; + } + + /* + * Clear all the invalid message reference that might be left over in + * the output array. + */ + memset(msgs, 0, capacity * sizeof(*msgs)); + + /* + * If no session are exposed on the relay found at the url provided by + * the user, session count will be 0. In this case, we return status + * end to return gracefully. + */ + if (lttng_live_msg_iter->sessions->len == 0) { + if (lttng_live->params.sess_not_found_act != SESSION_NOT_FOUND_ACTION_CONTINUE) { + status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_END; + goto end; + } else { + /* + * The are no more active session for this session + * name. Retry to create a viewer session for the + * requested session name. + */ + viewer_status = lttng_live_create_viewer_session(lttng_live_msg_iter); + if (viewer_status != LTTNG_LIVE_VIEWER_STATUS_OK) { + if (viewer_status == LTTNG_LIVE_VIEWER_STATUS_ERROR) { + status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_ERROR; + BT_COMP_LOGE_APPEND_CAUSE(self_comp, + "Error creating LTTng live viewer session"); + } else if (viewer_status == LTTNG_LIVE_VIEWER_STATUS_INTERRUPTED) { + status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_AGAIN; + } else { + bt_common_abort(); + } + goto end; + } + } + } + + if (lttng_live_msg_iter->active_stream_iter == 0) { + lttng_live_force_new_streams_and_metadata(lttng_live_msg_iter); + } + + /* + * Here the muxing of message is done. + * + * We need to iterate over all the streams of all the traces of all the + * viewer sessions in order to get the message with the smallest + * timestamp. In this case, a session is a viewer session and there is + * one viewer session per consumer daemon. (UST 32bit, UST 64bit and/or + * kernel). Each viewer session can have multiple traces, for example, + * 64bit UST viewer sessions could have multiple per-pid traces. + * + * We iterate over the streams of each traces to update and see what is + * their next message's timestamp. From those timestamps, we select the + * message with the smallest timestamp as the best candidate message + * for that trace and do the same thing across all the sessions. + * + * We then compare the timestamp of best candidate message of all the + * sessions to pick the message with the smallest timestamp and we + * return it. + */ + while (*count < capacity) { + struct lttng_live_stream_iterator *youngest_stream_iter = NULL, + *candidate_stream_iter = NULL; + int64_t youngest_msg_ts_ns = INT64_MAX; + + BT_ASSERT_DBG(lttng_live_msg_iter->sessions); + session_idx = 0; + while (session_idx < lttng_live_msg_iter->sessions->len) { + struct lttng_live_session *session = (lttng_live_session *) g_ptr_array_index( + lttng_live_msg_iter->sessions, session_idx); + + /* Find the best candidate message to send downstream. */ + stream_iter_status = next_stream_iterator_for_session(lttng_live_msg_iter, session, + &candidate_stream_iter); + + /* If we receive an END status, it means that either: + * - Those traces never had active streams (UST with no + * data produced yet), + * - All live stream iterators have ENDed.*/ + if (stream_iter_status == LTTNG_LIVE_ITERATOR_STATUS_END) { + if (session->closed && session->traces->len == 0) { + /* + * Remove the session from the list. + * session_idx is not modified since + * g_ptr_array_remove_index_fast + * replaces the the removed element with + * the array's last element. + */ + g_ptr_array_remove_index_fast(lttng_live_msg_iter->sessions, session_idx); + } else { + session_idx++; + } + continue; + } + + if (stream_iter_status != LTTNG_LIVE_ITERATOR_STATUS_OK) { + goto return_status; + } + + if (G_UNLIKELY(youngest_stream_iter == NULL) || + candidate_stream_iter->current_msg_ts_ns < youngest_msg_ts_ns) { + youngest_msg_ts_ns = candidate_stream_iter->current_msg_ts_ns; + youngest_stream_iter = candidate_stream_iter; + } else if (candidate_stream_iter->current_msg_ts_ns == youngest_msg_ts_ns) { + /* + * The currently selected message to be sent + * downstream next has the exact same timestamp + * that of the current candidate message. We + * must break the tie in a predictable manner. + */ + BT_COMP_LOGD_STR( + "Two of the next message candidates have the same timestamps, pick one deterministically."); + /* + * Order the messages in an arbitrary but + * deterministic way. + */ + int ret = common_muxing_compare_messages(candidate_stream_iter->current_msg, + youngest_stream_iter->current_msg); + if (ret < 0) { + /* + * The `candidate_stream_iter->current_msg` + * should go first. Update the next + * iterator and the current timestamp. + */ + youngest_msg_ts_ns = candidate_stream_iter->current_msg_ts_ns; + youngest_stream_iter = candidate_stream_iter; + } else if (ret == 0) { + /* Unable to pick which one should go first. */ + BT_COMP_LOGW( + "Cannot deterministically pick next live stream message iterator because they have identical next messages: " + "next-stream-iter-addr=%p" + "candidate-stream-iter-addr=%p", + youngest_stream_iter, candidate_stream_iter); + } + } + + session_idx++; + } + + if (!youngest_stream_iter) { + stream_iter_status = LTTNG_LIVE_ITERATOR_STATUS_AGAIN; + goto return_status; + } + + BT_ASSERT_DBG(youngest_stream_iter->current_msg); + /* Ensure monotonicity. */ + BT_ASSERT_DBG(lttng_live_msg_iter->last_msg_ts_ns <= + youngest_stream_iter->current_msg_ts_ns); + + /* + * Insert the next message to the message batch. This will set + * stream iterator current messsage to NULL so that next time + * we fetch the next message of that stream iterator + */ + BT_MESSAGE_MOVE_REF(msgs[*count], youngest_stream_iter->current_msg); + (*count)++; + + /* Update the last timestamp in nanoseconds sent downstream. */ + lttng_live_msg_iter->last_msg_ts_ns = youngest_msg_ts_ns; + youngest_stream_iter->current_msg_ts_ns = INT64_MAX; + + stream_iter_status = LTTNG_LIVE_ITERATOR_STATUS_OK; + } return_status: - switch (stream_iter_status) { - case LTTNG_LIVE_ITERATOR_STATUS_OK: - case LTTNG_LIVE_ITERATOR_STATUS_AGAIN: - /* - * If we gathered messages, return _OK even if the graph was - * interrupted. This allows for the components downstream to at - * least get the thoses messages. If the graph was indeed - * interrupted there should not be another _next() call as the - * application will tear down the graph. This component class - * doesn't support restarting after an interruption. - */ - if (*count > 0) { - status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_OK; - } else { - status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_AGAIN; - } - break; - case LTTNG_LIVE_ITERATOR_STATUS_END: - status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_END; - break; - case LTTNG_LIVE_ITERATOR_STATUS_NOMEM: - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Memory error preparing the next batch of messages: " - "live-iter-status=%s", - lttng_live_iterator_status_string(stream_iter_status)); - status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_MEMORY_ERROR; - break; - case LTTNG_LIVE_ITERATOR_STATUS_ERROR: - case LTTNG_LIVE_ITERATOR_STATUS_INVAL: - case LTTNG_LIVE_ITERATOR_STATUS_UNSUPPORTED: - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Error preparing the next batch of messages: " - "live-iter-status=%s", - lttng_live_iterator_status_string(stream_iter_status)); - - status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_ERROR; - /* Put all existing messages on error. */ - put_messages(msgs, *count); - break; - default: - bt_common_abort(); - } + switch (stream_iter_status) { + case LTTNG_LIVE_ITERATOR_STATUS_OK: + case LTTNG_LIVE_ITERATOR_STATUS_AGAIN: + /* + * If we gathered messages, return _OK even if the graph was + * interrupted. This allows for the components downstream to at + * least get the thoses messages. If the graph was indeed + * interrupted there should not be another _next() call as the + * application will tear down the graph. This component class + * doesn't support restarting after an interruption. + */ + if (*count > 0) { + status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_OK; + } else { + status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_AGAIN; + } + break; + case LTTNG_LIVE_ITERATOR_STATUS_END: + status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_END; + break; + case LTTNG_LIVE_ITERATOR_STATUS_NOMEM: + BT_COMP_LOGE_APPEND_CAUSE(self_comp, + "Memory error preparing the next batch of messages: " + "live-iter-status=%s", + lttng_live_iterator_status_string(stream_iter_status)); + status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_MEMORY_ERROR; + break; + case LTTNG_LIVE_ITERATOR_STATUS_ERROR: + case LTTNG_LIVE_ITERATOR_STATUS_INVAL: + case LTTNG_LIVE_ITERATOR_STATUS_UNSUPPORTED: + BT_COMP_LOGE_APPEND_CAUSE(self_comp, + "Error preparing the next batch of messages: " + "live-iter-status=%s", + lttng_live_iterator_status_string(stream_iter_status)); + + status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_ERROR; + /* Put all existing messages on error. */ + put_messages(msgs, *count); + break; + default: + bt_common_abort(); + } end: - return status; + return status; } -static -struct lttng_live_msg_iter *lttng_live_msg_iter_create( - struct lttng_live_component *lttng_live_comp, - bt_self_message_iterator *self_msg_it) +static struct lttng_live_msg_iter * +lttng_live_msg_iter_create(struct lttng_live_component *lttng_live_comp, + bt_self_message_iterator *self_msg_it) { - bt_self_component *self_comp = lttng_live_comp->self_comp; - bt_logging_level log_level = lttng_live_comp->log_level; - - struct lttng_live_msg_iter *lttng_live_msg_iter = - g_new0(struct lttng_live_msg_iter, 1); - if (!lttng_live_msg_iter) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Failed to allocate lttng_live_msg_iter"); - goto end; - } - - lttng_live_msg_iter->log_level = lttng_live_comp->log_level; - lttng_live_msg_iter->self_comp = lttng_live_comp->self_comp; - lttng_live_msg_iter->lttng_live_comp = lttng_live_comp; - lttng_live_msg_iter->self_msg_iter = self_msg_it; - - lttng_live_msg_iter->active_stream_iter = 0; - lttng_live_msg_iter->last_msg_ts_ns = INT64_MIN; - lttng_live_msg_iter->was_interrupted = false; - - lttng_live_msg_iter->sessions = g_ptr_array_new_with_free_func( - (GDestroyNotify) lttng_live_destroy_session); - BT_ASSERT(lttng_live_msg_iter->sessions); + bt_self_component *self_comp = lttng_live_comp->self_comp; + bt_logging_level log_level = lttng_live_comp->log_level; -end: - return lttng_live_msg_iter; + struct lttng_live_msg_iter *lttng_live_msg_iter = g_new0(struct lttng_live_msg_iter, 1); + if (!lttng_live_msg_iter) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Failed to allocate lttng_live_msg_iter"); + goto end; + } + + lttng_live_msg_iter->log_level = lttng_live_comp->log_level; + lttng_live_msg_iter->self_comp = lttng_live_comp->self_comp; + lttng_live_msg_iter->lttng_live_comp = lttng_live_comp; + lttng_live_msg_iter->self_msg_iter = self_msg_it; + + lttng_live_msg_iter->active_stream_iter = 0; + lttng_live_msg_iter->last_msg_ts_ns = INT64_MIN; + lttng_live_msg_iter->was_interrupted = false; + lttng_live_msg_iter->sessions = + g_ptr_array_new_with_free_func((GDestroyNotify) lttng_live_destroy_session); + BT_ASSERT(lttng_live_msg_iter->sessions); + +end: + return lttng_live_msg_iter; } BT_HIDDEN -bt_message_iterator_class_initialize_method_status lttng_live_msg_iter_init( - bt_self_message_iterator *self_msg_it, - bt_self_message_iterator_configuration *config, - bt_self_component_port_output *self_port) +bt_message_iterator_class_initialize_method_status +lttng_live_msg_iter_init(bt_self_message_iterator *self_msg_it, + bt_self_message_iterator_configuration *config, + bt_self_component_port_output *self_port) { - bt_message_iterator_class_initialize_method_status status; - struct lttng_live_component *lttng_live; - struct lttng_live_msg_iter *lttng_live_msg_iter; - enum lttng_live_viewer_status viewer_status; - bt_logging_level log_level; - bt_self_component *self_comp = - bt_self_message_iterator_borrow_component(self_msg_it); - - lttng_live = (lttng_live_component *) bt_self_component_get_data(self_comp); - log_level = lttng_live->log_level; - self_comp = lttng_live->self_comp; - - - /* There can be only one downstream iterator at the same time. */ - BT_ASSERT(!lttng_live->has_msg_iter); - lttng_live->has_msg_iter = true; - - lttng_live_msg_iter = lttng_live_msg_iter_create(lttng_live, - self_msg_it); - if (!lttng_live_msg_iter) { - status = BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_MEMORY_ERROR; - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Failed to create lttng_live_msg_iter"); - goto error; - } - - viewer_status = live_viewer_connection_create(self_comp, NULL, - log_level, lttng_live->params.url->str, false, - lttng_live_msg_iter, <tng_live_msg_iter->viewer_connection); - if (viewer_status != LTTNG_LIVE_VIEWER_STATUS_OK) { - if (viewer_status == LTTNG_LIVE_VIEWER_STATUS_ERROR) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Failed to create viewer connection"); - } else if (viewer_status == LTTNG_LIVE_VIEWER_STATUS_INTERRUPTED) { - /* - * Interruption in the _iter_init() method is not - * supported. Return an error. - */ - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Interrupted while creating viewer connection"); - } - goto error; - } - - viewer_status = lttng_live_create_viewer_session(lttng_live_msg_iter); - if (viewer_status != LTTNG_LIVE_VIEWER_STATUS_OK) { - if (viewer_status == LTTNG_LIVE_VIEWER_STATUS_ERROR) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Failed to create viewer session"); - } else if (viewer_status == LTTNG_LIVE_VIEWER_STATUS_INTERRUPTED) { - /* - * Interruption in the _iter_init() method is not - * supported. Return an error. - */ - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Interrupted when creating viewer session"); - } - goto error; - } - - if (lttng_live_msg_iter->sessions->len == 0) { - switch (lttng_live->params.sess_not_found_act) { - case SESSION_NOT_FOUND_ACTION_CONTINUE: - BT_COMP_LOGI("Unable to connect to the requested live viewer session. Keep trying to connect because of " - "%s=\"%s\" component parameter: url=\"%s\"", - SESS_NOT_FOUND_ACTION_PARAM, - SESS_NOT_FOUND_ACTION_CONTINUE_STR, - lttng_live->params.url->str); - break; - case SESSION_NOT_FOUND_ACTION_FAIL: - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Unable to connect to the requested live viewer session. Fail the message iterator initialization because of %s=\"%s\" " - "component parameter: url =\"%s\"", - SESS_NOT_FOUND_ACTION_PARAM, - SESS_NOT_FOUND_ACTION_FAIL_STR, - lttng_live->params.url->str); - goto error; - case SESSION_NOT_FOUND_ACTION_END: - BT_COMP_LOGI("Unable to connect to the requested live viewer session. End gracefully at the first _next() " - "call because of %s=\"%s\" component parameter: " - "url=\"%s\"", SESS_NOT_FOUND_ACTION_PARAM, - SESS_NOT_FOUND_ACTION_END_STR, - lttng_live->params.url->str); - break; - default: - bt_common_abort(); - } - } - - bt_self_message_iterator_set_data(self_msg_it, lttng_live_msg_iter); - status = BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_OK; - goto end; + bt_message_iterator_class_initialize_method_status status; + struct lttng_live_component *lttng_live; + struct lttng_live_msg_iter *lttng_live_msg_iter; + enum lttng_live_viewer_status viewer_status; + bt_logging_level log_level; + bt_self_component *self_comp = bt_self_message_iterator_borrow_component(self_msg_it); + + lttng_live = (lttng_live_component *) bt_self_component_get_data(self_comp); + log_level = lttng_live->log_level; + self_comp = lttng_live->self_comp; + + /* There can be only one downstream iterator at the same time. */ + BT_ASSERT(!lttng_live->has_msg_iter); + lttng_live->has_msg_iter = true; + + lttng_live_msg_iter = lttng_live_msg_iter_create(lttng_live, self_msg_it); + if (!lttng_live_msg_iter) { + status = BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_MEMORY_ERROR; + BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Failed to create lttng_live_msg_iter"); + goto error; + } + + viewer_status = live_viewer_connection_create( + self_comp, NULL, log_level, lttng_live->params.url->str, false, lttng_live_msg_iter, + <tng_live_msg_iter->viewer_connection); + if (viewer_status != LTTNG_LIVE_VIEWER_STATUS_OK) { + if (viewer_status == LTTNG_LIVE_VIEWER_STATUS_ERROR) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Failed to create viewer connection"); + } else if (viewer_status == LTTNG_LIVE_VIEWER_STATUS_INTERRUPTED) { + /* + * Interruption in the _iter_init() method is not + * supported. Return an error. + */ + BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Interrupted while creating viewer connection"); + } + goto error; + } + + viewer_status = lttng_live_create_viewer_session(lttng_live_msg_iter); + if (viewer_status != LTTNG_LIVE_VIEWER_STATUS_OK) { + if (viewer_status == LTTNG_LIVE_VIEWER_STATUS_ERROR) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Failed to create viewer session"); + } else if (viewer_status == LTTNG_LIVE_VIEWER_STATUS_INTERRUPTED) { + /* + * Interruption in the _iter_init() method is not + * supported. Return an error. + */ + BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Interrupted when creating viewer session"); + } + goto error; + } + + if (lttng_live_msg_iter->sessions->len == 0) { + switch (lttng_live->params.sess_not_found_act) { + case SESSION_NOT_FOUND_ACTION_CONTINUE: + BT_COMP_LOGI( + "Unable to connect to the requested live viewer session. Keep trying to connect because of " + "%s=\"%s\" component parameter: url=\"%s\"", + SESS_NOT_FOUND_ACTION_PARAM, SESS_NOT_FOUND_ACTION_CONTINUE_STR, + lttng_live->params.url->str); + break; + case SESSION_NOT_FOUND_ACTION_FAIL: + BT_COMP_LOGE_APPEND_CAUSE( + self_comp, + "Unable to connect to the requested live viewer session. Fail the message iterator initialization because of %s=\"%s\" " + "component parameter: url =\"%s\"", + SESS_NOT_FOUND_ACTION_PARAM, SESS_NOT_FOUND_ACTION_FAIL_STR, + lttng_live->params.url->str); + goto error; + case SESSION_NOT_FOUND_ACTION_END: + BT_COMP_LOGI( + "Unable to connect to the requested live viewer session. End gracefully at the first _next() " + "call because of %s=\"%s\" component parameter: " + "url=\"%s\"", + SESS_NOT_FOUND_ACTION_PARAM, SESS_NOT_FOUND_ACTION_END_STR, + lttng_live->params.url->str); + break; + default: + bt_common_abort(); + } + } + + bt_self_message_iterator_set_data(self_msg_it, lttng_live_msg_iter); + status = BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_OK; + goto end; error: - status = BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_ERROR; - lttng_live_msg_iter_destroy(lttng_live_msg_iter); + status = BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_ERROR; + lttng_live_msg_iter_destroy(lttng_live_msg_iter); end: - return status; + return status; } static struct bt_param_validation_map_value_entry_descr list_sessions_params[] = { - { URL_PARAM, BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_MANDATORY, - { bt_param_validation_value_descr::string_t } }, - BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_END -}; - -static -bt_component_class_query_method_status lttng_live_query_list_sessions( - const bt_value *params, const bt_value **result, - bt_self_component_class *self_comp_class, - bt_logging_level log_level) + {URL_PARAM, + BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_MANDATORY, + {bt_param_validation_value_descr::string_t}}, + BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_END}; + +static bt_component_class_query_method_status +lttng_live_query_list_sessions(const bt_value *params, const bt_value **result, + bt_self_component_class *self_comp_class, bt_logging_level log_level) { - bt_component_class_query_method_status status; - const bt_value *url_value = NULL; - const char *url; - struct live_viewer_connection *viewer_connection = NULL; - enum lttng_live_viewer_status viewer_status; - enum bt_param_validation_status validation_status; - gchar *validate_error = NULL; - - validation_status = bt_param_validation_validate(params, - list_sessions_params, &validate_error); - if (validation_status == BT_PARAM_VALIDATION_STATUS_MEMORY_ERROR) { - status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_MEMORY_ERROR; - goto error; - } else if (validation_status == BT_PARAM_VALIDATION_STATUS_VALIDATION_ERROR) { - status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; - BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, "%s", - validate_error); - goto error; - } - - url_value = bt_value_map_borrow_entry_value_const(params, URL_PARAM); - url = bt_value_string_get(url_value); - - viewer_status = live_viewer_connection_create(NULL, self_comp_class, - log_level, url, true, NULL, &viewer_connection); - if (viewer_status != LTTNG_LIVE_VIEWER_STATUS_OK) { - if (viewer_status == LTTNG_LIVE_VIEWER_STATUS_ERROR) { - BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, - "Failed to create viewer connection"); - status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; - } else if (viewer_status == LTTNG_LIVE_VIEWER_STATUS_INTERRUPTED) { - status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_AGAIN; - } else { - bt_common_abort(); - } - goto error; - } - - status = live_viewer_connection_list_sessions(viewer_connection, - result); - if (status != BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_OK) { - BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, - "Failed to list viewer sessions"); - goto error; - } - - goto end; + bt_component_class_query_method_status status; + const bt_value *url_value = NULL; + const char *url; + struct live_viewer_connection *viewer_connection = NULL; + enum lttng_live_viewer_status viewer_status; + enum bt_param_validation_status validation_status; + gchar *validate_error = NULL; + + validation_status = bt_param_validation_validate(params, list_sessions_params, &validate_error); + if (validation_status == BT_PARAM_VALIDATION_STATUS_MEMORY_ERROR) { + status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_MEMORY_ERROR; + goto error; + } else if (validation_status == BT_PARAM_VALIDATION_STATUS_VALIDATION_ERROR) { + status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; + BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, "%s", validate_error); + goto error; + } + + url_value = bt_value_map_borrow_entry_value_const(params, URL_PARAM); + url = bt_value_string_get(url_value); + + viewer_status = live_viewer_connection_create(NULL, self_comp_class, log_level, url, true, NULL, + &viewer_connection); + if (viewer_status != LTTNG_LIVE_VIEWER_STATUS_OK) { + if (viewer_status == LTTNG_LIVE_VIEWER_STATUS_ERROR) { + BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, "Failed to create viewer connection"); + status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; + } else if (viewer_status == LTTNG_LIVE_VIEWER_STATUS_INTERRUPTED) { + status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_AGAIN; + } else { + bt_common_abort(); + } + goto error; + } + + status = live_viewer_connection_list_sessions(viewer_connection, result); + if (status != BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_OK) { + BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, "Failed to list viewer sessions"); + goto error; + } + + goto end; error: - BT_VALUE_PUT_REF_AND_RESET(*result); + BT_VALUE_PUT_REF_AND_RESET(*result); - if (status >= 0) { - status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; - } + if (status >= 0) { + status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; + } end: - if (viewer_connection) { - live_viewer_connection_destroy(viewer_connection); - } + if (viewer_connection) { + live_viewer_connection_destroy(viewer_connection); + } - g_free(validate_error); + g_free(validate_error); - return status; + return status; } -static -bt_component_class_query_method_status lttng_live_query_support_info( - const bt_value *params, const bt_value **result, - bt_self_component_class *self_comp_class, - bt_logging_level log_level) +static bt_component_class_query_method_status +lttng_live_query_support_info(const bt_value *params, const bt_value **result, + bt_self_component_class *self_comp_class, bt_logging_level log_level) { - bt_component_class_query_method_status status = - BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_OK; - const bt_value *input_type_value; - const bt_value *input_value; - double weight = 0; - struct bt_common_lttng_live_url_parts parts = { 0 }; - - /* Used by the logging macros */ - __attribute__((unused)) bt_self_component *self_comp = NULL; - - *result = NULL; - input_type_value = bt_value_map_borrow_entry_value_const(params, - "type"); - if (!input_type_value) { - BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, - "Missing expected `type` parameter."); - goto error; - } - - if (!bt_value_is_string(input_type_value)) { - BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, - "`type` parameter is not a string value."); - goto error; - } - - if (strcmp(bt_value_string_get(input_type_value), "string") != 0) { - /* We don't handle file system paths */ - goto create_result; - } - - input_value = bt_value_map_borrow_entry_value_const(params, "input"); - if (!input_value) { - BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, - "Missing expected `input` parameter."); - goto error; - } - - if (!bt_value_is_string(input_value)) { - BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, - "`input` parameter is not a string value."); - goto error; - } - - parts = bt_common_parse_lttng_live_url(bt_value_string_get(input_value), - NULL, 0); - if (parts.session_name) { - /* - * Looks pretty much like an LTTng live URL: we got the - * session name part, which forms a complete URL. - */ - weight = .75; - } + bt_component_class_query_method_status status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_OK; + const bt_value *input_type_value; + const bt_value *input_value; + double weight = 0; + struct bt_common_lttng_live_url_parts parts = {0}; + + /* Used by the logging macros */ + __attribute__((unused)) bt_self_component *self_comp = NULL; + + *result = NULL; + input_type_value = bt_value_map_borrow_entry_value_const(params, "type"); + if (!input_type_value) { + BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, "Missing expected `type` parameter."); + goto error; + } + + if (!bt_value_is_string(input_type_value)) { + BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, "`type` parameter is not a string value."); + goto error; + } + + if (strcmp(bt_value_string_get(input_type_value), "string") != 0) { + /* We don't handle file system paths */ + goto create_result; + } + + input_value = bt_value_map_borrow_entry_value_const(params, "input"); + if (!input_value) { + BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, "Missing expected `input` parameter."); + goto error; + } + + if (!bt_value_is_string(input_value)) { + BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, + "`input` parameter is not a string value."); + goto error; + } + + parts = bt_common_parse_lttng_live_url(bt_value_string_get(input_value), NULL, 0); + if (parts.session_name) { + /* + * Looks pretty much like an LTTng live URL: we got the + * session name part, which forms a complete URL. + */ + weight = .75; + } create_result: - *result = bt_value_real_create_init(weight); - if (!*result) { - status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_MEMORY_ERROR; - goto error; - } + *result = bt_value_real_create_init(weight); + if (!*result) { + status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_MEMORY_ERROR; + goto error; + } - goto end; + goto end; error: - if (status >= 0) { - status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; - } + if (status >= 0) { + status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; + } - BT_ASSERT(!*result); + BT_ASSERT(!*result); end: - bt_common_destroy_lttng_live_url_parts(&parts); - return status; + bt_common_destroy_lttng_live_url_parts(&parts); + return status; } BT_HIDDEN -bt_component_class_query_method_status lttng_live_query( - bt_self_component_class_source *comp_class, - bt_private_query_executor *priv_query_exec, - const char *object, const bt_value *params, - __attribute__((unused)) void *method_data, - const bt_value **result) +bt_component_class_query_method_status lttng_live_query(bt_self_component_class_source *comp_class, + bt_private_query_executor *priv_query_exec, + const char *object, const bt_value *params, + __attribute__((unused)) void *method_data, + const bt_value **result) { - bt_component_class_query_method_status status = - BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_OK; - bt_self_component *self_comp = NULL; - bt_self_component_class *self_comp_class = - bt_self_component_class_source_as_self_component_class(comp_class); - bt_logging_level log_level = bt_query_executor_get_logging_level( - bt_private_query_executor_as_query_executor_const( - priv_query_exec)); - - if (strcmp(object, "sessions") == 0) { - status = lttng_live_query_list_sessions(params, result, - self_comp_class, log_level); - } else if (strcmp(object, "babeltrace.support-info") == 0) { - status = lttng_live_query_support_info(params, result, - self_comp_class, log_level); - } else { - BT_COMP_LOGI("Unknown query object `%s`", object); - status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_UNKNOWN_OBJECT; - goto end; - } + bt_component_class_query_method_status status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_OK; + bt_self_component *self_comp = NULL; + bt_self_component_class *self_comp_class = + bt_self_component_class_source_as_self_component_class(comp_class); + bt_logging_level log_level = bt_query_executor_get_logging_level( + bt_private_query_executor_as_query_executor_const(priv_query_exec)); + + if (strcmp(object, "sessions") == 0) { + status = lttng_live_query_list_sessions(params, result, self_comp_class, log_level); + } else if (strcmp(object, "babeltrace.support-info") == 0) { + status = lttng_live_query_support_info(params, result, self_comp_class, log_level); + } else { + BT_COMP_LOGI("Unknown query object `%s`", object); + status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_UNKNOWN_OBJECT; + goto end; + } end: - return status; + return status; } -static -void lttng_live_component_destroy_data(struct lttng_live_component *lttng_live) +static void lttng_live_component_destroy_data(struct lttng_live_component *lttng_live) { - if (!lttng_live) { - return; - } - if (lttng_live->params.url) { - g_string_free(lttng_live->params.url, TRUE); - } - g_free(lttng_live); + if (!lttng_live) { + return; + } + if (lttng_live->params.url) { + g_string_free(lttng_live->params.url, TRUE); + } + g_free(lttng_live); } BT_HIDDEN void lttng_live_component_finalize(bt_self_component_source *component) { - lttng_live_component *data = - (lttng_live_component *) bt_self_component_get_data( - bt_self_component_source_as_self_component(component)); - - if (!data) { - return; - } - lttng_live_component_destroy_data(data); + lttng_live_component *data = (lttng_live_component *) bt_self_component_get_data( + bt_self_component_source_as_self_component(component)); + + if (!data) { + return; + } + lttng_live_component_destroy_data(data); } -static -enum session_not_found_action parse_session_not_found_action_param( - const bt_value *no_session_param) +static enum session_not_found_action +parse_session_not_found_action_param(const bt_value *no_session_param) { - enum session_not_found_action action; - const char *no_session_act_str = bt_value_string_get(no_session_param); - - if (strcmp(no_session_act_str, SESS_NOT_FOUND_ACTION_CONTINUE_STR) == 0) { - action = SESSION_NOT_FOUND_ACTION_CONTINUE; - } else if (strcmp(no_session_act_str, SESS_NOT_FOUND_ACTION_FAIL_STR) == 0) { - action = SESSION_NOT_FOUND_ACTION_FAIL; - } else { - BT_ASSERT(strcmp(no_session_act_str, SESS_NOT_FOUND_ACTION_END_STR) == 0); - action = SESSION_NOT_FOUND_ACTION_END; - } - - return action; + enum session_not_found_action action; + const char *no_session_act_str = bt_value_string_get(no_session_param); + + if (strcmp(no_session_act_str, SESS_NOT_FOUND_ACTION_CONTINUE_STR) == 0) { + action = SESSION_NOT_FOUND_ACTION_CONTINUE; + } else if (strcmp(no_session_act_str, SESS_NOT_FOUND_ACTION_FAIL_STR) == 0) { + action = SESSION_NOT_FOUND_ACTION_FAIL; + } else { + BT_ASSERT(strcmp(no_session_act_str, SESS_NOT_FOUND_ACTION_END_STR) == 0); + action = SESSION_NOT_FOUND_ACTION_END; + } + + return action; } -static bt_param_validation_value_descr inputs_elem_descr{ - bt_param_validation_value_descr::string_t, +static bt_param_validation_value_descr inputs_elem_descr { + bt_param_validation_value_descr::string_t, }; static const char *sess_not_found_action_choices[] = { - SESS_NOT_FOUND_ACTION_CONTINUE_STR, - SESS_NOT_FOUND_ACTION_FAIL_STR, - SESS_NOT_FOUND_ACTION_END_STR, + SESS_NOT_FOUND_ACTION_CONTINUE_STR, + SESS_NOT_FOUND_ACTION_FAIL_STR, + SESS_NOT_FOUND_ACTION_END_STR, }; static struct bt_param_validation_map_value_entry_descr params_descr[] = { - { INPUTS_PARAM, BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_MANDATORY, - { bt_param_validation_value_descr::array_t, - 1, 1, inputs_elem_descr } }, - { SESS_NOT_FOUND_ACTION_PARAM, BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_OPTIONAL, - { bt_param_validation_value_descr::string_t, - sess_not_found_action_choices } }, - BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_END -}; - -static -bt_component_class_initialize_method_status lttng_live_component_create( - const bt_value *params, - bt_logging_level log_level, - bt_self_component *self_comp, - struct lttng_live_component **component) + {INPUTS_PARAM, + BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_MANDATORY, + {bt_param_validation_value_descr::array_t, 1, 1, inputs_elem_descr}}, + {SESS_NOT_FOUND_ACTION_PARAM, + BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_OPTIONAL, + {bt_param_validation_value_descr::string_t, sess_not_found_action_choices}}, + BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_END}; + +static bt_component_class_initialize_method_status +lttng_live_component_create(const bt_value *params, bt_logging_level log_level, + bt_self_component *self_comp, struct lttng_live_component **component) { - struct lttng_live_component *lttng_live = NULL; - const bt_value *inputs_value; - const bt_value *url_value; - const bt_value *value; - const char *url; - enum bt_param_validation_status validation_status; - gchar *validation_error = NULL; - bt_component_class_initialize_method_status status; - - validation_status = bt_param_validation_validate(params, params_descr, - &validation_error); - if (validation_status == BT_PARAM_VALIDATION_STATUS_MEMORY_ERROR) { - status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_MEMORY_ERROR; - goto error; - } else if (validation_status == BT_PARAM_VALIDATION_STATUS_VALIDATION_ERROR) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, "%s", validation_error); - status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_ERROR; - goto error; - } - - lttng_live = g_new0(struct lttng_live_component, 1); - if (!lttng_live) { - status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_MEMORY_ERROR; - goto end; - } - lttng_live->log_level = log_level; - lttng_live->self_comp = self_comp; - lttng_live->max_query_size = MAX_QUERY_SIZE; - lttng_live->has_msg_iter = false; - - inputs_value = - bt_value_map_borrow_entry_value_const(params, INPUTS_PARAM); - url_value = - bt_value_array_borrow_element_by_index_const(inputs_value, 0); - url = bt_value_string_get(url_value); - - lttng_live->params.url = g_string_new(url); - if (!lttng_live->params.url) { - status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_MEMORY_ERROR; - goto error; - } - - value = bt_value_map_borrow_entry_value_const(params, - SESS_NOT_FOUND_ACTION_PARAM); - if (value) { - lttng_live->params.sess_not_found_act = - parse_session_not_found_action_param(value); - } else { - BT_COMP_LOGI("Optional `%s` parameter is missing: " - "defaulting to `%s`.", - SESS_NOT_FOUND_ACTION_PARAM, - SESS_NOT_FOUND_ACTION_CONTINUE_STR); - lttng_live->params.sess_not_found_act = - SESSION_NOT_FOUND_ACTION_CONTINUE; - } - - status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK; - goto end; + struct lttng_live_component *lttng_live = NULL; + const bt_value *inputs_value; + const bt_value *url_value; + const bt_value *value; + const char *url; + enum bt_param_validation_status validation_status; + gchar *validation_error = NULL; + bt_component_class_initialize_method_status status; + + validation_status = bt_param_validation_validate(params, params_descr, &validation_error); + if (validation_status == BT_PARAM_VALIDATION_STATUS_MEMORY_ERROR) { + status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_MEMORY_ERROR; + goto error; + } else if (validation_status == BT_PARAM_VALIDATION_STATUS_VALIDATION_ERROR) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, "%s", validation_error); + status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_ERROR; + goto error; + } + + lttng_live = g_new0(struct lttng_live_component, 1); + if (!lttng_live) { + status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_MEMORY_ERROR; + goto end; + } + lttng_live->log_level = log_level; + lttng_live->self_comp = self_comp; + lttng_live->max_query_size = MAX_QUERY_SIZE; + lttng_live->has_msg_iter = false; + + inputs_value = bt_value_map_borrow_entry_value_const(params, INPUTS_PARAM); + url_value = bt_value_array_borrow_element_by_index_const(inputs_value, 0); + url = bt_value_string_get(url_value); + + lttng_live->params.url = g_string_new(url); + if (!lttng_live->params.url) { + status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_MEMORY_ERROR; + goto error; + } + + value = bt_value_map_borrow_entry_value_const(params, SESS_NOT_FOUND_ACTION_PARAM); + if (value) { + lttng_live->params.sess_not_found_act = parse_session_not_found_action_param(value); + } else { + BT_COMP_LOGI("Optional `%s` parameter is missing: " + "defaulting to `%s`.", + SESS_NOT_FOUND_ACTION_PARAM, SESS_NOT_FOUND_ACTION_CONTINUE_STR); + lttng_live->params.sess_not_found_act = SESSION_NOT_FOUND_ACTION_CONTINUE; + } + + status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK; + goto end; error: - lttng_live_component_destroy_data(lttng_live); - lttng_live = NULL; + lttng_live_component_destroy_data(lttng_live); + lttng_live = NULL; end: - g_free(validation_error); + g_free(validation_error); - *component = lttng_live; - return status; + *component = lttng_live; + return status; } BT_HIDDEN -bt_component_class_initialize_method_status lttng_live_component_init( - bt_self_component_source *self_comp_src, - bt_self_component_source_configuration *config, - const bt_value *params, - __attribute__((unused)) void *init_method_data) +bt_component_class_initialize_method_status +lttng_live_component_init(bt_self_component_source *self_comp_src, + bt_self_component_source_configuration *config, const bt_value *params, + __attribute__((unused)) void *init_method_data) { - struct lttng_live_component *lttng_live; - bt_component_class_initialize_method_status ret; - bt_self_component *self_comp = - bt_self_component_source_as_self_component(self_comp_src); - bt_logging_level log_level = bt_component_get_logging_level( - bt_self_component_as_component(self_comp)); - bt_self_component_add_port_status add_port_status; - - ret = lttng_live_component_create(params, log_level, self_comp, <tng_live); - if (ret != BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK) { - goto error; - } - - add_port_status = bt_self_component_source_add_output_port( - self_comp_src, "out", NULL, NULL); - if (add_port_status != BT_SELF_COMPONENT_ADD_PORT_STATUS_OK) { - ret = (bt_component_class_initialize_method_status) add_port_status; - goto end; - } - - bt_self_component_set_data(self_comp, lttng_live); - goto end; + struct lttng_live_component *lttng_live; + bt_component_class_initialize_method_status ret; + bt_self_component *self_comp = bt_self_component_source_as_self_component(self_comp_src); + bt_logging_level log_level = + bt_component_get_logging_level(bt_self_component_as_component(self_comp)); + bt_self_component_add_port_status add_port_status; + + ret = lttng_live_component_create(params, log_level, self_comp, <tng_live); + if (ret != BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK) { + goto error; + } + + add_port_status = bt_self_component_source_add_output_port(self_comp_src, "out", NULL, NULL); + if (add_port_status != BT_SELF_COMPONENT_ADD_PORT_STATUS_OK) { + ret = (bt_component_class_initialize_method_status) add_port_status; + goto end; + } + + bt_self_component_set_data(self_comp, lttng_live); + goto end; error: - lttng_live_component_destroy_data(lttng_live); - lttng_live = NULL; + lttng_live_component_destroy_data(lttng_live); + lttng_live = NULL; end: - return ret; + return ret; } diff --git a/src/plugins/ctf/lttng-live/lttng-live.hpp b/src/plugins/ctf/lttng-live/lttng-live.hpp index c965b8c7..4a4faf41 100644 --- a/src/plugins/ctf/lttng-live/lttng-live.hpp +++ b/src/plugins/ctf/lttng-live/lttng-live.hpp @@ -27,290 +27,298 @@ struct lttng_live_component; struct lttng_live_session; struct lttng_live_msg_iter; -enum lttng_live_stream_state { - /* This stream won't have data until some known time in the future. */ - LTTNG_LIVE_STREAM_QUIESCENT, - /* - * This stream won't have data until some known time in the future and - * the message iterator inactivity message was already sent downstream. - */ - LTTNG_LIVE_STREAM_QUIESCENT_NO_DATA, /* */ - /* This stream has data ready to be consumed. */ - LTTNG_LIVE_STREAM_ACTIVE_DATA, - /* - * This stream has no data left to consume. We should asked the relay - * for more. - */ - LTTNG_LIVE_STREAM_ACTIVE_NO_DATA, - /* This stream won't have anymore data, ever. */ - LTTNG_LIVE_STREAM_EOF, +enum lttng_live_stream_state +{ + /* This stream won't have data until some known time in the future. */ + LTTNG_LIVE_STREAM_QUIESCENT, + /* + * This stream won't have data until some known time in the future and + * the message iterator inactivity message was already sent downstream. + */ + LTTNG_LIVE_STREAM_QUIESCENT_NO_DATA, /* */ + /* This stream has data ready to be consumed. */ + LTTNG_LIVE_STREAM_ACTIVE_DATA, + /* + * This stream has no data left to consume. We should asked the relay + * for more. + */ + LTTNG_LIVE_STREAM_ACTIVE_NO_DATA, + /* This stream won't have anymore data, ever. */ + LTTNG_LIVE_STREAM_EOF, }; /* Iterator over a live stream. */ -struct lttng_live_stream_iterator { - bt_logging_level log_level; - bt_self_component *self_comp; - - /* Owned by this. */ - bt_stream *stream; - - /* Weak reference. */ - struct lttng_live_trace *trace; - - /* - * Since only a single iterator per viewer connection, we have - * only a single message iterator per stream. - */ - struct ctf_msg_iter *msg_iter; - - uint64_t viewer_stream_id; - - struct { - bool is_set; - uint64_t value; - } ctf_stream_class_id; - - /* base offset in current index. */ - uint64_t base_offset; - /* len to read in current index. */ - uint64_t len; - /* offset in current index. */ - uint64_t offset; - - /* - * Clock Snapshot value of the last message iterator inactivity message - * sent downstream. - */ - struct { - bool is_set; - uint64_t value; - } last_inactivity_ts; - - /* - * Clock Snapshot value of the current message iterator inactivity - * message we might want to send downstream. - */ - uint64_t current_inactivity_ts; - - enum lttng_live_stream_state state; - - /* - * The current message produced by this live stream iterator. Owned by - * this. - */ - const bt_message *current_msg; - - /* Timestamp in nanoseconds of the current message (current_msg). */ - int64_t current_msg_ts_ns; - - /* Owned by this. */ - uint8_t *buf; - size_t buflen; - - /* Owned by this. */ - GString *name; - - bool has_stream_hung_up; +struct lttng_live_stream_iterator +{ + bt_logging_level log_level; + bt_self_component *self_comp; + + /* Owned by this. */ + bt_stream *stream; + + /* Weak reference. */ + struct lttng_live_trace *trace; + + /* + * Since only a single iterator per viewer connection, we have + * only a single message iterator per stream. + */ + struct ctf_msg_iter *msg_iter; + + uint64_t viewer_stream_id; + + struct + { + bool is_set; + uint64_t value; + } ctf_stream_class_id; + + /* base offset in current index. */ + uint64_t base_offset; + /* len to read in current index. */ + uint64_t len; + /* offset in current index. */ + uint64_t offset; + + /* + * Clock Snapshot value of the last message iterator inactivity message + * sent downstream. + */ + struct + { + bool is_set; + uint64_t value; + } last_inactivity_ts; + + /* + * Clock Snapshot value of the current message iterator inactivity + * message we might want to send downstream. + */ + uint64_t current_inactivity_ts; + + enum lttng_live_stream_state state; + + /* + * The current message produced by this live stream iterator. Owned by + * this. + */ + const bt_message *current_msg; + + /* Timestamp in nanoseconds of the current message (current_msg). */ + int64_t current_msg_ts_ns; + + /* Owned by this. */ + uint8_t *buf; + size_t buflen; + + /* Owned by this. */ + GString *name; + + bool has_stream_hung_up; }; -struct lttng_live_metadata { - bt_logging_level log_level; - bt_self_component *self_comp; +struct lttng_live_metadata +{ + bt_logging_level log_level; + bt_self_component *self_comp; - uint64_t stream_id; - /* Weak reference. */ - struct ctf_metadata_decoder *decoder; + uint64_t stream_id; + /* Weak reference. */ + struct ctf_metadata_decoder *decoder; }; -enum lttng_live_metadata_stream_state { - /* - * The metadata needs to be updated. This is either because we just - * created the trace and haven't asked yet, or the relay specifically - * told us that new metadata is available. - */ - LTTNG_LIVE_METADATA_STREAM_STATE_NEEDED, - /* - * The metadata was updated and the relay has not told us we need to - * update it yet. - */ - LTTNG_LIVE_METADATA_STREAM_STATE_NOT_NEEDED, - /* - * The relay has closed this metadata stream. We set this in reaction - * to a LTTNG_VIEWER_METADATA_ERR reply to a LTTNG_VIEWER_GET_METADATA - * command to the relay. If this field is set, we have received all the - * metadata that we are ever going to get for that metadata stream. - */ - LTTNG_LIVE_METADATA_STREAM_STATE_CLOSED, +enum lttng_live_metadata_stream_state +{ + /* + * The metadata needs to be updated. This is either because we just + * created the trace and haven't asked yet, or the relay specifically + * told us that new metadata is available. + */ + LTTNG_LIVE_METADATA_STREAM_STATE_NEEDED, + /* + * The metadata was updated and the relay has not told us we need to + * update it yet. + */ + LTTNG_LIVE_METADATA_STREAM_STATE_NOT_NEEDED, + /* + * The relay has closed this metadata stream. We set this in reaction + * to a LTTNG_VIEWER_METADATA_ERR reply to a LTTNG_VIEWER_GET_METADATA + * command to the relay. If this field is set, we have received all the + * metadata that we are ever going to get for that metadata stream. + */ + LTTNG_LIVE_METADATA_STREAM_STATE_CLOSED, }; -struct lttng_live_trace { - bt_logging_level log_level; - bt_self_component *self_comp; +struct lttng_live_trace +{ + bt_logging_level log_level; + bt_self_component *self_comp; - /* Back reference to session. */ - struct lttng_live_session *session; + /* Back reference to session. */ + struct lttng_live_session *session; - /* ctf trace ID within the session. */ - uint64_t id; + /* ctf trace ID within the session. */ + uint64_t id; - /* Owned by this. */ - bt_trace *trace; + /* Owned by this. */ + bt_trace *trace; - /* Weak reference. */ - bt_trace_class *trace_class; + /* Weak reference. */ + bt_trace_class *trace_class; - struct lttng_live_metadata *metadata; + struct lttng_live_metadata *metadata; - const bt_clock_class *clock_class; + const bt_clock_class *clock_class; - /* Array of pointers to struct lttng_live_stream_iterator. */ - /* Owned by this. */ - GPtrArray *stream_iterators; + /* Array of pointers to struct lttng_live_stream_iterator. */ + /* Owned by this. */ + GPtrArray *stream_iterators; - enum lttng_live_metadata_stream_state metadata_stream_state; + enum lttng_live_metadata_stream_state metadata_stream_state; }; -struct lttng_live_session { - bt_logging_level log_level; - bt_self_component *self_comp; +struct lttng_live_session +{ + bt_logging_level log_level; + bt_self_component *self_comp; - /* Weak reference. */ - struct lttng_live_msg_iter *lttng_live_msg_iter; + /* Weak reference. */ + struct lttng_live_msg_iter *lttng_live_msg_iter; - /* Owned by this. */ - GString *hostname; + /* Owned by this. */ + GString *hostname; - /* Owned by this. */ - GString *session_name; + /* Owned by this. */ + GString *session_name; - uint64_t id; + uint64_t id; - /* Array of pointers to struct lttng_live_trace. */ - GPtrArray *traces; + /* Array of pointers to struct lttng_live_trace. */ + GPtrArray *traces; - bool attached; - bool new_streams_needed; - bool lazy_stream_msg_init; - bool closed; + bool attached; + bool new_streams_needed; + bool lazy_stream_msg_init; + bool closed; }; -enum session_not_found_action { - SESSION_NOT_FOUND_ACTION_CONTINUE, - SESSION_NOT_FOUND_ACTION_FAIL, - SESSION_NOT_FOUND_ACTION_END, +enum session_not_found_action +{ + SESSION_NOT_FOUND_ACTION_CONTINUE, + SESSION_NOT_FOUND_ACTION_FAIL, + SESSION_NOT_FOUND_ACTION_END, }; /* * A component instance is an iterator on a single session. */ -struct lttng_live_component { - bt_logging_level log_level; - - /* Weak reference. */ - bt_self_component *self_comp; - - struct { - GString *url; - enum session_not_found_action sess_not_found_act; - } params; - - size_t max_query_size; - - /* - * Keeps track of whether the downstream component already has a - * message iterator on this component. - */ - bool has_msg_iter; +struct lttng_live_component +{ + bt_logging_level log_level; + + /* Weak reference. */ + bt_self_component *self_comp; + + struct + { + GString *url; + enum session_not_found_action sess_not_found_act; + } params; + + size_t max_query_size; + + /* + * Keeps track of whether the downstream component already has a + * message iterator on this component. + */ + bool has_msg_iter; }; -struct lttng_live_msg_iter { - bt_logging_level log_level; - bt_self_component *self_comp; +struct lttng_live_msg_iter +{ + bt_logging_level log_level; + bt_self_component *self_comp; - /* Weak reference. */ - struct lttng_live_component *lttng_live_comp; + /* Weak reference. */ + struct lttng_live_component *lttng_live_comp; - /* Weak reference. */ - bt_self_message_iterator *self_msg_iter; + /* Weak reference. */ + bt_self_message_iterator *self_msg_iter; - /* Owned by this. */ - struct live_viewer_connection *viewer_connection; + /* Owned by this. */ + struct live_viewer_connection *viewer_connection; - /* Array of pointers to struct lttng_live_session. */ - GPtrArray *sessions; + /* Array of pointers to struct lttng_live_session. */ + GPtrArray *sessions; - /* Number of live stream iterator this message iterator has.*/ - uint64_t active_stream_iter; + /* Number of live stream iterator this message iterator has.*/ + uint64_t active_stream_iter; - /* Timestamp in nanosecond of the last message sent downstream. */ - int64_t last_msg_ts_ns; + /* Timestamp in nanosecond of the last message sent downstream. */ + int64_t last_msg_ts_ns; - /* True if the iterator was interrupted. */ - bool was_interrupted; + /* True if the iterator was interrupted. */ + bool was_interrupted; }; -enum lttng_live_iterator_status { - /** Iterator state has progressed. Continue iteration immediately. */ - LTTNG_LIVE_ITERATOR_STATUS_CONTINUE = 3, - /** No message available for now. Try again later. */ - LTTNG_LIVE_ITERATOR_STATUS_AGAIN = 2, - /** No more CTF_LTTNG_LIVEs to be delivered. */ - LTTNG_LIVE_ITERATOR_STATUS_END = 1, - /** No error, okay. */ - LTTNG_LIVE_ITERATOR_STATUS_OK = 0, - /** Invalid arguments. */ - LTTNG_LIVE_ITERATOR_STATUS_INVAL = -1, - /** General error. */ - LTTNG_LIVE_ITERATOR_STATUS_ERROR = -2, - /** Out of memory. */ - LTTNG_LIVE_ITERATOR_STATUS_NOMEM = -3, - /** Unsupported iterator feature. */ - LTTNG_LIVE_ITERATOR_STATUS_UNSUPPORTED = -4, +enum lttng_live_iterator_status +{ + /** Iterator state has progressed. Continue iteration immediately. */ + LTTNG_LIVE_ITERATOR_STATUS_CONTINUE = 3, + /** No message available for now. Try again later. */ + LTTNG_LIVE_ITERATOR_STATUS_AGAIN = 2, + /** No more CTF_LTTNG_LIVEs to be delivered. */ + LTTNG_LIVE_ITERATOR_STATUS_END = 1, + /** No error, okay. */ + LTTNG_LIVE_ITERATOR_STATUS_OK = 0, + /** Invalid arguments. */ + LTTNG_LIVE_ITERATOR_STATUS_INVAL = -1, + /** General error. */ + LTTNG_LIVE_ITERATOR_STATUS_ERROR = -2, + /** Out of memory. */ + LTTNG_LIVE_ITERATOR_STATUS_NOMEM = -3, + /** Unsupported iterator feature. */ + LTTNG_LIVE_ITERATOR_STATUS_UNSUPPORTED = -4, }; -bt_component_class_initialize_method_status lttng_live_component_init( - bt_self_component_source *self_comp, - bt_self_component_source_configuration *config, - const bt_value *params, void *init_method_data); +bt_component_class_initialize_method_status +lttng_live_component_init(bt_self_component_source *self_comp, + bt_self_component_source_configuration *config, const bt_value *params, + void *init_method_data); -bt_component_class_query_method_status lttng_live_query( - bt_self_component_class_source *comp_class, - bt_private_query_executor *priv_query_exec, - const char *object, const bt_value *params, - void *method_data, const bt_value **result); +bt_component_class_query_method_status lttng_live_query(bt_self_component_class_source *comp_class, + bt_private_query_executor *priv_query_exec, + const char *object, const bt_value *params, + void *method_data, const bt_value **result); void lttng_live_component_finalize(bt_self_component_source *component); -bt_message_iterator_class_next_method_status lttng_live_msg_iter_next( - bt_self_message_iterator *iterator, - bt_message_array_const msgs, uint64_t capacity, - uint64_t *count); +bt_message_iterator_class_next_method_status +lttng_live_msg_iter_next(bt_self_message_iterator *iterator, bt_message_array_const msgs, + uint64_t capacity, uint64_t *count); -bt_message_iterator_class_initialize_method_status lttng_live_msg_iter_init( - bt_self_message_iterator *self_msg_it, - bt_self_message_iterator_configuration *config, - bt_self_component_port_output *self_port); +bt_message_iterator_class_initialize_method_status +lttng_live_msg_iter_init(bt_self_message_iterator *self_msg_it, + bt_self_message_iterator_configuration *config, + bt_self_component_port_output *self_port); void lttng_live_msg_iter_finalize(bt_self_message_iterator *it); -enum lttng_live_viewer_status lttng_live_session_attach( - struct lttng_live_session *session, - bt_self_message_iterator *self_msg_iter); +enum lttng_live_viewer_status lttng_live_session_attach(struct lttng_live_session *session, + bt_self_message_iterator *self_msg_iter); -enum lttng_live_viewer_status lttng_live_session_detach( - struct lttng_live_session *session); +enum lttng_live_viewer_status lttng_live_session_detach(struct lttng_live_session *session); -enum lttng_live_iterator_status lttng_live_session_get_new_streams( - struct lttng_live_session *session, - bt_self_message_iterator *self_msg_iter); +enum lttng_live_iterator_status +lttng_live_session_get_new_streams(struct lttng_live_session *session, + bt_self_message_iterator *self_msg_iter); -struct lttng_live_trace *lttng_live_session_borrow_or_create_trace_by_id( - struct lttng_live_session *session, uint64_t trace_id); +struct lttng_live_trace * +lttng_live_session_borrow_or_create_trace_by_id(struct lttng_live_session *session, + uint64_t trace_id); -int lttng_live_add_session(struct lttng_live_msg_iter *lttng_live_msg_iter, - uint64_t session_id, - const char *hostname, - const char *session_name); +int lttng_live_add_session(struct lttng_live_msg_iter *lttng_live_msg_iter, uint64_t session_id, + const char *hostname, const char *session_name); /* * lttng_live_get_one_metadata_packet() asks the Relay Daemon for new metadata. @@ -319,24 +327,22 @@ int lttng_live_add_session(struct lttng_live_msg_iter *lttng_live_msg_iter, * called in loop until _END status is received to ensure all metadata is * written to the file. */ -enum lttng_live_get_one_metadata_status lttng_live_get_one_metadata_packet( - struct lttng_live_trace *trace, FILE *fp, size_t *reply_len); +enum lttng_live_get_one_metadata_status +lttng_live_get_one_metadata_packet(struct lttng_live_trace *trace, FILE *fp, size_t *reply_len); -enum lttng_live_iterator_status lttng_live_get_next_index( - struct lttng_live_msg_iter *lttng_live_msg_iter, - struct lttng_live_stream_iterator *stream, - struct packet_index *index); +enum lttng_live_iterator_status +lttng_live_get_next_index(struct lttng_live_msg_iter *lttng_live_msg_iter, + struct lttng_live_stream_iterator *stream, struct packet_index *index); -enum ctf_msg_iter_medium_status lttng_live_get_stream_bytes( - struct lttng_live_msg_iter *lttng_live_msg_iter, - struct lttng_live_stream_iterator *stream, uint8_t *buf, - uint64_t offset, uint64_t req_len, uint64_t *recv_len); +enum ctf_msg_iter_medium_status +lttng_live_get_stream_bytes(struct lttng_live_msg_iter *lttng_live_msg_iter, + struct lttng_live_stream_iterator *stream, uint8_t *buf, + uint64_t offset, uint64_t req_len, uint64_t *recv_len); bool lttng_live_graph_is_canceled(struct lttng_live_msg_iter *msg_iter); BT_HIDDEN -void lttng_live_stream_iterator_set_state( - struct lttng_live_stream_iterator *stream_iter, - enum lttng_live_stream_state new_state); +void lttng_live_stream_iterator_set_state(struct lttng_live_stream_iterator *stream_iter, + enum lttng_live_stream_state new_state); #endif /* BABELTRACE_PLUGIN_CTF_LTTNG_LIVE_H */ diff --git a/src/plugins/ctf/lttng-live/lttng-viewer-abi.hpp b/src/plugins/ctf/lttng-live/lttng-viewer-abi.hpp index 85c64bad..0d1911ad 100644 --- a/src/plugins/ctf/lttng-live/lttng-viewer-abi.hpp +++ b/src/plugins/ctf/lttng-live/lttng-viewer-abi.hpp @@ -12,228 +12,257 @@ #include #include "compat/limits.h" -#define LTTNG_VIEWER_PATH_MAX 4096 -#define LTTNG_VIEWER_NAME_MAX 255 -#define LTTNG_VIEWER_HOST_NAME_MAX 64 +#define LTTNG_VIEWER_PATH_MAX 4096 +#define LTTNG_VIEWER_NAME_MAX 255 +#define LTTNG_VIEWER_HOST_NAME_MAX 64 /* Flags in reply to get_next_index and get_packet. */ -enum { - /* New metadata is required to read this packet. */ - LTTNG_VIEWER_FLAG_NEW_METADATA = (1 << 0), - /* New stream got added to the trace. */ - LTTNG_VIEWER_FLAG_NEW_STREAM = (1 << 1), +enum +{ + /* New metadata is required to read this packet. */ + LTTNG_VIEWER_FLAG_NEW_METADATA = (1 << 0), + /* New stream got added to the trace. */ + LTTNG_VIEWER_FLAG_NEW_STREAM = (1 << 1), }; -enum lttng_viewer_command { - LTTNG_VIEWER_CONNECT = 1, - LTTNG_VIEWER_LIST_SESSIONS = 2, - LTTNG_VIEWER_ATTACH_SESSION = 3, - LTTNG_VIEWER_GET_NEXT_INDEX = 4, - LTTNG_VIEWER_GET_PACKET = 5, - LTTNG_VIEWER_GET_METADATA = 6, - LTTNG_VIEWER_GET_NEW_STREAMS = 7, - LTTNG_VIEWER_CREATE_SESSION = 8, - LTTNG_VIEWER_DETACH_SESSION = 9, +enum lttng_viewer_command +{ + LTTNG_VIEWER_CONNECT = 1, + LTTNG_VIEWER_LIST_SESSIONS = 2, + LTTNG_VIEWER_ATTACH_SESSION = 3, + LTTNG_VIEWER_GET_NEXT_INDEX = 4, + LTTNG_VIEWER_GET_PACKET = 5, + LTTNG_VIEWER_GET_METADATA = 6, + LTTNG_VIEWER_GET_NEW_STREAMS = 7, + LTTNG_VIEWER_CREATE_SESSION = 8, + LTTNG_VIEWER_DETACH_SESSION = 9, }; -enum lttng_viewer_attach_return_code { - LTTNG_VIEWER_ATTACH_OK = 1, /* The attach command succeeded. */ - LTTNG_VIEWER_ATTACH_ALREADY = 2, /* A viewer is already attached. */ - LTTNG_VIEWER_ATTACH_UNK = 3, /* The session ID is unknown. */ - LTTNG_VIEWER_ATTACH_NOT_LIVE = 4, /* The session is not live. */ - LTTNG_VIEWER_ATTACH_SEEK_ERR = 5, /* Seek error. */ - LTTNG_VIEWER_ATTACH_NO_SESSION = 6, /* No viewer session created. */ +enum lttng_viewer_attach_return_code +{ + LTTNG_VIEWER_ATTACH_OK = 1, /* The attach command succeeded. */ + LTTNG_VIEWER_ATTACH_ALREADY = 2, /* A viewer is already attached. */ + LTTNG_VIEWER_ATTACH_UNK = 3, /* The session ID is unknown. */ + LTTNG_VIEWER_ATTACH_NOT_LIVE = 4, /* The session is not live. */ + LTTNG_VIEWER_ATTACH_SEEK_ERR = 5, /* Seek error. */ + LTTNG_VIEWER_ATTACH_NO_SESSION = 6, /* No viewer session created. */ }; -enum lttng_viewer_detach_session_return_code { - LTTNG_VIEWER_DETACH_SESSION_OK = 1, - LTTNG_VIEWER_DETACH_SESSION_UNK = 2, - LTTNG_VIEWER_DETACH_SESSION_ERR = 3, +enum lttng_viewer_detach_session_return_code +{ + LTTNG_VIEWER_DETACH_SESSION_OK = 1, + LTTNG_VIEWER_DETACH_SESSION_UNK = 2, + LTTNG_VIEWER_DETACH_SESSION_ERR = 3, }; -enum lttng_viewer_next_index_return_code { - LTTNG_VIEWER_INDEX_OK = 1, /* Index is available. */ - LTTNG_VIEWER_INDEX_RETRY = 2, /* Index not yet available. */ - LTTNG_VIEWER_INDEX_HUP = 3, /* Index closed (trace destroyed). */ - LTTNG_VIEWER_INDEX_ERR = 4, /* Unknow error. */ - LTTNG_VIEWER_INDEX_INACTIVE = 5, /* Inactive stream beacon. */ - LTTNG_VIEWER_INDEX_EOF = 6, /* End of index file. */ +enum lttng_viewer_next_index_return_code +{ + LTTNG_VIEWER_INDEX_OK = 1, /* Index is available. */ + LTTNG_VIEWER_INDEX_RETRY = 2, /* Index not yet available. */ + LTTNG_VIEWER_INDEX_HUP = 3, /* Index closed (trace destroyed). */ + LTTNG_VIEWER_INDEX_ERR = 4, /* Unknow error. */ + LTTNG_VIEWER_INDEX_INACTIVE = 5, /* Inactive stream beacon. */ + LTTNG_VIEWER_INDEX_EOF = 6, /* End of index file. */ }; -enum lttng_viewer_get_packet_return_code { - LTTNG_VIEWER_GET_PACKET_OK = 1, - LTTNG_VIEWER_GET_PACKET_RETRY = 2, - LTTNG_VIEWER_GET_PACKET_ERR = 3, - LTTNG_VIEWER_GET_PACKET_EOF = 4, +enum lttng_viewer_get_packet_return_code +{ + LTTNG_VIEWER_GET_PACKET_OK = 1, + LTTNG_VIEWER_GET_PACKET_RETRY = 2, + LTTNG_VIEWER_GET_PACKET_ERR = 3, + LTTNG_VIEWER_GET_PACKET_EOF = 4, }; -enum lttng_viewer_get_metadata_return_code { - LTTNG_VIEWER_METADATA_OK = 1, - LTTNG_VIEWER_NO_NEW_METADATA = 2, - LTTNG_VIEWER_METADATA_ERR = 3, +enum lttng_viewer_get_metadata_return_code +{ + LTTNG_VIEWER_METADATA_OK = 1, + LTTNG_VIEWER_NO_NEW_METADATA = 2, + LTTNG_VIEWER_METADATA_ERR = 3, }; -enum lttng_viewer_connection_type { - LTTNG_VIEWER_CLIENT_COMMAND = 1, - LTTNG_VIEWER_CLIENT_MESSAGE = 2, +enum lttng_viewer_connection_type +{ + LTTNG_VIEWER_CLIENT_COMMAND = 1, + LTTNG_VIEWER_CLIENT_MESSAGE = 2, }; -enum lttng_viewer_seek { - /* Receive the trace packets from the beginning. */ - LTTNG_VIEWER_SEEK_BEGINNING = 1, - /* Receive the trace packets from now. */ - LTTNG_VIEWER_SEEK_LAST = 2, +enum lttng_viewer_seek +{ + /* Receive the trace packets from the beginning. */ + LTTNG_VIEWER_SEEK_BEGINNING = 1, + /* Receive the trace packets from now. */ + LTTNG_VIEWER_SEEK_LAST = 2, }; -enum lttng_viewer_new_streams_return_code { - LTTNG_VIEWER_NEW_STREAMS_OK = 1, /* If new streams are being sent. */ - LTTNG_VIEWER_NEW_STREAMS_NO_NEW = 2, /* If no new streams are available. */ - LTTNG_VIEWER_NEW_STREAMS_ERR = 3, /* Error. */ - LTTNG_VIEWER_NEW_STREAMS_HUP = 4, /* Session closed. */ +enum lttng_viewer_new_streams_return_code +{ + LTTNG_VIEWER_NEW_STREAMS_OK = 1, /* If new streams are being sent. */ + LTTNG_VIEWER_NEW_STREAMS_NO_NEW = 2, /* If no new streams are available. */ + LTTNG_VIEWER_NEW_STREAMS_ERR = 3, /* Error. */ + LTTNG_VIEWER_NEW_STREAMS_HUP = 4, /* Session closed. */ }; -enum lttng_viewer_create_session_return_code { - LTTNG_VIEWER_CREATE_SESSION_OK = 1, - LTTNG_VIEWER_CREATE_SESSION_ERR = 2, +enum lttng_viewer_create_session_return_code +{ + LTTNG_VIEWER_CREATE_SESSION_OK = 1, + LTTNG_VIEWER_CREATE_SESSION_ERR = 2, }; -struct lttng_viewer_session { - uint64_t id; - uint32_t live_timer; - uint32_t clients; - uint32_t streams; - char hostname[LTTNG_VIEWER_HOST_NAME_MAX]; - char session_name[LTTNG_VIEWER_NAME_MAX]; +struct lttng_viewer_session +{ + uint64_t id; + uint32_t live_timer; + uint32_t clients; + uint32_t streams; + char hostname[LTTNG_VIEWER_HOST_NAME_MAX]; + char session_name[LTTNG_VIEWER_NAME_MAX]; } __attribute__((__packed__)); -struct lttng_viewer_stream { - uint64_t id; - uint64_t ctf_trace_id; - uint32_t metadata_flag; - char path_name[LTTNG_VIEWER_PATH_MAX]; - char channel_name[LTTNG_VIEWER_NAME_MAX]; +struct lttng_viewer_stream +{ + uint64_t id; + uint64_t ctf_trace_id; + uint32_t metadata_flag; + char path_name[LTTNG_VIEWER_PATH_MAX]; + char channel_name[LTTNG_VIEWER_NAME_MAX]; } __attribute__((__packed__)); -struct lttng_viewer_cmd { - uint64_t data_size; /* data size following this header */ - uint32_t cmd; /* enum lttcomm_relayd_command */ - uint32_t cmd_version; /* command version */ +struct lttng_viewer_cmd +{ + uint64_t data_size; /* data size following this header */ + uint32_t cmd; /* enum lttcomm_relayd_command */ + uint32_t cmd_version; /* command version */ } __attribute__((__packed__)); /* * LTTNG_VIEWER_CONNECT payload. */ -struct lttng_viewer_connect { - /* session ID assigned by the relay for command connections */ - uint64_t viewer_session_id; - uint32_t major; - uint32_t minor; - uint32_t type; /* enum lttng_viewer_connection_type */ +struct lttng_viewer_connect +{ + /* session ID assigned by the relay for command connections */ + uint64_t viewer_session_id; + uint32_t major; + uint32_t minor; + uint32_t type; /* enum lttng_viewer_connection_type */ } __attribute__((__packed__)); /* * LTTNG_VIEWER_LIST_SESSIONS payload. */ -struct lttng_viewer_list_sessions { - uint32_t sessions_count; - char session_list[]; /* struct lttng_viewer_session */ +struct lttng_viewer_list_sessions +{ + uint32_t sessions_count; + char session_list[]; /* struct lttng_viewer_session */ } __attribute__((__packed__)); /* * LTTNG_VIEWER_ATTACH_SESSION payload. */ -struct lttng_viewer_attach_session_request { - uint64_t session_id; - uint64_t offset; /* unused for now */ - uint32_t seek; /* enum lttng_viewer_seek */ +struct lttng_viewer_attach_session_request +{ + uint64_t session_id; + uint64_t offset; /* unused for now */ + uint32_t seek; /* enum lttng_viewer_seek */ } __attribute__((__packed__)); -struct lttng_viewer_attach_session_response { - /* enum lttng_viewer_attach_return_code */ - uint32_t status; - uint32_t streams_count; - /* struct lttng_viewer_stream */ - char stream_list[]; +struct lttng_viewer_attach_session_response +{ + /* enum lttng_viewer_attach_return_code */ + uint32_t status; + uint32_t streams_count; + /* struct lttng_viewer_stream */ + char stream_list[]; } __attribute__((__packed__)); /* * LTTNG_VIEWER_GET_NEXT_INDEX payload. */ -struct lttng_viewer_get_next_index { - uint64_t stream_id; -} __attribute__ ((__packed__)); - -struct lttng_viewer_index { - uint64_t offset; - uint64_t packet_size; - uint64_t content_size; - uint64_t timestamp_begin; - uint64_t timestamp_end; - uint64_t events_discarded; - uint64_t stream_id; - uint32_t status; /* enum lttng_viewer_next_index_return_code */ - uint32_t flags; /* LTTNG_VIEWER_FLAG_* */ -} __attribute__ ((__packed__)); +struct lttng_viewer_get_next_index +{ + uint64_t stream_id; +} __attribute__((__packed__)); + +struct lttng_viewer_index +{ + uint64_t offset; + uint64_t packet_size; + uint64_t content_size; + uint64_t timestamp_begin; + uint64_t timestamp_end; + uint64_t events_discarded; + uint64_t stream_id; + uint32_t status; /* enum lttng_viewer_next_index_return_code */ + uint32_t flags; /* LTTNG_VIEWER_FLAG_* */ +} __attribute__((__packed__)); /* * LTTNG_VIEWER_GET_PACKET payload. */ -struct lttng_viewer_get_packet { - uint64_t stream_id; - uint64_t offset; - uint32_t len; +struct lttng_viewer_get_packet +{ + uint64_t stream_id; + uint64_t offset; + uint32_t len; } __attribute__((__packed__)); -struct lttng_viewer_trace_packet { - uint32_t status; /* enum lttng_viewer_get_packet_return_code */ - uint32_t len; - uint32_t flags; /* LTTNG_VIEWER_FLAG_* */ - char data[]; +struct lttng_viewer_trace_packet +{ + uint32_t status; /* enum lttng_viewer_get_packet_return_code */ + uint32_t len; + uint32_t flags; /* LTTNG_VIEWER_FLAG_* */ + char data[]; } __attribute__((__packed__)); /* * LTTNG_VIEWER_GET_METADATA payload. */ -struct lttng_viewer_get_metadata { - uint64_t stream_id; +struct lttng_viewer_get_metadata +{ + uint64_t stream_id; } __attribute__((__packed__)); -struct lttng_viewer_metadata_packet { - uint64_t len; - uint32_t status; /* enum lttng_viewer_get_metadata_return_code */ - char data[]; +struct lttng_viewer_metadata_packet +{ + uint64_t len; + uint32_t status; /* enum lttng_viewer_get_metadata_return_code */ + char data[]; } __attribute__((__packed__)); /* * LTTNG_VIEWER_GET_NEW_STREAMS payload. */ -struct lttng_viewer_new_streams_request { - uint64_t session_id; +struct lttng_viewer_new_streams_request +{ + uint64_t session_id; } __attribute__((__packed__)); -struct lttng_viewer_new_streams_response { - /* enum lttng_viewer_new_streams_return_code */ - uint32_t status; - uint32_t streams_count; - /* struct lttng_viewer_stream */ - char stream_list[]; +struct lttng_viewer_new_streams_response +{ + /* enum lttng_viewer_new_streams_return_code */ + uint32_t status; + uint32_t streams_count; + /* struct lttng_viewer_stream */ + char stream_list[]; } __attribute__((__packed__)); -struct lttng_viewer_create_session_response { - /* enum lttng_viewer_create_session_return_code */ - uint32_t status; +struct lttng_viewer_create_session_response +{ + /* enum lttng_viewer_create_session_return_code */ + uint32_t status; } __attribute__((__packed__)); /* * LTTNG_VIEWER_DETACH_SESSION payload. */ -struct lttng_viewer_detach_session_request { - uint64_t session_id; +struct lttng_viewer_detach_session_request +{ + uint64_t session_id; } __attribute__((__packed__)); -struct lttng_viewer_detach_session_response { - /* enum lttng_viewer_detach_session_return_code */ - uint32_t status; +struct lttng_viewer_detach_session_response +{ + /* enum lttng_viewer_detach_session_return_code */ + uint32_t status; } __attribute__((__packed__)); #endif /* LTTNG_VIEWER_ABI_H */ diff --git a/src/plugins/ctf/lttng-live/metadata.cpp b/src/plugins/ctf/lttng-live/metadata.cpp index feaf0afd..d49ce76f 100644 --- a/src/plugins/ctf/lttng-live/metadata.cpp +++ b/src/plugins/ctf/lttng-live/metadata.cpp @@ -7,8 +7,8 @@ */ #define BT_COMP_LOG_SELF_COMP self_comp -#define BT_LOG_OUTPUT_LEVEL log_level -#define BT_LOG_TAG "PLUGIN/SRC.CTF.LTTNG-LIVE/META" +#define BT_LOG_OUTPUT_LEVEL log_level +#define BT_LOG_TAG "PLUGIN/SRC.CTF.LTTNG-LIVE/META" #include "logging/comp-logging.h" #include @@ -23,338 +23,316 @@ #include "../common/metadata/decoder.hpp" #include "../common/metadata/ctf-meta-configure-ir-trace.hpp" -#define TSDL_MAGIC 0x75d11d57 - -struct packet_header { - uint32_t magic; - uint8_t uuid[16]; - uint32_t checksum; - uint32_t content_size; - uint32_t packet_size; - uint8_t compression_scheme; - uint8_t encryption_scheme; - uint8_t checksum_scheme; - uint8_t major; - uint8_t minor; -} __attribute__((__packed__)); +#define TSDL_MAGIC 0x75d11d57 +struct packet_header +{ + uint32_t magic; + uint8_t uuid[16]; + uint32_t checksum; + uint32_t content_size; + uint32_t packet_size; + uint8_t compression_scheme; + uint8_t encryption_scheme; + uint8_t checksum_scheme; + uint8_t major; + uint8_t minor; +} __attribute__((__packed__)); -static -bool stream_classes_all_have_default_clock_class(bt_trace_class *tc, - bt_logging_level log_level, - bt_self_component *self_comp) +static bool stream_classes_all_have_default_clock_class(bt_trace_class *tc, + bt_logging_level log_level, + bt_self_component *self_comp) { - uint64_t i, sc_count; - const bt_clock_class *cc = NULL; - const bt_stream_class *sc; - bool ret = true; - - sc_count = bt_trace_class_get_stream_class_count(tc); - for (i = 0; i < sc_count; i++) { - sc = bt_trace_class_borrow_stream_class_by_index_const(tc, i); - - BT_ASSERT(sc); - - cc = bt_stream_class_borrow_default_clock_class_const(sc); - if (!cc) { - ret = false; - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Stream class doesn't have a default clock class: " - "sc-id=%" PRIu64 ", sc-name=\"%s\"", - bt_stream_class_get_id(sc), - bt_stream_class_get_name(sc)); - goto end; - } - } + uint64_t i, sc_count; + const bt_clock_class *cc = NULL; + const bt_stream_class *sc; + bool ret = true; + + sc_count = bt_trace_class_get_stream_class_count(tc); + for (i = 0; i < sc_count; i++) { + sc = bt_trace_class_borrow_stream_class_by_index_const(tc, i); + + BT_ASSERT(sc); + + cc = bt_stream_class_borrow_default_clock_class_const(sc); + if (!cc) { + ret = false; + BT_COMP_LOGE_APPEND_CAUSE(self_comp, + "Stream class doesn't have a default clock class: " + "sc-id=%" PRIu64 ", sc-name=\"%s\"", + bt_stream_class_get_id(sc), bt_stream_class_get_name(sc)); + goto end; + } + } end: - return ret; + return ret; } /* * Iterate over the stream classes and returns the first clock class * encountered. This is useful to create message iterator inactivity message as * we don't need a particular clock class. */ -static -const bt_clock_class *borrow_any_clock_class(bt_trace_class *tc) +static const bt_clock_class *borrow_any_clock_class(bt_trace_class *tc) { - uint64_t i, sc_count; - const bt_clock_class *cc = NULL; - const bt_stream_class *sc; - - sc_count = bt_trace_class_get_stream_class_count(tc); - for (i = 0; i < sc_count; i++) { - sc = bt_trace_class_borrow_stream_class_by_index_const(tc, i); - BT_ASSERT_DBG(sc); - - cc = bt_stream_class_borrow_default_clock_class_const(sc); - if (cc) { - goto end; - } - } + uint64_t i, sc_count; + const bt_clock_class *cc = NULL; + const bt_stream_class *sc; + + sc_count = bt_trace_class_get_stream_class_count(tc); + for (i = 0; i < sc_count; i++) { + sc = bt_trace_class_borrow_stream_class_by_index_const(tc, i); + BT_ASSERT_DBG(sc); + + cc = bt_stream_class_borrow_default_clock_class_const(sc); + if (cc) { + goto end; + } + } end: - BT_ASSERT_DBG(cc); - return cc; + BT_ASSERT_DBG(cc); + return cc; } BT_HIDDEN -enum lttng_live_iterator_status lttng_live_metadata_update( - struct lttng_live_trace *trace) +enum lttng_live_iterator_status lttng_live_metadata_update(struct lttng_live_trace *trace) { - struct lttng_live_session *session = trace->session; - struct lttng_live_metadata *metadata = trace->metadata; - size_t size, len_read = 0; - char *metadata_buf = NULL; - bool keep_receiving; - FILE *fp = NULL; - enum ctf_metadata_decoder_status decoder_status; - enum lttng_live_iterator_status status = - LTTNG_LIVE_ITERATOR_STATUS_OK; - bt_logging_level log_level = trace->log_level; - bt_self_component *self_comp = trace->self_comp; - enum lttng_live_get_one_metadata_status metadata_status; - - BT_COMP_LOGD("Updating metadata for trace: session-id=%" PRIu64 - ", trace-id=%" PRIu64, session->id, trace->id); - - /* No metadata stream yet. */ - if (!metadata) { - if (session->new_streams_needed) { - status = LTTNG_LIVE_ITERATOR_STATUS_AGAIN; - } else { - session->new_streams_needed = true; - status = LTTNG_LIVE_ITERATOR_STATUS_CONTINUE; - } - goto end; - } - - if (trace->metadata_stream_state != LTTNG_LIVE_METADATA_STREAM_STATE_NEEDED) { - goto end; - } - - /* - * Open a new write only file handle to populate the `metadata_buf` - * memory buffer so we can write in loop in it easily. - */ - fp = bt_open_memstream(&metadata_buf, &size); - if (!fp) { - if (errno == EINTR && - lttng_live_graph_is_canceled(session->lttng_live_msg_iter)) { - session->lttng_live_msg_iter->was_interrupted = true; - status = LTTNG_LIVE_ITERATOR_STATUS_AGAIN; - } else { - BT_COMP_LOGE_APPEND_CAUSE_ERRNO(self_comp, - "Metadata open_memstream", "."); - status = LTTNG_LIVE_ITERATOR_STATUS_ERROR; - } - goto end; - } - - keep_receiving = true; - /* Grab all available metadata. */ - while (keep_receiving) { - size_t reply_len = 0; - /* - * lttng_live_get_one_metadata_packet() asks the Relay Daemon - * for new metadata. If new metadata is received, the function - * writes it to the provided file handle and updates the - * reply_len output parameter. We call this function in loop - * until it returns _END meaning that no new metadata is - * available. - * We may receive a _CLOSED status if the metadata stream we - * are requesting is no longer available on the relay. - * If we receive an _ERROR status, it means there was a - * networking, allocating, or some other unrecoverable error. - */ - metadata_status = lttng_live_get_one_metadata_packet(trace, fp, - &reply_len); - - switch (metadata_status) { - case LTTNG_LIVE_GET_ONE_METADATA_STATUS_OK: - len_read += reply_len; - break; - case LTTNG_LIVE_GET_ONE_METADATA_STATUS_END: - keep_receiving = false; - break; - case LTTNG_LIVE_GET_ONE_METADATA_STATUS_CLOSED: - BT_COMP_LOGD("Metadata stream was closed by the Relay, the trace is no longer active: " - "trace-id=%" PRIu64 ", metadata-stream-id=%" PRIu64, - trace->id, metadata->stream_id); - /* - * The stream was closed and we received everything - * there was to receive for this metadata stream. - * We go on with the decoding of what we received. So - * that data stream can be decoded. - */ - keep_receiving = false; - trace->metadata_stream_state = LTTNG_LIVE_METADATA_STREAM_STATE_CLOSED; - break; - case LTTNG_LIVE_GET_ONE_METADATA_STATUS_ERROR: - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Error getting one trace metadata packet: " - "trace-id=%" PRIu64, trace->id); - goto error; - default: - bt_common_abort(); - } - } - - /* The memory buffer `metadata_buf` contains all the metadata. */ - if (bt_close_memstream(&metadata_buf, &size, fp)) { - BT_COMP_LOGW_ERRNO("Metadata bt_close_memstream", "."); - } - - fp = NULL; - - if (len_read == 0) { - if (!trace->trace) { - status = LTTNG_LIVE_ITERATOR_STATUS_AGAIN; - goto end; - } - - /* The relay sent zero bytes of metdata. */ - trace->metadata_stream_state = LTTNG_LIVE_METADATA_STREAM_STATE_NOT_NEEDED; - goto end; - } - - /* - * Open a new reading file handle on the `metadata_buf` and pass it to - * the metadata decoder. - */ - fp = bt_fmemopen(metadata_buf, len_read, "rb"); - if (!fp) { - if (errno == EINTR && - lttng_live_graph_is_canceled(session->lttng_live_msg_iter)) { - session->lttng_live_msg_iter->was_interrupted = true; - status = LTTNG_LIVE_ITERATOR_STATUS_AGAIN; - } else { - BT_COMP_LOGE_APPEND_CAUSE_ERRNO(self_comp, - "Cannot memory-open metadata buffer", "."); - status = LTTNG_LIVE_ITERATOR_STATUS_ERROR; - } - goto end; - } - - /* - * The call to ctf_metadata_decoder_append_content() will append - * new metadata to our current trace class. - */ - BT_COMP_LOGD("Appending new metadata to the ctf_trace class"); - decoder_status = ctf_metadata_decoder_append_content( - metadata->decoder, fp); - switch (decoder_status) { - case CTF_METADATA_DECODER_STATUS_OK: - if (!trace->trace_class) { - struct ctf_trace_class *tc = - ctf_metadata_decoder_borrow_ctf_trace_class( - metadata->decoder); - - trace->trace_class = - ctf_metadata_decoder_get_ir_trace_class( - metadata->decoder); - trace->trace = bt_trace_create(trace->trace_class); - if (!trace->trace) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Failed to create bt_trace"); - goto error; - } - if (ctf_trace_class_configure_ir_trace(tc, - trace->trace)) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Failed to configure ctf trace class"); - goto error; - } - if (!stream_classes_all_have_default_clock_class( - trace->trace_class, log_level, - self_comp)) { - /* Error logged in function. */ - goto error; - } - trace->clock_class = - borrow_any_clock_class(trace->trace_class); - } - - /* The metadata was updated succesfully. */ - trace->metadata_stream_state = LTTNG_LIVE_METADATA_STREAM_STATE_NOT_NEEDED; - - break; - default: - goto error; - } - - goto end; + struct lttng_live_session *session = trace->session; + struct lttng_live_metadata *metadata = trace->metadata; + size_t size, len_read = 0; + char *metadata_buf = NULL; + bool keep_receiving; + FILE *fp = NULL; + enum ctf_metadata_decoder_status decoder_status; + enum lttng_live_iterator_status status = LTTNG_LIVE_ITERATOR_STATUS_OK; + bt_logging_level log_level = trace->log_level; + bt_self_component *self_comp = trace->self_comp; + enum lttng_live_get_one_metadata_status metadata_status; + + BT_COMP_LOGD("Updating metadata for trace: session-id=%" PRIu64 ", trace-id=%" PRIu64, + session->id, trace->id); + + /* No metadata stream yet. */ + if (!metadata) { + if (session->new_streams_needed) { + status = LTTNG_LIVE_ITERATOR_STATUS_AGAIN; + } else { + session->new_streams_needed = true; + status = LTTNG_LIVE_ITERATOR_STATUS_CONTINUE; + } + goto end; + } + + if (trace->metadata_stream_state != LTTNG_LIVE_METADATA_STREAM_STATE_NEEDED) { + goto end; + } + + /* + * Open a new write only file handle to populate the `metadata_buf` + * memory buffer so we can write in loop in it easily. + */ + fp = bt_open_memstream(&metadata_buf, &size); + if (!fp) { + if (errno == EINTR && lttng_live_graph_is_canceled(session->lttng_live_msg_iter)) { + session->lttng_live_msg_iter->was_interrupted = true; + status = LTTNG_LIVE_ITERATOR_STATUS_AGAIN; + } else { + BT_COMP_LOGE_APPEND_CAUSE_ERRNO(self_comp, "Metadata open_memstream", "."); + status = LTTNG_LIVE_ITERATOR_STATUS_ERROR; + } + goto end; + } + + keep_receiving = true; + /* Grab all available metadata. */ + while (keep_receiving) { + size_t reply_len = 0; + /* + * lttng_live_get_one_metadata_packet() asks the Relay Daemon + * for new metadata. If new metadata is received, the function + * writes it to the provided file handle and updates the + * reply_len output parameter. We call this function in loop + * until it returns _END meaning that no new metadata is + * available. + * We may receive a _CLOSED status if the metadata stream we + * are requesting is no longer available on the relay. + * If we receive an _ERROR status, it means there was a + * networking, allocating, or some other unrecoverable error. + */ + metadata_status = lttng_live_get_one_metadata_packet(trace, fp, &reply_len); + + switch (metadata_status) { + case LTTNG_LIVE_GET_ONE_METADATA_STATUS_OK: + len_read += reply_len; + break; + case LTTNG_LIVE_GET_ONE_METADATA_STATUS_END: + keep_receiving = false; + break; + case LTTNG_LIVE_GET_ONE_METADATA_STATUS_CLOSED: + BT_COMP_LOGD("Metadata stream was closed by the Relay, the trace is no longer active: " + "trace-id=%" PRIu64 ", metadata-stream-id=%" PRIu64, + trace->id, metadata->stream_id); + /* + * The stream was closed and we received everything + * there was to receive for this metadata stream. + * We go on with the decoding of what we received. So + * that data stream can be decoded. + */ + keep_receiving = false; + trace->metadata_stream_state = LTTNG_LIVE_METADATA_STREAM_STATE_CLOSED; + break; + case LTTNG_LIVE_GET_ONE_METADATA_STATUS_ERROR: + BT_COMP_LOGE_APPEND_CAUSE(self_comp, + "Error getting one trace metadata packet: " + "trace-id=%" PRIu64, + trace->id); + goto error; + default: + bt_common_abort(); + } + } + + /* The memory buffer `metadata_buf` contains all the metadata. */ + if (bt_close_memstream(&metadata_buf, &size, fp)) { + BT_COMP_LOGW_ERRNO("Metadata bt_close_memstream", "."); + } + + fp = NULL; + + if (len_read == 0) { + if (!trace->trace) { + status = LTTNG_LIVE_ITERATOR_STATUS_AGAIN; + goto end; + } + + /* The relay sent zero bytes of metdata. */ + trace->metadata_stream_state = LTTNG_LIVE_METADATA_STREAM_STATE_NOT_NEEDED; + goto end; + } + + /* + * Open a new reading file handle on the `metadata_buf` and pass it to + * the metadata decoder. + */ + fp = bt_fmemopen(metadata_buf, len_read, "rb"); + if (!fp) { + if (errno == EINTR && lttng_live_graph_is_canceled(session->lttng_live_msg_iter)) { + session->lttng_live_msg_iter->was_interrupted = true; + status = LTTNG_LIVE_ITERATOR_STATUS_AGAIN; + } else { + BT_COMP_LOGE_APPEND_CAUSE_ERRNO(self_comp, "Cannot memory-open metadata buffer", "."); + status = LTTNG_LIVE_ITERATOR_STATUS_ERROR; + } + goto end; + } + + /* + * The call to ctf_metadata_decoder_append_content() will append + * new metadata to our current trace class. + */ + BT_COMP_LOGD("Appending new metadata to the ctf_trace class"); + decoder_status = ctf_metadata_decoder_append_content(metadata->decoder, fp); + switch (decoder_status) { + case CTF_METADATA_DECODER_STATUS_OK: + if (!trace->trace_class) { + struct ctf_trace_class *tc = + ctf_metadata_decoder_borrow_ctf_trace_class(metadata->decoder); + + trace->trace_class = ctf_metadata_decoder_get_ir_trace_class(metadata->decoder); + trace->trace = bt_trace_create(trace->trace_class); + if (!trace->trace) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Failed to create bt_trace"); + goto error; + } + if (ctf_trace_class_configure_ir_trace(tc, trace->trace)) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Failed to configure ctf trace class"); + goto error; + } + if (!stream_classes_all_have_default_clock_class(trace->trace_class, log_level, + self_comp)) { + /* Error logged in function. */ + goto error; + } + trace->clock_class = borrow_any_clock_class(trace->trace_class); + } + + /* The metadata was updated succesfully. */ + trace->metadata_stream_state = LTTNG_LIVE_METADATA_STREAM_STATE_NOT_NEEDED; + + break; + default: + goto error; + } + + goto end; error: - status = LTTNG_LIVE_ITERATOR_STATUS_ERROR; + status = LTTNG_LIVE_ITERATOR_STATUS_ERROR; end: - if (fp) { - int closeret; - - closeret = fclose(fp); - if (closeret) { - BT_COMP_LOGW_ERRNO("Error on fclose", "."); - } - } - free(metadata_buf); - return status; + if (fp) { + int closeret; + + closeret = fclose(fp); + if (closeret) { + BT_COMP_LOGW_ERRNO("Error on fclose", "."); + } + } + free(metadata_buf); + return status; } BT_HIDDEN -int lttng_live_metadata_create_stream(struct lttng_live_session *session, - uint64_t ctf_trace_id, uint64_t stream_id, - const char *trace_name) +int lttng_live_metadata_create_stream(struct lttng_live_session *session, uint64_t ctf_trace_id, + uint64_t stream_id, const char *trace_name) { - bt_self_component *self_comp = session->self_comp; - bt_logging_level log_level = session->log_level; - struct lttng_live_metadata *metadata = NULL; - struct lttng_live_trace *trace; - - ctf_metadata_decoder_config cfg{}; - cfg.log_level = session->log_level; - cfg.self_comp = session->self_comp; - cfg.clock_class_offset_s = 0; - cfg.clock_class_offset_ns = 0; - cfg.create_trace_class = true; - - metadata = g_new0(struct lttng_live_metadata, 1); - if (!metadata) { - return -1; - } - metadata->log_level = session->log_level; - metadata->self_comp = session->self_comp; - metadata->stream_id = stream_id; - - metadata->decoder = ctf_metadata_decoder_create(&cfg); - if (!metadata->decoder) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Failed to create CTF metadata decoder"); - goto error; - } - trace = lttng_live_session_borrow_or_create_trace_by_id(session, - ctf_trace_id); - if (!trace) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Failed to borrow trace"); - goto error; - } - trace->metadata = metadata; - return 0; + bt_self_component *self_comp = session->self_comp; + bt_logging_level log_level = session->log_level; + struct lttng_live_metadata *metadata = NULL; + struct lttng_live_trace *trace; + + ctf_metadata_decoder_config cfg {}; + cfg.log_level = session->log_level; + cfg.self_comp = session->self_comp; + cfg.clock_class_offset_s = 0; + cfg.clock_class_offset_ns = 0; + cfg.create_trace_class = true; + + metadata = g_new0(struct lttng_live_metadata, 1); + if (!metadata) { + return -1; + } + metadata->log_level = session->log_level; + metadata->self_comp = session->self_comp; + metadata->stream_id = stream_id; + + metadata->decoder = ctf_metadata_decoder_create(&cfg); + if (!metadata->decoder) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Failed to create CTF metadata decoder"); + goto error; + } + trace = lttng_live_session_borrow_or_create_trace_by_id(session, ctf_trace_id); + if (!trace) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Failed to borrow trace"); + goto error; + } + trace->metadata = metadata; + return 0; error: - ctf_metadata_decoder_destroy(metadata->decoder); - g_free(metadata); - return -1; + ctf_metadata_decoder_destroy(metadata->decoder); + g_free(metadata); + return -1; } BT_HIDDEN void lttng_live_metadata_fini(struct lttng_live_trace *trace) { - struct lttng_live_metadata *metadata = trace->metadata; - - if (!metadata) { - return; - } - ctf_metadata_decoder_destroy(metadata->decoder); - trace->metadata = NULL; - g_free(metadata); + struct lttng_live_metadata *metadata = trace->metadata; + + if (!metadata) { + return; + } + ctf_metadata_decoder_destroy(metadata->decoder); + trace->metadata = NULL; + g_free(metadata); } diff --git a/src/plugins/ctf/lttng-live/metadata.hpp b/src/plugins/ctf/lttng-live/metadata.hpp index 08a1fb63..486c9132 100644 --- a/src/plugins/ctf/lttng-live/metadata.hpp +++ b/src/plugins/ctf/lttng-live/metadata.hpp @@ -12,12 +12,10 @@ #include "lttng-live.hpp" -int lttng_live_metadata_create_stream(struct lttng_live_session *session, - uint64_t ctf_trace_id, uint64_t stream_id, - const char *trace_name); +int lttng_live_metadata_create_stream(struct lttng_live_session *session, uint64_t ctf_trace_id, + uint64_t stream_id, const char *trace_name); -enum lttng_live_iterator_status lttng_live_metadata_update( - struct lttng_live_trace *trace); +enum lttng_live_iterator_status lttng_live_metadata_update(struct lttng_live_trace *trace); void lttng_live_metadata_fini(struct lttng_live_trace *trace); diff --git a/src/plugins/ctf/lttng-live/viewer-connection.cpp b/src/plugins/ctf/lttng-live/viewer-connection.cpp index 73677fa2..4a761b24 100644 --- a/src/plugins/ctf/lttng-live/viewer-connection.cpp +++ b/src/plugins/ctf/lttng-live/viewer-connection.cpp @@ -6,8 +6,8 @@ */ #define BT_COMP_LOG_SELF_COMP (viewer_connection->self_comp) -#define BT_LOG_OUTPUT_LEVEL (viewer_connection->log_level) -#define BT_LOG_TAG "PLUGIN/SRC.CTF.LTTNG-LIVE/VIEWER" +#define BT_LOG_OUTPUT_LEVEL (viewer_connection->log_level) +#define BT_LOG_TAG "PLUGIN/SRC.CTF.LTTNG-LIVE/VIEWER" #include "logging/comp-logging.h" #include @@ -32,178 +32,160 @@ #include "data-stream.hpp" #include "metadata.hpp" -#define viewer_handle_send_recv_status(_self_comp, _self_comp_class, \ - _status, _action, _msg_str) \ -do { \ - switch (_status) { \ - case LTTNG_LIVE_VIEWER_STATUS_INTERRUPTED: \ - break; \ - case LTTNG_LIVE_VIEWER_STATUS_ERROR: \ - BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(_self_comp, \ - _self_comp_class, "Error " _action " " _msg_str); \ - break; \ - default: \ - bt_common_abort(); \ - } \ -} while (0) - -#define viewer_handle_send_status(_self_comp, _self_comp_class, _status, _msg_str) \ - viewer_handle_send_recv_status(_self_comp, _self_comp_class, _status, \ - "sending", _msg_str) - -#define viewer_handle_recv_status(_self_comp, _self_comp_class, _status, _msg_str) \ - viewer_handle_send_recv_status(_self_comp, _self_comp_class, _status, \ - "receiving", _msg_str) - -#define LTTNG_LIVE_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE_ERRNO(_self_comp, \ - _self_comp_class, _msg, _fmt, ...) \ - do { \ - BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(_self_comp, _self_comp_class, \ - _msg ": %s" _fmt, bt_socket_errormsg(), ##__VA_ARGS__); \ - } while (0) - -static -const char *lttng_viewer_command_string(enum lttng_viewer_command cmd) +#define viewer_handle_send_recv_status(_self_comp, _self_comp_class, _status, _action, _msg_str) \ + do { \ + switch (_status) { \ + case LTTNG_LIVE_VIEWER_STATUS_INTERRUPTED: \ + break; \ + case LTTNG_LIVE_VIEWER_STATUS_ERROR: \ + BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(_self_comp, _self_comp_class, \ + "Error " _action " " _msg_str); \ + break; \ + default: \ + bt_common_abort(); \ + } \ + } while (0) + +#define viewer_handle_send_status(_self_comp, _self_comp_class, _status, _msg_str) \ + viewer_handle_send_recv_status(_self_comp, _self_comp_class, _status, "sending", _msg_str) + +#define viewer_handle_recv_status(_self_comp, _self_comp_class, _status, _msg_str) \ + viewer_handle_send_recv_status(_self_comp, _self_comp_class, _status, "receiving", _msg_str) + +#define LTTNG_LIVE_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE_ERRNO(_self_comp, _self_comp_class, _msg, \ + _fmt, ...) \ + do { \ + BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(_self_comp, _self_comp_class, _msg ": %s" _fmt, \ + bt_socket_errormsg(), ##__VA_ARGS__); \ + } while (0) + +static const char *lttng_viewer_command_string(enum lttng_viewer_command cmd) { - switch (cmd){ - case LTTNG_VIEWER_CONNECT: - return "CONNECT"; - case LTTNG_VIEWER_LIST_SESSIONS: - return "LIST_SESSIONS"; - case LTTNG_VIEWER_ATTACH_SESSION: - return "ATTACH_SESSION"; - case LTTNG_VIEWER_GET_NEXT_INDEX: - return "GET_NEXT_INDEX"; - case LTTNG_VIEWER_GET_PACKET: - return "GET_PACKET"; - case LTTNG_VIEWER_GET_METADATA: - return "GET_METADATA"; - case LTTNG_VIEWER_GET_NEW_STREAMS: - return "GET_NEW_STREAMS"; - case LTTNG_VIEWER_CREATE_SESSION: - return "CREATE_SESSION"; - case LTTNG_VIEWER_DETACH_SESSION: - return "DETACH_SESSION"; - } - - bt_common_abort(); + switch (cmd) { + case LTTNG_VIEWER_CONNECT: + return "CONNECT"; + case LTTNG_VIEWER_LIST_SESSIONS: + return "LIST_SESSIONS"; + case LTTNG_VIEWER_ATTACH_SESSION: + return "ATTACH_SESSION"; + case LTTNG_VIEWER_GET_NEXT_INDEX: + return "GET_NEXT_INDEX"; + case LTTNG_VIEWER_GET_PACKET: + return "GET_PACKET"; + case LTTNG_VIEWER_GET_METADATA: + return "GET_METADATA"; + case LTTNG_VIEWER_GET_NEW_STREAMS: + return "GET_NEW_STREAMS"; + case LTTNG_VIEWER_CREATE_SESSION: + return "CREATE_SESSION"; + case LTTNG_VIEWER_DETACH_SESSION: + return "DETACH_SESSION"; + } + + bt_common_abort(); } -static -const char *lttng_viewer_next_index_return_code_string( - enum lttng_viewer_next_index_return_code code) +static const char * +lttng_viewer_next_index_return_code_string(enum lttng_viewer_next_index_return_code code) { - switch (code) { - case LTTNG_VIEWER_INDEX_OK: - return "INDEX_OK"; - case LTTNG_VIEWER_INDEX_RETRY: - return "INDEX_RETRY"; - case LTTNG_VIEWER_INDEX_HUP: - return "INDEX_HUP"; - case LTTNG_VIEWER_INDEX_ERR: - return "INDEX_ERR"; - case LTTNG_VIEWER_INDEX_INACTIVE: - return "INDEX_INACTIVE"; - case LTTNG_VIEWER_INDEX_EOF: - return "INDEX_EOF"; - } - - bt_common_abort(); + switch (code) { + case LTTNG_VIEWER_INDEX_OK: + return "INDEX_OK"; + case LTTNG_VIEWER_INDEX_RETRY: + return "INDEX_RETRY"; + case LTTNG_VIEWER_INDEX_HUP: + return "INDEX_HUP"; + case LTTNG_VIEWER_INDEX_ERR: + return "INDEX_ERR"; + case LTTNG_VIEWER_INDEX_INACTIVE: + return "INDEX_INACTIVE"; + case LTTNG_VIEWER_INDEX_EOF: + return "INDEX_EOF"; + } + + bt_common_abort(); } -static -const char *lttng_viewer_next_index_return_code_string(uint32_t code) +static const char *lttng_viewer_next_index_return_code_string(uint32_t code) { - return lttng_viewer_next_index_return_code_string( - (lttng_viewer_next_index_return_code) code); + return lttng_viewer_next_index_return_code_string((lttng_viewer_next_index_return_code) code); } -static -const char *lttng_viewer_get_packet_return_code_string( - enum lttng_viewer_get_packet_return_code code) +static const char * +lttng_viewer_get_packet_return_code_string(enum lttng_viewer_get_packet_return_code code) { - switch (code) { - case LTTNG_VIEWER_GET_PACKET_OK: - return "GET_PACKET_OK"; - case LTTNG_VIEWER_GET_PACKET_RETRY: - return "GET_PACKET_RETRY"; - case LTTNG_VIEWER_GET_PACKET_ERR: - return "GET_PACKET_ERR"; - case LTTNG_VIEWER_GET_PACKET_EOF: - return "GET_PACKET_EOF"; - } - - bt_common_abort(); + switch (code) { + case LTTNG_VIEWER_GET_PACKET_OK: + return "GET_PACKET_OK"; + case LTTNG_VIEWER_GET_PACKET_RETRY: + return "GET_PACKET_RETRY"; + case LTTNG_VIEWER_GET_PACKET_ERR: + return "GET_PACKET_ERR"; + case LTTNG_VIEWER_GET_PACKET_EOF: + return "GET_PACKET_EOF"; + } + + bt_common_abort(); }; -static -const char *lttng_viewer_get_packet_return_code_string(uint32_t code) +static const char *lttng_viewer_get_packet_return_code_string(uint32_t code) { - return lttng_viewer_get_packet_return_code_string( - (lttng_viewer_get_packet_return_code) code); + return lttng_viewer_get_packet_return_code_string((lttng_viewer_get_packet_return_code) code); } -static -const char *lttng_viewer_seek_string(enum lttng_viewer_seek seek) +static const char *lttng_viewer_seek_string(enum lttng_viewer_seek seek) { - switch (seek) { - case LTTNG_VIEWER_SEEK_BEGINNING: - return "SEEK_BEGINNING"; - case LTTNG_VIEWER_SEEK_LAST: - return "SEEK_LAST"; - } - - bt_common_abort(); + switch (seek) { + case LTTNG_VIEWER_SEEK_BEGINNING: + return "SEEK_BEGINNING"; + case LTTNG_VIEWER_SEEK_LAST: + return "SEEK_LAST"; + } + + bt_common_abort(); } -static inline -enum lttng_live_iterator_status viewer_status_to_live_iterator_status( - enum lttng_live_viewer_status viewer_status) +static inline enum lttng_live_iterator_status +viewer_status_to_live_iterator_status(enum lttng_live_viewer_status viewer_status) { - switch (viewer_status) { - case LTTNG_LIVE_VIEWER_STATUS_OK: - return LTTNG_LIVE_ITERATOR_STATUS_OK; - case LTTNG_LIVE_VIEWER_STATUS_INTERRUPTED: - return LTTNG_LIVE_ITERATOR_STATUS_AGAIN; - case LTTNG_LIVE_VIEWER_STATUS_ERROR: - return LTTNG_LIVE_ITERATOR_STATUS_ERROR; - } - - bt_common_abort(); + switch (viewer_status) { + case LTTNG_LIVE_VIEWER_STATUS_OK: + return LTTNG_LIVE_ITERATOR_STATUS_OK; + case LTTNG_LIVE_VIEWER_STATUS_INTERRUPTED: + return LTTNG_LIVE_ITERATOR_STATUS_AGAIN; + case LTTNG_LIVE_VIEWER_STATUS_ERROR: + return LTTNG_LIVE_ITERATOR_STATUS_ERROR; + } + + bt_common_abort(); } -static inline -enum ctf_msg_iter_medium_status viewer_status_to_ctf_msg_iter_medium_status( - enum lttng_live_viewer_status viewer_status) +static inline enum ctf_msg_iter_medium_status +viewer_status_to_ctf_msg_iter_medium_status(enum lttng_live_viewer_status viewer_status) { - switch (viewer_status) { - case LTTNG_LIVE_VIEWER_STATUS_OK: - return CTF_MSG_ITER_MEDIUM_STATUS_OK; - case LTTNG_LIVE_VIEWER_STATUS_INTERRUPTED: - return CTF_MSG_ITER_MEDIUM_STATUS_AGAIN; - case LTTNG_LIVE_VIEWER_STATUS_ERROR: - return CTF_MSG_ITER_MEDIUM_STATUS_ERROR; - } - - bt_common_abort(); + switch (viewer_status) { + case LTTNG_LIVE_VIEWER_STATUS_OK: + return CTF_MSG_ITER_MEDIUM_STATUS_OK; + case LTTNG_LIVE_VIEWER_STATUS_INTERRUPTED: + return CTF_MSG_ITER_MEDIUM_STATUS_AGAIN; + case LTTNG_LIVE_VIEWER_STATUS_ERROR: + return CTF_MSG_ITER_MEDIUM_STATUS_ERROR; + } + + bt_common_abort(); } -static inline -void viewer_connection_close_socket( - struct live_viewer_connection *viewer_connection) +static inline void viewer_connection_close_socket(struct live_viewer_connection *viewer_connection) { - bt_self_component_class *self_comp_class = - viewer_connection->self_comp_class; - bt_self_component *self_comp = - viewer_connection->self_comp; - int ret = bt_socket_close(viewer_connection->control_sock); - if (ret == -1) { - BT_COMP_OR_COMP_CLASS_LOGW_ERRNO( - self_comp, self_comp_class, - "Error closing viewer connection socket: ", "."); - } - - viewer_connection->control_sock = BT_INVALID_SOCKET; + bt_self_component_class *self_comp_class = viewer_connection->self_comp_class; + bt_self_component *self_comp = viewer_connection->self_comp; + int ret = bt_socket_close(viewer_connection->control_sock); + if (ret == -1) { + BT_COMP_OR_COMP_CLASS_LOGW_ERRNO(self_comp, self_comp_class, + "Error closing viewer connection socket: ", "."); + } + + viewer_connection->control_sock = BT_INVALID_SOCKET; } /* @@ -212,84 +194,78 @@ void viewer_connection_close_socket( * If it's interrupted, it returns _INTERRUPTED, * otherwise, it returns _ERROR. */ -static -enum lttng_live_viewer_status lttng_live_recv( - struct live_viewer_connection *viewer_connection, - void *buf, size_t len) +static enum lttng_live_viewer_status +lttng_live_recv(struct live_viewer_connection *viewer_connection, void *buf, size_t len) { - ssize_t received; - bt_self_component_class *self_comp_class = - viewer_connection->self_comp_class; - bt_self_component *self_comp = - viewer_connection->self_comp; - size_t total_received = 0, to_receive = len; - struct lttng_live_msg_iter *lttng_live_msg_iter = - viewer_connection->lttng_live_msg_iter; - enum lttng_live_viewer_status status; - BT_SOCKET sock = viewer_connection->control_sock; - - /* - * Receive a message from the Relay. - */ - do { - received = bt_socket_recv(sock, (char *) buf + total_received, to_receive, 0); - if (received == BT_SOCKET_ERROR) { - if (bt_socket_interrupted()) { - if (lttng_live_graph_is_canceled(lttng_live_msg_iter)) { - /* - * This interruption was due to a - * SIGINT and the graph is being torn - * down. - */ - status = LTTNG_LIVE_VIEWER_STATUS_INTERRUPTED; - lttng_live_msg_iter->was_interrupted = true; - goto end; - } else { - /* - * A signal was received, but the graph - * is not being torn down. Carry on. - */ - continue; - } - } else { - /* - * For any other types of socket error, close - * the socket and return an error. - */ - LTTNG_LIVE_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE_ERRNO( - self_comp, self_comp_class, - "Error receiving from Relay", "."); - - viewer_connection_close_socket(viewer_connection); - status = LTTNG_LIVE_VIEWER_STATUS_ERROR; - goto end; - } - } else if (received == 0) { - /* - * The recv() call returned 0. This means the - * connection was orderly shutdown from the other peer. - * If that happens when we are trying to receive - * a message from it, it means something when wrong. - * Close the socket and return an error. - */ - BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, - self_comp_class, "Remote side has closed connection"); - viewer_connection_close_socket(viewer_connection); - status = LTTNG_LIVE_VIEWER_STATUS_ERROR; - goto end; - } - - BT_ASSERT(received <= to_receive); - total_received += received; - to_receive -= received; - - } while (to_receive > 0); - - BT_ASSERT(total_received == len); - status = LTTNG_LIVE_VIEWER_STATUS_OK; + ssize_t received; + bt_self_component_class *self_comp_class = viewer_connection->self_comp_class; + bt_self_component *self_comp = viewer_connection->self_comp; + size_t total_received = 0, to_receive = len; + struct lttng_live_msg_iter *lttng_live_msg_iter = viewer_connection->lttng_live_msg_iter; + enum lttng_live_viewer_status status; + BT_SOCKET sock = viewer_connection->control_sock; + + /* + * Receive a message from the Relay. + */ + do { + received = bt_socket_recv(sock, (char *) buf + total_received, to_receive, 0); + if (received == BT_SOCKET_ERROR) { + if (bt_socket_interrupted()) { + if (lttng_live_graph_is_canceled(lttng_live_msg_iter)) { + /* + * This interruption was due to a + * SIGINT and the graph is being torn + * down. + */ + status = LTTNG_LIVE_VIEWER_STATUS_INTERRUPTED; + lttng_live_msg_iter->was_interrupted = true; + goto end; + } else { + /* + * A signal was received, but the graph + * is not being torn down. Carry on. + */ + continue; + } + } else { + /* + * For any other types of socket error, close + * the socket and return an error. + */ + LTTNG_LIVE_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE_ERRNO( + self_comp, self_comp_class, "Error receiving from Relay", "."); + + viewer_connection_close_socket(viewer_connection); + status = LTTNG_LIVE_VIEWER_STATUS_ERROR; + goto end; + } + } else if (received == 0) { + /* + * The recv() call returned 0. This means the + * connection was orderly shutdown from the other peer. + * If that happens when we are trying to receive + * a message from it, it means something when wrong. + * Close the socket and return an error. + */ + BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class, + "Remote side has closed connection"); + viewer_connection_close_socket(viewer_connection); + status = LTTNG_LIVE_VIEWER_STATUS_ERROR; + goto end; + } + + BT_ASSERT(received <= to_receive); + total_received += received; + to_receive -= received; + + } while (to_receive > 0); + + BT_ASSERT(total_received == len); + status = LTTNG_LIVE_VIEWER_STATUS_OK; end: - return status; + return status; } /* @@ -298,528 +274,487 @@ end: * If it's interrupted, it returns _INTERRUPTED, * otherwise, it returns _ERROR. */ -static -enum lttng_live_viewer_status lttng_live_send( - struct live_viewer_connection *viewer_connection, - const void *buf, size_t len) +static enum lttng_live_viewer_status +lttng_live_send(struct live_viewer_connection *viewer_connection, const void *buf, size_t len) { - enum lttng_live_viewer_status status; - bt_self_component_class *self_comp_class = - viewer_connection->self_comp_class; - bt_self_component *self_comp = - viewer_connection->self_comp; - struct lttng_live_msg_iter *lttng_live_msg_iter = - viewer_connection->lttng_live_msg_iter; - BT_SOCKET sock = viewer_connection->control_sock; - size_t to_send = len; - ssize_t total_sent = 0; - - do { - ssize_t sent = bt_socket_send_nosigpipe(sock, (char *) buf + total_sent, - to_send); - if (sent == BT_SOCKET_ERROR) { - if (bt_socket_interrupted()) { - if (lttng_live_graph_is_canceled(lttng_live_msg_iter)) { - /* - * This interruption was a SIGINT and - * the graph is being teared down. - */ - status = LTTNG_LIVE_VIEWER_STATUS_INTERRUPTED; - lttng_live_msg_iter->was_interrupted = true; - goto end; - } else { - /* - * A signal was received, but the graph - * is not being teared down. Carry on. - */ - continue; - } - } else { - /* - * For any other types of socket error, close - * the socket and return an error. - */ - LTTNG_LIVE_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE_ERRNO( - self_comp, self_comp_class, - "Error sending to Relay", "."); - - viewer_connection_close_socket(viewer_connection); - status = LTTNG_LIVE_VIEWER_STATUS_ERROR; - goto end; - } - } - - BT_ASSERT(sent <= to_send); - total_sent += sent; - to_send -= sent; - - } while (to_send > 0); - - BT_ASSERT(total_sent == len); - status = LTTNG_LIVE_VIEWER_STATUS_OK; + enum lttng_live_viewer_status status; + bt_self_component_class *self_comp_class = viewer_connection->self_comp_class; + bt_self_component *self_comp = viewer_connection->self_comp; + struct lttng_live_msg_iter *lttng_live_msg_iter = viewer_connection->lttng_live_msg_iter; + BT_SOCKET sock = viewer_connection->control_sock; + size_t to_send = len; + ssize_t total_sent = 0; + + do { + ssize_t sent = bt_socket_send_nosigpipe(sock, (char *) buf + total_sent, to_send); + if (sent == BT_SOCKET_ERROR) { + if (bt_socket_interrupted()) { + if (lttng_live_graph_is_canceled(lttng_live_msg_iter)) { + /* + * This interruption was a SIGINT and + * the graph is being teared down. + */ + status = LTTNG_LIVE_VIEWER_STATUS_INTERRUPTED; + lttng_live_msg_iter->was_interrupted = true; + goto end; + } else { + /* + * A signal was received, but the graph + * is not being teared down. Carry on. + */ + continue; + } + } else { + /* + * For any other types of socket error, close + * the socket and return an error. + */ + LTTNG_LIVE_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE_ERRNO( + self_comp, self_comp_class, "Error sending to Relay", "."); + + viewer_connection_close_socket(viewer_connection); + status = LTTNG_LIVE_VIEWER_STATUS_ERROR; + goto end; + } + } + + BT_ASSERT(sent <= to_send); + total_sent += sent; + to_send -= sent; + + } while (to_send > 0); + + BT_ASSERT(total_sent == len); + status = LTTNG_LIVE_VIEWER_STATUS_OK; end: - return status; + return status; } -static -int parse_url(struct live_viewer_connection *viewer_connection) +static int parse_url(struct live_viewer_connection *viewer_connection) { - char error_buf[256] = { 0 }; - bt_self_component *self_comp = viewer_connection->self_comp; - bt_self_component_class *self_comp_class = viewer_connection->self_comp_class; - struct bt_common_lttng_live_url_parts lttng_live_url_parts = { 0 }; - int ret = -1; - const char *path = viewer_connection->url->str; - - if (!path) { - goto end; - } - - lttng_live_url_parts = bt_common_parse_lttng_live_url(path, error_buf, - sizeof(error_buf)); - if (!lttng_live_url_parts.proto) { - BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, - self_comp_class,"Invalid LTTng live URL format: %s", - error_buf); - goto end; - } - viewer_connection->proto = lttng_live_url_parts.proto; - lttng_live_url_parts.proto = NULL; - - viewer_connection->relay_hostname = lttng_live_url_parts.hostname; - lttng_live_url_parts.hostname = NULL; - - if (lttng_live_url_parts.port >= 0) { - viewer_connection->port = lttng_live_url_parts.port; - } else { - viewer_connection->port = LTTNG_DEFAULT_NETWORK_VIEWER_PORT; - } - - viewer_connection->target_hostname = lttng_live_url_parts.target_hostname; - lttng_live_url_parts.target_hostname = NULL; - - if (lttng_live_url_parts.session_name) { - viewer_connection->session_name = lttng_live_url_parts.session_name; - lttng_live_url_parts.session_name = NULL; - } - - ret = 0; + char error_buf[256] = {0}; + bt_self_component *self_comp = viewer_connection->self_comp; + bt_self_component_class *self_comp_class = viewer_connection->self_comp_class; + struct bt_common_lttng_live_url_parts lttng_live_url_parts = {0}; + int ret = -1; + const char *path = viewer_connection->url->str; + + if (!path) { + goto end; + } + + lttng_live_url_parts = bt_common_parse_lttng_live_url(path, error_buf, sizeof(error_buf)); + if (!lttng_live_url_parts.proto) { + BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class, + "Invalid LTTng live URL format: %s", error_buf); + goto end; + } + viewer_connection->proto = lttng_live_url_parts.proto; + lttng_live_url_parts.proto = NULL; + + viewer_connection->relay_hostname = lttng_live_url_parts.hostname; + lttng_live_url_parts.hostname = NULL; + + if (lttng_live_url_parts.port >= 0) { + viewer_connection->port = lttng_live_url_parts.port; + } else { + viewer_connection->port = LTTNG_DEFAULT_NETWORK_VIEWER_PORT; + } + + viewer_connection->target_hostname = lttng_live_url_parts.target_hostname; + lttng_live_url_parts.target_hostname = NULL; + + if (lttng_live_url_parts.session_name) { + viewer_connection->session_name = lttng_live_url_parts.session_name; + lttng_live_url_parts.session_name = NULL; + } + + ret = 0; end: - bt_common_destroy_lttng_live_url_parts(<tng_live_url_parts); - return ret; + bt_common_destroy_lttng_live_url_parts(<tng_live_url_parts); + return ret; } -static -enum lttng_live_viewer_status lttng_live_handshake( - struct live_viewer_connection *viewer_connection) +static enum lttng_live_viewer_status +lttng_live_handshake(struct live_viewer_connection *viewer_connection) { - struct lttng_viewer_cmd cmd; - struct lttng_viewer_connect connect; - enum lttng_live_viewer_status status; - bt_self_component_class *self_comp_class = viewer_connection->self_comp_class; - bt_self_component *self_comp = viewer_connection->self_comp; - const size_t cmd_buf_len = sizeof(cmd) + sizeof(connect); - char cmd_buf[cmd_buf_len]; - - BT_COMP_OR_COMP_CLASS_LOGD(self_comp, self_comp_class, - "Handshaking with the relay daemon: cmd=%s, major-version=%u, minor-version=%u", - lttng_viewer_command_string(LTTNG_VIEWER_CONNECT), LTTNG_LIVE_MAJOR, - LTTNG_LIVE_MINOR); - - cmd.cmd = htobe32(LTTNG_VIEWER_CONNECT); - cmd.data_size = htobe64((uint64_t) sizeof(connect)); - cmd.cmd_version = htobe32(0); - - connect.viewer_session_id = -1ULL; /* will be set on recv */ - connect.major = htobe32(LTTNG_LIVE_MAJOR); - connect.minor = htobe32(LTTNG_LIVE_MINOR); - connect.type = htobe32(LTTNG_VIEWER_CLIENT_COMMAND); - - /* - * Merge the cmd and connection request to prevent a write-write - * sequence on the TCP socket. Otherwise, a delayed ACK will prevent the - * second write to be performed quickly in presence of Nagle's algorithm - */ - memcpy(cmd_buf, &cmd, sizeof(cmd)); - memcpy(cmd_buf + sizeof(cmd), &connect, sizeof(connect)); - - status = lttng_live_send(viewer_connection, &cmd_buf, cmd_buf_len); - if (status != LTTNG_LIVE_VIEWER_STATUS_OK) { - viewer_handle_send_status(self_comp, self_comp_class, - status, "viewer connect command"); - goto end; - } - - status = lttng_live_recv(viewer_connection, &connect, sizeof(connect)); - if (status != LTTNG_LIVE_VIEWER_STATUS_OK) { - viewer_handle_recv_status(self_comp, self_comp_class, - status, "viewer connect reply"); - goto end; - } - - BT_COMP_OR_COMP_CLASS_LOGI(self_comp, self_comp_class, - "Received viewer session ID : %" PRIu64, - (uint64_t) be64toh(connect.viewer_session_id)); - BT_COMP_OR_COMP_CLASS_LOGI(self_comp, self_comp_class, - "Relayd version : %u.%u", be32toh(connect.major), - be32toh(connect.minor)); - - if (LTTNG_LIVE_MAJOR != be32toh(connect.major)) { - BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, - self_comp_class, "Incompatible lttng-relayd protocol"); - status = LTTNG_LIVE_VIEWER_STATUS_ERROR; - goto end; - } - /* Use the smallest protocol version implemented. */ - if (LTTNG_LIVE_MINOR > be32toh(connect.minor)) { - viewer_connection->minor = be32toh(connect.minor); - } else { - viewer_connection->minor = LTTNG_LIVE_MINOR; - } - viewer_connection->major = LTTNG_LIVE_MAJOR; - - status = LTTNG_LIVE_VIEWER_STATUS_OK; - - goto end; + struct lttng_viewer_cmd cmd; + struct lttng_viewer_connect connect; + enum lttng_live_viewer_status status; + bt_self_component_class *self_comp_class = viewer_connection->self_comp_class; + bt_self_component *self_comp = viewer_connection->self_comp; + const size_t cmd_buf_len = sizeof(cmd) + sizeof(connect); + char cmd_buf[cmd_buf_len]; + + BT_COMP_OR_COMP_CLASS_LOGD( + self_comp, self_comp_class, + "Handshaking with the relay daemon: cmd=%s, major-version=%u, minor-version=%u", + lttng_viewer_command_string(LTTNG_VIEWER_CONNECT), LTTNG_LIVE_MAJOR, LTTNG_LIVE_MINOR); + + cmd.cmd = htobe32(LTTNG_VIEWER_CONNECT); + cmd.data_size = htobe64((uint64_t) sizeof(connect)); + cmd.cmd_version = htobe32(0); + + connect.viewer_session_id = -1ULL; /* will be set on recv */ + connect.major = htobe32(LTTNG_LIVE_MAJOR); + connect.minor = htobe32(LTTNG_LIVE_MINOR); + connect.type = htobe32(LTTNG_VIEWER_CLIENT_COMMAND); + + /* + * Merge the cmd and connection request to prevent a write-write + * sequence on the TCP socket. Otherwise, a delayed ACK will prevent the + * second write to be performed quickly in presence of Nagle's algorithm + */ + memcpy(cmd_buf, &cmd, sizeof(cmd)); + memcpy(cmd_buf + sizeof(cmd), &connect, sizeof(connect)); + + status = lttng_live_send(viewer_connection, &cmd_buf, cmd_buf_len); + if (status != LTTNG_LIVE_VIEWER_STATUS_OK) { + viewer_handle_send_status(self_comp, self_comp_class, status, "viewer connect command"); + goto end; + } + + status = lttng_live_recv(viewer_connection, &connect, sizeof(connect)); + if (status != LTTNG_LIVE_VIEWER_STATUS_OK) { + viewer_handle_recv_status(self_comp, self_comp_class, status, "viewer connect reply"); + goto end; + } + + BT_COMP_OR_COMP_CLASS_LOGI(self_comp, self_comp_class, "Received viewer session ID : %" PRIu64, + (uint64_t) be64toh(connect.viewer_session_id)); + BT_COMP_OR_COMP_CLASS_LOGI(self_comp, self_comp_class, "Relayd version : %u.%u", + be32toh(connect.major), be32toh(connect.minor)); + + if (LTTNG_LIVE_MAJOR != be32toh(connect.major)) { + BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class, + "Incompatible lttng-relayd protocol"); + status = LTTNG_LIVE_VIEWER_STATUS_ERROR; + goto end; + } + /* Use the smallest protocol version implemented. */ + if (LTTNG_LIVE_MINOR > be32toh(connect.minor)) { + viewer_connection->minor = be32toh(connect.minor); + } else { + viewer_connection->minor = LTTNG_LIVE_MINOR; + } + viewer_connection->major = LTTNG_LIVE_MAJOR; + + status = LTTNG_LIVE_VIEWER_STATUS_OK; + + goto end; end: - return status; + return status; } -static -enum lttng_live_viewer_status lttng_live_connect_viewer( - struct live_viewer_connection *viewer_connection) +static enum lttng_live_viewer_status +lttng_live_connect_viewer(struct live_viewer_connection *viewer_connection) { - struct hostent *host; - struct sockaddr_in server_addr; - enum lttng_live_viewer_status status; - bt_self_component_class *self_comp_class = viewer_connection->self_comp_class; - bt_self_component *self_comp = viewer_connection->self_comp; - - if (parse_url(viewer_connection)) { - BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, - self_comp_class, "Failed to parse URL"); - status = LTTNG_LIVE_VIEWER_STATUS_ERROR; - goto error; - } - - BT_COMP_OR_COMP_CLASS_LOGD(self_comp, self_comp_class, - "Connecting to hostname : %s, port : %d, " - "target hostname : %s, session name : %s, proto : %s", - viewer_connection->relay_hostname->str, - viewer_connection->port, - !viewer_connection->target_hostname ? - "" : viewer_connection->target_hostname->str, - !viewer_connection->session_name ? - "" : viewer_connection->session_name->str, - viewer_connection->proto->str); - - host = gethostbyname(viewer_connection->relay_hostname->str); - if (!host) { - BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, - self_comp_class, "Cannot lookup hostname: hostname=\"%s\"", - viewer_connection->relay_hostname->str); - status = LTTNG_LIVE_VIEWER_STATUS_ERROR; - goto error; - } - - if ((viewer_connection->control_sock = socket(AF_INET, SOCK_STREAM, 0)) == BT_INVALID_SOCKET) { - BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, - self_comp_class, "Socket creation failed: %s", bt_socket_errormsg()); - status = LTTNG_LIVE_VIEWER_STATUS_ERROR; - goto error; - } - - server_addr.sin_family = AF_INET; - server_addr.sin_port = htons(viewer_connection->port); - server_addr.sin_addr = *((struct in_addr *) host->h_addr); - memset(&(server_addr.sin_zero), 0, 8); - - if (connect(viewer_connection->control_sock, (struct sockaddr *) &server_addr, - sizeof(struct sockaddr)) == BT_SOCKET_ERROR) { - BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, - self_comp_class, "Connection failed: %s", - bt_socket_errormsg()); - status = LTTNG_LIVE_VIEWER_STATUS_ERROR; - goto error; - } - - status = lttng_live_handshake(viewer_connection); - - /* - * Only print error and append cause in case of error. not in case of - * interruption. - */ - if (status == LTTNG_LIVE_VIEWER_STATUS_ERROR) { - BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, - self_comp_class, "Viewer handshake failed"); - goto error; - } else if (status == LTTNG_LIVE_VIEWER_STATUS_INTERRUPTED) { - goto end; - } - - goto end; + struct hostent *host; + struct sockaddr_in server_addr; + enum lttng_live_viewer_status status; + bt_self_component_class *self_comp_class = viewer_connection->self_comp_class; + bt_self_component *self_comp = viewer_connection->self_comp; + + if (parse_url(viewer_connection)) { + BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class, "Failed to parse URL"); + status = LTTNG_LIVE_VIEWER_STATUS_ERROR; + goto error; + } + + BT_COMP_OR_COMP_CLASS_LOGD( + self_comp, self_comp_class, + "Connecting to hostname : %s, port : %d, " + "target hostname : %s, session name : %s, proto : %s", + viewer_connection->relay_hostname->str, viewer_connection->port, + !viewer_connection->target_hostname ? "" : viewer_connection->target_hostname->str, + !viewer_connection->session_name ? "" : viewer_connection->session_name->str, + viewer_connection->proto->str); + + host = gethostbyname(viewer_connection->relay_hostname->str); + if (!host) { + BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class, + "Cannot lookup hostname: hostname=\"%s\"", + viewer_connection->relay_hostname->str); + status = LTTNG_LIVE_VIEWER_STATUS_ERROR; + goto error; + } + + if ((viewer_connection->control_sock = socket(AF_INET, SOCK_STREAM, 0)) == BT_INVALID_SOCKET) { + BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class, + "Socket creation failed: %s", bt_socket_errormsg()); + status = LTTNG_LIVE_VIEWER_STATUS_ERROR; + goto error; + } + + server_addr.sin_family = AF_INET; + server_addr.sin_port = htons(viewer_connection->port); + server_addr.sin_addr = *((struct in_addr *) host->h_addr); + memset(&(server_addr.sin_zero), 0, 8); + + if (connect(viewer_connection->control_sock, (struct sockaddr *) &server_addr, + sizeof(struct sockaddr)) == BT_SOCKET_ERROR) { + BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class, "Connection failed: %s", + bt_socket_errormsg()); + status = LTTNG_LIVE_VIEWER_STATUS_ERROR; + goto error; + } + + status = lttng_live_handshake(viewer_connection); + + /* + * Only print error and append cause in case of error. not in case of + * interruption. + */ + if (status == LTTNG_LIVE_VIEWER_STATUS_ERROR) { + BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class, + "Viewer handshake failed"); + goto error; + } else if (status == LTTNG_LIVE_VIEWER_STATUS_INTERRUPTED) { + goto end; + } + + goto end; error: - if (viewer_connection->control_sock != BT_INVALID_SOCKET) { - if (bt_socket_close(viewer_connection->control_sock) == BT_SOCKET_ERROR) { - BT_COMP_OR_COMP_CLASS_LOGW(self_comp, self_comp_class, - "Error closing socket: %s.", bt_socket_errormsg()); - } - } - viewer_connection->control_sock = BT_INVALID_SOCKET; + if (viewer_connection->control_sock != BT_INVALID_SOCKET) { + if (bt_socket_close(viewer_connection->control_sock) == BT_SOCKET_ERROR) { + BT_COMP_OR_COMP_CLASS_LOGW(self_comp, self_comp_class, "Error closing socket: %s.", + bt_socket_errormsg()); + } + } + viewer_connection->control_sock = BT_INVALID_SOCKET; end: - return status; + return status; } -static -void lttng_live_disconnect_viewer( - struct live_viewer_connection *viewer_connection) +static void lttng_live_disconnect_viewer(struct live_viewer_connection *viewer_connection) { - bt_self_component_class *self_comp_class = viewer_connection->self_comp_class; - bt_self_component *self_comp = viewer_connection->self_comp; - - if (viewer_connection->control_sock == BT_INVALID_SOCKET) { - return; - } - if (bt_socket_close(viewer_connection->control_sock) == BT_SOCKET_ERROR) { - BT_COMP_OR_COMP_CLASS_LOGW(self_comp, self_comp_class, - "Error closing socket: %s", bt_socket_errormsg()); - viewer_connection->control_sock = BT_INVALID_SOCKET; - } + bt_self_component_class *self_comp_class = viewer_connection->self_comp_class; + bt_self_component *self_comp = viewer_connection->self_comp; + + if (viewer_connection->control_sock == BT_INVALID_SOCKET) { + return; + } + if (bt_socket_close(viewer_connection->control_sock) == BT_SOCKET_ERROR) { + BT_COMP_OR_COMP_CLASS_LOGW(self_comp, self_comp_class, "Error closing socket: %s", + bt_socket_errormsg()); + viewer_connection->control_sock = BT_INVALID_SOCKET; + } } -static -int list_update_session(bt_value *results, - const struct lttng_viewer_session *session, - bool *_found, struct live_viewer_connection *viewer_connection) +static int list_update_session(bt_value *results, const struct lttng_viewer_session *session, + bool *_found, struct live_viewer_connection *viewer_connection) { - bt_self_component_class *self_comp_class = viewer_connection->self_comp_class; - bt_self_component *self_comp = viewer_connection->self_comp; - int ret = 0; - uint64_t i, len; - bt_value *map = NULL; - bt_value *hostname = NULL; - bt_value *session_name = NULL; - bt_value *btval = NULL; - bool found = false; - - len = bt_value_array_get_length(results); - for (i = 0; i < len; i++) { - const char *hostname_str = NULL; - const char *session_name_str = NULL; - - map = bt_value_array_borrow_element_by_index(results, i); - hostname = bt_value_map_borrow_entry_value(map, "target-hostname"); - if (!hostname) { - BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, - self_comp_class, - "Error borrowing \"target-hostname\" entry."); - ret = -1; - goto end; - } - session_name = bt_value_map_borrow_entry_value(map, "session-name"); - if (!session_name) { - BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, - self_comp_class, - "Error borrowing \"session-name\" entry."); - ret = -1; - goto end; - } - hostname_str = bt_value_string_get(hostname); - session_name_str = bt_value_string_get(session_name); - - if (strcmp(session->hostname, hostname_str) == 0 - && strcmp(session->session_name, session_name_str) == 0) { - int64_t val; - uint32_t streams = be32toh(session->streams); - uint32_t clients = be32toh(session->clients); - - found = true; - - btval = bt_value_map_borrow_entry_value(map, "stream-count"); - if (!btval) { - BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( - self_comp, self_comp_class, - "Error borrowing \"stream-count\" entry."); - ret = -1; - goto end; - } - val = bt_value_integer_unsigned_get(btval); - /* sum */ - val += streams; - bt_value_integer_unsigned_set(btval, val); - - btval = bt_value_map_borrow_entry_value(map, "client-count"); - if (!btval) { - BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( - self_comp, self_comp_class, - "Error borrowing \"client-count\" entry."); - ret = -1; - goto end; - } - val = bt_value_integer_unsigned_get(btval); - /* max */ - val = bt_max_t(int64_t, clients, val); - bt_value_integer_unsigned_set(btval, val); - } - - if (found) { - break; - } - } + bt_self_component_class *self_comp_class = viewer_connection->self_comp_class; + bt_self_component *self_comp = viewer_connection->self_comp; + int ret = 0; + uint64_t i, len; + bt_value *map = NULL; + bt_value *hostname = NULL; + bt_value *session_name = NULL; + bt_value *btval = NULL; + bool found = false; + + len = bt_value_array_get_length(results); + for (i = 0; i < len; i++) { + const char *hostname_str = NULL; + const char *session_name_str = NULL; + + map = bt_value_array_borrow_element_by_index(results, i); + hostname = bt_value_map_borrow_entry_value(map, "target-hostname"); + if (!hostname) { + BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class, + "Error borrowing \"target-hostname\" entry."); + ret = -1; + goto end; + } + session_name = bt_value_map_borrow_entry_value(map, "session-name"); + if (!session_name) { + BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class, + "Error borrowing \"session-name\" entry."); + ret = -1; + goto end; + } + hostname_str = bt_value_string_get(hostname); + session_name_str = bt_value_string_get(session_name); + + if (strcmp(session->hostname, hostname_str) == 0 && + strcmp(session->session_name, session_name_str) == 0) { + int64_t val; + uint32_t streams = be32toh(session->streams); + uint32_t clients = be32toh(session->clients); + + found = true; + + btval = bt_value_map_borrow_entry_value(map, "stream-count"); + if (!btval) { + BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class, + "Error borrowing \"stream-count\" entry."); + ret = -1; + goto end; + } + val = bt_value_integer_unsigned_get(btval); + /* sum */ + val += streams; + bt_value_integer_unsigned_set(btval, val); + + btval = bt_value_map_borrow_entry_value(map, "client-count"); + if (!btval) { + BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class, + "Error borrowing \"client-count\" entry."); + ret = -1; + goto end; + } + val = bt_value_integer_unsigned_get(btval); + /* max */ + val = bt_max_t(int64_t, clients, val); + bt_value_integer_unsigned_set(btval, val); + } + + if (found) { + break; + } + } end: - *_found = found; - return ret; + *_found = found; + return ret; } -static -int list_append_session(bt_value *results, - GString *base_url, - const struct lttng_viewer_session *session, - struct live_viewer_connection *viewer_connection) +static int list_append_session(bt_value *results, GString *base_url, + const struct lttng_viewer_session *session, + struct live_viewer_connection *viewer_connection) { - int ret = 0; - bt_self_component_class *self_comp_class = viewer_connection->self_comp_class; - bt_value_map_insert_entry_status insert_status; - bt_value_array_append_element_status append_status; - bt_value *map = NULL; - GString *url = NULL; - bool found = false; - - /* - * If the session already exists, add the stream count to it, - * and do max of client counts. - */ - ret = list_update_session(results, session, &found, viewer_connection); - if (ret || found) { - goto end; - } - - map = bt_value_map_create(); - if (!map) { - BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, - "Error creating map value."); - ret = -1; - goto end; - } - - if (base_url->len < 1) { - BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, - "Error: base_url length smaller than 1."); - ret = -1; - goto end; - } - /* - * key = "url", - * value = , - */ - url = g_string_new(base_url->str); - g_string_append(url, "/host/"); - g_string_append(url, session->hostname); - g_string_append_c(url, '/'); - g_string_append(url, session->session_name); - - insert_status = bt_value_map_insert_string_entry(map, "url", url->str); - if (insert_status != BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) { - BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, - "Error inserting \"url\" entry."); - ret = -1; - goto end; - } - - /* - * key = "target-hostname", - * value = , - */ - insert_status = bt_value_map_insert_string_entry(map, "target-hostname", - session->hostname); - if (insert_status != BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) { - BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, - "Error inserting \"target-hostname\" entry."); - ret = -1; - goto end; - } - - /* - * key = "session-name", - * value = , - */ - insert_status = bt_value_map_insert_string_entry(map, "session-name", - session->session_name); - if (insert_status != BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) { - BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, - "Error inserting \"session-name\" entry."); - ret = -1; - goto end; - } - - /* - * key = "timer-us", - * value = , - */ - { - uint32_t live_timer = be32toh(session->live_timer); - - insert_status = bt_value_map_insert_unsigned_integer_entry( - map, "timer-us", live_timer); - if (insert_status != BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) { - BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, - "Error inserting \"timer-us\" entry."); - ret = -1; - goto end; - } - } - - /* - * key = "stream-count", - * value = , - */ - { - uint32_t streams = be32toh(session->streams); - - insert_status = bt_value_map_insert_unsigned_integer_entry(map, - "stream-count", streams); - if (insert_status != BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) { - BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, - "Error inserting \"stream-count\" entry."); - ret = -1; - goto end; - } - } - - /* - * key = "client-count", - * value = , - */ - { - uint32_t clients = be32toh(session->clients); - - insert_status = bt_value_map_insert_unsigned_integer_entry(map, - "client-count", clients); - if (insert_status != BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) { - BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, - "Error inserting \"client-count\" entry."); - ret = -1; - goto end; - } - } - - append_status = bt_value_array_append_element(results, map); - if (append_status != BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_OK) { - BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, - "Error appending map to results."); - ret = -1; - } + int ret = 0; + bt_self_component_class *self_comp_class = viewer_connection->self_comp_class; + bt_value_map_insert_entry_status insert_status; + bt_value_array_append_element_status append_status; + bt_value *map = NULL; + GString *url = NULL; + bool found = false; + + /* + * If the session already exists, add the stream count to it, + * and do max of client counts. + */ + ret = list_update_session(results, session, &found, viewer_connection); + if (ret || found) { + goto end; + } + + map = bt_value_map_create(); + if (!map) { + BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, "Error creating map value."); + ret = -1; + goto end; + } + + if (base_url->len < 1) { + BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, "Error: base_url length smaller than 1."); + ret = -1; + goto end; + } + /* + * key = "url", + * value = , + */ + url = g_string_new(base_url->str); + g_string_append(url, "/host/"); + g_string_append(url, session->hostname); + g_string_append_c(url, '/'); + g_string_append(url, session->session_name); + + insert_status = bt_value_map_insert_string_entry(map, "url", url->str); + if (insert_status != BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) { + BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, "Error inserting \"url\" entry."); + ret = -1; + goto end; + } + + /* + * key = "target-hostname", + * value = , + */ + insert_status = bt_value_map_insert_string_entry(map, "target-hostname", session->hostname); + if (insert_status != BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) { + BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, + "Error inserting \"target-hostname\" entry."); + ret = -1; + goto end; + } + + /* + * key = "session-name", + * value = , + */ + insert_status = bt_value_map_insert_string_entry(map, "session-name", session->session_name); + if (insert_status != BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) { + BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, "Error inserting \"session-name\" entry."); + ret = -1; + goto end; + } + + /* + * key = "timer-us", + * value = , + */ + { + uint32_t live_timer = be32toh(session->live_timer); + + insert_status = bt_value_map_insert_unsigned_integer_entry(map, "timer-us", live_timer); + if (insert_status != BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) { + BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, "Error inserting \"timer-us\" entry."); + ret = -1; + goto end; + } + } + + /* + * key = "stream-count", + * value = , + */ + { + uint32_t streams = be32toh(session->streams); + + insert_status = bt_value_map_insert_unsigned_integer_entry(map, "stream-count", streams); + if (insert_status != BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) { + BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, + "Error inserting \"stream-count\" entry."); + ret = -1; + goto end; + } + } + + /* + * key = "client-count", + * value = , + */ + { + uint32_t clients = be32toh(session->clients); + + insert_status = bt_value_map_insert_unsigned_integer_entry(map, "client-count", clients); + if (insert_status != BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) { + BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, + "Error inserting \"client-count\" entry."); + ret = -1; + goto end; + } + } + + append_status = bt_value_array_append_element(results, map); + if (append_status != BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_OK) { + BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, "Error appending map to results."); + ret = -1; + } end: - if (url) { - g_string_free(url, true); - } - BT_VALUE_PUT_REF_AND_RESET(map); - return ret; + if (url) { + g_string_free(url, true); + } + BT_VALUE_PUT_REF_AND_RESET(map); + return ret; } /* @@ -859,1117 +794,1031 @@ end: */ BT_HIDDEN -bt_component_class_query_method_status live_viewer_connection_list_sessions( - struct live_viewer_connection *viewer_connection, - const bt_value **user_result) +bt_component_class_query_method_status +live_viewer_connection_list_sessions(struct live_viewer_connection *viewer_connection, + const bt_value **user_result) { - bt_self_component_class *self_comp_class = viewer_connection->self_comp_class; - bt_component_class_query_method_status status = - BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_OK; - bt_value *result = NULL; - enum lttng_live_viewer_status viewer_status; - struct lttng_viewer_cmd cmd; - struct lttng_viewer_list_sessions list; - uint32_t i, sessions_count; - - result = bt_value_array_create(); - if (!result) { - BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, - "Error creating array"); - status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_MEMORY_ERROR; - goto error; - } - - BT_LOGD("Requesting list of sessions: cmd=%s", - lttng_viewer_command_string(LTTNG_VIEWER_LIST_SESSIONS)); - - cmd.cmd = htobe32(LTTNG_VIEWER_LIST_SESSIONS); - cmd.data_size = htobe64((uint64_t) 0); - cmd.cmd_version = htobe32(0); - - viewer_status = lttng_live_send(viewer_connection, &cmd, sizeof(cmd)); - if (viewer_status == LTTNG_LIVE_VIEWER_STATUS_ERROR) { - BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, - "Error sending list sessions command"); - status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; - goto error; - } else if (viewer_status == LTTNG_LIVE_VIEWER_STATUS_INTERRUPTED) { - status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_AGAIN; - goto error; - } - - viewer_status = lttng_live_recv(viewer_connection, &list, sizeof(list)); - if (viewer_status == LTTNG_LIVE_VIEWER_STATUS_ERROR) { - BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, - "Error receiving session list"); - status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; - goto error; - } else if (viewer_status == LTTNG_LIVE_VIEWER_STATUS_INTERRUPTED) { - status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_AGAIN; - goto error; - } - - sessions_count = be32toh(list.sessions_count); - for (i = 0; i < sessions_count; i++) { - struct lttng_viewer_session lsession; - - viewer_status = lttng_live_recv(viewer_connection, &lsession, - sizeof(lsession)); - if (viewer_status == LTTNG_LIVE_VIEWER_STATUS_ERROR) { - BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, - "Error receiving session:"); - status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; - goto error; - } else if (viewer_status == LTTNG_LIVE_VIEWER_STATUS_INTERRUPTED) { - status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_AGAIN; - goto error; - } - - lsession.hostname[LTTNG_VIEWER_HOST_NAME_MAX - 1] = '\0'; - lsession.session_name[LTTNG_VIEWER_NAME_MAX - 1] = '\0'; - if (list_append_session(result, viewer_connection->url, - &lsession, viewer_connection)) { - BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, - "Error appending session"); - status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; - goto error; - } - } - - *user_result = result; - goto end; + bt_self_component_class *self_comp_class = viewer_connection->self_comp_class; + bt_component_class_query_method_status status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_OK; + bt_value *result = NULL; + enum lttng_live_viewer_status viewer_status; + struct lttng_viewer_cmd cmd; + struct lttng_viewer_list_sessions list; + uint32_t i, sessions_count; + + result = bt_value_array_create(); + if (!result) { + BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, "Error creating array"); + status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_MEMORY_ERROR; + goto error; + } + + BT_LOGD("Requesting list of sessions: cmd=%s", + lttng_viewer_command_string(LTTNG_VIEWER_LIST_SESSIONS)); + + cmd.cmd = htobe32(LTTNG_VIEWER_LIST_SESSIONS); + cmd.data_size = htobe64((uint64_t) 0); + cmd.cmd_version = htobe32(0); + + viewer_status = lttng_live_send(viewer_connection, &cmd, sizeof(cmd)); + if (viewer_status == LTTNG_LIVE_VIEWER_STATUS_ERROR) { + BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, "Error sending list sessions command"); + status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; + goto error; + } else if (viewer_status == LTTNG_LIVE_VIEWER_STATUS_INTERRUPTED) { + status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_AGAIN; + goto error; + } + + viewer_status = lttng_live_recv(viewer_connection, &list, sizeof(list)); + if (viewer_status == LTTNG_LIVE_VIEWER_STATUS_ERROR) { + BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, "Error receiving session list"); + status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; + goto error; + } else if (viewer_status == LTTNG_LIVE_VIEWER_STATUS_INTERRUPTED) { + status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_AGAIN; + goto error; + } + + sessions_count = be32toh(list.sessions_count); + for (i = 0; i < sessions_count; i++) { + struct lttng_viewer_session lsession; + + viewer_status = lttng_live_recv(viewer_connection, &lsession, sizeof(lsession)); + if (viewer_status == LTTNG_LIVE_VIEWER_STATUS_ERROR) { + BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, "Error receiving session:"); + status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; + goto error; + } else if (viewer_status == LTTNG_LIVE_VIEWER_STATUS_INTERRUPTED) { + status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_AGAIN; + goto error; + } + + lsession.hostname[LTTNG_VIEWER_HOST_NAME_MAX - 1] = '\0'; + lsession.session_name[LTTNG_VIEWER_NAME_MAX - 1] = '\0'; + if (list_append_session(result, viewer_connection->url, &lsession, viewer_connection)) { + BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, "Error appending session"); + status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; + goto error; + } + } + + *user_result = result; + goto end; error: - BT_VALUE_PUT_REF_AND_RESET(result); + BT_VALUE_PUT_REF_AND_RESET(result); end: - return status; + return status; } -static -enum lttng_live_viewer_status lttng_live_query_session_ids( - struct lttng_live_msg_iter *lttng_live_msg_iter) +static enum lttng_live_viewer_status +lttng_live_query_session_ids(struct lttng_live_msg_iter *lttng_live_msg_iter) { - struct lttng_viewer_cmd cmd; - struct lttng_viewer_list_sessions list; - struct lttng_viewer_session lsession; - uint32_t i, sessions_count; - uint64_t session_id; - enum lttng_live_viewer_status status; - struct live_viewer_connection *viewer_connection = - lttng_live_msg_iter->viewer_connection; - bt_self_component *self_comp = viewer_connection->self_comp; - bt_self_component_class *self_comp_class = - viewer_connection->self_comp_class; - - BT_COMP_LOGD("Asking the relay daemon for the list of sessions: cmd=%s", - lttng_viewer_command_string(LTTNG_VIEWER_LIST_SESSIONS)); - - cmd.cmd = htobe32(LTTNG_VIEWER_LIST_SESSIONS); - cmd.data_size = htobe64((uint64_t) 0); - cmd.cmd_version = htobe32(0); - - status = lttng_live_send(viewer_connection, &cmd, sizeof(cmd)); - if (status != LTTNG_LIVE_VIEWER_STATUS_OK) { - viewer_handle_send_status(self_comp, self_comp_class, - status, "list sessions command"); - goto end; - } - - status = lttng_live_recv(viewer_connection, &list, sizeof(list)); - if (status != LTTNG_LIVE_VIEWER_STATUS_OK) { - viewer_handle_recv_status(self_comp, self_comp_class, - status, "session list reply"); - goto end; - } - - sessions_count = be32toh(list.sessions_count); - for (i = 0; i < sessions_count; i++) { - status = lttng_live_recv(viewer_connection, &lsession, - sizeof(lsession)); - if (status != LTTNG_LIVE_VIEWER_STATUS_OK) { - viewer_handle_recv_status(self_comp, self_comp_class, - status, "session reply"); - goto end; - } - lsession.hostname[LTTNG_VIEWER_HOST_NAME_MAX - 1] = '\0'; - lsession.session_name[LTTNG_VIEWER_NAME_MAX - 1] = '\0'; - session_id = be64toh(lsession.id); - - BT_COMP_LOGI("Adding session to internal list: " - "session-id=%" PRIu64 ", hostname=\"%s\", session-name=\"%s\"", - session_id, lsession.hostname, lsession.session_name); - - if ((strncmp(lsession.session_name, - viewer_connection->session_name->str, - LTTNG_VIEWER_NAME_MAX) == 0) && (strncmp(lsession.hostname, - viewer_connection->target_hostname->str, - LTTNG_VIEWER_HOST_NAME_MAX) == 0)) { - - if (lttng_live_add_session(lttng_live_msg_iter, session_id, - lsession.hostname, - lsession.session_name)) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Failed to add live session"); - status = LTTNG_LIVE_VIEWER_STATUS_ERROR; - goto end; - } - } - } - - status = LTTNG_LIVE_VIEWER_STATUS_OK; + struct lttng_viewer_cmd cmd; + struct lttng_viewer_list_sessions list; + struct lttng_viewer_session lsession; + uint32_t i, sessions_count; + uint64_t session_id; + enum lttng_live_viewer_status status; + struct live_viewer_connection *viewer_connection = lttng_live_msg_iter->viewer_connection; + bt_self_component *self_comp = viewer_connection->self_comp; + bt_self_component_class *self_comp_class = viewer_connection->self_comp_class; + + BT_COMP_LOGD("Asking the relay daemon for the list of sessions: cmd=%s", + lttng_viewer_command_string(LTTNG_VIEWER_LIST_SESSIONS)); + + cmd.cmd = htobe32(LTTNG_VIEWER_LIST_SESSIONS); + cmd.data_size = htobe64((uint64_t) 0); + cmd.cmd_version = htobe32(0); + + status = lttng_live_send(viewer_connection, &cmd, sizeof(cmd)); + if (status != LTTNG_LIVE_VIEWER_STATUS_OK) { + viewer_handle_send_status(self_comp, self_comp_class, status, "list sessions command"); + goto end; + } + + status = lttng_live_recv(viewer_connection, &list, sizeof(list)); + if (status != LTTNG_LIVE_VIEWER_STATUS_OK) { + viewer_handle_recv_status(self_comp, self_comp_class, status, "session list reply"); + goto end; + } + + sessions_count = be32toh(list.sessions_count); + for (i = 0; i < sessions_count; i++) { + status = lttng_live_recv(viewer_connection, &lsession, sizeof(lsession)); + if (status != LTTNG_LIVE_VIEWER_STATUS_OK) { + viewer_handle_recv_status(self_comp, self_comp_class, status, "session reply"); + goto end; + } + lsession.hostname[LTTNG_VIEWER_HOST_NAME_MAX - 1] = '\0'; + lsession.session_name[LTTNG_VIEWER_NAME_MAX - 1] = '\0'; + session_id = be64toh(lsession.id); + + BT_COMP_LOGI("Adding session to internal list: " + "session-id=%" PRIu64 ", hostname=\"%s\", session-name=\"%s\"", + session_id, lsession.hostname, lsession.session_name); + + if ((strncmp(lsession.session_name, viewer_connection->session_name->str, + LTTNG_VIEWER_NAME_MAX) == 0) && + (strncmp(lsession.hostname, viewer_connection->target_hostname->str, + LTTNG_VIEWER_HOST_NAME_MAX) == 0)) { + if (lttng_live_add_session(lttng_live_msg_iter, session_id, lsession.hostname, + lsession.session_name)) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Failed to add live session"); + status = LTTNG_LIVE_VIEWER_STATUS_ERROR; + goto end; + } + } + } + + status = LTTNG_LIVE_VIEWER_STATUS_OK; end: - return status; + return status; } BT_HIDDEN -enum lttng_live_viewer_status lttng_live_create_viewer_session( - struct lttng_live_msg_iter *lttng_live_msg_iter) +enum lttng_live_viewer_status +lttng_live_create_viewer_session(struct lttng_live_msg_iter *lttng_live_msg_iter) { - struct lttng_viewer_cmd cmd; - struct lttng_viewer_create_session_response resp; - enum lttng_live_viewer_status status; - struct live_viewer_connection *viewer_connection = - lttng_live_msg_iter->viewer_connection; - bt_self_component *self_comp = viewer_connection->self_comp; - bt_self_component_class *self_comp_class = - viewer_connection->self_comp_class; - - BT_COMP_OR_COMP_CLASS_LOGD(self_comp, self_comp_class, - "Creating a viewer session: cmd=%s", - lttng_viewer_command_string(LTTNG_VIEWER_CREATE_SESSION)); - - cmd.cmd = htobe32(LTTNG_VIEWER_CREATE_SESSION); - cmd.data_size = htobe64((uint64_t) 0); - cmd.cmd_version = htobe32(0); - - status = lttng_live_send(viewer_connection, &cmd, sizeof(cmd)); - if (status != LTTNG_LIVE_VIEWER_STATUS_OK) { - viewer_handle_send_status(self_comp, self_comp_class, - status, "create session command"); - goto end; - } - - status = lttng_live_recv(viewer_connection, &resp, sizeof(resp)); - if (status != LTTNG_LIVE_VIEWER_STATUS_OK) { - viewer_handle_recv_status(self_comp, self_comp_class, - status, "create session reply"); - goto end; - } - - if (be32toh(resp.status) != LTTNG_VIEWER_CREATE_SESSION_OK) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Error creating viewer session"); - status = LTTNG_LIVE_VIEWER_STATUS_ERROR; - goto end; - } - - status = lttng_live_query_session_ids(lttng_live_msg_iter); - if (status == LTTNG_LIVE_VIEWER_STATUS_ERROR) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Failed to query live viewer session ids"); - goto end; - } else if (status == LTTNG_LIVE_VIEWER_STATUS_INTERRUPTED) { - goto end; - } + struct lttng_viewer_cmd cmd; + struct lttng_viewer_create_session_response resp; + enum lttng_live_viewer_status status; + struct live_viewer_connection *viewer_connection = lttng_live_msg_iter->viewer_connection; + bt_self_component *self_comp = viewer_connection->self_comp; + bt_self_component_class *self_comp_class = viewer_connection->self_comp_class; + + BT_COMP_OR_COMP_CLASS_LOGD(self_comp, self_comp_class, "Creating a viewer session: cmd=%s", + lttng_viewer_command_string(LTTNG_VIEWER_CREATE_SESSION)); + + cmd.cmd = htobe32(LTTNG_VIEWER_CREATE_SESSION); + cmd.data_size = htobe64((uint64_t) 0); + cmd.cmd_version = htobe32(0); + + status = lttng_live_send(viewer_connection, &cmd, sizeof(cmd)); + if (status != LTTNG_LIVE_VIEWER_STATUS_OK) { + viewer_handle_send_status(self_comp, self_comp_class, status, "create session command"); + goto end; + } + + status = lttng_live_recv(viewer_connection, &resp, sizeof(resp)); + if (status != LTTNG_LIVE_VIEWER_STATUS_OK) { + viewer_handle_recv_status(self_comp, self_comp_class, status, "create session reply"); + goto end; + } + + if (be32toh(resp.status) != LTTNG_VIEWER_CREATE_SESSION_OK) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Error creating viewer session"); + status = LTTNG_LIVE_VIEWER_STATUS_ERROR; + goto end; + } + + status = lttng_live_query_session_ids(lttng_live_msg_iter); + if (status == LTTNG_LIVE_VIEWER_STATUS_ERROR) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Failed to query live viewer session ids"); + goto end; + } else if (status == LTTNG_LIVE_VIEWER_STATUS_INTERRUPTED) { + goto end; + } end: - return status; + return status; } -static -enum lttng_live_viewer_status receive_streams(struct lttng_live_session *session, - uint32_t stream_count, - bt_self_message_iterator *self_msg_iter) +static enum lttng_live_viewer_status receive_streams(struct lttng_live_session *session, + uint32_t stream_count, + bt_self_message_iterator *self_msg_iter) { - uint32_t i; - struct lttng_live_msg_iter *lttng_live_msg_iter = - session->lttng_live_msg_iter; - enum lttng_live_viewer_status status; - struct live_viewer_connection *viewer_connection = - lttng_live_msg_iter->viewer_connection; - bt_self_component *self_comp = viewer_connection->self_comp; - - BT_COMP_LOGI("Getting %" PRIu32 " new streams", stream_count); - for (i = 0; i < stream_count; i++) { - struct lttng_viewer_stream stream; - struct lttng_live_stream_iterator *live_stream; - uint64_t stream_id; - uint64_t ctf_trace_id; - - status = lttng_live_recv(viewer_connection, &stream, - sizeof(stream)); - if (status != LTTNG_LIVE_VIEWER_STATUS_OK) { - viewer_handle_recv_status(self_comp, NULL, - status, "stream reply"); - goto end; - } - stream.path_name[LTTNG_VIEWER_PATH_MAX - 1] = '\0'; - stream.channel_name[LTTNG_VIEWER_NAME_MAX - 1] = '\0'; - stream_id = be64toh(stream.id); - ctf_trace_id = be64toh(stream.ctf_trace_id); - - if (stream.metadata_flag) { - BT_COMP_LOGI(" metadata stream %" PRIu64 " : %s/%s", - stream_id, stream.path_name, stream.channel_name); - if (lttng_live_metadata_create_stream(session, - ctf_trace_id, stream_id, - stream.path_name)) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Error creating metadata stream"); - status = LTTNG_LIVE_VIEWER_STATUS_ERROR; - goto end; - } - session->lazy_stream_msg_init = true; - } else { - BT_COMP_LOGI(" stream %" PRIu64 " : %s/%s", - stream_id, stream.path_name, stream.channel_name); - live_stream = lttng_live_stream_iterator_create(session, - ctf_trace_id, stream_id, self_msg_iter); - if (!live_stream) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Error creating stream"); - status = LTTNG_LIVE_VIEWER_STATUS_ERROR; - goto end; - } - } - } - status = LTTNG_LIVE_VIEWER_STATUS_OK; + uint32_t i; + struct lttng_live_msg_iter *lttng_live_msg_iter = session->lttng_live_msg_iter; + enum lttng_live_viewer_status status; + struct live_viewer_connection *viewer_connection = lttng_live_msg_iter->viewer_connection; + bt_self_component *self_comp = viewer_connection->self_comp; + + BT_COMP_LOGI("Getting %" PRIu32 " new streams", stream_count); + for (i = 0; i < stream_count; i++) { + struct lttng_viewer_stream stream; + struct lttng_live_stream_iterator *live_stream; + uint64_t stream_id; + uint64_t ctf_trace_id; + + status = lttng_live_recv(viewer_connection, &stream, sizeof(stream)); + if (status != LTTNG_LIVE_VIEWER_STATUS_OK) { + viewer_handle_recv_status(self_comp, NULL, status, "stream reply"); + goto end; + } + stream.path_name[LTTNG_VIEWER_PATH_MAX - 1] = '\0'; + stream.channel_name[LTTNG_VIEWER_NAME_MAX - 1] = '\0'; + stream_id = be64toh(stream.id); + ctf_trace_id = be64toh(stream.ctf_trace_id); + + if (stream.metadata_flag) { + BT_COMP_LOGI(" metadata stream %" PRIu64 " : %s/%s", stream_id, stream.path_name, + stream.channel_name); + if (lttng_live_metadata_create_stream(session, ctf_trace_id, stream_id, + stream.path_name)) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Error creating metadata stream"); + status = LTTNG_LIVE_VIEWER_STATUS_ERROR; + goto end; + } + session->lazy_stream_msg_init = true; + } else { + BT_COMP_LOGI(" stream %" PRIu64 " : %s/%s", stream_id, stream.path_name, + stream.channel_name); + live_stream = + lttng_live_stream_iterator_create(session, ctf_trace_id, stream_id, self_msg_iter); + if (!live_stream) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Error creating stream"); + status = LTTNG_LIVE_VIEWER_STATUS_ERROR; + goto end; + } + } + } + status = LTTNG_LIVE_VIEWER_STATUS_OK; end: - return status; + return status; } BT_HIDDEN -enum lttng_live_viewer_status lttng_live_session_attach( - struct lttng_live_session *session, - bt_self_message_iterator *self_msg_iter) +enum lttng_live_viewer_status lttng_live_session_attach(struct lttng_live_session *session, + bt_self_message_iterator *self_msg_iter) { - struct lttng_viewer_cmd cmd; - enum lttng_live_viewer_status status; - struct lttng_viewer_attach_session_request rq; - struct lttng_viewer_attach_session_response rp; - struct lttng_live_msg_iter *lttng_live_msg_iter = - session->lttng_live_msg_iter; - struct live_viewer_connection *viewer_connection = - lttng_live_msg_iter->viewer_connection; - bt_self_component *self_comp = viewer_connection->self_comp; - uint64_t session_id = session->id; - uint32_t streams_count; - const size_t cmd_buf_len = sizeof(cmd) + sizeof(rq); - char cmd_buf[cmd_buf_len]; - - BT_COMP_LOGD("Attaching to session: cmd=%s, session-id=%" PRIu64 - ", seek=%s", - lttng_viewer_command_string(LTTNG_VIEWER_ATTACH_SESSION), - session_id, - lttng_viewer_seek_string(LTTNG_VIEWER_SEEK_LAST)); - - cmd.cmd = htobe32(LTTNG_VIEWER_ATTACH_SESSION); - cmd.data_size = htobe64((uint64_t) sizeof(rq)); - cmd.cmd_version = htobe32(0); - - memset(&rq, 0, sizeof(rq)); - rq.session_id = htobe64(session_id); - // TODO: add cmd line parameter to select seek beginning - // rq.seek = htobe32(LTTNG_VIEWER_SEEK_BEGINNING); - rq.seek = htobe32(LTTNG_VIEWER_SEEK_LAST); - - /* - * Merge the cmd and connection request to prevent a write-write - * sequence on the TCP socket. Otherwise, a delayed ACK will prevent the - * second write to be performed quickly in presence of Nagle's algorithm. - */ - memcpy(cmd_buf, &cmd, sizeof(cmd)); - memcpy(cmd_buf + sizeof(cmd), &rq, sizeof(rq)); - status = lttng_live_send(viewer_connection, &cmd_buf, cmd_buf_len); - if (status != LTTNG_LIVE_VIEWER_STATUS_OK) { - viewer_handle_send_status(self_comp, NULL, - status, "attach session command"); - goto end; - } - - status = lttng_live_recv(viewer_connection, &rp, sizeof(rp)); - if (status != LTTNG_LIVE_VIEWER_STATUS_OK) { - viewer_handle_recv_status(self_comp, NULL, - status, "attach session reply"); - goto end; - } - - streams_count = be32toh(rp.streams_count); - switch(be32toh(rp.status)) { - case LTTNG_VIEWER_ATTACH_OK: - break; - case LTTNG_VIEWER_ATTACH_UNK: - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Session id %" PRIu64 " is unknown", session_id); - status = LTTNG_LIVE_VIEWER_STATUS_ERROR; - goto end; - case LTTNG_VIEWER_ATTACH_ALREADY: - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "There is already a viewer attached to this session"); - status = LTTNG_LIVE_VIEWER_STATUS_ERROR; - goto end; - case LTTNG_VIEWER_ATTACH_NOT_LIVE: - BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Not a live session"); - status = LTTNG_LIVE_VIEWER_STATUS_ERROR; - goto end; - case LTTNG_VIEWER_ATTACH_SEEK_ERR: - BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Wrong seek parameter"); - status = LTTNG_LIVE_VIEWER_STATUS_ERROR; - goto end; - default: - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Unknown attach return code %u", be32toh(rp.status)); - status = LTTNG_LIVE_VIEWER_STATUS_ERROR; - goto end; - } - - /* We receive the initial list of streams. */ - status = receive_streams(session, streams_count, self_msg_iter); - switch (status) { - case LTTNG_LIVE_VIEWER_STATUS_OK: - break; - case LTTNG_LIVE_VIEWER_STATUS_INTERRUPTED: - goto end; - case LTTNG_LIVE_VIEWER_STATUS_ERROR: - BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Error receiving streams"); - goto end; - default: - bt_common_abort(); - } - - session->attached = true; - session->new_streams_needed = false; + struct lttng_viewer_cmd cmd; + enum lttng_live_viewer_status status; + struct lttng_viewer_attach_session_request rq; + struct lttng_viewer_attach_session_response rp; + struct lttng_live_msg_iter *lttng_live_msg_iter = session->lttng_live_msg_iter; + struct live_viewer_connection *viewer_connection = lttng_live_msg_iter->viewer_connection; + bt_self_component *self_comp = viewer_connection->self_comp; + uint64_t session_id = session->id; + uint32_t streams_count; + const size_t cmd_buf_len = sizeof(cmd) + sizeof(rq); + char cmd_buf[cmd_buf_len]; + + BT_COMP_LOGD("Attaching to session: cmd=%s, session-id=%" PRIu64 ", seek=%s", + lttng_viewer_command_string(LTTNG_VIEWER_ATTACH_SESSION), session_id, + lttng_viewer_seek_string(LTTNG_VIEWER_SEEK_LAST)); + + cmd.cmd = htobe32(LTTNG_VIEWER_ATTACH_SESSION); + cmd.data_size = htobe64((uint64_t) sizeof(rq)); + cmd.cmd_version = htobe32(0); + + memset(&rq, 0, sizeof(rq)); + rq.session_id = htobe64(session_id); + // TODO: add cmd line parameter to select seek beginning + // rq.seek = htobe32(LTTNG_VIEWER_SEEK_BEGINNING); + rq.seek = htobe32(LTTNG_VIEWER_SEEK_LAST); + + /* + * Merge the cmd and connection request to prevent a write-write + * sequence on the TCP socket. Otherwise, a delayed ACK will prevent the + * second write to be performed quickly in presence of Nagle's algorithm. + */ + memcpy(cmd_buf, &cmd, sizeof(cmd)); + memcpy(cmd_buf + sizeof(cmd), &rq, sizeof(rq)); + status = lttng_live_send(viewer_connection, &cmd_buf, cmd_buf_len); + if (status != LTTNG_LIVE_VIEWER_STATUS_OK) { + viewer_handle_send_status(self_comp, NULL, status, "attach session command"); + goto end; + } + + status = lttng_live_recv(viewer_connection, &rp, sizeof(rp)); + if (status != LTTNG_LIVE_VIEWER_STATUS_OK) { + viewer_handle_recv_status(self_comp, NULL, status, "attach session reply"); + goto end; + } + + streams_count = be32toh(rp.streams_count); + switch (be32toh(rp.status)) { + case LTTNG_VIEWER_ATTACH_OK: + break; + case LTTNG_VIEWER_ATTACH_UNK: + BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Session id %" PRIu64 " is unknown", session_id); + status = LTTNG_LIVE_VIEWER_STATUS_ERROR; + goto end; + case LTTNG_VIEWER_ATTACH_ALREADY: + BT_COMP_LOGE_APPEND_CAUSE(self_comp, "There is already a viewer attached to this session"); + status = LTTNG_LIVE_VIEWER_STATUS_ERROR; + goto end; + case LTTNG_VIEWER_ATTACH_NOT_LIVE: + BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Not a live session"); + status = LTTNG_LIVE_VIEWER_STATUS_ERROR; + goto end; + case LTTNG_VIEWER_ATTACH_SEEK_ERR: + BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Wrong seek parameter"); + status = LTTNG_LIVE_VIEWER_STATUS_ERROR; + goto end; + default: + BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Unknown attach return code %u", be32toh(rp.status)); + status = LTTNG_LIVE_VIEWER_STATUS_ERROR; + goto end; + } + + /* We receive the initial list of streams. */ + status = receive_streams(session, streams_count, self_msg_iter); + switch (status) { + case LTTNG_LIVE_VIEWER_STATUS_OK: + break; + case LTTNG_LIVE_VIEWER_STATUS_INTERRUPTED: + goto end; + case LTTNG_LIVE_VIEWER_STATUS_ERROR: + BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Error receiving streams"); + goto end; + default: + bt_common_abort(); + } + + session->attached = true; + session->new_streams_needed = false; end: - return status; + return status; } BT_HIDDEN -enum lttng_live_viewer_status lttng_live_session_detach( - struct lttng_live_session *session) +enum lttng_live_viewer_status lttng_live_session_detach(struct lttng_live_session *session) { - struct lttng_viewer_cmd cmd; - enum lttng_live_viewer_status status; - struct lttng_viewer_detach_session_request rq; - struct lttng_viewer_detach_session_response rp; - struct lttng_live_msg_iter *lttng_live_msg_iter = - session->lttng_live_msg_iter; - bt_self_component *self_comp = session->self_comp; - struct live_viewer_connection *viewer_connection = - lttng_live_msg_iter->viewer_connection; - uint64_t session_id = session->id; - const size_t cmd_buf_len = sizeof(cmd) + sizeof(rq); - char cmd_buf[cmd_buf_len]; - - /* - * The session might already be detached and the viewer socket might - * already been closed. This happens when calling this function when - * tearing down the graph after an error. - */ - if (!session->attached || viewer_connection->control_sock == BT_INVALID_SOCKET) { - return LTTNG_LIVE_VIEWER_STATUS_OK; - } - - BT_COMP_LOGD("Detaching from session: cmd=%s, session-id=%" PRIu64, - lttng_viewer_command_string(LTTNG_VIEWER_DETACH_SESSION), - session_id); - - cmd.cmd = htobe32(LTTNG_VIEWER_DETACH_SESSION); - cmd.data_size = htobe64((uint64_t) sizeof(rq)); - cmd.cmd_version = htobe32(0); - - memset(&rq, 0, sizeof(rq)); - rq.session_id = htobe64(session_id); - - /* - * Merge the cmd and connection request to prevent a write-write - * sequence on the TCP socket. Otherwise, a delayed ACK will prevent the - * second write to be performed quickly in presence of Nagle's algorithm. - */ - memcpy(cmd_buf, &cmd, sizeof(cmd)); - memcpy(cmd_buf + sizeof(cmd), &rq, sizeof(rq)); - status = lttng_live_send(viewer_connection, &cmd_buf, cmd_buf_len); - if (status != LTTNG_LIVE_VIEWER_STATUS_OK) { - viewer_handle_send_status(self_comp, NULL, - status, "detach session command"); - goto end; - } - - status = lttng_live_recv(viewer_connection, &rp, sizeof(rp)); - if (status != LTTNG_LIVE_VIEWER_STATUS_OK) { - viewer_handle_recv_status(self_comp, NULL, - status, "detach session reply"); - goto end; - } - - switch(be32toh(rp.status)) { - case LTTNG_VIEWER_DETACH_SESSION_OK: - break; - case LTTNG_VIEWER_DETACH_SESSION_UNK: - BT_COMP_LOGW("Session id %" PRIu64 " is unknown", session_id); - status = LTTNG_LIVE_VIEWER_STATUS_ERROR; - goto end; - case LTTNG_VIEWER_DETACH_SESSION_ERR: - BT_COMP_LOGW("Error detaching session id %" PRIu64 "", session_id); - status = LTTNG_LIVE_VIEWER_STATUS_ERROR; - goto end; - default: - BT_COMP_LOGE("Unknown detach return code %u", be32toh(rp.status)); - status = LTTNG_LIVE_VIEWER_STATUS_ERROR; - goto end; - } - - session->attached = false; - - status = LTTNG_LIVE_VIEWER_STATUS_OK; + struct lttng_viewer_cmd cmd; + enum lttng_live_viewer_status status; + struct lttng_viewer_detach_session_request rq; + struct lttng_viewer_detach_session_response rp; + struct lttng_live_msg_iter *lttng_live_msg_iter = session->lttng_live_msg_iter; + bt_self_component *self_comp = session->self_comp; + struct live_viewer_connection *viewer_connection = lttng_live_msg_iter->viewer_connection; + uint64_t session_id = session->id; + const size_t cmd_buf_len = sizeof(cmd) + sizeof(rq); + char cmd_buf[cmd_buf_len]; + + /* + * The session might already be detached and the viewer socket might + * already been closed. This happens when calling this function when + * tearing down the graph after an error. + */ + if (!session->attached || viewer_connection->control_sock == BT_INVALID_SOCKET) { + return LTTNG_LIVE_VIEWER_STATUS_OK; + } + + BT_COMP_LOGD("Detaching from session: cmd=%s, session-id=%" PRIu64, + lttng_viewer_command_string(LTTNG_VIEWER_DETACH_SESSION), session_id); + + cmd.cmd = htobe32(LTTNG_VIEWER_DETACH_SESSION); + cmd.data_size = htobe64((uint64_t) sizeof(rq)); + cmd.cmd_version = htobe32(0); + + memset(&rq, 0, sizeof(rq)); + rq.session_id = htobe64(session_id); + + /* + * Merge the cmd and connection request to prevent a write-write + * sequence on the TCP socket. Otherwise, a delayed ACK will prevent the + * second write to be performed quickly in presence of Nagle's algorithm. + */ + memcpy(cmd_buf, &cmd, sizeof(cmd)); + memcpy(cmd_buf + sizeof(cmd), &rq, sizeof(rq)); + status = lttng_live_send(viewer_connection, &cmd_buf, cmd_buf_len); + if (status != LTTNG_LIVE_VIEWER_STATUS_OK) { + viewer_handle_send_status(self_comp, NULL, status, "detach session command"); + goto end; + } + + status = lttng_live_recv(viewer_connection, &rp, sizeof(rp)); + if (status != LTTNG_LIVE_VIEWER_STATUS_OK) { + viewer_handle_recv_status(self_comp, NULL, status, "detach session reply"); + goto end; + } + + switch (be32toh(rp.status)) { + case LTTNG_VIEWER_DETACH_SESSION_OK: + break; + case LTTNG_VIEWER_DETACH_SESSION_UNK: + BT_COMP_LOGW("Session id %" PRIu64 " is unknown", session_id); + status = LTTNG_LIVE_VIEWER_STATUS_ERROR; + goto end; + case LTTNG_VIEWER_DETACH_SESSION_ERR: + BT_COMP_LOGW("Error detaching session id %" PRIu64 "", session_id); + status = LTTNG_LIVE_VIEWER_STATUS_ERROR; + goto end; + default: + BT_COMP_LOGE("Unknown detach return code %u", be32toh(rp.status)); + status = LTTNG_LIVE_VIEWER_STATUS_ERROR; + goto end; + } + + session->attached = false; + + status = LTTNG_LIVE_VIEWER_STATUS_OK; end: - return status; + return status; } BT_HIDDEN -enum lttng_live_get_one_metadata_status lttng_live_get_one_metadata_packet( - struct lttng_live_trace *trace, FILE *fp, size_t *reply_len) +enum lttng_live_get_one_metadata_status +lttng_live_get_one_metadata_packet(struct lttng_live_trace *trace, FILE *fp, size_t *reply_len) { - uint64_t len = 0; - enum lttng_live_get_one_metadata_status status; - enum lttng_live_viewer_status viewer_status; - struct lttng_viewer_cmd cmd; - struct lttng_viewer_get_metadata rq; - struct lttng_viewer_metadata_packet rp; - gchar *data = NULL; - ssize_t writelen; - struct lttng_live_session *session = trace->session; - struct lttng_live_msg_iter *lttng_live_msg_iter = - session->lttng_live_msg_iter; - struct lttng_live_metadata *metadata = trace->metadata; - struct live_viewer_connection *viewer_connection = - lttng_live_msg_iter->viewer_connection; - bt_self_component *self_comp = viewer_connection->self_comp; - const size_t cmd_buf_len = sizeof(cmd) + sizeof(rq); - char cmd_buf[cmd_buf_len]; - - BT_COMP_LOGD("Requesting new metadata for trace:" - "cmd=%s, trace-id=%" PRIu64 ", metadata-stream-id=%" PRIu64, - lttng_viewer_command_string(LTTNG_VIEWER_GET_METADATA), - trace->id, metadata->stream_id); - - rq.stream_id = htobe64(metadata->stream_id); - cmd.cmd = htobe32(LTTNG_VIEWER_GET_METADATA); - cmd.data_size = htobe64((uint64_t) sizeof(rq)); - cmd.cmd_version = htobe32(0); - - /* - * Merge the cmd and connection request to prevent a write-write - * sequence on the TCP socket. Otherwise, a delayed ACK will prevent the - * second write to be performed quickly in presence of Nagle's algorithm. - */ - memcpy(cmd_buf, &cmd, sizeof(cmd)); - memcpy(cmd_buf + sizeof(cmd), &rq, sizeof(rq)); - viewer_status = lttng_live_send(viewer_connection, &cmd_buf, cmd_buf_len); - if (viewer_status != LTTNG_LIVE_VIEWER_STATUS_OK) { - viewer_handle_send_status(self_comp, NULL, - viewer_status, "get metadata command"); - status = (enum lttng_live_get_one_metadata_status) viewer_status; - goto end; - } - - viewer_status = lttng_live_recv(viewer_connection, &rp, sizeof(rp)); - if (viewer_status != LTTNG_LIVE_VIEWER_STATUS_OK) { - viewer_handle_recv_status(self_comp, NULL, - viewer_status, "get metadata reply"); - status = (enum lttng_live_get_one_metadata_status) viewer_status; - goto end; - } - - switch (be32toh(rp.status)) { - case LTTNG_VIEWER_METADATA_OK: - BT_COMP_LOGD("Received get_metadata response: ok"); - break; - case LTTNG_VIEWER_NO_NEW_METADATA: - BT_COMP_LOGD("Received get_metadata response: no new"); - status = LTTNG_LIVE_GET_ONE_METADATA_STATUS_END; - goto end; - case LTTNG_VIEWER_METADATA_ERR: - /* - * The Relayd cannot find this stream id. Maybe its - * gone already. This can happen in short lived UST app - * in a per-pid session. - */ - BT_COMP_LOGD("Received get_metadata response: error"); - status = LTTNG_LIVE_GET_ONE_METADATA_STATUS_CLOSED; - goto end; - default: - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Received get_metadata response: unknown"); - status = LTTNG_LIVE_GET_ONE_METADATA_STATUS_ERROR; - goto end; - } - - len = be64toh(rp.len); - BT_COMP_LOGD("Writing %" PRIu64" bytes to metadata", len); - if (len <= 0) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Erroneous response length"); - status = LTTNG_LIVE_GET_ONE_METADATA_STATUS_ERROR; - goto end; - } - - data = g_new0(gchar, len); - if (!data) { - BT_COMP_LOGE_APPEND_CAUSE_ERRNO(self_comp, - "Failed to allocate data buffer", "."); - status = LTTNG_LIVE_GET_ONE_METADATA_STATUS_ERROR; - goto end; - } - - viewer_status = lttng_live_recv(viewer_connection, data, len); - if (viewer_status != LTTNG_LIVE_VIEWER_STATUS_OK) { - viewer_handle_recv_status(self_comp, NULL, - viewer_status, "get metadata packet"); - status = (enum lttng_live_get_one_metadata_status) viewer_status; - goto end; - } - - /* - * Write the metadata to the file handle. - */ - writelen = fwrite(data, sizeof(uint8_t), len, fp); - if (writelen != len) { - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Writing in the metadata file stream"); - status = LTTNG_LIVE_GET_ONE_METADATA_STATUS_ERROR; - goto end; - } - - *reply_len = len; - status = LTTNG_LIVE_GET_ONE_METADATA_STATUS_OK; + uint64_t len = 0; + enum lttng_live_get_one_metadata_status status; + enum lttng_live_viewer_status viewer_status; + struct lttng_viewer_cmd cmd; + struct lttng_viewer_get_metadata rq; + struct lttng_viewer_metadata_packet rp; + gchar *data = NULL; + ssize_t writelen; + struct lttng_live_session *session = trace->session; + struct lttng_live_msg_iter *lttng_live_msg_iter = session->lttng_live_msg_iter; + struct lttng_live_metadata *metadata = trace->metadata; + struct live_viewer_connection *viewer_connection = lttng_live_msg_iter->viewer_connection; + bt_self_component *self_comp = viewer_connection->self_comp; + const size_t cmd_buf_len = sizeof(cmd) + sizeof(rq); + char cmd_buf[cmd_buf_len]; + + BT_COMP_LOGD("Requesting new metadata for trace:" + "cmd=%s, trace-id=%" PRIu64 ", metadata-stream-id=%" PRIu64, + lttng_viewer_command_string(LTTNG_VIEWER_GET_METADATA), trace->id, + metadata->stream_id); + + rq.stream_id = htobe64(metadata->stream_id); + cmd.cmd = htobe32(LTTNG_VIEWER_GET_METADATA); + cmd.data_size = htobe64((uint64_t) sizeof(rq)); + cmd.cmd_version = htobe32(0); + + /* + * Merge the cmd and connection request to prevent a write-write + * sequence on the TCP socket. Otherwise, a delayed ACK will prevent the + * second write to be performed quickly in presence of Nagle's algorithm. + */ + memcpy(cmd_buf, &cmd, sizeof(cmd)); + memcpy(cmd_buf + sizeof(cmd), &rq, sizeof(rq)); + viewer_status = lttng_live_send(viewer_connection, &cmd_buf, cmd_buf_len); + if (viewer_status != LTTNG_LIVE_VIEWER_STATUS_OK) { + viewer_handle_send_status(self_comp, NULL, viewer_status, "get metadata command"); + status = (enum lttng_live_get_one_metadata_status) viewer_status; + goto end; + } + + viewer_status = lttng_live_recv(viewer_connection, &rp, sizeof(rp)); + if (viewer_status != LTTNG_LIVE_VIEWER_STATUS_OK) { + viewer_handle_recv_status(self_comp, NULL, viewer_status, "get metadata reply"); + status = (enum lttng_live_get_one_metadata_status) viewer_status; + goto end; + } + + switch (be32toh(rp.status)) { + case LTTNG_VIEWER_METADATA_OK: + BT_COMP_LOGD("Received get_metadata response: ok"); + break; + case LTTNG_VIEWER_NO_NEW_METADATA: + BT_COMP_LOGD("Received get_metadata response: no new"); + status = LTTNG_LIVE_GET_ONE_METADATA_STATUS_END; + goto end; + case LTTNG_VIEWER_METADATA_ERR: + /* + * The Relayd cannot find this stream id. Maybe its + * gone already. This can happen in short lived UST app + * in a per-pid session. + */ + BT_COMP_LOGD("Received get_metadata response: error"); + status = LTTNG_LIVE_GET_ONE_METADATA_STATUS_CLOSED; + goto end; + default: + BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Received get_metadata response: unknown"); + status = LTTNG_LIVE_GET_ONE_METADATA_STATUS_ERROR; + goto end; + } + + len = be64toh(rp.len); + BT_COMP_LOGD("Writing %" PRIu64 " bytes to metadata", len); + if (len <= 0) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Erroneous response length"); + status = LTTNG_LIVE_GET_ONE_METADATA_STATUS_ERROR; + goto end; + } + + data = g_new0(gchar, len); + if (!data) { + BT_COMP_LOGE_APPEND_CAUSE_ERRNO(self_comp, "Failed to allocate data buffer", "."); + status = LTTNG_LIVE_GET_ONE_METADATA_STATUS_ERROR; + goto end; + } + + viewer_status = lttng_live_recv(viewer_connection, data, len); + if (viewer_status != LTTNG_LIVE_VIEWER_STATUS_OK) { + viewer_handle_recv_status(self_comp, NULL, viewer_status, "get metadata packet"); + status = (enum lttng_live_get_one_metadata_status) viewer_status; + goto end; + } + + /* + * Write the metadata to the file handle. + */ + writelen = fwrite(data, sizeof(uint8_t), len, fp); + if (writelen != len) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Writing in the metadata file stream"); + status = LTTNG_LIVE_GET_ONE_METADATA_STATUS_ERROR; + goto end; + } + + *reply_len = len; + status = LTTNG_LIVE_GET_ONE_METADATA_STATUS_OK; end: - g_free(data); - return status; + g_free(data); + return status; } /* * Assign the fields from a lttng_viewer_index to a packet_index. */ -static -void lttng_index_to_packet_index(struct lttng_viewer_index *lindex, - struct packet_index *pindex) +static void lttng_index_to_packet_index(struct lttng_viewer_index *lindex, + struct packet_index *pindex) { - BT_ASSERT(lindex); - BT_ASSERT(pindex); - - pindex->offset = be64toh(lindex->offset); - pindex->packet_size = be64toh(lindex->packet_size); - pindex->content_size = be64toh(lindex->content_size); - pindex->ts_cycles.timestamp_begin = be64toh(lindex->timestamp_begin); - pindex->ts_cycles.timestamp_end = be64toh(lindex->timestamp_end); - pindex->events_discarded = be64toh(lindex->events_discarded); + BT_ASSERT(lindex); + BT_ASSERT(pindex); + + pindex->offset = be64toh(lindex->offset); + pindex->packet_size = be64toh(lindex->packet_size); + pindex->content_size = be64toh(lindex->content_size); + pindex->ts_cycles.timestamp_begin = be64toh(lindex->timestamp_begin); + pindex->ts_cycles.timestamp_end = be64toh(lindex->timestamp_end); + pindex->events_discarded = be64toh(lindex->events_discarded); } -static -void lttng_live_need_new_streams(struct lttng_live_msg_iter *lttng_live_msg_iter) +static void lttng_live_need_new_streams(struct lttng_live_msg_iter *lttng_live_msg_iter) { - uint64_t session_idx; - struct live_viewer_connection *viewer_connection = - lttng_live_msg_iter->viewer_connection; - - for (session_idx = 0; session_idx < lttng_live_msg_iter->sessions->len; - session_idx++) { - struct lttng_live_session *session = - (lttng_live_session *) g_ptr_array_index(lttng_live_msg_iter->sessions, session_idx); - BT_COMP_LOGD("Marking session as needing new streams: " - "session-id=%" PRIu64, session->id); - session->new_streams_needed = true; - } + uint64_t session_idx; + struct live_viewer_connection *viewer_connection = lttng_live_msg_iter->viewer_connection; + + for (session_idx = 0; session_idx < lttng_live_msg_iter->sessions->len; session_idx++) { + struct lttng_live_session *session = + (lttng_live_session *) g_ptr_array_index(lttng_live_msg_iter->sessions, session_idx); + BT_COMP_LOGD("Marking session as needing new streams: " + "session-id=%" PRIu64, + session->id); + session->new_streams_needed = true; + } } BT_HIDDEN -enum lttng_live_iterator_status lttng_live_get_next_index( - struct lttng_live_msg_iter *lttng_live_msg_iter, - struct lttng_live_stream_iterator *stream, - struct packet_index *index) +enum lttng_live_iterator_status +lttng_live_get_next_index(struct lttng_live_msg_iter *lttng_live_msg_iter, + struct lttng_live_stream_iterator *stream, struct packet_index *index) { - struct lttng_viewer_cmd cmd; - struct lttng_viewer_get_next_index rq; - enum lttng_live_viewer_status viewer_status; - struct lttng_viewer_index rp; - enum lttng_live_iterator_status status; - struct live_viewer_connection *viewer_connection = - lttng_live_msg_iter->viewer_connection; - bt_self_component *self_comp = viewer_connection->self_comp; - struct lttng_live_trace *trace = stream->trace; - const size_t cmd_buf_len = sizeof(cmd) + sizeof(rq); - char cmd_buf[cmd_buf_len]; - uint32_t flags, rp_status; - - BT_COMP_LOGD("Requesting next index for stream: cmd=%s, " - "viewer-stream-id=%" PRIu64, - lttng_viewer_command_string(LTTNG_VIEWER_GET_NEXT_INDEX), - stream->viewer_stream_id); - cmd.cmd = htobe32(LTTNG_VIEWER_GET_NEXT_INDEX); - cmd.data_size = htobe64((uint64_t) sizeof(rq)); - cmd.cmd_version = htobe32(0); - - memset(&rq, 0, sizeof(rq)); - rq.stream_id = htobe64(stream->viewer_stream_id); - - /* - * Merge the cmd and connection request to prevent a write-write - * sequence on the TCP socket. Otherwise, a delayed ACK will prevent the - * second write to be performed quickly in presence of Nagle's algorithm. - */ - memcpy(cmd_buf, &cmd, sizeof(cmd)); - memcpy(cmd_buf + sizeof(cmd), &rq, sizeof(rq)); - - viewer_status = lttng_live_send(viewer_connection, &cmd_buf, cmd_buf_len); - if (viewer_status != LTTNG_LIVE_VIEWER_STATUS_OK) { - viewer_handle_send_status(self_comp, NULL, - viewer_status, "get next index command"); - goto error; - } - - viewer_status = lttng_live_recv(viewer_connection, &rp, sizeof(rp)); - if (viewer_status != LTTNG_LIVE_VIEWER_STATUS_OK) { - viewer_handle_recv_status(self_comp, NULL, - viewer_status, "get next index reply"); - goto error; - } - - flags = be32toh(rp.flags); - rp_status = be32toh(rp.status); - - BT_COMP_LOGD("Received response from relay daemon: cmd=%s, response=%s", - lttng_viewer_command_string(LTTNG_VIEWER_GET_NEXT_INDEX), - lttng_viewer_next_index_return_code_string(rp_status)); - switch (rp_status) { - case LTTNG_VIEWER_INDEX_INACTIVE: - { - uint64_t ctf_stream_class_id; - - memset(index, 0, sizeof(struct packet_index)); - index->ts_cycles.timestamp_end = be64toh(rp.timestamp_end); - stream->current_inactivity_ts = index->ts_cycles.timestamp_end; - ctf_stream_class_id = be64toh(rp.stream_id); - if (stream->ctf_stream_class_id.is_set) { - BT_ASSERT(stream->ctf_stream_class_id.value== - ctf_stream_class_id); - } else { - stream->ctf_stream_class_id.value = ctf_stream_class_id; - stream->ctf_stream_class_id.is_set = true; - } - lttng_live_stream_iterator_set_state(stream, LTTNG_LIVE_STREAM_QUIESCENT); - status = LTTNG_LIVE_ITERATOR_STATUS_OK; - break; - } - case LTTNG_VIEWER_INDEX_OK: - { - uint64_t ctf_stream_class_id; - - lttng_index_to_packet_index(&rp, index); - ctf_stream_class_id = be64toh(rp.stream_id); - if (stream->ctf_stream_class_id.is_set) { - BT_ASSERT(stream->ctf_stream_class_id.value== - ctf_stream_class_id); - } else { - stream->ctf_stream_class_id.value = ctf_stream_class_id; - stream->ctf_stream_class_id.is_set = true; - } - - lttng_live_stream_iterator_set_state(stream, LTTNG_LIVE_STREAM_ACTIVE_DATA); - - if (flags & LTTNG_VIEWER_FLAG_NEW_METADATA) { - BT_COMP_LOGD("Marking trace as needing new metadata: " - "response=%s, response-flag=NEW_METADATA, trace-id=%" PRIu64, - lttng_viewer_next_index_return_code_string(rp_status), - trace->id); - trace->metadata_stream_state = LTTNG_LIVE_METADATA_STREAM_STATE_NEEDED; - } - if (flags & LTTNG_VIEWER_FLAG_NEW_STREAM) { - BT_COMP_LOGD("Marking all sessions as possibly needing new streams: " - "response=%s, response-flag=NEW_STREAM", - lttng_viewer_next_index_return_code_string(rp_status)); - lttng_live_need_new_streams(lttng_live_msg_iter); - } - status = LTTNG_LIVE_ITERATOR_STATUS_OK; - break; - } - case LTTNG_VIEWER_INDEX_RETRY: - memset(index, 0, sizeof(struct packet_index)); - lttng_live_stream_iterator_set_state(stream, LTTNG_LIVE_STREAM_ACTIVE_NO_DATA); - status = LTTNG_LIVE_ITERATOR_STATUS_AGAIN; - goto end; - case LTTNG_VIEWER_INDEX_HUP: - memset(index, 0, sizeof(struct packet_index)); - index->offset = EOF; - lttng_live_stream_iterator_set_state(stream, LTTNG_LIVE_STREAM_EOF); - stream->has_stream_hung_up = true; - status = LTTNG_LIVE_ITERATOR_STATUS_END; - break; - case LTTNG_VIEWER_INDEX_ERR: - memset(index, 0, sizeof(struct packet_index)); - lttng_live_stream_iterator_set_state(stream, LTTNG_LIVE_STREAM_ACTIVE_NO_DATA); - status = LTTNG_LIVE_ITERATOR_STATUS_ERROR; - goto end; - default: - BT_COMP_LOGD("Received get_next_index response: unknown value"); - memset(index, 0, sizeof(struct packet_index)); - lttng_live_stream_iterator_set_state(stream, LTTNG_LIVE_STREAM_ACTIVE_NO_DATA); - status = LTTNG_LIVE_ITERATOR_STATUS_ERROR; - goto end; - } - goto end; + struct lttng_viewer_cmd cmd; + struct lttng_viewer_get_next_index rq; + enum lttng_live_viewer_status viewer_status; + struct lttng_viewer_index rp; + enum lttng_live_iterator_status status; + struct live_viewer_connection *viewer_connection = lttng_live_msg_iter->viewer_connection; + bt_self_component *self_comp = viewer_connection->self_comp; + struct lttng_live_trace *trace = stream->trace; + const size_t cmd_buf_len = sizeof(cmd) + sizeof(rq); + char cmd_buf[cmd_buf_len]; + uint32_t flags, rp_status; + + BT_COMP_LOGD("Requesting next index for stream: cmd=%s, " + "viewer-stream-id=%" PRIu64, + lttng_viewer_command_string(LTTNG_VIEWER_GET_NEXT_INDEX), + stream->viewer_stream_id); + cmd.cmd = htobe32(LTTNG_VIEWER_GET_NEXT_INDEX); + cmd.data_size = htobe64((uint64_t) sizeof(rq)); + cmd.cmd_version = htobe32(0); + + memset(&rq, 0, sizeof(rq)); + rq.stream_id = htobe64(stream->viewer_stream_id); + + /* + * Merge the cmd and connection request to prevent a write-write + * sequence on the TCP socket. Otherwise, a delayed ACK will prevent the + * second write to be performed quickly in presence of Nagle's algorithm. + */ + memcpy(cmd_buf, &cmd, sizeof(cmd)); + memcpy(cmd_buf + sizeof(cmd), &rq, sizeof(rq)); + + viewer_status = lttng_live_send(viewer_connection, &cmd_buf, cmd_buf_len); + if (viewer_status != LTTNG_LIVE_VIEWER_STATUS_OK) { + viewer_handle_send_status(self_comp, NULL, viewer_status, "get next index command"); + goto error; + } + + viewer_status = lttng_live_recv(viewer_connection, &rp, sizeof(rp)); + if (viewer_status != LTTNG_LIVE_VIEWER_STATUS_OK) { + viewer_handle_recv_status(self_comp, NULL, viewer_status, "get next index reply"); + goto error; + } + + flags = be32toh(rp.flags); + rp_status = be32toh(rp.status); + + BT_COMP_LOGD("Received response from relay daemon: cmd=%s, response=%s", + lttng_viewer_command_string(LTTNG_VIEWER_GET_NEXT_INDEX), + lttng_viewer_next_index_return_code_string(rp_status)); + switch (rp_status) { + case LTTNG_VIEWER_INDEX_INACTIVE: + { + uint64_t ctf_stream_class_id; + + memset(index, 0, sizeof(struct packet_index)); + index->ts_cycles.timestamp_end = be64toh(rp.timestamp_end); + stream->current_inactivity_ts = index->ts_cycles.timestamp_end; + ctf_stream_class_id = be64toh(rp.stream_id); + if (stream->ctf_stream_class_id.is_set) { + BT_ASSERT(stream->ctf_stream_class_id.value == ctf_stream_class_id); + } else { + stream->ctf_stream_class_id.value = ctf_stream_class_id; + stream->ctf_stream_class_id.is_set = true; + } + lttng_live_stream_iterator_set_state(stream, LTTNG_LIVE_STREAM_QUIESCENT); + status = LTTNG_LIVE_ITERATOR_STATUS_OK; + break; + } + case LTTNG_VIEWER_INDEX_OK: + { + uint64_t ctf_stream_class_id; + + lttng_index_to_packet_index(&rp, index); + ctf_stream_class_id = be64toh(rp.stream_id); + if (stream->ctf_stream_class_id.is_set) { + BT_ASSERT(stream->ctf_stream_class_id.value == ctf_stream_class_id); + } else { + stream->ctf_stream_class_id.value = ctf_stream_class_id; + stream->ctf_stream_class_id.is_set = true; + } + + lttng_live_stream_iterator_set_state(stream, LTTNG_LIVE_STREAM_ACTIVE_DATA); + + if (flags & LTTNG_VIEWER_FLAG_NEW_METADATA) { + BT_COMP_LOGD("Marking trace as needing new metadata: " + "response=%s, response-flag=NEW_METADATA, trace-id=%" PRIu64, + lttng_viewer_next_index_return_code_string(rp_status), trace->id); + trace->metadata_stream_state = LTTNG_LIVE_METADATA_STREAM_STATE_NEEDED; + } + if (flags & LTTNG_VIEWER_FLAG_NEW_STREAM) { + BT_COMP_LOGD("Marking all sessions as possibly needing new streams: " + "response=%s, response-flag=NEW_STREAM", + lttng_viewer_next_index_return_code_string(rp_status)); + lttng_live_need_new_streams(lttng_live_msg_iter); + } + status = LTTNG_LIVE_ITERATOR_STATUS_OK; + break; + } + case LTTNG_VIEWER_INDEX_RETRY: + memset(index, 0, sizeof(struct packet_index)); + lttng_live_stream_iterator_set_state(stream, LTTNG_LIVE_STREAM_ACTIVE_NO_DATA); + status = LTTNG_LIVE_ITERATOR_STATUS_AGAIN; + goto end; + case LTTNG_VIEWER_INDEX_HUP: + memset(index, 0, sizeof(struct packet_index)); + index->offset = EOF; + lttng_live_stream_iterator_set_state(stream, LTTNG_LIVE_STREAM_EOF); + stream->has_stream_hung_up = true; + status = LTTNG_LIVE_ITERATOR_STATUS_END; + break; + case LTTNG_VIEWER_INDEX_ERR: + memset(index, 0, sizeof(struct packet_index)); + lttng_live_stream_iterator_set_state(stream, LTTNG_LIVE_STREAM_ACTIVE_NO_DATA); + status = LTTNG_LIVE_ITERATOR_STATUS_ERROR; + goto end; + default: + BT_COMP_LOGD("Received get_next_index response: unknown value"); + memset(index, 0, sizeof(struct packet_index)); + lttng_live_stream_iterator_set_state(stream, LTTNG_LIVE_STREAM_ACTIVE_NO_DATA); + status = LTTNG_LIVE_ITERATOR_STATUS_ERROR; + goto end; + } + goto end; error: - status = viewer_status_to_live_iterator_status(viewer_status); + status = viewer_status_to_live_iterator_status(viewer_status); end: - return status; + return status; } BT_HIDDEN -enum ctf_msg_iter_medium_status lttng_live_get_stream_bytes( - struct lttng_live_msg_iter *lttng_live_msg_iter, - struct lttng_live_stream_iterator *stream, uint8_t *buf, - uint64_t offset, uint64_t req_len, uint64_t *recv_len) +enum ctf_msg_iter_medium_status +lttng_live_get_stream_bytes(struct lttng_live_msg_iter *lttng_live_msg_iter, + struct lttng_live_stream_iterator *stream, uint8_t *buf, + uint64_t offset, uint64_t req_len, uint64_t *recv_len) { - enum ctf_msg_iter_medium_status status; - enum lttng_live_viewer_status viewer_status; - struct lttng_viewer_trace_packet rp; - struct lttng_viewer_cmd cmd; - struct lttng_viewer_get_packet rq; - struct live_viewer_connection *viewer_connection = - lttng_live_msg_iter->viewer_connection; - bt_self_component *self_comp = viewer_connection->self_comp; - struct lttng_live_trace *trace = stream->trace; - const size_t cmd_buf_len = sizeof(cmd) + sizeof(rq); - char cmd_buf[cmd_buf_len]; - uint32_t flags, rp_status; - - BT_COMP_LOGD("Requesting data from stream: cmd=%s, " - "offset=%" PRIu64 ", request-len=%" PRIu64, - lttng_viewer_command_string(LTTNG_VIEWER_GET_PACKET), - offset, req_len); - - cmd.cmd = htobe32(LTTNG_VIEWER_GET_PACKET); - cmd.data_size = htobe64((uint64_t) sizeof(rq)); - cmd.cmd_version = htobe32(0); - - memset(&rq, 0, sizeof(rq)); - rq.stream_id = htobe64(stream->viewer_stream_id); - rq.offset = htobe64(offset); - rq.len = htobe32(req_len); - - /* - * Merge the cmd and connection request to prevent a write-write - * sequence on the TCP socket. Otherwise, a delayed ACK will prevent the - * second write to be performed quickly in presence of Nagle's algorithm. - */ - memcpy(cmd_buf, &cmd, sizeof(cmd)); - memcpy(cmd_buf + sizeof(cmd), &rq, sizeof(rq)); - - viewer_status = lttng_live_send(viewer_connection, &cmd_buf, cmd_buf_len); - if (viewer_status != LTTNG_LIVE_VIEWER_STATUS_OK) { - viewer_handle_send_status(self_comp, NULL, - viewer_status, "get data packet command"); - goto error_convert_status; - } - - viewer_status = lttng_live_recv(viewer_connection, &rp, sizeof(rp)); - if (viewer_status != LTTNG_LIVE_VIEWER_STATUS_OK) { - viewer_handle_recv_status(self_comp, NULL, - viewer_status, "get data packet reply"); - goto error_convert_status; - } - - flags = be32toh(rp.flags); - rp_status = be32toh(rp.status); - - BT_COMP_LOGD("Received response from relay daemon: cmd=%s, response=%s", - lttng_viewer_command_string(LTTNG_VIEWER_GET_PACKET), - lttng_viewer_get_packet_return_code_string(rp_status)); - switch (rp_status) { - case LTTNG_VIEWER_GET_PACKET_OK: - req_len = be32toh(rp.len); - BT_COMP_LOGD("Got packet from relay daemon: response=%s, packet-len=%" PRIu64 "", - lttng_viewer_get_packet_return_code_string(rp_status), - req_len); - status = CTF_MSG_ITER_MEDIUM_STATUS_OK; - break; - case LTTNG_VIEWER_GET_PACKET_RETRY: - /* Unimplemented by relay daemon */ - status = CTF_MSG_ITER_MEDIUM_STATUS_AGAIN; - goto end; - case LTTNG_VIEWER_GET_PACKET_ERR: - if (flags & LTTNG_VIEWER_FLAG_NEW_METADATA) { - BT_COMP_LOGD("Marking trace as needing new metadata: " - "response=%s, response-flag=NEW_METADATA, trace-id=%" PRIu64, - lttng_viewer_next_index_return_code_string(rp_status), - trace->id); - trace->metadata_stream_state = LTTNG_LIVE_METADATA_STREAM_STATE_NEEDED; - } - if (flags & LTTNG_VIEWER_FLAG_NEW_STREAM) { - BT_COMP_LOGD("Marking all sessions as possibly needing new streams: " - "response=%s, response-flag=NEW_STREAM", - lttng_viewer_next_index_return_code_string(rp_status)); - lttng_live_need_new_streams(lttng_live_msg_iter); - } - if (flags & (LTTNG_VIEWER_FLAG_NEW_METADATA - | LTTNG_VIEWER_FLAG_NEW_STREAM)) { - status = CTF_MSG_ITER_MEDIUM_STATUS_AGAIN; - BT_COMP_LOGD("Reply with any one flags set means we should retry: response=%s", - lttng_viewer_get_packet_return_code_string(rp_status)); - goto end; - } - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Received get_data_packet response: error"); - status = CTF_MSG_ITER_MEDIUM_STATUS_ERROR; - goto end; - case LTTNG_VIEWER_GET_PACKET_EOF: - status = CTF_MSG_ITER_MEDIUM_STATUS_EOF; - goto end; - default: - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Received get_data_packet response: unknown (%d)", rp_status); - status = CTF_MSG_ITER_MEDIUM_STATUS_ERROR; - goto end; - } - - if (req_len == 0) { - status = CTF_MSG_ITER_MEDIUM_STATUS_ERROR; - goto end; - } - - viewer_status = lttng_live_recv(viewer_connection, buf, req_len); - if (viewer_status != LTTNG_LIVE_VIEWER_STATUS_OK) { - viewer_handle_recv_status(self_comp, NULL, - viewer_status, "get data packet"); - goto error_convert_status; - } - *recv_len = req_len; - - status = CTF_MSG_ITER_MEDIUM_STATUS_OK; - goto end; + enum ctf_msg_iter_medium_status status; + enum lttng_live_viewer_status viewer_status; + struct lttng_viewer_trace_packet rp; + struct lttng_viewer_cmd cmd; + struct lttng_viewer_get_packet rq; + struct live_viewer_connection *viewer_connection = lttng_live_msg_iter->viewer_connection; + bt_self_component *self_comp = viewer_connection->self_comp; + struct lttng_live_trace *trace = stream->trace; + const size_t cmd_buf_len = sizeof(cmd) + sizeof(rq); + char cmd_buf[cmd_buf_len]; + uint32_t flags, rp_status; + + BT_COMP_LOGD("Requesting data from stream: cmd=%s, " + "offset=%" PRIu64 ", request-len=%" PRIu64, + lttng_viewer_command_string(LTTNG_VIEWER_GET_PACKET), offset, req_len); + + cmd.cmd = htobe32(LTTNG_VIEWER_GET_PACKET); + cmd.data_size = htobe64((uint64_t) sizeof(rq)); + cmd.cmd_version = htobe32(0); + + memset(&rq, 0, sizeof(rq)); + rq.stream_id = htobe64(stream->viewer_stream_id); + rq.offset = htobe64(offset); + rq.len = htobe32(req_len); + + /* + * Merge the cmd and connection request to prevent a write-write + * sequence on the TCP socket. Otherwise, a delayed ACK will prevent the + * second write to be performed quickly in presence of Nagle's algorithm. + */ + memcpy(cmd_buf, &cmd, sizeof(cmd)); + memcpy(cmd_buf + sizeof(cmd), &rq, sizeof(rq)); + + viewer_status = lttng_live_send(viewer_connection, &cmd_buf, cmd_buf_len); + if (viewer_status != LTTNG_LIVE_VIEWER_STATUS_OK) { + viewer_handle_send_status(self_comp, NULL, viewer_status, "get data packet command"); + goto error_convert_status; + } + + viewer_status = lttng_live_recv(viewer_connection, &rp, sizeof(rp)); + if (viewer_status != LTTNG_LIVE_VIEWER_STATUS_OK) { + viewer_handle_recv_status(self_comp, NULL, viewer_status, "get data packet reply"); + goto error_convert_status; + } + + flags = be32toh(rp.flags); + rp_status = be32toh(rp.status); + + BT_COMP_LOGD("Received response from relay daemon: cmd=%s, response=%s", + lttng_viewer_command_string(LTTNG_VIEWER_GET_PACKET), + lttng_viewer_get_packet_return_code_string(rp_status)); + switch (rp_status) { + case LTTNG_VIEWER_GET_PACKET_OK: + req_len = be32toh(rp.len); + BT_COMP_LOGD("Got packet from relay daemon: response=%s, packet-len=%" PRIu64 "", + lttng_viewer_get_packet_return_code_string(rp_status), req_len); + status = CTF_MSG_ITER_MEDIUM_STATUS_OK; + break; + case LTTNG_VIEWER_GET_PACKET_RETRY: + /* Unimplemented by relay daemon */ + status = CTF_MSG_ITER_MEDIUM_STATUS_AGAIN; + goto end; + case LTTNG_VIEWER_GET_PACKET_ERR: + if (flags & LTTNG_VIEWER_FLAG_NEW_METADATA) { + BT_COMP_LOGD("Marking trace as needing new metadata: " + "response=%s, response-flag=NEW_METADATA, trace-id=%" PRIu64, + lttng_viewer_next_index_return_code_string(rp_status), trace->id); + trace->metadata_stream_state = LTTNG_LIVE_METADATA_STREAM_STATE_NEEDED; + } + if (flags & LTTNG_VIEWER_FLAG_NEW_STREAM) { + BT_COMP_LOGD("Marking all sessions as possibly needing new streams: " + "response=%s, response-flag=NEW_STREAM", + lttng_viewer_next_index_return_code_string(rp_status)); + lttng_live_need_new_streams(lttng_live_msg_iter); + } + if (flags & (LTTNG_VIEWER_FLAG_NEW_METADATA | LTTNG_VIEWER_FLAG_NEW_STREAM)) { + status = CTF_MSG_ITER_MEDIUM_STATUS_AGAIN; + BT_COMP_LOGD("Reply with any one flags set means we should retry: response=%s", + lttng_viewer_get_packet_return_code_string(rp_status)); + goto end; + } + BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Received get_data_packet response: error"); + status = CTF_MSG_ITER_MEDIUM_STATUS_ERROR; + goto end; + case LTTNG_VIEWER_GET_PACKET_EOF: + status = CTF_MSG_ITER_MEDIUM_STATUS_EOF; + goto end; + default: + BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Received get_data_packet response: unknown (%d)", + rp_status); + status = CTF_MSG_ITER_MEDIUM_STATUS_ERROR; + goto end; + } + + if (req_len == 0) { + status = CTF_MSG_ITER_MEDIUM_STATUS_ERROR; + goto end; + } + + viewer_status = lttng_live_recv(viewer_connection, buf, req_len); + if (viewer_status != LTTNG_LIVE_VIEWER_STATUS_OK) { + viewer_handle_recv_status(self_comp, NULL, viewer_status, "get data packet"); + goto error_convert_status; + } + *recv_len = req_len; + + status = CTF_MSG_ITER_MEDIUM_STATUS_OK; + goto end; error_convert_status: - status = viewer_status_to_ctf_msg_iter_medium_status(viewer_status); + status = viewer_status_to_ctf_msg_iter_medium_status(viewer_status); end: - return status; + return status; } /* * Request new streams for a session. */ BT_HIDDEN -enum lttng_live_iterator_status lttng_live_session_get_new_streams( - struct lttng_live_session *session, - bt_self_message_iterator *self_msg_iter) +enum lttng_live_iterator_status +lttng_live_session_get_new_streams(struct lttng_live_session *session, + bt_self_message_iterator *self_msg_iter) { - enum lttng_live_iterator_status status = - LTTNG_LIVE_ITERATOR_STATUS_OK; - struct lttng_viewer_cmd cmd; - struct lttng_viewer_new_streams_request rq; - struct lttng_viewer_new_streams_response rp; - struct lttng_live_msg_iter *lttng_live_msg_iter = - session->lttng_live_msg_iter; - enum lttng_live_viewer_status viewer_status; - struct live_viewer_connection *viewer_connection = - lttng_live_msg_iter->viewer_connection; - bt_self_component *self_comp = viewer_connection->self_comp; - uint32_t streams_count; - const size_t cmd_buf_len = sizeof(cmd) + sizeof(rq); - char cmd_buf[cmd_buf_len]; - - if (!session->new_streams_needed) { - status = LTTNG_LIVE_ITERATOR_STATUS_OK; - goto end; - } - - BT_COMP_LOGD("Requesting new streams for session: cmd=%s, " - "session-id=%" PRIu64, - lttng_viewer_command_string(LTTNG_VIEWER_GET_NEW_STREAMS), - session->id); - - cmd.cmd = htobe32(LTTNG_VIEWER_GET_NEW_STREAMS); - cmd.data_size = htobe64((uint64_t) sizeof(rq)); - cmd.cmd_version = htobe32(0); - - memset(&rq, 0, sizeof(rq)); - rq.session_id = htobe64(session->id); - - /* - * Merge the cmd and connection request to prevent a write-write - * sequence on the TCP socket. Otherwise, a delayed ACK will prevent the - * second write to be performed quickly in presence of Nagle's algorithm. - */ - memcpy(cmd_buf, &cmd, sizeof(cmd)); - memcpy(cmd_buf + sizeof(cmd), &rq, sizeof(rq)); - - viewer_status = lttng_live_send(viewer_connection, &cmd_buf, cmd_buf_len); - if (viewer_status != LTTNG_LIVE_VIEWER_STATUS_OK) { - viewer_handle_send_status(self_comp, NULL, - viewer_status, "get new streams command"); - status = viewer_status_to_live_iterator_status(viewer_status); - goto end; - } - - viewer_status = lttng_live_recv(viewer_connection, &rp, sizeof(rp)); - if (viewer_status != LTTNG_LIVE_VIEWER_STATUS_OK) { - viewer_handle_recv_status(self_comp, NULL, - viewer_status, "get new streams reply"); - status = viewer_status_to_live_iterator_status(viewer_status); - goto end; - } - - streams_count = be32toh(rp.streams_count); - - switch(be32toh(rp.status)) { - case LTTNG_VIEWER_NEW_STREAMS_OK: - session->new_streams_needed = false; - break; - case LTTNG_VIEWER_NEW_STREAMS_NO_NEW: - session->new_streams_needed = false; - goto end; - case LTTNG_VIEWER_NEW_STREAMS_HUP: - session->new_streams_needed = false; - session->closed = true; - status = LTTNG_LIVE_ITERATOR_STATUS_END; - goto end; - case LTTNG_VIEWER_NEW_STREAMS_ERR: - BT_COMP_LOGD("Received get_new_streams response: error"); - status = LTTNG_LIVE_ITERATOR_STATUS_ERROR; - goto end; - default: - BT_COMP_LOGE_APPEND_CAUSE(self_comp, - "Received get_new_streams response: Unknown:" - "return code %u", be32toh(rp.status)); - status = LTTNG_LIVE_ITERATOR_STATUS_ERROR; - goto end; - } - - viewer_status = receive_streams(session, streams_count, self_msg_iter); - if (viewer_status != LTTNG_LIVE_VIEWER_STATUS_OK) { - viewer_handle_recv_status(self_comp, NULL, - viewer_status, "new streams"); - status = viewer_status_to_live_iterator_status(viewer_status); - goto end; - } - - status = LTTNG_LIVE_ITERATOR_STATUS_OK; + enum lttng_live_iterator_status status = LTTNG_LIVE_ITERATOR_STATUS_OK; + struct lttng_viewer_cmd cmd; + struct lttng_viewer_new_streams_request rq; + struct lttng_viewer_new_streams_response rp; + struct lttng_live_msg_iter *lttng_live_msg_iter = session->lttng_live_msg_iter; + enum lttng_live_viewer_status viewer_status; + struct live_viewer_connection *viewer_connection = lttng_live_msg_iter->viewer_connection; + bt_self_component *self_comp = viewer_connection->self_comp; + uint32_t streams_count; + const size_t cmd_buf_len = sizeof(cmd) + sizeof(rq); + char cmd_buf[cmd_buf_len]; + + if (!session->new_streams_needed) { + status = LTTNG_LIVE_ITERATOR_STATUS_OK; + goto end; + } + + BT_COMP_LOGD("Requesting new streams for session: cmd=%s, " + "session-id=%" PRIu64, + lttng_viewer_command_string(LTTNG_VIEWER_GET_NEW_STREAMS), session->id); + + cmd.cmd = htobe32(LTTNG_VIEWER_GET_NEW_STREAMS); + cmd.data_size = htobe64((uint64_t) sizeof(rq)); + cmd.cmd_version = htobe32(0); + + memset(&rq, 0, sizeof(rq)); + rq.session_id = htobe64(session->id); + + /* + * Merge the cmd and connection request to prevent a write-write + * sequence on the TCP socket. Otherwise, a delayed ACK will prevent the + * second write to be performed quickly in presence of Nagle's algorithm. + */ + memcpy(cmd_buf, &cmd, sizeof(cmd)); + memcpy(cmd_buf + sizeof(cmd), &rq, sizeof(rq)); + + viewer_status = lttng_live_send(viewer_connection, &cmd_buf, cmd_buf_len); + if (viewer_status != LTTNG_LIVE_VIEWER_STATUS_OK) { + viewer_handle_send_status(self_comp, NULL, viewer_status, "get new streams command"); + status = viewer_status_to_live_iterator_status(viewer_status); + goto end; + } + + viewer_status = lttng_live_recv(viewer_connection, &rp, sizeof(rp)); + if (viewer_status != LTTNG_LIVE_VIEWER_STATUS_OK) { + viewer_handle_recv_status(self_comp, NULL, viewer_status, "get new streams reply"); + status = viewer_status_to_live_iterator_status(viewer_status); + goto end; + } + + streams_count = be32toh(rp.streams_count); + + switch (be32toh(rp.status)) { + case LTTNG_VIEWER_NEW_STREAMS_OK: + session->new_streams_needed = false; + break; + case LTTNG_VIEWER_NEW_STREAMS_NO_NEW: + session->new_streams_needed = false; + goto end; + case LTTNG_VIEWER_NEW_STREAMS_HUP: + session->new_streams_needed = false; + session->closed = true; + status = LTTNG_LIVE_ITERATOR_STATUS_END; + goto end; + case LTTNG_VIEWER_NEW_STREAMS_ERR: + BT_COMP_LOGD("Received get_new_streams response: error"); + status = LTTNG_LIVE_ITERATOR_STATUS_ERROR; + goto end; + default: + BT_COMP_LOGE_APPEND_CAUSE(self_comp, + "Received get_new_streams response: Unknown:" + "return code %u", + be32toh(rp.status)); + status = LTTNG_LIVE_ITERATOR_STATUS_ERROR; + goto end; + } + + viewer_status = receive_streams(session, streams_count, self_msg_iter); + if (viewer_status != LTTNG_LIVE_VIEWER_STATUS_OK) { + viewer_handle_recv_status(self_comp, NULL, viewer_status, "new streams"); + status = viewer_status_to_live_iterator_status(viewer_status); + goto end; + } + + status = LTTNG_LIVE_ITERATOR_STATUS_OK; end: - return status; + return status; } BT_HIDDEN enum lttng_live_viewer_status live_viewer_connection_create( - bt_self_component *self_comp, - bt_self_component_class *self_comp_class, - bt_logging_level log_level, - const char *url, bool in_query, - struct lttng_live_msg_iter *lttng_live_msg_iter, - struct live_viewer_connection **viewer) + bt_self_component *self_comp, bt_self_component_class *self_comp_class, + bt_logging_level log_level, const char *url, bool in_query, + struct lttng_live_msg_iter *lttng_live_msg_iter, struct live_viewer_connection **viewer) { - struct live_viewer_connection *viewer_connection; - enum lttng_live_viewer_status status; - - viewer_connection = g_new0(struct live_viewer_connection, 1); - - if (bt_socket_init(log_level) != 0) { - BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, - self_comp_class, "Failed to init socket"); - status = LTTNG_LIVE_VIEWER_STATUS_ERROR; - goto error; - } - - viewer_connection->log_level = log_level; - - viewer_connection->self_comp = self_comp; - viewer_connection->self_comp_class = self_comp_class; - - viewer_connection->control_sock = BT_INVALID_SOCKET; - viewer_connection->port = -1; - viewer_connection->in_query = in_query; - viewer_connection->lttng_live_msg_iter = lttng_live_msg_iter; - viewer_connection->url = g_string_new(url); - if (!viewer_connection->url) { - BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, - self_comp_class, "Failed to allocate URL buffer"); - status = LTTNG_LIVE_VIEWER_STATUS_ERROR; - goto error; - } - - BT_COMP_OR_COMP_CLASS_LOGD(self_comp, self_comp_class, - "Establishing connection to url \"%s\"...", url); - status = lttng_live_connect_viewer(viewer_connection); - /* - * Only print error and append cause in case of error. not in case of - * interruption. - */ - if (status == LTTNG_LIVE_VIEWER_STATUS_ERROR) { - BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, - self_comp_class, "Failed to establish connection: " - "url=\"%s\"", url); - goto error; - } else if (status == LTTNG_LIVE_VIEWER_STATUS_INTERRUPTED) { - goto error; - } - BT_COMP_OR_COMP_CLASS_LOGD(self_comp, self_comp_class, - "Connection to url \"%s\" is established", url); - - *viewer = viewer_connection; - status = LTTNG_LIVE_VIEWER_STATUS_OK; - goto end; + struct live_viewer_connection *viewer_connection; + enum lttng_live_viewer_status status; + + viewer_connection = g_new0(struct live_viewer_connection, 1); + + if (bt_socket_init(log_level) != 0) { + BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class, + "Failed to init socket"); + status = LTTNG_LIVE_VIEWER_STATUS_ERROR; + goto error; + } + + viewer_connection->log_level = log_level; + + viewer_connection->self_comp = self_comp; + viewer_connection->self_comp_class = self_comp_class; + + viewer_connection->control_sock = BT_INVALID_SOCKET; + viewer_connection->port = -1; + viewer_connection->in_query = in_query; + viewer_connection->lttng_live_msg_iter = lttng_live_msg_iter; + viewer_connection->url = g_string_new(url); + if (!viewer_connection->url) { + BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class, + "Failed to allocate URL buffer"); + status = LTTNG_LIVE_VIEWER_STATUS_ERROR; + goto error; + } + + BT_COMP_OR_COMP_CLASS_LOGD(self_comp, self_comp_class, + "Establishing connection to url \"%s\"...", url); + status = lttng_live_connect_viewer(viewer_connection); + /* + * Only print error and append cause in case of error. not in case of + * interruption. + */ + if (status == LTTNG_LIVE_VIEWER_STATUS_ERROR) { + BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class, + "Failed to establish connection: " + "url=\"%s\"", + url); + goto error; + } else if (status == LTTNG_LIVE_VIEWER_STATUS_INTERRUPTED) { + goto error; + } + BT_COMP_OR_COMP_CLASS_LOGD(self_comp, self_comp_class, + "Connection to url \"%s\" is established", url); + + *viewer = viewer_connection; + status = LTTNG_LIVE_VIEWER_STATUS_OK; + goto end; error: - if (viewer_connection) { - live_viewer_connection_destroy(viewer_connection); - } + if (viewer_connection) { + live_viewer_connection_destroy(viewer_connection); + } end: - return status; + return status; } BT_HIDDEN -void live_viewer_connection_destroy( - struct live_viewer_connection *viewer_connection) +void live_viewer_connection_destroy(struct live_viewer_connection *viewer_connection) { - bt_self_component *self_comp = viewer_connection->self_comp; - bt_self_component_class *self_comp_class = viewer_connection->self_comp_class; + bt_self_component *self_comp = viewer_connection->self_comp; + bt_self_component_class *self_comp_class = viewer_connection->self_comp_class; - if (!viewer_connection) { - goto end; - } + if (!viewer_connection) { + goto end; + } - BT_COMP_OR_COMP_CLASS_LOGD(self_comp, self_comp_class, - "Closing connection to relay:" - "relay-url=\"%s\"", viewer_connection->url->str); + BT_COMP_OR_COMP_CLASS_LOGD(self_comp, self_comp_class, + "Closing connection to relay:" + "relay-url=\"%s\"", + viewer_connection->url->str); - lttng_live_disconnect_viewer(viewer_connection); + lttng_live_disconnect_viewer(viewer_connection); - if (viewer_connection->url) { - g_string_free(viewer_connection->url, true); - } + if (viewer_connection->url) { + g_string_free(viewer_connection->url, true); + } - if (viewer_connection->relay_hostname) { - g_string_free(viewer_connection->relay_hostname, true); - } + if (viewer_connection->relay_hostname) { + g_string_free(viewer_connection->relay_hostname, true); + } - if (viewer_connection->target_hostname) { - g_string_free(viewer_connection->target_hostname, true); - } + if (viewer_connection->target_hostname) { + g_string_free(viewer_connection->target_hostname, true); + } - if (viewer_connection->session_name) { - g_string_free(viewer_connection->session_name, true); - } + if (viewer_connection->session_name) { + g_string_free(viewer_connection->session_name, true); + } - if (viewer_connection->proto) { - g_string_free(viewer_connection->proto, true); - } + if (viewer_connection->proto) { + g_string_free(viewer_connection->proto, true); + } - g_free(viewer_connection); + g_free(viewer_connection); - bt_socket_fini(); + bt_socket_fini(); end: - return; + return; } diff --git a/src/plugins/ctf/lttng-live/viewer-connection.hpp b/src/plugins/ctf/lttng-live/viewer-connection.hpp index 45cc8e21..2943e109 100644 --- a/src/plugins/ctf/lttng-live/viewer-connection.hpp +++ b/src/plugins/ctf/lttng-live/viewer-connection.hpp @@ -18,93 +18,96 @@ #include "common/macros.h" #include "compat/socket.h" -#define LTTNG_DEFAULT_NETWORK_VIEWER_PORT 5344 +#define LTTNG_DEFAULT_NETWORK_VIEWER_PORT 5344 -#define LTTNG_LIVE_MAJOR 2 -#define LTTNG_LIVE_MINOR 4 +#define LTTNG_LIVE_MAJOR 2 +#define LTTNG_LIVE_MINOR 4 -enum lttng_live_viewer_status { - LTTNG_LIVE_VIEWER_STATUS_OK = 0, - LTTNG_LIVE_VIEWER_STATUS_ERROR = -1, - LTTNG_LIVE_VIEWER_STATUS_INTERRUPTED = -2, +enum lttng_live_viewer_status +{ + LTTNG_LIVE_VIEWER_STATUS_OK = 0, + LTTNG_LIVE_VIEWER_STATUS_ERROR = -1, + LTTNG_LIVE_VIEWER_STATUS_INTERRUPTED = -2, }; -enum lttng_live_get_one_metadata_status { - /* The end of the metadata stream was reached. */ - LTTNG_LIVE_GET_ONE_METADATA_STATUS_END = 1, - /* One metadata packet was received and written to file. */ - LTTNG_LIVE_GET_ONE_METADATA_STATUS_OK = LTTNG_LIVE_VIEWER_STATUS_OK, - /* - * A critical error occurred when contacting the relay or while - * handling its response. - */ - LTTNG_LIVE_GET_ONE_METADATA_STATUS_ERROR = LTTNG_LIVE_VIEWER_STATUS_ERROR, - - LTTNG_LIVE_GET_ONE_METADATA_STATUS_INTERRUPTED = LTTNG_LIVE_VIEWER_STATUS_INTERRUPTED, - - /* The metadata stream was not found on the relay. */ - LTTNG_LIVE_GET_ONE_METADATA_STATUS_CLOSED = -3, +enum lttng_live_get_one_metadata_status +{ + /* The end of the metadata stream was reached. */ + LTTNG_LIVE_GET_ONE_METADATA_STATUS_END = 1, + /* One metadata packet was received and written to file. */ + LTTNG_LIVE_GET_ONE_METADATA_STATUS_OK = LTTNG_LIVE_VIEWER_STATUS_OK, + /* + * A critical error occurred when contacting the relay or while + * handling its response. + */ + LTTNG_LIVE_GET_ONE_METADATA_STATUS_ERROR = LTTNG_LIVE_VIEWER_STATUS_ERROR, + + LTTNG_LIVE_GET_ONE_METADATA_STATUS_INTERRUPTED = LTTNG_LIVE_VIEWER_STATUS_INTERRUPTED, + + /* The metadata stream was not found on the relay. */ + LTTNG_LIVE_GET_ONE_METADATA_STATUS_CLOSED = -3, }; struct lttng_live_component; -struct live_viewer_connection { - bt_logging_level log_level; - bt_self_component *self_comp; - bt_self_component_class *self_comp_class; +struct live_viewer_connection +{ + bt_logging_level log_level; + bt_self_component *self_comp; + bt_self_component_class *self_comp_class; - GString *url; + GString *url; - GString *relay_hostname; - GString *target_hostname; - GString *session_name; - GString *proto; + GString *relay_hostname; + GString *target_hostname; + GString *session_name; + GString *proto; - BT_SOCKET control_sock; - int port; + BT_SOCKET control_sock; + int port; - int32_t major; - int32_t minor; + int32_t major; + int32_t minor; - bool in_query; - struct lttng_live_msg_iter *lttng_live_msg_iter; + bool in_query; + struct lttng_live_msg_iter *lttng_live_msg_iter; }; -struct packet_index_time { - uint64_t timestamp_begin; - uint64_t timestamp_end; +struct packet_index_time +{ + uint64_t timestamp_begin; + uint64_t timestamp_end; }; -struct packet_index { - off_t offset; /* offset of the packet in the file, in bytes */ - int64_t data_offset; /* offset of data within the packet, in bits */ - uint64_t packet_size; /* packet size, in bits */ - uint64_t content_size; /* content size, in bits */ - uint64_t events_discarded; - uint64_t events_discarded_len; /* length of the field, in bits */ - struct packet_index_time ts_cycles; /* timestamp in cycles */ - struct packet_index_time ts_real; /* realtime timestamp */ - /* CTF_INDEX 1.0 limit */ - uint64_t stream_instance_id; /* ID of the channel instance */ - uint64_t packet_seq_num; /* packet sequence number */ +struct packet_index +{ + off_t offset; /* offset of the packet in the file, in bytes */ + int64_t data_offset; /* offset of data within the packet, in bits */ + uint64_t packet_size; /* packet size, in bits */ + uint64_t content_size; /* content size, in bits */ + uint64_t events_discarded; + uint64_t events_discarded_len; /* length of the field, in bits */ + struct packet_index_time ts_cycles; /* timestamp in cycles */ + struct packet_index_time ts_real; /* realtime timestamp */ + /* CTF_INDEX 1.0 limit */ + uint64_t stream_instance_id; /* ID of the channel instance */ + uint64_t packet_seq_num; /* packet sequence number */ }; -enum lttng_live_viewer_status live_viewer_connection_create( - bt_self_component *self_comp, - bt_self_component_class *self_comp_class, - bt_logging_level log_level, - const char *url, bool in_query, - struct lttng_live_msg_iter *lttng_live_msg_iter, - struct live_viewer_connection **viewer_connection); +enum lttng_live_viewer_status +live_viewer_connection_create(bt_self_component *self_comp, + bt_self_component_class *self_comp_class, bt_logging_level log_level, + const char *url, bool in_query, + struct lttng_live_msg_iter *lttng_live_msg_iter, + struct live_viewer_connection **viewer_connection); -void live_viewer_connection_destroy( - struct live_viewer_connection *conn); +void live_viewer_connection_destroy(struct live_viewer_connection *conn); -enum lttng_live_viewer_status lttng_live_create_viewer_session( - struct lttng_live_msg_iter *lttng_live_msg_iter); +enum lttng_live_viewer_status +lttng_live_create_viewer_session(struct lttng_live_msg_iter *lttng_live_msg_iter); -bt_component_class_query_method_status live_viewer_connection_list_sessions( - struct live_viewer_connection *viewer_connection, - const bt_value **user_result); +bt_component_class_query_method_status +live_viewer_connection_list_sessions(struct live_viewer_connection *viewer_connection, + const bt_value **user_result); #endif /* LTTNG_LIVE_VIEWER_CONNECTION_H */ diff --git a/src/plugins/ctf/plugin.cpp b/src/plugins/ctf/plugin.cpp index eeab90e2..835d16c3 100644 --- a/src/plugins/ctf/plugin.cpp +++ b/src/plugins/ctf/plugin.cpp @@ -24,45 +24,37 @@ BT_PLUGIN_LICENSE("MIT"); /* ctf.fs source */ BT_PLUGIN_SOURCE_COMPONENT_CLASS(fs, ctf_fs_iterator_next); -BT_PLUGIN_SOURCE_COMPONENT_CLASS_DESCRIPTION(fs, - "Read CTF traces from the file system."); -BT_PLUGIN_SOURCE_COMPONENT_CLASS_HELP(fs, - "See the babeltrace2-source.ctf.fs(7) manual page."); +BT_PLUGIN_SOURCE_COMPONENT_CLASS_DESCRIPTION(fs, "Read CTF traces from the file system."); +BT_PLUGIN_SOURCE_COMPONENT_CLASS_HELP(fs, "See the babeltrace2-source.ctf.fs(7) manual page."); BT_PLUGIN_SOURCE_COMPONENT_CLASS_INITIALIZE_METHOD(fs, ctf_fs_init); BT_PLUGIN_SOURCE_COMPONENT_CLASS_QUERY_METHOD(fs, ctf_fs_query); BT_PLUGIN_SOURCE_COMPONENT_CLASS_FINALIZE_METHOD(fs, ctf_fs_finalize); -BT_PLUGIN_SOURCE_COMPONENT_CLASS_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD(fs, - ctf_fs_iterator_init); +BT_PLUGIN_SOURCE_COMPONENT_CLASS_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD(fs, ctf_fs_iterator_init); BT_PLUGIN_SOURCE_COMPONENT_CLASS_MESSAGE_ITERATOR_CLASS_FINALIZE_METHOD(fs, - ctf_fs_iterator_finalize); -BT_PLUGIN_SOURCE_COMPONENT_CLASS_MESSAGE_ITERATOR_CLASS_SEEK_BEGINNING_METHODS(fs, - ctf_fs_iterator_seek_beginning, NULL); + ctf_fs_iterator_finalize); +BT_PLUGIN_SOURCE_COMPONENT_CLASS_MESSAGE_ITERATOR_CLASS_SEEK_BEGINNING_METHODS( + fs, ctf_fs_iterator_seek_beginning, NULL); /* ctf.fs sink */ BT_PLUGIN_SINK_COMPONENT_CLASS(fs, ctf_fs_sink_consume); BT_PLUGIN_SINK_COMPONENT_CLASS_INITIALIZE_METHOD(fs, ctf_fs_sink_init); BT_PLUGIN_SINK_COMPONENT_CLASS_FINALIZE_METHOD(fs, ctf_fs_sink_finalize); -BT_PLUGIN_SINK_COMPONENT_CLASS_GRAPH_IS_CONFIGURED_METHOD(fs, - ctf_fs_sink_graph_is_configured); -BT_PLUGIN_SINK_COMPONENT_CLASS_DESCRIPTION(fs, - "Write CTF traces to the file system."); -BT_PLUGIN_SINK_COMPONENT_CLASS_HELP(fs, - "See the babeltrace2-sink.ctf.fs(7) manual page."); +BT_PLUGIN_SINK_COMPONENT_CLASS_GRAPH_IS_CONFIGURED_METHOD(fs, ctf_fs_sink_graph_is_configured); +BT_PLUGIN_SINK_COMPONENT_CLASS_DESCRIPTION(fs, "Write CTF traces to the file system."); +BT_PLUGIN_SINK_COMPONENT_CLASS_HELP(fs, "See the babeltrace2-sink.ctf.fs(7) manual page."); /* ctf.lttng-live source */ -BT_PLUGIN_SOURCE_COMPONENT_CLASS_WITH_ID(auto, lttng_live, "lttng-live", - lttng_live_msg_iter_next); -BT_PLUGIN_SOURCE_COMPONENT_CLASS_DESCRIPTION_WITH_ID(auto, lttng_live, - "Connect to an LTTng relay daemon and receive CTF streams."); -BT_PLUGIN_SOURCE_COMPONENT_CLASS_HELP_WITH_ID(auto, lttng_live, - "See the babeltrace2-source.ctf.lttng-live(7) manual page."); +BT_PLUGIN_SOURCE_COMPONENT_CLASS_WITH_ID(auto, lttng_live, "lttng-live", lttng_live_msg_iter_next); +BT_PLUGIN_SOURCE_COMPONENT_CLASS_DESCRIPTION_WITH_ID( + auto, lttng_live, "Connect to an LTTng relay daemon and receive CTF streams."); +BT_PLUGIN_SOURCE_COMPONENT_CLASS_HELP_WITH_ID( + auto, lttng_live, "See the babeltrace2-source.ctf.lttng-live(7) manual page."); BT_PLUGIN_SOURCE_COMPONENT_CLASS_INITIALIZE_METHOD_WITH_ID(auto, lttng_live, - lttng_live_component_init); -BT_PLUGIN_SOURCE_COMPONENT_CLASS_QUERY_METHOD_WITH_ID(auto, lttng_live, - lttng_live_query); + lttng_live_component_init); +BT_PLUGIN_SOURCE_COMPONENT_CLASS_QUERY_METHOD_WITH_ID(auto, lttng_live, lttng_live_query); BT_PLUGIN_SOURCE_COMPONENT_CLASS_FINALIZE_METHOD_WITH_ID(auto, lttng_live, - lttng_live_component_finalize); -BT_PLUGIN_SOURCE_COMPONENT_CLASS_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_WITH_ID(auto, - lttng_live, lttng_live_msg_iter_init); -BT_PLUGIN_SOURCE_COMPONENT_CLASS_MESSAGE_ITERATOR_CLASS_FINALIZE_METHOD_WITH_ID(auto, - lttng_live, lttng_live_msg_iter_finalize); + lttng_live_component_finalize); +BT_PLUGIN_SOURCE_COMPONENT_CLASS_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_WITH_ID( + auto, lttng_live, lttng_live_msg_iter_init); +BT_PLUGIN_SOURCE_COMPONENT_CLASS_MESSAGE_ITERATOR_CLASS_FINALIZE_METHOD_WITH_ID( + auto, lttng_live, lttng_live_msg_iter_finalize); -- 2.34.1