lib: bt_object_{get,put}_ref(): accept a `const` parameter
[babeltrace.git] / cli / babeltrace-cfg-cli-args-connect.c
CommitLineData
ebba3338
PP
1/*
2 * Copyright 2017 Philippe Proulx <pproulx@efficios.com>
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 * SOFTWARE.
21 */
22
0fbb9a9f 23#include <stdlib.h>
ebba3338 24#include <babeltrace/values.h>
da91b29a 25#include <babeltrace/private-values.h>
db0f160a 26#include <babeltrace/common-internal.h>
ebba3338 27#include "babeltrace-cfg.h"
9009cc24 28#include "babeltrace-cfg-cli-args-connect.h"
ebba3338 29
db0f160a 30static bool all_named_and_printable_in_array(GPtrArray *comps)
ebba3338
PP
31{
32 size_t i;
db0f160a 33 bool all_named_and_printable = true;
ebba3338
PP
34
35 for (i = 0; i < comps->len; i++) {
36 struct bt_config_component *comp = g_ptr_array_index(comps, i);
37
38 if (comp->instance_name->len == 0) {
db0f160a
PP
39 all_named_and_printable = false;
40 goto end;
41 }
42
43 if (!bt_common_string_is_printable(comp->instance_name->str)) {
44 all_named_and_printable = false;
ebba3338
PP
45 goto end;
46 }
47 }
48
49end:
db0f160a 50 return all_named_and_printable;
ebba3338
PP
51}
52
db0f160a 53static bool all_named_and_printable(struct bt_config *cfg)
ebba3338 54{
db0f160a
PP
55 return all_named_and_printable_in_array(cfg->cmd_data.run.sources) &&
56 all_named_and_printable_in_array(cfg->cmd_data.run.filters) &&
57 all_named_and_printable_in_array(cfg->cmd_data.run.sinks);
ebba3338
PP
58}
59
ebba3338
PP
60static struct bt_config_connection *bt_config_connection_create(const char *arg)
61{
62 struct bt_config_connection *cfg_connection;
63
64 cfg_connection = g_new0(struct bt_config_connection, 1);
65 if (!cfg_connection) {
66 goto error;
67 }
68
9009cc24
PP
69 cfg_connection->upstream_comp_name = g_string_new(NULL);
70 if (!cfg_connection->upstream_comp_name) {
ebba3338
PP
71 goto error;
72 }
73
9009cc24
PP
74 cfg_connection->downstream_comp_name = g_string_new(NULL);
75 if (!cfg_connection->downstream_comp_name) {
ebba3338
PP
76 goto error;
77 }
78
9009cc24
PP
79 cfg_connection->upstream_port_glob = g_string_new("*");
80 if (!cfg_connection->upstream_port_glob) {
ebba3338
PP
81 goto error;
82 }
83
9009cc24
PP
84 cfg_connection->downstream_port_glob = g_string_new("*");
85 if (!cfg_connection->downstream_port_glob) {
ebba3338
PP
86 goto error;
87 }
88
89 cfg_connection->arg = g_string_new(arg);
90 if (!cfg_connection->arg) {
91 goto error;
92 }
93
94 goto end;
95
96error:
97 g_free(cfg_connection);
98 cfg_connection = NULL;
99
100end:
101 return cfg_connection;
102}
103
9009cc24
PP
104static bool validate_port_glob(const char *port_glob)
105{
106 bool is_valid = true;
107 const char *ch = port_glob;
108
f6ccaed9 109 BT_ASSERT(port_glob);
9009cc24
PP
110
111 while (*ch != '\0') {
112 switch (*ch) {
113 case '\\':
114 switch (ch[1]) {
115 case '\0':
116 goto end;
117 default:
118 ch += 2;
119 continue;
120 }
121 case '?':
122 case '[':
123 /*
124 * This is reserved for future use, to support
125 * full globbing patterns. Those characters must
126 * be escaped with `\`.
127 */
128 is_valid = false;
129 goto end;
130 default:
131 ch++;
132 break;
133 }
134 }
135
136end:
137 return is_valid;
138}
139
140static int normalize_glob_pattern(GString *glob_pattern_gs)
141{
142 int ret = 0;
143 char *glob_pattern = strdup(glob_pattern_gs->str);
144
145 if (!glob_pattern) {
146 ret = -1;
147 goto end;
148 }
149
150 bt_common_normalize_star_glob_pattern(glob_pattern);
151 g_string_assign(glob_pattern_gs, glob_pattern);
152 free(glob_pattern);
153
154end:
155 return ret;
156}
157
ebba3338
PP
158static struct bt_config_connection *cfg_connection_from_arg(const char *arg)
159{
db0f160a
PP
160 const char *at = arg;
161 size_t end_pos;
162 struct bt_config_connection *cfg_conn = NULL;
163 GString *gs = NULL;
ebba3338 164 enum {
9009cc24
PP
165 UPSTREAM_NAME,
166 DOWNSTREAM_NAME,
167 UPSTREAM_PORT_GLOB,
168 DOWNSTREAM_PORT_GLOB,
169 } state = UPSTREAM_NAME;
db0f160a
PP
170
171 if (!bt_common_string_is_printable(arg)) {
ebba3338
PP
172 goto error;
173 }
174
db0f160a
PP
175 cfg_conn = bt_config_connection_create(arg);
176 if (!cfg_conn) {
ebba3338
PP
177 goto error;
178 }
179
ebba3338 180 while (true) {
ebba3338 181 switch (state) {
9009cc24 182 case UPSTREAM_NAME:
db0f160a
PP
183 gs = bt_common_string_until(at, ".:\\", ".:", &end_pos);
184 if (!gs || gs->len == 0) {
ebba3338
PP
185 goto error;
186 }
187
9009cc24
PP
188 g_string_free(cfg_conn->upstream_comp_name, TRUE);
189 cfg_conn->upstream_comp_name = gs;
db0f160a 190 gs = NULL;
ebba3338 191
db0f160a 192 if (at[end_pos] == ':') {
9009cc24 193 state = DOWNSTREAM_NAME;
db0f160a 194 } else if (at[end_pos] == '.') {
9009cc24 195 state = UPSTREAM_PORT_GLOB;
db0f160a 196 } else {
ebba3338
PP
197 goto error;
198 }
199
db0f160a 200 at += end_pos + 1;
ebba3338 201 break;
9009cc24 202 case DOWNSTREAM_NAME:
db0f160a
PP
203 gs = bt_common_string_until(at, ".:\\", ".:", &end_pos);
204 if (!gs || gs->len == 0) {
ebba3338
PP
205 goto error;
206 }
207
9009cc24
PP
208 g_string_free(cfg_conn->downstream_comp_name, TRUE);
209 cfg_conn->downstream_comp_name = gs;
db0f160a
PP
210 gs = NULL;
211
212 if (at[end_pos] == '.') {
9009cc24 213 state = DOWNSTREAM_PORT_GLOB;
db0f160a
PP
214 } else if (at[end_pos] == '\0') {
215 goto end;
216 } else {
ebba3338
PP
217 goto error;
218 }
219
db0f160a 220 at += end_pos + 1;
ebba3338 221 break;
9009cc24
PP
222 case UPSTREAM_PORT_GLOB:
223 gs = bt_common_string_until(at, ".:", ".:", &end_pos);
db0f160a 224 if (!gs || gs->len == 0) {
ebba3338
PP
225 goto error;
226 }
227
9009cc24
PP
228 if (!validate_port_glob(gs->str)) {
229 goto error;
230 }
231
232 if (normalize_glob_pattern(gs)) {
233 goto error;
234 }
235
236 g_string_free(cfg_conn->upstream_port_glob, TRUE);
237 cfg_conn->upstream_port_glob = gs;
db0f160a
PP
238 gs = NULL;
239
240 if (at[end_pos] == ':') {
9009cc24 241 state = DOWNSTREAM_NAME;
db0f160a 242 } else {
ebba3338
PP
243 goto error;
244 }
245
db0f160a 246 at += end_pos + 1;
ebba3338 247 break;
9009cc24
PP
248 case DOWNSTREAM_PORT_GLOB:
249 gs = bt_common_string_until(at, ".:", ".:", &end_pos);
db0f160a 250 if (!gs || gs->len == 0) {
ebba3338
PP
251 goto error;
252 }
253
9009cc24
PP
254 if (!validate_port_glob(gs->str)) {
255 goto error;
256 }
257
258 if (normalize_glob_pattern(gs)) {
259 goto error;
260 }
261
262 g_string_free(cfg_conn->downstream_port_glob, TRUE);
263 cfg_conn->downstream_port_glob = gs;
db0f160a
PP
264 gs = NULL;
265
266 if (at[end_pos] == '\0') {
267 goto end;
268 } else {
269 goto error;
270 }
ebba3338
PP
271 break;
272 default:
0fbb9a9f 273 abort();
ebba3338
PP
274 }
275 }
276
ebba3338 277error:
db0f160a
PP
278 bt_config_connection_destroy(cfg_conn);
279 cfg_conn = NULL;
ebba3338
PP
280
281end:
db0f160a
PP
282 if (gs) {
283 g_string_free(gs, TRUE);
ebba3338
PP
284 }
285
db0f160a 286 return cfg_conn;
ebba3338
PP
287}
288
289static struct bt_config_component *find_component_in_array(GPtrArray *comps,
290 const char *name)
291{
292 size_t i;
293 struct bt_config_component *found_comp = NULL;
294
295 for (i = 0; i < comps->len; i++) {
296 struct bt_config_component *comp = g_ptr_array_index(comps, i);
297
298 if (strcmp(name, comp->instance_name->str) == 0) {
398454ed
PP
299 found_comp = comp;
300 bt_object_get_ref(found_comp);
ebba3338
PP
301 goto end;
302 }
303 }
304
305end:
306 return found_comp;
307}
308
309static struct bt_config_component *find_component(struct bt_config *cfg,
90de159b 310 const char *name)
ebba3338
PP
311{
312 struct bt_config_component *comp;
313
db0f160a 314 comp = find_component_in_array(cfg->cmd_data.run.sources, name);
ebba3338 315 if (comp) {
ebba3338
PP
316 goto end;
317 }
318
db0f160a 319 comp = find_component_in_array(cfg->cmd_data.run.filters, name);
ebba3338 320 if (comp) {
ebba3338
PP
321 goto end;
322 }
323
db0f160a 324 comp = find_component_in_array(cfg->cmd_data.run.sinks, name);
ebba3338 325 if (comp) {
ebba3338
PP
326 goto end;
327 }
328
329end:
330 return comp;
331}
332
333static int validate_all_endpoints_exist(struct bt_config *cfg, char *error_buf,
334 size_t error_buf_size)
335{
336 size_t i;
337 int ret = 0;
338
db0f160a 339 for (i = 0; i < cfg->cmd_data.run.connections->len; i++) {
ebba3338 340 struct bt_config_connection *connection =
db0f160a 341 g_ptr_array_index(cfg->cmd_data.run.connections, i);
ebba3338 342 struct bt_config_component *comp;
ebba3338 343
9009cc24 344 comp = find_component(cfg, connection->upstream_comp_name->str);
65300d60 345 bt_object_put_ref(comp);
ebba3338 346 if (!comp) {
db0f160a
PP
347 snprintf(error_buf, error_buf_size,
348 "Invalid connection: cannot find upstream component `%s`:\n %s\n",
9009cc24 349 connection->upstream_comp_name->str,
db0f160a
PP
350 connection->arg->str);
351 ret = -1;
352 goto end;
353 }
354
9009cc24 355 comp = find_component(cfg, connection->downstream_comp_name->str);
65300d60 356 bt_object_put_ref(comp);
db0f160a
PP
357 if (!comp) {
358 snprintf(error_buf, error_buf_size,
359 "Invalid connection: cannot find downstream component `%s`:\n %s\n",
9009cc24 360 connection->downstream_comp_name->str,
db0f160a
PP
361 connection->arg->str);
362 ret = -1;
363 goto end;
ebba3338
PP
364 }
365 }
366
367end:
368 return ret;
369}
370
371static int validate_connection_directions(struct bt_config *cfg,
372 char *error_buf, size_t error_buf_size)
373{
374 size_t i;
375 int ret = 0;
376 struct bt_config_component *src_comp = NULL;
377 struct bt_config_component *dst_comp = NULL;
378
db0f160a 379 for (i = 0; i < cfg->cmd_data.run.connections->len; i++) {
ebba3338 380 struct bt_config_connection *connection =
db0f160a 381 g_ptr_array_index(cfg->cmd_data.run.connections, i);
ebba3338
PP
382
383 src_comp = find_component(cfg,
9009cc24 384 connection->upstream_comp_name->str);
f6ccaed9 385 BT_ASSERT(src_comp);
ebba3338 386 dst_comp = find_component(cfg,
9009cc24 387 connection->downstream_comp_name->str);
f6ccaed9 388 BT_ASSERT(dst_comp);
ebba3338 389
90de159b
PP
390 if (src_comp->type == BT_COMPONENT_CLASS_TYPE_SOURCE) {
391 if (dst_comp->type != BT_COMPONENT_CLASS_TYPE_FILTER &&
392 dst_comp->type != BT_COMPONENT_CLASS_TYPE_SINK) {
ebba3338
PP
393 snprintf(error_buf, error_buf_size,
394 "Invalid connection: source component `%s` not connected to filter or sink component:\n %s\n",
9009cc24 395 connection->upstream_comp_name->str,
ebba3338
PP
396 connection->arg->str);
397 ret = -1;
398 goto end;
399 }
90de159b
PP
400 } else if (src_comp->type == BT_COMPONENT_CLASS_TYPE_FILTER) {
401 if (dst_comp->type != BT_COMPONENT_CLASS_TYPE_FILTER &&
402 dst_comp->type != BT_COMPONENT_CLASS_TYPE_SINK) {
ebba3338
PP
403 snprintf(error_buf, error_buf_size,
404 "Invalid connection: filter component `%s` not connected to filter or sink component:\n %s\n",
9009cc24 405 connection->upstream_comp_name->str,
ebba3338
PP
406 connection->arg->str);
407 ret = -1;
408 goto end;
409 }
410 } else {
411 snprintf(error_buf, error_buf_size,
412 "Invalid connection: cannot connect sink component `%s` to component `%s`:\n %s\n",
9009cc24
PP
413 connection->upstream_comp_name->str,
414 connection->downstream_comp_name->str,
ebba3338
PP
415 connection->arg->str);
416 ret = -1;
417 goto end;
418 }
419
65300d60
PP
420 BT_OBJECT_PUT_REF_AND_RESET(src_comp);
421 BT_OBJECT_PUT_REF_AND_RESET(dst_comp);
ebba3338
PP
422 }
423
424end:
65300d60
PP
425 bt_object_put_ref(src_comp);
426 bt_object_put_ref(dst_comp);
ebba3338
PP
427 return ret;
428}
429
db0f160a
PP
430static int validate_no_cycles_rec(struct bt_config *cfg, GPtrArray *path,
431 char *error_buf, size_t error_buf_size)
432{
433 int ret = 0;
434 size_t conn_i;
435 const char *src_comp_name;
436
f6ccaed9 437 BT_ASSERT(path && path->len > 0);
db0f160a
PP
438 src_comp_name = g_ptr_array_index(path, path->len - 1);
439
440 for (conn_i = 0; conn_i < cfg->cmd_data.run.connections->len; conn_i++) {
441 struct bt_config_connection *conn =
442 g_ptr_array_index(cfg->cmd_data.run.connections, conn_i);
443
9009cc24 444 if (strcmp(conn->upstream_comp_name->str, src_comp_name) == 0) {
db0f160a
PP
445 size_t path_i;
446
447 for (path_i = 0; path_i < path->len; path_i++) {
448 const char *comp_name =
449 g_ptr_array_index(path, path_i);
450
9009cc24 451 if (strcmp(comp_name, conn->downstream_comp_name->str) == 0) {
db0f160a
PP
452 snprintf(error_buf, error_buf_size,
453 "Invalid connection: connection forms a cycle:\n %s\n",
454 conn->arg->str);
455 ret = -1;
456 goto end;
457 }
458 }
459
9009cc24 460 g_ptr_array_add(path, conn->downstream_comp_name->str);
db0f160a
PP
461 ret = validate_no_cycles_rec(cfg, path, error_buf,
462 error_buf_size);
463 if (ret) {
464 goto end;
465 }
466
467 g_ptr_array_remove_index(path, path->len - 1);
468 }
469 }
470
471end:
472 return ret;
473}
474
475static int validate_no_cycles(struct bt_config *cfg, char *error_buf,
ebba3338
PP
476 size_t error_buf_size)
477{
478 size_t i;
479 int ret = 0;
db0f160a 480 GPtrArray *path;
ebba3338 481
db0f160a
PP
482 path = g_ptr_array_new();
483 if (!path) {
484 ret = -1;
485 goto end;
486 }
ebba3338 487
db0f160a
PP
488 g_ptr_array_add(path, NULL);
489
490 for (i = 0; i < cfg->cmd_data.run.connections->len; i++) {
491 struct bt_config_connection *conn =
492 g_ptr_array_index(cfg->cmd_data.run.connections, i);
493
9009cc24 494 g_ptr_array_index(path, 0) = conn->upstream_comp_name->str;
db0f160a
PP
495 ret = validate_no_cycles_rec(cfg, path,
496 error_buf, error_buf_size);
497 if (ret) {
ebba3338
PP
498 goto end;
499 }
500 }
501
502end:
db0f160a
PP
503 if (path) {
504 g_ptr_array_free(path, TRUE);
505 }
506
ebba3338
PP
507 return ret;
508}
509
510static int validate_all_components_connected_in_array(GPtrArray *comps,
511 struct bt_value *connected_components,
512 char *error_buf, size_t error_buf_size)
513{
514 int ret = 0;
515 size_t i;
516
517 for (i = 0; i < comps->len; i++) {
518 struct bt_config_component *comp = g_ptr_array_index(comps, i);
519
07208d85 520 if (!bt_value_map_has_entry(connected_components,
ebba3338
PP
521 comp->instance_name->str)) {
522 snprintf(error_buf, error_buf_size,
523 "Component `%s` is not connected\n",
524 comp->instance_name->str);
525 ret = -1;
526 goto end;
527 }
528 }
529
530end:
531 return ret;
532}
533
534static int validate_all_components_connected(struct bt_config *cfg,
535 char *error_buf, size_t error_buf_size)
536{
537 size_t i;
538 int ret = 0;
da91b29a
PP
539 struct bt_private_value *connected_components =
540 bt_private_value_map_create();
ebba3338
PP
541
542 if (!connected_components) {
543 ret = -1;
544 goto end;
545 }
546
db0f160a 547 for (i = 0; i < cfg->cmd_data.run.connections->len; i++) {
ebba3338 548 struct bt_config_connection *connection =
db0f160a 549 g_ptr_array_index(cfg->cmd_data.run.connections, i);
ebba3338 550
da91b29a 551 ret = bt_private_value_map_insert_entry(connected_components,
9009cc24 552 connection->upstream_comp_name->str, bt_value_null);
ebba3338
PP
553 if (ret) {
554 goto end;
555 }
556
da91b29a 557 ret = bt_private_value_map_insert_entry(connected_components,
9009cc24 558 connection->downstream_comp_name->str, bt_value_null);
ebba3338
PP
559 if (ret) {
560 goto end;
561 }
562 }
563
564 ret = validate_all_components_connected_in_array(
da91b29a 565 cfg->cmd_data.run.sources,
707b7d35 566 bt_private_value_as_value(connected_components),
ebba3338
PP
567 error_buf, error_buf_size);
568 if (ret) {
569 goto end;
570 }
571
572 ret = validate_all_components_connected_in_array(
da91b29a 573 cfg->cmd_data.run.filters,
707b7d35 574 bt_private_value_as_value(connected_components),
ebba3338
PP
575 error_buf, error_buf_size);
576 if (ret) {
577 goto end;
578 }
579
580 ret = validate_all_components_connected_in_array(
da91b29a 581 cfg->cmd_data.run.sinks,
707b7d35 582 bt_private_value_as_value(connected_components),
ebba3338
PP
583 error_buf, error_buf_size);
584 if (ret) {
585 goto end;
586 }
587
588end:
65300d60 589 bt_object_put_ref(connected_components);
ebba3338
PP
590 return ret;
591}
592
593static int validate_no_duplicate_connection(struct bt_config *cfg,
594 char *error_buf, size_t error_buf_size)
595{
596 size_t i;
597 int ret = 0;
da91b29a
PP
598 struct bt_private_value *flat_connection_names =
599 bt_private_value_map_create();
ebba3338
PP
600 GString *flat_connection_name = NULL;
601
602 if (!flat_connection_names) {
603 ret = -1;
604 goto end;
605 }
606
607 flat_connection_name = g_string_new(NULL);
608 if (!flat_connection_name) {
609 ret = -1;
610 goto end;
611 }
612
db0f160a 613 for (i = 0; i < cfg->cmd_data.run.connections->len; i++) {
ebba3338 614 struct bt_config_connection *connection =
db0f160a 615 g_ptr_array_index(cfg->cmd_data.run.connections, i);
ebba3338 616
db0f160a 617 g_string_printf(flat_connection_name, "%s\x01%s\x01%s\x01%s",
9009cc24
PP
618 connection->upstream_comp_name->str,
619 connection->upstream_port_glob->str,
620 connection->downstream_comp_name->str,
621 connection->downstream_port_glob->str);
ebba3338 622
707b7d35 623 if (bt_value_map_has_entry(bt_private_value_as_value(
da91b29a 624 flat_connection_names),
ebba3338
PP
625 flat_connection_name->str)) {
626 snprintf(error_buf, error_buf_size,
627 "Duplicate connection:\n %s\n",
628 connection->arg->str);
629 ret = -1;
630 goto end;
631 }
632
da91b29a 633 ret = bt_private_value_map_insert_entry(flat_connection_names,
ebba3338
PP
634 flat_connection_name->str, bt_value_null);
635 if (ret) {
636 goto end;
637 }
638 }
639
640end:
65300d60 641 bt_object_put_ref(flat_connection_names);
ebba3338
PP
642
643 if (flat_connection_name) {
644 g_string_free(flat_connection_name, TRUE);
645 }
646
647 return ret;
648}
649
650static int validate_connections(struct bt_config *cfg, char *error_buf,
651 size_t error_buf_size)
652{
653 int ret;
654
655 ret = validate_all_endpoints_exist(cfg, error_buf, error_buf_size);
656 if (ret) {
657 goto end;
658 }
659
660 ret = validate_connection_directions(cfg, error_buf, error_buf_size);
661 if (ret) {
662 goto end;
663 }
664
ebba3338
PP
665 ret = validate_all_components_connected(cfg, error_buf, error_buf_size);
666 if (ret) {
667 goto end;
668 }
669
670 ret = validate_no_duplicate_connection(cfg, error_buf, error_buf_size);
671 if (ret) {
672 goto end;
673 }
674
db0f160a 675 ret = validate_no_cycles(cfg, error_buf, error_buf_size);
ebba3338
PP
676 if (ret) {
677 goto end;
678 }
679
ebba3338 680end:
ebba3338
PP
681 return ret;
682}
683
9009cc24 684int bt_config_cli_args_create_connections(struct bt_config *cfg,
ebba3338
PP
685 struct bt_value *connection_args,
686 char *error_buf, size_t error_buf_size)
687{
688 int ret;
689 size_t i;
690
db0f160a
PP
691 if (!all_named_and_printable(cfg)) {
692 snprintf(error_buf, error_buf_size,
693 "One or more components are unnamed (use --name) or contain a non-printable character\n");
ebba3338
PP
694 goto error;
695 }
696
07208d85 697 for (i = 0; i < bt_value_array_get_size(connection_args); i++) {
ebba3338 698 struct bt_value *arg_value =
07208d85
PP
699 bt_value_array_borrow_element_by_index(
700 connection_args, i);
ebba3338
PP
701 const char *arg;
702 struct bt_config_connection *cfg_connection;
703
601b0d3c 704 arg = bt_value_string_get(arg_value);
ebba3338
PP
705 cfg_connection = cfg_connection_from_arg(arg);
706 if (!cfg_connection) {
707 snprintf(error_buf, error_buf_size, "Cannot parse --connect option's argument:\n %s\n",
708 arg);
709 goto error;
710 }
711
db0f160a 712 g_ptr_array_add(cfg->cmd_data.run.connections,
ebba3338
PP
713 cfg_connection);
714 }
715
716
717 ret = validate_connections(cfg, error_buf, error_buf_size);
718 if (ret) {
719 goto error;
720 }
721
722 goto end;
723
724error:
725 ret = -1;
726
727end:
728 return ret;
729}
This page took 0.065165 seconds and 4 git commands to generate.