common: optimize color code functions
[babeltrace.git] / cli / 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>
b2e0c907
PP
32#include <babeltrace/graph/component.h>
33#include <babeltrace/graph/component-source.h>
34#include <babeltrace/graph/component-sink.h>
35#include <babeltrace/graph/component-filter.h>
36#include <babeltrace/graph/component-class.h>
37#include <babeltrace/graph/port.h>
38#include <babeltrace/graph/graph.h>
39#include <babeltrace/graph/connection.h>
40#include <babeltrace/graph/notification-iterator.h>
2e339de1
JG
41#include <babeltrace/ref.h>
42#include <babeltrace/values.h>
a8ff38ef 43#include <unistd.h>
34ac0e6c 44#include <stdlib.h>
7f26a816
PP
45#include <popt.h>
46#include <string.h>
47#include <stdio.h>
33b34c43 48#include <glib.h>
dc3fffef 49#include <inttypes.h>
c42c79ea 50#include "babeltrace-cfg.h"
9009cc24
PP
51#include "babeltrace-cfg-cli-args.h"
52#include "babeltrace-cfg-cli-args-default.h"
53
54#define ENV_BABELTRACE_WARN_COMMAND_NAME_DIRECTORY_CLASH "BABELTRACE_CLI_WARN_COMMAND_NAME_DIRECTORY_CLASH"
34ac0e6c 55
33b34c43
PP
56GPtrArray *loaded_plugins;
57
58static
9009cc24 59void init_static_data(void)
33b34c43 60{
9009cc24 61 loaded_plugins = g_ptr_array_new_with_free_func(bt_put);
33b34c43
PP
62}
63
64static
9009cc24 65void fini_static_data(void)
33b34c43
PP
66{
67 g_ptr_array_free(loaded_plugins, TRUE);
68}
69
70static
71struct bt_plugin *find_plugin(const char *name)
72{
73 int i;
74 struct bt_plugin *plugin = NULL;
75
76 for (i = 0; i < loaded_plugins->len; i++) {
77 plugin = g_ptr_array_index(loaded_plugins, i);
78
79 if (strcmp(name, bt_plugin_get_name(plugin)) == 0) {
80 break;
81 }
82
83 plugin = NULL;
84 }
85
86 return bt_get(plugin);
87}
88
89static
90struct bt_component_class *find_component_class(const char *plugin_name,
91 const char *comp_class_name,
d3e4dcd8 92 enum bt_component_class_type comp_class_type)
33b34c43
PP
93{
94 struct bt_component_class *comp_class = NULL;
95 struct bt_plugin *plugin = find_plugin(plugin_name);
96
97 if (!plugin) {
98 goto end;
99 }
100
101 comp_class = bt_plugin_get_component_class_by_name_and_type(plugin,
102 comp_class_name, comp_class_type);
103 BT_PUT(plugin);
104end:
105 return comp_class;
106}
6c2f3ee5 107
c42c79ea
PP
108static
109void print_indent(size_t indent)
110{
111 size_t i;
112
113 for (i = 0; i < indent; i++) {
00447e45 114 printf(" ");
c42c79ea
PP
115 }
116}
117
87796884
PP
118static
119const char *component_type_str(enum bt_component_class_type type)
120{
121 switch (type) {
122 case BT_COMPONENT_CLASS_TYPE_SOURCE:
123 return "source";
124 case BT_COMPONENT_CLASS_TYPE_SINK:
125 return "sink";
126 case BT_COMPONENT_CLASS_TYPE_FILTER:
127 return "filter";
128 case BT_COMPONENT_CLASS_TYPE_UNKNOWN:
129 default:
130 return "unknown";
131 }
132}
133
9009cc24
PP
134static
135void print_plugin_comp_cls_opt(FILE *fh, const char *plugin_name,
87796884
PP
136 const char *comp_cls_name, enum bt_component_class_type type)
137{
9009cc24
PP
138 GString *shell_plugin_name = NULL;
139 GString *shell_comp_cls_name = NULL;
87796884 140
9009cc24 141 shell_plugin_name = bt_common_shell_quote(plugin_name, false);
87796884
PP
142 if (!shell_plugin_name) {
143 goto end;
144 }
145
9009cc24 146 shell_comp_cls_name = bt_common_shell_quote(comp_cls_name, false);
87796884
PP
147 if (!shell_comp_cls_name) {
148 goto end;
149 }
150
151 fprintf(fh, "%s%s--%s%s %s'%s%s%s%s.%s%s%s'",
152 bt_common_color_bold(),
153 bt_common_color_fg_cyan(),
154 component_type_str(type),
155 bt_common_color_reset(),
156 bt_common_color_fg_default(),
157 bt_common_color_bold(),
158 bt_common_color_fg_blue(),
9009cc24 159 shell_plugin_name->str,
87796884
PP
160 bt_common_color_fg_default(),
161 bt_common_color_fg_yellow(),
9009cc24 162 shell_comp_cls_name->str,
87796884
PP
163 bt_common_color_reset());
164
165end:
9009cc24
PP
166 if (shell_plugin_name) {
167 g_string_free(shell_plugin_name, TRUE);
168 }
169
170 if (shell_comp_cls_name) {
171 g_string_free(shell_comp_cls_name, TRUE);
172 }
87796884
PP
173}
174
c42c79ea 175static
290725f7 176void print_value(struct bt_value *, size_t);
c42c79ea 177
c1081aa6
PP
178static
179void print_value_rec(struct bt_value *, size_t);
180
c42c79ea
PP
181static
182bool print_map_value(const char *key, struct bt_value *object, void *data)
183{
290725f7
PP
184 size_t *indent = data;
185
186 print_indent(*indent);
187 printf("%s: ", key);
188
189 if (bt_value_is_array(object) &&
190 bt_value_array_is_empty(object)) {
191 printf("[ ]\n");
192 return true;
193 }
194
195 if (bt_value_is_map(object) &&
196 bt_value_map_is_empty(object)) {
197 printf("{ }\n");
198 return true;
199 }
c42c79ea 200
290725f7
PP
201 if (bt_value_is_array(object) ||
202 bt_value_is_map(object)) {
203 printf("\n");
204 }
c42c79ea 205
c1081aa6 206 print_value_rec(object, *indent + 2);
c42c79ea
PP
207 return true;
208}
209
210static
c1081aa6 211void print_value_rec(struct bt_value *value, size_t indent)
c42c79ea
PP
212{
213 bool bool_val;
214 int64_t int_val;
215 double dbl_val;
216 const char *str_val;
217 int size;
218 int i;
219
220 if (!value) {
221 return;
222 }
223
c42c79ea
PP
224 switch (bt_value_get_type(value)) {
225 case BT_VALUE_TYPE_NULL:
c1081aa6
PP
226 printf("%snull%s\n", bt_common_color_bold(),
227 bt_common_color_reset());
c42c79ea
PP
228 break;
229 case BT_VALUE_TYPE_BOOL:
230 bt_value_bool_get(value, &bool_val);
c1081aa6
PP
231 printf("%s%s%s%s\n", bt_common_color_bold(),
232 bt_common_color_fg_cyan(), bool_val ? "yes" : "no",
233 bt_common_color_reset());
c42c79ea
PP
234 break;
235 case BT_VALUE_TYPE_INTEGER:
236 bt_value_integer_get(value, &int_val);
c1081aa6
PP
237 printf("%s%s%" PRId64 "%s\n", bt_common_color_bold(),
238 bt_common_color_fg_red(), int_val,
239 bt_common_color_reset());
c42c79ea
PP
240 break;
241 case BT_VALUE_TYPE_FLOAT:
242 bt_value_float_get(value, &dbl_val);
c1081aa6
PP
243 printf("%s%s%lf%s\n", bt_common_color_bold(),
244 bt_common_color_fg_red(), dbl_val,
245 bt_common_color_reset());
c42c79ea
PP
246 break;
247 case BT_VALUE_TYPE_STRING:
248 bt_value_string_get(value, &str_val);
c1081aa6
PP
249 printf("%s%s%s%s\n", bt_common_color_bold(),
250 bt_common_color_fg_green(), str_val,
251 bt_common_color_reset());
c42c79ea
PP
252 break;
253 case BT_VALUE_TYPE_ARRAY:
254 size = bt_value_array_size(value);
290725f7
PP
255 assert(size >= 0);
256
257 if (size == 0) {
258 print_indent(indent);
259 printf("[ ]\n");
260 break;
261 }
c42c79ea
PP
262
263 for (i = 0; i < size; i++) {
264 struct bt_value *element =
265 bt_value_array_get(value, i);
266
290725f7
PP
267 assert(element);
268 print_indent(indent);
269 printf("- ");
270
271 if (bt_value_is_array(element) &&
272 bt_value_array_is_empty(element)) {
273 printf("[ ]\n");
274 continue;
275 }
276
277 if (bt_value_is_map(element) &&
278 bt_value_map_is_empty(element)) {
279 printf("{ }\n");
280 continue;
281 }
282
283 if (bt_value_is_array(element) ||
284 bt_value_is_map(element)) {
285 printf("\n");
286 }
287
c1081aa6 288 print_value_rec(element, indent + 2);
c42c79ea
PP
289 BT_PUT(element);
290 }
c42c79ea
PP
291 break;
292 case BT_VALUE_TYPE_MAP:
293 if (bt_value_map_is_empty(value)) {
290725f7
PP
294 print_indent(indent);
295 printf("{ }\n");
296 break;
c42c79ea
PP
297 }
298
290725f7 299 bt_value_map_foreach(value, print_map_value, &indent);
c42c79ea
PP
300 break;
301 default:
302 assert(false);
303 }
304}
305
c1081aa6
PP
306static
307void print_value(struct bt_value *value, size_t indent)
308{
309 if (!bt_value_is_array(value) && !bt_value_is_map(value)) {
310 print_indent(indent);
311 }
312
313 print_value_rec(value, indent);
314}
315
c42c79ea
PP
316static
317void print_bt_config_component(struct bt_config_component *bt_config_component)
318{
87796884
PP
319 printf(" ");
320 print_plugin_comp_cls_opt(stdout, bt_config_component->plugin_name->str,
db0f160a 321 bt_config_component->comp_cls_name->str,
87796884
PP
322 bt_config_component->type);
323 printf(":\n");
3b6cfcc5
PP
324
325 if (bt_config_component->instance_name->len > 0) {
326 printf(" Name: %s\n",
327 bt_config_component->instance_name->str);
328 }
329
290725f7
PP
330 printf(" Parameters:\n");
331 print_value(bt_config_component->params, 8);
c42c79ea
PP
332}
333
334static
335void print_bt_config_components(GPtrArray *array)
336{
337 size_t i;
338
339 for (i = 0; i < array->len; i++) {
340 struct bt_config_component *cfg_component =
e5bc7f81 341 bt_config_get_component(array, i);
c42c79ea
PP
342 print_bt_config_component(cfg_component);
343 BT_PUT(cfg_component);
344 }
345}
346
290725f7
PP
347static
348void print_plugin_paths(struct bt_value *plugin_paths)
349{
350 printf(" Plugin paths:\n");
351 print_value(plugin_paths, 4);
352}
353
354static
db0f160a 355void print_cfg_run(struct bt_config *cfg)
290725f7 356{
ebba3338
PP
357 size_t i;
358
db0f160a 359 print_plugin_paths(cfg->plugin_paths);
290725f7 360 printf(" Source component instances:\n");
db0f160a 361 print_bt_config_components(cfg->cmd_data.run.sources);
ebba3338 362
db0f160a 363 if (cfg->cmd_data.run.filters->len > 0) {
ebba3338 364 printf(" Filter component instances:\n");
db0f160a 365 print_bt_config_components(cfg->cmd_data.run.filters);
ebba3338
PP
366 }
367
290725f7 368 printf(" Sink component instances:\n");
db0f160a 369 print_bt_config_components(cfg->cmd_data.run.sinks);
ebba3338
PP
370 printf(" Connections:\n");
371
db0f160a 372 for (i = 0; i < cfg->cmd_data.run.connections->len; i++) {
ebba3338 373 struct bt_config_connection *cfg_connection =
db0f160a 374 g_ptr_array_index(cfg->cmd_data.run.connections,
ebba3338
PP
375 i);
376
377 printf(" %s%s%s -> %s%s%s\n",
9009cc24
PP
378 cfg_connection->upstream_comp_name->str,
379 cfg_connection->upstream_port_glob->len > 0 ? "." : "",
380 cfg_connection->upstream_port_glob->str,
381 cfg_connection->downstream_comp_name->str,
382 cfg_connection->downstream_port_glob->len > 0 ? "." : "",
383 cfg_connection->downstream_port_glob->str);
ebba3338 384 }
290725f7
PP
385}
386
387static
388void print_cfg_list_plugins(struct bt_config *cfg)
389{
db0f160a 390 print_plugin_paths(cfg->plugin_paths);
290725f7
PP
391}
392
c1081aa6
PP
393static
394void print_cfg_help(struct bt_config *cfg)
395{
db0f160a
PP
396 print_plugin_paths(cfg->plugin_paths);
397}
398
399static
400void print_cfg_print_ctf_metadata(struct bt_config *cfg)
401{
402 print_plugin_paths(cfg->plugin_paths);
403 printf(" Path: %s\n", cfg->cmd_data.print_ctf_metadata.path->str);
404}
405
406static
407void print_cfg_print_lttng_live_sessions(struct bt_config *cfg)
408{
409 print_plugin_paths(cfg->plugin_paths);
410 printf(" URL: %s\n", cfg->cmd_data.print_lttng_live_sessions.url->str);
c1081aa6
PP
411}
412
413static
a67681c1 414void print_cfg_query(struct bt_config *cfg)
c1081aa6 415{
db0f160a 416 print_plugin_paths(cfg->plugin_paths);
a67681c1 417 printf(" Object: `%s`\n", cfg->cmd_data.query.object->str);
c1081aa6 418 printf(" Component class:\n");
a67681c1 419 print_bt_config_component(cfg->cmd_data.query.cfg_component);
c1081aa6
PP
420}
421
c42c79ea
PP
422static
423void print_cfg(struct bt_config *cfg)
424{
00447e45
PP
425 if (!babeltrace_verbose) {
426 return;
427 }
428
290725f7
PP
429 printf("Configuration:\n");
430 printf(" Debug mode: %s\n", cfg->debug ? "yes" : "no");
431 printf(" Verbose mode: %s\n", cfg->verbose ? "yes" : "no");
432
433 switch (cfg->command) {
db0f160a
PP
434 case BT_CONFIG_COMMAND_RUN:
435 print_cfg_run(cfg);
290725f7
PP
436 break;
437 case BT_CONFIG_COMMAND_LIST_PLUGINS:
438 print_cfg_list_plugins(cfg);
c1081aa6
PP
439 break;
440 case BT_CONFIG_COMMAND_HELP:
441 print_cfg_help(cfg);
442 break;
a67681c1
PP
443 case BT_CONFIG_COMMAND_QUERY:
444 print_cfg_query(cfg);
290725f7 445 break;
db0f160a
PP
446 case BT_CONFIG_COMMAND_PRINT_CTF_METADATA:
447 print_cfg_print_ctf_metadata(cfg);
448 break;
449 case BT_CONFIG_COMMAND_PRINT_LTTNG_LIVE_SESSIONS:
450 print_cfg_print_lttng_live_sessions(cfg);
451 break;
290725f7
PP
452 default:
453 assert(false);
454 }
c42c79ea
PP
455}
456
33b34c43 457static
a8ff38ef 458void add_to_loaded_plugins(struct bt_plugin_set *plugin_set)
98ecef32 459{
544d0515
PP
460 int64_t i;
461 int64_t count;
a8ff38ef
PP
462
463 count = bt_plugin_set_get_plugin_count(plugin_set);
464 assert(count >= 0);
465
466 for (i = 0; i < count; i++) {
467 struct bt_plugin *plugin =
468 bt_plugin_set_get_plugin(plugin_set, i);
33b34c43
PP
469 struct bt_plugin *loaded_plugin =
470 find_plugin(bt_plugin_get_name(plugin));
471
a8ff38ef
PP
472 assert(plugin);
473
33b34c43
PP
474 if (loaded_plugin) {
475 printf_verbose("Not loading plugin `%s`: already loaded from `%s`\n",
476 bt_plugin_get_path(plugin),
477 bt_plugin_get_path(loaded_plugin));
a8ff38ef 478 bt_put(loaded_plugin);
33b34c43 479 } else {
a8ff38ef
PP
480 /* Add to global array. */
481 g_ptr_array_add(loaded_plugins, bt_get(plugin));
33b34c43 482 }
a8ff38ef
PP
483
484 bt_put(plugin);
33b34c43
PP
485 }
486}
487
488static
290725f7 489int load_dynamic_plugins(struct bt_value *plugin_paths)
33b34c43
PP
490{
491 int nr_paths, i, ret = 0;
98ecef32 492
290725f7 493 nr_paths = bt_value_array_size(plugin_paths);
98ecef32 494 if (nr_paths < 0) {
33b34c43
PP
495 ret = -1;
496 goto end;
98ecef32 497 }
33b34c43 498
98ecef32
MD
499 for (i = 0; i < nr_paths; i++) {
500 struct bt_value *plugin_path_value = NULL;
501 const char *plugin_path;
a8ff38ef 502 struct bt_plugin_set *plugin_set;
98ecef32 503
290725f7 504 plugin_path_value = bt_value_array_get(plugin_paths, i);
98ecef32
MD
505 if (bt_value_string_get(plugin_path_value,
506 &plugin_path)) {
507 BT_PUT(plugin_path_value);
508 continue;
509 }
33b34c43 510
a8ff38ef
PP
511 plugin_set = bt_plugin_create_all_from_dir(plugin_path, false);
512 if (!plugin_set) {
98ecef32
MD
513 printf_debug("Unable to dynamically load plugins from path %s.\n",
514 plugin_path);
33b34c43
PP
515 BT_PUT(plugin_path_value);
516 continue;
98ecef32 517 }
33b34c43 518
a8ff38ef
PP
519 add_to_loaded_plugins(plugin_set);
520 bt_put(plugin_set);
98ecef32
MD
521 BT_PUT(plugin_path_value);
522 }
33b34c43
PP
523end:
524 return ret;
525}
526
527static
528int load_static_plugins(void)
529{
530 int ret = 0;
a8ff38ef 531 struct bt_plugin_set *plugin_set;
33b34c43 532
a8ff38ef
PP
533 plugin_set = bt_plugin_create_all_from_static();
534 if (!plugin_set) {
33b34c43
PP
535 printf_debug("Unable to load static plugins.\n");
536 ret = -1;
537 goto end;
538 }
539
a8ff38ef
PP
540 add_to_loaded_plugins(plugin_set);
541 bt_put(plugin_set);
33b34c43
PP
542end:
543 return ret;
98ecef32
MD
544}
545
9009cc24
PP
546static
547int load_all_plugins(struct bt_value *plugin_paths)
290725f7
PP
548{
549 int ret = 0;
33b34c43 550
290725f7
PP
551 if (load_dynamic_plugins(plugin_paths)) {
552 fprintf(stderr, "Failed to load dynamic plugins.\n");
553 ret = -1;
c1870f57
JG
554 goto end;
555 }
556
290725f7
PP
557 if (load_static_plugins()) {
558 fprintf(stderr, "Failed to load static plugins.\n");
559 ret = -1;
c1870f57
JG
560 goto end;
561 }
562
290725f7
PP
563end:
564 return ret;
565}
566
9009cc24
PP
567static
568void print_plugin_info(struct bt_plugin *plugin)
22e22462
PP
569{
570 unsigned int major, minor, patch;
571 const char *extra;
572 enum bt_plugin_status version_status;
573 const char *plugin_name;
574 const char *path;
575 const char *author;
576 const char *license;
577 const char *plugin_description;
578
579 plugin_name = bt_plugin_get_name(plugin);
580 path = bt_plugin_get_path(plugin);
581 author = bt_plugin_get_author(plugin);
582 license = bt_plugin_get_license(plugin);
583 plugin_description = bt_plugin_get_description(plugin);
584 version_status = bt_plugin_get_version(plugin, &major, &minor,
585 &patch, &extra);
586 printf("%s%s%s%s:\n", bt_common_color_bold(),
587 bt_common_color_fg_blue(), plugin_name,
588 bt_common_color_reset());
589 printf(" %sPath%s: %s\n", bt_common_color_bold(),
590 bt_common_color_reset(), path ? path : "(None)");
591
592 if (version_status == BT_PLUGIN_STATUS_OK) {
593 printf(" %sVersion%s: %u.%u.%u",
594 bt_common_color_bold(), bt_common_color_reset(),
595 major, minor, patch);
596
597 if (extra) {
598 printf("%s", extra);
599 }
600
601 printf("\n");
602 }
603
604 printf(" %sDescription%s: %s\n", bt_common_color_bold(),
605 bt_common_color_reset(),
606 plugin_description ? plugin_description : "(None)");
607 printf(" %sAuthor%s: %s\n", bt_common_color_bold(),
608 bt_common_color_reset(), author ? author : "(Unknown)");
609 printf(" %sLicense%s: %s\n", bt_common_color_bold(),
610 bt_common_color_reset(),
611 license ? license : "(Unknown)");
612}
613
9009cc24
PP
614static
615int cmd_query(struct bt_config *cfg)
63ce0e1d
PP
616{
617 int ret;
618 struct bt_component_class *comp_cls = NULL;
619 struct bt_value *results = NULL;
620
db0f160a 621 ret = load_all_plugins(cfg->plugin_paths);
63ce0e1d
PP
622 if (ret) {
623 goto end;
624 }
625
a67681c1 626 comp_cls = find_component_class(cfg->cmd_data.query.cfg_component->plugin_name->str,
db0f160a 627 cfg->cmd_data.query.cfg_component->comp_cls_name->str,
a67681c1 628 cfg->cmd_data.query.cfg_component->type);
63ce0e1d
PP
629 if (!comp_cls) {
630 fprintf(stderr, "%s%sCannot find component class %s",
631 bt_common_color_bold(),
632 bt_common_color_fg_red(),
633 bt_common_color_reset());
634 print_plugin_comp_cls_opt(stderr,
a67681c1 635 cfg->cmd_data.query.cfg_component->plugin_name->str,
db0f160a 636 cfg->cmd_data.query.cfg_component->comp_cls_name->str,
a67681c1 637 cfg->cmd_data.query.cfg_component->type);
63ce0e1d
PP
638 fprintf(stderr, "\n");
639 ret = -1;
640 goto end;
641 }
642
a67681c1
PP
643 results = bt_component_class_query(comp_cls,
644 cfg->cmd_data.query.object->str,
645 cfg->cmd_data.query.cfg_component->params);
63ce0e1d
PP
646 if (!results) {
647 fprintf(stderr, "%s%sFailed to query info to %s",
648 bt_common_color_bold(),
649 bt_common_color_fg_red(),
650 bt_common_color_reset());
651 print_plugin_comp_cls_opt(stderr,
a67681c1 652 cfg->cmd_data.query.cfg_component->plugin_name->str,
db0f160a 653 cfg->cmd_data.query.cfg_component->comp_cls_name->str,
a67681c1
PP
654 cfg->cmd_data.query.cfg_component->type);
655 fprintf(stderr, "%s%s with object `%s`%s\n",
63ce0e1d
PP
656 bt_common_color_bold(),
657 bt_common_color_fg_red(),
a67681c1 658 cfg->cmd_data.query.object->str,
63ce0e1d
PP
659 bt_common_color_reset());
660 ret = -1;
661 goto end;
662 }
663
664 print_value(results, 0);
665
666end:
667 bt_put(comp_cls);
668 bt_put(results);
669 return ret;
670}
671
9009cc24
PP
672static
673int cmd_help(struct bt_config *cfg)
22e22462
PP
674{
675 int ret;
676 struct bt_plugin *plugin = NULL;
677 size_t i;
678
db0f160a 679 ret = load_all_plugins(cfg->plugin_paths);
22e22462
PP
680 if (ret) {
681 goto end;
682 }
683
90de159b 684 plugin = find_plugin(cfg->cmd_data.help.cfg_component->plugin_name->str);
22e22462
PP
685 if (!plugin) {
686 fprintf(stderr, "%s%sCannot find plugin %s%s%s\n",
687 bt_common_color_bold(), bt_common_color_fg_red(),
688 bt_common_color_fg_blue(),
90de159b 689 cfg->cmd_data.help.cfg_component->plugin_name->str,
22e22462
PP
690 bt_common_color_reset());
691 ret = -1;
692 goto end;
693 }
694
695 print_plugin_info(plugin);
696 printf(" %sComponent classes%s: %d\n",
697 bt_common_color_bold(),
698 bt_common_color_reset(),
544d0515 699 (int) bt_plugin_get_component_class_count(plugin));
22e22462
PP
700
701
90de159b 702 if (cfg->cmd_data.help.cfg_component->type !=
22e22462
PP
703 BT_COMPONENT_CLASS_TYPE_UNKNOWN) {
704 struct bt_component_class *needed_comp_cls =
705 find_component_class(
90de159b 706 cfg->cmd_data.help.cfg_component->plugin_name->str,
db0f160a 707 cfg->cmd_data.help.cfg_component->comp_cls_name->str,
90de159b 708 cfg->cmd_data.help.cfg_component->type);
22e22462
PP
709
710 if (!needed_comp_cls) {
711 fprintf(stderr, "\n%s%sCannot find component class %s",
712 bt_common_color_bold(),
713 bt_common_color_fg_red(),
714 bt_common_color_reset());
715 print_plugin_comp_cls_opt(stderr,
90de159b 716 cfg->cmd_data.help.cfg_component->plugin_name->str,
db0f160a 717 cfg->cmd_data.help.cfg_component->comp_cls_name->str,
90de159b 718 cfg->cmd_data.help.cfg_component->type);
22e22462
PP
719 fprintf(stderr, "\n");
720 ret = -1;
721 goto end;
722 }
723
724 bt_put(needed_comp_cls);
725 }
726
727 for (i = 0; i < bt_plugin_get_component_class_count(plugin); i++) {
728 struct bt_component_class *comp_cls =
9ac68eb1 729 bt_plugin_get_component_class_by_index(plugin, i);
22e22462
PP
730 const char *comp_class_name =
731 bt_component_class_get_name(comp_cls);
732 const char *comp_class_description =
733 bt_component_class_get_description(comp_cls);
734 const char *comp_class_help =
735 bt_component_class_get_help(comp_cls);
736 enum bt_component_class_type type =
737 bt_component_class_get_type(comp_cls);
738
739 assert(comp_cls);
740
90de159b 741 if (cfg->cmd_data.help.cfg_component->type !=
22e22462 742 BT_COMPONENT_CLASS_TYPE_UNKNOWN) {
db0f160a 743 if (strcmp(cfg->cmd_data.help.cfg_component->comp_cls_name->str,
22e22462
PP
744 comp_class_name) != 0 &&
745 type ==
90de159b 746 cfg->cmd_data.help.cfg_component->type) {
22e22462
PP
747 bt_put(comp_cls);
748 continue;
749 }
750 }
751
752 printf("\n");
753 print_plugin_comp_cls_opt(stdout,
90de159b 754 cfg->cmd_data.help.cfg_component->plugin_name->str,
22e22462
PP
755 comp_class_name,
756 type);
757 printf("\n");
758 printf(" %sDescription%s: %s\n", bt_common_color_bold(),
759 bt_common_color_reset(),
760 comp_class_description ? comp_class_description : "(None)");
761
762 if (comp_class_help) {
763 printf("\n%s\n", comp_class_help);
764 }
765
766 bt_put(comp_cls);
767 }
768
769end:
770 bt_put(plugin);
771 return ret;
772}
773
9009cc24
PP
774static
775int cmd_list_plugins(struct bt_config *cfg)
290725f7
PP
776{
777 int ret;
778 int plugins_count, component_classes_count = 0, i;
779
db0f160a 780 ret = load_all_plugins(cfg->plugin_paths);
290725f7 781 if (ret) {
56a1cced
JG
782 goto end;
783 }
784
22e22462 785 printf("From the following plugin paths:\n\n");
db0f160a 786 print_value(cfg->plugin_paths, 2);
22e22462 787 printf("\n");
290725f7
PP
788 plugins_count = loaded_plugins->len;
789 if (plugins_count == 0) {
790 fprintf(stderr, "%s%sNo plugins found.%s\n",
791 bt_common_color_bold(), bt_common_color_fg_red(),
792 bt_common_color_reset());
793 fprintf(stderr, "\n");
794 fprintf(stderr, "Please make sure your plugin search path is set correctly. You can use\n");
795 fprintf(stderr, "the --plugin-path command-line option or the BABELTRACE_PLUGIN_PATH\n");
796 fprintf(stderr, "environment variable.\n");
56a1cced
JG
797 ret = -1;
798 goto end;
799 }
800
290725f7
PP
801 for (i = 0; i < plugins_count; i++) {
802 struct bt_plugin *plugin = g_ptr_array_index(loaded_plugins, i);
803
804 component_classes_count += bt_plugin_get_component_class_count(plugin);
805 }
33bceaf8 806
290725f7
PP
807 printf("Found %s%d%s component classes in %s%d%s plugins.\n",
808 bt_common_color_bold(),
809 component_classes_count,
810 bt_common_color_reset(),
811 bt_common_color_bold(),
812 plugins_count,
813 bt_common_color_reset());
814
815 for (i = 0; i < plugins_count; i++) {
816 int j;
817 struct bt_plugin *plugin = g_ptr_array_index(loaded_plugins, i);
290725f7
PP
818
819 component_classes_count =
820 bt_plugin_get_component_class_count(plugin);
22e22462
PP
821 printf("\n");
822 print_plugin_info(plugin);
290725f7
PP
823
824 if (component_classes_count == 0) {
9009cc24 825 printf(" %sComponent classes%s: (none)\n",
290725f7
PP
826 bt_common_color_bold(),
827 bt_common_color_reset());
828 } else {
829 printf(" %sComponent classes%s:\n",
830 bt_common_color_bold(),
831 bt_common_color_reset());
832 }
833
834 for (j = 0; j < component_classes_count; j++) {
835 struct bt_component_class *comp_class =
9ac68eb1
PP
836 bt_plugin_get_component_class_by_index(
837 plugin, j);
290725f7
PP
838 const char *comp_class_name =
839 bt_component_class_get_name(comp_class);
840 const char *comp_class_description =
841 bt_component_class_get_description(comp_class);
842 enum bt_component_class_type type =
843 bt_component_class_get_type(comp_class);
844
22e22462
PP
845 printf(" ");
846 print_plugin_comp_cls_opt(stdout,
847 bt_plugin_get_name(plugin), comp_class_name,
848 type);
290725f7
PP
849
850 if (comp_class_description) {
851 printf(": %s", comp_class_description);
852 }
853
854 printf("\n");
855 bt_put(comp_class);
856 }
857 }
858
859end:
860 return ret;
861}
862
9009cc24
PP
863static
864int cmd_print_lttng_live_sessions(struct bt_config *cfg)
db0f160a
PP
865{
866 printf("TODO\n");
867 return -1;
868}
869
9009cc24
PP
870static
871int cmd_print_ctf_metadata(struct bt_config *cfg)
05a67631
PP
872{
873 int ret = 0;
874 struct bt_component_class *comp_cls = NULL;
05a67631 875 struct bt_value *results = NULL;
05a67631
PP
876 struct bt_value *params = NULL;
877 struct bt_value *metadata_text_value = NULL;
878 const char *metadata_text = NULL;
db0f160a
PP
879 static const char * const plugin_name = "ctf";
880 static const char * const comp_cls_name = "fs";
881 static const enum bt_component_class_type comp_cls_type =
882 BT_COMPONENT_CLASS_TYPE_SOURCE;
883
884 assert(cfg->cmd_data.print_ctf_metadata.path);
885 comp_cls = find_component_class(plugin_name, comp_cls_name,
886 comp_cls_type);
05a67631
PP
887 if (!comp_cls) {
888 fprintf(stderr, "%s%sCannot find component class %s",
889 bt_common_color_bold(),
890 bt_common_color_fg_red(),
891 bt_common_color_reset());
db0f160a
PP
892 print_plugin_comp_cls_opt(stderr, plugin_name,
893 comp_cls_name, comp_cls_type);
05a67631
PP
894 fprintf(stderr, "\n");
895 ret = -1;
896 goto end;
897 }
898
05a67631
PP
899 params = bt_value_map_create();
900 if (!params) {
901 ret = -1;
902 goto end;
903 }
904
db0f160a
PP
905 ret = bt_value_map_insert_string(params, "path",
906 cfg->cmd_data.print_ctf_metadata.path->str);
05a67631
PP
907 if (ret) {
908 ret = -1;
909 goto end;
910 }
911
a67681c1 912 results = bt_component_class_query(comp_cls, "metadata-info",
05a67631
PP
913 params);
914 if (!results) {
915 ret = -1;
a67681c1 916 fprintf(stderr, "%s%sFailed to request metadata info%s\n",
05a67631
PP
917 bt_common_color_bold(),
918 bt_common_color_fg_red(),
919 bt_common_color_reset());
920 goto end;
921 }
922
923 metadata_text_value = bt_value_map_get(results, "text");
924 if (!metadata_text_value) {
925 ret = -1;
926 goto end;
927 }
928
929 ret = bt_value_string_get(metadata_text_value, &metadata_text);
930 assert(ret == 0);
931 printf("%s\n", metadata_text);
932
933end:
934 bt_put(results);
05a67631
PP
935 bt_put(params);
936 bt_put(metadata_text_value);
937 bt_put(comp_cls);
05a67631
PP
938 return 0;
939}
940
9009cc24
PP
941struct cmd_run_ctx {
942 /* Owned by this */
943 GHashTable *components;
944
945 /* Owned by this */
946 struct bt_graph *graph;
947
948 /* Weak */
949 struct bt_config *cfg;
950
951 bool connect_ports;
952};
953
954static
955int cmd_run_ctx_connect_upstream_port_to_downstream_component(
956 struct cmd_run_ctx *ctx, struct bt_component *upstream_comp,
957 struct bt_port *upstream_port,
958 struct bt_config_connection *cfg_conn)
290725f7
PP
959{
960 int ret = 0;
9009cc24
PP
961 GQuark downstreamp_comp_name_quark;
962 struct bt_component *downstream_comp;
963 int64_t downstream_port_count;
964 uint64_t i;
965 int64_t (*port_count_fn)(struct bt_component *);
966 struct bt_port *(*port_by_index_fn)(struct bt_component *, uint64_t);
967 void *conn = NULL;
968
969 downstreamp_comp_name_quark = g_quark_from_string(
970 cfg_conn->downstream_comp_name->str);
971 assert(downstreamp_comp_name_quark > 0);
972 downstream_comp = g_hash_table_lookup(ctx->components,
973 (gpointer) (long) downstreamp_comp_name_quark);
974 if (!downstream_comp) {
975 fprintf(stderr, "Cannot create connection: cannot find downstream component: %s\n",
976 cfg_conn->arg->str);
977 goto error;
978 }
979
980 if (bt_component_is_filter(downstream_comp)) {
981 port_count_fn = bt_component_filter_get_input_port_count;
982 port_by_index_fn = bt_component_filter_get_input_port_by_index;
983 } else if (bt_component_is_sink(downstream_comp)) {
984 port_count_fn = bt_component_sink_get_input_port_count;
985 port_by_index_fn = bt_component_sink_get_input_port_by_index;
986 } else {
987 /*
988 * Should never happen because the connections are
989 * validated before we get here.
990 */
991 assert(false);
992 }
290725f7 993
9009cc24
PP
994 downstream_port_count = port_count_fn(downstream_comp);
995 assert(downstream_port_count >= 0);
996
997 for (i = 0; i < downstream_port_count; i++) {
998 struct bt_port *downstream_port =
999 port_by_index_fn(downstream_comp, i);
1000 const char *downstream_port_name;
1001
1002 assert(downstream_port);
1003
1004 /* Skip port if it's already connected */
1005 if (bt_port_is_connected(downstream_port)) {
1006 bt_put(downstream_port);
1007 continue;
1008 }
1009
1010 downstream_port_name = bt_port_get_name(downstream_port);
1011 assert(downstream_port_name);
1012
1013 if (bt_common_star_glob_match(
1014 cfg_conn->downstream_port_glob->str, -1ULL,
1015 downstream_port_name, -1ULL)) {
1016 /* We have a winner! */
1017 conn = bt_graph_connect_ports(ctx->graph,
1018 upstream_port, downstream_port);
1019 bt_put(downstream_port);
1020 if (!conn) {
1021 fprintf(stderr,
1022 "Cannot create connection: graph refuses to connect ports (`%s` to `%s`): %s\n",
1023 bt_port_get_name(upstream_port),
1024 downstream_port_name,
1025 cfg_conn->arg->str);
1026 goto error;
1027 }
1028
1029 goto end;
1030 }
1031
1032 bt_put(downstream_port);
1033 }
1034
1035 if (!conn) {
1036 fprintf(stderr,
1037 "Cannot create connection: cannot find a matching downstream port for upstream port `%s`: %s\n",
1038 bt_port_get_name(upstream_port), cfg_conn->arg->str);
1039 goto error;
05a67631
PP
1040 }
1041
9009cc24
PP
1042 goto end;
1043
1044error:
1045 ret = -1;
1046
1047end:
1048 bt_put(conn);
1049 return ret;
1050}
1051
1052static
1053int cmd_run_ctx_connect_upstream_port(struct cmd_run_ctx *ctx,
1054 struct bt_port *upstream_port)
1055{
1056 int ret = 0;
1057 const char *upstream_port_name;
1058 const char *upstream_comp_name;
1059 struct bt_component *upstream_comp = NULL;
1060 size_t i;
1061
1062 assert(ctx);
1063 assert(upstream_port);
1064 upstream_port_name = bt_port_get_name(upstream_port);
1065 assert(upstream_port_name);
1066 upstream_comp = bt_port_get_component(upstream_port);
1067 if (!upstream_comp) {
1068 // TODO: log warning
98ecef32
MD
1069 ret = -1;
1070 goto end;
33bceaf8
JG
1071 }
1072
9009cc24
PP
1073 upstream_comp_name = bt_component_get_name(upstream_comp);
1074 assert(upstream_comp_name);
1075
1076 for (i = 0; i < ctx->cfg->cmd_data.run.connections->len; i++) {
1077 struct bt_config_connection *cfg_conn =
1078 g_ptr_array_index(
1079 ctx->cfg->cmd_data.run.connections, i);
1080
1081 if (strcmp(cfg_conn->upstream_comp_name->str,
1082 upstream_comp_name) == 0) {
1083 if (bt_common_star_glob_match(
1084 cfg_conn->upstream_port_glob->str,
1085 -1ULL, upstream_port_name, -1ULL)) {
1086 ret = cmd_run_ctx_connect_upstream_port_to_downstream_component(
1087 ctx, upstream_comp, upstream_port,
1088 cfg_conn);
1089 if (ret) {
1090 fprintf(stderr,
1091 "Cannot connect port `%s` of component `%s` to a downstream port: %s\n",
1092 upstream_port_name,
1093 upstream_comp_name,
1094 cfg_conn->arg->str);
1095 goto error;
1096 }
1097
1098 goto end;
1099 }
1100 }
1101 }
1102
1103 fprintf(stderr,
1104 "Cannot create connection: upstream port `%s` does not match any connection\n",
1105 bt_port_get_name(upstream_port));
1106
1107error:
1108 ret = -1;
1109
1110end:
1111 bt_put(upstream_comp);
1112 return ret;
1113}
1114
1115static
1116void graph_port_added_listener(struct bt_port *port, void *data)
1117{
1118 struct bt_component *comp = NULL;
1119 struct cmd_run_ctx *ctx = data;
1120
1121 if (bt_port_is_connected(port)) {
1122 // TODO: log warning
56a1cced
JG
1123 goto end;
1124 }
7c7c0433 1125
9009cc24
PP
1126 comp = bt_port_get_component(port);
1127 if (!comp) {
1128 // TODO: log warning
7c7c0433
JG
1129 goto end;
1130 }
1131
9009cc24
PP
1132 if (!bt_port_is_output(port)) {
1133 // TODO: log info
61ddbc8a
JG
1134 goto end;
1135 }
1136
9009cc24
PP
1137 if (cmd_run_ctx_connect_upstream_port(ctx, port)) {
1138 // TODO: log fatal
1139 fprintf(stderr, "Added port could not be connected: aborting\n");
1140 abort();
1141 }
1142
1143end:
1144 bt_put(comp);
1145 return;
1146}
1147
1148static
1149void graph_port_removed_listener(struct bt_component *component,
1150 struct bt_port *port, void *data)
1151{
1152 // TODO: log info
1153}
1154
1155static
1156void graph_ports_connected_listener(struct bt_port *upstream_port,
1157 struct bt_port *downstream_port, void *data)
1158{
1159 // TODO: log info
1160}
1161
1162static
1163void graph_ports_disconnected_listener(
1164 struct bt_component *upstream_component,
1165 struct bt_component *downstream_component,
1166 struct bt_port *upstream_port, struct bt_port *downstream_port,
1167 void *data)
1168{
1169 // TODO: log info
1170}
1171
1172static
1173void cmd_run_ctx_destroy(struct cmd_run_ctx *ctx)
1174{
1175 if (!ctx) {
1176 return;
1177 }
1178
1179 if (ctx->components) {
1180 g_hash_table_destroy(ctx->components);
1181 ctx->components = NULL;
1182 }
1183
1184 BT_PUT(ctx->graph);
1185 ctx->cfg = NULL;
1186}
1187
1188static
1189int cmd_run_ctx_init(struct cmd_run_ctx *ctx, struct bt_config *cfg)
1190{
1191 int ret = 0;
1192
1193 ctx->cfg = cfg;
1194 ctx->connect_ports = false;
1195 ctx->components = g_hash_table_new_full(g_direct_hash, g_direct_equal,
1196 NULL, bt_put);
1197 if (!ctx->components) {
1198 goto error;
1199 }
1200
1201 ctx->graph = bt_graph_create();
1202 if (!ctx->graph) {
1203 goto error;
1204 }
1205
1206 ret = bt_graph_add_port_added_listener(ctx->graph,
1207 graph_port_added_listener, ctx);
1208 if (ret) {
1209 goto error;
1210 }
1211
1212 ret = bt_graph_add_port_removed_listener(ctx->graph,
1213 graph_port_removed_listener, ctx);
1214 if (ret) {
1215 goto error;
1216 }
1217
1218 ret = bt_graph_add_ports_connected_listener(ctx->graph,
1219 graph_ports_connected_listener, ctx);
1220 if (ret) {
1221 goto error;
1222 }
1223
1224 ret = bt_graph_add_ports_disconnected_listener(ctx->graph,
1225 graph_ports_disconnected_listener, ctx);
1226 if (ret) {
1227 goto error;
1228 }
1229
1230 goto end;
1231
1232error:
1233 cmd_run_ctx_destroy(ctx);
1234 ret = -1;
1235
1236end:
1237 return ret;
1238}
1239
1240static
1241int cmd_run_ctx_create_components_from_config_components(
1242 struct cmd_run_ctx *ctx, GPtrArray *cfg_components)
1243{
1244 size_t i;
1245 struct bt_component_class *comp_cls = NULL;
1246 struct bt_component *comp = NULL;
1247 int ret = 0;
1248
1249 for (i = 0; i < cfg_components->len; i++) {
1250 struct bt_config_component *cfg_comp =
1251 g_ptr_array_index(cfg_components, i);
1252 GQuark quark;
1253
1254 comp_cls = find_component_class(cfg_comp->plugin_name->str,
1255 cfg_comp->comp_cls_name->str, cfg_comp->type);
1256 if (!comp_cls) {
1257 fprintf(stderr, "%s%sCannot find component class %s",
1258 bt_common_color_bold(),
1259 bt_common_color_fg_red(),
1260 bt_common_color_reset());
1261 print_plugin_comp_cls_opt(stderr,
1262 cfg_comp->plugin_name->str,
1263 cfg_comp->comp_cls_name->str,
1264 cfg_comp->type);
1265 fprintf(stderr, "\n");
1266 goto error;
1267 }
1268
1269 comp = bt_component_create(comp_cls,
1270 cfg_comp->instance_name->str, cfg_comp->params);
1271 if (!comp) {
1272 fprintf(stderr, "%s%sCannot create component `%s`%s\n",
1273 bt_common_color_bold(),
1274 bt_common_color_fg_red(),
1275 cfg_comp->instance_name->str,
1276 bt_common_color_reset());
1277 goto error;
1278 }
1279
1280 quark = g_quark_from_string(cfg_comp->instance_name->str);
1281 assert(quark > 0);
1282 g_hash_table_insert(ctx->components,
1283 (gpointer) (long) quark, comp);
1284 comp = NULL;
1285 BT_PUT(comp_cls);
1286 }
1287
1288 goto end;
1289
1290error:
1291 ret = -1;
1292
1293end:
1294 bt_put(comp);
1295 bt_put(comp_cls);
1296 return ret;
1297}
56a1cced 1298
9009cc24
PP
1299static
1300int cmd_run_ctx_create_components(struct cmd_run_ctx *ctx)
1301{
1302 int ret = 0;
1303
1304 /*
1305 * Make sure that, during this phase, our graph's "port added"
1306 * listener does not connect ports while we are creating the
1307 * components because we have a special, initial phase for
1308 * this.
1309 */
1310 ctx->connect_ports = false;
1311
1312 ret = cmd_run_ctx_create_components_from_config_components(
1313 ctx, ctx->cfg->cmd_data.run.sources);
1314 if (ret) {
7c7c0433 1315 ret = -1;
2e339de1
JG
1316 goto end;
1317 }
1318
9009cc24
PP
1319 ret = cmd_run_ctx_create_components_from_config_components(
1320 ctx, ctx->cfg->cmd_data.run.filters);
6c2f3ee5 1321 if (ret) {
290725f7 1322 ret = -1;
fec2a9f2
JG
1323 goto end;
1324 }
78586d8a 1325
9009cc24
PP
1326 ret = cmd_run_ctx_create_components_from_config_components(
1327 ctx, ctx->cfg->cmd_data.run.sinks);
1328 if (ret) {
1329 ret = -1;
1330 goto end;
1331 }
1332
1333end:
1334 return ret;
1335}
1336
1337static
1338int cmd_run_ctx_connect_comp_ports(struct cmd_run_ctx *ctx,
1339 struct bt_component *comp,
1340 int64_t (*port_count_fn)(struct bt_component *),
1341 struct bt_port *(*port_by_index_fn)(struct bt_component *, uint64_t))
1342{
1343 int ret = 0;
1344 int64_t count;
1345 uint64_t i;
1346
1347 count = port_count_fn(comp);
1348 assert(count >= 0);
1349
1350 for (i = 0; i < count; i++) {
1351 struct bt_port *upstream_port = port_by_index_fn(comp, i);
1352
1353 assert(upstream_port);
1354 ret = cmd_run_ctx_connect_upstream_port(ctx, upstream_port);
1355 bt_put(upstream_port);
1356 if (ret) {
1357 goto end;
1358 }
1359 }
1360
1361end:
1362 return ret;
1363}
1364
1365static
1366int cmd_run_ctx_connect_ports(struct cmd_run_ctx *ctx)
1367{
1368 int ret = 0;
1369 GHashTableIter iter;
1370 gpointer g_name_quark, g_comp;
1371
1372 ctx->connect_ports = true;
1373 g_hash_table_iter_init(&iter, ctx->components);
1374
1375 while (g_hash_table_iter_next(&iter, &g_name_quark, &g_comp)) {
1376 if (bt_component_is_source(g_comp)) {
1377 ret = cmd_run_ctx_connect_comp_ports(ctx,
1378 g_comp, bt_component_source_get_output_port_count,
1379 bt_component_source_get_output_port_by_index);
1380 } else if (bt_component_is_filter(g_comp)) {
1381 ret = cmd_run_ctx_connect_comp_ports(ctx,
1382 g_comp, bt_component_filter_get_output_port_count,
1383 bt_component_filter_get_output_port_by_index);
1384 }
1385
1386 if (ret) {
1387 goto end;
1388 }
1389 }
1390
1391end:
1392 return ret;
1393}
1394
1395static
1396int cmd_run(struct bt_config *cfg)
1397{
1398 int ret = 0;
1399 struct cmd_run_ctx ctx = { 0 };
1400
1401 ret = load_all_plugins(cfg->plugin_paths);
1402 if (ret) {
1403 goto error;
1404 }
1405
1406 /* Initialize the command's context and the graph object */
1407 if (cmd_run_ctx_init(&ctx, cfg)) {
1408 fprintf(stderr, "Cannot initialize the command's context\n");
1409 goto error;
1410 }
1411
1412 /* Create the requested component instances */
1413 if (cmd_run_ctx_create_components(&ctx)) {
1414 fprintf(stderr, "Cannot create components\n");
1415 goto error;
1416 }
1417
1418 /* Connect the initially visible component ports */
1419 if (cmd_run_ctx_connect_ports(&ctx)) {
1420 fprintf(stderr, "Cannot connect initial component ports\n");
1421 goto error;
1422 }
1423
1424 /* Run the graph */
fec2a9f2 1425 while (true) {
9009cc24 1426 enum bt_graph_status graph_status = bt_graph_run(ctx.graph);
61ddbc8a 1427
61ddbc8a 1428 switch (graph_status) {
9009cc24
PP
1429 case BT_GRAPH_STATUS_OK:
1430 break;
61ddbc8a 1431 case BT_GRAPH_STATUS_AGAIN:
9009cc24
PP
1432 if (cfg->cmd_data.run.retry_duration_us > 0) {
1433 if (usleep(cfg->cmd_data.run.retry_duration_us)) {
1434 // TODO: check EINTR and signal handler
1435 }
1436 }
78586d8a 1437 break;
fec2a9f2
JG
1438 case BT_COMPONENT_STATUS_END:
1439 goto end;
1440 default:
1441 fprintf(stderr, "Sink component returned an error, aborting...\n");
9009cc24 1442 goto error;
78586d8a 1443 }
fec2a9f2 1444 }
290725f7 1445
9009cc24
PP
1446 goto end;
1447
1448error:
1449 if (ret == 0) {
1450 ret = -1;
1451 }
1452
11e1d048 1453end:
9009cc24 1454 cmd_run_ctx_destroy(&ctx);
290725f7
PP
1455 return ret;
1456}
1457
9009cc24
PP
1458static
1459void warn_command_name_and_directory_clash(struct bt_config *cfg)
290725f7 1460{
9009cc24
PP
1461 const char *env_clash;
1462
290725f7
PP
1463 if (!cfg->command_name) {
1464 return;
1465 }
1466
9009cc24
PP
1467 env_clash = getenv(ENV_BABELTRACE_WARN_COMMAND_NAME_DIRECTORY_CLASH);
1468 if (env_clash && strcmp(env_clash, "0") == 0) {
1469 return;
1470 }
1471
290725f7
PP
1472 if (g_file_test(cfg->command_name,
1473 G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) {
1474 fprintf(stderr, "\nNOTE: The `%s` command was executed. If you meant to convert a\n",
1475 cfg->command_name);
1476 fprintf(stderr, "trace located in the local `%s` directory, please use:\n",
1477 cfg->command_name);
1478 fprintf(stderr, "\n");
1479 fprintf(stderr, " babeltrace convert %s [OPTIONS]\n",
1480 cfg->command_name);
1481 }
1482}
1483
1484int main(int argc, const char **argv)
1485{
1486 int ret;
1487 int retcode;
1488 struct bt_config *cfg;
1489
9009cc24
PP
1490 init_static_data();
1491 cfg = bt_config_cli_args_create_with_default(argc, argv, &retcode);
290725f7
PP
1492
1493 if (retcode < 0) {
1494 /* Quit without errors; typically usage/version */
1495 retcode = 0;
1496 goto end;
1497 }
1498
1499 if (retcode > 0) {
1500 goto end;
1501 }
1502
1503 if (!cfg) {
1504 fprintf(stderr, "Failed to create Babeltrace configuration\n");
db0f160a 1505 retcode = 1;
290725f7
PP
1506 goto end;
1507 }
1508
1509 babeltrace_debug = cfg->debug;
1510 babeltrace_verbose = cfg->verbose;
1511 print_cfg(cfg);
1512
db0f160a
PP
1513 if (cfg->command_needs_plugins) {
1514 ret = load_all_plugins(cfg->plugin_paths);
1515 if (ret) {
1516 retcode = 1;
1517 goto end;
1518 }
1519 }
1520
290725f7 1521 switch (cfg->command) {
db0f160a
PP
1522 case BT_CONFIG_COMMAND_RUN:
1523 ret = cmd_run(cfg);
290725f7
PP
1524 break;
1525 case BT_CONFIG_COMMAND_LIST_PLUGINS:
1526 ret = cmd_list_plugins(cfg);
1527 break;
22e22462
PP
1528 case BT_CONFIG_COMMAND_HELP:
1529 ret = cmd_help(cfg);
1530 break;
a67681c1
PP
1531 case BT_CONFIG_COMMAND_QUERY:
1532 ret = cmd_query(cfg);
63ce0e1d 1533 break;
db0f160a
PP
1534 case BT_CONFIG_COMMAND_PRINT_CTF_METADATA:
1535 ret = cmd_print_ctf_metadata(cfg);
1536 break;
1537 case BT_CONFIG_COMMAND_PRINT_LTTNG_LIVE_SESSIONS:
1538 ret = cmd_print_lttng_live_sessions(cfg);
1539 break;
290725f7
PP
1540 default:
1541 assert(false);
1542 }
1543
1544 warn_command_name_and_directory_clash(cfg);
1545 retcode = ret ? 1 : 0;
1546
1547end:
1548 BT_PUT(cfg);
9009cc24 1549 fini_static_data();
290725f7 1550 return retcode;
4c8bfb7e 1551}
This page took 0.117709 seconds and 4 git commands to generate.