plugins/ctf/lttng-live/Makefile
plugins/muxer/Makefile
plugins/text/Makefile
+ plugins/text/pretty/Makefile
plugins/writer/Makefile
plugins/utils/Makefile
plugins/utils/dummy/Makefile
AM_CFLAGS = $(PACKAGE_CFLAGS) -I$(top_srcdir)/include -I$(top_srcdir)/plugins
-SUBDIRS = .
+SUBDIRS = pretty .
plugindir = "$(PLUGINSDIR)"
-plugin_LTLIBRARIES = libbabeltrace-plugin-ctf-text.la
+plugin_LTLIBRARIES = libbabeltrace-plugin-text.la
-# ctf-text plugin
-libbabeltrace_plugin_ctf_text_la_SOURCES = \
- text.c \
- print.c \
- text.h
-
-libbabeltrace_plugin_ctf_text_la_LDFLAGS = \
+libbabeltrace_plugin_text_la_SOURCES = plugin.c
+libbabeltrace_plugin_text_la_LDFLAGS = \
-version-info $(BABELTRACE_LIBRARY_VERSION)
-
-libbabeltrace_plugin_ctf_text_la_LIBADD = \
+libbabeltrace_plugin_text_la_LIBADD = \
$(top_builddir)/lib/libbabeltrace.la \
- $(top_builddir)/common/libbabeltrace-common.la
+ pretty/libbabeltrace-plugin-text-pretty-cc.la
--- /dev/null
+/*
+ * Copyright 2017 Philippe Proulx <pproulx@efficios.com>
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#include <babeltrace/plugin/plugin-dev.h>
+#include "pretty/pretty.h"
+
+BT_PLUGIN(text);
+BT_PLUGIN_DESCRIPTION("Plain text component classes");
+BT_PLUGIN_AUTHOR("Julien Desfossez, Mathieu Desnoyers, Philippe Proulx");
+BT_PLUGIN_LICENSE("MIT");
+
+/* pretty sink */
+BT_PLUGIN_SINK_COMPONENT_CLASS(pretty, pretty_consume);
+BT_PLUGIN_SINK_COMPONENT_CLASS_INIT_METHOD(pretty, pretty_init);
+BT_PLUGIN_SINK_COMPONENT_CLASS_FINALIZE_METHOD(pretty, pretty_finalize);
+BT_PLUGIN_SINK_COMPONENT_CLASS_ACCEPT_PORT_CONNECTION_METHOD(pretty,
+ pretty_accept_port_connection);
+BT_PLUGIN_SINK_COMPONENT_CLASS_DESCRIPTION(pretty,
+ "Pretty-printing text output (`text` format of Babeltrace 1)");
--- /dev/null
+AM_CFLAGS = $(PACKAGE_CFLAGS) -I$(top_srcdir)/include -I$(top_srcdir)/plugins
+
+SUBDIRS = .
+
+noinst_LTLIBRARIES = libbabeltrace-plugin-text-pretty-cc.la
+
+# ctf-text plugin
+libbabeltrace_plugin_text_pretty_cc_la_SOURCES = \
+ pretty.c \
+ print.c \
+ pretty.h
+
+libbabeltrace_plugin_text_pretty_cc_la_LIBADD = \
+ $(top_builddir)/common/libbabeltrace-common.la
--- /dev/null
+/*
+ * pretty.c
+ *
+ * Babeltrace CTF Text Output Plugin
+ *
+ * Copyright 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ * Copyright 2016 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#include <babeltrace/plugin/plugin-dev.h>
+#include <babeltrace/graph/component.h>
+#include <babeltrace/graph/private-component.h>
+#include <babeltrace/graph/component-sink.h>
+#include <babeltrace/graph/port.h>
+#include <babeltrace/graph/private-port.h>
+#include <babeltrace/graph/connection.h>
+#include <babeltrace/graph/private-connection.h>
+#include <babeltrace/graph/notification.h>
+#include <babeltrace/graph/notification-iterator.h>
+#include <babeltrace/graph/notification-event.h>
+#include <babeltrace/values.h>
+#include <babeltrace/compiler-internal.h>
+#include <babeltrace/common-internal.h>
+#include <plugins-common.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <glib.h>
+#include <assert.h>
+
+#include "pretty.h"
+
+static
+const char *plugin_options[] = {
+ "color",
+ "output-path",
+ "debug-info-dir",
+ "debug-info-target-prefix",
+ "debug-info-full-path",
+ "no-delta",
+ "clock-cycles",
+ "clock-seconds",
+ "clock-date",
+ "clock-gmt",
+ "verbose",
+ "name-default", /* show/hide */
+ "name-payload",
+ "name-context",
+ "name-scope",
+ "name-header",
+ "field-default", /* show/hide */
+ "field-trace",
+ "field-trace:hostname",
+ "field-trace:domain",
+ "field-trace:procname",
+ "field-trace:vpid",
+ "field-loglevel",
+ "field-emf",
+ "field-callsite",
+};
+
+static
+void destroy_pretty_data(struct pretty_component *pretty)
+{
+ bt_put(pretty->input_iterator);
+ (void) g_string_free(pretty->string, TRUE);
+ if (pretty->out != stdout) {
+ int ret;
+
+ ret = fclose(pretty->out);
+ if (ret) {
+ perror("close output file");
+ }
+ }
+ g_free(pretty->options.output_path);
+ g_free(pretty->options.debug_info_dir);
+ g_free(pretty->options.debug_info_target_prefix);
+ g_free(pretty);
+}
+
+static
+struct pretty_component *create_pretty(void)
+{
+ struct pretty_component *pretty;
+
+ pretty = g_new0(struct pretty_component, 1);
+ if (!pretty) {
+ goto end;
+ }
+ pretty->string = g_string_new("");
+ if (!pretty->string) {
+ goto error;
+ }
+end:
+ return pretty;
+
+error:
+ g_free(pretty);
+ return NULL;
+}
+
+BT_HIDDEN
+void pretty_finalize(struct bt_private_component *component)
+{
+ void *data = bt_private_component_get_user_data(component);
+
+ destroy_pretty_data(data);
+}
+
+static
+enum bt_component_status handle_notification(struct pretty_component *pretty,
+ struct bt_notification *notification)
+{
+ enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
+
+ if (!pretty) {
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+
+ switch (bt_notification_get_type(notification)) {
+ case BT_NOTIFICATION_TYPE_PACKET_BEGIN:
+ break;
+ case BT_NOTIFICATION_TYPE_PACKET_END:
+ break;
+ case BT_NOTIFICATION_TYPE_EVENT:
+ {
+ struct bt_ctf_event *event = bt_notification_event_get_event(
+ notification);
+
+ if (!event) {
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+ ret = pretty_print_event(pretty, event);
+ bt_put(event);
+ if (ret != BT_COMPONENT_STATUS_OK) {
+ goto end;
+ }
+ break;
+ }
+ case BT_NOTIFICATION_TYPE_STREAM_END:
+ break;
+ default:
+ puts("Unhandled notification type");
+ }
+end:
+ return ret;
+}
+
+BT_HIDDEN
+enum bt_component_status pretty_accept_port_connection(
+ struct bt_private_component *component,
+ struct bt_private_port *self_port,
+ struct bt_port *other_port)
+{
+ enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
+ struct bt_private_connection *connection;
+ struct pretty_component *pretty;
+
+ pretty = bt_private_component_get_user_data(component);
+ assert(pretty);
+ assert(!pretty->input_iterator);
+ connection = bt_private_port_get_private_connection(self_port);
+ assert(connection);
+ pretty->input_iterator =
+ bt_private_connection_create_notification_iterator(connection);
+
+ if (!pretty->input_iterator) {
+ ret = BT_COMPONENT_STATUS_ERROR;
+ }
+
+ bt_put(connection);
+ return ret;
+}
+
+BT_HIDDEN
+enum bt_component_status pretty_consume(struct bt_private_component *component)
+{
+ enum bt_component_status ret;
+ struct bt_notification *notification = NULL;
+ struct bt_notification_iterator *it;
+ struct pretty_component *pretty =
+ bt_private_component_get_user_data(component);
+ enum bt_notification_iterator_status it_ret;
+
+ it = pretty->input_iterator;
+
+ it_ret = bt_notification_iterator_next(it);
+ switch (it_ret) {
+ case BT_NOTIFICATION_ITERATOR_STATUS_ERROR:
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ case BT_NOTIFICATION_ITERATOR_STATUS_END:
+ ret = BT_COMPONENT_STATUS_END;
+ BT_PUT(pretty->input_iterator);
+ goto end;
+ default:
+ break;
+ }
+
+ notification = bt_notification_iterator_get_notification(it);
+ assert(notification);
+ ret = handle_notification(pretty, notification);
+ pretty->processed_first_event = true;
+end:
+ bt_put(notification);
+ return ret;
+}
+
+static
+enum bt_component_status add_params_to_map(struct bt_value *plugin_opt_map)
+{
+ enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
+ unsigned int i;
+
+ for (i = 0; i < BT_ARRAY_SIZE(plugin_options); i++) {
+ const char *key = plugin_options[i];
+ enum bt_value_status status;
+
+ status = bt_value_map_insert(plugin_opt_map, key, bt_value_null);
+ switch (status) {
+ case BT_VALUE_STATUS_OK:
+ break;
+ default:
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+ }
+end:
+ return ret;
+}
+
+static
+bool check_param_exists(const char *key, struct bt_value *object, void *data)
+{
+ struct pretty_component *pretty = data;
+ struct bt_value *plugin_opt_map = pretty->plugin_opt_map;
+
+ if (!bt_value_map_get(plugin_opt_map, key)) {
+ fprintf(pretty->err,
+ "[warning] Parameter \"%s\" unknown to \"text.pretty\" sink component\n", key);
+ }
+ return true;
+}
+
+static
+enum bt_component_status apply_one_string(const char *key,
+ struct bt_value *params,
+ char **option)
+{
+ enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
+ struct bt_value *value = NULL;
+ enum bt_value_status status;
+ const char *str;
+
+ value = bt_value_map_get(params, key);
+ if (!value) {
+ goto end;
+ }
+ if (bt_value_is_null(value)) {
+ goto end;
+ }
+ status = bt_value_string_get(value, &str);
+ switch (status) {
+ case BT_VALUE_STATUS_OK:
+ break;
+ default:
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+ *option = g_strdup(str);
+end:
+ bt_put(value);
+ return ret;
+}
+
+static
+enum bt_component_status apply_one_bool(const char *key,
+ struct bt_value *params,
+ bool *option,
+ bool *found)
+{
+ enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
+ struct bt_value *value = NULL;
+ enum bt_value_status status;
+
+ value = bt_value_map_get(params, key);
+ if (!value) {
+ goto end;
+ }
+ status = bt_value_bool_get(value, option);
+ switch (status) {
+ case BT_VALUE_STATUS_OK:
+ break;
+ default:
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+ if (found) {
+ *found = true;
+ }
+end:
+ bt_put(value);
+ return ret;
+}
+
+static
+void warn_wrong_color_param(struct pretty_component *pretty)
+{
+ fprintf(pretty->err,
+ "[warning] Accepted values for the \"color\" parameter are:\n \"always\", \"auto\", \"never\"\n");
+}
+
+static
+enum bt_component_status open_output_file(struct pretty_component *pretty)
+{
+ enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
+
+ if (!pretty->options.output_path) {
+ goto end;
+ }
+
+ pretty->out = fopen(pretty->options.output_path, "w");
+ if (!pretty->out) {
+ goto error;
+ }
+
+ goto end;
+
+error:
+ ret = BT_COMPONENT_STATUS_ERROR;
+end:
+ return ret;
+}
+
+static
+enum bt_component_status apply_params(struct pretty_component *pretty,
+ struct bt_value *params)
+{
+ enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
+ enum bt_value_status status;
+ bool value, found;
+ char *str = NULL;
+
+ pretty->plugin_opt_map = bt_value_map_create();
+ if (!pretty->plugin_opt_map) {
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+ ret = add_params_to_map(pretty->plugin_opt_map);
+ if (ret != BT_COMPONENT_STATUS_OK) {
+ goto end;
+ }
+ /* Report unknown parameters. */
+ status = bt_value_map_foreach(params, check_param_exists, pretty);
+ switch (status) {
+ case BT_VALUE_STATUS_OK:
+ break;
+ default:
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+ /* Known parameters. */
+ pretty->options.color = PRETTY_COLOR_OPT_AUTO;
+ if (bt_value_map_has_key(params, "color")) {
+ struct bt_value *color_value;
+ const char *color;
+
+ color_value = bt_value_map_get(params, "color");
+ if (!color_value) {
+ goto end;
+ }
+
+ status = bt_value_string_get(color_value, &color);
+ if (status) {
+ warn_wrong_color_param(pretty);
+ } else {
+ if (strcmp(color, "never") == 0) {
+ pretty->options.color = PRETTY_COLOR_OPT_NEVER;
+ } else if (strcmp(color, "auto") == 0) {
+ pretty->options.color = PRETTY_COLOR_OPT_AUTO;
+ } else if (strcmp(color, "always") == 0) {
+ pretty->options.color = PRETTY_COLOR_OPT_ALWAYS;
+ } else {
+ warn_wrong_color_param(pretty);
+ }
+ }
+
+ bt_put(color_value);
+ }
+
+ ret = apply_one_string("output-path",
+ params,
+ &pretty->options.output_path);
+ if (ret != BT_COMPONENT_STATUS_OK) {
+ goto end;
+ }
+ ret = open_output_file(pretty);
+ if (ret != BT_COMPONENT_STATUS_OK) {
+ goto end;
+ }
+
+ ret = apply_one_string("debug-info-dir",
+ params,
+ &pretty->options.debug_info_dir);
+ if (ret != BT_COMPONENT_STATUS_OK) {
+ goto end;
+ }
+
+ ret = apply_one_string("debug-info-target-prefix",
+ params,
+ &pretty->options.debug_info_target_prefix);
+ if (ret != BT_COMPONENT_STATUS_OK) {
+ goto end;
+ }
+
+ value = false; /* Default. */
+ ret = apply_one_bool("debug-info-full-path", params, &value, NULL);
+ if (ret != BT_COMPONENT_STATUS_OK) {
+ goto end;
+ }
+ pretty->options.debug_info_full_path = value;
+
+ value = false; /* Default. */
+ ret = apply_one_bool("no-delta", params, &value, NULL);
+ if (ret != BT_COMPONENT_STATUS_OK) {
+ goto end;
+ }
+ pretty->options.print_delta_field = !value; /* Reverse logic. */
+
+ value = false; /* Default. */
+ ret = apply_one_bool("clock-cycles", params, &value, NULL);
+ if (ret != BT_COMPONENT_STATUS_OK) {
+ goto end;
+ }
+ pretty->options.print_timestamp_cycles = value;
+
+ value = false; /* Default. */
+ ret = apply_one_bool("clock-seconds", params, &value, NULL);
+ if (ret != BT_COMPONENT_STATUS_OK) {
+ goto end;
+ }
+ pretty->options.clock_seconds = value;
+
+ value = false; /* Default. */
+ ret = apply_one_bool("clock-date", params, &value, NULL);
+ if (ret != BT_COMPONENT_STATUS_OK) {
+ goto end;
+ }
+ pretty->options.clock_date = value;
+
+ value = false; /* Default. */
+ ret = apply_one_bool("clock-gmt", params, &value, NULL);
+ if (ret != BT_COMPONENT_STATUS_OK) {
+ goto end;
+ }
+ pretty->options.clock_gmt = value;
+
+ value = false; /* Default. */
+ ret = apply_one_bool("verbose", params, &value, NULL);
+ if (ret != BT_COMPONENT_STATUS_OK) {
+ goto end;
+ }
+ pretty->options.verbose = value;
+
+ /* Names. */
+ ret = apply_one_string("name-default", params, &str);
+ if (ret != BT_COMPONENT_STATUS_OK) {
+ goto end;
+ }
+ if (!str) {
+ pretty->options.name_default = PRETTY_DEFAULT_UNSET;
+ } else if (!strcmp(str, "show")) {
+ pretty->options.name_default = PRETTY_DEFAULT_SHOW;
+ } else if (!strcmp(str, "hide")) {
+ pretty->options.name_default = PRETTY_DEFAULT_HIDE;
+ } else {
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+ g_free(str);
+ str = NULL;
+
+ switch (pretty->options.name_default) {
+ case PRETTY_DEFAULT_UNSET:
+ pretty->options.print_payload_field_names = true;
+ pretty->options.print_context_field_names = true;
+ pretty->options.print_header_field_names = false;
+ pretty->options.print_scope_field_names = false;
+ break;
+ case PRETTY_DEFAULT_SHOW:
+ pretty->options.print_payload_field_names = true;
+ pretty->options.print_context_field_names = true;
+ pretty->options.print_header_field_names = true;
+ pretty->options.print_scope_field_names = true;
+ break;
+ case PRETTY_DEFAULT_HIDE:
+ pretty->options.print_payload_field_names = false;
+ pretty->options.print_context_field_names = false;
+ pretty->options.print_header_field_names = false;
+ pretty->options.print_scope_field_names = false;
+ break;
+ default:
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+
+ value = false;
+ found = false;
+ ret = apply_one_bool("name-payload", params, &value, &found);
+ if (ret != BT_COMPONENT_STATUS_OK) {
+ goto end;
+ }
+ if (found) {
+ pretty->options.print_payload_field_names = value;
+ }
+
+ value = false;
+ found = false;
+ ret = apply_one_bool("name-context", params, &value, &found);
+ if (ret != BT_COMPONENT_STATUS_OK) {
+ goto end;
+ }
+ if (found) {
+ pretty->options.print_context_field_names = value;
+ }
+
+ value = false;
+ found = false;
+ ret = apply_one_bool("name-header", params, &value, &found);
+ if (ret != BT_COMPONENT_STATUS_OK) {
+ goto end;
+ }
+ if (found) {
+ pretty->options.print_header_field_names = value;
+ }
+
+ value = false;
+ found = false;
+ ret = apply_one_bool("name-scope", params, &value, &found);
+ if (ret != BT_COMPONENT_STATUS_OK) {
+ goto end;
+ }
+ if (found) {
+ pretty->options.print_scope_field_names = value;
+ }
+
+ /* Fields. */
+ ret = apply_one_string("field-default", params, &str);
+ if (ret != BT_COMPONENT_STATUS_OK) {
+ goto end;
+ }
+ if (!str) {
+ pretty->options.field_default = PRETTY_DEFAULT_UNSET;
+ } else if (!strcmp(str, "show")) {
+ pretty->options.field_default = PRETTY_DEFAULT_SHOW;
+ } else if (!strcmp(str, "hide")) {
+ pretty->options.field_default = PRETTY_DEFAULT_HIDE;
+ } else {
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+ g_free(str);
+ str = NULL;
+
+ switch (pretty->options.field_default) {
+ case PRETTY_DEFAULT_UNSET:
+ pretty->options.print_trace_field = false;
+ pretty->options.print_trace_hostname_field = true;
+ pretty->options.print_trace_domain_field = false;
+ pretty->options.print_trace_procname_field = true;
+ pretty->options.print_trace_vpid_field = true;
+ pretty->options.print_loglevel_field = false;
+ pretty->options.print_emf_field = false;
+ pretty->options.print_callsite_field = false;
+ break;
+ case PRETTY_DEFAULT_SHOW:
+ pretty->options.print_trace_field = true;
+ pretty->options.print_trace_hostname_field = true;
+ pretty->options.print_trace_domain_field = true;
+ pretty->options.print_trace_procname_field = true;
+ pretty->options.print_trace_vpid_field = true;
+ pretty->options.print_loglevel_field = true;
+ pretty->options.print_emf_field = true;
+ pretty->options.print_callsite_field = true;
+ break;
+ case PRETTY_DEFAULT_HIDE:
+ pretty->options.print_trace_field = false;
+ pretty->options.print_trace_hostname_field = false;
+ pretty->options.print_trace_domain_field = false;
+ pretty->options.print_trace_procname_field = false;
+ pretty->options.print_trace_vpid_field = false;
+ pretty->options.print_loglevel_field = false;
+ pretty->options.print_emf_field = false;
+ pretty->options.print_callsite_field = false;
+ break;
+ default:
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+
+ value = false;
+ found = false;
+ ret = apply_one_bool("field-trace", params, &value, &found);
+ if (ret != BT_COMPONENT_STATUS_OK) {
+ goto end;
+ }
+ if (found) {
+ pretty->options.print_trace_field = value;
+ }
+
+ value = false;
+ found = false;
+ ret = apply_one_bool("field-trace:hostname", params, &value, &found);
+ if (ret != BT_COMPONENT_STATUS_OK) {
+ goto end;
+ }
+ if (found) {
+ pretty->options.print_trace_hostname_field = value;
+ }
+
+ value = false;
+ found = false;
+ ret = apply_one_bool("field-trace:domain", params, &value, &found);
+ if (ret != BT_COMPONENT_STATUS_OK) {
+ goto end;
+ }
+ if (found) {
+ pretty->options.print_trace_domain_field = value;
+ }
+
+ value = false;
+ found = false;
+ ret = apply_one_bool("field-trace:procname", params, &value, &found);
+ if (ret != BT_COMPONENT_STATUS_OK) {
+ goto end;
+ }
+ if (found) {
+ pretty->options.print_trace_procname_field = value;
+ }
+
+ value = false;
+ found = false;
+ ret = apply_one_bool("field-trace:vpid", params, &value, &found);
+ if (ret != BT_COMPONENT_STATUS_OK) {
+ goto end;
+ }
+ if (found) {
+ pretty->options.print_trace_vpid_field = value;
+ }
+
+ value = false;
+ found = false;
+ ret = apply_one_bool("field-loglevel", params, &value, &found);
+ if (ret != BT_COMPONENT_STATUS_OK) {
+ goto end;
+ }
+ if (found) {
+ pretty->options.print_loglevel_field = value;
+ }
+
+ value = false;
+ found = false;
+ ret = apply_one_bool("field-emf", params, &value, &found);
+ if (ret != BT_COMPONENT_STATUS_OK) {
+ goto end;
+ }
+ if (found) {
+ pretty->options.print_emf_field = value;
+ }
+
+ value = false;
+ found = false;
+ ret = apply_one_bool("field-callsite", params, &value, &found);
+ if (ret != BT_COMPONENT_STATUS_OK) {
+ goto end;
+ }
+ if (found) {
+ pretty->options.print_callsite_field = value;
+ }
+
+end:
+ bt_put(pretty->plugin_opt_map);
+ pretty->plugin_opt_map = NULL;
+ g_free(str);
+ return ret;
+}
+
+static
+void set_use_colors(struct pretty_component *pretty)
+{
+ switch (pretty->options.color) {
+ case PRETTY_COLOR_OPT_ALWAYS:
+ pretty->use_colors = true;
+ break;
+ case PRETTY_COLOR_OPT_AUTO:
+ pretty->use_colors = pretty->out == stdout &&
+ bt_common_colors_supported();
+ break;
+ case PRETTY_COLOR_OPT_NEVER:
+ pretty->use_colors = false;
+ break;
+ }
+}
+
+static
+void init_stream_packet_context_quarks(void)
+{
+ stream_packet_context_quarks[Q_TIMESTAMP_BEGIN] =
+ g_quark_from_string("timestamp_begin");
+ stream_packet_context_quarks[Q_TIMESTAMP_BEGIN] =
+ g_quark_from_string("timestamp_begin");
+ stream_packet_context_quarks[Q_TIMESTAMP_END] =
+ g_quark_from_string("timestamp_end");
+ stream_packet_context_quarks[Q_EVENTS_DISCARDED] =
+ g_quark_from_string("events_discarded");
+ stream_packet_context_quarks[Q_CONTENT_SIZE] =
+ g_quark_from_string("content_size");
+ stream_packet_context_quarks[Q_PACKET_SIZE] =
+ g_quark_from_string("packet_size");
+ stream_packet_context_quarks[Q_PACKET_SEQ_NUM] =
+ g_quark_from_string("packet_seq_num");
+}
+
+BT_HIDDEN
+enum bt_component_status pretty_init(
+ struct bt_private_component *component,
+ struct bt_value *params,
+ UNUSED_VAR void *init_method_data)
+{
+ enum bt_component_status ret;
+ struct pretty_component *pretty = create_pretty();
+
+ if (!pretty) {
+ ret = BT_COMPONENT_STATUS_NOMEM;
+ goto end;
+ }
+
+ pretty->out = stdout;
+ pretty->err = stderr;
+
+ pretty->delta_cycles = -1ULL;
+ pretty->last_cycles_timestamp = -1ULL;
+
+ pretty->delta_real_timestamp = -1ULL;
+ pretty->last_real_timestamp = -1ULL;
+
+ ret = apply_params(pretty, params);
+ if (ret != BT_COMPONENT_STATUS_OK) {
+ goto error;
+ }
+
+ set_use_colors(pretty);
+
+ ret = bt_private_component_set_user_data(component, pretty);
+ if (ret != BT_COMPONENT_STATUS_OK) {
+ goto error;
+ }
+
+ init_stream_packet_context_quarks();
+
+end:
+ return ret;
+error:
+ destroy_pretty_data(pretty);
+ return ret;
+}
--- /dev/null
+#ifndef BABELTRACE_PLUGIN_TEXT_PRETTY_PRETTY_H
+#define BABELTRACE_PLUGIN_TEXT_PRETTY_PRETTY_H
+
+/*
+ * BabelTrace - CTF Text Output Plug-in
+ *
+ * Copyright 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#include <stdbool.h>
+#include <babeltrace/babeltrace-internal.h>
+#include <babeltrace/graph/component.h>
+#include <babeltrace/graph/private-component.h>
+#include <babeltrace/graph/private-port.h>
+#include <babeltrace/ctf-ir/event.h>
+
+enum pretty_default {
+ PRETTY_DEFAULT_UNSET,
+ PRETTY_DEFAULT_SHOW,
+ PRETTY_DEFAULT_HIDE,
+};
+
+enum pretty_color_option {
+ PRETTY_COLOR_OPT_NEVER,
+ PRETTY_COLOR_OPT_AUTO,
+ PRETTY_COLOR_OPT_ALWAYS,
+};
+
+struct pretty_options {
+ char *output_path;
+ char *debug_info_dir;
+ char *debug_info_target_prefix;
+
+ enum pretty_default name_default;
+ enum pretty_default field_default;
+
+ bool print_scope_field_names;
+ bool print_header_field_names;
+ bool print_context_field_names;
+ bool print_payload_field_names;
+
+ bool print_delta_field;
+ bool print_loglevel_field;
+ bool print_emf_field;
+ bool print_callsite_field;
+ bool print_trace_field;
+ bool print_trace_domain_field;
+ bool print_trace_procname_field;
+ bool print_trace_vpid_field;
+ bool print_trace_hostname_field;
+
+ bool print_timestamp_cycles;
+ bool clock_seconds;
+ bool clock_date;
+ bool clock_gmt;
+ bool debug_info_full_path;
+ enum pretty_color_option color;
+ bool verbose;
+};
+
+struct pretty_component {
+ struct pretty_options options;
+ struct bt_notification_iterator *input_iterator;
+ FILE *out, *err;
+ bool processed_first_event; /* Should be per-iterator. */
+ int depth; /* nesting, used for tabulation alignment. */
+ bool start_line;
+ GString *string;
+ struct bt_value *plugin_opt_map; /* Temporary parameter map. */
+ bool use_colors;
+
+ uint64_t last_cycles_timestamp;
+ uint64_t delta_cycles;
+
+ uint64_t last_real_timestamp;
+ uint64_t delta_real_timestamp;
+};
+
+enum stream_packet_context_quarks_enum {
+ Q_TIMESTAMP_BEGIN,
+ Q_TIMESTAMP_END,
+ Q_EVENTS_DISCARDED,
+ Q_CONTENT_SIZE,
+ Q_PACKET_SIZE,
+ Q_PACKET_SEQ_NUM,
+ STREAM_PACKET_CONTEXT_QUARKS_LEN, /* Always the last one of this enum. */
+};
+
+GQuark stream_packet_context_quarks[STREAM_PACKET_CONTEXT_QUARKS_LEN];
+
+BT_HIDDEN
+enum bt_component_status pretty_init(
+ struct bt_private_component *component,
+ struct bt_value *params,
+ void *init_method_data);
+
+BT_HIDDEN
+enum bt_component_status pretty_consume(struct bt_private_component *component);
+
+BT_HIDDEN
+enum bt_component_status pretty_accept_port_connection(
+ struct bt_private_component *component,
+ struct bt_private_port *self_port,
+ struct bt_port *other_port);
+
+BT_HIDDEN
+void pretty_finalize(struct bt_private_component *component);
+
+BT_HIDDEN
+enum bt_component_status pretty_print_event(struct pretty_component *pretty,
+ struct bt_ctf_event *event);
+
+#endif /* BABELTRACE_PLUGIN_TEXT_PRETTY_PRETTY_H */
--- /dev/null
+/*
+ * print.c
+ *
+ * Babeltrace CTF Text Output Plugin Event Printing
+ *
+ * Copyright 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ * Copyright 2016 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#include <babeltrace/ctf-ir/event.h>
+#include <babeltrace/ctf-ir/event-class.h>
+#include <babeltrace/ctf-ir/packet.h>
+#include <babeltrace/ctf-ir/stream.h>
+#include <babeltrace/ctf-ir/stream-class.h>
+#include <babeltrace/ctf-ir/clock-class.h>
+#include <babeltrace/ctf-ir/field-types.h>
+#include <babeltrace/ctf-ir/fields.h>
+#include <babeltrace/ctf-ir/trace.h>
+#include <babeltrace/bitfield-internal.h>
+#include <babeltrace/common-internal.h>
+#include <inttypes.h>
+#include <ctype.h>
+#include "pretty.h"
+
+#define NSEC_PER_SEC 1000000000LL
+
+#define COLOR_NAME BT_COMMON_COLOR_BOLD
+#define COLOR_FIELD_NAME BT_COMMON_COLOR_FG_CYAN
+#define COLOR_RST BT_COMMON_COLOR_RESET
+#define COLOR_STRING_VALUE BT_COMMON_COLOR_BOLD
+#define COLOR_NUMBER_VALUE BT_COMMON_COLOR_BOLD
+#define COLOR_ENUM_MAPPING_NAME BT_COMMON_COLOR_BOLD
+#define COLOR_UNKNOWN BT_COMMON_COLOR_BOLD BT_COMMON_COLOR_FG_RED
+#define COLOR_EVENT_NAME BT_COMMON_COLOR_BOLD BT_COMMON_COLOR_FG_MAGENTA
+#define COLOR_TIMESTAMP BT_COMMON_COLOR_BOLD BT_COMMON_COLOR_FG_YELLOW
+
+static inline
+const char *rem_(const char *str)
+{
+ if (str[0] == '_')
+ return &str[1];
+ else
+ return str;
+}
+
+struct timestamp {
+ int64_t real_timestamp; /* Relative to UNIX epoch. */
+ uint64_t clock_value; /* In cycles. */
+};
+
+static
+enum bt_component_status print_field(struct pretty_component *pretty,
+ struct bt_ctf_field *field, bool print_names,
+ GQuark *filters_fields, int filter_array_len);
+
+static
+void print_name_equal(struct pretty_component *pretty, const char *name)
+{
+ if (pretty->use_colors) {
+ fprintf(pretty->out, "%s%s%s = ", COLOR_NAME, name, COLOR_RST);
+ } else {
+ fprintf(pretty->out, "%s = ", name);
+ }
+}
+
+static
+void print_field_name_equal(struct pretty_component *pretty, const char *name)
+{
+ if (pretty->use_colors) {
+ fprintf(pretty->out, "%s%s%s = ", COLOR_FIELD_NAME, name,
+ COLOR_RST);
+ } else {
+ fprintf(pretty->out, "%s = ", name);
+ }
+}
+
+static
+void print_timestamp_cycles(struct pretty_component *pretty,
+ struct bt_ctf_clock_class *clock_class,
+ struct bt_ctf_event *event)
+{
+ int ret;
+ struct bt_ctf_clock_value *clock_value;
+ uint64_t cycles;
+
+ clock_value = bt_ctf_event_get_clock_value(event, clock_class);
+ if (!clock_value) {
+ fputs("????????????????????", pretty->out);
+ return;
+ }
+
+ ret = bt_ctf_clock_value_get_value(clock_value, &cycles);
+ bt_put(clock_value);
+ if (ret) {
+ fprintf(pretty->out, "Error");
+ return;
+ }
+ fprintf(pretty->out, "%020" PRIu64, cycles);
+
+ if (pretty->last_cycles_timestamp != -1ULL) {
+ pretty->delta_cycles = cycles - pretty->last_cycles_timestamp;
+ }
+ pretty->last_cycles_timestamp = cycles;
+}
+
+static
+void print_timestamp_wall(struct pretty_component *pretty,
+ struct bt_ctf_clock_class *clock_class,
+ struct bt_ctf_event *event)
+{
+ int ret;
+ struct bt_ctf_clock_value *clock_value;
+ int64_t ts_nsec = 0; /* add configurable offset */
+ int64_t ts_sec = 0; /* add configurable offset */
+ uint64_t ts_sec_abs, ts_nsec_abs;
+ bool is_negative;
+
+ clock_value = bt_ctf_event_get_clock_value(event, clock_class);
+ if (!clock_value) {
+ fputs("??:??:??.?????????", pretty->out);
+ return;
+ }
+
+ ret = bt_ctf_clock_value_get_value_ns_from_epoch(clock_value, &ts_nsec);
+ bt_put(clock_value);
+ if (ret) {
+ fprintf(pretty->out, "Error");
+ return;
+ }
+
+ if (pretty->last_real_timestamp != -1ULL) {
+ pretty->delta_real_timestamp = ts_nsec - pretty->last_real_timestamp;
+ }
+ pretty->last_real_timestamp = ts_nsec;
+
+ ts_sec += ts_nsec / NSEC_PER_SEC;
+ ts_nsec = ts_nsec % NSEC_PER_SEC;
+ if (ts_sec >= 0 && ts_nsec >= 0) {
+ is_negative = false;
+ ts_sec_abs = ts_sec;
+ ts_nsec_abs = ts_nsec;
+ } else if (ts_sec > 0 && ts_nsec < 0) {
+ is_negative = false;
+ ts_sec_abs = ts_sec - 1;
+ ts_nsec_abs = NSEC_PER_SEC + ts_nsec;
+ } else if (ts_sec == 0 && ts_nsec < 0) {
+ is_negative = true;
+ ts_sec_abs = ts_sec;
+ ts_nsec_abs = -ts_nsec;
+ } else if (ts_sec < 0 && ts_nsec > 0) {
+ is_negative = true;
+ ts_sec_abs = -(ts_sec + 1);
+ ts_nsec_abs = NSEC_PER_SEC - ts_nsec;
+ } else if (ts_sec < 0 && ts_nsec == 0) {
+ is_negative = true;
+ ts_sec_abs = -ts_sec;
+ ts_nsec_abs = ts_nsec;
+ } else { /* (ts_sec < 0 && ts_nsec < 0) */
+ is_negative = true;
+ ts_sec_abs = -ts_sec;
+ ts_nsec_abs = -ts_nsec;
+ }
+
+ if (!pretty->options.clock_seconds) {
+ struct tm tm;
+ time_t time_s = (time_t) ts_sec_abs;
+
+ if (is_negative) {
+ fprintf(stderr, "[warning] Fallback to [sec.ns] to print negative time value. Use --clock-seconds.\n");
+ goto seconds;
+ }
+
+ if (!pretty->options.clock_gmt) {
+ struct tm *res;
+
+ res = localtime_r(&time_s, &tm);
+ if (!res) {
+ fprintf(stderr, "[warning] Unable to get localtime.\n");
+ goto seconds;
+ }
+ } else {
+ struct tm *res;
+
+ res = gmtime_r(&time_s, &tm);
+ if (!res) {
+ fprintf(stderr, "[warning] Unable to get gmtime.\n");
+ goto seconds;
+ }
+ }
+ if (pretty->options.clock_date) {
+ char timestr[26];
+ size_t res;
+
+ /* Print date and time */
+ res = strftime(timestr, sizeof(timestr),
+ "%F ", &tm);
+ if (!res) {
+ fprintf(stderr, "[warning] Unable to print ascii time.\n");
+ goto seconds;
+ }
+ fprintf(pretty->out, "%s", timestr);
+ }
+ /* Print time in HH:MM:SS.ns */
+ fprintf(pretty->out, "%02d:%02d:%02d.%09" PRIu64,
+ tm.tm_hour, tm.tm_min, tm.tm_sec, ts_nsec_abs);
+ goto end;
+ }
+seconds:
+ fprintf(pretty->out, "%s%" PRId64 ".%09" PRIu64,
+ is_negative ? "-" : "", ts_sec_abs, ts_nsec_abs);
+end:
+ return;
+}
+
+static
+enum bt_component_status print_event_timestamp(struct pretty_component *pretty,
+ struct bt_ctf_event *event, bool *start_line)
+{
+ bool print_names = pretty->options.print_header_field_names;
+ enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
+ struct bt_ctf_stream *stream = NULL;
+ struct bt_ctf_stream_class *stream_class = NULL;
+ struct bt_ctf_trace *trace = NULL;
+ struct bt_ctf_clock_class *clock_class = NULL;
+ FILE *out = pretty->out;
+
+ stream = bt_ctf_event_get_stream(event);
+ if (!stream) {
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+
+ stream_class = bt_ctf_stream_get_class(stream);
+ if (!stream_class) {
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+ trace = bt_ctf_stream_class_get_trace(stream_class);
+ if (!trace) {
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+ clock_class = bt_ctf_trace_get_clock_class(trace, 0);
+ if (!clock_class) {
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+
+ if (print_names) {
+ print_name_equal(pretty, "timestamp");
+ } else {
+ fputs("[", out);
+ }
+ if (pretty->use_colors) {
+ fputs(COLOR_TIMESTAMP, pretty->out);
+ }
+ if (pretty->options.print_timestamp_cycles) {
+ print_timestamp_cycles(pretty, clock_class, event);
+ } else {
+ print_timestamp_wall(pretty, clock_class, event);
+ }
+ if (pretty->use_colors) {
+ fputs(COLOR_RST, pretty->out);
+ }
+
+ if (!print_names)
+ fputs("] ", out);
+
+ if (pretty->options.print_delta_field) {
+ if (print_names) {
+ fputs(", ", pretty->out);
+ print_name_equal(pretty, "delta");
+ } else {
+ fputs("(", pretty->out);
+ }
+ if (pretty->options.print_timestamp_cycles) {
+ if (pretty->delta_cycles == -1ULL) {
+ fputs("+??????????\?\?) ", pretty->out); /* Not a trigraph. */
+ } else {
+ fprintf(pretty->out, "+%012" PRIu64, pretty->delta_cycles);
+ }
+ } else {
+ if (pretty->delta_real_timestamp != -1ULL) {
+ uint64_t delta_sec, delta_nsec, delta;
+
+ delta = pretty->delta_real_timestamp;
+ delta_sec = delta / NSEC_PER_SEC;
+ delta_nsec = delta % NSEC_PER_SEC;
+ fprintf(pretty->out, "+%" PRIu64 ".%09" PRIu64,
+ delta_sec, delta_nsec);
+ } else {
+ fputs("+?.?????????", pretty->out);
+ }
+ }
+ if (!print_names) {
+ fputs(") ", pretty->out);
+ }
+ }
+ *start_line = !print_names;
+
+end:
+ bt_put(stream);
+ bt_put(clock_class);
+ bt_put(stream_class);
+ bt_put(trace);
+ return ret;
+}
+
+static
+enum bt_component_status print_event_header(struct pretty_component *pretty,
+ struct bt_ctf_event *event)
+{
+ bool print_names = pretty->options.print_header_field_names;
+ enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
+ struct bt_ctf_event_class *event_class = NULL;
+ struct bt_ctf_stream_class *stream_class = NULL;
+ struct bt_ctf_trace *trace_class = NULL;
+ int dom_print = 0;
+
+ event_class = bt_ctf_event_get_class(event);
+ if (!event_class) {
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+ stream_class = bt_ctf_event_class_get_stream_class(event_class);
+ if (!stream_class) {
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+ trace_class = bt_ctf_stream_class_get_trace(stream_class);
+ if (!trace_class) {
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+ ret = print_event_timestamp(pretty, event, &pretty->start_line);
+ if (ret != BT_COMPONENT_STATUS_OK) {
+ goto end;
+ }
+ if (pretty->options.print_trace_field) {
+ const char *name;
+
+ name = bt_ctf_trace_get_name(trace_class);
+ if (name) {
+ if (!pretty->start_line) {
+ fputs(", ", pretty->out);
+ }
+ if (print_names) {
+ print_name_equal(pretty, "trace");
+ }
+ fprintf(pretty->out, "%s", name);
+ if (!print_names) {
+ fprintf(pretty->out, " ");
+ }
+ }
+ }
+ if (pretty->options.print_trace_hostname_field) {
+ struct bt_value *hostname_str;
+
+ hostname_str = bt_ctf_trace_get_environment_field_value_by_name(trace_class,
+ "hostname");
+ if (hostname_str) {
+ const char *str;
+
+ if (!pretty->start_line) {
+ fputs(", ", pretty->out);
+ }
+ if (print_names) {
+ print_name_equal(pretty, "trace:hostname");
+ }
+ if (bt_value_string_get(hostname_str, &str)
+ == BT_VALUE_STATUS_OK) {
+ fprintf(pretty->out, "%s", str);
+ }
+ bt_put(hostname_str);
+ dom_print = 1;
+ }
+ }
+ if (pretty->options.print_trace_domain_field) {
+ struct bt_value *domain_str;
+
+ domain_str = bt_ctf_trace_get_environment_field_value_by_name(trace_class,
+ "domain");
+ if (domain_str) {
+ const char *str;
+
+ if (!pretty->start_line) {
+ fputs(", ", pretty->out);
+ }
+ if (print_names) {
+ print_name_equal(pretty, "trace:domain");
+ } else if (dom_print) {
+ fputs(":", pretty->out);
+ }
+ if (bt_value_string_get(domain_str, &str)
+ == BT_VALUE_STATUS_OK) {
+ fprintf(pretty->out, "%s", str);
+ }
+ bt_put(domain_str);
+ dom_print = 1;
+ }
+ }
+ if (pretty->options.print_trace_procname_field) {
+ struct bt_value *procname_str;
+
+ procname_str = bt_ctf_trace_get_environment_field_value_by_name(trace_class,
+ "procname");
+ if (procname_str) {
+ const char *str;
+
+ if (!pretty->start_line) {
+ fputs(", ", pretty->out);
+ }
+ if (print_names) {
+ print_name_equal(pretty, "trace:procname");
+ } else if (dom_print) {
+ fputs(":", pretty->out);
+ }
+ if (bt_value_string_get(procname_str, &str)
+ == BT_VALUE_STATUS_OK) {
+ fprintf(pretty->out, "%s", str);
+ }
+ bt_put(procname_str);
+ dom_print = 1;
+ }
+ }
+ if (pretty->options.print_trace_vpid_field) {
+ struct bt_value *vpid_value;
+
+ vpid_value = bt_ctf_trace_get_environment_field_value_by_name(trace_class,
+ "vpid");
+ if (vpid_value) {
+ int64_t value;
+
+ if (!pretty->start_line) {
+ fputs(", ", pretty->out);
+ }
+ if (print_names) {
+ print_name_equal(pretty, "trace:vpid");
+ } else if (dom_print) {
+ fputs(":", pretty->out);
+ }
+ if (bt_value_integer_get(vpid_value, &value)
+ == BT_VALUE_STATUS_OK) {
+ fprintf(pretty->out, "(%" PRId64 ")", value);
+ }
+ bt_put(vpid_value);
+ dom_print = 1;
+ }
+ }
+ if (pretty->options.print_loglevel_field) {
+ struct bt_value *loglevel_str, *loglevel_value;
+
+ loglevel_str = bt_ctf_event_class_get_attribute_value_by_name(event_class,
+ "loglevel_string");
+ loglevel_value = bt_ctf_event_class_get_attribute_value_by_name(event_class,
+ "loglevel");
+ if (loglevel_str || loglevel_value) {
+ bool has_str = false;
+
+ if (!pretty->start_line) {
+ fputs(", ", pretty->out);
+ }
+ if (print_names) {
+ print_name_equal(pretty, "loglevel");
+ } else if (dom_print) {
+ fputs(":", pretty->out);
+ }
+ if (loglevel_str) {
+ const char *str;
+
+ if (bt_value_string_get(loglevel_str, &str)
+ == BT_VALUE_STATUS_OK) {
+ fprintf(pretty->out, "%s", str);
+ has_str = true;
+ }
+ }
+ if (loglevel_value) {
+ int64_t value;
+
+ if (bt_value_integer_get(loglevel_value, &value)
+ == BT_VALUE_STATUS_OK) {
+ fprintf(pretty->out, "%s(%" PRId64 ")",
+ has_str ? " " : "", value);
+ }
+ }
+ bt_put(loglevel_str);
+ bt_put(loglevel_value);
+ dom_print = 1;
+ }
+ }
+ if (pretty->options.print_emf_field) {
+ struct bt_value *uri_str;
+
+ uri_str = bt_ctf_event_class_get_attribute_value_by_name(event_class,
+ "model.emf.uri");
+ if (uri_str) {
+ if (!pretty->start_line) {
+ fputs(", ", pretty->out);
+ }
+ if (print_names) {
+ print_name_equal(pretty, "model.emf.uri");
+ } else if (dom_print) {
+ fputs(":", pretty->out);
+ }
+ if (uri_str) {
+ const char *str;
+
+ if (bt_value_string_get(uri_str, &str)
+ == BT_VALUE_STATUS_OK) {
+ fprintf(pretty->out, "%s", str);
+ }
+ }
+ bt_put(uri_str);
+ dom_print = 1;
+ }
+ }
+ if (dom_print && !print_names) {
+ fputs(" ", pretty->out);
+ }
+ if (!pretty->start_line) {
+ fputs(", ", pretty->out);
+ }
+ pretty->start_line = true;
+ if (print_names) {
+ print_name_equal(pretty, "name");
+ }
+ if (pretty->use_colors) {
+ fputs(COLOR_EVENT_NAME, pretty->out);
+ }
+ fputs(bt_ctf_event_class_get_name(event_class), pretty->out);
+ if (pretty->use_colors) {
+ fputs(COLOR_RST, pretty->out);
+ }
+ if (!print_names) {
+ fputs(": ", pretty->out);
+ } else {
+ fputs(", ", pretty->out);
+ }
+end:
+ bt_put(trace_class);
+ bt_put(stream_class);
+ bt_put(event_class);
+ return ret;
+}
+
+static
+enum bt_component_status print_integer(struct pretty_component *pretty,
+ struct bt_ctf_field *field)
+{
+ enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
+ struct bt_ctf_field_type *field_type = NULL;
+ enum bt_ctf_integer_base base;
+ enum bt_ctf_string_encoding encoding;
+ int signedness;
+ union {
+ uint64_t u;
+ int64_t s;
+ } v;
+ bool rst_color = false;
+
+ field_type = bt_ctf_field_get_type(field);
+ if (!field_type) {
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+ signedness = bt_ctf_field_type_integer_get_signed(field_type);
+ if (signedness < 0) {
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+ if (!signedness) {
+ if (bt_ctf_field_unsigned_integer_get_value(field, &v.u) < 0) {
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+ } else {
+ if (bt_ctf_field_signed_integer_get_value(field, &v.s) < 0) {
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+ }
+
+ encoding = bt_ctf_field_type_integer_get_encoding(field_type);
+ switch (encoding) {
+ case BT_CTF_STRING_ENCODING_UTF8:
+ case BT_CTF_STRING_ENCODING_ASCII:
+ g_string_append_c(pretty->string, (int) v.u);
+ goto end;
+ case BT_CTF_STRING_ENCODING_NONE:
+ case BT_CTF_STRING_ENCODING_UNKNOWN:
+ break;
+ default:
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+
+ if (pretty->use_colors) {
+ fputs(COLOR_NUMBER_VALUE, pretty->out);
+ rst_color = true;
+ }
+
+ base = bt_ctf_field_type_integer_get_base(field_type);
+ switch (base) {
+ case BT_CTF_INTEGER_BASE_BINARY:
+ {
+ int bitnr, len;
+
+ len = bt_ctf_field_type_integer_get_size(field_type);
+ if (len < 0) {
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+ fprintf(pretty->out, "0b");
+ v.u = _bt_piecewise_lshift(v.u, 64 - len);
+ for (bitnr = 0; bitnr < len; bitnr++) {
+ fprintf(pretty->out, "%u", (v.u & (1ULL << 63)) ? 1 : 0);
+ v.u = _bt_piecewise_lshift(v.u, 1);
+ }
+ break;
+ }
+ case BT_CTF_INTEGER_BASE_OCTAL:
+ {
+ if (signedness) {
+ int len;
+
+ len = bt_ctf_field_type_integer_get_size(field_type);
+ if (len < 0) {
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+ if (len < 64) {
+ size_t rounded_len;
+
+ assert(len != 0);
+ /* Round length to the nearest 3-bit */
+ rounded_len = (((len - 1) / 3) + 1) * 3;
+ v.u &= ((uint64_t) 1 << rounded_len) - 1;
+ }
+ }
+
+ fprintf(pretty->out, "0%" PRIo64, v.u);
+ break;
+ }
+ case BT_CTF_INTEGER_BASE_DECIMAL:
+ if (!signedness) {
+ fprintf(pretty->out, "%" PRIu64, v.u);
+ } else {
+ fprintf(pretty->out, "%" PRId64, v.s);
+ }
+ break;
+ case BT_CTF_INTEGER_BASE_HEXADECIMAL:
+ {
+ int len;
+
+ len = bt_ctf_field_type_integer_get_size(field_type);
+ if (len < 0) {
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+ if (len < 64) {
+ /* Round length to the nearest nibble */
+ uint8_t rounded_len = ((len + 3) & ~0x3);
+
+ v.u &= ((uint64_t) 1 << rounded_len) - 1;
+ }
+
+ fprintf(pretty->out, "0x%" PRIX64, v.u);
+ break;
+ }
+ default:
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+end:
+ if (rst_color) {
+ fputs(COLOR_RST, pretty->out);
+ }
+ bt_put(field_type);
+ return ret;
+}
+
+static
+void print_escape_string(struct pretty_component *pretty, const char *str)
+{
+ int i;
+
+ fputc('"', pretty->out);
+ for (i = 0; i < strlen(str); i++) {
+ /* Escape sequences not recognized by iscntrl(). */
+ switch (str[i]) {
+ case '\\':
+ fputs("\\\\", pretty->out);
+ continue;
+ case '\'':
+ fputs("\\\'", pretty->out);
+ continue;
+ case '\"':
+ fputs("\\\"", pretty->out);
+ continue;
+ case '\?':
+ fputs("\\\?", pretty->out);
+ continue;
+ }
+
+ /* Standard characters. */
+ if (!iscntrl(str[i])) {
+ fputc(str[i], pretty->out);
+ continue;
+ }
+
+ switch (str[i]) {
+ case '\0':
+ fputs("\\0", pretty->out);
+ break;
+ case '\a':
+ fputs("\\a", pretty->out);
+ break;
+ case '\b':
+ fputs("\\b", pretty->out);
+ break;
+ case '\e':
+ fputs("\\e", pretty->out);
+ break;
+ case '\f':
+ fputs("\\f", pretty->out);
+ break;
+ case '\n':
+ fputs("\\n", pretty->out);
+ break;
+ case '\r':
+ fputs("\\r", pretty->out);
+ break;
+ case '\t':
+ fputs("\\t", pretty->out);
+ break;
+ case '\v':
+ fputs("\\v", pretty->out);
+ break;
+ default:
+ /* Unhandled control-sequence, print as hex. */
+ fprintf(pretty->out, "\\x%02x", str[i]);
+ break;
+ }
+ }
+ fputc('"', pretty->out);
+}
+
+static
+enum bt_component_status print_enum(struct pretty_component *pretty,
+ struct bt_ctf_field *field)
+{
+ enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
+ struct bt_ctf_field *container_field = NULL;
+ struct bt_ctf_field_type *enumeration_field_type = NULL;
+ struct bt_ctf_field_type *container_field_type = NULL;
+ struct bt_ctf_field_type_enumeration_mapping_iterator *iter = NULL;
+ int nr_mappings = 0;
+ int is_signed;
+
+ enumeration_field_type = bt_ctf_field_get_type(field);
+ if (!enumeration_field_type) {
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+ container_field = bt_ctf_field_enumeration_get_container(field);
+ if (!container_field) {
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+ container_field_type = bt_ctf_field_get_type(container_field);
+ if (!container_field_type) {
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+ is_signed = bt_ctf_field_type_integer_get_signed(container_field_type);
+ if (is_signed < 0) {
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+ if (is_signed) {
+ int64_t value;
+
+ if (bt_ctf_field_signed_integer_get_value(container_field,
+ &value)) {
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+ iter = bt_ctf_field_type_enumeration_find_mappings_by_signed_value(
+ enumeration_field_type, value);
+ } else {
+ uint64_t value;
+
+ if (bt_ctf_field_unsigned_integer_get_value(container_field,
+ &value)) {
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+ iter = bt_ctf_field_type_enumeration_find_mappings_by_unsigned_value(
+ enumeration_field_type, value);
+ }
+ if (!iter) {
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+ fprintf(pretty->out, "( ");
+ for (;;) {
+ const char *mapping_name;
+
+ if (bt_ctf_field_type_enumeration_mapping_iterator_get_signed(
+ iter, &mapping_name, NULL, NULL) < 0) {
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+ if (nr_mappings++)
+ fprintf(pretty->out, ", ");
+ if (pretty->use_colors) {
+ fputs(COLOR_ENUM_MAPPING_NAME, pretty->out);
+ }
+ print_escape_string(pretty, mapping_name);
+ if (pretty->use_colors) {
+ fputs(COLOR_RST, pretty->out);
+ }
+ if (bt_ctf_field_type_enumeration_mapping_iterator_next(iter) < 0) {
+ break;
+ }
+ }
+ if (!nr_mappings) {
+ if (pretty->use_colors) {
+ fputs(COLOR_UNKNOWN, pretty->out);
+ }
+ fprintf(pretty->out, "<unknown>");
+ if (pretty->use_colors) {
+ fputs(COLOR_RST, pretty->out);
+ }
+ }
+ fprintf(pretty->out, " : container = ");
+ ret = print_integer(pretty, container_field);
+ if (ret != BT_COMPONENT_STATUS_OK) {
+ goto end;
+ }
+ fprintf(pretty->out, " )");
+end:
+ bt_put(iter);
+ bt_put(container_field_type);
+ bt_put(container_field);
+ bt_put(enumeration_field_type);
+ return ret;
+}
+
+static
+int filter_field_name(struct pretty_component *pretty, const char *field_name,
+ GQuark *filter_fields, int filter_array_len)
+{
+ int i;
+ GQuark field_quark = g_quark_try_string(field_name);
+
+ if (!field_quark || pretty->options.verbose) {
+ return 1;
+ }
+
+ for (i = 0; i < filter_array_len; i++) {
+ if (field_quark == filter_fields[i]) {
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static
+enum bt_component_status print_struct_field(struct pretty_component *pretty,
+ struct bt_ctf_field *_struct,
+ struct bt_ctf_field_type *struct_type,
+ int i, bool print_names, int *nr_printed_fields,
+ GQuark *filter_fields, int filter_array_len)
+{
+ enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
+ const char *field_name;
+ struct bt_ctf_field *field = NULL;
+ struct bt_ctf_field_type *field_type = NULL;;
+
+ field = bt_ctf_field_structure_get_field_by_index(_struct, i);
+ if (!field) {
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+ if (bt_ctf_field_type_structure_get_field(struct_type,
+ &field_name, &field_type, i) < 0) {
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+
+ if (filter_fields && !filter_field_name(pretty, field_name,
+ filter_fields, filter_array_len)) {
+ ret = BT_COMPONENT_STATUS_OK;
+ goto end;
+ }
+
+ if (*nr_printed_fields > 0) {
+ fprintf(pretty->out, ", ");
+ } else {
+ fprintf(pretty->out, " ");
+ }
+ if (print_names) {
+ print_field_name_equal(pretty, rem_(field_name));
+ }
+ ret = print_field(pretty, field, print_names, NULL, 0);
+ *nr_printed_fields += 1;
+end:
+ bt_put(field_type);
+ bt_put(field);
+ return ret;
+}
+
+static
+enum bt_component_status print_struct(struct pretty_component *pretty,
+ struct bt_ctf_field *_struct, bool print_names,
+ GQuark *filter_fields, int filter_array_len)
+{
+ enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
+ struct bt_ctf_field_type *struct_type = NULL;
+ int nr_fields, i, nr_printed_fields;
+
+ struct_type = bt_ctf_field_get_type(_struct);
+ if (!struct_type) {
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+ nr_fields = bt_ctf_field_type_structure_get_field_count(struct_type);
+ if (nr_fields < 0) {
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+ fprintf(pretty->out, "{");
+ pretty->depth++;
+ nr_printed_fields = 0;
+ for (i = 0; i < nr_fields; i++) {
+ ret = print_struct_field(pretty, _struct, struct_type, i,
+ print_names, &nr_printed_fields, filter_fields,
+ filter_array_len);
+ if (ret != BT_COMPONENT_STATUS_OK) {
+ goto end;
+ }
+ }
+ pretty->depth--;
+ fprintf(pretty->out, " }");
+end:
+ bt_put(struct_type);
+ return ret;
+}
+
+static
+enum bt_component_status print_array_field(struct pretty_component *pretty,
+ struct bt_ctf_field *array, uint64_t i,
+ bool is_string, bool print_names)
+{
+ enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
+ struct bt_ctf_field *field = NULL;
+
+ if (!is_string) {
+ if (i != 0) {
+ fprintf(pretty->out, ", ");
+ } else {
+ fprintf(pretty->out, " ");
+ }
+ if (print_names) {
+ fprintf(pretty->out, "[%" PRIu64 "] = ", i);
+ }
+ }
+ field = bt_ctf_field_array_get_field(array, i);
+ if (!field) {
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+ ret = print_field(pretty, field, print_names, NULL, 0);
+end:
+ bt_put(field);
+ return ret;
+}
+
+static
+enum bt_component_status print_array(struct pretty_component *pretty,
+ struct bt_ctf_field *array, bool print_names)
+{
+ enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
+ struct bt_ctf_field_type *array_type = NULL, *field_type = NULL;
+ enum bt_ctf_field_type_id type_id;
+ int64_t len;
+ uint64_t i;
+ bool is_string = false;
+
+ array_type = bt_ctf_field_get_type(array);
+ if (!array_type) {
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+ field_type = bt_ctf_field_type_array_get_element_type(array_type);
+ if (!field_type) {
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+ len = bt_ctf_field_type_array_get_length(array_type);
+ if (len < 0) {
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+ type_id = bt_ctf_field_type_get_type_id(field_type);
+ if (type_id == BT_CTF_FIELD_TYPE_ID_INTEGER) {
+ enum bt_ctf_string_encoding encoding;
+
+ encoding = bt_ctf_field_type_integer_get_encoding(field_type);
+ if (encoding == BT_CTF_STRING_ENCODING_UTF8
+ || encoding == BT_CTF_STRING_ENCODING_ASCII) {
+ int integer_len, integer_alignment;
+
+ integer_len = bt_ctf_field_type_integer_get_size(field_type);
+ if (integer_len < 0) {
+ return BT_COMPONENT_STATUS_ERROR;
+ }
+ integer_alignment = bt_ctf_field_type_get_alignment(field_type);
+ if (integer_alignment < 0) {
+ return BT_COMPONENT_STATUS_ERROR;
+ }
+ if (integer_len == CHAR_BIT
+ && integer_alignment == CHAR_BIT) {
+ is_string = true;
+ }
+ }
+ }
+
+ if (is_string) {
+ g_string_assign(pretty->string, "");
+ } else {
+ fprintf(pretty->out, "[");
+ }
+
+ pretty->depth++;
+ for (i = 0; i < len; i++) {
+ ret = print_array_field(pretty, array, i, is_string, print_names);
+ if (ret != BT_COMPONENT_STATUS_OK) {
+ goto end;
+ }
+ }
+ pretty->depth--;
+
+ if (is_string) {
+ if (pretty->use_colors) {
+ fputs(COLOR_STRING_VALUE, pretty->out);
+ }
+ print_escape_string(pretty, pretty->string->str);
+ if (pretty->use_colors) {
+ fputs(COLOR_RST, pretty->out);
+ }
+ } else {
+ fprintf(pretty->out, " ]");
+ }
+end:
+ bt_put(field_type);
+ bt_put(array_type);
+ return ret;
+}
+
+static
+enum bt_component_status print_sequence_field(struct pretty_component *pretty,
+ struct bt_ctf_field *seq, uint64_t i,
+ bool is_string, bool print_names)
+{
+ enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
+ struct bt_ctf_field *field = NULL;
+
+ if (!is_string) {
+ if (i != 0) {
+ fprintf(pretty->out, ", ");
+ } else {
+ fprintf(pretty->out, " ");
+ }
+ if (print_names) {
+ fprintf(pretty->out, "[%" PRIu64 "] = ", i);
+ }
+ }
+ field = bt_ctf_field_sequence_get_field(seq, i);
+ if (!field) {
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+ ret = print_field(pretty, field, print_names, NULL, 0);
+end:
+ bt_put(field);
+ return ret;
+}
+
+static
+enum bt_component_status print_sequence(struct pretty_component *pretty,
+ struct bt_ctf_field *seq, bool print_names)
+{
+ enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
+ struct bt_ctf_field_type *seq_type = NULL, *field_type = NULL;
+ struct bt_ctf_field *length_field = NULL;
+ enum bt_ctf_field_type_id type_id;
+ uint64_t len;
+ uint64_t i;
+ bool is_string = false;
+
+ seq_type = bt_ctf_field_get_type(seq);
+ if (!seq_type) {
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+ length_field = bt_ctf_field_sequence_get_length(seq);
+ if (!length_field) {
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+ if (bt_ctf_field_unsigned_integer_get_value(length_field, &len) < 0) {
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+ field_type = bt_ctf_field_type_sequence_get_element_type(seq_type);
+ if (!field_type) {
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+ type_id = bt_ctf_field_type_get_type_id(field_type);
+ if (type_id == BT_CTF_FIELD_TYPE_ID_INTEGER) {
+ enum bt_ctf_string_encoding encoding;
+
+ encoding = bt_ctf_field_type_integer_get_encoding(field_type);
+ if (encoding == BT_CTF_STRING_ENCODING_UTF8
+ || encoding == BT_CTF_STRING_ENCODING_ASCII) {
+ int integer_len, integer_alignment;
+
+ integer_len = bt_ctf_field_type_integer_get_size(field_type);
+ if (integer_len < 0) {
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+ integer_alignment = bt_ctf_field_type_get_alignment(field_type);
+ if (integer_alignment < 0) {
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+ if (integer_len == CHAR_BIT
+ && integer_alignment == CHAR_BIT) {
+ is_string = true;
+ }
+ }
+ }
+
+ if (is_string) {
+ g_string_assign(pretty->string, "");
+ } else {
+ fprintf(pretty->out, "[");
+ }
+
+ pretty->depth++;
+ for (i = 0; i < len; i++) {
+ ret = print_sequence_field(pretty, seq, i,
+ is_string, print_names);
+ if (ret != BT_COMPONENT_STATUS_OK) {
+ goto end;
+ }
+ }
+ pretty->depth--;
+
+ if (is_string) {
+ if (pretty->use_colors) {
+ fputs(COLOR_STRING_VALUE, pretty->out);
+ }
+ print_escape_string(pretty, pretty->string->str);
+ if (pretty->use_colors) {
+ fputs(COLOR_RST, pretty->out);
+ }
+ } else {
+ fprintf(pretty->out, " ]");
+ }
+end:
+ bt_put(length_field);
+ bt_put(field_type);
+ bt_put(seq_type);
+ return ret;
+}
+
+static
+enum bt_component_status print_variant(struct pretty_component *pretty,
+ struct bt_ctf_field *variant, bool print_names)
+{
+ enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
+ struct bt_ctf_field *field = NULL;
+
+ field = bt_ctf_field_variant_get_current_field(variant);
+ if (!field) {
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+ fprintf(pretty->out, "{ ");
+ pretty->depth++;
+ if (print_names) {
+ int iter_ret;
+ struct bt_ctf_field *tag_field = NULL;
+ const char *tag_choice;
+ struct bt_ctf_field_type_enumeration_mapping_iterator *iter;
+
+ tag_field = bt_ctf_field_variant_get_tag(variant);
+ if (!tag_field) {
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+
+ iter = bt_ctf_field_enumeration_get_mappings(tag_field);
+ if (!iter) {
+ bt_put(tag_field);
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+
+ iter_ret =
+ bt_ctf_field_type_enumeration_mapping_iterator_get_signed(
+ iter, &tag_choice, NULL, NULL);
+ if (iter_ret) {
+ bt_put(iter);
+ bt_put(tag_field);
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+ print_field_name_equal(pretty, rem_(tag_choice));
+ bt_put(tag_field);
+ bt_put(iter);
+ }
+ ret = print_field(pretty, field, print_names, NULL, 0);
+ if (ret != BT_COMPONENT_STATUS_OK) {
+ goto end;
+ }
+ pretty->depth--;
+ fprintf(pretty->out, " }");
+end:
+ bt_put(field);
+ return ret;
+}
+
+static
+enum bt_component_status print_field(struct pretty_component *pretty,
+ struct bt_ctf_field *field, bool print_names,
+ GQuark *filter_fields, int filter_array_len)
+{
+ enum bt_ctf_field_type_id type_id;
+
+ type_id = bt_ctf_field_get_type_id(field);
+ switch (type_id) {
+ case CTF_TYPE_INTEGER:
+ return print_integer(pretty, field);
+ case CTF_TYPE_FLOAT:
+ {
+ double v;
+
+ if (bt_ctf_field_floating_point_get_value(field, &v)) {
+ return BT_COMPONENT_STATUS_ERROR;
+ }
+ if (pretty->use_colors) {
+ fputs(COLOR_NUMBER_VALUE, pretty->out);
+ }
+ fprintf(pretty->out, "%g", v);
+ if (pretty->use_colors) {
+ fputs(COLOR_RST, pretty->out);
+ }
+ return BT_COMPONENT_STATUS_OK;
+ }
+ case CTF_TYPE_ENUM:
+ return print_enum(pretty, field);
+ case CTF_TYPE_STRING:
+ if (pretty->use_colors) {
+ fputs(COLOR_STRING_VALUE, pretty->out);
+ }
+ print_escape_string(pretty, bt_ctf_field_string_get_value(field));
+ if (pretty->use_colors) {
+ fputs(COLOR_RST, pretty->out);
+ }
+ return BT_COMPONENT_STATUS_OK;
+ case CTF_TYPE_STRUCT:
+ return print_struct(pretty, field, print_names, filter_fields,
+ filter_array_len);
+ case CTF_TYPE_UNTAGGED_VARIANT:
+ case CTF_TYPE_VARIANT:
+ return print_variant(pretty, field, print_names);
+ case CTF_TYPE_ARRAY:
+ return print_array(pretty, field, print_names);
+ case CTF_TYPE_SEQUENCE:
+ return print_sequence(pretty, field, print_names);
+ default:
+ fprintf(pretty->err, "[error] Unknown type id: %d\n", (int) type_id);
+ return BT_COMPONENT_STATUS_ERROR;
+ }
+}
+
+static
+enum bt_component_status print_stream_packet_context(struct pretty_component *pretty,
+ struct bt_ctf_event *event)
+{
+ enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
+ struct bt_ctf_packet *packet = NULL;
+ struct bt_ctf_field *main_field = NULL;
+
+ packet = bt_ctf_event_get_packet(event);
+ if (!packet) {
+ ret = BT_COMPONENT_STATUS_ERROR;
+ goto end;
+ }
+ main_field = bt_ctf_packet_get_context(packet);
+ if (!main_field) {
+ goto end;
+ }
+ if (!pretty->start_line) {
+ fputs(", ", pretty->out);
+ }
+ pretty->start_line = false;
+ if (pretty->options.print_scope_field_names) {
+ print_name_equal(pretty, "stream.packet.context");
+ }
+ ret = print_field(pretty, main_field,
+ pretty->options.print_context_field_names,
+ stream_packet_context_quarks,
+ STREAM_PACKET_CONTEXT_QUARKS_LEN);
+end:
+ bt_put(main_field);
+ bt_put(packet);
+ return ret;
+}
+
+static
+enum bt_component_status print_event_header_raw(struct pretty_component *pretty,
+ struct bt_ctf_event *event)
+{
+ enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
+ struct bt_ctf_field *main_field = NULL;
+
+ main_field = bt_ctf_event_get_header(event);
+ if (!main_field) {
+ goto end;
+ }
+ if (!pretty->start_line) {
+ fputs(", ", pretty->out);
+ }
+ pretty->start_line = false;
+ if (pretty->options.print_scope_field_names) {
+ print_name_equal(pretty, "stream.event.header");
+ }
+ ret = print_field(pretty, main_field,
+ pretty->options.print_header_field_names, NULL, 0);
+end:
+ bt_put(main_field);
+ return ret;
+}
+
+static
+enum bt_component_status print_stream_event_context(struct pretty_component *pretty,
+ struct bt_ctf_event *event)
+{
+ enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
+ struct bt_ctf_field *main_field = NULL;
+
+ main_field = bt_ctf_event_get_stream_event_context(event);
+ if (!main_field) {
+ goto end;
+ }
+ if (!pretty->start_line) {
+ fputs(", ", pretty->out);
+ }
+ pretty->start_line = false;
+ if (pretty->options.print_scope_field_names) {
+ print_name_equal(pretty, "stream.event.context");
+ }
+ ret = print_field(pretty, main_field,
+ pretty->options.print_context_field_names, NULL, 0);
+end:
+ bt_put(main_field);
+ return ret;
+}
+
+static
+enum bt_component_status print_event_context(struct pretty_component *pretty,
+ struct bt_ctf_event *event)
+{
+ enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
+ struct bt_ctf_field *main_field = NULL;
+
+ main_field = bt_ctf_event_get_event_context(event);
+ if (!main_field) {
+ goto end;
+ }
+ if (!pretty->start_line) {
+ fputs(", ", pretty->out);
+ }
+ pretty->start_line = false;
+ if (pretty->options.print_scope_field_names) {
+ print_name_equal(pretty, "event.context");
+ }
+ ret = print_field(pretty, main_field,
+ pretty->options.print_context_field_names, NULL, 0);
+end:
+ bt_put(main_field);
+ return ret;
+}
+
+static
+enum bt_component_status print_event_payload(struct pretty_component *pretty,
+ struct bt_ctf_event *event)
+{
+ enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
+ struct bt_ctf_field *main_field = NULL;
+
+ main_field = bt_ctf_event_get_payload_field(event);
+ if (!main_field) {
+ goto end;
+ }
+ if (!pretty->start_line) {
+ fputs(", ", pretty->out);
+ }
+ pretty->start_line = false;
+ if (pretty->options.print_scope_field_names) {
+ print_name_equal(pretty, "event.fields");
+ }
+ ret = print_field(pretty, main_field,
+ pretty->options.print_payload_field_names, NULL, 0);
+end:
+ bt_put(main_field);
+ return ret;
+}
+
+BT_HIDDEN
+enum bt_component_status pretty_print_event(struct pretty_component *pretty,
+ struct bt_ctf_event *event)
+{
+ enum bt_component_status ret;
+
+ pretty->start_line = true;
+ ret = print_event_header(pretty, event);
+ if (ret != BT_COMPONENT_STATUS_OK) {
+ goto end;
+ }
+
+ ret = print_stream_packet_context(pretty, event);
+ if (ret != BT_COMPONENT_STATUS_OK) {
+ goto end;
+ }
+
+ if (pretty->options.verbose) {
+ ret = print_event_header_raw(pretty, event);
+ if (ret != BT_COMPONENT_STATUS_OK) {
+ goto end;
+ }
+ }
+
+ ret = print_stream_event_context(pretty, event);
+ if (ret != BT_COMPONENT_STATUS_OK) {
+ goto end;
+ }
+
+ ret = print_event_context(pretty, event);
+ if (ret != BT_COMPONENT_STATUS_OK) {
+ goto end;
+ }
+
+ ret = print_event_payload(pretty, event);
+ if (ret != BT_COMPONENT_STATUS_OK) {
+ goto end;
+ }
+
+ fputc('\n', pretty->out);
+end:
+ return ret;
+}
+++ /dev/null
-/*
- * print.c
- *
- * Babeltrace CTF Text Output Plugin Event Printing
- *
- * Copyright 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- * Copyright 2016 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * 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.
- *
- * 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.
- */
-
-#include <babeltrace/ctf-ir/event.h>
-#include <babeltrace/ctf-ir/event-class.h>
-#include <babeltrace/ctf-ir/packet.h>
-#include <babeltrace/ctf-ir/stream.h>
-#include <babeltrace/ctf-ir/stream-class.h>
-#include <babeltrace/ctf-ir/clock-class.h>
-#include <babeltrace/ctf-ir/field-types.h>
-#include <babeltrace/ctf-ir/fields.h>
-#include <babeltrace/ctf-ir/trace.h>
-#include <babeltrace/bitfield-internal.h>
-#include <babeltrace/common-internal.h>
-#include <inttypes.h>
-#include <ctype.h>
-#include "text.h"
-
-#define NSEC_PER_SEC 1000000000LL
-
-#define COLOR_NAME BT_COMMON_COLOR_BOLD
-#define COLOR_FIELD_NAME BT_COMMON_COLOR_FG_CYAN
-#define COLOR_RST BT_COMMON_COLOR_RESET
-#define COLOR_STRING_VALUE BT_COMMON_COLOR_BOLD
-#define COLOR_NUMBER_VALUE BT_COMMON_COLOR_BOLD
-#define COLOR_ENUM_MAPPING_NAME BT_COMMON_COLOR_BOLD
-#define COLOR_UNKNOWN BT_COMMON_COLOR_BOLD BT_COMMON_COLOR_FG_RED
-#define COLOR_EVENT_NAME BT_COMMON_COLOR_BOLD BT_COMMON_COLOR_FG_MAGENTA
-#define COLOR_TIMESTAMP BT_COMMON_COLOR_BOLD BT_COMMON_COLOR_FG_YELLOW
-
-static inline
-const char *rem_(const char *str)
-{
- if (str[0] == '_')
- return &str[1];
- else
- return str;
-}
-
-struct timestamp {
- int64_t real_timestamp; /* Relative to UNIX epoch. */
- uint64_t clock_value; /* In cycles. */
-};
-
-static
-enum bt_component_status print_field(struct text_component *text,
- struct bt_ctf_field *field, bool print_names,
- GQuark *filters_fields, int filter_array_len);
-
-static
-void print_name_equal(struct text_component *text, const char *name)
-{
- if (text->use_colors) {
- fprintf(text->out, "%s%s%s = ", COLOR_NAME, name, COLOR_RST);
- } else {
- fprintf(text->out, "%s = ", name);
- }
-}
-
-static
-void print_field_name_equal(struct text_component *text, const char *name)
-{
- if (text->use_colors) {
- fprintf(text->out, "%s%s%s = ", COLOR_FIELD_NAME, name,
- COLOR_RST);
- } else {
- fprintf(text->out, "%s = ", name);
- }
-}
-
-static
-void print_timestamp_cycles(struct text_component *text,
- struct bt_ctf_clock_class *clock_class,
- struct bt_ctf_event *event)
-{
- int ret;
- struct bt_ctf_clock_value *clock_value;
- uint64_t cycles;
-
- clock_value = bt_ctf_event_get_clock_value(event, clock_class);
- if (!clock_value) {
- fputs("????????????????????", text->out);
- return;
- }
-
- ret = bt_ctf_clock_value_get_value(clock_value, &cycles);
- bt_put(clock_value);
- if (ret) {
- fprintf(text->out, "Error");
- return;
- }
- fprintf(text->out, "%020" PRIu64, cycles);
-
- if (text->last_cycles_timestamp != -1ULL) {
- text->delta_cycles = cycles - text->last_cycles_timestamp;
- }
- text->last_cycles_timestamp = cycles;
-}
-
-static
-void print_timestamp_wall(struct text_component *text,
- struct bt_ctf_clock_class *clock_class,
- struct bt_ctf_event *event)
-{
- int ret;
- struct bt_ctf_clock_value *clock_value;
- int64_t ts_nsec = 0; /* add configurable offset */
- int64_t ts_sec = 0; /* add configurable offset */
- uint64_t ts_sec_abs, ts_nsec_abs;
- bool is_negative;
-
- clock_value = bt_ctf_event_get_clock_value(event, clock_class);
- if (!clock_value) {
- fputs("??:??:??.?????????", text->out);
- return;
- }
-
- ret = bt_ctf_clock_value_get_value_ns_from_epoch(clock_value, &ts_nsec);
- bt_put(clock_value);
- if (ret) {
- fprintf(text->out, "Error");
- return;
- }
-
- if (text->last_real_timestamp != -1ULL) {
- text->delta_real_timestamp = ts_nsec - text->last_real_timestamp;
- }
- text->last_real_timestamp = ts_nsec;
-
- ts_sec += ts_nsec / NSEC_PER_SEC;
- ts_nsec = ts_nsec % NSEC_PER_SEC;
- if (ts_sec >= 0 && ts_nsec >= 0) {
- is_negative = false;
- ts_sec_abs = ts_sec;
- ts_nsec_abs = ts_nsec;
- } else if (ts_sec > 0 && ts_nsec < 0) {
- is_negative = false;
- ts_sec_abs = ts_sec - 1;
- ts_nsec_abs = NSEC_PER_SEC + ts_nsec;
- } else if (ts_sec == 0 && ts_nsec < 0) {
- is_negative = true;
- ts_sec_abs = ts_sec;
- ts_nsec_abs = -ts_nsec;
- } else if (ts_sec < 0 && ts_nsec > 0) {
- is_negative = true;
- ts_sec_abs = -(ts_sec + 1);
- ts_nsec_abs = NSEC_PER_SEC - ts_nsec;
- } else if (ts_sec < 0 && ts_nsec == 0) {
- is_negative = true;
- ts_sec_abs = -ts_sec;
- ts_nsec_abs = ts_nsec;
- } else { /* (ts_sec < 0 && ts_nsec < 0) */
- is_negative = true;
- ts_sec_abs = -ts_sec;
- ts_nsec_abs = -ts_nsec;
- }
-
- if (!text->options.clock_seconds) {
- struct tm tm;
- time_t time_s = (time_t) ts_sec_abs;
-
- if (is_negative) {
- fprintf(stderr, "[warning] Fallback to [sec.ns] to print negative time value. Use --clock-seconds.\n");
- goto seconds;
- }
-
- if (!text->options.clock_gmt) {
- struct tm *res;
-
- res = localtime_r(&time_s, &tm);
- if (!res) {
- fprintf(stderr, "[warning] Unable to get localtime.\n");
- goto seconds;
- }
- } else {
- struct tm *res;
-
- res = gmtime_r(&time_s, &tm);
- if (!res) {
- fprintf(stderr, "[warning] Unable to get gmtime.\n");
- goto seconds;
- }
- }
- if (text->options.clock_date) {
- char timestr[26];
- size_t res;
-
- /* Print date and time */
- res = strftime(timestr, sizeof(timestr),
- "%F ", &tm);
- if (!res) {
- fprintf(stderr, "[warning] Unable to print ascii time.\n");
- goto seconds;
- }
- fprintf(text->out, "%s", timestr);
- }
- /* Print time in HH:MM:SS.ns */
- fprintf(text->out, "%02d:%02d:%02d.%09" PRIu64,
- tm.tm_hour, tm.tm_min, tm.tm_sec, ts_nsec_abs);
- goto end;
- }
-seconds:
- fprintf(text->out, "%s%" PRId64 ".%09" PRIu64,
- is_negative ? "-" : "", ts_sec_abs, ts_nsec_abs);
-end:
- return;
-}
-
-static
-enum bt_component_status print_event_timestamp(struct text_component *text,
- struct bt_ctf_event *event, bool *start_line)
-{
- bool print_names = text->options.print_header_field_names;
- enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
- struct bt_ctf_stream *stream = NULL;
- struct bt_ctf_stream_class *stream_class = NULL;
- struct bt_ctf_trace *trace = NULL;
- struct bt_ctf_clock_class *clock_class = NULL;
- FILE *out = text->out;
-
- stream = bt_ctf_event_get_stream(event);
- if (!stream) {
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
-
- stream_class = bt_ctf_stream_get_class(stream);
- if (!stream_class) {
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
- trace = bt_ctf_stream_class_get_trace(stream_class);
- if (!trace) {
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
- clock_class = bt_ctf_trace_get_clock_class(trace, 0);
- if (!clock_class) {
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
-
- if (print_names) {
- print_name_equal(text, "timestamp");
- } else {
- fputs("[", out);
- }
- if (text->use_colors) {
- fputs(COLOR_TIMESTAMP, text->out);
- }
- if (text->options.print_timestamp_cycles) {
- print_timestamp_cycles(text, clock_class, event);
- } else {
- print_timestamp_wall(text, clock_class, event);
- }
- if (text->use_colors) {
- fputs(COLOR_RST, text->out);
- }
-
- if (!print_names)
- fputs("] ", out);
-
- if (text->options.print_delta_field) {
- if (print_names) {
- fputs(", ", text->out);
- print_name_equal(text, "delta");
- } else {
- fputs("(", text->out);
- }
- if (text->options.print_timestamp_cycles) {
- if (text->delta_cycles == -1ULL) {
- fputs("+??????????\?\?) ", text->out); /* Not a trigraph. */
- } else {
- fprintf(text->out, "+%012" PRIu64, text->delta_cycles);
- }
- } else {
- if (text->delta_real_timestamp != -1ULL) {
- uint64_t delta_sec, delta_nsec, delta;
-
- delta = text->delta_real_timestamp;
- delta_sec = delta / NSEC_PER_SEC;
- delta_nsec = delta % NSEC_PER_SEC;
- fprintf(text->out, "+%" PRIu64 ".%09" PRIu64,
- delta_sec, delta_nsec);
- } else {
- fputs("+?.?????????", text->out);
- }
- }
- if (!print_names) {
- fputs(") ", text->out);
- }
- }
- *start_line = !print_names;
-
-end:
- bt_put(stream);
- bt_put(clock_class);
- bt_put(stream_class);
- bt_put(trace);
- return ret;
-}
-
-static
-enum bt_component_status print_event_header(struct text_component *text,
- struct bt_ctf_event *event)
-{
- bool print_names = text->options.print_header_field_names;
- enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
- struct bt_ctf_event_class *event_class = NULL;
- struct bt_ctf_stream_class *stream_class = NULL;
- struct bt_ctf_trace *trace_class = NULL;
- int dom_print = 0;
-
- event_class = bt_ctf_event_get_class(event);
- if (!event_class) {
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
- stream_class = bt_ctf_event_class_get_stream_class(event_class);
- if (!stream_class) {
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
- trace_class = bt_ctf_stream_class_get_trace(stream_class);
- if (!trace_class) {
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
- ret = print_event_timestamp(text, event, &text->start_line);
- if (ret != BT_COMPONENT_STATUS_OK) {
- goto end;
- }
- if (text->options.print_trace_field) {
- const char *name;
-
- name = bt_ctf_trace_get_name(trace_class);
- if (name) {
- if (!text->start_line) {
- fputs(", ", text->out);
- }
- if (print_names) {
- print_name_equal(text, "trace");
- }
- fprintf(text->out, "%s", name);
- if (!print_names) {
- fprintf(text->out, " ");
- }
- }
- }
- if (text->options.print_trace_hostname_field) {
- struct bt_value *hostname_str;
-
- hostname_str = bt_ctf_trace_get_environment_field_value_by_name(trace_class,
- "hostname");
- if (hostname_str) {
- const char *str;
-
- if (!text->start_line) {
- fputs(", ", text->out);
- }
- if (print_names) {
- print_name_equal(text, "trace:hostname");
- }
- if (bt_value_string_get(hostname_str, &str)
- == BT_VALUE_STATUS_OK) {
- fprintf(text->out, "%s", str);
- }
- bt_put(hostname_str);
- dom_print = 1;
- }
- }
- if (text->options.print_trace_domain_field) {
- struct bt_value *domain_str;
-
- domain_str = bt_ctf_trace_get_environment_field_value_by_name(trace_class,
- "domain");
- if (domain_str) {
- const char *str;
-
- if (!text->start_line) {
- fputs(", ", text->out);
- }
- if (print_names) {
- print_name_equal(text, "trace:domain");
- } else if (dom_print) {
- fputs(":", text->out);
- }
- if (bt_value_string_get(domain_str, &str)
- == BT_VALUE_STATUS_OK) {
- fprintf(text->out, "%s", str);
- }
- bt_put(domain_str);
- dom_print = 1;
- }
- }
- if (text->options.print_trace_procname_field) {
- struct bt_value *procname_str;
-
- procname_str = bt_ctf_trace_get_environment_field_value_by_name(trace_class,
- "procname");
- if (procname_str) {
- const char *str;
-
- if (!text->start_line) {
- fputs(", ", text->out);
- }
- if (print_names) {
- print_name_equal(text, "trace:procname");
- } else if (dom_print) {
- fputs(":", text->out);
- }
- if (bt_value_string_get(procname_str, &str)
- == BT_VALUE_STATUS_OK) {
- fprintf(text->out, "%s", str);
- }
- bt_put(procname_str);
- dom_print = 1;
- }
- }
- if (text->options.print_trace_vpid_field) {
- struct bt_value *vpid_value;
-
- vpid_value = bt_ctf_trace_get_environment_field_value_by_name(trace_class,
- "vpid");
- if (vpid_value) {
- int64_t value;
-
- if (!text->start_line) {
- fputs(", ", text->out);
- }
- if (print_names) {
- print_name_equal(text, "trace:vpid");
- } else if (dom_print) {
- fputs(":", text->out);
- }
- if (bt_value_integer_get(vpid_value, &value)
- == BT_VALUE_STATUS_OK) {
- fprintf(text->out, "(%" PRId64 ")", value);
- }
- bt_put(vpid_value);
- dom_print = 1;
- }
- }
- if (text->options.print_loglevel_field) {
- struct bt_value *loglevel_str, *loglevel_value;
-
- loglevel_str = bt_ctf_event_class_get_attribute_value_by_name(event_class,
- "loglevel_string");
- loglevel_value = bt_ctf_event_class_get_attribute_value_by_name(event_class,
- "loglevel");
- if (loglevel_str || loglevel_value) {
- bool has_str = false;
-
- if (!text->start_line) {
- fputs(", ", text->out);
- }
- if (print_names) {
- print_name_equal(text, "loglevel");
- } else if (dom_print) {
- fputs(":", text->out);
- }
- if (loglevel_str) {
- const char *str;
-
- if (bt_value_string_get(loglevel_str, &str)
- == BT_VALUE_STATUS_OK) {
- fprintf(text->out, "%s", str);
- has_str = true;
- }
- }
- if (loglevel_value) {
- int64_t value;
-
- if (bt_value_integer_get(loglevel_value, &value)
- == BT_VALUE_STATUS_OK) {
- fprintf(text->out, "%s(%" PRId64 ")",
- has_str ? " " : "", value);
- }
- }
- bt_put(loglevel_str);
- bt_put(loglevel_value);
- dom_print = 1;
- }
- }
- if (text->options.print_emf_field) {
- struct bt_value *uri_str;
-
- uri_str = bt_ctf_event_class_get_attribute_value_by_name(event_class,
- "model.emf.uri");
- if (uri_str) {
- if (!text->start_line) {
- fputs(", ", text->out);
- }
- if (print_names) {
- print_name_equal(text, "model.emf.uri");
- } else if (dom_print) {
- fputs(":", text->out);
- }
- if (uri_str) {
- const char *str;
-
- if (bt_value_string_get(uri_str, &str)
- == BT_VALUE_STATUS_OK) {
- fprintf(text->out, "%s", str);
- }
- }
- bt_put(uri_str);
- dom_print = 1;
- }
- }
- if (dom_print && !print_names) {
- fputs(" ", text->out);
- }
- if (!text->start_line) {
- fputs(", ", text->out);
- }
- text->start_line = true;
- if (print_names) {
- print_name_equal(text, "name");
- }
- if (text->use_colors) {
- fputs(COLOR_EVENT_NAME, text->out);
- }
- fputs(bt_ctf_event_class_get_name(event_class), text->out);
- if (text->use_colors) {
- fputs(COLOR_RST, text->out);
- }
- if (!print_names) {
- fputs(": ", text->out);
- } else {
- fputs(", ", text->out);
- }
-end:
- bt_put(trace_class);
- bt_put(stream_class);
- bt_put(event_class);
- return ret;
-}
-
-static
-enum bt_component_status print_integer(struct text_component *text,
- struct bt_ctf_field *field)
-{
- enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
- struct bt_ctf_field_type *field_type = NULL;
- enum bt_ctf_integer_base base;
- enum bt_ctf_string_encoding encoding;
- int signedness;
- union {
- uint64_t u;
- int64_t s;
- } v;
- bool rst_color = false;
-
- field_type = bt_ctf_field_get_type(field);
- if (!field_type) {
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
- signedness = bt_ctf_field_type_integer_get_signed(field_type);
- if (signedness < 0) {
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
- if (!signedness) {
- if (bt_ctf_field_unsigned_integer_get_value(field, &v.u) < 0) {
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
- } else {
- if (bt_ctf_field_signed_integer_get_value(field, &v.s) < 0) {
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
- }
-
- encoding = bt_ctf_field_type_integer_get_encoding(field_type);
- switch (encoding) {
- case BT_CTF_STRING_ENCODING_UTF8:
- case BT_CTF_STRING_ENCODING_ASCII:
- g_string_append_c(text->string, (int) v.u);
- goto end;
- case BT_CTF_STRING_ENCODING_NONE:
- case BT_CTF_STRING_ENCODING_UNKNOWN:
- break;
- default:
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
-
- if (text->use_colors) {
- fputs(COLOR_NUMBER_VALUE, text->out);
- rst_color = true;
- }
-
- base = bt_ctf_field_type_integer_get_base(field_type);
- switch (base) {
- case BT_CTF_INTEGER_BASE_BINARY:
- {
- int bitnr, len;
-
- len = bt_ctf_field_type_integer_get_size(field_type);
- if (len < 0) {
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
- fprintf(text->out, "0b");
- v.u = _bt_piecewise_lshift(v.u, 64 - len);
- for (bitnr = 0; bitnr < len; bitnr++) {
- fprintf(text->out, "%u", (v.u & (1ULL << 63)) ? 1 : 0);
- v.u = _bt_piecewise_lshift(v.u, 1);
- }
- break;
- }
- case BT_CTF_INTEGER_BASE_OCTAL:
- {
- if (signedness) {
- int len;
-
- len = bt_ctf_field_type_integer_get_size(field_type);
- if (len < 0) {
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
- if (len < 64) {
- size_t rounded_len;
-
- assert(len != 0);
- /* Round length to the nearest 3-bit */
- rounded_len = (((len - 1) / 3) + 1) * 3;
- v.u &= ((uint64_t) 1 << rounded_len) - 1;
- }
- }
-
- fprintf(text->out, "0%" PRIo64, v.u);
- break;
- }
- case BT_CTF_INTEGER_BASE_DECIMAL:
- if (!signedness) {
- fprintf(text->out, "%" PRIu64, v.u);
- } else {
- fprintf(text->out, "%" PRId64, v.s);
- }
- break;
- case BT_CTF_INTEGER_BASE_HEXADECIMAL:
- {
- int len;
-
- len = bt_ctf_field_type_integer_get_size(field_type);
- if (len < 0) {
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
- if (len < 64) {
- /* Round length to the nearest nibble */
- uint8_t rounded_len = ((len + 3) & ~0x3);
-
- v.u &= ((uint64_t) 1 << rounded_len) - 1;
- }
-
- fprintf(text->out, "0x%" PRIX64, v.u);
- break;
- }
- default:
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
-end:
- if (rst_color) {
- fputs(COLOR_RST, text->out);
- }
- bt_put(field_type);
- return ret;
-}
-
-static
-void print_escape_string(struct text_component *text, const char *str)
-{
- int i;
-
- fputc('"', text->out);
- for (i = 0; i < strlen(str); i++) {
- /* Escape sequences not recognized by iscntrl(). */
- switch (str[i]) {
- case '\\':
- fputs("\\\\", text->out);
- continue;
- case '\'':
- fputs("\\\'", text->out);
- continue;
- case '\"':
- fputs("\\\"", text->out);
- continue;
- case '\?':
- fputs("\\\?", text->out);
- continue;
- }
-
- /* Standard characters. */
- if (!iscntrl(str[i])) {
- fputc(str[i], text->out);
- continue;
- }
-
- switch (str[i]) {
- case '\0':
- fputs("\\0", text->out);
- break;
- case '\a':
- fputs("\\a", text->out);
- break;
- case '\b':
- fputs("\\b", text->out);
- break;
- case '\e':
- fputs("\\e", text->out);
- break;
- case '\f':
- fputs("\\f", text->out);
- break;
- case '\n':
- fputs("\\n", text->out);
- break;
- case '\r':
- fputs("\\r", text->out);
- break;
- case '\t':
- fputs("\\t", text->out);
- break;
- case '\v':
- fputs("\\v", text->out);
- break;
- default:
- /* Unhandled control-sequence, print as hex. */
- fprintf(text->out, "\\x%02x", str[i]);
- break;
- }
- }
- fputc('"', text->out);
-}
-
-static
-enum bt_component_status print_enum(struct text_component *text,
- struct bt_ctf_field *field)
-{
- enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
- struct bt_ctf_field *container_field = NULL;
- struct bt_ctf_field_type *enumeration_field_type = NULL;
- struct bt_ctf_field_type *container_field_type = NULL;
- struct bt_ctf_field_type_enumeration_mapping_iterator *iter = NULL;
- int nr_mappings = 0;
- int is_signed;
-
- enumeration_field_type = bt_ctf_field_get_type(field);
- if (!enumeration_field_type) {
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
- container_field = bt_ctf_field_enumeration_get_container(field);
- if (!container_field) {
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
- container_field_type = bt_ctf_field_get_type(container_field);
- if (!container_field_type) {
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
- is_signed = bt_ctf_field_type_integer_get_signed(container_field_type);
- if (is_signed < 0) {
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
- if (is_signed) {
- int64_t value;
-
- if (bt_ctf_field_signed_integer_get_value(container_field,
- &value)) {
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
- iter = bt_ctf_field_type_enumeration_find_mappings_by_signed_value(
- enumeration_field_type, value);
- } else {
- uint64_t value;
-
- if (bt_ctf_field_unsigned_integer_get_value(container_field,
- &value)) {
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
- iter = bt_ctf_field_type_enumeration_find_mappings_by_unsigned_value(
- enumeration_field_type, value);
- }
- if (!iter) {
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
- fprintf(text->out, "( ");
- for (;;) {
- const char *mapping_name;
-
- if (bt_ctf_field_type_enumeration_mapping_iterator_get_signed(
- iter, &mapping_name, NULL, NULL) < 0) {
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
- if (nr_mappings++)
- fprintf(text->out, ", ");
- if (text->use_colors) {
- fputs(COLOR_ENUM_MAPPING_NAME, text->out);
- }
- print_escape_string(text, mapping_name);
- if (text->use_colors) {
- fputs(COLOR_RST, text->out);
- }
- if (bt_ctf_field_type_enumeration_mapping_iterator_next(iter) < 0) {
- break;
- }
- }
- if (!nr_mappings) {
- if (text->use_colors) {
- fputs(COLOR_UNKNOWN, text->out);
- }
- fprintf(text->out, "<unknown>");
- if (text->use_colors) {
- fputs(COLOR_RST, text->out);
- }
- }
- fprintf(text->out, " : container = ");
- ret = print_integer(text, container_field);
- if (ret != BT_COMPONENT_STATUS_OK) {
- goto end;
- }
- fprintf(text->out, " )");
-end:
- bt_put(iter);
- bt_put(container_field_type);
- bt_put(container_field);
- bt_put(enumeration_field_type);
- return ret;
-}
-
-static
-int filter_field_name(struct text_component *text, const char *field_name,
- GQuark *filter_fields, int filter_array_len)
-{
- int i;
- GQuark field_quark = g_quark_try_string(field_name);
-
- if (!field_quark || text->options.verbose) {
- return 1;
- }
-
- for (i = 0; i < filter_array_len; i++) {
- if (field_quark == filter_fields[i]) {
- return 0;
- }
- }
- return 1;
-}
-
-static
-enum bt_component_status print_struct_field(struct text_component *text,
- struct bt_ctf_field *_struct,
- struct bt_ctf_field_type *struct_type,
- int i, bool print_names, int *nr_printed_fields,
- GQuark *filter_fields, int filter_array_len)
-{
- enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
- const char *field_name;
- struct bt_ctf_field *field = NULL;
- struct bt_ctf_field_type *field_type = NULL;;
-
- field = bt_ctf_field_structure_get_field_by_index(_struct, i);
- if (!field) {
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
- if (bt_ctf_field_type_structure_get_field(struct_type,
- &field_name, &field_type, i) < 0) {
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
-
- if (filter_fields && !filter_field_name(text, field_name,
- filter_fields, filter_array_len)) {
- ret = BT_COMPONENT_STATUS_OK;
- goto end;
- }
-
- if (*nr_printed_fields > 0) {
- fprintf(text->out, ", ");
- } else {
- fprintf(text->out, " ");
- }
- if (print_names) {
- print_field_name_equal(text, rem_(field_name));
- }
- ret = print_field(text, field, print_names, NULL, 0);
- *nr_printed_fields += 1;
-end:
- bt_put(field_type);
- bt_put(field);
- return ret;
-}
-
-static
-enum bt_component_status print_struct(struct text_component *text,
- struct bt_ctf_field *_struct, bool print_names,
- GQuark *filter_fields, int filter_array_len)
-{
- enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
- struct bt_ctf_field_type *struct_type = NULL;
- int nr_fields, i, nr_printed_fields;
-
- struct_type = bt_ctf_field_get_type(_struct);
- if (!struct_type) {
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
- nr_fields = bt_ctf_field_type_structure_get_field_count(struct_type);
- if (nr_fields < 0) {
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
- fprintf(text->out, "{");
- text->depth++;
- nr_printed_fields = 0;
- for (i = 0; i < nr_fields; i++) {
- ret = print_struct_field(text, _struct, struct_type, i,
- print_names, &nr_printed_fields, filter_fields,
- filter_array_len);
- if (ret != BT_COMPONENT_STATUS_OK) {
- goto end;
- }
- }
- text->depth--;
- fprintf(text->out, " }");
-end:
- bt_put(struct_type);
- return ret;
-}
-
-static
-enum bt_component_status print_array_field(struct text_component *text,
- struct bt_ctf_field *array, uint64_t i,
- bool is_string, bool print_names)
-{
- enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
- struct bt_ctf_field *field = NULL;
-
- if (!is_string) {
- if (i != 0) {
- fprintf(text->out, ", ");
- } else {
- fprintf(text->out, " ");
- }
- if (print_names) {
- fprintf(text->out, "[%" PRIu64 "] = ", i);
- }
- }
- field = bt_ctf_field_array_get_field(array, i);
- if (!field) {
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
- ret = print_field(text, field, print_names, NULL, 0);
-end:
- bt_put(field);
- return ret;
-}
-
-static
-enum bt_component_status print_array(struct text_component *text,
- struct bt_ctf_field *array, bool print_names)
-{
- enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
- struct bt_ctf_field_type *array_type = NULL, *field_type = NULL;
- enum bt_ctf_field_type_id type_id;
- int64_t len;
- uint64_t i;
- bool is_string = false;
-
- array_type = bt_ctf_field_get_type(array);
- if (!array_type) {
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
- field_type = bt_ctf_field_type_array_get_element_type(array_type);
- if (!field_type) {
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
- len = bt_ctf_field_type_array_get_length(array_type);
- if (len < 0) {
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
- type_id = bt_ctf_field_type_get_type_id(field_type);
- if (type_id == BT_CTF_FIELD_TYPE_ID_INTEGER) {
- enum bt_ctf_string_encoding encoding;
-
- encoding = bt_ctf_field_type_integer_get_encoding(field_type);
- if (encoding == BT_CTF_STRING_ENCODING_UTF8
- || encoding == BT_CTF_STRING_ENCODING_ASCII) {
- int integer_len, integer_alignment;
-
- integer_len = bt_ctf_field_type_integer_get_size(field_type);
- if (integer_len < 0) {
- return BT_COMPONENT_STATUS_ERROR;
- }
- integer_alignment = bt_ctf_field_type_get_alignment(field_type);
- if (integer_alignment < 0) {
- return BT_COMPONENT_STATUS_ERROR;
- }
- if (integer_len == CHAR_BIT
- && integer_alignment == CHAR_BIT) {
- is_string = true;
- }
- }
- }
-
- if (is_string) {
- g_string_assign(text->string, "");
- } else {
- fprintf(text->out, "[");
- }
-
- text->depth++;
- for (i = 0; i < len; i++) {
- ret = print_array_field(text, array, i, is_string, print_names);
- if (ret != BT_COMPONENT_STATUS_OK) {
- goto end;
- }
- }
- text->depth--;
-
- if (is_string) {
- if (text->use_colors) {
- fputs(COLOR_STRING_VALUE, text->out);
- }
- print_escape_string(text, text->string->str);
- if (text->use_colors) {
- fputs(COLOR_RST, text->out);
- }
- } else {
- fprintf(text->out, " ]");
- }
-end:
- bt_put(field_type);
- bt_put(array_type);
- return ret;
-}
-
-static
-enum bt_component_status print_sequence_field(struct text_component *text,
- struct bt_ctf_field *seq, uint64_t i,
- bool is_string, bool print_names)
-{
- enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
- struct bt_ctf_field *field = NULL;
-
- if (!is_string) {
- if (i != 0) {
- fprintf(text->out, ", ");
- } else {
- fprintf(text->out, " ");
- }
- if (print_names) {
- fprintf(text->out, "[%" PRIu64 "] = ", i);
- }
- }
- field = bt_ctf_field_sequence_get_field(seq, i);
- if (!field) {
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
- ret = print_field(text, field, print_names, NULL, 0);
-end:
- bt_put(field);
- return ret;
-}
-
-static
-enum bt_component_status print_sequence(struct text_component *text,
- struct bt_ctf_field *seq, bool print_names)
-{
- enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
- struct bt_ctf_field_type *seq_type = NULL, *field_type = NULL;
- struct bt_ctf_field *length_field = NULL;
- enum bt_ctf_field_type_id type_id;
- uint64_t len;
- uint64_t i;
- bool is_string = false;
-
- seq_type = bt_ctf_field_get_type(seq);
- if (!seq_type) {
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
- length_field = bt_ctf_field_sequence_get_length(seq);
- if (!length_field) {
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
- if (bt_ctf_field_unsigned_integer_get_value(length_field, &len) < 0) {
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
- field_type = bt_ctf_field_type_sequence_get_element_type(seq_type);
- if (!field_type) {
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
- type_id = bt_ctf_field_type_get_type_id(field_type);
- if (type_id == BT_CTF_FIELD_TYPE_ID_INTEGER) {
- enum bt_ctf_string_encoding encoding;
-
- encoding = bt_ctf_field_type_integer_get_encoding(field_type);
- if (encoding == BT_CTF_STRING_ENCODING_UTF8
- || encoding == BT_CTF_STRING_ENCODING_ASCII) {
- int integer_len, integer_alignment;
-
- integer_len = bt_ctf_field_type_integer_get_size(field_type);
- if (integer_len < 0) {
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
- integer_alignment = bt_ctf_field_type_get_alignment(field_type);
- if (integer_alignment < 0) {
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
- if (integer_len == CHAR_BIT
- && integer_alignment == CHAR_BIT) {
- is_string = true;
- }
- }
- }
-
- if (is_string) {
- g_string_assign(text->string, "");
- } else {
- fprintf(text->out, "[");
- }
-
- text->depth++;
- for (i = 0; i < len; i++) {
- ret = print_sequence_field(text, seq, i,
- is_string, print_names);
- if (ret != BT_COMPONENT_STATUS_OK) {
- goto end;
- }
- }
- text->depth--;
-
- if (is_string) {
- if (text->use_colors) {
- fputs(COLOR_STRING_VALUE, text->out);
- }
- print_escape_string(text, text->string->str);
- if (text->use_colors) {
- fputs(COLOR_RST, text->out);
- }
- } else {
- fprintf(text->out, " ]");
- }
-end:
- bt_put(length_field);
- bt_put(field_type);
- bt_put(seq_type);
- return ret;
-}
-
-static
-enum bt_component_status print_variant(struct text_component *text,
- struct bt_ctf_field *variant, bool print_names)
-{
- enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
- struct bt_ctf_field *field = NULL;
-
- field = bt_ctf_field_variant_get_current_field(variant);
- if (!field) {
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
- fprintf(text->out, "{ ");
- text->depth++;
- if (print_names) {
- int iter_ret;
- struct bt_ctf_field *tag_field = NULL;
- const char *tag_choice;
- struct bt_ctf_field_type_enumeration_mapping_iterator *iter;
-
- tag_field = bt_ctf_field_variant_get_tag(variant);
- if (!tag_field) {
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
-
- iter = bt_ctf_field_enumeration_get_mappings(tag_field);
- if (!iter) {
- bt_put(tag_field);
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
-
- iter_ret =
- bt_ctf_field_type_enumeration_mapping_iterator_get_signed(
- iter, &tag_choice, NULL, NULL);
- if (iter_ret) {
- bt_put(iter);
- bt_put(tag_field);
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
- print_field_name_equal(text, rem_(tag_choice));
- bt_put(tag_field);
- bt_put(iter);
- }
- ret = print_field(text, field, print_names, NULL, 0);
- if (ret != BT_COMPONENT_STATUS_OK) {
- goto end;
- }
- text->depth--;
- fprintf(text->out, " }");
-end:
- bt_put(field);
- return ret;
-}
-
-static
-enum bt_component_status print_field(struct text_component *text,
- struct bt_ctf_field *field, bool print_names,
- GQuark *filter_fields, int filter_array_len)
-{
- enum bt_ctf_field_type_id type_id;
-
- type_id = bt_ctf_field_get_type_id(field);
- switch (type_id) {
- case CTF_TYPE_INTEGER:
- return print_integer(text, field);
- case CTF_TYPE_FLOAT:
- {
- double v;
-
- if (bt_ctf_field_floating_point_get_value(field, &v)) {
- return BT_COMPONENT_STATUS_ERROR;
- }
- if (text->use_colors) {
- fputs(COLOR_NUMBER_VALUE, text->out);
- }
- fprintf(text->out, "%g", v);
- if (text->use_colors) {
- fputs(COLOR_RST, text->out);
- }
- return BT_COMPONENT_STATUS_OK;
- }
- case CTF_TYPE_ENUM:
- return print_enum(text, field);
- case CTF_TYPE_STRING:
- if (text->use_colors) {
- fputs(COLOR_STRING_VALUE, text->out);
- }
- print_escape_string(text, bt_ctf_field_string_get_value(field));
- if (text->use_colors) {
- fputs(COLOR_RST, text->out);
- }
- return BT_COMPONENT_STATUS_OK;
- case CTF_TYPE_STRUCT:
- return print_struct(text, field, print_names, filter_fields,
- filter_array_len);
- case CTF_TYPE_UNTAGGED_VARIANT:
- case CTF_TYPE_VARIANT:
- return print_variant(text, field, print_names);
- case CTF_TYPE_ARRAY:
- return print_array(text, field, print_names);
- case CTF_TYPE_SEQUENCE:
- return print_sequence(text, field, print_names);
- default:
- fprintf(text->err, "[error] Unknown type id: %d\n", (int) type_id);
- return BT_COMPONENT_STATUS_ERROR;
- }
-}
-
-static
-enum bt_component_status print_stream_packet_context(struct text_component *text,
- struct bt_ctf_event *event)
-{
- enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
- struct bt_ctf_packet *packet = NULL;
- struct bt_ctf_field *main_field = NULL;
-
- packet = bt_ctf_event_get_packet(event);
- if (!packet) {
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
- main_field = bt_ctf_packet_get_context(packet);
- if (!main_field) {
- goto end;
- }
- if (!text->start_line) {
- fputs(", ", text->out);
- }
- text->start_line = false;
- if (text->options.print_scope_field_names) {
- print_name_equal(text, "stream.packet.context");
- }
- ret = print_field(text, main_field,
- text->options.print_context_field_names,
- stream_packet_context_quarks,
- STREAM_PACKET_CONTEXT_QUARKS_LEN);
-end:
- bt_put(main_field);
- bt_put(packet);
- return ret;
-}
-
-static
-enum bt_component_status print_event_header_raw(struct text_component *text,
- struct bt_ctf_event *event)
-{
- enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
- struct bt_ctf_field *main_field = NULL;
-
- main_field = bt_ctf_event_get_header(event);
- if (!main_field) {
- goto end;
- }
- if (!text->start_line) {
- fputs(", ", text->out);
- }
- text->start_line = false;
- if (text->options.print_scope_field_names) {
- print_name_equal(text, "stream.event.header");
- }
- ret = print_field(text, main_field,
- text->options.print_header_field_names, NULL, 0);
-end:
- bt_put(main_field);
- return ret;
-}
-
-static
-enum bt_component_status print_stream_event_context(struct text_component *text,
- struct bt_ctf_event *event)
-{
- enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
- struct bt_ctf_field *main_field = NULL;
-
- main_field = bt_ctf_event_get_stream_event_context(event);
- if (!main_field) {
- goto end;
- }
- if (!text->start_line) {
- fputs(", ", text->out);
- }
- text->start_line = false;
- if (text->options.print_scope_field_names) {
- print_name_equal(text, "stream.event.context");
- }
- ret = print_field(text, main_field,
- text->options.print_context_field_names, NULL, 0);
-end:
- bt_put(main_field);
- return ret;
-}
-
-static
-enum bt_component_status print_event_context(struct text_component *text,
- struct bt_ctf_event *event)
-{
- enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
- struct bt_ctf_field *main_field = NULL;
-
- main_field = bt_ctf_event_get_event_context(event);
- if (!main_field) {
- goto end;
- }
- if (!text->start_line) {
- fputs(", ", text->out);
- }
- text->start_line = false;
- if (text->options.print_scope_field_names) {
- print_name_equal(text, "event.context");
- }
- ret = print_field(text, main_field,
- text->options.print_context_field_names, NULL, 0);
-end:
- bt_put(main_field);
- return ret;
-}
-
-static
-enum bt_component_status print_event_payload(struct text_component *text,
- struct bt_ctf_event *event)
-{
- enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
- struct bt_ctf_field *main_field = NULL;
-
- main_field = bt_ctf_event_get_payload_field(event);
- if (!main_field) {
- goto end;
- }
- if (!text->start_line) {
- fputs(", ", text->out);
- }
- text->start_line = false;
- if (text->options.print_scope_field_names) {
- print_name_equal(text, "event.fields");
- }
- ret = print_field(text, main_field,
- text->options.print_payload_field_names, NULL, 0);
-end:
- bt_put(main_field);
- return ret;
-}
-
-BT_HIDDEN
-enum bt_component_status text_print_event(struct text_component *text,
- struct bt_ctf_event *event)
-{
- enum bt_component_status ret;
-
- text->start_line = true;
- ret = print_event_header(text, event);
- if (ret != BT_COMPONENT_STATUS_OK) {
- goto end;
- }
-
- ret = print_stream_packet_context(text, event);
- if (ret != BT_COMPONENT_STATUS_OK) {
- goto end;
- }
-
- if (text->options.verbose) {
- ret = print_event_header_raw(text, event);
- if (ret != BT_COMPONENT_STATUS_OK) {
- goto end;
- }
- }
-
- ret = print_stream_event_context(text, event);
- if (ret != BT_COMPONENT_STATUS_OK) {
- goto end;
- }
-
- ret = print_event_context(text, event);
- if (ret != BT_COMPONENT_STATUS_OK) {
- goto end;
- }
-
- ret = print_event_payload(text, event);
- if (ret != BT_COMPONENT_STATUS_OK) {
- goto end;
- }
-
- fputc('\n', text->out);
-end:
- return ret;
-}
+++ /dev/null
-/*
- * text.c
- *
- * Babeltrace CTF Text Output Plugin
- *
- * Copyright 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- * Copyright 2016 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * 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.
- *
- * 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.
- */
-
-#include <babeltrace/plugin/plugin-dev.h>
-#include <babeltrace/graph/component.h>
-#include <babeltrace/graph/private-component.h>
-#include <babeltrace/graph/component-sink.h>
-#include <babeltrace/graph/port.h>
-#include <babeltrace/graph/private-port.h>
-#include <babeltrace/graph/connection.h>
-#include <babeltrace/graph/private-connection.h>
-#include <babeltrace/graph/notification.h>
-#include <babeltrace/graph/notification-iterator.h>
-#include <babeltrace/graph/notification-event.h>
-#include <babeltrace/values.h>
-#include <babeltrace/compiler-internal.h>
-#include <babeltrace/common-internal.h>
-#include <plugins-common.h>
-#include <stdio.h>
-#include <stdbool.h>
-#include <glib.h>
-#include "text.h"
-#include <assert.h>
-
-static
-const char *plugin_options[] = {
- "color",
- "output-path",
- "debug-info-dir",
- "debug-info-target-prefix",
- "debug-info-full-path",
- "no-delta",
- "clock-cycles",
- "clock-seconds",
- "clock-date",
- "clock-gmt",
- "verbose",
- "name-default", /* show/hide */
- "name-payload",
- "name-context",
- "name-scope",
- "name-header",
- "field-default", /* show/hide */
- "field-trace",
- "field-trace:hostname",
- "field-trace:domain",
- "field-trace:procname",
- "field-trace:vpid",
- "field-loglevel",
- "field-emf",
- "field-callsite",
-};
-
-static
-void destroy_text_data(struct text_component *text)
-{
- bt_put(text->input_iterator);
- (void) g_string_free(text->string, TRUE);
- if (text->out != stdout) {
- int ret;
-
- ret = fclose(text->out);
- if (ret) {
- perror("close output file");
- }
- }
- g_free(text->options.output_path);
- g_free(text->options.debug_info_dir);
- g_free(text->options.debug_info_target_prefix);
- g_free(text);
-}
-
-static
-struct text_component *create_text(void)
-{
- struct text_component *text;
-
- text = g_new0(struct text_component, 1);
- if (!text) {
- goto end;
- }
- text->string = g_string_new("");
- if (!text->string) {
- goto error;
- }
-end:
- return text;
-
-error:
- g_free(text);
- return NULL;
-}
-
-static
-void finalize_text(struct bt_private_component *component)
-{
- void *data = bt_private_component_get_user_data(component);
-
- destroy_text_data(data);
-}
-
-static
-enum bt_component_status handle_notification(struct text_component *text,
- struct bt_notification *notification)
-{
- enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
-
- if (!text) {
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
-
- switch (bt_notification_get_type(notification)) {
- case BT_NOTIFICATION_TYPE_PACKET_BEGIN:
- break;
- case BT_NOTIFICATION_TYPE_PACKET_END:
- break;
- case BT_NOTIFICATION_TYPE_EVENT:
- {
- struct bt_ctf_event *event = bt_notification_event_get_event(
- notification);
-
- if (!event) {
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
- ret = text_print_event(text, event);
- bt_put(event);
- if (ret != BT_COMPONENT_STATUS_OK) {
- goto end;
- }
- break;
- }
- case BT_NOTIFICATION_TYPE_STREAM_END:
- break;
- default:
- puts("Unhandled notification type");
- }
-end:
- return ret;
-}
-
-static
-enum bt_component_status text_accept_port_connection(
- struct bt_private_component *component,
- struct bt_private_port *self_port,
- struct bt_port *other_port)
-{
- enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
- struct bt_private_connection *connection;
- struct text_component *text;
-
- text = bt_private_component_get_user_data(component);
- assert(text);
- assert(!text->input_iterator);
- connection = bt_private_port_get_private_connection(self_port);
- assert(connection);
- text->input_iterator =
- bt_private_connection_create_notification_iterator(connection);
-
- if (!text->input_iterator) {
- ret = BT_COMPONENT_STATUS_ERROR;
- }
-
- bt_put(connection);
- return ret;
-}
-
-static
-enum bt_component_status run(struct bt_private_component *component)
-{
- enum bt_component_status ret;
- struct bt_notification *notification = NULL;
- struct bt_notification_iterator *it;
- struct text_component *text =
- bt_private_component_get_user_data(component);
- enum bt_notification_iterator_status it_ret;
-
- it = text->input_iterator;
-
- it_ret = bt_notification_iterator_next(it);
- switch (it_ret) {
- case BT_NOTIFICATION_ITERATOR_STATUS_ERROR:
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- case BT_NOTIFICATION_ITERATOR_STATUS_END:
- ret = BT_COMPONENT_STATUS_END;
- BT_PUT(text->input_iterator);
- goto end;
- default:
- break;
- }
-
- notification = bt_notification_iterator_get_notification(it);
- assert(notification);
- ret = handle_notification(text, notification);
- text->processed_first_event = true;
-end:
- bt_put(notification);
- return ret;
-}
-
-static
-enum bt_component_status add_params_to_map(struct bt_value *plugin_opt_map)
-{
- enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
- unsigned int i;
-
- for (i = 0; i < BT_ARRAY_SIZE(plugin_options); i++) {
- const char *key = plugin_options[i];
- enum bt_value_status status;
-
- status = bt_value_map_insert(plugin_opt_map, key, bt_value_null);
- switch (status) {
- case BT_VALUE_STATUS_OK:
- break;
- default:
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
- }
-end:
- return ret;
-}
-
-static
-bool check_param_exists(const char *key, struct bt_value *object, void *data)
-{
- struct text_component *text = data;
- struct bt_value *plugin_opt_map = text->plugin_opt_map;
-
- if (!bt_value_map_get(plugin_opt_map, key)) {
- fprintf(text->err,
- "[warning] Parameter \"%s\" unknown to \"text\" plugin\n", key);
- }
- return true;
-}
-
-static
-enum bt_component_status apply_one_string(const char *key,
- struct bt_value *params,
- char **option)
-{
- enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
- struct bt_value *value = NULL;
- enum bt_value_status status;
- const char *str;
-
- value = bt_value_map_get(params, key);
- if (!value) {
- goto end;
- }
- if (bt_value_is_null(value)) {
- goto end;
- }
- status = bt_value_string_get(value, &str);
- switch (status) {
- case BT_VALUE_STATUS_OK:
- break;
- default:
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
- *option = g_strdup(str);
-end:
- bt_put(value);
- return ret;
-}
-
-static
-enum bt_component_status apply_one_bool(const char *key,
- struct bt_value *params,
- bool *option,
- bool *found)
-{
- enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
- struct bt_value *value = NULL;
- enum bt_value_status status;
-
- value = bt_value_map_get(params, key);
- if (!value) {
- goto end;
- }
- status = bt_value_bool_get(value, option);
- switch (status) {
- case BT_VALUE_STATUS_OK:
- break;
- default:
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
- if (found) {
- *found = true;
- }
-end:
- bt_put(value);
- return ret;
-}
-
-static
-void warn_wrong_color_param(struct text_component *text)
-{
- fprintf(text->err,
- "[warning] Accepted values for the \"color\" parameter are:\n \"always\", \"auto\", \"never\"\n");
-}
-
-static
-enum bt_component_status open_output_file(struct text_component *text)
-{
- enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
-
- if (!text->options.output_path) {
- goto end;
- }
-
- text->out = fopen(text->options.output_path, "w");
- if (!text->out) {
- goto error;
- }
-
- goto end;
-
-error:
- ret = BT_COMPONENT_STATUS_ERROR;
-end:
- return ret;
-}
-
-static
-enum bt_component_status apply_params(struct text_component *text,
- struct bt_value *params)
-{
- enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
- enum bt_value_status status;
- bool value, found;
- char *str = NULL;
-
- text->plugin_opt_map = bt_value_map_create();
- if (!text->plugin_opt_map) {
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
- ret = add_params_to_map(text->plugin_opt_map);
- if (ret != BT_COMPONENT_STATUS_OK) {
- goto end;
- }
- /* Report unknown parameters. */
- status = bt_value_map_foreach(params, check_param_exists, text);
- switch (status) {
- case BT_VALUE_STATUS_OK:
- break;
- default:
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
- /* Known parameters. */
- text->options.color = TEXT_COLOR_OPT_AUTO;
- if (bt_value_map_has_key(params, "color")) {
- struct bt_value *color_value;
- const char *color;
-
- color_value = bt_value_map_get(params, "color");
- if (!color_value) {
- goto end;
- }
-
- status = bt_value_string_get(color_value, &color);
- if (status) {
- warn_wrong_color_param(text);
- } else {
- if (strcmp(color, "never") == 0) {
- text->options.color = TEXT_COLOR_OPT_NEVER;
- } else if (strcmp(color, "auto") == 0) {
- text->options.color = TEXT_COLOR_OPT_AUTO;
- } else if (strcmp(color, "always") == 0) {
- text->options.color = TEXT_COLOR_OPT_ALWAYS;
- } else {
- warn_wrong_color_param(text);
- }
- }
-
- bt_put(color_value);
- }
-
- ret = apply_one_string("output-path",
- params,
- &text->options.output_path);
- if (ret != BT_COMPONENT_STATUS_OK) {
- goto end;
- }
- ret = open_output_file(text);
- if (ret != BT_COMPONENT_STATUS_OK) {
- goto end;
- }
-
- ret = apply_one_string("debug-info-dir",
- params,
- &text->options.debug_info_dir);
- if (ret != BT_COMPONENT_STATUS_OK) {
- goto end;
- }
-
- ret = apply_one_string("debug-info-target-prefix",
- params,
- &text->options.debug_info_target_prefix);
- if (ret != BT_COMPONENT_STATUS_OK) {
- goto end;
- }
-
- value = false; /* Default. */
- ret = apply_one_bool("debug-info-full-path", params, &value, NULL);
- if (ret != BT_COMPONENT_STATUS_OK) {
- goto end;
- }
- text->options.debug_info_full_path = value;
-
- value = false; /* Default. */
- ret = apply_one_bool("no-delta", params, &value, NULL);
- if (ret != BT_COMPONENT_STATUS_OK) {
- goto end;
- }
- text->options.print_delta_field = !value; /* Reverse logic. */
-
- value = false; /* Default. */
- ret = apply_one_bool("clock-cycles", params, &value, NULL);
- if (ret != BT_COMPONENT_STATUS_OK) {
- goto end;
- }
- text->options.print_timestamp_cycles = value;
-
- value = false; /* Default. */
- ret = apply_one_bool("clock-seconds", params, &value, NULL);
- if (ret != BT_COMPONENT_STATUS_OK) {
- goto end;
- }
- text->options.clock_seconds = value;
-
- value = false; /* Default. */
- ret = apply_one_bool("clock-date", params, &value, NULL);
- if (ret != BT_COMPONENT_STATUS_OK) {
- goto end;
- }
- text->options.clock_date = value;
-
- value = false; /* Default. */
- ret = apply_one_bool("clock-gmt", params, &value, NULL);
- if (ret != BT_COMPONENT_STATUS_OK) {
- goto end;
- }
- text->options.clock_gmt = value;
-
- value = false; /* Default. */
- ret = apply_one_bool("verbose", params, &value, NULL);
- if (ret != BT_COMPONENT_STATUS_OK) {
- goto end;
- }
- text->options.verbose = value;
-
- /* Names. */
- ret = apply_one_string("name-default", params, &str);
- if (ret != BT_COMPONENT_STATUS_OK) {
- goto end;
- }
- if (!str) {
- text->options.name_default = TEXT_DEFAULT_UNSET;
- } else if (!strcmp(str, "show")) {
- text->options.name_default = TEXT_DEFAULT_SHOW;
- } else if (!strcmp(str, "hide")) {
- text->options.name_default = TEXT_DEFAULT_HIDE;
- } else {
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
- g_free(str);
- str = NULL;
-
- switch (text->options.name_default) {
- case TEXT_DEFAULT_UNSET:
- text->options.print_payload_field_names = true;
- text->options.print_context_field_names = true;
- text->options.print_header_field_names = false;
- text->options.print_scope_field_names = false;
- break;
- case TEXT_DEFAULT_SHOW:
- text->options.print_payload_field_names = true;
- text->options.print_context_field_names = true;
- text->options.print_header_field_names = true;
- text->options.print_scope_field_names = true;
- break;
- case TEXT_DEFAULT_HIDE:
- text->options.print_payload_field_names = false;
- text->options.print_context_field_names = false;
- text->options.print_header_field_names = false;
- text->options.print_scope_field_names = false;
- break;
- default:
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
-
- value = false;
- found = false;
- ret = apply_one_bool("name-payload", params, &value, &found);
- if (ret != BT_COMPONENT_STATUS_OK) {
- goto end;
- }
- if (found) {
- text->options.print_payload_field_names = value;
- }
-
- value = false;
- found = false;
- ret = apply_one_bool("name-context", params, &value, &found);
- if (ret != BT_COMPONENT_STATUS_OK) {
- goto end;
- }
- if (found) {
- text->options.print_context_field_names = value;
- }
-
- value = false;
- found = false;
- ret = apply_one_bool("name-header", params, &value, &found);
- if (ret != BT_COMPONENT_STATUS_OK) {
- goto end;
- }
- if (found) {
- text->options.print_header_field_names = value;
- }
-
- value = false;
- found = false;
- ret = apply_one_bool("name-scope", params, &value, &found);
- if (ret != BT_COMPONENT_STATUS_OK) {
- goto end;
- }
- if (found) {
- text->options.print_scope_field_names = value;
- }
-
- /* Fields. */
- ret = apply_one_string("field-default", params, &str);
- if (ret != BT_COMPONENT_STATUS_OK) {
- goto end;
- }
- if (!str) {
- text->options.field_default = TEXT_DEFAULT_UNSET;
- } else if (!strcmp(str, "show")) {
- text->options.field_default = TEXT_DEFAULT_SHOW;
- } else if (!strcmp(str, "hide")) {
- text->options.field_default = TEXT_DEFAULT_HIDE;
- } else {
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
- g_free(str);
- str = NULL;
-
- switch (text->options.field_default) {
- case TEXT_DEFAULT_UNSET:
- text->options.print_trace_field = false;
- text->options.print_trace_hostname_field = true;
- text->options.print_trace_domain_field = false;
- text->options.print_trace_procname_field = true;
- text->options.print_trace_vpid_field = true;
- text->options.print_loglevel_field = false;
- text->options.print_emf_field = false;
- text->options.print_callsite_field = false;
- break;
- case TEXT_DEFAULT_SHOW:
- text->options.print_trace_field = true;
- text->options.print_trace_hostname_field = true;
- text->options.print_trace_domain_field = true;
- text->options.print_trace_procname_field = true;
- text->options.print_trace_vpid_field = true;
- text->options.print_loglevel_field = true;
- text->options.print_emf_field = true;
- text->options.print_callsite_field = true;
- break;
- case TEXT_DEFAULT_HIDE:
- text->options.print_trace_field = false;
- text->options.print_trace_hostname_field = false;
- text->options.print_trace_domain_field = false;
- text->options.print_trace_procname_field = false;
- text->options.print_trace_vpid_field = false;
- text->options.print_loglevel_field = false;
- text->options.print_emf_field = false;
- text->options.print_callsite_field = false;
- break;
- default:
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
-
- value = false;
- found = false;
- ret = apply_one_bool("field-trace", params, &value, &found);
- if (ret != BT_COMPONENT_STATUS_OK) {
- goto end;
- }
- if (found) {
- text->options.print_trace_field = value;
- }
-
- value = false;
- found = false;
- ret = apply_one_bool("field-trace:hostname", params, &value, &found);
- if (ret != BT_COMPONENT_STATUS_OK) {
- goto end;
- }
- if (found) {
- text->options.print_trace_hostname_field = value;
- }
-
- value = false;
- found = false;
- ret = apply_one_bool("field-trace:domain", params, &value, &found);
- if (ret != BT_COMPONENT_STATUS_OK) {
- goto end;
- }
- if (found) {
- text->options.print_trace_domain_field = value;
- }
-
- value = false;
- found = false;
- ret = apply_one_bool("field-trace:procname", params, &value, &found);
- if (ret != BT_COMPONENT_STATUS_OK) {
- goto end;
- }
- if (found) {
- text->options.print_trace_procname_field = value;
- }
-
- value = false;
- found = false;
- ret = apply_one_bool("field-trace:vpid", params, &value, &found);
- if (ret != BT_COMPONENT_STATUS_OK) {
- goto end;
- }
- if (found) {
- text->options.print_trace_vpid_field = value;
- }
-
- value = false;
- found = false;
- ret = apply_one_bool("field-loglevel", params, &value, &found);
- if (ret != BT_COMPONENT_STATUS_OK) {
- goto end;
- }
- if (found) {
- text->options.print_loglevel_field = value;
- }
-
- value = false;
- found = false;
- ret = apply_one_bool("field-emf", params, &value, &found);
- if (ret != BT_COMPONENT_STATUS_OK) {
- goto end;
- }
- if (found) {
- text->options.print_emf_field = value;
- }
-
- value = false;
- found = false;
- ret = apply_one_bool("field-callsite", params, &value, &found);
- if (ret != BT_COMPONENT_STATUS_OK) {
- goto end;
- }
- if (found) {
- text->options.print_callsite_field = value;
- }
-
-end:
- bt_put(text->plugin_opt_map);
- text->plugin_opt_map = NULL;
- g_free(str);
- return ret;
-}
-
-static
-void set_use_colors(struct text_component *text)
-{
- switch (text->options.color) {
- case TEXT_COLOR_OPT_ALWAYS:
- text->use_colors = true;
- break;
- case TEXT_COLOR_OPT_AUTO:
- text->use_colors = text->out == stdout &&
- bt_common_colors_supported();
- break;
- case TEXT_COLOR_OPT_NEVER:
- text->use_colors = false;
- break;
- }
-}
-
-static
-void init_stream_packet_context_quarks(void)
-{
- stream_packet_context_quarks[Q_TIMESTAMP_BEGIN] =
- g_quark_from_string("timestamp_begin");
- stream_packet_context_quarks[Q_TIMESTAMP_BEGIN] =
- g_quark_from_string("timestamp_begin");
- stream_packet_context_quarks[Q_TIMESTAMP_END] =
- g_quark_from_string("timestamp_end");
- stream_packet_context_quarks[Q_EVENTS_DISCARDED] =
- g_quark_from_string("events_discarded");
- stream_packet_context_quarks[Q_CONTENT_SIZE] =
- g_quark_from_string("content_size");
- stream_packet_context_quarks[Q_PACKET_SIZE] =
- g_quark_from_string("packet_size");
- stream_packet_context_quarks[Q_PACKET_SEQ_NUM] =
- g_quark_from_string("packet_seq_num");
-}
-
-static
-enum bt_component_status text_component_init(
- struct bt_private_component *component,
- struct bt_value *params,
- UNUSED_VAR void *init_method_data)
-{
- enum bt_component_status ret;
- struct text_component *text = create_text();
-
- if (!text) {
- ret = BT_COMPONENT_STATUS_NOMEM;
- goto end;
- }
-
- text->out = stdout;
- text->err = stderr;
-
- text->delta_cycles = -1ULL;
- text->last_cycles_timestamp = -1ULL;
-
- text->delta_real_timestamp = -1ULL;
- text->last_real_timestamp = -1ULL;
-
- ret = apply_params(text, params);
- if (ret != BT_COMPONENT_STATUS_OK) {
- goto error;
- }
-
- set_use_colors(text);
-
- ret = bt_private_component_set_user_data(component, text);
- if (ret != BT_COMPONENT_STATUS_OK) {
- goto error;
- }
-
- init_stream_packet_context_quarks();
-
-end:
- return ret;
-error:
- destroy_text_data(text);
- return ret;
-}
-
-/* Initialize plug-in entry points. */
-BT_PLUGIN(text);
-BT_PLUGIN_DESCRIPTION("Babeltrace text output plug-in.");
-BT_PLUGIN_AUTHOR("Jérémie Galarneau");
-BT_PLUGIN_LICENSE("MIT");
-BT_PLUGIN_SINK_COMPONENT_CLASS(text, run);
-BT_PLUGIN_SINK_COMPONENT_CLASS_INIT_METHOD(text, text_component_init);
-BT_PLUGIN_SINK_COMPONENT_CLASS_ACCEPT_PORT_CONNECTION_METHOD(text, text_accept_port_connection);
-BT_PLUGIN_SINK_COMPONENT_CLASS_FINALIZE_METHOD(text, finalize_text);
-BT_PLUGIN_SINK_COMPONENT_CLASS_DESCRIPTION(text,
- "Formats CTF-IR to text. Formerly known as ctf-text.");
+++ /dev/null
-#ifndef BABELTRACE_PLUGIN_TEXT_H
-#define BABELTRACE_PLUGIN_TEXT_H
-
-/*
- * BabelTrace - CTF Text Output Plug-in
- *
- * Copyright 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * 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.
- *
- * 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.
- */
-
-#include <stdbool.h>
-#include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/graph/component.h>
-
-enum text_default {
- TEXT_DEFAULT_UNSET,
- TEXT_DEFAULT_SHOW,
- TEXT_DEFAULT_HIDE,
-};
-
-enum text_color_option {
- TEXT_COLOR_OPT_NEVER,
- TEXT_COLOR_OPT_AUTO,
- TEXT_COLOR_OPT_ALWAYS,
-};
-
-struct text_options {
- char *output_path;
- char *debug_info_dir;
- char *debug_info_target_prefix;
-
- enum text_default name_default;
- enum text_default field_default;
-
- bool print_scope_field_names;
- bool print_header_field_names;
- bool print_context_field_names;
- bool print_payload_field_names;
-
- bool print_delta_field;
- bool print_loglevel_field;
- bool print_emf_field;
- bool print_callsite_field;
- bool print_trace_field;
- bool print_trace_domain_field;
- bool print_trace_procname_field;
- bool print_trace_vpid_field;
- bool print_trace_hostname_field;
-
- bool print_timestamp_cycles;
- bool clock_seconds;
- bool clock_date;
- bool clock_gmt;
- bool debug_info_full_path;
- enum text_color_option color;
- bool verbose;
-};
-
-struct text_component {
- struct text_options options;
- struct bt_notification_iterator *input_iterator;
- FILE *out, *err;
- bool processed_first_event; /* Should be per-iterator. */
- int depth; /* nesting, used for tabulation alignment. */
- bool start_line;
- GString *string;
- struct bt_value *plugin_opt_map; /* Temporary parameter map. */
- bool use_colors;
-
- uint64_t last_cycles_timestamp;
- uint64_t delta_cycles;
-
- uint64_t last_real_timestamp;
- uint64_t delta_real_timestamp;
-};
-
-enum stream_packet_context_quarks_enum {
- Q_TIMESTAMP_BEGIN,
- Q_TIMESTAMP_END,
- Q_EVENTS_DISCARDED,
- Q_CONTENT_SIZE,
- Q_PACKET_SIZE,
- Q_PACKET_SEQ_NUM,
- STREAM_PACKET_CONTEXT_QUARKS_LEN, /* Always the last one of this enum. */
-};
-
-GQuark stream_packet_context_quarks[STREAM_PACKET_CONTEXT_QUARKS_LEN];
-
-BT_HIDDEN
-enum bt_component_status text_print_event(struct text_component *text,
- struct bt_ctf_event *event);
-
-#endif /* BABELTRACE_PLUGIN_TEXT_H */