4 * Babeltrace Trace Converter
6 * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation
8 * Author: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
10 * Permission is hereby granted, free of charge, to any person obtaining a copy
11 * of this software and associated documentation files (the "Software"), to deal
12 * in the Software without restriction, including without limitation the rights
13 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the Software is
15 * furnished to do so, subject to the following conditions:
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 #include <babeltrace/babeltrace.h>
30 #include <babeltrace/plugin/plugin.h>
31 #include <babeltrace/common-internal.h>
32 #include <babeltrace/component/component.h>
33 #include <babeltrace/component/component-source.h>
34 #include <babeltrace/component/component-sink.h>
35 #include <babeltrace/component/component-filter.h>
36 #include <babeltrace/component/component-class.h>
37 #include <babeltrace/component/port.h>
38 #include <babeltrace/component/graph.h>
39 #include <babeltrace/component/connection.h>
40 #include <babeltrace/component/notification/iterator.h>
41 #include <babeltrace/ref.h>
42 #include <babeltrace/values.h>
44 #include <babeltrace/ctf-ir/metadata.h> /* for clocks */
49 #include "babeltrace-cfg.h"
50 #include "babeltrace-cfg-connect.h"
51 #include "default-cfg.h"
53 GPtrArray
*loaded_plugins
;
56 void init_loaded_plugins_array(void)
58 loaded_plugins
= g_ptr_array_new_full(8, bt_put
);
62 void fini_loaded_plugins_array(void)
64 g_ptr_array_free(loaded_plugins
, TRUE
);
68 struct bt_plugin
*find_plugin(const char *name
)
71 struct bt_plugin
*plugin
= NULL
;
73 for (i
= 0; i
< loaded_plugins
->len
; i
++) {
74 plugin
= g_ptr_array_index(loaded_plugins
, i
);
76 if (strcmp(name
, bt_plugin_get_name(plugin
)) == 0) {
83 return bt_get(plugin
);
87 struct bt_component_class
*find_component_class(const char *plugin_name
,
88 const char *comp_class_name
,
89 enum bt_component_class_type comp_class_type
)
91 struct bt_component_class
*comp_class
= NULL
;
92 struct bt_plugin
*plugin
= find_plugin(plugin_name
);
98 comp_class
= bt_plugin_get_component_class_by_name_and_type(plugin
,
99 comp_class_name
, comp_class_type
);
106 void print_indent(size_t indent
)
110 for (i
= 0; i
< indent
; i
++) {
116 void print_value(struct bt_value
*, size_t);
119 void print_value_rec(struct bt_value
*, size_t);
122 bool print_map_value(const char *key
, struct bt_value
*object
, void *data
)
124 size_t *indent
= data
;
126 print_indent(*indent
);
129 if (bt_value_is_array(object
) &&
130 bt_value_array_is_empty(object
)) {
135 if (bt_value_is_map(object
) &&
136 bt_value_map_is_empty(object
)) {
141 if (bt_value_is_array(object
) ||
142 bt_value_is_map(object
)) {
146 print_value_rec(object
, *indent
+ 2);
151 void print_value_rec(struct bt_value
*value
, size_t indent
)
164 switch (bt_value_get_type(value
)) {
165 case BT_VALUE_TYPE_NULL
:
166 printf("%snull%s\n", bt_common_color_bold(),
167 bt_common_color_reset());
169 case BT_VALUE_TYPE_BOOL
:
170 bt_value_bool_get(value
, &bool_val
);
171 printf("%s%s%s%s\n", bt_common_color_bold(),
172 bt_common_color_fg_cyan(), bool_val
? "yes" : "no",
173 bt_common_color_reset());
175 case BT_VALUE_TYPE_INTEGER
:
176 bt_value_integer_get(value
, &int_val
);
177 printf("%s%s%" PRId64
"%s\n", bt_common_color_bold(),
178 bt_common_color_fg_red(), int_val
,
179 bt_common_color_reset());
181 case BT_VALUE_TYPE_FLOAT
:
182 bt_value_float_get(value
, &dbl_val
);
183 printf("%s%s%lf%s\n", bt_common_color_bold(),
184 bt_common_color_fg_red(), dbl_val
,
185 bt_common_color_reset());
187 case BT_VALUE_TYPE_STRING
:
188 bt_value_string_get(value
, &str_val
);
189 printf("%s%s%s%s\n", bt_common_color_bold(),
190 bt_common_color_fg_green(), str_val
,
191 bt_common_color_reset());
193 case BT_VALUE_TYPE_ARRAY
:
194 size
= bt_value_array_size(value
);
198 print_indent(indent
);
203 for (i
= 0; i
< size
; i
++) {
204 struct bt_value
*element
=
205 bt_value_array_get(value
, i
);
208 print_indent(indent
);
211 if (bt_value_is_array(element
) &&
212 bt_value_array_is_empty(element
)) {
217 if (bt_value_is_map(element
) &&
218 bt_value_map_is_empty(element
)) {
223 if (bt_value_is_array(element
) ||
224 bt_value_is_map(element
)) {
228 print_value_rec(element
, indent
+ 2);
232 case BT_VALUE_TYPE_MAP
:
233 if (bt_value_map_is_empty(value
)) {
234 print_indent(indent
);
239 bt_value_map_foreach(value
, print_map_value
, &indent
);
247 void print_value(struct bt_value
*value
, size_t indent
)
249 if (!bt_value_is_array(value
) && !bt_value_is_map(value
)) {
250 print_indent(indent
);
253 print_value_rec(value
, indent
);
257 void print_bt_config_component(struct bt_config_component
*bt_config_component
)
259 printf(" %s.%s:\n", bt_config_component
->plugin_name
->str
,
260 bt_config_component
->component_name
->str
);
262 if (bt_config_component
->instance_name
->len
> 0) {
263 printf(" Name: %s\n",
264 bt_config_component
->instance_name
->str
);
267 printf(" Parameters:\n");
268 print_value(bt_config_component
->params
, 8);
272 void print_bt_config_components(GPtrArray
*array
)
276 for (i
= 0; i
< array
->len
; i
++) {
277 struct bt_config_component
*cfg_component
=
278 bt_config_get_component(array
, i
);
279 print_bt_config_component(cfg_component
);
280 BT_PUT(cfg_component
);
285 void print_plugin_paths(struct bt_value
*plugin_paths
)
287 printf(" Plugin paths:\n");
288 print_value(plugin_paths
, 4);
292 void print_cfg_convert(struct bt_config
*cfg
)
296 printf(" Force correlate: %s\n",
297 cfg
->cmd_data
.convert
.force_correlate
? "yes" : "no");
298 print_plugin_paths(cfg
->cmd_data
.convert
.plugin_paths
);
299 printf(" Print CTF metadata: %s\n",
300 cfg
->cmd_data
.convert
.print_ctf_metadata
? "yes" : "no");
301 printf(" Source component instances:\n");
302 print_bt_config_components(cfg
->cmd_data
.convert
.sources
);
304 if (cfg
->cmd_data
.convert
.filters
->len
> 0) {
305 printf(" Filter component instances:\n");
306 print_bt_config_components(cfg
->cmd_data
.convert
.filters
);
309 printf(" Sink component instances:\n");
310 print_bt_config_components(cfg
->cmd_data
.convert
.sinks
);
311 printf(" Connections:\n");
313 for (i
= 0; i
< cfg
->cmd_data
.convert
.connections
->len
; i
++) {
314 struct bt_config_connection
*cfg_connection
=
315 g_ptr_array_index(cfg
->cmd_data
.convert
.connections
,
318 printf(" %s%s%s -> %s%s%s\n",
319 cfg_connection
->src_instance_name
->str
,
320 cfg_connection
->src_port_name
->len
> 0 ? "." : "",
321 cfg_connection
->src_port_name
->str
,
322 cfg_connection
->dst_instance_name
->str
,
323 cfg_connection
->dst_port_name
->len
> 0 ? "." : "",
324 cfg_connection
->dst_port_name
->str
);
329 void print_cfg_list_plugins(struct bt_config
*cfg
)
331 print_plugin_paths(cfg
->cmd_data
.list_plugins
.plugin_paths
);
335 void print_cfg_help(struct bt_config
*cfg
)
337 print_plugin_paths(cfg
->cmd_data
.help
.plugin_paths
);
341 void print_cfg_query(struct bt_config
*cfg
)
343 print_plugin_paths(cfg
->cmd_data
.query
.plugin_paths
);
344 printf(" Object: `%s`\n", cfg
->cmd_data
.query
.object
->str
);
345 printf(" Component class:\n");
346 print_bt_config_component(cfg
->cmd_data
.query
.cfg_component
);
350 void print_cfg(struct bt_config
*cfg
)
352 if (!babeltrace_verbose
) {
356 printf("Configuration:\n");
357 printf(" Debug mode: %s\n", cfg
->debug
? "yes" : "no");
358 printf(" Verbose mode: %s\n", cfg
->verbose
? "yes" : "no");
360 switch (cfg
->command
) {
361 case BT_CONFIG_COMMAND_CONVERT
:
362 print_cfg_convert(cfg
);
364 case BT_CONFIG_COMMAND_LIST_PLUGINS
:
365 print_cfg_list_plugins(cfg
);
367 case BT_CONFIG_COMMAND_HELP
:
370 case BT_CONFIG_COMMAND_QUERY
:
371 print_cfg_query(cfg
);
379 struct bt_component
*create_trimmer(struct bt_config_component
*source_cfg
)
381 struct bt_component
*trimmer
= NULL
;
382 struct bt_component_class
*trimmer_class
= NULL
;
383 struct bt_value
*trimmer_params
= NULL
;
384 struct bt_value
*value
;
386 trimmer_params
= bt_value_map_create();
387 if (!trimmer_params
) {
391 value
= bt_value_map_get(source_cfg
->params
, "begin");
393 enum bt_value_status ret
;
395 ret
= bt_value_map_insert(trimmer_params
, "begin",
402 value
= bt_value_map_get(source_cfg
->params
, "end");
404 enum bt_value_status ret
;
406 ret
= bt_value_map_insert(trimmer_params
, "end",
413 value
= bt_value_map_get(source_cfg
->params
, "clock-gmt");
415 enum bt_value_status ret
;
417 ret
= bt_value_map_insert(trimmer_params
, "clock-gmt",
425 trimmer_class
= find_component_class("utils", "trimmer",
426 BT_COMPONENT_CLASS_TYPE_FILTER
);
427 if (!trimmer_class
) {
428 fprintf(stderr
, "Could not find trimmer component class. Aborting...\n");
431 trimmer
= bt_component_create(trimmer_class
, "source_trimmer",
437 bt_put(trimmer_params
);
438 bt_put(trimmer_class
);
443 int connect_source_sink(struct bt_graph
*graph
,
444 struct bt_component
*source
,
445 struct bt_config_component
*source_cfg
,
446 struct bt_component
*sink
)
449 struct bt_connection
*connection
= NULL
;
450 struct bt_component
*trimmer
= NULL
;
451 struct bt_port
*source_port
=
452 bt_component_source_get_default_output_port(source
);
453 struct bt_port
*sink_port
=
454 bt_component_sink_get_default_input_port(sink
);
455 struct bt_port
*to_sink_port
= NULL
;
456 struct bt_port
*trimmer_input_port
= NULL
;
459 fprintf(stderr
, "Failed to find default source output port. Aborting...\n");
464 fprintf(stderr
, "Failed to find default sink input port. Aborting...\n");
469 if (bt_value_map_has_key(source_cfg
->params
, "begin")
470 || bt_value_map_has_key(source_cfg
->params
, "end")) {
471 /* A trimmer must be inserted in the graph. */
472 trimmer
= create_trimmer(source_cfg
);
474 fprintf(stderr
, "Failed to create trimmer component. Aborting...\n");
479 trimmer_input_port
= bt_component_filter_get_default_input_port(
481 if (!trimmer_input_port
) {
482 fprintf(stderr
, "Failed to find trimmer input port. Aborting...\n");
486 to_sink_port
= bt_component_filter_get_default_output_port(
489 fprintf(stderr
, "Failed to find trimmer output port. Aborting...\n");
494 connection
= bt_graph_connect(graph
, source_port
,
497 fprintf(stderr
, "Failed to connect source to trimmer. Aborting...\n");
503 BT_MOVE(to_sink_port
, source_port
);
506 connection
= bt_graph_connect(graph
, to_sink_port
, sink_port
);
508 fprintf(stderr
, "Failed to connect to sink. Aborting...\n");
516 bt_put(to_sink_port
);
522 void add_to_loaded_plugins(struct bt_plugin
**plugins
)
525 struct bt_plugin
*plugin
= *plugins
;
526 /* Check if it's already loaded (from another path). */
527 struct bt_plugin
*loaded_plugin
=
528 find_plugin(bt_plugin_get_name(plugin
));
531 printf_verbose("Not loading plugin `%s`: already loaded from `%s`\n",
532 bt_plugin_get_path(plugin
),
533 bt_plugin_get_path(loaded_plugin
));
534 BT_PUT(loaded_plugin
);
537 /* Transfer ownership to global array. */
538 g_ptr_array_add(loaded_plugins
, plugin
);
545 int load_dynamic_plugins(struct bt_value
*plugin_paths
)
547 int nr_paths
, i
, ret
= 0;
549 nr_paths
= bt_value_array_size(plugin_paths
);
555 for (i
= 0; i
< nr_paths
; i
++) {
556 struct bt_value
*plugin_path_value
= NULL
;
557 const char *plugin_path
;
558 struct bt_plugin
**plugins
;
560 plugin_path_value
= bt_value_array_get(plugin_paths
, i
);
561 if (bt_value_string_get(plugin_path_value
,
563 BT_PUT(plugin_path_value
);
567 plugins
= bt_plugin_create_all_from_dir(plugin_path
, false);
569 printf_debug("Unable to dynamically load plugins from path %s.\n",
571 BT_PUT(plugin_path_value
);
575 add_to_loaded_plugins(plugins
);
578 BT_PUT(plugin_path_value
);
585 int load_static_plugins(void)
588 struct bt_plugin
**plugins
;
590 plugins
= bt_plugin_create_all_from_static();
592 printf_debug("Unable to load static plugins.\n");
597 add_to_loaded_plugins(plugins
);
604 const char *component_type_str(enum bt_component_class_type type
)
607 case BT_COMPONENT_CLASS_TYPE_SOURCE
:
609 case BT_COMPONENT_CLASS_TYPE_SINK
:
611 case BT_COMPONENT_CLASS_TYPE_FILTER
:
613 case BT_COMPONENT_CLASS_TYPE_UNKNOWN
:
619 static int load_all_plugins(struct bt_value
*plugin_paths
)
623 if (load_dynamic_plugins(plugin_paths
)) {
624 fprintf(stderr
, "Failed to load dynamic plugins.\n");
629 if (load_static_plugins()) {
630 fprintf(stderr
, "Failed to load static plugins.\n");
639 static void print_plugin_info(struct bt_plugin
*plugin
)
641 unsigned int major
, minor
, patch
;
643 enum bt_plugin_status version_status
;
644 const char *plugin_name
;
648 const char *plugin_description
;
650 plugin_name
= bt_plugin_get_name(plugin
);
651 path
= bt_plugin_get_path(plugin
);
652 author
= bt_plugin_get_author(plugin
);
653 license
= bt_plugin_get_license(plugin
);
654 plugin_description
= bt_plugin_get_description(plugin
);
655 version_status
= bt_plugin_get_version(plugin
, &major
, &minor
,
657 printf("%s%s%s%s:\n", bt_common_color_bold(),
658 bt_common_color_fg_blue(), plugin_name
,
659 bt_common_color_reset());
660 printf(" %sPath%s: %s\n", bt_common_color_bold(),
661 bt_common_color_reset(), path
? path
: "(None)");
663 if (version_status
== BT_PLUGIN_STATUS_OK
) {
664 printf(" %sVersion%s: %u.%u.%u",
665 bt_common_color_bold(), bt_common_color_reset(),
666 major
, minor
, patch
);
675 printf(" %sDescription%s: %s\n", bt_common_color_bold(),
676 bt_common_color_reset(),
677 plugin_description
? plugin_description
: "(None)");
678 printf(" %sAuthor%s: %s\n", bt_common_color_bold(),
679 bt_common_color_reset(), author
? author
: "(Unknown)");
680 printf(" %sLicense%s: %s\n", bt_common_color_bold(),
681 bt_common_color_reset(),
682 license
? license
: "(Unknown)");
685 static void print_plugin_comp_cls_opt(FILE *fh
, const char *plugin_name
,
686 const char *comp_cls_name
, enum bt_component_class_type type
)
688 fprintf(fh
, "%s%s--%s%s %s%s%s.%s%s%s",
689 bt_common_color_bold(),
690 bt_common_color_fg_cyan(),
691 component_type_str(type
),
692 bt_common_color_fg_default(),
693 bt_common_color_fg_blue(),
695 bt_common_color_fg_default(),
696 bt_common_color_fg_yellow(),
698 bt_common_color_reset());
701 static int cmd_query(struct bt_config
*cfg
)
704 struct bt_component_class
*comp_cls
= NULL
;
705 struct bt_value
*results
= NULL
;
707 ret
= load_all_plugins(cfg
->cmd_data
.list_plugins
.plugin_paths
);
712 comp_cls
= find_component_class(cfg
->cmd_data
.query
.cfg_component
->plugin_name
->str
,
713 cfg
->cmd_data
.query
.cfg_component
->component_name
->str
,
714 cfg
->cmd_data
.query
.cfg_component
->type
);
716 fprintf(stderr
, "%s%sCannot find component class %s",
717 bt_common_color_bold(),
718 bt_common_color_fg_red(),
719 bt_common_color_reset());
720 print_plugin_comp_cls_opt(stderr
,
721 cfg
->cmd_data
.query
.cfg_component
->plugin_name
->str
,
722 cfg
->cmd_data
.query
.cfg_component
->component_name
->str
,
723 cfg
->cmd_data
.query
.cfg_component
->type
);
724 fprintf(stderr
, "\n");
729 results
= bt_component_class_query(comp_cls
,
730 cfg
->cmd_data
.query
.object
->str
,
731 cfg
->cmd_data
.query
.cfg_component
->params
);
733 fprintf(stderr
, "%s%sFailed to query info to %s",
734 bt_common_color_bold(),
735 bt_common_color_fg_red(),
736 bt_common_color_reset());
737 print_plugin_comp_cls_opt(stderr
,
738 cfg
->cmd_data
.query
.cfg_component
->plugin_name
->str
,
739 cfg
->cmd_data
.query
.cfg_component
->component_name
->str
,
740 cfg
->cmd_data
.query
.cfg_component
->type
);
741 fprintf(stderr
, "%s%s with object `%s`%s\n",
742 bt_common_color_bold(),
743 bt_common_color_fg_red(),
744 cfg
->cmd_data
.query
.object
->str
,
745 bt_common_color_reset());
750 print_value(results
, 0);
758 static int cmd_help(struct bt_config
*cfg
)
761 struct bt_plugin
*plugin
= NULL
;
764 ret
= load_all_plugins(cfg
->cmd_data
.list_plugins
.plugin_paths
);
769 plugin
= find_plugin(cfg
->cmd_data
.help
.cfg_component
->plugin_name
->str
);
771 fprintf(stderr
, "%s%sCannot find plugin %s%s%s\n",
772 bt_common_color_bold(), bt_common_color_fg_red(),
773 bt_common_color_fg_blue(),
774 cfg
->cmd_data
.help
.cfg_component
->plugin_name
->str
,
775 bt_common_color_reset());
780 print_plugin_info(plugin
);
781 printf(" %sComponent classes%s: %d\n",
782 bt_common_color_bold(),
783 bt_common_color_reset(),
784 bt_plugin_get_component_class_count(plugin
));
787 if (cfg
->cmd_data
.help
.cfg_component
->type
!=
788 BT_COMPONENT_CLASS_TYPE_UNKNOWN
) {
789 struct bt_component_class
*needed_comp_cls
=
790 find_component_class(
791 cfg
->cmd_data
.help
.cfg_component
->plugin_name
->str
,
792 cfg
->cmd_data
.help
.cfg_component
->component_name
->str
,
793 cfg
->cmd_data
.help
.cfg_component
->type
);
795 if (!needed_comp_cls
) {
796 fprintf(stderr
, "\n%s%sCannot find component class %s",
797 bt_common_color_bold(),
798 bt_common_color_fg_red(),
799 bt_common_color_reset());
800 print_plugin_comp_cls_opt(stderr
,
801 cfg
->cmd_data
.help
.cfg_component
->plugin_name
->str
,
802 cfg
->cmd_data
.help
.cfg_component
->component_name
->str
,
803 cfg
->cmd_data
.help
.cfg_component
->type
);
804 fprintf(stderr
, "\n");
809 bt_put(needed_comp_cls
);
812 for (i
= 0; i
< bt_plugin_get_component_class_count(plugin
); i
++) {
813 struct bt_component_class
*comp_cls
=
814 bt_plugin_get_component_class(plugin
, i
);
815 const char *comp_class_name
=
816 bt_component_class_get_name(comp_cls
);
817 const char *comp_class_description
=
818 bt_component_class_get_description(comp_cls
);
819 const char *comp_class_help
=
820 bt_component_class_get_help(comp_cls
);
821 enum bt_component_class_type type
=
822 bt_component_class_get_type(comp_cls
);
826 if (cfg
->cmd_data
.help
.cfg_component
->type
!=
827 BT_COMPONENT_CLASS_TYPE_UNKNOWN
) {
828 if (strcmp(cfg
->cmd_data
.help
.cfg_component
->component_name
->str
,
829 comp_class_name
) != 0 &&
831 cfg
->cmd_data
.help
.cfg_component
->type
) {
838 print_plugin_comp_cls_opt(stdout
,
839 cfg
->cmd_data
.help
.cfg_component
->plugin_name
->str
,
843 printf(" %sDescription%s: %s\n", bt_common_color_bold(),
844 bt_common_color_reset(),
845 comp_class_description
? comp_class_description
: "(None)");
847 if (comp_class_help
) {
848 printf("\n%s\n", comp_class_help
);
859 static int cmd_list_plugins(struct bt_config
*cfg
)
862 int plugins_count
, component_classes_count
= 0, i
;
864 ret
= load_all_plugins(cfg
->cmd_data
.list_plugins
.plugin_paths
);
869 printf("From the following plugin paths:\n\n");
870 print_value(cfg
->cmd_data
.list_plugins
.plugin_paths
, 2);
872 plugins_count
= loaded_plugins
->len
;
873 if (plugins_count
== 0) {
874 fprintf(stderr
, "%s%sNo plugins found.%s\n",
875 bt_common_color_bold(), bt_common_color_fg_red(),
876 bt_common_color_reset());
877 fprintf(stderr
, "\n");
878 fprintf(stderr
, "Please make sure your plugin search path is set correctly. You can use\n");
879 fprintf(stderr
, "the --plugin-path command-line option or the BABELTRACE_PLUGIN_PATH\n");
880 fprintf(stderr
, "environment variable.\n");
885 for (i
= 0; i
< plugins_count
; i
++) {
886 struct bt_plugin
*plugin
= g_ptr_array_index(loaded_plugins
, i
);
888 component_classes_count
+= bt_plugin_get_component_class_count(plugin
);
891 printf("Found %s%d%s component classes in %s%d%s plugins.\n",
892 bt_common_color_bold(),
893 component_classes_count
,
894 bt_common_color_reset(),
895 bt_common_color_bold(),
897 bt_common_color_reset());
899 for (i
= 0; i
< plugins_count
; i
++) {
901 struct bt_plugin
*plugin
= g_ptr_array_index(loaded_plugins
, i
);
903 component_classes_count
=
904 bt_plugin_get_component_class_count(plugin
);
906 print_plugin_info(plugin
);
908 if (component_classes_count
== 0) {
909 printf(" %sComponent classes%s: (None)\n",
910 bt_common_color_bold(),
911 bt_common_color_reset());
913 printf(" %sComponent classes%s:\n",
914 bt_common_color_bold(),
915 bt_common_color_reset());
918 for (j
= 0; j
< component_classes_count
; j
++) {
919 struct bt_component_class
*comp_class
=
920 bt_plugin_get_component_class(plugin
, j
);
921 const char *comp_class_name
=
922 bt_component_class_get_name(comp_class
);
923 const char *comp_class_description
=
924 bt_component_class_get_description(comp_class
);
925 enum bt_component_class_type type
=
926 bt_component_class_get_type(comp_class
);
929 print_plugin_comp_cls_opt(stdout
,
930 bt_plugin_get_name(plugin
), comp_class_name
,
933 if (comp_class_description
) {
934 printf(": %s", comp_class_description
);
946 static int print_ctf_metadata(struct bt_config
*cfg
)
949 struct bt_component_class
*comp_cls
= NULL
;
950 struct bt_config_component
*source_cfg
= NULL
;
951 struct bt_value
*results
= NULL
;
952 struct bt_value
*path
= NULL
;
953 struct bt_value
*params
= NULL
;
954 struct bt_value
*metadata_text_value
= NULL
;
955 const char *metadata_text
= NULL
;
957 assert(cfg
->cmd_data
.convert
.sources
->len
== 1);
958 source_cfg
= bt_config_get_component(cfg
->cmd_data
.convert
.sources
, 0);
960 comp_cls
= find_component_class(source_cfg
->plugin_name
->str
,
961 source_cfg
->component_name
->str
,
964 fprintf(stderr
, "%s%sCannot find component class %s",
965 bt_common_color_bold(),
966 bt_common_color_fg_red(),
967 bt_common_color_reset());
968 print_plugin_comp_cls_opt(stderr
,
969 source_cfg
->plugin_name
->str
,
970 source_cfg
->component_name
->str
,
972 fprintf(stderr
, "\n");
977 path
= bt_value_map_get(source_cfg
->params
, "path");
983 params
= bt_value_map_create();
989 ret
= bt_value_map_insert(params
, "path", path
);
995 results
= bt_component_class_query(comp_cls
, "metadata-info",
999 fprintf(stderr
, "%s%sFailed to request metadata info%s\n",
1000 bt_common_color_bold(),
1001 bt_common_color_fg_red(),
1002 bt_common_color_reset());
1006 metadata_text_value
= bt_value_map_get(results
, "text");
1007 if (!metadata_text_value
) {
1012 ret
= bt_value_string_get(metadata_text_value
, &metadata_text
);
1014 printf("%s\n", metadata_text
);
1020 bt_put(metadata_text_value
);
1026 static int cmd_convert(struct bt_config
*cfg
)
1029 struct bt_component_class
*source_class
= NULL
;
1030 struct bt_component_class
*sink_class
= NULL
;
1031 struct bt_component
*source
= NULL
, *sink
= NULL
;
1032 struct bt_value
*source_params
= NULL
, *sink_params
= NULL
;
1033 struct bt_config_component
*source_cfg
= NULL
, *sink_cfg
= NULL
;
1034 struct bt_graph
*graph
= NULL
;
1036 ret
= load_all_plugins(cfg
->cmd_data
.convert
.plugin_paths
);
1038 fprintf(stderr
, "Could not load plugins from configured plugin paths. Aborting...\n");
1042 if (cfg
->cmd_data
.convert
.print_ctf_metadata
) {
1043 ret
= print_ctf_metadata(cfg
);
1047 /* TODO handle more than 1 source and 1 sink. */
1048 if (cfg
->cmd_data
.convert
.sources
->len
!= 1 ||
1049 cfg
->cmd_data
.convert
.sinks
->len
!= 1) {
1050 fprintf(stderr
, "Only one source and one sink component class are supported. Aborting...\n");
1055 source_cfg
= bt_config_get_component(cfg
->cmd_data
.convert
.sources
, 0);
1056 source_params
= bt_get(source_cfg
->params
);
1057 source_class
= find_component_class(source_cfg
->plugin_name
->str
,
1058 source_cfg
->component_name
->str
,
1059 BT_COMPONENT_CLASS_TYPE_SOURCE
);
1060 if (!source_class
) {
1061 fprintf(stderr
, "Could not find %s.%s source component class. Aborting...\n",
1062 source_cfg
->plugin_name
->str
,
1063 source_cfg
->component_name
->str
);
1068 sink_cfg
= bt_config_get_component(cfg
->cmd_data
.convert
.sinks
, 0);
1069 sink_params
= bt_get(sink_cfg
->params
);
1070 sink_class
= find_component_class(sink_cfg
->plugin_name
->str
,
1071 sink_cfg
->component_name
->str
,
1072 BT_COMPONENT_CLASS_TYPE_SINK
);
1074 fprintf(stderr
, "Could not find %s.%s output component class. Aborting...\n",
1075 sink_cfg
->plugin_name
->str
,
1076 sink_cfg
->component_name
->str
);
1081 graph
= bt_graph_create();
1087 source
= bt_component_create(source_class
, "source", source_params
);
1089 fprintf(stderr
, "Failed to instantiate selected source component. Aborting...\n");
1094 sink
= bt_component_create(sink_class
, "sink", sink_params
);
1096 fprintf(stderr
, "Failed to instantiate selected output component. Aborting...\n");
1101 ret
= connect_source_sink(graph
, source
, source_cfg
, sink
);
1108 enum bt_graph_status graph_status
;
1110 graph_status
= bt_graph_run(graph
, NULL
);
1111 switch (graph_status
) {
1112 case BT_GRAPH_STATUS_AGAIN
:
1113 /* Wait for an arbitraty 500 ms. */
1116 case BT_COMPONENT_STATUS_END
:
1119 fprintf(stderr
, "Sink component returned an error, aborting...\n");
1127 bt_put(source_class
);
1130 bt_put(source_params
);
1131 bt_put(sink_params
);
1138 static void warn_command_name_and_directory_clash(struct bt_config
*cfg
)
1140 if (!cfg
->command_name
) {
1144 if (g_file_test(cfg
->command_name
,
1145 G_FILE_TEST_EXISTS
| G_FILE_TEST_IS_DIR
)) {
1146 fprintf(stderr
, "\nNOTE: The `%s` command was executed. If you meant to convert a\n",
1148 fprintf(stderr
, "trace located in the local `%s` directory, please use:\n",
1150 fprintf(stderr
, "\n");
1151 fprintf(stderr
, " babeltrace convert %s [OPTIONS]\n",
1156 int main(int argc
, const char **argv
)
1160 struct bt_config
*cfg
;
1162 init_loaded_plugins_array();
1163 cfg
= bt_config_from_args_with_defaults(argc
, argv
, &retcode
);
1166 /* Quit without errors; typically usage/version */
1176 fprintf(stderr
, "Failed to create Babeltrace configuration\n");
1180 babeltrace_debug
= cfg
->debug
;
1181 babeltrace_verbose
= cfg
->verbose
;
1184 switch (cfg
->command
) {
1185 case BT_CONFIG_COMMAND_CONVERT
:
1186 ret
= cmd_convert(cfg
);
1188 case BT_CONFIG_COMMAND_LIST_PLUGINS
:
1189 ret
= cmd_list_plugins(cfg
);
1191 case BT_CONFIG_COMMAND_HELP
:
1192 ret
= cmd_help(cfg
);
1194 case BT_CONFIG_COMMAND_QUERY
:
1195 ret
= cmd_query(cfg
);
1201 warn_command_name_and_directory_clash(cfg
);
1202 retcode
= ret
? 1 : 0;
1206 fini_loaded_plugins_array();