return g_scanner_new(&scanner_config);
}
+/*
+ * Inserts a string (if exists and not empty) or null to a map value
+ * object.
+ */
+static
+enum bt_value_status map_insert_string_or_null(struct bt_value *map,
+ const char *key, GString *string)
+{
+ enum bt_value_status ret;
+
+ if (string && string->len > 0) {
+ ret = bt_value_map_insert_string(map, key, string->str);
+ } else {
+ ret = bt_value_map_insert(map, key, bt_value_null);
+ }
+ return ret;
+}
+
/*
* Converts a comma-delimited list of known names (--names option) to
* an array value object containing those names as string value objects.
{
GScanner *scanner = NULL;
struct bt_value *names = NULL;
+ bool found_all = false, found_none = false, found_item = false;
names = bt_value_array_create();
if (!names) {
if (!strcmp(identifier, "payload") ||
!strcmp(identifier, "args") ||
!strcmp(identifier, "arg")) {
+ found_item = true;
if (bt_value_array_append_string(names,
"payload")) {
goto error;
}
} else if (!strcmp(identifier, "context") ||
!strcmp(identifier, "ctx")) {
+ found_item = true;
if (bt_value_array_append_string(names,
"context")) {
goto error;
}
} else if (!strcmp(identifier, "scope") ||
!strcmp(identifier, "header")) {
+ found_item = true;
if (bt_value_array_append_string(names,
identifier)) {
goto error;
}
- } else if (!strcmp(identifier, "all") ||
- !strcmp(identifier, "none")) {
- /*
- * "all" and "none" override all the
- * specific names.
- */
- BT_PUT(names);
- names = bt_value_array_create();
- if (!names) {
- print_err_oom();
+ } else if (!strcmp(identifier, "all")) {
+ found_all = true;
+ if (bt_value_array_append_string(names,
+ identifier)) {
goto error;
}
-
+ } else if (!strcmp(identifier, "none")) {
+ found_none = true;
if (bt_value_array_append_string(names,
identifier)) {
goto error;
}
- goto end;
} else {
printf_err("Unknown field name: \"%s\"\n",
identifier);
}
}
- goto end;
+end:
+ if (found_none && found_all) {
+ printf_err("Only either \"all\" or \"none\" can be specified in the list given to the \"--names\" option, but not both.\n");
+ goto error;
+ }
+ /*
+ * Legacy behavior is to clear the defaults (show none) when at
+ * least one item is specified.
+ */
+ if (found_item && !found_none && !found_all) {
+ if (bt_value_array_append_string(names, "none")) {
+ goto error;
+ }
+ }
+ if (scanner) {
+ g_scanner_destroy(scanner);
+ }
+ return names;
error:
BT_PUT(names);
-
-end:
if (scanner) {
g_scanner_destroy(scanner);
}
!strcmp(identifier, "trace:vpid") ||
!strcmp(identifier, "loglevel") ||
!strcmp(identifier, "emf") ||
- !strcmp(identifier, "callsite")) {
- if (bt_value_array_append_string(fields,
- identifier)) {
- goto error;
- }
- } else if (!strcmp(identifier, "all")) {
- /* "all" override all the specific fields */
- BT_PUT(fields);
- fields = bt_value_array_create();
- if (!fields) {
- print_err_oom();
- goto error;
- }
-
+ !strcmp(identifier, "callsite") ||
+ !strcmp(identifier, "all")) {
if (bt_value_array_append_string(fields,
identifier)) {
goto error;
}
- goto end;
} else {
printf_err("Unknown field name: \"%s\"\n",
identifier);
{
int ret = 0;
int i;
- GString *tmpstr = NULL;
+ GString *tmpstr = NULL, *default_value = NULL;
/*
* array_obj may be NULL if no CLI options were specified to
goto end;
}
+ default_value = g_string_new(NULL);
+ if (!default_value) {
+ print_err_oom();
+ ret = -1;
+ goto end;
+ }
+
for (i = 0; i < bt_value_array_size(array_obj); i++) {
struct bt_value *str_obj = bt_value_array_get(array_obj, i);
const char *suffix;
+ bool is_default = false;
if (!str_obj) {
printf_err("Unexpected error\n");
g_string_assign(tmpstr, prefix);
g_string_append(tmpstr, "-");
- g_string_append(tmpstr, suffix);
- ret = bt_value_map_insert_bool(map_obj, tmpstr->str, true);
- if (ret) {
- print_err_oom();
- goto end;
+
+ /* Special-case for "all" and "none". */
+ if (!strcmp(suffix, "all")) {
+ is_default = true;
+ g_string_assign(default_value, "show");
+ } else if (!strcmp(suffix, "none")) {
+ is_default = true;
+ g_string_assign(default_value, "hide");
+ }
+ if (is_default) {
+ g_string_append(tmpstr, "default");
+ ret = map_insert_string_or_null(map_obj,
+ tmpstr->str,
+ default_value);
+ if (ret) {
+ print_err_oom();
+ goto end;
+ }
+ } else {
+ g_string_append(tmpstr, suffix);
+ ret = bt_value_map_insert_bool(map_obj, tmpstr->str,
+ true);
+ if (ret) {
+ print_err_oom();
+ goto end;
+ }
}
}
end:
+ if (default_value) {
+ g_string_free(default_value, TRUE);
+ }
if (tmpstr) {
g_string_free(tmpstr, TRUE);
}
return ret;
}
-/*
- * Inserts a string (if exists and not empty) or null to a map value
- * object.
- */
-static
-enum bt_value_status map_insert_string_or_null(struct bt_value *map,
- const char *key, GString *string)
-{
- enum bt_value_status ret;
-
- if (string && string->len > 0) {
- ret = bt_value_map_insert_string(map, key, string->str);
- } else {
- ret = bt_value_map_insert(map, key, bt_value_null);
- }
- return ret;
-}
-
/*
* Returns the parameters (map value object) corresponding to the
* legacy text format options.
ret = BT_COMPONENT_STATUS_ERROR;
goto end;
}
+ if (!text->start_line) {
+ fputs(", ", text->out);
+ }
+ text->start_line = false;
ret = print_event_timestamp(text, event);
if (ret != BT_COMPONENT_STATUS_OK) {
goto end;
ret = BT_COMPONENT_STATUS_ERROR;
goto end;
}
+ if (!text->start_line) {
+ fputs(", ", text->out);
+ }
+ text->start_line = false;
if (text->options.print_scope_field_names) {
- fputs(" stream.packet.context = ", text->out);
+ fputs("stream.packet.context = ", text->out);
}
ret = print_field(text, main_field,
text->options.print_context_field_names);
ret = BT_COMPONENT_STATUS_ERROR;
goto end;
}
+ if (!text->start_line) {
+ fputs(", ", text->out);
+ }
+ text->start_line = false;
if (text->options.print_scope_field_names) {
- fputs(" stream.event.header = ", text->out);
+ fputs("stream.event.header = ", text->out);
}
ret = print_field(text, main_field,
- text->options.print_context_field_names);
+ text->options.print_header_field_names);
end:
bt_put(main_field);
return ret;
ret = BT_COMPONENT_STATUS_ERROR;
goto end;
}
+ if (!text->start_line) {
+ fputs(", ", text->out);
+ }
+ text->start_line = false;
if (text->options.print_scope_field_names) {
- fputs(" stream.event.context = ", text->out);
+ fputs("stream.event.context = ", text->out);
}
ret = print_field(text, main_field,
text->options.print_context_field_names);
ret = BT_COMPONENT_STATUS_ERROR;
goto end;
}
+ if (!text->start_line) {
+ fputs(", ", text->out);
+ }
+ text->start_line = false;
if (text->options.print_scope_field_names) {
- fputs(" event.context = ", text->out);
+ fputs("event.context = ", text->out);
}
ret = print_field(text, main_field,
text->options.print_context_field_names);
ret = BT_COMPONENT_STATUS_ERROR;
goto end;
}
+ if (!text->start_line) {
+ fputs(", ", text->out);
+ }
+ text->start_line = false;
if (text->options.print_scope_field_names) {
- fputs(" event.fields = ", text->out);
+ fputs("event.fields = ", text->out);
}
ret = print_field(text, main_field,
text->options.print_payload_field_names);
{
enum bt_component_status ret;
- //TEST XXX
- text->options.print_scope_field_names = true;
- text->options.print_payload_field_names = true;
- text->options.print_context_field_names = true;
-
+ text->start_line = true;
ret = print_event_header(text, event);
if (ret != BT_COMPONENT_STATUS_OK) {
goto end;
}
- fputs(",", text->out);
ret = print_stream_packet_context(text, event);
if (ret != BT_COMPONENT_STATUS_OK) {
goto end;
}
- fputs(",", text->out);
ret = print_event_header_raw(text, event);
if (ret != BT_COMPONENT_STATUS_OK) {
goto end;
}
- fputs(",", text->out);
ret = print_stream_event_context(text, event);
if (ret != BT_COMPONENT_STATUS_OK) {
goto end;
}
- fputs(",", text->out);
ret = print_event_context(text, event);
if (ret != BT_COMPONENT_STATUS_OK) {
goto end;
}
- fputs(",", text->out);
ret = print_event_payload(text, event);
if (ret != BT_COMPONENT_STATUS_OK) {
#include <babeltrace/plugin/notification/notification.h>
#include <babeltrace/plugin/notification/iterator.h>
#include <babeltrace/plugin/notification/event.h>
+#include <babeltrace/values.h>
+#include <babeltrace/compiler.h>
#include <stdio.h>
#include <stdbool.h>
#include <glib.h>
#include "text.h"
+#define PLUGIN_NAME "text"
+
+static
+const char *plugin_options[] = {
+ "output-path",
+ "debug-info-dir",
+ "debug-info-target-prefix",
+ "debug-info-full-path",
+ "no-delta",
+ "clock-cycles",
+ "clock-seconds",
+ "clock-date",
+ "clock-gmt",
+ "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
const char *loglevel_str [] = {
[LOGLEVEL_EMERG] = "TRACE_EMERG",
void destroy_text_data(struct text_component *text)
{
(void) g_string_free(text->string, TRUE);
+ 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
enum bt_component_status handle_notification(struct text_component *text,
- struct bt_notification *notification)
+ struct bt_notification *notification)
{
enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
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 \"%s\" plugin\n",
+ key, PLUGIN_NAME);
+ }
+ 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
+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. */
+ ret = apply_one_string("output-path",
+ params,
+ &text->options.output_path);
+ 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;
+
+ /* 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_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_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_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-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
enum bt_component_status text_component_init(
- struct bt_component *component, struct bt_value *params)
+ struct bt_component *component, struct bt_value *params)
{
enum bt_component_status ret;
struct text_component *text = create_text();
goto end;
}
+ text->out = stdout;
+ text->err = stderr;
+
+ ret = apply_params(text, params);
+ if (ret != BT_COMPONENT_STATUS_OK) {
+ goto error;
+ }
+
ret = bt_component_set_destroy_cb(component,
destroy_text);
if (ret != BT_COMPONENT_STATUS_OK) {
if (ret != BT_COMPONENT_STATUS_OK) {
goto error;
}
-
- text->out = stdout;
- text->err = stderr;
end:
return ret;
error:
BT_PLUGIN_LICENSE("MIT");
BT_PLUGIN_COMPONENT_CLASSES_BEGIN
-BT_PLUGIN_SINK_COMPONENT_CLASS_ENTRY("text",
+BT_PLUGIN_SINK_COMPONENT_CLASS_ENTRY(PLUGIN_NAME,
"Formats CTF-IR to text. Formerly known as ctf-text.",
text_component_init)
BT_PLUGIN_COMPONENT_CLASSES_END