babeltrace convert: add --name option
[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
PP
36#include <babeltrace/component/component-class.h>
37#include <babeltrace/component/notification/iterator.h>
2e339de1
JG
38#include <babeltrace/ref.h>
39#include <babeltrace/values.h>
34ac0e6c 40#include <stdlib.h>
a44bc4c9 41#include <babeltrace/ctf-ir/metadata.h> /* for clocks */
7f26a816
PP
42#include <popt.h>
43#include <string.h>
44#include <stdio.h>
33b34c43 45#include <glib.h>
c42c79ea 46#include "babeltrace-cfg.h"
c1870f57 47#include "default-cfg.h"
34ac0e6c 48
33b34c43
PP
49GPtrArray *loaded_plugins;
50
51static
52void init_loaded_plugins_array(void)
53{
54 loaded_plugins = g_ptr_array_new_full(8, bt_put);
55}
56
57static
58void fini_loaded_plugins_array(void)
59{
60 g_ptr_array_free(loaded_plugins, TRUE);
61}
62
63static
64struct bt_plugin *find_plugin(const char *name)
65{
66 int i;
67 struct bt_plugin *plugin = NULL;
68
69 for (i = 0; i < loaded_plugins->len; i++) {
70 plugin = g_ptr_array_index(loaded_plugins, i);
71
72 if (strcmp(name, bt_plugin_get_name(plugin)) == 0) {
73 break;
74 }
75
76 plugin = NULL;
77 }
78
79 return bt_get(plugin);
80}
81
82static
83struct bt_component_class *find_component_class(const char *plugin_name,
84 const char *comp_class_name,
d3e4dcd8 85 enum bt_component_class_type comp_class_type)
33b34c43
PP
86{
87 struct bt_component_class *comp_class = NULL;
88 struct bt_plugin *plugin = find_plugin(plugin_name);
89
90 if (!plugin) {
91 goto end;
92 }
93
94 comp_class = bt_plugin_get_component_class_by_name_and_type(plugin,
95 comp_class_name, comp_class_type);
96 BT_PUT(plugin);
97end:
98 return comp_class;
99}
6c2f3ee5 100
c42c79ea
PP
101static
102void print_indent(size_t indent)
103{
104 size_t i;
105
106 for (i = 0; i < indent; i++) {
00447e45 107 printf(" ");
c42c79ea
PP
108 }
109}
110
111static
290725f7 112void print_value(struct bt_value *, size_t);
c42c79ea
PP
113
114static
115bool print_map_value(const char *key, struct bt_value *object, void *data)
116{
290725f7
PP
117 size_t *indent = data;
118
119 print_indent(*indent);
120 printf("%s: ", key);
121
122 if (bt_value_is_array(object) &&
123 bt_value_array_is_empty(object)) {
124 printf("[ ]\n");
125 return true;
126 }
127
128 if (bt_value_is_map(object) &&
129 bt_value_map_is_empty(object)) {
130 printf("{ }\n");
131 return true;
132 }
c42c79ea 133
290725f7
PP
134 if (bt_value_is_array(object) ||
135 bt_value_is_map(object)) {
136 printf("\n");
137 }
c42c79ea 138
290725f7 139 print_value(object, *indent + 2);
c42c79ea
PP
140 return true;
141}
142
143static
290725f7 144void print_value(struct bt_value *value, size_t indent)
c42c79ea
PP
145{
146 bool bool_val;
147 int64_t int_val;
148 double dbl_val;
149 const char *str_val;
150 int size;
151 int i;
152
153 if (!value) {
154 return;
155 }
156
c42c79ea
PP
157 switch (bt_value_get_type(value)) {
158 case BT_VALUE_TYPE_NULL:
00447e45 159 printf("null\n");
c42c79ea
PP
160 break;
161 case BT_VALUE_TYPE_BOOL:
162 bt_value_bool_get(value, &bool_val);
290725f7 163 printf("%s\n", bool_val ? "yes" : "no");
c42c79ea
PP
164 break;
165 case BT_VALUE_TYPE_INTEGER:
166 bt_value_integer_get(value, &int_val);
00447e45 167 printf("%" PRId64 "\n", int_val);
c42c79ea
PP
168 break;
169 case BT_VALUE_TYPE_FLOAT:
170 bt_value_float_get(value, &dbl_val);
00447e45 171 printf("%lf\n", dbl_val);
c42c79ea
PP
172 break;
173 case BT_VALUE_TYPE_STRING:
174 bt_value_string_get(value, &str_val);
290725f7 175 printf("%s\n", str_val);
c42c79ea
PP
176 break;
177 case BT_VALUE_TYPE_ARRAY:
178 size = bt_value_array_size(value);
290725f7
PP
179 assert(size >= 0);
180
181 if (size == 0) {
182 print_indent(indent);
183 printf("[ ]\n");
184 break;
185 }
c42c79ea
PP
186
187 for (i = 0; i < size; i++) {
188 struct bt_value *element =
189 bt_value_array_get(value, i);
190
290725f7
PP
191 assert(element);
192 print_indent(indent);
193 printf("- ");
194
195 if (bt_value_is_array(element) &&
196 bt_value_array_is_empty(element)) {
197 printf("[ ]\n");
198 continue;
199 }
200
201 if (bt_value_is_map(element) &&
202 bt_value_map_is_empty(element)) {
203 printf("{ }\n");
204 continue;
205 }
206
207 if (bt_value_is_array(element) ||
208 bt_value_is_map(element)) {
209 printf("\n");
210 }
211
212 print_value(element, indent + 2);
c42c79ea
PP
213 BT_PUT(element);
214 }
c42c79ea
PP
215 break;
216 case BT_VALUE_TYPE_MAP:
217 if (bt_value_map_is_empty(value)) {
290725f7
PP
218 print_indent(indent);
219 printf("{ }\n");
220 break;
c42c79ea
PP
221 }
222
290725f7 223 bt_value_map_foreach(value, print_map_value, &indent);
c42c79ea
PP
224 break;
225 default:
226 assert(false);
227 }
228}
229
230static
231void print_bt_config_component(struct bt_config_component *bt_config_component)
232{
290725f7 233 printf(" %s.%s:\n", bt_config_component->plugin_name->str,
c42c79ea 234 bt_config_component->component_name->str);
3b6cfcc5
PP
235
236 if (bt_config_component->instance_name->len > 0) {
237 printf(" Name: %s\n",
238 bt_config_component->instance_name->str);
239 }
240
290725f7
PP
241 printf(" Parameters:\n");
242 print_value(bt_config_component->params, 8);
c42c79ea
PP
243}
244
245static
246void print_bt_config_components(GPtrArray *array)
247{
248 size_t i;
249
250 for (i = 0; i < array->len; i++) {
251 struct bt_config_component *cfg_component =
e5bc7f81 252 bt_config_get_component(array, i);
c42c79ea
PP
253 print_bt_config_component(cfg_component);
254 BT_PUT(cfg_component);
255 }
256}
257
290725f7
PP
258static
259void print_plugin_paths(struct bt_value *plugin_paths)
260{
261 printf(" Plugin paths:\n");
262 print_value(plugin_paths, 4);
263}
264
265static
266void print_cfg_convert(struct bt_config *cfg)
267{
268 printf(" Force correlate: %s\n",
269 cfg->cmd_data.convert.force_correlate ? "yes" : "no");
270 print_plugin_paths(cfg->cmd_data.convert.plugin_paths);
271 printf(" Source component instances:\n");
272 print_bt_config_components(cfg->cmd_data.convert.sources);
273 printf(" Sink component instances:\n");
274 print_bt_config_components(cfg->cmd_data.convert.sinks);
275}
276
277static
278void print_cfg_list_plugins(struct bt_config *cfg)
279{
280 print_plugin_paths(cfg->cmd_data.list_plugins.plugin_paths);
281}
282
c42c79ea
PP
283static
284void print_cfg(struct bt_config *cfg)
285{
00447e45
PP
286 if (!babeltrace_verbose) {
287 return;
288 }
289
290725f7
PP
290 printf("Configuration:\n");
291 printf(" Debug mode: %s\n", cfg->debug ? "yes" : "no");
292 printf(" Verbose mode: %s\n", cfg->verbose ? "yes" : "no");
293
294 switch (cfg->command) {
295 case BT_CONFIG_COMMAND_CONVERT:
296 print_cfg_convert(cfg);
297 break;
298 case BT_CONFIG_COMMAND_LIST_PLUGINS:
299 print_cfg_list_plugins(cfg);
300 break;
301 default:
302 assert(false);
303 }
c42c79ea
PP
304}
305
6c2f3ee5
JG
306static
307struct bt_component *create_trimmer(struct bt_config_component *source_cfg)
308{
309 struct bt_component *trimmer = NULL;
310 struct bt_component_class *trimmer_class = NULL;
311 struct bt_value *trimmer_params = NULL;
528debdf 312 struct bt_value *value;
6c2f3ee5 313
6c2f3ee5
JG
314 trimmer_params = bt_value_map_create();
315 if (!trimmer_params) {
316 goto end;
317 }
318
528debdf
MD
319 value = bt_value_map_get(source_cfg->params, "begin");
320 if (value) {
6c2f3ee5 321 enum bt_value_status ret;
6c2f3ee5 322
528debdf 323 ret = bt_value_map_insert(trimmer_params, "begin",
6c2f3ee5
JG
324 value);
325 BT_PUT(value);
326 if (ret) {
327 goto end;
328 }
329 }
528debdf
MD
330 value = bt_value_map_get(source_cfg->params, "end");
331 if (value) {
6c2f3ee5 332 enum bt_value_status ret;
6c2f3ee5 333
528debdf
MD
334 ret = bt_value_map_insert(trimmer_params, "end",
335 value);
336 BT_PUT(value);
337 if (ret) {
6c2f3ee5
JG
338 goto end;
339 }
528debdf
MD
340 }
341 value = bt_value_map_get(source_cfg->params, "clock-gmt");
342 if (value) {
343 enum bt_value_status ret;
6c2f3ee5 344
528debdf 345 ret = bt_value_map_insert(trimmer_params, "clock-gmt",
6c2f3ee5
JG
346 value);
347 BT_PUT(value);
348 if (ret) {
349 goto end;
350 }
351 }
352
33b34c43 353 trimmer_class = find_component_class("utils", "trimmer",
d3e4dcd8 354 BT_COMPONENT_CLASS_TYPE_FILTER);
6c2f3ee5
JG
355 if (!trimmer_class) {
356 fprintf(stderr, "Could not find trimmer component class. Aborting...\n");
357 goto end;
358 }
359 trimmer = bt_component_create(trimmer_class, "source_trimmer",
360 trimmer_params);
361 if (!trimmer) {
362 goto end;
363 }
364end:
365 bt_put(trimmer_params);
366 bt_put(trimmer_class);
367 return trimmer;
368}
369
370static
371int connect_source_sink(struct bt_component *source,
372 struct bt_config_component *source_cfg,
373 struct bt_component *sink)
374{
375 int ret = 0;
376 enum bt_component_status sink_status;
377 struct bt_component *trimmer = NULL;
378 struct bt_notification_iterator *source_it = NULL;
379 struct bt_notification_iterator *to_sink_it = NULL;
380
c725abdd 381 source_it = bt_component_source_create_notification_iterator(source);
6c2f3ee5
JG
382 if (!source_it) {
383 fprintf(stderr, "Failed to instantiate source iterator. Aborting...\n");
384 ret = -1;
385 goto end;
386 }
387
528debdf
MD
388 if (bt_value_map_has_key(source_cfg->params, "begin")
389 || bt_value_map_has_key(source_cfg->params, "end")) {
6c2f3ee5
JG
390 /* A trimmer must be inserted in the graph. */
391 enum bt_component_status trimmer_status;
392
393 trimmer = create_trimmer(source_cfg);
394 if (!trimmer) {
395 fprintf(stderr, "Failed to create trimmer component. Aborting...\n");
396 ret = -1;
397 goto end;
398 }
399
400 trimmer_status = bt_component_filter_add_iterator(trimmer,
401 source_it);
402 BT_PUT(source_it);
403 if (trimmer_status != BT_COMPONENT_STATUS_OK) {
404 fprintf(stderr, "Failed to connect source to trimmer. Aborting...\n");
405 ret = -1;
406 goto end;
407 }
408
c725abdd 409 to_sink_it = bt_component_filter_create_notification_iterator(trimmer);
6c2f3ee5
JG
410 if (!to_sink_it) {
411 fprintf(stderr, "Failed to instantiate trimmer iterator. Aborting...\n");
412 ret = -1;
413 goto end;
414 }
415 } else {
416 BT_MOVE(to_sink_it, source_it);
417 }
418
419 sink_status = bt_component_sink_add_iterator(sink, to_sink_it);
420 if (sink_status != BT_COMPONENT_STATUS_OK) {
421 fprintf(stderr, "Failed to connect to sink component. Aborting...\n");
422 ret = -1;
423 goto end;
424 }
425end:
426 bt_put(trimmer);
427 bt_put(source_it);
428 bt_put(to_sink_it);
429 return ret;
430}
431
33b34c43
PP
432static
433void add_to_loaded_plugins(struct bt_plugin **plugins)
98ecef32 434{
33b34c43
PP
435 while (*plugins) {
436 struct bt_plugin *plugin = *plugins;
437 /* Check if it's already loaded (from another path). */
438 struct bt_plugin *loaded_plugin =
439 find_plugin(bt_plugin_get_name(plugin));
440
441 if (loaded_plugin) {
442 printf_verbose("Not loading plugin `%s`: already loaded from `%s`\n",
443 bt_plugin_get_path(plugin),
444 bt_plugin_get_path(loaded_plugin));
445 BT_PUT(loaded_plugin);
446 BT_PUT(plugin);
447 } else {
448 /* Transfer ownership to global array. */
449 g_ptr_array_add(loaded_plugins, plugin);
450 }
451 *(plugins++) = NULL;
452 }
453}
454
455static
290725f7 456int load_dynamic_plugins(struct bt_value *plugin_paths)
33b34c43
PP
457{
458 int nr_paths, i, ret = 0;
98ecef32 459
290725f7 460 nr_paths = bt_value_array_size(plugin_paths);
98ecef32 461 if (nr_paths < 0) {
33b34c43
PP
462 ret = -1;
463 goto end;
98ecef32 464 }
33b34c43 465
98ecef32
MD
466 for (i = 0; i < nr_paths; i++) {
467 struct bt_value *plugin_path_value = NULL;
468 const char *plugin_path;
33b34c43 469 struct bt_plugin **plugins;
98ecef32 470
290725f7 471 plugin_path_value = bt_value_array_get(plugin_paths, i);
98ecef32
MD
472 if (bt_value_string_get(plugin_path_value,
473 &plugin_path)) {
474 BT_PUT(plugin_path_value);
475 continue;
476 }
33b34c43 477
5a3ee633 478 plugins = bt_plugin_create_all_from_dir(plugin_path, false);
33b34c43 479 if (!plugins) {
98ecef32
MD
480 printf_debug("Unable to dynamically load plugins from path %s.\n",
481 plugin_path);
33b34c43
PP
482 BT_PUT(plugin_path_value);
483 continue;
98ecef32 484 }
33b34c43
PP
485
486 add_to_loaded_plugins(plugins);
487 free(plugins);
488
98ecef32
MD
489 BT_PUT(plugin_path_value);
490 }
33b34c43
PP
491end:
492 return ret;
493}
494
495static
496int load_static_plugins(void)
497{
498 int ret = 0;
499 struct bt_plugin **plugins;
500
501 plugins = bt_plugin_create_all_from_static();
502 if (!plugins) {
503 printf_debug("Unable to load static plugins.\n");
504 ret = -1;
505 goto end;
506 }
507
508 add_to_loaded_plugins(plugins);
509 free(plugins);
510end:
511 return ret;
98ecef32
MD
512}
513
290725f7
PP
514static
515const char *component_type_str(enum bt_component_class_type type)
34ac0e6c 516{
290725f7
PP
517 switch (type) {
518 case BT_COMPONENT_CLASS_TYPE_SOURCE:
519 return "source";
520 case BT_COMPONENT_CLASS_TYPE_SINK:
521 return "sink";
522 case BT_COMPONENT_CLASS_TYPE_FILTER:
523 return "filter";
524 case BT_COMPONENT_CLASS_TYPE_UNKNOWN:
525 default:
526 return "unknown";
527 }
528}
c42c79ea 529
290725f7
PP
530static int load_all_plugins(struct bt_value *plugin_paths)
531{
532 int ret = 0;
33b34c43 533
290725f7
PP
534 if (load_dynamic_plugins(plugin_paths)) {
535 fprintf(stderr, "Failed to load dynamic plugins.\n");
536 ret = -1;
c1870f57
JG
537 goto end;
538 }
539
290725f7
PP
540 if (load_static_plugins()) {
541 fprintf(stderr, "Failed to load static plugins.\n");
542 ret = -1;
c1870f57
JG
543 goto end;
544 }
545
290725f7
PP
546end:
547 return ret;
548}
549
22e22462
PP
550static void print_plugin_info(struct bt_plugin *plugin)
551{
552 unsigned int major, minor, patch;
553 const char *extra;
554 enum bt_plugin_status version_status;
555 const char *plugin_name;
556 const char *path;
557 const char *author;
558 const char *license;
559 const char *plugin_description;
560
561 plugin_name = bt_plugin_get_name(plugin);
562 path = bt_plugin_get_path(plugin);
563 author = bt_plugin_get_author(plugin);
564 license = bt_plugin_get_license(plugin);
565 plugin_description = bt_plugin_get_description(plugin);
566 version_status = bt_plugin_get_version(plugin, &major, &minor,
567 &patch, &extra);
568 printf("%s%s%s%s:\n", bt_common_color_bold(),
569 bt_common_color_fg_blue(), plugin_name,
570 bt_common_color_reset());
571 printf(" %sPath%s: %s\n", bt_common_color_bold(),
572 bt_common_color_reset(), path ? path : "(None)");
573
574 if (version_status == BT_PLUGIN_STATUS_OK) {
575 printf(" %sVersion%s: %u.%u.%u",
576 bt_common_color_bold(), bt_common_color_reset(),
577 major, minor, patch);
578
579 if (extra) {
580 printf("%s", extra);
581 }
582
583 printf("\n");
584 }
585
586 printf(" %sDescription%s: %s\n", bt_common_color_bold(),
587 bt_common_color_reset(),
588 plugin_description ? plugin_description : "(None)");
589 printf(" %sAuthor%s: %s\n", bt_common_color_bold(),
590 bt_common_color_reset(), author ? author : "(Unknown)");
591 printf(" %sLicense%s: %s\n", bt_common_color_bold(),
592 bt_common_color_reset(),
593 license ? license : "(Unknown)");
594}
595
596static void print_plugin_comp_cls_opt(FILE *fh, const char *plugin_name,
597 const char *comp_cls_name, enum bt_component_class_type type)
598{
599 fprintf(fh, "%s%s--%s%s %s%s%s.%s%s%s",
600 bt_common_color_bold(),
601 bt_common_color_fg_cyan(),
602 component_type_str(type),
603 bt_common_color_fg_default(),
604 bt_common_color_fg_blue(),
605 plugin_name,
606 bt_common_color_fg_default(),
607 bt_common_color_fg_yellow(),
608 comp_cls_name,
609 bt_common_color_reset());
610}
611
612static int cmd_help(struct bt_config *cfg)
613{
614 int ret;
615 struct bt_plugin *plugin = NULL;
616 size_t i;
617
618 ret = load_all_plugins(cfg->cmd_data.list_plugins.plugin_paths);
619 if (ret) {
620 goto end;
621 }
622
623 plugin = find_plugin(cfg->cmd_data.help.plugin_name->str);
624 if (!plugin) {
625 fprintf(stderr, "%s%sCannot find plugin %s%s%s\n",
626 bt_common_color_bold(), bt_common_color_fg_red(),
627 bt_common_color_fg_blue(),
628 cfg->cmd_data.help.plugin_name->str,
629 bt_common_color_reset());
630 ret = -1;
631 goto end;
632 }
633
634 print_plugin_info(plugin);
635 printf(" %sComponent classes%s: %d\n",
636 bt_common_color_bold(),
637 bt_common_color_reset(),
638 bt_plugin_get_component_class_count(plugin));
639
640
641 if (cfg->cmd_data.help.comp_cls_type !=
642 BT_COMPONENT_CLASS_TYPE_UNKNOWN) {
643 struct bt_component_class *needed_comp_cls =
644 find_component_class(
645 cfg->cmd_data.help.plugin_name->str,
646 cfg->cmd_data.help.component_name->str,
647 cfg->cmd_data.help.comp_cls_type);
648
649 if (!needed_comp_cls) {
650 fprintf(stderr, "\n%s%sCannot find component class %s",
651 bt_common_color_bold(),
652 bt_common_color_fg_red(),
653 bt_common_color_reset());
654 print_plugin_comp_cls_opt(stderr,
655 cfg->cmd_data.help.plugin_name->str,
656 cfg->cmd_data.help.component_name->str,
657 cfg->cmd_data.help.comp_cls_type);
658 fprintf(stderr, "\n");
659 ret = -1;
660 goto end;
661 }
662
663 bt_put(needed_comp_cls);
664 }
665
666 for (i = 0; i < bt_plugin_get_component_class_count(plugin); i++) {
667 struct bt_component_class *comp_cls =
668 bt_plugin_get_component_class(plugin, i);
669 const char *comp_class_name =
670 bt_component_class_get_name(comp_cls);
671 const char *comp_class_description =
672 bt_component_class_get_description(comp_cls);
673 const char *comp_class_help =
674 bt_component_class_get_help(comp_cls);
675 enum bt_component_class_type type =
676 bt_component_class_get_type(comp_cls);
677
678 assert(comp_cls);
679
680 if (cfg->cmd_data.help.comp_cls_type !=
681 BT_COMPONENT_CLASS_TYPE_UNKNOWN) {
682 if (strcmp(cfg->cmd_data.help.component_name->str,
683 comp_class_name) != 0 &&
684 type ==
685 cfg->cmd_data.help.comp_cls_type) {
686 bt_put(comp_cls);
687 continue;
688 }
689 }
690
691 printf("\n");
692 print_plugin_comp_cls_opt(stdout,
693 cfg->cmd_data.help.plugin_name->str,
694 comp_class_name,
695 type);
696 printf("\n");
697 printf(" %sDescription%s: %s\n", bt_common_color_bold(),
698 bt_common_color_reset(),
699 comp_class_description ? comp_class_description : "(None)");
700
701 if (comp_class_help) {
702 printf("\n%s\n", comp_class_help);
703 }
704
705 bt_put(comp_cls);
706 }
707
708end:
709 bt_put(plugin);
710 return ret;
711}
712
290725f7
PP
713static int cmd_list_plugins(struct bt_config *cfg)
714{
715 int ret;
716 int plugins_count, component_classes_count = 0, i;
717
718 ret = load_all_plugins(cfg->cmd_data.list_plugins.plugin_paths);
719 if (ret) {
56a1cced
JG
720 goto end;
721 }
722
22e22462
PP
723 printf("From the following plugin paths:\n\n");
724 print_value(cfg->cmd_data.list_plugins.plugin_paths, 2);
725 printf("\n");
290725f7
PP
726 plugins_count = loaded_plugins->len;
727 if (plugins_count == 0) {
728 fprintf(stderr, "%s%sNo plugins found.%s\n",
729 bt_common_color_bold(), bt_common_color_fg_red(),
730 bt_common_color_reset());
731 fprintf(stderr, "\n");
732 fprintf(stderr, "Please make sure your plugin search path is set correctly. You can use\n");
733 fprintf(stderr, "the --plugin-path command-line option or the BABELTRACE_PLUGIN_PATH\n");
734 fprintf(stderr, "environment variable.\n");
56a1cced
JG
735 ret = -1;
736 goto end;
737 }
738
290725f7
PP
739 for (i = 0; i < plugins_count; i++) {
740 struct bt_plugin *plugin = g_ptr_array_index(loaded_plugins, i);
741
742 component_classes_count += bt_plugin_get_component_class_count(plugin);
743 }
33bceaf8 744
290725f7
PP
745 printf("Found %s%d%s component classes in %s%d%s plugins.\n",
746 bt_common_color_bold(),
747 component_classes_count,
748 bt_common_color_reset(),
749 bt_common_color_bold(),
750 plugins_count,
751 bt_common_color_reset());
752
753 for (i = 0; i < plugins_count; i++) {
754 int j;
755 struct bt_plugin *plugin = g_ptr_array_index(loaded_plugins, i);
290725f7
PP
756
757 component_classes_count =
758 bt_plugin_get_component_class_count(plugin);
22e22462
PP
759 printf("\n");
760 print_plugin_info(plugin);
290725f7
PP
761
762 if (component_classes_count == 0) {
763 printf(" %sComponent classes%s: (None)\n",
764 bt_common_color_bold(),
765 bt_common_color_reset());
766 } else {
767 printf(" %sComponent classes%s:\n",
768 bt_common_color_bold(),
769 bt_common_color_reset());
770 }
771
772 for (j = 0; j < component_classes_count; j++) {
773 struct bt_component_class *comp_class =
774 bt_plugin_get_component_class(plugin, j);
775 const char *comp_class_name =
776 bt_component_class_get_name(comp_class);
777 const char *comp_class_description =
778 bt_component_class_get_description(comp_class);
779 enum bt_component_class_type type =
780 bt_component_class_get_type(comp_class);
781
22e22462
PP
782 printf(" ");
783 print_plugin_comp_cls_opt(stdout,
784 bt_plugin_get_name(plugin), comp_class_name,
785 type);
290725f7
PP
786
787 if (comp_class_description) {
788 printf(": %s", comp_class_description);
789 }
790
791 printf("\n");
792 bt_put(comp_class);
793 }
794 }
795
796end:
797 return ret;
798}
799
800static int cmd_convert(struct bt_config *cfg)
801{
802 int ret = 0;
803 struct bt_component_class *source_class = NULL;
804 struct bt_component_class *sink_class = NULL;
805 struct bt_component *source = NULL, *sink = NULL;
806 struct bt_value *source_params = NULL, *sink_params = NULL;
807 enum bt_component_status sink_status;
808 struct bt_config_component *source_cfg = NULL, *sink_cfg = NULL;
809
810 /* TODO handle more than 1 source and 1 sink. */
811 if (cfg->cmd_data.convert.sources->len != 1 ||
812 cfg->cmd_data.convert.sinks->len != 1) {
98ecef32
MD
813 ret = -1;
814 goto end;
33bceaf8
JG
815 }
816
290725f7
PP
817 ret = load_all_plugins(cfg->cmd_data.convert.plugin_paths);
818 if (ret) {
cba174d5
JG
819 goto end;
820 }
821
290725f7 822 source_cfg = bt_config_get_component(cfg->cmd_data.convert.sources, 0);
e5bc7f81 823 source_params = bt_get(source_cfg->params);
33b34c43
PP
824 source_class = find_component_class(source_cfg->plugin_name->str,
825 source_cfg->component_name->str,
d3e4dcd8 826 BT_COMPONENT_CLASS_TYPE_SOURCE);
56a1cced 827 if (!source_class) {
e5bc7f81
JG
828 fprintf(stderr, "Could not find %s.%s source component class. Aborting...\n",
829 source_cfg->plugin_name->str,
830 source_cfg->component_name->str);
56a1cced
JG
831 ret = -1;
832 goto end;
833 }
7c7c0433 834
290725f7 835 sink_cfg = bt_config_get_component(cfg->cmd_data.convert.sinks, 0);
e5bc7f81 836 sink_params = bt_get(sink_cfg->params);
33b34c43
PP
837 sink_class = find_component_class(sink_cfg->plugin_name->str,
838 sink_cfg->component_name->str,
d3e4dcd8 839 BT_COMPONENT_CLASS_TYPE_SINK);
7c7c0433 840 if (!sink_class) {
e5bc7f81
JG
841 fprintf(stderr, "Could not find %s.%s output component class. Aborting...\n",
842 sink_cfg->plugin_name->str,
843 sink_cfg->component_name->str);
7c7c0433
JG
844 ret = -1;
845 goto end;
846 }
847
e5bc7f81 848 source = bt_component_create(source_class, "source", source_params);
56a1cced 849 if (!source) {
e5bc7f81 850 fprintf(stderr, "Failed to instantiate selected source component. Aborting...\n");
c42c79ea
PP
851 ret = -1;
852 goto end;
853 }
56a1cced 854
e5bc7f81 855 sink = bt_component_create(sink_class, "sink", sink_params);
7c7c0433 856 if (!sink) {
e5bc7f81 857 fprintf(stderr, "Failed to instantiate selected output component. Aborting...\n");
7c7c0433 858 ret = -1;
2e339de1
JG
859 goto end;
860 }
861
6c2f3ee5
JG
862 ret = connect_source_sink(source, source_cfg, sink);
863 if (ret) {
290725f7 864 ret = -1;
fec2a9f2
JG
865 goto end;
866 }
78586d8a 867
fec2a9f2
JG
868 while (true) {
869 sink_status = bt_component_sink_consume(sink);
fec2a9f2
JG
870 switch (sink_status) {
871 case BT_COMPONENT_STATUS_AGAIN:
872 /* Wait for an arbitraty 500 ms. */
873 usleep(500000);
78586d8a 874 break;
fec2a9f2
JG
875 case BT_COMPONENT_STATUS_OK:
876 break;
877 case BT_COMPONENT_STATUS_END:
878 goto end;
879 default:
880 fprintf(stderr, "Sink component returned an error, aborting...\n");
881 ret = -1;
882 goto end;
78586d8a 883 }
fec2a9f2 884 }
290725f7 885
11e1d048 886end:
7c7c0433
JG
887 BT_PUT(sink_class);
888 BT_PUT(source_class);
889 BT_PUT(source);
890 BT_PUT(sink);
891 BT_PUT(source_params);
892 BT_PUT(sink_params);
e5bc7f81
JG
893 BT_PUT(sink_cfg);
894 BT_PUT(source_cfg);
290725f7
PP
895 return ret;
896}
897
898static void warn_command_name_and_directory_clash(struct bt_config *cfg)
899{
900 if (!cfg->command_name) {
901 return;
902 }
903
904 if (g_file_test(cfg->command_name,
905 G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) {
906 fprintf(stderr, "\nNOTE: The `%s` command was executed. If you meant to convert a\n",
907 cfg->command_name);
908 fprintf(stderr, "trace located in the local `%s` directory, please use:\n",
909 cfg->command_name);
910 fprintf(stderr, "\n");
911 fprintf(stderr, " babeltrace convert %s [OPTIONS]\n",
912 cfg->command_name);
913 }
914}
915
916int main(int argc, const char **argv)
917{
918 int ret;
919 int retcode;
920 struct bt_config *cfg;
921
922 init_loaded_plugins_array();
923 cfg = bt_config_from_args_with_defaults(argc, argv, &retcode);
924
925 if (retcode < 0) {
926 /* Quit without errors; typically usage/version */
927 retcode = 0;
928 goto end;
929 }
930
931 if (retcode > 0) {
932 goto end;
933 }
934
935 if (!cfg) {
936 fprintf(stderr, "Failed to create Babeltrace configuration\n");
937 goto end;
938 }
939
940 babeltrace_debug = cfg->debug;
941 babeltrace_verbose = cfg->verbose;
942 print_cfg(cfg);
943
944 switch (cfg->command) {
945 case BT_CONFIG_COMMAND_CONVERT:
946 ret = cmd_convert(cfg);
947 break;
948 case BT_CONFIG_COMMAND_LIST_PLUGINS:
949 ret = cmd_list_plugins(cfg);
950 break;
22e22462
PP
951 case BT_CONFIG_COMMAND_HELP:
952 ret = cmd_help(cfg);
953 break;
290725f7
PP
954 default:
955 assert(false);
956 }
957
958 warn_command_name_and_directory_clash(cfg);
959 retcode = ret ? 1 : 0;
960
961end:
962 BT_PUT(cfg);
33b34c43 963 fini_loaded_plugins_array();
290725f7 964 return retcode;
4c8bfb7e 965}
This page took 0.086449 seconds and 4 git commands to generate.