X-Git-Url: http://git.efficios.com/?p=babeltrace.git;a=blobdiff_plain;f=src%2Fplugins%2Fctf%2Ffs-sink%2Ftranslate-trace-ir-to-ctf-ir.c;h=19ca9dcdbbee3d7194ce2095195ea6bf513ea4b4;hp=c7be897e657ce06415b9ed34942b51216d27523e;hb=0235b0db7de5bcacdb3650c92461f2ce5eb2143d;hpb=45c51519900e100d9acda4acb9516ef69bc2d045 diff --git a/src/plugins/ctf/fs-sink/translate-trace-ir-to-ctf-ir.c b/src/plugins/ctf/fs-sink/translate-trace-ir-to-ctf-ir.c index c7be897e..19ca9dcd 100644 --- a/src/plugins/ctf/fs-sink/translate-trace-ir-to-ctf-ir.c +++ b/src/plugins/ctf/fs-sink/translate-trace-ir-to-ctf-ir.c @@ -1,29 +1,15 @@ /* - * Copyright 2019 Philippe Proulx - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. + * SPDX-License-Identifier: MIT * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * Copyright 2019 Philippe Proulx */ #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" -#include "plugins/comp-logging.h" +#include "logging/comp-logging.h" + +#include "translate-trace-ir-to-ctf-ir.h" #include #include "common/macros.h" @@ -58,7 +44,7 @@ struct ctx { /* Weak */ struct fs_sink_ctf_event_class *cur_ec; - bt_scope cur_scope; + bt_field_path_scope cur_scope; /* * Array of `struct field_path_elem` */ @@ -152,14 +138,14 @@ bool ist_valid_identifier(const char *name) } /* Make sure the name starts with a letter or `_` */ - if (!isalpha(name[0]) && name[0] != '_') { + 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(*at) && *at != '_') { + if (!isalnum((unsigned char) *at) && *at != '_') { ist_valid = false; goto end; } @@ -215,7 +201,7 @@ int cur_path_stack_push(struct ctx *ctx, g_string_append(field_path_elem->name, name); - if (ctx->cur_scope == BT_SCOPE_PACKET_CONTEXT) { + 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") || @@ -288,24 +274,24 @@ int create_relative_field_ref(struct ctx *ctx, /* Get target field class's name */ switch (bt_field_path_get_root_scope(tgt_ir_field_path)) { - case BT_SCOPE_PACKET_CONTEXT: + case BT_FIELD_PATH_SCOPE_PACKET_CONTEXT: BT_ASSERT(ctx->cur_sc); tgt_fc = ctx->cur_sc->packet_context_fc; break; - case BT_SCOPE_EVENT_COMMON_CONTEXT: + 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_SCOPE_EVENT_SPECIFIC_CONTEXT: + case BT_FIELD_PATH_SCOPE_EVENT_SPECIFIC_CONTEXT: BT_ASSERT(ctx->cur_ec); tgt_fc = ctx->cur_ec->spec_context_fc; break; - case BT_SCOPE_EVENT_PAYLOAD: + case BT_FIELD_PATH_SCOPE_EVENT_PAYLOAD: BT_ASSERT(ctx->cur_ec); tgt_fc = ctx->cur_ec->payload_fc; break; default: - abort(); + bt_common_abort(); } i = 0; @@ -319,6 +305,13 @@ int create_relative_field_ref(struct ctx *ctx, 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) == @@ -346,7 +339,7 @@ int create_relative_field_ref(struct ctx *ctx, break; } default: - abort(); + bt_common_abort(); } if (named_fc) { @@ -363,8 +356,8 @@ int create_relative_field_ref(struct ctx *ctx, /* 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; - struct fs_sink_ctf_field_class_variant *var_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; @@ -449,28 +442,28 @@ int create_absolute_field_ref(struct ctx *ctx, uint64_t i; switch (bt_field_path_get_root_scope(tgt_ir_field_path)) { - case BT_SCOPE_PACKET_CONTEXT: + 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_SCOPE_EVENT_COMMON_CONTEXT: + 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_SCOPE_EVENT_SPECIFIC_CONTEXT: + 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_SCOPE_EVENT_PAYLOAD: + 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: - abort(); + bt_common_abort(); } BT_ASSERT(fc); @@ -504,7 +497,7 @@ int create_absolute_field_ref(struct ctx *ctx, bt_field_path_item_index_get_index(fp_item)); break; default: - abort(); + bt_common_abort(); } BT_ASSERT(named_fc); @@ -535,7 +528,7 @@ void resolve_field_class(struct ctx *ctx, struct fs_sink_ctf_field_class **user_tgt_fc) { int ret; - bt_scope tgt_scope; + bt_field_path_scope tgt_scope; *create_before = false; @@ -568,7 +561,6 @@ void resolve_field_class(struct ctx *ctx, tgt_field_ref, user_tgt_fc); if (ret) { *create_before = true; - ret = 0; goto end; } } @@ -599,6 +591,16 @@ void append_to_parent_field_class(struct ctx *ctx, fs_sink_ctf_field_class_struct_append_member((void *) 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 = + (void *) 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((void *) parent_fc, cur_path_stack_top(ctx)->name->str, fc); @@ -615,7 +617,7 @@ void append_to_parent_field_class(struct ctx *ctx, break; } default: - abort(); + bt_common_abort(); } } @@ -709,116 +711,10 @@ end: } /* - * This function returns whether or not a given field class `tag_fc` - * is valid as the tag field class of the variant field class `fc`. - * - * CTF 1.8 requires that the tag field class be an enumeration field - * class and that, for each variant field class option's range set, the - * tag field class contains a mapping which has the option's name and an - * equal range set. - */ -static inline -bool _is_variant_field_class_tag_valid( - struct fs_sink_ctf_field_class_variant *fc, - struct fs_sink_ctf_field_class *tag_fc) -{ - bool is_valid = true; - bt_field_class_type ir_tag_fc_type = bt_field_class_get_type( - tag_fc->ir_fc); - uint64_t i; - GString *escaped_opt_name = g_string_new(NULL); - - BT_ASSERT(escaped_opt_name); - - if (ir_tag_fc_type != BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION && - ir_tag_fc_type != BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION) { - is_valid = false; - goto end; - } - - for (i = 0; i < bt_field_class_variant_get_option_count( - fc->base.ir_fc); i++) { - const bt_field_class_variant_option *var_opt_base = - bt_field_class_variant_borrow_option_by_index_const( - fc->base.ir_fc, i); - const char *opt_name = bt_field_class_variant_option_get_name( - var_opt_base); - - /* - * If the option is named `name` in trace IR, then it - * was _possibly_ named `_name` originally if it comes - * from `src.ctf.fs`. This means the corresponding - * enumeration field class mapping was also named - * `_name`, but this one didn't change, as enumeration - * FC mapping names are not escaped; they are literal - * strings. - * - * The `sink.ctf.fs` component escapes all the variant - * FC option names with `_`. Therefore the - * _escaped name_ must match the original enumeration - * FC mapping name. - */ - g_string_assign(escaped_opt_name, "_"); - g_string_append(escaped_opt_name, opt_name); - - if (ir_tag_fc_type == BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION) { - const bt_field_class_variant_with_unsigned_selector_option *var_opt = - bt_field_class_variant_with_unsigned_selector_borrow_option_by_index_const( - fc->base.ir_fc, i); - const bt_field_class_unsigned_enumeration_mapping *mapping; - const bt_integer_range_set_unsigned *opt_ranges; - const bt_integer_range_set_unsigned *mapping_ranges; - - mapping = bt_field_class_unsigned_enumeration_borrow_mapping_by_label_const( - tag_fc->ir_fc, escaped_opt_name->str); - if (!mapping) { - is_valid = false; - goto end; - } - - opt_ranges = bt_field_class_variant_with_unsigned_selector_option_borrow_ranges_const( - var_opt); - mapping_ranges = bt_field_class_unsigned_enumeration_mapping_borrow_ranges_const( - mapping); - if (!bt_integer_range_set_unsigned_compare(opt_ranges, - mapping_ranges)) { - is_valid = false; - goto end; - } - } else { - const bt_field_class_variant_with_signed_selector_option *var_opt = - bt_field_class_variant_with_signed_selector_borrow_option_by_index_const( - fc->base.ir_fc, i); - const bt_field_class_signed_enumeration_mapping *mapping; - const bt_integer_range_set_signed *opt_ranges; - const bt_integer_range_set_signed *mapping_ranges; - - mapping = bt_field_class_signed_enumeration_borrow_mapping_by_label_const( - tag_fc->ir_fc, escaped_opt_name->str); - if (!mapping) { - is_valid = false; - goto end; - } - - opt_ranges = bt_field_class_variant_with_signed_selector_option_borrow_ranges_const( - var_opt); - mapping_ranges = bt_field_class_signed_enumeration_mapping_borrow_ranges_const( - mapping); - if (!bt_integer_range_set_signed_compare(opt_ranges, - mapping_ranges)) { - is_valid = false; - goto end; - } - } - } - -end: - return is_valid; -} - -/* - * This function indicates whether or not a given variant FC option name - * must be protected (with the `_` prefix). + * This function protects a given variant FC option name (with the `_` + * prefix) if required. On success, `name_buf->str` contains the variant + * FC option name to use (original option name or protected if + * required). * * One of the goals of `sink.ctf.fs` is to write a CTF trace which is as * close as possible to an original CTF trace as decoded by @@ -884,9 +780,9 @@ end: * FC options and enumeration FC mappings by range set. */ static -int must_protect_variant_option_name(const bt_field_class *ir_var_fc, +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, bool *must_protect) + GString *name_buf) { int ret = 0; uint64_t i; @@ -897,7 +793,6 @@ int must_protect_variant_option_name(const bt_field_class *ir_var_fc, const bt_field_class_variant_option *base_var_opt; bool force_protect = false; - *must_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); @@ -913,7 +808,6 @@ int must_protect_variant_option_name(const bt_field_class *ir_var_fc, */ force_protect = must_protect_identifier(ir_opt_name); if (force_protect) { - *must_protect = true; g_string_assign(name_buf, "_"); g_string_append(name_buf, ir_opt_name); } else { @@ -921,43 +815,43 @@ int must_protect_variant_option_name(const bt_field_class *ir_var_fc, } /* Borrow option's ranges */ - if (ir_var_fc_type == BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR) { + 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_SELECTOR) { - const bt_field_class_variant_with_unsigned_selector_option *var_opt = - bt_field_class_variant_with_unsigned_selector_borrow_option_by_index_const( + } 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 = - bt_field_class_variant_with_unsigned_selector_option_borrow_ranges_const( + bt_field_class_variant_with_selector_field_integer_unsigned_option_borrow_ranges_const( var_opt); } else { - const bt_field_class_variant_with_signed_selector_option *var_opt = - bt_field_class_variant_with_signed_selector_borrow_option_by_index_const( + 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 = - bt_field_class_variant_with_signed_selector_option_borrow_ranges_const( + 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_SELECTOR) { + 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_unsigned_enumeration_mapping *mapping; + const bt_field_class_enumeration_unsigned_mapping *mapping; const bt_integer_range_set_unsigned *mapping_ranges; - mapping = bt_field_class_unsigned_enumeration_borrow_mapping_by_index_const( + mapping = bt_field_class_enumeration_unsigned_borrow_mapping_by_index_const( ir_tag_fc, i); - mapping_ranges = bt_field_class_unsigned_enumeration_mapping_borrow_ranges_const( + mapping_ranges = bt_field_class_enumeration_unsigned_mapping_borrow_ranges_const( mapping); - if (bt_integer_range_set_unsigned_compare(opt_ranges, + if (bt_integer_range_set_unsigned_is_equal(opt_ranges, mapping_ranges)) { /* We have a winner */ mapping_base = - bt_field_class_unsigned_enumeration_mapping_as_mapping_const( + bt_field_class_enumeration_unsigned_mapping_as_mapping_const( mapping); mapping_label = bt_field_class_enumeration_mapping_get_label( @@ -966,19 +860,19 @@ int must_protect_variant_option_name(const bt_field_class *ir_var_fc, } } else { const bt_field_class_enumeration_mapping *mapping_base; - const bt_field_class_signed_enumeration_mapping *mapping; + const bt_field_class_enumeration_signed_mapping *mapping; const bt_integer_range_set_signed *mapping_ranges; - mapping = bt_field_class_signed_enumeration_borrow_mapping_by_index_const( + mapping = bt_field_class_enumeration_signed_borrow_mapping_by_index_const( ir_tag_fc, i); - mapping_ranges = bt_field_class_signed_enumeration_mapping_borrow_ranges_const( + mapping_ranges = bt_field_class_enumeration_signed_mapping_borrow_ranges_const( mapping); - if (bt_integer_range_set_signed_compare(opt_ranges, + if (bt_integer_range_set_signed_is_equal(opt_ranges, mapping_ranges)) { /* We have a winner */ mapping_base = - bt_field_class_signed_enumeration_mapping_as_mapping_const( + bt_field_class_enumeration_signed_mapping_as_mapping_const( mapping); mapping_label = bt_field_class_enumeration_mapping_get_label( @@ -1017,15 +911,53 @@ int must_protect_variant_option_name(const bt_field_class *ir_var_fc, ret = -1; goto end; } + } - /* - * If this comes from a `src.ctf.fs` source, it looks - * like the variant FC option name was initially - * protected: protect it again when going back to TSDL. - */ - *must_protect = true; +end: + return ret; +} + +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, (void *) fc); + ret = cur_path_stack_push(ctx, UINT64_C(-1), NULL, false, content_ir_fc, + (void *) fc); + 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; } @@ -1052,9 +984,9 @@ int translate_variant_field_class(struct ctx *ctx) 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 (ir_fc_type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR || - ir_fc_type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR) { - ir_selector_field_path = bt_field_class_variant_with_selector_borrow_selector_field_path_const( + 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); } @@ -1071,14 +1003,14 @@ int translate_variant_field_class(struct ctx *ctx) bt_field_class_type type = bt_field_class_get_type( tgt_fc->ir_fc); - if (type != BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION && - type != BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION) { + if (!bt_field_class_type_is(type, + BT_FIELD_CLASS_TYPE_ENUMERATION)) { fc->tag_is_before = true; goto validate_opts; } /* - * Call must_protect_variant_option_name() for each + * 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. @@ -1098,6 +1030,7 @@ int translate_variant_field_class(struct ctx *ctx) * create the appropriate selector field class. */ fc->tag_is_before = true; + goto validate_opts; } validate_opts: @@ -1112,12 +1045,13 @@ validate_opts: * cur_path_stack_push(). */ for (i = 0; i < opt_count; i++) { - bool must_protect = false; - - ret = must_protect_variant_option_name(fc->base.ir_fc, - tgt_fc->ir_fc, i, name_buf, &must_protect); - if (ret) { - fc->tag_is_before = true; + 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, @@ -1143,7 +1077,7 @@ validate_opts: opt_name_b = bt_value_array_borrow_element_by_index_const( prot_opt_names, j); - if (bt_value_compare(opt_name_a, opt_name_b)) { + if (bt_value_is_equal(opt_name_a, opt_name_b)) { /* * Variant FC option names are not * unique when protected. @@ -1253,10 +1187,13 @@ int translate_dynamic_array_field_class(struct ctx *ctx) BT_ASSERT(fc); /* Resolve length field class before appending to parent */ - resolve_field_class(ctx, - bt_field_class_dynamic_array_borrow_length_field_path_const( - fc->base.base.ir_fc), - fc->length_ref, &fc->length_is_before, NULL); + 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, (void *) fc); ret = cur_path_stack_push(ctx, UINT64_C(-1), NULL, false, elem_ir_fc, @@ -1279,6 +1216,32 @@ end: return ret; } +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, (void *) fc); + return 0; +} + +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, (void *) fc); + return 0; +} + static inline int translate_integer_field_class(struct ctx *ctx) { @@ -1329,36 +1292,36 @@ static int translate_field_class(struct ctx *ctx) { int ret; - - switch (bt_field_class_get_type(cur_path_stack_top(ctx)->ir_fc)) { - case BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER: - case BT_FIELD_CLASS_TYPE_SIGNED_INTEGER: - case BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION: - case BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION: + 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); - break; - case BT_FIELD_CLASS_TYPE_REAL: + } else if (bt_field_class_type_is(ir_fc_type, + BT_FIELD_CLASS_TYPE_REAL)) { ret = translate_real_field_class(ctx); - break; - case BT_FIELD_CLASS_TYPE_STRING: + } else if (ir_fc_type == BT_FIELD_CLASS_TYPE_STRING) { ret = translate_string_field_class(ctx); - break; - case BT_FIELD_CLASS_TYPE_STRUCTURE: + } else if (ir_fc_type == BT_FIELD_CLASS_TYPE_STRUCTURE) { ret = translate_structure_field_class(ctx); - break; - case BT_FIELD_CLASS_TYPE_STATIC_ARRAY: + } else if (ir_fc_type == BT_FIELD_CLASS_TYPE_STATIC_ARRAY) { ret = translate_static_array_field_class(ctx); - break; - case BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY: + } else if (bt_field_class_type_is(ir_fc_type, + BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY)) { ret = translate_dynamic_array_field_class(ctx); - break; - case BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR: - case BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR: - case BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR: + } 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); - break; - default: - abort(); + } else { + bt_common_abort(); } return ret; @@ -1385,6 +1348,30 @@ int set_field_ref(struct fs_sink_ctf_field_class *fc, const char *fc_name, } 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 = (void *) 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 = (void *) fc; @@ -1404,7 +1391,7 @@ int set_field_ref(struct fs_sink_ctf_field_class *fc, const char *fc_name, break; } default: - abort(); + bt_common_abort(); } BT_ASSERT(field_ref); @@ -1472,12 +1459,28 @@ int set_field_refs(struct fs_sink_ctf_field_class * const 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 = (void *) 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; + 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; @@ -1551,7 +1554,7 @@ end: * fill it. */ static -int translate_scope_field_class(struct ctx *ctx, bt_scope scope, +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) { @@ -1630,7 +1633,7 @@ int translate_event_class(struct fs_sink_comp *fs_sink, BT_ASSERT(ec); ctx.cur_sc = sc; ctx.cur_ec = ec; - ret = translate_scope_field_class(&ctx, BT_SCOPE_EVENT_SPECIFIC_CONTEXT, + 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)); @@ -1638,7 +1641,7 @@ int translate_event_class(struct fs_sink_comp *fs_sink, goto end; } - ret = translate_scope_field_class(&ctx, BT_SCOPE_EVENT_PAYLOAD, + 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) { @@ -1675,6 +1678,7 @@ end: return ret; } +static bool default_clock_class_name_exists(struct fs_sink_ctf_trace *trace, const char *name) { @@ -1754,7 +1758,6 @@ int translate_stream_class(struct fs_sink_comp *fs_sink, (*out_sc)->default_clock_class_name->str)) { /* Invalid: create a new name */ make_unique_default_clock_class_name(*out_sc); - ret = 0; } } else { /* No name: create a name */ @@ -1763,7 +1766,7 @@ int translate_stream_class(struct fs_sink_comp *fs_sink, } ctx.cur_sc = *out_sc; - ret = translate_scope_field_class(&ctx, BT_SCOPE_PACKET_CONTEXT, + 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) { @@ -1780,7 +1783,7 @@ int translate_stream_class(struct fs_sink_comp *fs_sink, (void *) (*out_sc)->packet_context_fc, 8); } - ret = translate_scope_field_class(&ctx, BT_SCOPE_EVENT_COMMON_CONTEXT, + 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));