Fix: missing reference release in field reset
[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
87796884
PP
115static char *escape_name_for_shell(const char *input)
116{
117 char *output = g_malloc0(strlen(input) * 5 + 1);
118 const char *in;
119 char *out = output;
120
121 if (!output) {
122 goto end;
123 }
124
125 for (in = input; *in != '\0'; in++) {
126 switch (*in) {
127 case '\\':
128 *out++ = '\\';
129 *out++ = '\\';
130 break;
131 case '\'':
132 *out++ = '\'';
133 *out++ = '"';
134 *out++ = '\'';
135 *out++ = '"';
136 *out++ = '\'';
137 break;
138 case '.':
139 *out++ = '\\';
140 *out++ = '.';
141 break;
142 default:
143 *out++ = *in;
144 break;
145 }
146 }
147
148end:
149 return output;
150}
151
152static
153const char *component_type_str(enum bt_component_class_type type)
154{
155 switch (type) {
156 case BT_COMPONENT_CLASS_TYPE_SOURCE:
157 return "source";
158 case BT_COMPONENT_CLASS_TYPE_SINK:
159 return "sink";
160 case BT_COMPONENT_CLASS_TYPE_FILTER:
161 return "filter";
162 case BT_COMPONENT_CLASS_TYPE_UNKNOWN:
163 default:
164 return "unknown";
165 }
166}
167
168static void print_plugin_comp_cls_opt(FILE *fh, const char *plugin_name,
169 const char *comp_cls_name, enum bt_component_class_type type)
170{
171 char *shell_plugin_name = NULL;
172 char *shell_comp_cls_name = NULL;
173
174 shell_plugin_name = escape_name_for_shell(plugin_name);
175 if (!shell_plugin_name) {
176 goto end;
177 }
178
179 shell_comp_cls_name = escape_name_for_shell(comp_cls_name);
180 if (!shell_comp_cls_name) {
181 goto end;
182 }
183
184 fprintf(fh, "%s%s--%s%s %s'%s%s%s%s.%s%s%s'",
185 bt_common_color_bold(),
186 bt_common_color_fg_cyan(),
187 component_type_str(type),
188 bt_common_color_reset(),
189 bt_common_color_fg_default(),
190 bt_common_color_bold(),
191 bt_common_color_fg_blue(),
192 shell_plugin_name,
193 bt_common_color_fg_default(),
194 bt_common_color_fg_yellow(),
195 shell_comp_cls_name,
196 bt_common_color_reset());
197
198end:
199 g_free(shell_plugin_name);
200 g_free(shell_comp_cls_name);
201}
202
c42c79ea 203static
290725f7 204void print_value(struct bt_value *, size_t);
c42c79ea 205
c1081aa6
PP
206static
207void print_value_rec(struct bt_value *, size_t);
208
c42c79ea
PP
209static
210bool print_map_value(const char *key, struct bt_value *object, void *data)
211{
290725f7
PP
212 size_t *indent = data;
213
214 print_indent(*indent);
215 printf("%s: ", key);
216
217 if (bt_value_is_array(object) &&
218 bt_value_array_is_empty(object)) {
219 printf("[ ]\n");
220 return true;
221 }
222
223 if (bt_value_is_map(object) &&
224 bt_value_map_is_empty(object)) {
225 printf("{ }\n");
226 return true;
227 }
c42c79ea 228
290725f7
PP
229 if (bt_value_is_array(object) ||
230 bt_value_is_map(object)) {
231 printf("\n");
232 }
c42c79ea 233
c1081aa6 234 print_value_rec(object, *indent + 2);
c42c79ea
PP
235 return true;
236}
237
238static
c1081aa6 239void print_value_rec(struct bt_value *value, size_t indent)
c42c79ea
PP
240{
241 bool bool_val;
242 int64_t int_val;
243 double dbl_val;
244 const char *str_val;
245 int size;
246 int i;
247
248 if (!value) {
249 return;
250 }
251
c42c79ea
PP
252 switch (bt_value_get_type(value)) {
253 case BT_VALUE_TYPE_NULL:
c1081aa6
PP
254 printf("%snull%s\n", bt_common_color_bold(),
255 bt_common_color_reset());
c42c79ea
PP
256 break;
257 case BT_VALUE_TYPE_BOOL:
258 bt_value_bool_get(value, &bool_val);
c1081aa6
PP
259 printf("%s%s%s%s\n", bt_common_color_bold(),
260 bt_common_color_fg_cyan(), bool_val ? "yes" : "no",
261 bt_common_color_reset());
c42c79ea
PP
262 break;
263 case BT_VALUE_TYPE_INTEGER:
264 bt_value_integer_get(value, &int_val);
c1081aa6
PP
265 printf("%s%s%" PRId64 "%s\n", bt_common_color_bold(),
266 bt_common_color_fg_red(), int_val,
267 bt_common_color_reset());
c42c79ea
PP
268 break;
269 case BT_VALUE_TYPE_FLOAT:
270 bt_value_float_get(value, &dbl_val);
c1081aa6
PP
271 printf("%s%s%lf%s\n", bt_common_color_bold(),
272 bt_common_color_fg_red(), dbl_val,
273 bt_common_color_reset());
c42c79ea
PP
274 break;
275 case BT_VALUE_TYPE_STRING:
276 bt_value_string_get(value, &str_val);
c1081aa6
PP
277 printf("%s%s%s%s\n", bt_common_color_bold(),
278 bt_common_color_fg_green(), str_val,
279 bt_common_color_reset());
c42c79ea
PP
280 break;
281 case BT_VALUE_TYPE_ARRAY:
282 size = bt_value_array_size(value);
290725f7
PP
283 assert(size >= 0);
284
285 if (size == 0) {
286 print_indent(indent);
287 printf("[ ]\n");
288 break;
289 }
c42c79ea
PP
290
291 for (i = 0; i < size; i++) {
292 struct bt_value *element =
293 bt_value_array_get(value, i);
294
290725f7
PP
295 assert(element);
296 print_indent(indent);
297 printf("- ");
298
299 if (bt_value_is_array(element) &&
300 bt_value_array_is_empty(element)) {
301 printf("[ ]\n");
302 continue;
303 }
304
305 if (bt_value_is_map(element) &&
306 bt_value_map_is_empty(element)) {
307 printf("{ }\n");
308 continue;
309 }
310
311 if (bt_value_is_array(element) ||
312 bt_value_is_map(element)) {
313 printf("\n");
314 }
315
c1081aa6 316 print_value_rec(element, indent + 2);
c42c79ea
PP
317 BT_PUT(element);
318 }
c42c79ea
PP
319 break;
320 case BT_VALUE_TYPE_MAP:
321 if (bt_value_map_is_empty(value)) {
290725f7
PP
322 print_indent(indent);
323 printf("{ }\n");
324 break;
c42c79ea
PP
325 }
326
290725f7 327 bt_value_map_foreach(value, print_map_value, &indent);
c42c79ea
PP
328 break;
329 default:
330 assert(false);
331 }
332}
333
c1081aa6
PP
334static
335void print_value(struct bt_value *value, size_t indent)
336{
337 if (!bt_value_is_array(value) && !bt_value_is_map(value)) {
338 print_indent(indent);
339 }
340
341 print_value_rec(value, indent);
342}
343
c42c79ea
PP
344static
345void print_bt_config_component(struct bt_config_component *bt_config_component)
346{
87796884
PP
347 printf(" ");
348 print_plugin_comp_cls_opt(stdout, bt_config_component->plugin_name->str,
349 bt_config_component->component_name->str,
350 bt_config_component->type);
351 printf(":\n");
3b6cfcc5
PP
352
353 if (bt_config_component->instance_name->len > 0) {
354 printf(" Name: %s\n",
355 bt_config_component->instance_name->str);
356 }
357
290725f7
PP
358 printf(" Parameters:\n");
359 print_value(bt_config_component->params, 8);
c42c79ea
PP
360}
361
362static
363void print_bt_config_components(GPtrArray *array)
364{
365 size_t i;
366
367 for (i = 0; i < array->len; i++) {
368 struct bt_config_component *cfg_component =
e5bc7f81 369 bt_config_get_component(array, i);
c42c79ea
PP
370 print_bt_config_component(cfg_component);
371 BT_PUT(cfg_component);
372 }
373}
374
290725f7
PP
375static
376void print_plugin_paths(struct bt_value *plugin_paths)
377{
378 printf(" Plugin paths:\n");
379 print_value(plugin_paths, 4);
380}
381
382static
383void print_cfg_convert(struct bt_config *cfg)
384{
ebba3338
PP
385 size_t i;
386
290725f7
PP
387 printf(" Force correlate: %s\n",
388 cfg->cmd_data.convert.force_correlate ? "yes" : "no");
389 print_plugin_paths(cfg->cmd_data.convert.plugin_paths);
05a67631
PP
390 printf(" Print CTF metadata: %s\n",
391 cfg->cmd_data.convert.print_ctf_metadata ? "yes" : "no");
290725f7
PP
392 printf(" Source component instances:\n");
393 print_bt_config_components(cfg->cmd_data.convert.sources);
ebba3338
PP
394
395 if (cfg->cmd_data.convert.filters->len > 0) {
396 printf(" Filter component instances:\n");
397 print_bt_config_components(cfg->cmd_data.convert.filters);
398 }
399
290725f7
PP
400 printf(" Sink component instances:\n");
401 print_bt_config_components(cfg->cmd_data.convert.sinks);
ebba3338
PP
402 printf(" Connections:\n");
403
404 for (i = 0; i < cfg->cmd_data.convert.connections->len; i++) {
405 struct bt_config_connection *cfg_connection =
406 g_ptr_array_index(cfg->cmd_data.convert.connections,
407 i);
408
409 printf(" %s%s%s -> %s%s%s\n",
410 cfg_connection->src_instance_name->str,
411 cfg_connection->src_port_name->len > 0 ? "." : "",
412 cfg_connection->src_port_name->str,
413 cfg_connection->dst_instance_name->str,
414 cfg_connection->dst_port_name->len > 0 ? "." : "",
415 cfg_connection->dst_port_name->str);
416 }
290725f7
PP
417}
418
419static
420void print_cfg_list_plugins(struct bt_config *cfg)
421{
422 print_plugin_paths(cfg->cmd_data.list_plugins.plugin_paths);
423}
424
c1081aa6
PP
425static
426void print_cfg_help(struct bt_config *cfg)
427{
428 print_plugin_paths(cfg->cmd_data.help.plugin_paths);
429}
430
431static
a67681c1 432void print_cfg_query(struct bt_config *cfg)
c1081aa6 433{
a67681c1
PP
434 print_plugin_paths(cfg->cmd_data.query.plugin_paths);
435 printf(" Object: `%s`\n", cfg->cmd_data.query.object->str);
c1081aa6 436 printf(" Component class:\n");
a67681c1 437 print_bt_config_component(cfg->cmd_data.query.cfg_component);
c1081aa6
PP
438}
439
c42c79ea
PP
440static
441void print_cfg(struct bt_config *cfg)
442{
00447e45
PP
443 if (!babeltrace_verbose) {
444 return;
445 }
446
290725f7
PP
447 printf("Configuration:\n");
448 printf(" Debug mode: %s\n", cfg->debug ? "yes" : "no");
449 printf(" Verbose mode: %s\n", cfg->verbose ? "yes" : "no");
450
451 switch (cfg->command) {
452 case BT_CONFIG_COMMAND_CONVERT:
453 print_cfg_convert(cfg);
454 break;
455 case BT_CONFIG_COMMAND_LIST_PLUGINS:
456 print_cfg_list_plugins(cfg);
c1081aa6
PP
457 break;
458 case BT_CONFIG_COMMAND_HELP:
459 print_cfg_help(cfg);
460 break;
a67681c1
PP
461 case BT_CONFIG_COMMAND_QUERY:
462 print_cfg_query(cfg);
290725f7
PP
463 break;
464 default:
465 assert(false);
466 }
c42c79ea
PP
467}
468
6c2f3ee5
JG
469static
470struct bt_component *create_trimmer(struct bt_config_component *source_cfg)
471{
472 struct bt_component *trimmer = NULL;
473 struct bt_component_class *trimmer_class = NULL;
474 struct bt_value *trimmer_params = NULL;
528debdf 475 struct bt_value *value;
6c2f3ee5 476
6c2f3ee5
JG
477 trimmer_params = bt_value_map_create();
478 if (!trimmer_params) {
479 goto end;
480 }
481
528debdf
MD
482 value = bt_value_map_get(source_cfg->params, "begin");
483 if (value) {
6c2f3ee5 484 enum bt_value_status ret;
6c2f3ee5 485
528debdf 486 ret = bt_value_map_insert(trimmer_params, "begin",
6c2f3ee5
JG
487 value);
488 BT_PUT(value);
489 if (ret) {
490 goto end;
491 }
492 }
528debdf
MD
493 value = bt_value_map_get(source_cfg->params, "end");
494 if (value) {
6c2f3ee5 495 enum bt_value_status ret;
6c2f3ee5 496
528debdf
MD
497 ret = bt_value_map_insert(trimmer_params, "end",
498 value);
499 BT_PUT(value);
500 if (ret) {
6c2f3ee5
JG
501 goto end;
502 }
528debdf
MD
503 }
504 value = bt_value_map_get(source_cfg->params, "clock-gmt");
505 if (value) {
506 enum bt_value_status ret;
6c2f3ee5 507
528debdf 508 ret = bt_value_map_insert(trimmer_params, "clock-gmt",
6c2f3ee5
JG
509 value);
510 BT_PUT(value);
511 if (ret) {
512 goto end;
513 }
514 }
515
33b34c43 516 trimmer_class = find_component_class("utils", "trimmer",
d3e4dcd8 517 BT_COMPONENT_CLASS_TYPE_FILTER);
6c2f3ee5
JG
518 if (!trimmer_class) {
519 fprintf(stderr, "Could not find trimmer component class. Aborting...\n");
520 goto end;
521 }
522 trimmer = bt_component_create(trimmer_class, "source_trimmer",
523 trimmer_params);
524 if (!trimmer) {
525 goto end;
526 }
527end:
528 bt_put(trimmer_params);
529 bt_put(trimmer_class);
530 return trimmer;
531}
532
533static
61ddbc8a
JG
534int connect_source_sink(struct bt_graph *graph,
535 struct bt_component *source,
6c2f3ee5
JG
536 struct bt_config_component *source_cfg,
537 struct bt_component *sink)
538{
539 int ret = 0;
61ddbc8a 540 struct bt_connection *connection = NULL;
6c2f3ee5 541 struct bt_component *trimmer = NULL;
61ddbc8a
JG
542 struct bt_port *source_port =
543 bt_component_source_get_default_output_port(source);
544 struct bt_port *sink_port =
545 bt_component_sink_get_default_input_port(sink);
546 struct bt_port *to_sink_port = NULL;
547 struct bt_port *trimmer_input_port = NULL;
548
549 if (!source_port) {
550 fprintf(stderr, "Failed to find default source output port. Aborting...\n");
551 ret = -1;
552 goto end;
553 }
554 if (!sink_port) {
555 fprintf(stderr, "Failed to find default sink input port. Aborting...\n");
556 ret = -1;
557 goto end;
558 }
6c2f3ee5 559
528debdf
MD
560 if (bt_value_map_has_key(source_cfg->params, "begin")
561 || bt_value_map_has_key(source_cfg->params, "end")) {
6c2f3ee5 562 /* A trimmer must be inserted in the graph. */
6c2f3ee5
JG
563 trimmer = create_trimmer(source_cfg);
564 if (!trimmer) {
565 fprintf(stderr, "Failed to create trimmer component. Aborting...\n");
566 ret = -1;
567 goto end;
568 }
569
61ddbc8a
JG
570 trimmer_input_port = bt_component_filter_get_default_input_port(
571 trimmer);
572 if (!trimmer_input_port) {
573 fprintf(stderr, "Failed to find trimmer input port. Aborting...\n");
574 ret = -1;
575 goto end;
576 }
577 to_sink_port = bt_component_filter_get_default_output_port(
578 trimmer);
579 if (!to_sink_port) {
580 fprintf(stderr, "Failed to find trimmer output port. Aborting...\n");
6c2f3ee5
JG
581 ret = -1;
582 goto end;
583 }
584
61ddbc8a
JG
585 connection = bt_graph_connect(graph, source_port,
586 trimmer_input_port);
587 if (!connection) {
588 fprintf(stderr, "Failed to connect source to trimmer. Aborting...\n");
6c2f3ee5
JG
589 ret = -1;
590 goto end;
591 }
61ddbc8a 592 BT_PUT(connection);
6c2f3ee5 593 } else {
61ddbc8a 594 BT_MOVE(to_sink_port, source_port);
6c2f3ee5
JG
595 }
596
61ddbc8a
JG
597 connection = bt_graph_connect(graph, to_sink_port, sink_port);
598 if (!connection) {
599 fprintf(stderr, "Failed to connect to sink. Aborting...\n");
6c2f3ee5
JG
600 ret = -1;
601 goto end;
602 }
603end:
604 bt_put(trimmer);
61ddbc8a
JG
605 bt_put(source_port);
606 bt_put(sink_port);
607 bt_put(to_sink_port);
608 bt_put(connection);
6c2f3ee5
JG
609 return ret;
610}
611
33b34c43
PP
612static
613void add_to_loaded_plugins(struct bt_plugin **plugins)
98ecef32 614{
33b34c43
PP
615 while (*plugins) {
616 struct bt_plugin *plugin = *plugins;
617 /* Check if it's already loaded (from another path). */
618 struct bt_plugin *loaded_plugin =
619 find_plugin(bt_plugin_get_name(plugin));
620
621 if (loaded_plugin) {
622 printf_verbose("Not loading plugin `%s`: already loaded from `%s`\n",
623 bt_plugin_get_path(plugin),
624 bt_plugin_get_path(loaded_plugin));
625 BT_PUT(loaded_plugin);
626 BT_PUT(plugin);
627 } else {
628 /* Transfer ownership to global array. */
629 g_ptr_array_add(loaded_plugins, plugin);
630 }
631 *(plugins++) = NULL;
632 }
633}
634
635static
290725f7 636int load_dynamic_plugins(struct bt_value *plugin_paths)
33b34c43
PP
637{
638 int nr_paths, i, ret = 0;
98ecef32 639
290725f7 640 nr_paths = bt_value_array_size(plugin_paths);
98ecef32 641 if (nr_paths < 0) {
33b34c43
PP
642 ret = -1;
643 goto end;
98ecef32 644 }
33b34c43 645
98ecef32
MD
646 for (i = 0; i < nr_paths; i++) {
647 struct bt_value *plugin_path_value = NULL;
648 const char *plugin_path;
33b34c43 649 struct bt_plugin **plugins;
98ecef32 650
290725f7 651 plugin_path_value = bt_value_array_get(plugin_paths, i);
98ecef32
MD
652 if (bt_value_string_get(plugin_path_value,
653 &plugin_path)) {
654 BT_PUT(plugin_path_value);
655 continue;
656 }
33b34c43 657
5a3ee633 658 plugins = bt_plugin_create_all_from_dir(plugin_path, false);
33b34c43 659 if (!plugins) {
98ecef32
MD
660 printf_debug("Unable to dynamically load plugins from path %s.\n",
661 plugin_path);
33b34c43
PP
662 BT_PUT(plugin_path_value);
663 continue;
98ecef32 664 }
33b34c43
PP
665
666 add_to_loaded_plugins(plugins);
667 free(plugins);
668
98ecef32
MD
669 BT_PUT(plugin_path_value);
670 }
33b34c43
PP
671end:
672 return ret;
673}
674
675static
676int load_static_plugins(void)
677{
678 int ret = 0;
679 struct bt_plugin **plugins;
680
681 plugins = bt_plugin_create_all_from_static();
682 if (!plugins) {
683 printf_debug("Unable to load static plugins.\n");
684 ret = -1;
685 goto end;
686 }
687
688 add_to_loaded_plugins(plugins);
689 free(plugins);
690end:
691 return ret;
98ecef32
MD
692}
693
290725f7
PP
694static int load_all_plugins(struct bt_value *plugin_paths)
695{
696 int ret = 0;
33b34c43 697
290725f7
PP
698 if (load_dynamic_plugins(plugin_paths)) {
699 fprintf(stderr, "Failed to load dynamic plugins.\n");
700 ret = -1;
c1870f57
JG
701 goto end;
702 }
703
290725f7
PP
704 if (load_static_plugins()) {
705 fprintf(stderr, "Failed to load static plugins.\n");
706 ret = -1;
c1870f57
JG
707 goto end;
708 }
709
290725f7
PP
710end:
711 return ret;
712}
713
22e22462
PP
714static void print_plugin_info(struct bt_plugin *plugin)
715{
716 unsigned int major, minor, patch;
717 const char *extra;
718 enum bt_plugin_status version_status;
719 const char *plugin_name;
720 const char *path;
721 const char *author;
722 const char *license;
723 const char *plugin_description;
724
725 plugin_name = bt_plugin_get_name(plugin);
726 path = bt_plugin_get_path(plugin);
727 author = bt_plugin_get_author(plugin);
728 license = bt_plugin_get_license(plugin);
729 plugin_description = bt_plugin_get_description(plugin);
730 version_status = bt_plugin_get_version(plugin, &major, &minor,
731 &patch, &extra);
732 printf("%s%s%s%s:\n", bt_common_color_bold(),
733 bt_common_color_fg_blue(), plugin_name,
734 bt_common_color_reset());
735 printf(" %sPath%s: %s\n", bt_common_color_bold(),
736 bt_common_color_reset(), path ? path : "(None)");
737
738 if (version_status == BT_PLUGIN_STATUS_OK) {
739 printf(" %sVersion%s: %u.%u.%u",
740 bt_common_color_bold(), bt_common_color_reset(),
741 major, minor, patch);
742
743 if (extra) {
744 printf("%s", extra);
745 }
746
747 printf("\n");
748 }
749
750 printf(" %sDescription%s: %s\n", bt_common_color_bold(),
751 bt_common_color_reset(),
752 plugin_description ? plugin_description : "(None)");
753 printf(" %sAuthor%s: %s\n", bt_common_color_bold(),
754 bt_common_color_reset(), author ? author : "(Unknown)");
755 printf(" %sLicense%s: %s\n", bt_common_color_bold(),
756 bt_common_color_reset(),
757 license ? license : "(Unknown)");
758}
759
a67681c1 760static int cmd_query(struct bt_config *cfg)
63ce0e1d
PP
761{
762 int ret;
763 struct bt_component_class *comp_cls = NULL;
764 struct bt_value *results = NULL;
765
766 ret = load_all_plugins(cfg->cmd_data.list_plugins.plugin_paths);
767 if (ret) {
768 goto end;
769 }
770
a67681c1
PP
771 comp_cls = find_component_class(cfg->cmd_data.query.cfg_component->plugin_name->str,
772 cfg->cmd_data.query.cfg_component->component_name->str,
773 cfg->cmd_data.query.cfg_component->type);
63ce0e1d
PP
774 if (!comp_cls) {
775 fprintf(stderr, "%s%sCannot find component class %s",
776 bt_common_color_bold(),
777 bt_common_color_fg_red(),
778 bt_common_color_reset());
779 print_plugin_comp_cls_opt(stderr,
a67681c1
PP
780 cfg->cmd_data.query.cfg_component->plugin_name->str,
781 cfg->cmd_data.query.cfg_component->component_name->str,
782 cfg->cmd_data.query.cfg_component->type);
63ce0e1d
PP
783 fprintf(stderr, "\n");
784 ret = -1;
785 goto end;
786 }
787
a67681c1
PP
788 results = bt_component_class_query(comp_cls,
789 cfg->cmd_data.query.object->str,
790 cfg->cmd_data.query.cfg_component->params);
63ce0e1d
PP
791 if (!results) {
792 fprintf(stderr, "%s%sFailed to query info to %s",
793 bt_common_color_bold(),
794 bt_common_color_fg_red(),
795 bt_common_color_reset());
796 print_plugin_comp_cls_opt(stderr,
a67681c1
PP
797 cfg->cmd_data.query.cfg_component->plugin_name->str,
798 cfg->cmd_data.query.cfg_component->component_name->str,
799 cfg->cmd_data.query.cfg_component->type);
800 fprintf(stderr, "%s%s with object `%s`%s\n",
63ce0e1d
PP
801 bt_common_color_bold(),
802 bt_common_color_fg_red(),
a67681c1 803 cfg->cmd_data.query.object->str,
63ce0e1d
PP
804 bt_common_color_reset());
805 ret = -1;
806 goto end;
807 }
808
809 print_value(results, 0);
810
811end:
812 bt_put(comp_cls);
813 bt_put(results);
814 return ret;
815}
816
22e22462
PP
817static int cmd_help(struct bt_config *cfg)
818{
819 int ret;
820 struct bt_plugin *plugin = NULL;
821 size_t i;
822
823 ret = load_all_plugins(cfg->cmd_data.list_plugins.plugin_paths);
824 if (ret) {
825 goto end;
826 }
827
90de159b 828 plugin = find_plugin(cfg->cmd_data.help.cfg_component->plugin_name->str);
22e22462
PP
829 if (!plugin) {
830 fprintf(stderr, "%s%sCannot find plugin %s%s%s\n",
831 bt_common_color_bold(), bt_common_color_fg_red(),
832 bt_common_color_fg_blue(),
90de159b 833 cfg->cmd_data.help.cfg_component->plugin_name->str,
22e22462
PP
834 bt_common_color_reset());
835 ret = -1;
836 goto end;
837 }
838
839 print_plugin_info(plugin);
840 printf(" %sComponent classes%s: %d\n",
841 bt_common_color_bold(),
842 bt_common_color_reset(),
843 bt_plugin_get_component_class_count(plugin));
844
845
90de159b 846 if (cfg->cmd_data.help.cfg_component->type !=
22e22462
PP
847 BT_COMPONENT_CLASS_TYPE_UNKNOWN) {
848 struct bt_component_class *needed_comp_cls =
849 find_component_class(
90de159b
PP
850 cfg->cmd_data.help.cfg_component->plugin_name->str,
851 cfg->cmd_data.help.cfg_component->component_name->str,
852 cfg->cmd_data.help.cfg_component->type);
22e22462
PP
853
854 if (!needed_comp_cls) {
855 fprintf(stderr, "\n%s%sCannot find component class %s",
856 bt_common_color_bold(),
857 bt_common_color_fg_red(),
858 bt_common_color_reset());
859 print_plugin_comp_cls_opt(stderr,
90de159b
PP
860 cfg->cmd_data.help.cfg_component->plugin_name->str,
861 cfg->cmd_data.help.cfg_component->component_name->str,
862 cfg->cmd_data.help.cfg_component->type);
22e22462
PP
863 fprintf(stderr, "\n");
864 ret = -1;
865 goto end;
866 }
867
868 bt_put(needed_comp_cls);
869 }
870
871 for (i = 0; i < bt_plugin_get_component_class_count(plugin); i++) {
872 struct bt_component_class *comp_cls =
873 bt_plugin_get_component_class(plugin, i);
874 const char *comp_class_name =
875 bt_component_class_get_name(comp_cls);
876 const char *comp_class_description =
877 bt_component_class_get_description(comp_cls);
878 const char *comp_class_help =
879 bt_component_class_get_help(comp_cls);
880 enum bt_component_class_type type =
881 bt_component_class_get_type(comp_cls);
882
883 assert(comp_cls);
884
90de159b 885 if (cfg->cmd_data.help.cfg_component->type !=
22e22462 886 BT_COMPONENT_CLASS_TYPE_UNKNOWN) {
90de159b 887 if (strcmp(cfg->cmd_data.help.cfg_component->component_name->str,
22e22462
PP
888 comp_class_name) != 0 &&
889 type ==
90de159b 890 cfg->cmd_data.help.cfg_component->type) {
22e22462
PP
891 bt_put(comp_cls);
892 continue;
893 }
894 }
895
896 printf("\n");
897 print_plugin_comp_cls_opt(stdout,
90de159b 898 cfg->cmd_data.help.cfg_component->plugin_name->str,
22e22462
PP
899 comp_class_name,
900 type);
901 printf("\n");
902 printf(" %sDescription%s: %s\n", bt_common_color_bold(),
903 bt_common_color_reset(),
904 comp_class_description ? comp_class_description : "(None)");
905
906 if (comp_class_help) {
907 printf("\n%s\n", comp_class_help);
908 }
909
910 bt_put(comp_cls);
911 }
912
913end:
914 bt_put(plugin);
915 return ret;
916}
917
290725f7
PP
918static int cmd_list_plugins(struct bt_config *cfg)
919{
920 int ret;
921 int plugins_count, component_classes_count = 0, i;
922
923 ret = load_all_plugins(cfg->cmd_data.list_plugins.plugin_paths);
924 if (ret) {
56a1cced
JG
925 goto end;
926 }
927
22e22462
PP
928 printf("From the following plugin paths:\n\n");
929 print_value(cfg->cmd_data.list_plugins.plugin_paths, 2);
930 printf("\n");
290725f7
PP
931 plugins_count = loaded_plugins->len;
932 if (plugins_count == 0) {
933 fprintf(stderr, "%s%sNo plugins found.%s\n",
934 bt_common_color_bold(), bt_common_color_fg_red(),
935 bt_common_color_reset());
936 fprintf(stderr, "\n");
937 fprintf(stderr, "Please make sure your plugin search path is set correctly. You can use\n");
938 fprintf(stderr, "the --plugin-path command-line option or the BABELTRACE_PLUGIN_PATH\n");
939 fprintf(stderr, "environment variable.\n");
56a1cced
JG
940 ret = -1;
941 goto end;
942 }
943
290725f7
PP
944 for (i = 0; i < plugins_count; i++) {
945 struct bt_plugin *plugin = g_ptr_array_index(loaded_plugins, i);
946
947 component_classes_count += bt_plugin_get_component_class_count(plugin);
948 }
33bceaf8 949
290725f7
PP
950 printf("Found %s%d%s component classes in %s%d%s plugins.\n",
951 bt_common_color_bold(),
952 component_classes_count,
953 bt_common_color_reset(),
954 bt_common_color_bold(),
955 plugins_count,
956 bt_common_color_reset());
957
958 for (i = 0; i < plugins_count; i++) {
959 int j;
960 struct bt_plugin *plugin = g_ptr_array_index(loaded_plugins, i);
290725f7
PP
961
962 component_classes_count =
963 bt_plugin_get_component_class_count(plugin);
22e22462
PP
964 printf("\n");
965 print_plugin_info(plugin);
290725f7
PP
966
967 if (component_classes_count == 0) {
968 printf(" %sComponent classes%s: (None)\n",
969 bt_common_color_bold(),
970 bt_common_color_reset());
971 } else {
972 printf(" %sComponent classes%s:\n",
973 bt_common_color_bold(),
974 bt_common_color_reset());
975 }
976
977 for (j = 0; j < component_classes_count; j++) {
978 struct bt_component_class *comp_class =
979 bt_plugin_get_component_class(plugin, j);
980 const char *comp_class_name =
981 bt_component_class_get_name(comp_class);
982 const char *comp_class_description =
983 bt_component_class_get_description(comp_class);
984 enum bt_component_class_type type =
985 bt_component_class_get_type(comp_class);
986
22e22462
PP
987 printf(" ");
988 print_plugin_comp_cls_opt(stdout,
989 bt_plugin_get_name(plugin), comp_class_name,
990 type);
290725f7
PP
991
992 if (comp_class_description) {
993 printf(": %s", comp_class_description);
994 }
995
996 printf("\n");
997 bt_put(comp_class);
998 }
999 }
1000
1001end:
1002 return ret;
1003}
1004
05a67631
PP
1005static int print_ctf_metadata(struct bt_config *cfg)
1006{
1007 int ret = 0;
1008 struct bt_component_class *comp_cls = NULL;
1009 struct bt_config_component *source_cfg = NULL;
1010 struct bt_value *results = NULL;
1011 struct bt_value *path = NULL;
1012 struct bt_value *params = NULL;
1013 struct bt_value *metadata_text_value = NULL;
1014 const char *metadata_text = NULL;
1015
1016 assert(cfg->cmd_data.convert.sources->len == 1);
1017 source_cfg = bt_config_get_component(cfg->cmd_data.convert.sources, 0);
1018 assert(source_cfg);
1019 comp_cls = find_component_class(source_cfg->plugin_name->str,
1020 source_cfg->component_name->str,
1021 source_cfg->type);
1022 if (!comp_cls) {
1023 fprintf(stderr, "%s%sCannot find component class %s",
1024 bt_common_color_bold(),
1025 bt_common_color_fg_red(),
1026 bt_common_color_reset());
1027 print_plugin_comp_cls_opt(stderr,
1028 source_cfg->plugin_name->str,
1029 source_cfg->component_name->str,
1030 source_cfg->type);
1031 fprintf(stderr, "\n");
1032 ret = -1;
1033 goto end;
1034 }
1035
1036 path = bt_value_map_get(source_cfg->params, "path");
1037 if (!path) {
1038 ret = -1;
1039 goto end;
1040 }
1041
1042 params = bt_value_map_create();
1043 if (!params) {
1044 ret = -1;
1045 goto end;
1046 }
1047
1048 ret = bt_value_map_insert(params, "path", path);
1049 if (ret) {
1050 ret = -1;
1051 goto end;
1052 }
1053
a67681c1 1054 results = bt_component_class_query(comp_cls, "metadata-info",
05a67631
PP
1055 params);
1056 if (!results) {
1057 ret = -1;
a67681c1 1058 fprintf(stderr, "%s%sFailed to request metadata info%s\n",
05a67631
PP
1059 bt_common_color_bold(),
1060 bt_common_color_fg_red(),
1061 bt_common_color_reset());
1062 goto end;
1063 }
1064
1065 metadata_text_value = bt_value_map_get(results, "text");
1066 if (!metadata_text_value) {
1067 ret = -1;
1068 goto end;
1069 }
1070
1071 ret = bt_value_string_get(metadata_text_value, &metadata_text);
1072 assert(ret == 0);
1073 printf("%s\n", metadata_text);
1074
1075end:
1076 bt_put(results);
1077 bt_put(path);
1078 bt_put(params);
1079 bt_put(metadata_text_value);
1080 bt_put(comp_cls);
1081 bt_put(source_cfg);
1082 return 0;
1083}
1084
290725f7
PP
1085static int cmd_convert(struct bt_config *cfg)
1086{
1087 int ret = 0;
1088 struct bt_component_class *source_class = NULL;
1089 struct bt_component_class *sink_class = NULL;
1090 struct bt_component *source = NULL, *sink = NULL;
1091 struct bt_value *source_params = NULL, *sink_params = NULL;
290725f7 1092 struct bt_config_component *source_cfg = NULL, *sink_cfg = NULL;
61ddbc8a 1093 struct bt_graph *graph = NULL;
290725f7 1094
05a67631
PP
1095 ret = load_all_plugins(cfg->cmd_data.convert.plugin_paths);
1096 if (ret) {
1097 fprintf(stderr, "Could not load plugins from configured plugin paths. Aborting...\n");
1098 goto end;
1099 }
1100
1101 if (cfg->cmd_data.convert.print_ctf_metadata) {
1102 ret = print_ctf_metadata(cfg);
1103 goto end;
1104 }
1105
290725f7
PP
1106 /* TODO handle more than 1 source and 1 sink. */
1107 if (cfg->cmd_data.convert.sources->len != 1 ||
1108 cfg->cmd_data.convert.sinks->len != 1) {
ebba3338 1109 fprintf(stderr, "Only one source and one sink component class are supported. Aborting...\n");
98ecef32
MD
1110 ret = -1;
1111 goto end;
33bceaf8
JG
1112 }
1113
290725f7 1114 source_cfg = bt_config_get_component(cfg->cmd_data.convert.sources, 0);
e5bc7f81 1115 source_params = bt_get(source_cfg->params);
33b34c43
PP
1116 source_class = find_component_class(source_cfg->plugin_name->str,
1117 source_cfg->component_name->str,
d3e4dcd8 1118 BT_COMPONENT_CLASS_TYPE_SOURCE);
56a1cced 1119 if (!source_class) {
87796884
PP
1120 fprintf(stderr, "Could not find ");
1121 print_plugin_comp_cls_opt(stderr, source_cfg->plugin_name->str,
1122 source_cfg->component_name->str, BT_COMPONENT_CLASS_TYPE_SOURCE);
1123 fprintf(stderr, ". Aborting...\n");
56a1cced
JG
1124 ret = -1;
1125 goto end;
1126 }
7c7c0433 1127
290725f7 1128 sink_cfg = bt_config_get_component(cfg->cmd_data.convert.sinks, 0);
e5bc7f81 1129 sink_params = bt_get(sink_cfg->params);
33b34c43
PP
1130 sink_class = find_component_class(sink_cfg->plugin_name->str,
1131 sink_cfg->component_name->str,
d3e4dcd8 1132 BT_COMPONENT_CLASS_TYPE_SINK);
7c7c0433 1133 if (!sink_class) {
87796884
PP
1134 fprintf(stderr, "Could not find ");
1135 print_plugin_comp_cls_opt(stderr, sink_cfg->plugin_name->str,
1136 sink_cfg->component_name->str, BT_COMPONENT_CLASS_TYPE_SINK);
1137 fprintf(stderr, ". Aborting...\n");
7c7c0433
JG
1138 ret = -1;
1139 goto end;
1140 }
1141
61ddbc8a
JG
1142 graph = bt_graph_create();
1143 if (!graph) {
1144 ret = -1;
1145 goto end;
1146 }
1147
e5bc7f81 1148 source = bt_component_create(source_class, "source", source_params);
56a1cced 1149 if (!source) {
e5bc7f81 1150 fprintf(stderr, "Failed to instantiate selected source component. Aborting...\n");
c42c79ea
PP
1151 ret = -1;
1152 goto end;
1153 }
56a1cced 1154
e5bc7f81 1155 sink = bt_component_create(sink_class, "sink", sink_params);
7c7c0433 1156 if (!sink) {
e5bc7f81 1157 fprintf(stderr, "Failed to instantiate selected output component. Aborting...\n");
7c7c0433 1158 ret = -1;
2e339de1
JG
1159 goto end;
1160 }
1161
61ddbc8a 1162 ret = connect_source_sink(graph, source, source_cfg, sink);
6c2f3ee5 1163 if (ret) {
290725f7 1164 ret = -1;
fec2a9f2
JG
1165 goto end;
1166 }
78586d8a 1167
fec2a9f2 1168 while (true) {
61ddbc8a
JG
1169 enum bt_graph_status graph_status;
1170
1171 graph_status = bt_graph_run(graph, NULL);
1172 switch (graph_status) {
1173 case BT_GRAPH_STATUS_AGAIN:
fec2a9f2
JG
1174 /* Wait for an arbitraty 500 ms. */
1175 usleep(500000);
78586d8a 1176 break;
fec2a9f2
JG
1177 case BT_COMPONENT_STATUS_END:
1178 goto end;
1179 default:
1180 fprintf(stderr, "Sink component returned an error, aborting...\n");
1181 ret = -1;
1182 goto end;
78586d8a 1183 }
fec2a9f2 1184 }
290725f7 1185
11e1d048 1186end:
61ddbc8a
JG
1187 bt_put(sink_class);
1188 bt_put(source_class);
1189 bt_put(source);
1190 bt_put(sink);
1191 bt_put(source_params);
1192 bt_put(sink_params);
1193 bt_put(sink_cfg);
1194 bt_put(source_cfg);
1195 bt_put(graph);
290725f7
PP
1196 return ret;
1197}
1198
1199static void warn_command_name_and_directory_clash(struct bt_config *cfg)
1200{
1201 if (!cfg->command_name) {
1202 return;
1203 }
1204
1205 if (g_file_test(cfg->command_name,
1206 G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) {
1207 fprintf(stderr, "\nNOTE: The `%s` command was executed. If you meant to convert a\n",
1208 cfg->command_name);
1209 fprintf(stderr, "trace located in the local `%s` directory, please use:\n",
1210 cfg->command_name);
1211 fprintf(stderr, "\n");
1212 fprintf(stderr, " babeltrace convert %s [OPTIONS]\n",
1213 cfg->command_name);
1214 }
1215}
1216
1217int main(int argc, const char **argv)
1218{
1219 int ret;
1220 int retcode;
1221 struct bt_config *cfg;
1222
1223 init_loaded_plugins_array();
1224 cfg = bt_config_from_args_with_defaults(argc, argv, &retcode);
1225
1226 if (retcode < 0) {
1227 /* Quit without errors; typically usage/version */
1228 retcode = 0;
1229 goto end;
1230 }
1231
1232 if (retcode > 0) {
1233 goto end;
1234 }
1235
1236 if (!cfg) {
1237 fprintf(stderr, "Failed to create Babeltrace configuration\n");
1238 goto end;
1239 }
1240
1241 babeltrace_debug = cfg->debug;
1242 babeltrace_verbose = cfg->verbose;
1243 print_cfg(cfg);
1244
1245 switch (cfg->command) {
1246 case BT_CONFIG_COMMAND_CONVERT:
1247 ret = cmd_convert(cfg);
1248 break;
1249 case BT_CONFIG_COMMAND_LIST_PLUGINS:
1250 ret = cmd_list_plugins(cfg);
1251 break;
22e22462
PP
1252 case BT_CONFIG_COMMAND_HELP:
1253 ret = cmd_help(cfg);
1254 break;
a67681c1
PP
1255 case BT_CONFIG_COMMAND_QUERY:
1256 ret = cmd_query(cfg);
63ce0e1d 1257 break;
290725f7
PP
1258 default:
1259 assert(false);
1260 }
1261
1262 warn_command_name_and_directory_clash(cfg);
1263 retcode = ret ? 1 : 0;
1264
1265end:
1266 BT_PUT(cfg);
33b34c43 1267 fini_loaded_plugins_array();
290725f7 1268 return retcode;
4c8bfb7e 1269}
This page took 0.098465 seconds and 4 git commands to generate.