#include "common/assert.h"
#include "common/common.h"
+#include "common/uuid.h"
#include "details.h"
#include "write.h"
#include "obj-lifetime-mgmt.h"
}
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
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)
{
color_bold(ctx), value, color_reset(ctx));
}
+static inline
+void write_none_prop_value(struct details_write_ctx *ctx, const char *value)
+{
+ g_string_append_printf(ctx->str, "%s%s%s%s",
+ color_bold(ctx), color_fg_magenta(ctx),
+ value, color_reset(ctx));
+}
+
static inline
void write_uint_str_prop_value(struct details_write_ctx *ctx, const char *value)
{
}
static inline
-void write_bool_prop_line(struct details_write_ctx *ctx, const char *prop_name,
- bt_bool prop_value)
+void write_bool_prop_value(struct details_write_ctx *ctx, bt_bool prop_value)
{
const char *str;
- write_indent(ctx);
- write_prop_name(ctx, prop_name);
- g_string_append_printf(ctx->str, ": %s", color_bold(ctx));
+ g_string_append(ctx->str, color_bold(ctx));
if (prop_value) {
g_string_append(ctx->str, color_fg_green(ctx));
str = "No";
}
- g_string_append_printf(ctx->str, "%s%s\n", str, color_reset(ctx));
+ g_string_append_printf(ctx->str, "%s%s", str, color_reset(ctx));
+}
+
+static inline
+void write_bool_prop_line(struct details_write_ctx *ctx, const char *prop_name,
+ bt_bool prop_value)
+{
+ write_indent(ctx);
+ write_prop_name(ctx, prop_name);
+ g_string_append(ctx->str, ": ");
+ write_bool_prop_value(ctx, prop_value);
+ write_nl(ctx);
}
static inline
write_indent(ctx);
write_prop_name(ctx, prop_name);
g_string_append_printf(ctx->str,
- ": %s%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x%s\n",
+ ": %s" BT_UUID_FMT "%s\n",
color_bold(ctx),
- (unsigned int) uuid[0],
- (unsigned int) uuid[1],
- (unsigned int) uuid[2],
- (unsigned int) uuid[3],
- (unsigned int) uuid[4],
- (unsigned int) uuid[5],
- (unsigned int) uuid[6],
- (unsigned int) uuid[7],
- (unsigned int) uuid[8],
- (unsigned int) uuid[9],
- (unsigned int) uuid[10],
- (unsigned int) uuid[11],
- (unsigned int) uuid[12],
- (unsigned int) uuid[13],
- (unsigned int) uuid[14],
- (unsigned int) uuid[15],
+ BT_UUID_FMT_VALUES(uuid),
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)
}
}
-struct enum_field_class_mapping_range {
+struct int_range {
union {
uint64_t u;
int64_t i;
/* Weak */
const char *label;
- /* Array of `struct enum_field_class_mapping_range` */
+ /* Array of `struct int_range` */
GArray *ranges;
};
}
static
-gint compare_enum_field_class_mapping_ranges_signed(
- struct enum_field_class_mapping_range *a,
- struct enum_field_class_mapping_range *b)
+gint compare_int_ranges_signed(struct int_range *a, struct int_range *b)
{
if (a->lower.i < b->lower.i) {
}
static
-gint compare_enum_field_class_mapping_ranges_unsigned(
- struct enum_field_class_mapping_range *a,
- struct enum_field_class_mapping_range *b)
+gint compare_int_ranges_unsigned(struct int_range *a, struct int_range *b)
{
if (a->lower.u < b->lower.u) {
return -1;
}
}
+static
+GArray *range_set_to_int_ranges(const void *spec_range_set, bool is_signed)
+{
+ uint64_t i;
+ const bt_integer_range_set *range_set;
+ GArray *ranges = g_array_new(FALSE, TRUE, sizeof(struct int_range));
+
+ if (!ranges) {
+ goto end;
+ }
+
+ if (is_signed) {
+ range_set = bt_integer_range_set_signed_as_range_set_const(
+ spec_range_set);
+ } else {
+ range_set = bt_integer_range_set_unsigned_as_range_set_const(
+ spec_range_set);
+ }
+
+ for (i = 0; i < bt_integer_range_set_get_range_count(range_set); i++) {
+ struct int_range range;
+
+ if (is_signed) {
+ const bt_integer_range_signed *orig_range =
+ bt_integer_range_set_signed_borrow_range_by_index_const(
+ spec_range_set, i);
+
+ range.lower.i = bt_integer_range_signed_get_lower(orig_range);
+ range.upper.i = bt_integer_range_signed_get_upper(orig_range);
+ } else {
+ const bt_integer_range_unsigned *orig_range =
+ bt_integer_range_set_unsigned_borrow_range_by_index_const(
+ spec_range_set, i);
+
+ range.lower.u = bt_integer_range_unsigned_get_lower(orig_range);
+ range.upper.u = bt_integer_range_unsigned_get_upper(orig_range);
+ }
+
+ g_array_append_val(ranges, range);
+ }
+
+ if (is_signed) {
+ g_array_sort(ranges, (GCompareFunc) compare_int_ranges_signed);
+ } else {
+ g_array_sort(ranges,
+ (GCompareFunc) compare_int_ranges_unsigned);
+ }
+
+end:
+ return ranges;
+}
+
static
void destroy_enum_field_class_mapping(struct enum_field_class_mapping *mapping)
{
}
static
-void write_enum_field_class_mapping_range(struct details_write_ctx *ctx,
- struct enum_field_class_mapping_range *range, bool is_signed)
+struct int_range *int_range_at(GArray *ranges, uint64_t index)
+{
+ return &g_array_index(ranges, struct int_range, index);
+}
+
+static
+void write_int_range(struct details_write_ctx *ctx,
+ struct int_range *range, bool is_signed)
{
g_string_append(ctx->str, "[");
write_int_prop_value(ctx, range->lower.u);
}
- g_string_append(ctx->str, ", ");
+ if (range->lower.u != range->upper.u) {
+ g_string_append(ctx->str, ", ");
- if (is_signed) {
- write_int_prop_value(ctx, range->upper.i);
- } else {
- write_int_prop_value(ctx, range->upper.u);
+ if (is_signed) {
+ write_int_prop_value(ctx, range->upper.i);
+ } else {
+ write_int_prop_value(ctx, range->upper.u);
+ }
}
g_string_append(ctx->str, "]");
*/
for (i = 0; i < bt_field_class_enumeration_get_mapping_count(fc); i++) {
const void *fc_mapping;
+ const void *fc_range_set;
struct enum_field_class_mapping *mapping = g_new0(
struct enum_field_class_mapping, 1);
BT_ASSERT(mapping);
- mapping->ranges = g_array_new(FALSE, TRUE,
- sizeof(struct enum_field_class_mapping_range));
- BT_ASSERT(mapping->ranges);
if (is_signed) {
- fc_mapping = bt_field_class_signed_enumeration_borrow_mapping_by_index_const(
+ fc_mapping = bt_field_class_enumeration_signed_borrow_mapping_by_index_const(
fc, i);
+ fc_range_set = bt_field_class_enumeration_signed_mapping_borrow_ranges_const(
+ fc_mapping);
} else {
- fc_mapping = bt_field_class_unsigned_enumeration_borrow_mapping_by_index_const(
+ fc_mapping = bt_field_class_enumeration_unsigned_borrow_mapping_by_index_const(
fc, i);
+ fc_range_set = bt_field_class_enumeration_unsigned_mapping_borrow_ranges_const(
+ fc_mapping);
}
mapping->label = bt_field_class_enumeration_mapping_get_label(
- bt_field_class_signed_enumeration_mapping_as_mapping_const(
+ bt_field_class_enumeration_signed_mapping_as_mapping_const(
fc_mapping));
-
- for (range_i = 0;
- range_i < bt_field_class_enumeration_mapping_get_range_count(
- bt_field_class_signed_enumeration_mapping_as_mapping_const(fc_mapping));
- range_i++) {
- struct enum_field_class_mapping_range range;
-
- if (is_signed) {
- bt_field_class_signed_enumeration_mapping_get_range_by_index(
- fc_mapping, range_i,
- &range.lower.i, &range.upper.i);
- } else {
- bt_field_class_unsigned_enumeration_mapping_get_range_by_index(
- fc_mapping, range_i,
- &range.lower.u, &range.upper.u);
- }
-
- g_array_append_val(mapping->ranges, range);
- }
-
+ mapping->ranges = range_set_to_int_ranges(fc_range_set,
+ is_signed);
+ BT_ASSERT(mapping->ranges);
g_ptr_array_add(mappings, mapping);
}
- /* Sort mappings, and for each mapping, sort ranges */
+ /* Sort mappings (ranges are already sorted within mappings) */
g_ptr_array_sort(mappings,
(GCompareFunc) compare_enum_field_class_mappings);
- for (i = 0; i < mappings->len; i++) {
- struct enum_field_class_mapping *mapping = mappings->pdata[i];
-
- if (is_signed) {
- g_array_sort(mapping->ranges,
- (GCompareFunc)
- compare_enum_field_class_mapping_ranges_signed);
- } else {
- g_array_sort(mapping->ranges,
- (GCompareFunc)
- compare_enum_field_class_mapping_ranges_unsigned);
- }
- }
-
/* Write mappings */
for (i = 0; i < mappings->len; i++) {
struct enum_field_class_mapping *mapping = mappings->pdata[i];
write_nl(ctx);
- write_compound_member_name(ctx, mapping->label);
-
- if (mapping->ranges->len == 1) {
- /* Single one: write on same line */
- write_sp(ctx);
- write_enum_field_class_mapping_range(ctx,
- &g_array_index(mapping->ranges,
- struct enum_field_class_mapping_range,
- 0), is_signed);
- continue;
- }
-
- incr_indent(ctx);
+ write_prop_name_line(ctx, mapping->label);
for (range_i = 0; range_i < mapping->ranges->len; range_i++) {
- write_nl(ctx);
- write_indent(ctx);
- write_enum_field_class_mapping_range(ctx,
- &g_array_index(mapping->ranges,
- struct enum_field_class_mapping_range,
- range_i), is_signed);
+ write_sp(ctx);
+ write_int_range(ctx,
+ int_range_at(mapping->ranges, range_i),
+ is_signed);
}
-
- decr_indent(ctx);
}
g_ptr_array_free(mappings, TRUE);
g_string_append_c(ctx->str, '[');
switch (bt_field_path_get_root_scope(field_path)) {
- case BT_SCOPE_PACKET_CONTEXT:
+ case BT_FIELD_PATH_SCOPE_PACKET_CONTEXT:
write_str_prop_value(ctx, "Packet context");
break;
- case BT_SCOPE_EVENT_COMMON_CONTEXT:
+ case BT_FIELD_PATH_SCOPE_EVENT_COMMON_CONTEXT:
write_str_prop_value(ctx, "Event common context");
break;
- case BT_SCOPE_EVENT_SPECIFIC_CONTEXT:
+ case BT_FIELD_PATH_SCOPE_EVENT_SPECIFIC_CONTEXT:
write_str_prop_value(ctx, "Event specific context");
break;
- case BT_SCOPE_EVENT_PAYLOAD:
+ case BT_FIELD_PATH_SCOPE_EVENT_PAYLOAD:
write_str_prop_value(ctx, "Event payload");
break;
default:
}
static
-void write_field_class(struct details_write_ctx *ctx, const bt_field_class *fc,
- const char *name)
+void write_field_class(struct details_write_ctx *ctx, const bt_field_class *fc);
+
+static
+void write_variant_field_class_option(struct details_write_ctx *ctx,
+ const bt_field_class *fc, uint64_t index)
{
- uint64_t i;
- const char *type;
bt_field_class_type fc_type = bt_field_class_get_type(fc);
+ const bt_field_class_variant_option *option =
+ bt_field_class_variant_borrow_option_by_index_const(
+ fc, index);
+ 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 field class's name */
- if (name) {
- write_compound_member_name(ctx, name);
+ 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_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_field_integer_unsigned_option_borrow_ranges_const(
+ spec_opt);
+ is_signed = false;
+ } 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_field_integer_signed_option_borrow_ranges_const(
+ spec_opt);
+ is_signed = true;
+ }
+
+ if (orig_ranges) {
+ uint64_t i;
+
+ int_ranges = range_set_to_int_ranges(orig_ranges, is_signed);
+ BT_ASSERT(int_ranges);
+
+ for (i = 0; i < int_ranges->len; i++) {
+ struct int_range *range = int_range_at(int_ranges, i);
+
+ write_sp(ctx);
+ write_int_range(ctx, range, is_signed);
+ }
+
+ g_string_append(ctx->str, ": ");
+ } else {
write_sp(ctx);
}
+ if (bt_value_map_is_empty(user_attrs)) {
+ write_field_class(ctx, option_fc);
+ } else {
+ write_nl(ctx);
+ incr_indent(ctx);
+
+ /* Field class */
+ write_prop_name_line(ctx, "Field class");
+ write_sp(ctx);
+ write_field_class(ctx, option_fc);
+ write_nl(ctx);
+
+ /* User attributes */
+ write_user_attributes(ctx, user_attrs,
+ false, NULL);
+
+ decr_indent(ctx);
+ }
+
+ if (int_ranges) {
+ g_array_free(int_ranges, TRUE);
+ }
+}
+
+static
+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;
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";
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_VARIANT:
- type = "Variant";
+ 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_WITH_SIGNED_INTEGER_SELECTOR_FIELD:
+ type = "Option (signed integer selector)";
+ break;
+ case BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR_FIELD:
+ type = "Variant (no selector)";
+ break;
+ 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_INTEGER_SELECTOR_FIELD:
+ type = "Variant (signed integer selector)";
break;
default:
abort();
g_string_append_printf(ctx->str, "%s%s%s",
color_fg_blue(ctx), type, color_reset(ctx));
- /* Write field class's properties */
- switch (fc_type) {
- case BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER:
- case BT_FIELD_CLASS_TYPE_SIGNED_INTEGER:
- write_sp(ctx);
- write_int_field_class_props(ctx, fc, true);
- break;
- case BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION:
- case BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION:
- {
+ /* Write field class's single-line properties */
+ if (bt_field_class_type_is(fc_type, BT_FIELD_CLASS_TYPE_ENUMERATION)) {
uint64_t mapping_count =
bt_field_class_enumeration_get_mapping_count(fc);
write_uint_prop_value(ctx, mapping_count);
g_string_append_printf(ctx->str, " mapping%s)",
plural(mapping_count));
-
- if (mapping_count > 0) {
- g_string_append_c(ctx->str, ':');
- incr_indent(ctx);
- write_enum_field_class_mappings(ctx, fc);
- decr_indent(ctx);
- }
-
- 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)");
- }
-
- break;
- case BT_FIELD_CLASS_TYPE_STRUCTURE:
- {
+ } else if (bt_field_class_type_is(fc_type,
+ BT_FIELD_CLASS_TYPE_INTEGER)) {
+ write_sp(ctx);
+ write_int_field_class_props(ctx, fc, true);
+ } else if (fc_type == BT_FIELD_CLASS_TYPE_STRUCTURE) {
uint64_t member_count =
bt_field_class_structure_get_member_count(fc);
write_uint_prop_value(ctx, member_count);
g_string_append_printf(ctx->str, " member%s)",
plural(member_count));
+ } else 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, ')');
+ } else if (bt_field_class_type_is(fc_type,
+ BT_FIELD_CLASS_TYPE_OPTION_WITH_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, ')');
+ } else if (bt_field_class_type_is(fc_type,
+ BT_FIELD_CLASS_TYPE_VARIANT)) {
+ uint64_t option_count =
+ bt_field_class_variant_get_option_count(fc);
+ const bt_field_path *sel_field_path = NULL;
+
+ if (bt_field_class_type_is(fc_type,
+ BT_FIELD_CLASS_TYPE_VARIANT_WITH_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, ')');
+ }
+
+ 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 */
+ if (bt_field_class_type_is(fc_type, BT_FIELD_CLASS_TYPE_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);
+ }
+ }
+ } else if (fc_type == BT_FIELD_CLASS_TYPE_STRUCTURE) {
+ uint64_t member_count =
+ bt_field_class_structure_get_member_count(fc);
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_field_class(ctx,
- bt_field_class_structure_member_borrow_field_class_const(member),
+ write_compound_member_name(ctx,
bt_field_class_structure_member_get_name(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);
+ }
+ }
+ } else if (bt_field_class_type_is(fc_type, BT_FIELD_CLASS_TYPE_ARRAY)) {
+ if (wrote_user_attrs) {
+ write_nl(ctx);
+ } else {
+ g_string_append(ctx->str, ":\n");
}
- 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_static_array_get_length(fc));
- g_string_append_c(ctx->str, ')');
+ write_prop_name_line(ctx, "Element");
+ write_sp(ctx);
+ write_field_class(ctx,
+ bt_field_class_array_borrow_element_field_class_const(fc));
+ } else if (bt_field_class_type_is(fc_type,
+ BT_FIELD_CLASS_TYPE_OPTION)) {
+ const void *ranges = NULL;
+ bool selector_is_signed = false;
+
+ if (wrote_user_attrs) {
+ write_nl(ctx);
} else {
- const bt_field_path *length_field_path =
- bt_field_class_dynamic_array_borrow_length_field_path_const(
- fc);
+ g_string_append(ctx->str, ":\n");
+ }
- 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, ')');
- }
+ 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;
}
- g_string_append_c(ctx->str, ':');
- write_nl(ctx);
- incr_indent(ctx);
- write_field_class(ctx,
- bt_field_class_array_borrow_element_field_class_const(fc),
- "Element");
- decr_indent(ctx);
- break;
- case BT_FIELD_CLASS_TYPE_VARIANT:
- {
- uint64_t option_count =
- bt_field_class_variant_get_option_count(fc);
- const bt_field_path *sel_field_path =
- bt_field_class_variant_borrow_selector_field_path_const(
- fc);
+ if (ranges) {
+ GArray *sorted_ranges = range_set_to_int_ranges(
+ ranges, selector_is_signed);
+ uint64_t i;
- g_string_append(ctx->str, " (");
- write_uint_prop_value(ctx, option_count);
- g_string_append_printf(ctx->str, " option%s, ",
- plural(option_count));
+ BT_ASSERT(sorted_ranges);
+ BT_ASSERT(sorted_ranges->len > 0);
+ write_prop_name_line(ctx, "Selector ranges");
- if (sel_field_path) {
- g_string_append(ctx->str, "Selector field path ");
- write_field_path(ctx, sel_field_path);
+ 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);
}
- g_string_append_c(ctx->str, ')');
+ write_prop_name_line(ctx, "Content");
+ write_sp(ctx);
+ write_field_class(ctx,
+ bt_field_class_option_borrow_field_class_const(fc));
+ } else if (bt_field_class_type_is(fc_type,
+ BT_FIELD_CLASS_TYPE_VARIANT)) {
+ uint64_t option_count =
+ bt_field_class_variant_get_option_count(fc);
if (option_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, "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++) {
- const bt_field_class_variant_option *option =
- bt_field_class_variant_borrow_option_by_index_const(
- fc, i);
-
- write_nl(ctx);
- write_field_class(ctx,
- bt_field_class_variant_option_borrow_field_class_const(option),
- bt_field_class_variant_option_get_name(option));
+ write_variant_field_class_option(ctx, fc, i);
}
- decr_indent(ctx);
+ if (wrote_user_attrs) {
+ decr_indent(ctx);
+ }
}
-
- break;
- }
- default:
- break;
}
+
+ decr_indent(ctx);
}
static
write_indent(ctx);
write_prop_name(ctx, name);
g_string_append(ctx->str, ": ");
- write_field_class(ctx, fc, NULL);
+ write_field_class(ctx, fc);
write_nl(ctx);
}
/* 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) {
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);
/* 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,
- "Packets have beginning default clock snapshot",
- bt_stream_class_packets_have_beginning_default_clock_snapshot(sc));
- write_bool_prop_line(ctx,
- "Packets have end default clock snapshot",
- bt_stream_class_packets_have_end_default_clock_snapshot(sc));
+ "Supports packets", bt_stream_class_supports_packets(sc));
+
+ if (bt_stream_class_supports_packets(sc)) {
+ write_bool_prop_line(ctx,
+ "Packets have beginning default clock snapshot",
+ bt_stream_class_packets_have_beginning_default_clock_snapshot(sc));
+ write_bool_prop_line(ctx,
+ "Packets have end default clock snapshot",
+ bt_stream_class_packets_have_end_default_clock_snapshot(sc));
+ }
+
write_bool_prop_line(ctx,
"Supports discarded events",
bt_stream_class_supports_discarded_events(sc));
- write_bool_prop_line(ctx,
- "Discarded events have default clock snapshots",
- bt_stream_class_discarded_events_have_default_clock_snapshots(sc));
+
+ if (bt_stream_class_supports_discarded_events(sc)) {
+ write_bool_prop_line(ctx,
+ "Discarded events have default clock snapshots",
+ bt_stream_class_discarded_events_have_default_clock_snapshots(sc));
+ }
+
write_bool_prop_line(ctx,
"Supports discarded packets",
bt_stream_class_supports_discarded_packets(sc));
- write_bool_prop_line(ctx,
- "Discarded packets have default clock snapshots",
- bt_stream_class_discarded_packets_have_default_clock_snapshots(sc));
+
+ if (bt_stream_class_supports_discarded_packets(sc)) {
+ write_bool_prop_line(ctx,
+ "Discarded packets have default clock snapshots",
+ bt_stream_class_discarded_packets_have_default_clock_snapshots(sc));
+ }
/* Write default clock class */
if (bt_stream_class_borrow_default_clock_class_const(sc)) {
write_event_class(ctx, event_classes->pdata[i]);
}
- decr_indent(ctx);
- g_ptr_array_free(event_classes, TRUE);
-}
-
-static
-gint compare_stream_classes(const bt_stream_class **a, const bt_stream_class **b)
-{
- uint64_t id_a = bt_stream_class_get_id(*a);
- uint64_t id_b = bt_stream_class_get_id(*b);
-
- if (id_a < id_b) {
- return -1;
- } else if (id_a > id_b) {
- return 1;
- } else {
- return 0;
- }
-}
-
-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)
-{
- GPtrArray *stream_classes = g_ptr_array_new();
- GPtrArray *env_names = g_ptr_array_new();
- uint64_t env_count;
- uint64_t i;
- bool printed_prop = false;
-
- write_indent(ctx);
- write_obj_type_name(ctx, "Trace class");
-
- /* Write name */
- if (ctx->details_comp->cfg.with_trace_class_name) {
- const char *name = bt_trace_class_get_name(tc);
-
- if (name) {
- g_string_append(ctx->str, " `");
- write_str_prop_value(ctx, name);
- g_string_append(ctx->str, "`");
- }
- }
-
- /* Write properties */
- incr_indent(ctx);
-
- if (ctx->details_comp->cfg.with_uuid) {
- bt_uuid uuid = bt_trace_class_get_uuid(tc);
-
- if (uuid) {
- if (!printed_prop) {
- g_string_append(ctx->str, ":\n");
- printed_prop = true;
- }
-
- write_uuid_prop_line(ctx, "UUID", uuid);
- }
- }
-
- /* Write environment */
- env_count = bt_trace_class_get_environment_entry_count(tc);
- if (env_count > 0) {
- if (!printed_prop) {
- g_string_append(ctx->str, ":\n");
- printed_prop = true;
- }
-
- write_indent(ctx);
- write_prop_name(ctx, "Environment");
- g_string_append(ctx->str, " (");
- write_uint_prop_value(ctx, env_count);
- g_string_append_printf(ctx->str, " entr%s):",
- env_count == 1 ? "y" : "ies");
- write_nl(ctx);
- incr_indent(ctx);
-
- for (i = 0; i < env_count; i++) {
- const char *name;
- const bt_value *value;
-
- bt_trace_class_borrow_environment_entry_by_index_const(
- tc, i, &name, &value);
- g_ptr_array_add(env_names, (gpointer) name);
- }
-
- g_ptr_array_sort(env_names, (GCompareFunc) compare_strings);
+ decr_indent(ctx);
+ g_ptr_array_free(event_classes, TRUE);
+}
- for (i = 0; i < env_names->len; i++) {
- const char *name = env_names->pdata[i];
- const bt_value *value =
- bt_trace_class_borrow_environment_entry_value_by_name_const(
- tc, name);
+static
+gint compare_stream_classes(const bt_stream_class **a, const bt_stream_class **b)
+{
+ uint64_t id_a = bt_stream_class_get_id(*a);
+ uint64_t id_b = bt_stream_class_get_id(*b);
- BT_ASSERT(value);
- write_compound_member_name(ctx, name);
- write_sp(ctx);
+ if (id_a < id_b) {
+ return -1;
+ } else if (id_a > id_b) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
- if (bt_value_get_type(value) ==
- BT_VALUE_TYPE_SIGNED_INTEGER) {
- write_int_prop_value(ctx,
- bt_value_signed_integer_get(value));
- } else if (bt_value_get_type(value) ==
- BT_VALUE_TYPE_STRING) {
- write_str_prop_value(ctx,
- bt_value_string_get(value));
- } else {
- abort();
- }
+static
+void write_trace_class(struct details_write_ctx *ctx, const bt_trace_class *tc)
+{
+ GPtrArray *stream_classes = g_ptr_array_new();
+ uint64_t i;
+ bool printed_prop = false;
- write_nl(ctx);
- }
+ write_indent(ctx);
+ write_obj_type_name(ctx, "Trace class");
- decr_indent(ctx);
- }
for (i = 0; i < bt_trace_class_get_stream_class_count(tc); i++) {
g_ptr_array_add(stream_classes,
}
}
+ 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]);
}
- decr_indent(ctx);
-
if (!printed_prop) {
write_nl(ctx);
}
+ decr_indent(ctx);
g_ptr_array_free(stream_classes, TRUE);
- g_ptr_array_free(env_names, TRUE);
}
static
* rewrite `sc`.
*/
write_trace_class(ctx, tc);
- write_nl(ctx);
/*
* Mark this trace class as written, as well as all
* 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
}
write_event_class(ctx, ec);
- write_nl(ctx);
details_did_write_meta_object(ctx, tc, ec);
goto end;
}
static
void write_time(struct details_write_ctx *ctx, const bt_clock_snapshot *cs)
{
- bt_clock_snapshot_status status;
+ bt_clock_snapshot_get_ns_from_origin_status cs_status;
int64_t ns_from_origin;
char buf[32];
color_bold(ctx), color_fg_blue(ctx), buf,
color_reset(ctx),
ctx->details_comp->cfg.compact ? "" : " cycles");
- status = bt_clock_snapshot_get_ns_from_origin(cs, &ns_from_origin);
- if (status == BT_CLOCK_SNAPSHOT_STATUS_OK) {
+ cs_status = bt_clock_snapshot_get_ns_from_origin(cs, &ns_from_origin);
+ if (cs_status == BT_CLOCK_SNAPSHOT_GET_NS_FROM_ORIGIN_STATUS_OK) {
format_int(buf, ns_from_origin, 10);
g_string_append_printf(ctx->str, "%s %s%s%s%s%s",
ctx->details_comp->cfg.compact ? "" : ",",
}
/* Write field's value */
- switch (fc_type) {
- case BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER:
- case BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION:
- case BT_FIELD_CLASS_TYPE_SIGNED_INTEGER:
- case BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION:
- {
+ if (fc_type == BT_FIELD_CLASS_TYPE_BOOL) {
+ write_sp(ctx);
+ write_bool_prop_value(ctx, bt_field_bool_get_value(field));
+ } else if (fc_type == 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);
+ } else if (bt_field_class_type_is(fc_type,
+ BT_FIELD_CLASS_TYPE_INTEGER)) {
unsigned int fmt_base;
bt_field_class_integer_preferred_display_base base;
abort();
}
- if (fc_type == BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER ||
- fc_type == BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION) {
+ if (bt_field_class_type_is(fc_type,
+ BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER)) {
format_uint(buf,
- bt_field_unsigned_integer_get_value(field),
+ bt_field_integer_unsigned_get_value(field),
fmt_base);
write_sp(ctx);
write_uint_str_prop_value(ctx, buf);
} else {
format_int(buf,
- bt_field_signed_integer_get_value(field),
+ bt_field_integer_signed_get_value(field),
fmt_base);
write_sp(ctx);
write_int_str_prop_value(ctx, buf);
}
-
- break;
- }
- case BT_FIELD_CLASS_TYPE_REAL:
+ } else if (fc_type == BT_FIELD_CLASS_TYPE_SINGLE_PRECISION_REAL) {
write_sp(ctx);
- write_float_prop_value(ctx, bt_field_real_get_value(field));
- break;
- case BT_FIELD_CLASS_TYPE_STRING:
+ write_float_prop_value(ctx, bt_field_real_single_precision_get_value(field));
+ } else if (fc_type == BT_FIELD_CLASS_TYPE_DOUBLE_PRECISION_REAL) {
+ write_sp(ctx);
+ write_float_prop_value(ctx, bt_field_real_double_precision_get_value(field));
+ } else if (fc_type == BT_FIELD_CLASS_TYPE_STRING) {
write_sp(ctx);
write_str_prop_value(ctx, bt_field_string_get_value(field));
- break;
- case BT_FIELD_CLASS_TYPE_STRUCTURE:
- {
+ } else if (fc_type == BT_FIELD_CLASS_TYPE_STRUCTURE) {
uint64_t member_count;
fc = bt_field_borrow_class_const(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:
- {
+ } else if (bt_field_class_type_is(fc_type, BT_FIELD_CLASS_TYPE_ARRAY)) {
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);
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_VARIANT:
+ } else if (bt_field_class_type_is(fc_type,
+ BT_FIELD_CLASS_TYPE_OPTION)) {
+ const bt_field *content_field =
+ bt_field_option_borrow_field_const(field);
+
+ if (!content_field) {
+ write_sp(ctx);
+ write_none_prop_value(ctx, "None");
+ } else {
+ write_field(ctx, content_field, NULL);
+ }
+ } else if (bt_field_class_type_is(fc_type,
+ BT_FIELD_CLASS_TYPE_VARIANT)) {
write_field(ctx,
bt_field_variant_borrow_selected_option_field_const(
field), NULL);
- break;
- default:
+ } else {
abort();
}
}
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,
decr_indent(ctx);
end:
-
return ret;
}
void write_trace(struct details_write_ctx *ctx, const bt_trace *trace)
{
const char *name;
- const bt_trace_class *tc = bt_trace_borrow_class_const(trace);
GPtrArray *streams = g_ptr_array_new();
uint64_t i;
bool printed_prop = false;
+ GPtrArray *env_names = g_ptr_array_new();
+ uint64_t env_count;
write_indent(ctx);
write_obj_type_name(ctx, "Trace");
/* Write properties */
incr_indent(ctx);
- if (ctx->details_comp->cfg.with_trace_class_name) {
- name = bt_trace_class_get_name(tc);
- if (name) {
+ /* Write UUID */
+ if (ctx->details_comp->cfg.with_uuid) {
+ bt_uuid uuid = bt_trace_get_uuid(trace);
+
+ if (uuid) {
if (!printed_prop) {
g_string_append(ctx->str, ":\n");
printed_prop = true;
}
- write_str_prop_line(ctx, "Class name", name);
+ write_uuid_prop_line(ctx, "UUID", uuid);
}
}
- if (ctx->details_comp->cfg.with_uuid) {
- bt_uuid uuid = bt_trace_class_get_uuid(tc);
+ /* Write environment */
+ env_count = bt_trace_get_environment_entry_count(trace);
+ if (env_count > 0) {
+ if (!printed_prop) {
+ g_string_append(ctx->str, ":\n");
+ printed_prop = true;
+ }
- if (uuid) {
- if (!printed_prop) {
- g_string_append(ctx->str, ":\n");
- printed_prop = true;
+ write_indent(ctx);
+ write_prop_name(ctx, "Environment");
+ g_string_append(ctx->str, " (");
+ write_uint_prop_value(ctx, env_count);
+ g_string_append_printf(ctx->str, " entr%s):",
+ env_count == 1 ? "y" : "ies");
+ write_nl(ctx);
+ incr_indent(ctx);
+
+ for (i = 0; i < env_count; i++) {
+ const char *name;
+ const bt_value *value;
+
+ bt_trace_borrow_environment_entry_by_index_const(
+ trace, i, &name, &value);
+ g_ptr_array_add(env_names, (gpointer) name);
+ }
+
+ g_ptr_array_sort(env_names, (GCompareFunc) compare_strings);
+
+ for (i = 0; i < env_names->len; i++) {
+ const char *name = env_names->pdata[i];
+ const bt_value *value =
+ bt_trace_borrow_environment_entry_value_by_name_const(
+ trace, name);
+
+ BT_ASSERT(value);
+ write_compound_member_name(ctx, name);
+ write_sp(ctx);
+
+ if (bt_value_get_type(value) ==
+ BT_VALUE_TYPE_SIGNED_INTEGER) {
+ write_int_prop_value(ctx,
+ bt_value_integer_signed_get(value));
+ } else if (bt_value_get_type(value) ==
+ BT_VALUE_TYPE_STRING) {
+ write_str_prop_value(ctx,
+ bt_value_string_get(value));
+ } else {
+ abort();
}
- write_uuid_prop_line(ctx, "Class UUID", uuid);
+ write_nl(ctx);
}
+
+ decr_indent(ctx);
}
for (i = 0; i < bt_trace_get_stream_count(trace); i++) {
}
g_ptr_array_free(streams, TRUE);
+ g_ptr_array_free(env_names, TRUE);
}
static
bt_message_stream_beginning_borrow_stream_const(msg);
const bt_trace *trace = bt_stream_borrow_trace_const(stream);
const bt_stream_class *sc = bt_stream_borrow_class_const(stream);
+ const bt_clock_class *cc = bt_stream_class_borrow_default_clock_class_const(sc);
const bt_trace_class *tc = bt_stream_class_borrow_trace_class_const(sc);
const char *name;
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;
+ bt_message_stream_clock_snapshot_state cs_state =
+ bt_message_stream_beginning_borrow_default_clock_snapshot_const(msg, &cs);
+
+ if (cs_state == BT_MESSAGE_STREAM_CLOCK_SNAPSHOT_STATE_KNOWN) {
+ write_time(ctx, cs);
+ } else {
+ write_time_str(ctx, "Unknown");
+ }
+ }
+
/* Write follow tag for message */
ret = write_message_follow_tag(ctx, stream);
if (ret) {
int ret = 0;
const bt_stream *stream =
bt_message_stream_end_borrow_stream_const(msg);
+ const bt_stream_class *sc =
+ bt_stream_borrow_class_const(stream);
+ const bt_clock_class *cc =
+ bt_stream_class_borrow_default_clock_class_const(sc);
- /* Write follow tag for message */
- ret = write_message_follow_tag(ctx, stream);
- if (ret) {
+ if (!ctx->details_comp->cfg.with_data) {
goto end;
}
- /* Write stream properties */
- write_obj_type_name(ctx, "Stream end\n");
-
-end:
- return ret;
-}
-
-static
-int write_stream_activity_beginning_message(struct details_write_ctx *ctx,
- const bt_message *msg)
-{
- int ret = 0;
- const bt_stream *stream =
- bt_message_stream_activity_beginning_borrow_stream_const(msg);
- bt_message_stream_activity_clock_snapshot_state cs_state;
- const bt_clock_snapshot *cs = NULL;
-
/* Write time */
- cs_state = bt_message_stream_activity_beginning_borrow_default_clock_snapshot_const(
- msg, &cs);
- switch (cs_state) {
- case BT_MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_KNOWN:
- BT_ASSERT(cs);
- write_time(ctx, cs);
- break;
- case BT_MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_UNKNOWN:
- write_time_str(ctx, "Unknown");
- break;
- case BT_MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_INFINITE:
- write_time_str(ctx, "-Infinity");
- break;
- default:
- abort();
- }
-
- /* Write follow tag for message */
- ret = write_message_follow_tag(ctx, stream);
- if (ret) {
- goto end;
- }
-
- write_obj_type_name(ctx, "Stream activity beginning");
- write_nl(ctx);
-
-end:
- return ret;
-}
-
-static
-int write_stream_activity_end_message(struct details_write_ctx *ctx,
- const bt_message *msg)
-{
- int ret = 0;
- const bt_stream *stream =
- bt_message_stream_activity_end_borrow_stream_const(msg);
- bt_message_stream_activity_clock_snapshot_state cs_state;
- const bt_clock_snapshot *cs = NULL;
+ if (cc) {
+ const bt_clock_snapshot *cs;
+ bt_message_stream_clock_snapshot_state cs_state =
+ bt_message_stream_end_borrow_default_clock_snapshot_const(msg, &cs);
- /* Write time */
- cs_state = bt_message_stream_activity_end_borrow_default_clock_snapshot_const(
- msg, &cs);
- switch (cs_state) {
- case BT_MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_KNOWN:
- BT_ASSERT(cs);
- write_time(ctx, cs);
- break;
- case BT_MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_UNKNOWN:
- write_time_str(ctx, "Unknown");
- break;
- case BT_MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_INFINITE:
- write_time_str(ctx, "+Infinity");
- break;
- default:
- abort();
+ if (cs_state == BT_MESSAGE_STREAM_CLOCK_SNAPSHOT_STATE_KNOWN) {
+ write_time(ctx, cs);
+ } else {
+ write_time_str(ctx, "Unknown");
+ }
}
/* Write follow tag for message */
goto end;
}
- write_obj_type_name(ctx, "Stream activity end");
- write_nl(ctx);
+ /* Write stream properties */
+ write_obj_type_name(ctx, "Stream end\n");
end:
return ret;
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,
}
/* 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;
}
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);
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(
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);
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(
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
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,
/* 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);
case BT_MESSAGE_TYPE_PACKET_END:
ret = write_packet_end_message(&ctx, msg);
break;
- case BT_MESSAGE_TYPE_STREAM_ACTIVITY_BEGINNING:
- ret = write_stream_activity_beginning_message(&ctx, msg);
- break;
- case BT_MESSAGE_TYPE_STREAM_ACTIVITY_END:
- ret = write_stream_activity_end_message(&ctx, msg);
- break;
case BT_MESSAGE_TYPE_DISCARDED_EVENTS:
ret = write_discarded_events_message(&ctx, msg);
break;
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;
}