X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=src%2Fplugins%2Ftext%2Fdetails%2Fwrite.c;h=47bf66fd45634ccf62d10413078b46fafd75ad55;hb=8bc207afcf9695b096a0a8e8405f06b6328f069b;hp=fa150b6abe6bfb54b438686d4aaf30bf6d1c1345;hpb=1bca9d2143c448c1faf53ba6b719507ea0d09e2f;p=babeltrace.git diff --git a/src/plugins/text/details/write.c b/src/plugins/text/details/write.c index fa150b6a..47bf66fd 100644 --- a/src/plugins/text/details/write.c +++ b/src/plugins/text/details/write.c @@ -199,14 +199,15 @@ void write_compound_member_name(struct details_write_ctx *ctx, const char *name) } static inline -void write_array_index(struct details_write_ctx *ctx, uint64_t index) +void write_array_index(struct details_write_ctx *ctx, uint64_t index, + const char *color) { char buf[32]; write_indent(ctx); format_uint(buf, index, 10); g_string_append_printf(ctx->str, "%s[%s]%s:", - color_fg_cyan(ctx), buf, color_reset(ctx)); + color, buf, color_reset(ctx)); } static inline @@ -223,6 +224,14 @@ void write_prop_name(struct details_write_ctx *ctx, const char *prop_name) color_fg_magenta(ctx), prop_name, color_reset(ctx)); } +static inline +void write_prop_name_line(struct details_write_ctx *ctx, const char *prop_name) +{ + write_indent(ctx); + g_string_append_printf(ctx->str, "%s%s%s:", + color_fg_magenta(ctx), prop_name, color_reset(ctx)); +} + static inline void write_str_prop_value(struct details_write_ctx *ctx, const char *value) { @@ -352,6 +361,152 @@ void write_uuid_prop_line(struct details_write_ctx *ctx, const char *prop_name, color_reset(ctx)); } +static +gint compare_strings(const char **a, const char **b) +{ + return strcmp(*a, *b); +} + +static +bt_bool map_value_foreach_add_key_to_array(const char *key, + const bt_value *object, void *data) +{ + GPtrArray *keys = data; + + BT_ASSERT(keys); + g_ptr_array_add(keys, (void *) key); + return BT_TRUE; +} + +static +void write_value(struct details_write_ctx *ctx, const bt_value *value, + const char *name) +{ + uint64_t i; + bt_value_type value_type = bt_value_get_type(value); + GPtrArray *keys = g_ptr_array_new(); + char buf[64]; + + BT_ASSERT(keys); + + /* Write field's name */ + if (name) { + write_prop_name_line(ctx, name); + } + + /* Write field's value */ + switch (value_type) { + case BT_VALUE_TYPE_NULL: + write_sp(ctx); + write_none_prop_value(ctx, "Null"); + break; + case BT_VALUE_TYPE_BOOL: + write_sp(ctx); + write_bool_prop_value(ctx, bt_value_bool_get(value)); + break; + case BT_VALUE_TYPE_UNSIGNED_INTEGER: + format_uint(buf, bt_value_integer_unsigned_get(value), 10); + write_sp(ctx); + write_uint_str_prop_value(ctx, buf); + break; + case BT_VALUE_TYPE_SIGNED_INTEGER: + format_int(buf, bt_value_integer_signed_get(value), 10); + write_sp(ctx); + write_int_str_prop_value(ctx, buf); + break; + case BT_VALUE_TYPE_REAL: + write_sp(ctx); + write_float_prop_value(ctx, bt_value_real_get(value)); + break; + case BT_VALUE_TYPE_STRING: + write_sp(ctx); + write_str_prop_value(ctx, bt_value_string_get(value)); + break; + case BT_VALUE_TYPE_ARRAY: + { + uint64_t length = bt_value_array_get_length(value); + + if (length == 0) { + write_sp(ctx); + write_none_prop_value(ctx, "Empty"); + } else { + g_string_append(ctx->str, " Length "); + write_uint_prop_value(ctx, length); + g_string_append_c(ctx->str, ':'); + } + + incr_indent(ctx); + + for (i = 0; i < length; i++) { + const bt_value *elem_value = + bt_value_array_borrow_element_by_index_const( + value, i); + + write_nl(ctx); + write_array_index(ctx, i, color_fg_magenta(ctx)); + write_value(ctx, elem_value, NULL); + } + + decr_indent(ctx); + break; + } + case BT_VALUE_TYPE_MAP: + { + bt_value_map_foreach_entry_const_status foreach_status = + bt_value_map_foreach_entry_const(value, + map_value_foreach_add_key_to_array, keys); + + BT_ASSERT(foreach_status == + BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_OK); + g_ptr_array_sort(keys, (GCompareFunc) compare_strings); + + if (keys->len > 0) { + incr_indent(ctx); + + for (i = 0; i < keys->len; i++) { + const char *key = keys->pdata[i]; + const bt_value *entry_value = + bt_value_map_borrow_entry_value_const( + value, key); + + write_nl(ctx); + write_value(ctx, entry_value, key); + } + + decr_indent(ctx); + } else { + write_sp(ctx); + write_none_prop_value(ctx, "Empty"); + } + + break; + } + default: + abort(); + } + + g_ptr_array_free(keys, TRUE); +} + +static +void write_user_attributes(struct details_write_ctx *ctx, + const bt_value *user_attrs, bool write_newline, bool *written) +{ + BT_ASSERT(user_attrs); + + if (!bt_value_map_is_empty(user_attrs)) { + write_value(ctx, user_attrs, "User attributes"); + + if (write_newline) { + write_nl(ctx); + } + + if (written) { + *written = true; + } + } +} + static void write_int_field_class_props(struct details_write_ctx *ctx, const bt_field_class *fc, bool close) @@ -597,7 +752,7 @@ void write_enum_field_class_mappings(struct details_write_ctx *ctx, struct enum_field_class_mapping *mapping = mappings->pdata[i]; write_nl(ctx); - write_compound_member_name(ctx, mapping->label); + write_prop_name_line(ctx, mapping->label); for (range_i = 0; range_i < mapping->ranges->len; range_i++) { write_sp(ctx); @@ -672,30 +827,35 @@ void write_variant_field_class_option(struct details_write_ctx *ctx, const bt_field_class_variant_option *option = bt_field_class_variant_borrow_option_by_index_const( fc, index); - const void *orig_ranges; + const void *orig_ranges = NULL; GArray *int_ranges = NULL; bool is_signed; + const bt_value *user_attrs = + bt_field_class_variant_option_borrow_user_attributes_const( + option); + const bt_field_class *option_fc = + bt_field_class_variant_option_borrow_field_class_const(option); write_nl(ctx); write_compound_member_name(ctx, bt_field_class_variant_option_get_name(option)); - if (fc_type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR) { - const bt_field_class_variant_with_selector_unsigned_option *spec_opt = - bt_field_class_variant_with_selector_unsigned_borrow_option_by_index_const( + if (fc_type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD) { + const bt_field_class_variant_with_selector_field_integer_unsigned_option *spec_opt = + bt_field_class_variant_with_selector_field_integer_unsigned_borrow_option_by_index_const( fc, index); orig_ranges = - bt_field_class_variant_with_selector_unsigned_option_borrow_ranges_const( + bt_field_class_variant_with_selector_field_integer_unsigned_option_borrow_ranges_const( spec_opt); is_signed = false; - } else { - const bt_field_class_variant_with_selector_signed_option *spec_opt = - bt_field_class_variant_with_selector_signed_borrow_option_by_index_const( + } else if (fc_type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR_FIELD) { + const bt_field_class_variant_with_selector_field_integer_signed_option *spec_opt = + bt_field_class_variant_with_selector_field_integer_signed_borrow_option_by_index_const( fc, index); orig_ranges = - bt_field_class_variant_with_selector_signed_option_borrow_ranges_const( + bt_field_class_variant_with_selector_field_integer_signed_option_borrow_ranges_const( spec_opt); is_signed = true; } @@ -718,53 +878,27 @@ void write_variant_field_class_option(struct details_write_ctx *ctx, write_sp(ctx); } - write_field_class(ctx, - bt_field_class_variant_option_borrow_field_class_const(option)); - - if (int_ranges) { - g_array_free(int_ranges, TRUE); - } -} - -static -void write_variant_field_class(struct details_write_ctx *ctx, - const bt_field_class *fc) -{ - bt_field_class_type fc_type = bt_field_class_get_type(fc); - uint64_t option_count = - bt_field_class_variant_get_option_count(fc); - const bt_field_path *sel_field_path = NULL; + if (bt_value_map_is_empty(user_attrs)) { + write_field_class(ctx, option_fc); + } else { + write_nl(ctx); + incr_indent(ctx); - if (fc_type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR) { - sel_field_path = - bt_field_class_variant_with_selector_borrow_selector_field_path_const( - fc); - BT_ASSERT(sel_field_path); - } + /* Field class */ + write_prop_name_line(ctx, "Field class"); + write_sp(ctx); + write_field_class(ctx, option_fc); + write_nl(ctx); - g_string_append(ctx->str, " ("); - write_uint_prop_value(ctx, option_count); - g_string_append_printf(ctx->str, " option%s, ", - plural(option_count)); + /* User attributes */ + write_user_attributes(ctx, user_attrs, + false, NULL); - if (sel_field_path) { - g_string_append(ctx->str, "Selector field path "); - write_field_path(ctx, sel_field_path); + decr_indent(ctx); } - g_string_append_c(ctx->str, ')'); - - if (option_count > 0) { - uint64_t i; - - g_string_append_c(ctx->str, ':'); - incr_indent(ctx); - - for (i = 0; i < option_count; i++) { - write_variant_field_class_option(ctx, fc, i); - } - - decr_indent(ctx); + if (int_ranges) { + g_array_free(int_ranges, TRUE); } } @@ -774,12 +908,17 @@ void write_field_class(struct details_write_ctx *ctx, const bt_field_class *fc) uint64_t i; const char *type; bt_field_class_type fc_type = bt_field_class_get_type(fc); + const bt_value *user_attrs; + bool wrote_user_attrs = false; /* Write field class's type */ switch (fc_type) { case BT_FIELD_CLASS_TYPE_BOOL: type = "Boolean"; break; + case BT_FIELD_CLASS_TYPE_BIT_ARRAY: + type = "Bit array"; + break; case BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER: type = "Unsigned integer"; break; @@ -792,8 +931,11 @@ void write_field_class(struct details_write_ctx *ctx, const bt_field_class *fc) case BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION: type = "Signed enumeration"; break; - case BT_FIELD_CLASS_TYPE_REAL: - type = "Real"; + case BT_FIELD_CLASS_TYPE_SINGLE_PRECISION_REAL: + type = "Single-precision real"; + break; + case BT_FIELD_CLASS_TYPE_DOUBLE_PRECISION_REAL: + type = "Double-precision real"; break; case BT_FIELD_CLASS_TYPE_STRING: type = "String"; @@ -804,20 +946,32 @@ void write_field_class(struct details_write_ctx *ctx, const bt_field_class *fc) case BT_FIELD_CLASS_TYPE_STATIC_ARRAY: type = "Static array"; break; - case BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY: - type = "Dynamic array"; + case BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITHOUT_LENGTH_FIELD: + type = "Dynamic array (no length field)"; + break; + case BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITH_LENGTH_FIELD: + type = "Dynamic array (with length field)"; + break; + case BT_FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR_FIELD: + type = "Option (no selector)"; + break; + case BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR_FIELD: + type = "Option (boolean selector)"; + break; + case BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD: + type = "Option (unsigned integer selector)"; break; - case BT_FIELD_CLASS_TYPE_OPTION: - type = "Option"; + case BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR_FIELD: + type = "Option (signed integer selector)"; break; - case BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR: + case BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR_FIELD: type = "Variant (no selector)"; break; - case BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR: - type = "Variant (unsigned selector)"; + case BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD: + type = "Variant (unsigned integer selector)"; break; - case BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR: - type = "Variant (signed selector)"; + case BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR_FIELD: + type = "Variant (signed integer selector)"; break; default: abort(); @@ -826,7 +980,7 @@ void write_field_class(struct details_write_ctx *ctx, const bt_field_class *fc) g_string_append_printf(ctx->str, "%s%s%s", color_fg_blue(ctx), type, color_reset(ctx)); - /* Write field class's properties */ + /* Write field class's single-line properties */ switch (fc_type) { case BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER: case BT_FIELD_CLASS_TYPE_SIGNED_INTEGER: @@ -845,113 +999,279 @@ void write_field_class(struct details_write_ctx *ctx, const bt_field_class *fc) write_uint_prop_value(ctx, mapping_count); g_string_append_printf(ctx->str, " mapping%s)", plural(mapping_count)); + break; + } + case BT_FIELD_CLASS_TYPE_STRUCTURE: + { + uint64_t member_count = + bt_field_class_structure_get_member_count(fc); - if (mapping_count > 0) { - g_string_append_c(ctx->str, ':'); - incr_indent(ctx); - write_enum_field_class_mappings(ctx, fc); - decr_indent(ctx); + g_string_append(ctx->str, " ("); + write_uint_prop_value(ctx, member_count); + g_string_append_printf(ctx->str, " member%s)", + plural(member_count)); + break; + } + case BT_FIELD_CLASS_TYPE_STATIC_ARRAY: + case BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITHOUT_LENGTH_FIELD: + case BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITH_LENGTH_FIELD: + if (fc_type == BT_FIELD_CLASS_TYPE_STATIC_ARRAY) { + g_string_append(ctx->str, " (Length "); + write_uint_prop_value(ctx, + bt_field_class_array_static_get_length(fc)); + g_string_append_c(ctx->str, ')'); + } else if (fc_type == BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITH_LENGTH_FIELD) { + const bt_field_path *length_field_path = + bt_field_class_array_dynamic_with_length_field_borrow_length_field_path_const( + fc); + + g_string_append(ctx->str, " (Length field path "); + write_field_path(ctx, length_field_path); + g_string_append_c(ctx->str, ')'); } + break; + case BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR_FIELD: + case BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD: + case BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR_FIELD: + { + const bt_field_path *selector_field_path = + bt_field_class_option_with_selector_field_borrow_selector_field_path_const( + fc); + + g_string_append(ctx->str, " (Selector field path "); + write_field_path(ctx, selector_field_path); + g_string_append_c(ctx->str, ')'); break; } - case BT_FIELD_CLASS_TYPE_REAL: - if (bt_field_class_real_is_single_precision(fc)) { - g_string_append(ctx->str, " (Single precision)"); - } else { - g_string_append(ctx->str, " (Double precision)"); + case BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR_FIELD: + case BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD: + case BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR_FIELD: + { + uint64_t option_count = + bt_field_class_variant_get_option_count(fc); + const bt_field_path *sel_field_path = NULL; + + if (fc_type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD || + fc_type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR_FIELD) { + sel_field_path = + bt_field_class_variant_with_selector_field_borrow_selector_field_path_const( + fc); + BT_ASSERT(sel_field_path); + } + + g_string_append(ctx->str, " ("); + write_uint_prop_value(ctx, option_count); + g_string_append_printf(ctx->str, " option%s", + plural(option_count)); + + if (sel_field_path) { + g_string_append(ctx->str, ", Selector field path "); + write_field_path(ctx, sel_field_path); + } + + g_string_append_c(ctx->str, ')'); + break; + } + default: + break; + } + + incr_indent(ctx); + user_attrs = bt_field_class_borrow_user_attributes_const(fc); + if (!bt_value_map_is_empty(user_attrs)) { + g_string_append(ctx->str, ":\n"); + write_user_attributes(ctx, user_attrs, false, NULL); + wrote_user_attrs = true; + } + + /* Write field class's complex properties */ + switch (fc_type) { + case BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION: + case BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION: + { + uint64_t mapping_count = + bt_field_class_enumeration_get_mapping_count(fc); + + if (mapping_count > 0) { + if (wrote_user_attrs) { + write_nl(ctx); + write_indent(ctx); + write_prop_name(ctx, "Mappings"); + g_string_append_c(ctx->str, ':'); + incr_indent(ctx); + } else { + /* Each mapping starts with its own newline */ + g_string_append_c(ctx->str, ':'); + } + + write_enum_field_class_mappings(ctx, fc); + + if (wrote_user_attrs) { + decr_indent(ctx); + } } break; + } case BT_FIELD_CLASS_TYPE_STRUCTURE: { uint64_t member_count = bt_field_class_structure_get_member_count(fc); - g_string_append(ctx->str, " ("); - write_uint_prop_value(ctx, member_count); - g_string_append_printf(ctx->str, " member%s)", - plural(member_count)); - if (member_count > 0) { - g_string_append_c(ctx->str, ':'); - incr_indent(ctx); + if (wrote_user_attrs) { + write_nl(ctx); + write_indent(ctx); + write_prop_name(ctx, "Members"); + g_string_append_c(ctx->str, ':'); + incr_indent(ctx); + } else { + /* Each member starts with its own newline */ + g_string_append_c(ctx->str, ':'); + } for (i = 0; i < member_count; i++) { const bt_field_class_structure_member *member = bt_field_class_structure_borrow_member_by_index_const( fc, i); + const bt_value *user_attrs; + const bt_field_class *member_fc = + bt_field_class_structure_member_borrow_field_class_const(member); write_nl(ctx); write_compound_member_name(ctx, bt_field_class_structure_member_get_name(member)); - write_sp(ctx); - write_field_class(ctx, - bt_field_class_structure_member_borrow_field_class_const(member)); + user_attrs = bt_field_class_structure_member_borrow_user_attributes_const( + member); + + if (bt_value_map_is_empty(user_attrs)) { + write_sp(ctx); + write_field_class(ctx, member_fc); + } else { + write_nl(ctx); + incr_indent(ctx); + + /* Field class */ + write_prop_name_line(ctx, "Field class"); + write_sp(ctx); + write_field_class(ctx, member_fc); + write_nl(ctx); + + /* User attributes */ + write_user_attributes(ctx, user_attrs, + false, NULL); + + decr_indent(ctx); + } } - decr_indent(ctx); + if (wrote_user_attrs) { + decr_indent(ctx); + } } break; } case BT_FIELD_CLASS_TYPE_STATIC_ARRAY: - case BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY: - if (fc_type == BT_FIELD_CLASS_TYPE_STATIC_ARRAY) { - g_string_append(ctx->str, " (Length "); - write_uint_prop_value(ctx, - bt_field_class_array_static_get_length(fc)); - g_string_append_c(ctx->str, ')'); + case BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITHOUT_LENGTH_FIELD: + case BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITH_LENGTH_FIELD: + if (wrote_user_attrs) { + write_nl(ctx); } else { - const bt_field_path *length_field_path = - bt_field_class_array_dynamic_borrow_length_field_path_const( - fc); - - if (length_field_path) { - g_string_append(ctx->str, " (Length field path "); - write_field_path(ctx, length_field_path); - g_string_append_c(ctx->str, ')'); - } + g_string_append(ctx->str, ":\n"); } - g_string_append_c(ctx->str, ':'); - write_nl(ctx); - incr_indent(ctx); - write_compound_member_name(ctx, "Element"); + write_prop_name_line(ctx, "Element"); write_sp(ctx); write_field_class(ctx, bt_field_class_array_borrow_element_field_class_const(fc)); - decr_indent(ctx); break; - case BT_FIELD_CLASS_TYPE_OPTION: + case BT_FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR_FIELD: + case BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR_FIELD: + case BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD: + case BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR_FIELD: { - const bt_field_path *selector_field_path = - bt_field_class_option_borrow_selector_field_path_const(fc); + const void *ranges = NULL; + bool selector_is_signed = false; - if (selector_field_path) { - g_string_append(ctx->str, " (Selector field path "); - write_field_path(ctx, selector_field_path); - g_string_append_c(ctx->str, ')'); + if (wrote_user_attrs) { + write_nl(ctx); + } else { + g_string_append(ctx->str, ":\n"); } - g_string_append_c(ctx->str, ':'); - write_nl(ctx); - incr_indent(ctx); - write_compound_member_name(ctx, "Content"); + if (fc_type == BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR_FIELD) { + write_bool_prop_line(ctx, "Selector is reversed", + bt_field_class_option_with_selector_field_bool_selector_is_reversed(fc)); + } else if (fc_type == BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD) { + ranges = bt_field_class_option_with_selector_field_integer_unsigned_borrow_selector_ranges_const(fc); + } else if (fc_type == BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR_FIELD) { + ranges = bt_field_class_option_with_selector_field_integer_signed_borrow_selector_ranges_const(fc); + selector_is_signed = true; + } + + if (ranges) { + GArray *sorted_ranges = range_set_to_int_ranges( + ranges, selector_is_signed); + uint64_t i; + + BT_ASSERT(sorted_ranges); + BT_ASSERT(sorted_ranges->len > 0); + write_prop_name_line(ctx, "Selector ranges"); + + for (i = 0; i < sorted_ranges->len; i++) { + write_sp(ctx); + write_int_range(ctx, + int_range_at(sorted_ranges, i), + selector_is_signed); + } + + write_nl(ctx); + g_array_free(sorted_ranges, TRUE); + } + + write_prop_name_line(ctx, "Content"); write_sp(ctx); write_field_class(ctx, bt_field_class_option_borrow_field_class_const(fc)); - decr_indent(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: - write_variant_field_class(ctx, fc); + case BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR_FIELD: + case BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD: + case BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR_FIELD: + { + uint64_t option_count = + bt_field_class_variant_get_option_count(fc); + + if (option_count > 0) { + if (wrote_user_attrs) { + write_nl(ctx); + write_indent(ctx); + write_prop_name(ctx, "Options"); + g_string_append_c(ctx->str, ':'); + incr_indent(ctx); + } else { + /* Each option starts with its own newline */ + g_string_append_c(ctx->str, ':'); + } + + for (i = 0; i < option_count; i++) { + write_variant_field_class_option(ctx, fc, i); + } + + if (wrote_user_attrs) { + decr_indent(ctx); + } + } + break; + } default: break; } + + decr_indent(ctx); } static @@ -991,6 +1311,10 @@ void write_event_class(struct details_write_ctx *ctx, const bt_event_class *ec) /* Write properties */ incr_indent(ctx); + /* Write user attributes */ + write_user_attributes(ctx, + bt_event_class_borrow_user_attributes_const(ec), true, NULL); + /* Write log level */ if (bt_event_class_get_log_level(ec, &log_level) == BT_PROPERTY_AVAILABILITY_AVAILABLE) { @@ -1083,6 +1407,8 @@ void write_clock_class_prop_lines(struct details_write_ctx *ctx, write_str_prop_line(ctx, "Name", str); } + write_user_attributes(ctx, + bt_clock_class_borrow_user_attributes_const(cc), true, NULL); str = bt_clock_class_get_description(cc); if (str) { write_str_prop_line(ctx, "Description", str); @@ -1151,6 +1477,10 @@ void write_stream_class(struct details_write_ctx *ctx, /* Write properties */ incr_indent(ctx); + /* Write user attributes */ + write_user_attributes(ctx, + bt_stream_class_borrow_user_attributes_const(sc), true, NULL); + /* Write configuration */ write_bool_prop_line(ctx, "Supports packets", bt_stream_class_supports_packets(sc)); @@ -1238,12 +1568,6 @@ gint compare_stream_classes(const bt_stream_class **a, const bt_stream_class **b } } -static -gint compare_strings(const char **a, const char **b) -{ - return strcmp(*a, *b); -} - static void write_trace_class(struct details_write_ctx *ctx, const bt_trace_class *tc) { @@ -1254,6 +1578,7 @@ void write_trace_class(struct details_write_ctx *ctx, const bt_trace_class *tc) write_indent(ctx); write_obj_type_name(ctx, "Trace class"); + for (i = 0; i < bt_trace_class_get_stream_class_count(tc); i++) { g_ptr_array_add(stream_classes, (gpointer) bt_trace_class_borrow_stream_class_by_index_const( @@ -1271,6 +1596,12 @@ void write_trace_class(struct details_write_ctx *ctx, const bt_trace_class *tc) incr_indent(ctx); + /* Write user attributes */ + write_user_attributes(ctx, + bt_trace_class_borrow_user_attributes_const(tc), true, + &printed_prop); + + /* Write stream classes */ for (i = 0; i < stream_classes->len; i++) { write_stream_class(ctx, stream_classes->pdata[i]); } @@ -1310,7 +1641,6 @@ int try_write_meta(struct details_write_ctx *ctx, const bt_trace_class *tc, * rewrite `sc`. */ write_trace_class(ctx, tc); - write_nl(ctx); /* * Mark this trace class as written, as well as all @@ -1362,7 +1692,6 @@ int try_write_meta(struct details_write_ctx *ctx, const bt_trace_class *tc, * classes, so we don't need to rewrite `ec`. */ write_stream_class(ctx, sc); - write_nl(ctx); /* * Mark this stream class as written, as well as all its @@ -1395,7 +1724,6 @@ int try_write_meta(struct details_write_ctx *ctx, const bt_trace_class *tc, } write_event_class(ctx, ec); - write_nl(ctx); details_did_write_meta_object(ctx, tc, ec); goto end; } @@ -1520,6 +1848,12 @@ void write_field(struct details_write_ctx *ctx, const bt_field *field, write_sp(ctx); write_bool_prop_value(ctx, bt_field_bool_get_value(field)); break; + case BT_FIELD_CLASS_TYPE_BIT_ARRAY: + format_uint(buf, bt_field_bit_array_get_value_as_integer(field), + 16); + write_sp(ctx); + write_uint_str_prop_value(ctx, buf); + break; case BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER: case BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION: case BT_FIELD_CLASS_TYPE_SIGNED_INTEGER: @@ -1565,9 +1899,13 @@ void write_field(struct details_write_ctx *ctx, const bt_field *field, break; } - case BT_FIELD_CLASS_TYPE_REAL: + case BT_FIELD_CLASS_TYPE_SINGLE_PRECISION_REAL: write_sp(ctx); - write_float_prop_value(ctx, bt_field_real_get_value(field)); + write_float_prop_value(ctx, bt_field_real_single_precision_get_value(field)); + break; + case BT_FIELD_CLASS_TYPE_DOUBLE_PRECISION_REAL: + write_sp(ctx); + write_float_prop_value(ctx, bt_field_real_double_precision_get_value(field)); break; case BT_FIELD_CLASS_TYPE_STRING: write_sp(ctx); @@ -1598,18 +1936,21 @@ void write_field(struct details_write_ctx *ctx, const bt_field *field, decr_indent(ctx); } else { - g_string_append(ctx->str, " Empty"); + write_sp(ctx); + write_none_prop_value(ctx, "Empty"); } break; } case BT_FIELD_CLASS_TYPE_STATIC_ARRAY: - case BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY: + case BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITHOUT_LENGTH_FIELD: + case BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITH_LENGTH_FIELD: { uint64_t length = bt_field_array_get_length(field); if (length == 0) { - g_string_append(ctx->str, " Empty"); + write_sp(ctx); + write_none_prop_value(ctx, "Empty"); } else { g_string_append(ctx->str, " Length "); write_uint_prop_value(ctx, length); @@ -1624,14 +1965,17 @@ void write_field(struct details_write_ctx *ctx, const bt_field *field, field, i); write_nl(ctx); - write_array_index(ctx, i); + write_array_index(ctx, i, color_fg_cyan(ctx)); write_field(ctx, elem_field, NULL); } decr_indent(ctx); break; } - case BT_FIELD_CLASS_TYPE_OPTION: + case BT_FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR_FIELD: + case BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR_FIELD: + case BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD: + case BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR_FIELD: { const bt_field *content_field = bt_field_option_borrow_field_const(field); @@ -1645,9 +1989,9 @@ void write_field(struct details_write_ctx *ctx, const bt_field *field, 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: + case BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR_FIELD: + case BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD: + case BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR_FIELD: write_field(ctx, bt_field_variant_borrow_selected_option_field_const( field), NULL); @@ -1688,6 +2032,18 @@ int write_event_message(struct details_write_ctx *ctx, goto end; } + if (!ctx->details_comp->cfg.with_data) { + goto end; + } + + if (ctx->str->len > 0) { + /* + * Output buffer contains metadata: separate blocks with + * newline. + */ + write_nl(ctx); + } + /* Write time */ if (bt_stream_class_borrow_default_clock_class_const(sc)) { write_time(ctx, @@ -1744,7 +2100,6 @@ int write_event_message(struct details_write_ctx *ctx, decr_indent(ctx); end: - return ret; } @@ -1925,6 +2280,18 @@ int write_stream_beginning_message(struct details_write_ctx *ctx, goto end; } + if (!ctx->details_comp->cfg.with_data) { + goto end; + } + + if (ctx->str->len > 0) { + /* + * Output buffer contains metadata: separate blocks with + * newline. + */ + write_nl(ctx); + } + /* Write time */ if (cc) { const bt_clock_snapshot *cs; @@ -1988,6 +2355,10 @@ int write_stream_end_message(struct details_write_ctx *ctx, const bt_clock_class *cc = bt_stream_class_borrow_default_clock_class_const(sc); + if (!ctx->details_comp->cfg.with_data) { + goto end; + } + /* Write time */ if (cc) { const bt_clock_snapshot *cs; @@ -2025,6 +2396,10 @@ int write_packet_beginning_message(struct details_write_ctx *ctx, const bt_stream_class *sc = bt_stream_borrow_class_const(stream); const bt_field *field; + if (!ctx->details_comp->cfg.with_data) { + goto end; + } + /* Write time */ if (bt_stream_class_packets_have_beginning_default_clock_snapshot(sc)) { write_time(ctx, @@ -2046,15 +2421,16 @@ int write_packet_beginning_message(struct details_write_ctx *ctx, } /* Write field */ - g_string_append(ctx->str, ":\n"); - incr_indent(ctx); field = bt_packet_borrow_context_field_const(packet); if (field) { + g_string_append(ctx->str, ":\n"); + incr_indent(ctx); write_root_field(ctx, "Context", field); + decr_indent(ctx); + } else { + write_nl(ctx); } - decr_indent(ctx); - end: return ret; } @@ -2101,6 +2477,7 @@ static int write_discarded_events_message(struct details_write_ctx *ctx, const bt_message *msg) { + int ret = 0; const bt_stream *stream = bt_message_discarded_events_borrow_stream_const( msg); const bt_stream_class *sc = bt_stream_borrow_class_const(stream); @@ -2108,6 +2485,10 @@ int write_discarded_events_message(struct details_write_ctx *ctx, const bt_clock_snapshot *end_cs = NULL; uint64_t count; + if (!ctx->details_comp->cfg.with_data) { + goto end; + } + if (bt_stream_class_discarded_events_have_default_clock_snapshots(sc)) { beginning_cs = bt_message_discarded_events_borrow_beginning_default_clock_snapshot_const( @@ -2122,14 +2503,18 @@ int write_discarded_events_message(struct details_write_ctx *ctx, count = UINT64_C(-1); } - return write_discarded_items_message(ctx, "events", stream, + ret = write_discarded_items_message(ctx, "events", stream, beginning_cs, end_cs, count); + +end: + return ret; } static int write_discarded_packets_message(struct details_write_ctx *ctx, const bt_message *msg) { + int ret = 0; const bt_stream *stream = bt_message_discarded_packets_borrow_stream_const( msg); const bt_stream_class *sc = bt_stream_borrow_class_const(stream); @@ -2137,6 +2522,10 @@ int write_discarded_packets_message(struct details_write_ctx *ctx, const bt_clock_snapshot *end_cs = NULL; uint64_t count; + if (!ctx->details_comp->cfg.with_data) { + goto end; + } + if (bt_stream_class_discarded_packets_have_default_clock_snapshots(sc)) { beginning_cs = bt_message_discarded_packets_borrow_beginning_default_clock_snapshot_const( @@ -2151,8 +2540,11 @@ int write_discarded_packets_message(struct details_write_ctx *ctx, count = UINT64_C(-1); } - return write_discarded_items_message(ctx, "packets", stream, + ret = write_discarded_items_message(ctx, "packets", stream, beginning_cs, end_cs, count); + +end: + return ret; } static @@ -2165,6 +2557,10 @@ int write_packet_end_message(struct details_write_ctx *ctx, const bt_stream *stream = bt_packet_borrow_stream_const(packet); const bt_stream_class *sc = bt_stream_borrow_class_const(stream); + if (!ctx->details_comp->cfg.with_data) { + goto end; + } + /* Write time */ if (bt_stream_class_packets_have_end_default_clock_snapshot(sc)) { write_time(ctx, @@ -2233,10 +2629,6 @@ int details_write_message(struct details_comp *details_comp, /* Reset output buffer */ g_string_assign(details_comp->str, ""); - if (details_comp->printed_something && !details_comp->cfg.compact) { - write_nl(&ctx); - } - switch (bt_message_get_type(msg)) { case BT_MESSAGE_TYPE_EVENT: ret = write_event_message(&ctx, msg); @@ -2266,5 +2658,17 @@ int details_write_message(struct details_comp *details_comp, abort(); } + /* + * If this component printed at least one character so far, and + * we're not in compact mode, and there's something in the + * output buffer for this message, then prepend a newline to the + * output buffer to visually separate message blocks. + */ + if (details_comp->printed_something && !details_comp->cfg.compact && + details_comp->str->len > 0) { + /* TODO: Optimize this */ + g_string_prepend_c(details_comp->str, '\n'); + } + return ret; }