X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=src%2Fplugins%2Ftext%2Fpretty%2Fpretty.c;h=510ed24e8c2df93e24d51469cd21b87362b99b57;hb=1353b066072e6c389ff35853bac83f65597e7a6a;hp=8cb3b472239e8211318a259da717c90fd1c76617;hpb=498e7994d60bd0e9f63c3d5c0fd00eec77ba7c34;p=babeltrace.git diff --git a/src/plugins/text/pretty/pretty.c b/src/plugins/text/pretty/pretty.c index 8cb3b472..510ed24e 100644 --- a/src/plugins/text/pretty/pretty.c +++ b/src/plugins/text/pretty/pretty.c @@ -1,30 +1,12 @@ /* + * SPDX-License-Identifier: MIT + * * Copyright 2016 Jérémie Galarneau * Copyright 2016 Mathieu Desnoyers - * - * Author: Jérémie Galarneau - * - * 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. */ -#define BT_COMP_LOG_SELF_COMP self_comp -#define BT_LOG_OUTPUT_LEVEL log_level +#define BT_COMP_LOG_SELF_COMP (pretty->self_comp) +#define BT_LOG_OUTPUT_LEVEL (pretty->log_level) #define BT_LOG_TAG "PLUGIN/SINK.TEXT.PRETTY" #include "logging/comp-logging.h" @@ -46,11 +28,12 @@ const char * const in_port_name = "in"; static void destroy_pretty_data(struct pretty_component *pretty) { + uint64_t i; if (!pretty) { goto end; } - bt_self_component_port_input_message_iterator_put_ref(pretty->iterator); + bt_message_iterator_put_ref(pretty->iterator); if (pretty->string) { (void) g_string_free(pretty->string, TRUE); @@ -68,6 +51,13 @@ void destroy_pretty_data(struct pretty_component *pretty) perror("close output file"); } } + + for (i = 0; i < ENUMERATION_MAX_BITFLAGS_COUNT; i++) { + if (pretty->enum_bit_labels[i]) { + g_ptr_array_free(pretty->enum_bit_labels[i], true); + } + } + g_free(pretty->options.output_path); g_free(pretty); @@ -100,7 +90,6 @@ error: return NULL; } -BT_HIDDEN void pretty_finalize(bt_self_component_sink *comp) { destroy_pretty_data( @@ -109,25 +98,29 @@ void pretty_finalize(bt_self_component_sink *comp) } static -bt_component_class_message_iterator_next_method_status handle_message( +bt_message_iterator_class_next_method_status handle_message( struct pretty_component *pretty, const bt_message *message) { - bt_component_class_message_iterator_next_method_status ret = - BT_COMPONENT_CLASS_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_OK; + bt_message_iterator_class_next_method_status ret = + BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_OK; BT_ASSERT_DBG(pretty); switch (bt_message_get_type(message)) { case BT_MESSAGE_TYPE_EVENT: if (pretty_print_event(pretty, message)) { - ret = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_ERROR; + BT_COMP_LOGE_APPEND_CAUSE(pretty->self_comp, + "Failed to print one event."); + ret = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_ERROR; } break; case BT_MESSAGE_TYPE_DISCARDED_EVENTS: case BT_MESSAGE_TYPE_DISCARDED_PACKETS: if (pretty_print_discarded_items(pretty, message)) { - ret = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_ERROR; + BT_COMP_LOGE_APPEND_CAUSE(pretty->self_comp, + "Failed to print discarded items."); + ret = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_ERROR; } break; default: @@ -137,23 +130,34 @@ bt_component_class_message_iterator_next_method_status handle_message( return ret; } -BT_HIDDEN bt_component_class_sink_graph_is_configured_method_status -pretty_graph_is_configured(bt_self_component_sink *comp) +pretty_graph_is_configured(bt_self_component_sink *self_comp_sink) { bt_component_class_sink_graph_is_configured_method_status status; - bt_self_component_port_input_message_iterator_create_from_sink_component_status + bt_message_iterator_create_from_sink_component_status msg_iter_status; struct pretty_component *pretty; + bt_self_component *self_comp = + bt_self_component_sink_as_self_component(self_comp_sink); + bt_self_component_port_input *in_port; - pretty = bt_self_component_get_data( - bt_self_component_sink_as_self_component(comp)); + pretty = bt_self_component_get_data(self_comp); BT_ASSERT(pretty); BT_ASSERT(!pretty->iterator); - msg_iter_status = bt_self_component_port_input_message_iterator_create_from_sink_component( - comp, bt_self_component_sink_borrow_input_port_by_name(comp, - in_port_name), &pretty->iterator); - if (msg_iter_status != BT_SELF_COMPONENT_PORT_INPUT_MESSAGE_ITERATOR_CREATE_FROM_SINK_COMPONENT_STATUS_OK) { + + in_port = bt_self_component_sink_borrow_input_port_by_name(self_comp_sink, + in_port_name); + if (!bt_port_is_connected(bt_port_input_as_port_const( + bt_self_component_port_input_as_port_input(in_port)))) { + BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Single input port is not connected: " + "port-name=\"%s\"", in_port_name); + status = BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_ERROR; + goto end; + } + + msg_iter_status = bt_message_iterator_create_from_sink_component( + self_comp_sink, in_port, &pretty->iterator); + if (msg_iter_status != BT_MESSAGE_ITERATOR_CREATE_FROM_SINK_COMPONENT_STATUS_OK) { status = (int) msg_iter_status; goto end; } @@ -164,14 +168,12 @@ end: return status; } -BT_HIDDEN bt_component_class_sink_consume_method_status pretty_consume( bt_self_component_sink *comp) { - bt_component_class_sink_consume_method_status ret = - BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_OK; + bt_component_class_sink_consume_method_status status; bt_message_array_const msgs; - bt_self_component_port_input_message_iterator *it; + bt_message_iterator *it; struct pretty_component *pretty = bt_self_component_get_data( bt_self_component_sink_as_self_component(comp)); bt_message_iterator_next_status next_status; @@ -179,43 +181,30 @@ bt_component_class_sink_consume_method_status pretty_consume( uint64_t i = 0; it = pretty->iterator; - next_status = bt_self_component_port_input_message_iterator_next(it, + next_status = bt_message_iterator_next(it, &msgs, &count); - - switch (next_status) { - case BT_MESSAGE_ITERATOR_NEXT_STATUS_OK: - break; - case BT_MESSAGE_ITERATOR_NEXT_STATUS_MEMORY_ERROR: - case BT_MESSAGE_ITERATOR_NEXT_STATUS_AGAIN: - ret = (int) next_status; - goto end; - case BT_MESSAGE_ITERATOR_NEXT_STATUS_END: - ret = (int) next_status; - BT_SELF_COMPONENT_PORT_INPUT_MESSAGE_ITERATOR_PUT_REF_AND_RESET( - pretty->iterator); - goto end; - default: - ret = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; + if (next_status != BT_MESSAGE_ITERATOR_NEXT_STATUS_OK) { + status = (int) next_status; goto end; } - BT_ASSERT_DBG(next_status == BT_MESSAGE_ITERATOR_NEXT_STATUS_OK); - for (i = 0; i < count; i++) { - ret = (int) handle_message(pretty, msgs[i]); - if (ret) { + status = (int) handle_message(pretty, msgs[i]); + if (status) { goto end; } bt_message_put_ref(msgs[i]); } + status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_OK; + end: for (; i < count; i++) { bt_message_put_ref(msgs[i]); } - return ret; + return status; } static @@ -296,6 +285,7 @@ end: static const char *color_choices[] = { "never", "auto", "always", NULL }; static const char *show_hide_choices[] = { "show", "hide", NULL }; +static struct bt_param_validation_map_value_entry_descr pretty_params[] = { { "color", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_OPTIONAL, { BT_VALUE_TYPE_STRING, .string = { .choices = color_choices, @@ -327,13 +317,13 @@ struct bt_param_validation_map_value_entry_descr pretty_params[] = { { "field-loglevel", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_OPTIONAL, { .type = BT_VALUE_TYPE_BOOL } }, { "field-emf", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_OPTIONAL, { .type = BT_VALUE_TYPE_BOOL } }, { "field-callsite", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_OPTIONAL, { .type = BT_VALUE_TYPE_BOOL } }, + { "print-enum-flags", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_OPTIONAL, { .type = BT_VALUE_TYPE_BOOL } }, BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_END }; static bt_component_class_initialize_method_status apply_params( - struct pretty_component *pretty, const bt_value *params, - bt_self_component *self_comp, bt_logging_level log_level) + struct pretty_component *pretty, const bt_value *params) { int ret; const bt_value *value; @@ -348,7 +338,7 @@ bt_component_class_initialize_method_status apply_params( goto end; } else if (validation_status == BT_PARAM_VALIDATION_STATUS_VALIDATION_ERROR) { status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_ERROR; - BT_COMP_LOGE_APPEND_CAUSE(self_comp, "%s", validate_error); + BT_COMP_LOGE_APPEND_CAUSE(pretty->self_comp, "%s", validate_error); goto end; } @@ -371,6 +361,8 @@ bt_component_class_initialize_method_status apply_params( apply_one_string("path", params, &pretty->options.output_path); ret = open_output_file(pretty); if (ret) { + BT_COMP_LOGE_APPEND_CAUSE(pretty->self_comp, + "Failed to open output file: %s", validate_error); status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_ERROR; goto end; } @@ -395,6 +387,9 @@ bt_component_class_initialize_method_status apply_params( apply_one_bool_with_default("verbose", params, &pretty->options.verbose, false); + apply_one_bool_with_default("print-enum-flags", params, + &pretty->options.print_enum_flags, false); + /* Names. */ value = bt_value_map_borrow_entry_value_const(params, "name-default"); if (value) { @@ -519,6 +514,7 @@ bt_component_class_initialize_method_status apply_params( apply_one_bool_if_specified("field-callsite", params, &pretty->options.print_callsite_field); + pretty_print_init(); status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK; end: @@ -544,7 +540,6 @@ void set_use_colors(struct pretty_component *pretty) } } -BT_HIDDEN bt_component_class_initialize_method_status pretty_init( bt_self_component_sink *self_comp_sink, bt_self_component_sink_configuration *config, @@ -560,10 +555,21 @@ bt_component_class_initialize_method_status pretty_init( bt_logging_level log_level = bt_component_get_logging_level(comp); if (!pretty) { + /* + * Don't use BT_COMP_LOGE_APPEND_CAUSE, as `pretty` is not + * initialized yet. + */ + BT_COMP_LOG_CUR_LVL(BT_LOG_ERROR, log_level, self_comp, + "Failed to allocate component."); + BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_COMPONENT( + self_comp, "Failed to allocate component."); status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_MEMORY_ERROR; goto error; } + pretty->self_comp = self_comp; + pretty->log_level = log_level; + add_port_status = bt_self_component_sink_add_input_port(self_comp_sink, in_port_name, NULL, NULL); if (add_port_status != BT_SELF_COMPONENT_ADD_PORT_STATUS_OK) { @@ -580,12 +586,24 @@ bt_component_class_initialize_method_status pretty_init( pretty->delta_real_timestamp = -1ULL; pretty->last_real_timestamp = -1ULL; - status = apply_params(pretty, params, self_comp, log_level); + status = apply_params(pretty, params); if (status != BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK) { goto error; } set_use_colors(pretty); + + if (pretty->options.print_enum_flags) { + uint64_t i; + /* + * Allocate all label arrays during the initialization of the + * component and reuse the same set of arrays for all + * enumerations. + */ + for (i = 0; i < ENUMERATION_MAX_BITFLAGS_COUNT; i++) { + pretty->enum_bit_labels[i] = g_ptr_array_new(); + } + } bt_self_component_set_data(self_comp, pretty); status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK;