Remove component prefix from graph, connection and port filenames
[babeltrace.git] / converter / babeltrace.c
CommitLineData
34ac0e6c
MD
1/*
2 * babeltrace.c
3 *
4 * Babeltrace Trace Converter
5 *
64fa3fec
MD
6 * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation
7 *
8 * Author: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
34ac0e6c
MD
9 *
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:
16 *
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
c462e188
MD
19 *
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
26 * SOFTWARE.
34ac0e6c 27 */
4c8bfb7e 28
95d36295 29#include <babeltrace/babeltrace.h>
7c7c0433 30#include <babeltrace/plugin/plugin.h>
290725f7 31#include <babeltrace/common-internal.h>
33b34c43 32#include <babeltrace/component/component.h>
d71dcf2c
PP
33#include <babeltrace/component/component-source.h>
34#include <babeltrace/component/component-sink.h>
35#include <babeltrace/component/component-filter.h>
33b34c43 36#include <babeltrace/component/component-class.h>
7d55361f
JG
37#include <babeltrace/component/port.h>
38#include <babeltrace/component/graph.h>
39#include <babeltrace/component/connection.h>
33b34c43 40#include <babeltrace/component/notification/iterator.h>
2e339de1
JG
41#include <babeltrace/ref.h>
42#include <babeltrace/values.h>
34ac0e6c 43#include <stdlib.h>
a44bc4c9 44#include <babeltrace/ctf-ir/metadata.h> /* for clocks */
7f26a816
PP
45#include <popt.h>
46#include <string.h>
47#include <stdio.h>
33b34c43 48#include <glib.h>
c42c79ea 49#include "babeltrace-cfg.h"
ebba3338 50#include "babeltrace-cfg-connect.h"
c1870f57 51#include "default-cfg.h"
34ac0e6c 52
33b34c43
PP
53GPtrArray *loaded_plugins;
54
55static
56void init_loaded_plugins_array(void)
57{
58 loaded_plugins = g_ptr_array_new_full(8, bt_put);
59}
60
61static
62void fini_loaded_plugins_array(void)
63{
64 g_ptr_array_free(loaded_plugins, TRUE);
65}
66
67static
68struct bt_plugin *find_plugin(const char *name)
69{
70 int i;
71 struct bt_plugin *plugin = NULL;
72
73 for (i = 0; i < loaded_plugins->len; i++) {
74 plugin = g_ptr_array_index(loaded_plugins, i);
75
76 if (strcmp(name, bt_plugin_get_name(plugin)) == 0) {
77 break;
78 }
79
80 plugin = NULL;
81 }
82
83 return bt_get(plugin);
84}
85
86static
87struct bt_component_class *find_component_class(const char *plugin_name,
88 const char *comp_class_name,
d3e4dcd8 89 enum bt_component_class_type comp_class_type)
33b34c43
PP
90{
91 struct bt_component_class *comp_class = NULL;
92 struct bt_plugin *plugin = find_plugin(plugin_name);
93
94 if (!plugin) {
95 goto end;
96 }
97
98 comp_class = bt_plugin_get_component_class_by_name_and_type(plugin,
99 comp_class_name, comp_class_type);
100 BT_PUT(plugin);
101end:
102 return comp_class;
103}
6c2f3ee5 104
c42c79ea
PP
105static
106void print_indent(size_t indent)
107{
108 size_t i;
109
110 for (i = 0; i < indent; i++) {
00447e45 111 printf(" ");
c42c79ea
PP
112 }
113}
114
115static
290725f7 116void print_value(struct bt_value *, size_t);
c42c79ea 117
c1081aa6
PP
118static
119void print_value_rec(struct bt_value *, size_t);
120
c42c79ea
PP
121static
122bool print_map_value(const char *key, struct bt_value *object, void *data)
123{
290725f7
PP
124 size_t *indent = data;
125
126 print_indent(*indent);
127 printf("%s: ", key);
128
129 if (bt_value_is_array(object) &&
130 bt_value_array_is_empty(object)) {
131 printf("[ ]\n");
132 return true;
133 }
134
135 if (bt_value_is_map(object) &&
136 bt_value_map_is_empty(object)) {
137 printf("{ }\n");
138 return true;
139 }
c42c79ea 140
290725f7
PP
141 if (bt_value_is_array(object) ||
142 bt_value_is_map(object)) {
143 printf("\n");
144 }
c42c79ea 145
c1081aa6 146 print_value_rec(object, *indent + 2);
c42c79ea
PP
147 return true;
148}
149
150static
c1081aa6 151void print_value_rec(struct bt_value *value, size_t indent)
c42c79ea
PP
152{
153 bool bool_val;
154 int64_t int_val;
155 double dbl_val;
156 const char *str_val;
157 int size;
158 int i;
159
160 if (!value) {
161 return;
162 }
163
c42c79ea
PP
164 switch (bt_value_get_type(value)) {
165 case BT_VALUE_TYPE_NULL:
c1081aa6
PP
166 printf("%snull%s\n", bt_common_color_bold(),
167 bt_common_color_reset());
c42c79ea
PP
168 break;
169 case BT_VALUE_TYPE_BOOL:
170 bt_value_bool_get(value, &bool_val);
c1081aa6
PP
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());
c42c79ea
PP
174 break;
175 case BT_VALUE_TYPE_INTEGER:
176 bt_value_integer_get(value, &int_val);
c1081aa6
PP
177 printf("%s%s%" PRId64 "%s\n", bt_common_color_bold(),
178 bt_common_color_fg_red(), int_val,
179 bt_common_color_reset());
c42c79ea
PP
180 break;
181 case BT_VALUE_TYPE_FLOAT:
182 bt_value_float_get(value, &dbl_val);
c1081aa6
PP
183 printf("%s%s%lf%s\n", bt_common_color_bold(),
184 bt_common_color_fg_red(), dbl_val,
185 bt_common_color_reset());
c42c79ea
PP
186 break;
187 case BT_VALUE_TYPE_STRING:
188 bt_value_string_get(value, &str_val);
c1081aa6
PP
189 printf("%s%s%s%s\n", bt_common_color_bold(),
190 bt_common_color_fg_green(), str_val,
191 bt_common_color_reset());
c42c79ea
PP
192 break;
193 case BT_VALUE_TYPE_ARRAY:
194 size = bt_value_array_size(value);
290725f7
PP
195 assert(size >= 0);
196
197 if (size == 0) {
198 print_indent(indent);
199 printf("[ ]\n");
200 break;
201 }
c42c79ea
PP
202
203 for (i = 0; i < size; i++) {
204 struct bt_value *element =
205 bt_value_array_get(value, i);
206
290725f7
PP
207 assert(element);
208 print_indent(indent);
209 printf("- ");
210
211 if (bt_value_is_array(element) &&
212 bt_value_array_is_empty(element)) {
213 printf("[ ]\n");
214 continue;
215 }
216
217 if (bt_value_is_map(element) &&
218 bt_value_map_is_empty(element)) {
219 printf("{ }\n");
220 continue;
221 }
222
223 if (bt_value_is_array(element) ||
224 bt_value_is_map(element)) {
225 printf("\n");
226 }
227
c1081aa6 228 print_value_rec(element, indent + 2);
c42c79ea
PP
229 BT_PUT(element);
230 }
c42c79ea
PP
231 break;
232 case BT_VALUE_TYPE_MAP:
233 if (bt_value_map_is_empty(value)) {
290725f7
PP
234 print_indent(indent);
235 printf("{ }\n");
236 break;
c42c79ea
PP
237 }
238
290725f7 239 bt_value_map_foreach(value, print_map_value, &indent);
c42c79ea
PP
240 break;
241 default:
242 assert(false);
243 }
244}
245
c1081aa6
PP
246static
247void print_value(struct bt_value *value, size_t indent)
248{
249 if (!bt_value_is_array(value) && !bt_value_is_map(value)) {
250 print_indent(indent);
251 }
252
253 print_value_rec(value, indent);
254}
255
c42c79ea
PP
256static
257void print_bt_config_component(struct bt_config_component *bt_config_component)
258{
290725f7 259 printf(" %s.%s:\n", bt_config_component->plugin_name->str,
c42c79ea 260 bt_config_component->component_name->str);
3b6cfcc5
PP
261
262 if (bt_config_component->instance_name->len > 0) {
263 printf(" Name: %s\n",
264 bt_config_component->instance_name->str);
265 }
266
290725f7
PP
267 printf(" Parameters:\n");
268 print_value(bt_config_component->params, 8);
c42c79ea
PP
269}
270
271static
272void print_bt_config_components(GPtrArray *array)
273{
274 size_t i;
275
276 for (i = 0; i < array->len; i++) {
277 struct bt_config_component *cfg_component =
e5bc7f81 278 bt_config_get_component(array, i);
c42c79ea
PP
279 print_bt_config_component(cfg_component);
280 BT_PUT(cfg_component);
281 }
282}
283
290725f7
PP
284static
285void print_plugin_paths(struct bt_value *plugin_paths)
286{
287 printf(" Plugin paths:\n");
288 print_value(plugin_paths, 4);
289}
290
291static
292void print_cfg_convert(struct bt_config *cfg)
293{
ebba3338
PP
294 size_t i;
295
290725f7
PP
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);
05a67631
PP
299 printf(" Print CTF metadata: %s\n",
300 cfg->cmd_data.convert.print_ctf_metadata ? "yes" : "no");
290725f7
PP
301 printf(" Source component instances:\n");
302 print_bt_config_components(cfg->cmd_data.convert.sources);
ebba3338
PP
303
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);
307 }
308
290725f7
PP
309 printf(" Sink component instances:\n");
310 print_bt_config_components(cfg->cmd_data.convert.sinks);
ebba3338
PP
311 printf(" Connections:\n");
312
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,
316 i);
317
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);
325 }
290725f7
PP
326}
327
328static
329void print_cfg_list_plugins(struct bt_config *cfg)
330{
331 print_plugin_paths(cfg->cmd_data.list_plugins.plugin_paths);
332}
333
c1081aa6
PP
334static
335void print_cfg_help(struct bt_config *cfg)
336{
337 print_plugin_paths(cfg->cmd_data.help.plugin_paths);
338}
339
340static
a67681c1 341void print_cfg_query(struct bt_config *cfg)
c1081aa6 342{
a67681c1
PP
343 print_plugin_paths(cfg->cmd_data.query.plugin_paths);
344 printf(" Object: `%s`\n", cfg->cmd_data.query.object->str);
c1081aa6 345 printf(" Component class:\n");
a67681c1 346 print_bt_config_component(cfg->cmd_data.query.cfg_component);
c1081aa6
PP
347}
348
c42c79ea
PP
349static
350void print_cfg(struct bt_config *cfg)
351{
00447e45
PP
352 if (!babeltrace_verbose) {
353 return;
354 }
355
290725f7
PP
356 printf("Configuration:\n");
357 printf(" Debug mode: %s\n", cfg->debug ? "yes" : "no");
358 printf(" Verbose mode: %s\n", cfg->verbose ? "yes" : "no");
359
360 switch (cfg->command) {
361 case BT_CONFIG_COMMAND_CONVERT:
362 print_cfg_convert(cfg);
363 break;
364 case BT_CONFIG_COMMAND_LIST_PLUGINS:
365 print_cfg_list_plugins(cfg);
c1081aa6
PP
366 break;
367 case BT_CONFIG_COMMAND_HELP:
368 print_cfg_help(cfg);
369 break;
a67681c1
PP
370 case BT_CONFIG_COMMAND_QUERY:
371 print_cfg_query(cfg);
290725f7
PP
372 break;
373 default:
374 assert(false);
375 }
c42c79ea
PP
376}
377
6c2f3ee5
JG
378static
379struct bt_component *create_trimmer(struct bt_config_component *source_cfg)
380{
381 struct bt_component *trimmer = NULL;
382 struct bt_component_class *trimmer_class = NULL;
383 struct bt_value *trimmer_params = NULL;
528debdf 384 struct bt_value *value;
6c2f3ee5 385
6c2f3ee5
JG
386 trimmer_params = bt_value_map_create();
387 if (!trimmer_params) {
388 goto end;
389 }
390
528debdf
MD
391 value = bt_value_map_get(source_cfg->params, "begin");
392 if (value) {
6c2f3ee5 393 enum bt_value_status ret;
6c2f3ee5 394
528debdf 395 ret = bt_value_map_insert(trimmer_params, "begin",
6c2f3ee5
JG
396 value);
397 BT_PUT(value);
398 if (ret) {
399 goto end;
400 }
401 }
528debdf
MD
402 value = bt_value_map_get(source_cfg->params, "end");
403 if (value) {
6c2f3ee5 404 enum bt_value_status ret;
6c2f3ee5 405
528debdf
MD
406 ret = bt_value_map_insert(trimmer_params, "end",
407 value);
408 BT_PUT(value);
409 if (ret) {
6c2f3ee5
JG
410 goto end;
411 }
528debdf
MD
412 }
413 value = bt_value_map_get(source_cfg->params, "clock-gmt");
414 if (value) {
415 enum bt_value_status ret;
6c2f3ee5 416
528debdf 417 ret = bt_value_map_insert(trimmer_params, "clock-gmt",
6c2f3ee5
JG
418 value);
419 BT_PUT(value);
420 if (ret) {
421 goto end;
422 }
423 }
424
33b34c43 425 trimmer_class = find_component_class("utils", "trimmer",
d3e4dcd8 426 BT_COMPONENT_CLASS_TYPE_FILTER);
6c2f3ee5
JG
427 if (!trimmer_class) {
428 fprintf(stderr, "Could not find trimmer component class. Aborting...\n");
429 goto end;
430 }
431 trimmer = bt_component_create(trimmer_class, "source_trimmer",
432 trimmer_params);
433 if (!trimmer) {
434 goto end;
435 }
436end:
437 bt_put(trimmer_params);
438 bt_put(trimmer_class);
439 return trimmer;
440}
441
442static
61ddbc8a
JG
443int connect_source_sink(struct bt_graph *graph,
444 struct bt_component *source,
6c2f3ee5
JG
445 struct bt_config_component *source_cfg,
446 struct bt_component *sink)
447{
448 int ret = 0;
61ddbc8a 449 struct bt_connection *connection = NULL;
6c2f3ee5 450 struct bt_component *trimmer = NULL;
61ddbc8a
JG
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;
457
458 if (!source_port) {
459 fprintf(stderr, "Failed to find default source output port. Aborting...\n");
460 ret = -1;
461 goto end;
462 }
463 if (!sink_port) {
464 fprintf(stderr, "Failed to find default sink input port. Aborting...\n");
465 ret = -1;
466 goto end;
467 }
6c2f3ee5 468
528debdf
MD
469 if (bt_value_map_has_key(source_cfg->params, "begin")
470 || bt_value_map_has_key(source_cfg->params, "end")) {
6c2f3ee5 471 /* A trimmer must be inserted in the graph. */
6c2f3ee5
JG
472 trimmer = create_trimmer(source_cfg);
473 if (!trimmer) {
474 fprintf(stderr, "Failed to create trimmer component. Aborting...\n");
475 ret = -1;
476 goto end;
477 }
478
61ddbc8a
JG
479 trimmer_input_port = bt_component_filter_get_default_input_port(
480 trimmer);
481 if (!trimmer_input_port) {
482 fprintf(stderr, "Failed to find trimmer input port. Aborting...\n");
483 ret = -1;
484 goto end;
485 }
486 to_sink_port = bt_component_filter_get_default_output_port(
487 trimmer);
488 if (!to_sink_port) {
489 fprintf(stderr, "Failed to find trimmer output port. Aborting...\n");
6c2f3ee5
JG
490 ret = -1;
491 goto end;
492 }
493
61ddbc8a
JG
494 connection = bt_graph_connect(graph, source_port,
495 trimmer_input_port);
496 if (!connection) {
497 fprintf(stderr, "Failed to connect source to trimmer. Aborting...\n");
6c2f3ee5
JG
498 ret = -1;
499 goto end;
500 }
61ddbc8a 501 BT_PUT(connection);
6c2f3ee5 502 } else {
61ddbc8a 503 BT_MOVE(to_sink_port, source_port);
6c2f3ee5
JG
504 }
505
61ddbc8a
JG
506 connection = bt_graph_connect(graph, to_sink_port, sink_port);
507 if (!connection) {
508 fprintf(stderr, "Failed to connect to sink. Aborting...\n");
6c2f3ee5
JG
509 ret = -1;
510 goto end;
511 }
512end:
513 bt_put(trimmer);
61ddbc8a
JG
514 bt_put(source_port);
515 bt_put(sink_port);
516 bt_put(to_sink_port);
517 bt_put(connection);
6c2f3ee5
JG
518 return ret;
519}
520
33b34c43
PP
521static
522void add_to_loaded_plugins(struct bt_plugin **plugins)
98ecef32 523{
33b34c43
PP
524 while (*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));
529
530 if (loaded_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);
535 BT_PUT(plugin);
536 } else {
537 /* Transfer ownership to global array. */
538 g_ptr_array_add(loaded_plugins, plugin);
539 }
540 *(plugins++) = NULL;
541 }
542}
543
544static
290725f7 545int load_dynamic_plugins(struct bt_value *plugin_paths)
33b34c43
PP
546{
547 int nr_paths, i, ret = 0;
98ecef32 548
290725f7 549 nr_paths = bt_value_array_size(plugin_paths);
98ecef32 550 if (nr_paths < 0) {
33b34c43
PP
551 ret = -1;
552 goto end;
98ecef32 553 }
33b34c43 554
98ecef32
MD
555 for (i = 0; i < nr_paths; i++) {
556 struct bt_value *plugin_path_value = NULL;
557 const char *plugin_path;
33b34c43 558 struct bt_plugin **plugins;
98ecef32 559
290725f7 560 plugin_path_value = bt_value_array_get(plugin_paths, i);
98ecef32
MD
561 if (bt_value_string_get(plugin_path_value,
562 &plugin_path)) {
563 BT_PUT(plugin_path_value);
564 continue;
565 }
33b34c43 566
5a3ee633 567 plugins = bt_plugin_create_all_from_dir(plugin_path, false);
33b34c43 568 if (!plugins) {
98ecef32
MD
569 printf_debug("Unable to dynamically load plugins from path %s.\n",
570 plugin_path);
33b34c43
PP
571 BT_PUT(plugin_path_value);
572 continue;
98ecef32 573 }
33b34c43
PP
574
575 add_to_loaded_plugins(plugins);
576 free(plugins);
577
98ecef32
MD
578 BT_PUT(plugin_path_value);
579 }
33b34c43
PP
580end:
581 return ret;
582}
583
584static
585int load_static_plugins(void)
586{
587 int ret = 0;
588 struct bt_plugin **plugins;
589
590 plugins = bt_plugin_create_all_from_static();
591 if (!plugins) {
592 printf_debug("Unable to load static plugins.\n");
593 ret = -1;
594 goto end;
595 }
596
597 add_to_loaded_plugins(plugins);
598 free(plugins);
599end:
600 return ret;
98ecef32
MD
601}
602
290725f7
PP
603static
604const char *component_type_str(enum bt_component_class_type type)
34ac0e6c 605{
290725f7
PP
606 switch (type) {
607 case BT_COMPONENT_CLASS_TYPE_SOURCE:
608 return "source";
609 case BT_COMPONENT_CLASS_TYPE_SINK:
610 return "sink";
611 case BT_COMPONENT_CLASS_TYPE_FILTER:
612 return "filter";
613 case BT_COMPONENT_CLASS_TYPE_UNKNOWN:
614 default:
615 return "unknown";
616 }
617}
c42c79ea 618
290725f7
PP
619static int load_all_plugins(struct bt_value *plugin_paths)
620{
621 int ret = 0;
33b34c43 622
290725f7
PP
623 if (load_dynamic_plugins(plugin_paths)) {
624 fprintf(stderr, "Failed to load dynamic plugins.\n");
625 ret = -1;
c1870f57
JG
626 goto end;
627 }
628
290725f7
PP
629 if (load_static_plugins()) {
630 fprintf(stderr, "Failed to load static plugins.\n");
631 ret = -1;
c1870f57
JG
632 goto end;
633 }
634
290725f7
PP
635end:
636 return ret;
637}
638
22e22462
PP
639static void print_plugin_info(struct bt_plugin *plugin)
640{
641 unsigned int major, minor, patch;
642 const char *extra;
643 enum bt_plugin_status version_status;
644 const char *plugin_name;
645 const char *path;
646 const char *author;
647 const char *license;
648 const char *plugin_description;
649
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,
656 &patch, &extra);
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)");
662
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);
667
668 if (extra) {
669 printf("%s", extra);
670 }
671
672 printf("\n");
673 }
674
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)");
683}
684
685static void print_plugin_comp_cls_opt(FILE *fh, const char *plugin_name,
686 const char *comp_cls_name, enum bt_component_class_type type)
687{
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(),
694 plugin_name,
695 bt_common_color_fg_default(),
696 bt_common_color_fg_yellow(),
697 comp_cls_name,
698 bt_common_color_reset());
699}
700
a67681c1 701static int cmd_query(struct bt_config *cfg)
63ce0e1d
PP
702{
703 int ret;
704 struct bt_component_class *comp_cls = NULL;
705 struct bt_value *results = NULL;
706
707 ret = load_all_plugins(cfg->cmd_data.list_plugins.plugin_paths);
708 if (ret) {
709 goto end;
710 }
711
a67681c1
PP
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);
63ce0e1d
PP
715 if (!comp_cls) {
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,
a67681c1
PP
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);
63ce0e1d
PP
724 fprintf(stderr, "\n");
725 ret = -1;
726 goto end;
727 }
728
a67681c1
PP
729 results = bt_component_class_query(comp_cls,
730 cfg->cmd_data.query.object->str,
731 cfg->cmd_data.query.cfg_component->params);
63ce0e1d
PP
732 if (!results) {
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,
a67681c1
PP
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",
63ce0e1d
PP
742 bt_common_color_bold(),
743 bt_common_color_fg_red(),
a67681c1 744 cfg->cmd_data.query.object->str,
63ce0e1d
PP
745 bt_common_color_reset());
746 ret = -1;
747 goto end;
748 }
749
750 print_value(results, 0);
751
752end:
753 bt_put(comp_cls);
754 bt_put(results);
755 return ret;
756}
757
22e22462
PP
758static int cmd_help(struct bt_config *cfg)
759{
760 int ret;
761 struct bt_plugin *plugin = NULL;
762 size_t i;
763
764 ret = load_all_plugins(cfg->cmd_data.list_plugins.plugin_paths);
765 if (ret) {
766 goto end;
767 }
768
90de159b 769 plugin = find_plugin(cfg->cmd_data.help.cfg_component->plugin_name->str);
22e22462
PP
770 if (!plugin) {
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(),
90de159b 774 cfg->cmd_data.help.cfg_component->plugin_name->str,
22e22462
PP
775 bt_common_color_reset());
776 ret = -1;
777 goto end;
778 }
779
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));
785
786
90de159b 787 if (cfg->cmd_data.help.cfg_component->type !=
22e22462
PP
788 BT_COMPONENT_CLASS_TYPE_UNKNOWN) {
789 struct bt_component_class *needed_comp_cls =
790 find_component_class(
90de159b
PP
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);
22e22462
PP
794
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,
90de159b
PP
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);
22e22462
PP
804 fprintf(stderr, "\n");
805 ret = -1;
806 goto end;
807 }
808
809 bt_put(needed_comp_cls);
810 }
811
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);
823
824 assert(comp_cls);
825
90de159b 826 if (cfg->cmd_data.help.cfg_component->type !=
22e22462 827 BT_COMPONENT_CLASS_TYPE_UNKNOWN) {
90de159b 828 if (strcmp(cfg->cmd_data.help.cfg_component->component_name->str,
22e22462
PP
829 comp_class_name) != 0 &&
830 type ==
90de159b 831 cfg->cmd_data.help.cfg_component->type) {
22e22462
PP
832 bt_put(comp_cls);
833 continue;
834 }
835 }
836
837 printf("\n");
838 print_plugin_comp_cls_opt(stdout,
90de159b 839 cfg->cmd_data.help.cfg_component->plugin_name->str,
22e22462
PP
840 comp_class_name,
841 type);
842 printf("\n");
843 printf(" %sDescription%s: %s\n", bt_common_color_bold(),
844 bt_common_color_reset(),
845 comp_class_description ? comp_class_description : "(None)");
846
847 if (comp_class_help) {
848 printf("\n%s\n", comp_class_help);
849 }
850
851 bt_put(comp_cls);
852 }
853
854end:
855 bt_put(plugin);
856 return ret;
857}
858
290725f7
PP
859static int cmd_list_plugins(struct bt_config *cfg)
860{
861 int ret;
862 int plugins_count, component_classes_count = 0, i;
863
864 ret = load_all_plugins(cfg->cmd_data.list_plugins.plugin_paths);
865 if (ret) {
56a1cced
JG
866 goto end;
867 }
868
22e22462
PP
869 printf("From the following plugin paths:\n\n");
870 print_value(cfg->cmd_data.list_plugins.plugin_paths, 2);
871 printf("\n");
290725f7
PP
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");
56a1cced
JG
881 ret = -1;
882 goto end;
883 }
884
290725f7
PP
885 for (i = 0; i < plugins_count; i++) {
886 struct bt_plugin *plugin = g_ptr_array_index(loaded_plugins, i);
887
888 component_classes_count += bt_plugin_get_component_class_count(plugin);
889 }
33bceaf8 890
290725f7
PP
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(),
896 plugins_count,
897 bt_common_color_reset());
898
899 for (i = 0; i < plugins_count; i++) {
900 int j;
901 struct bt_plugin *plugin = g_ptr_array_index(loaded_plugins, i);
290725f7
PP
902
903 component_classes_count =
904 bt_plugin_get_component_class_count(plugin);
22e22462
PP
905 printf("\n");
906 print_plugin_info(plugin);
290725f7
PP
907
908 if (component_classes_count == 0) {
909 printf(" %sComponent classes%s: (None)\n",
910 bt_common_color_bold(),
911 bt_common_color_reset());
912 } else {
913 printf(" %sComponent classes%s:\n",
914 bt_common_color_bold(),
915 bt_common_color_reset());
916 }
917
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);
927
22e22462
PP
928 printf(" ");
929 print_plugin_comp_cls_opt(stdout,
930 bt_plugin_get_name(plugin), comp_class_name,
931 type);
290725f7
PP
932
933 if (comp_class_description) {
934 printf(": %s", comp_class_description);
935 }
936
937 printf("\n");
938 bt_put(comp_class);
939 }
940 }
941
942end:
943 return ret;
944}
945
05a67631
PP
946static int print_ctf_metadata(struct bt_config *cfg)
947{
948 int ret = 0;
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;
956
957 assert(cfg->cmd_data.convert.sources->len == 1);
958 source_cfg = bt_config_get_component(cfg->cmd_data.convert.sources, 0);
959 assert(source_cfg);
960 comp_cls = find_component_class(source_cfg->plugin_name->str,
961 source_cfg->component_name->str,
962 source_cfg->type);
963 if (!comp_cls) {
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,
971 source_cfg->type);
972 fprintf(stderr, "\n");
973 ret = -1;
974 goto end;
975 }
976
977 path = bt_value_map_get(source_cfg->params, "path");
978 if (!path) {
979 ret = -1;
980 goto end;
981 }
982
983 params = bt_value_map_create();
984 if (!params) {
985 ret = -1;
986 goto end;
987 }
988
989 ret = bt_value_map_insert(params, "path", path);
990 if (ret) {
991 ret = -1;
992 goto end;
993 }
994
a67681c1 995 results = bt_component_class_query(comp_cls, "metadata-info",
05a67631
PP
996 params);
997 if (!results) {
998 ret = -1;
a67681c1 999 fprintf(stderr, "%s%sFailed to request metadata info%s\n",
05a67631
PP
1000 bt_common_color_bold(),
1001 bt_common_color_fg_red(),
1002 bt_common_color_reset());
1003 goto end;
1004 }
1005
1006 metadata_text_value = bt_value_map_get(results, "text");
1007 if (!metadata_text_value) {
1008 ret = -1;
1009 goto end;
1010 }
1011
1012 ret = bt_value_string_get(metadata_text_value, &metadata_text);
1013 assert(ret == 0);
1014 printf("%s\n", metadata_text);
1015
1016end:
1017 bt_put(results);
1018 bt_put(path);
1019 bt_put(params);
1020 bt_put(metadata_text_value);
1021 bt_put(comp_cls);
1022 bt_put(source_cfg);
1023 return 0;
1024}
1025
290725f7
PP
1026static int cmd_convert(struct bt_config *cfg)
1027{
1028 int ret = 0;
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;
290725f7 1033 struct bt_config_component *source_cfg = NULL, *sink_cfg = NULL;
61ddbc8a 1034 struct bt_graph *graph = NULL;
290725f7 1035
05a67631
PP
1036 ret = load_all_plugins(cfg->cmd_data.convert.plugin_paths);
1037 if (ret) {
1038 fprintf(stderr, "Could not load plugins from configured plugin paths. Aborting...\n");
1039 goto end;
1040 }
1041
1042 if (cfg->cmd_data.convert.print_ctf_metadata) {
1043 ret = print_ctf_metadata(cfg);
1044 goto end;
1045 }
1046
290725f7
PP
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) {
ebba3338 1050 fprintf(stderr, "Only one source and one sink component class are supported. Aborting...\n");
98ecef32
MD
1051 ret = -1;
1052 goto end;
33bceaf8
JG
1053 }
1054
290725f7 1055 source_cfg = bt_config_get_component(cfg->cmd_data.convert.sources, 0);
e5bc7f81 1056 source_params = bt_get(source_cfg->params);
33b34c43
PP
1057 source_class = find_component_class(source_cfg->plugin_name->str,
1058 source_cfg->component_name->str,
d3e4dcd8 1059 BT_COMPONENT_CLASS_TYPE_SOURCE);
56a1cced 1060 if (!source_class) {
e5bc7f81
JG
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);
56a1cced
JG
1064 ret = -1;
1065 goto end;
1066 }
7c7c0433 1067
290725f7 1068 sink_cfg = bt_config_get_component(cfg->cmd_data.convert.sinks, 0);
e5bc7f81 1069 sink_params = bt_get(sink_cfg->params);
33b34c43
PP
1070 sink_class = find_component_class(sink_cfg->plugin_name->str,
1071 sink_cfg->component_name->str,
d3e4dcd8 1072 BT_COMPONENT_CLASS_TYPE_SINK);
7c7c0433 1073 if (!sink_class) {
e5bc7f81
JG
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);
7c7c0433
JG
1077 ret = -1;
1078 goto end;
1079 }
1080
61ddbc8a
JG
1081 graph = bt_graph_create();
1082 if (!graph) {
1083 ret = -1;
1084 goto end;
1085 }
1086
e5bc7f81 1087 source = bt_component_create(source_class, "source", source_params);
56a1cced 1088 if (!source) {
e5bc7f81 1089 fprintf(stderr, "Failed to instantiate selected source component. Aborting...\n");
c42c79ea
PP
1090 ret = -1;
1091 goto end;
1092 }
56a1cced 1093
e5bc7f81 1094 sink = bt_component_create(sink_class, "sink", sink_params);
7c7c0433 1095 if (!sink) {
e5bc7f81 1096 fprintf(stderr, "Failed to instantiate selected output component. Aborting...\n");
7c7c0433 1097 ret = -1;
2e339de1
JG
1098 goto end;
1099 }
1100
61ddbc8a 1101 ret = connect_source_sink(graph, source, source_cfg, sink);
6c2f3ee5 1102 if (ret) {
290725f7 1103 ret = -1;
fec2a9f2
JG
1104 goto end;
1105 }
78586d8a 1106
fec2a9f2 1107 while (true) {
61ddbc8a
JG
1108 enum bt_graph_status graph_status;
1109
1110 graph_status = bt_graph_run(graph, NULL);
1111 switch (graph_status) {
1112 case BT_GRAPH_STATUS_AGAIN:
fec2a9f2
JG
1113 /* Wait for an arbitraty 500 ms. */
1114 usleep(500000);
78586d8a 1115 break;
fec2a9f2
JG
1116 case BT_COMPONENT_STATUS_END:
1117 goto end;
1118 default:
1119 fprintf(stderr, "Sink component returned an error, aborting...\n");
1120 ret = -1;
1121 goto end;
78586d8a 1122 }
fec2a9f2 1123 }
290725f7 1124
11e1d048 1125end:
61ddbc8a
JG
1126 bt_put(sink_class);
1127 bt_put(source_class);
1128 bt_put(source);
1129 bt_put(sink);
1130 bt_put(source_params);
1131 bt_put(sink_params);
1132 bt_put(sink_cfg);
1133 bt_put(source_cfg);
1134 bt_put(graph);
290725f7
PP
1135 return ret;
1136}
1137
1138static void warn_command_name_and_directory_clash(struct bt_config *cfg)
1139{
1140 if (!cfg->command_name) {
1141 return;
1142 }
1143
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",
1147 cfg->command_name);
1148 fprintf(stderr, "trace located in the local `%s` directory, please use:\n",
1149 cfg->command_name);
1150 fprintf(stderr, "\n");
1151 fprintf(stderr, " babeltrace convert %s [OPTIONS]\n",
1152 cfg->command_name);
1153 }
1154}
1155
1156int main(int argc, const char **argv)
1157{
1158 int ret;
1159 int retcode;
1160 struct bt_config *cfg;
1161
1162 init_loaded_plugins_array();
1163 cfg = bt_config_from_args_with_defaults(argc, argv, &retcode);
1164
1165 if (retcode < 0) {
1166 /* Quit without errors; typically usage/version */
1167 retcode = 0;
1168 goto end;
1169 }
1170
1171 if (retcode > 0) {
1172 goto end;
1173 }
1174
1175 if (!cfg) {
1176 fprintf(stderr, "Failed to create Babeltrace configuration\n");
1177 goto end;
1178 }
1179
1180 babeltrace_debug = cfg->debug;
1181 babeltrace_verbose = cfg->verbose;
1182 print_cfg(cfg);
1183
1184 switch (cfg->command) {
1185 case BT_CONFIG_COMMAND_CONVERT:
1186 ret = cmd_convert(cfg);
1187 break;
1188 case BT_CONFIG_COMMAND_LIST_PLUGINS:
1189 ret = cmd_list_plugins(cfg);
1190 break;
22e22462
PP
1191 case BT_CONFIG_COMMAND_HELP:
1192 ret = cmd_help(cfg);
1193 break;
a67681c1
PP
1194 case BT_CONFIG_COMMAND_QUERY:
1195 ret = cmd_query(cfg);
63ce0e1d 1196 break;
290725f7
PP
1197 default:
1198 assert(false);
1199 }
1200
1201 warn_command_name_and_directory_clash(cfg);
1202 retcode = ret ? 1 : 0;
1203
1204end:
1205 BT_PUT(cfg);
33b34c43 1206 fini_loaded_plugins_array();
290725f7 1207 return retcode;
4c8bfb7e 1208}
This page took 0.097452 seconds and 4 git commands to generate.