Cleanup: remove private babeltrace.h
[babeltrace.git] / src / cli / babeltrace2-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
91d81473 23#include <stdio.h>
0fbb9a9f 24#include <stdlib.h>
91d81473 25#include <string.h>
3fadfbc0 26#include <babeltrace2/babeltrace.h>
578e048b 27#include "common/common.h"
ec2c5e50
MJ
28#include "babeltrace2-cfg.h"
29#include "babeltrace2-cfg-cli-args-connect.h"
ebba3338 30
db0f160a 31static bool all_named_and_printable_in_array(GPtrArray *comps)
ebba3338
PP
32{
33 size_t i;
db0f160a 34 bool all_named_and_printable = true;
ebba3338
PP
35
36 for (i = 0; i < comps->len; i++) {
37 struct bt_config_component *comp = g_ptr_array_index(comps, i);
38
39 if (comp->instance_name->len == 0) {
db0f160a
PP
40 all_named_and_printable = false;
41 goto end;
42 }
43
44 if (!bt_common_string_is_printable(comp->instance_name->str)) {
45 all_named_and_printable = false;
ebba3338
PP
46 goto end;
47 }
48 }
49
50end:
db0f160a 51 return all_named_and_printable;
ebba3338
PP
52}
53
db0f160a 54static bool all_named_and_printable(struct bt_config *cfg)
ebba3338 55{
db0f160a
PP
56 return all_named_and_printable_in_array(cfg->cmd_data.run.sources) &&
57 all_named_and_printable_in_array(cfg->cmd_data.run.filters) &&
58 all_named_and_printable_in_array(cfg->cmd_data.run.sinks);
ebba3338
PP
59}
60
ebba3338
PP
61static struct bt_config_connection *bt_config_connection_create(const char *arg)
62{
63 struct bt_config_connection *cfg_connection;
64
65 cfg_connection = g_new0(struct bt_config_connection, 1);
66 if (!cfg_connection) {
67 goto error;
68 }
69
9009cc24
PP
70 cfg_connection->upstream_comp_name = g_string_new(NULL);
71 if (!cfg_connection->upstream_comp_name) {
ebba3338
PP
72 goto error;
73 }
74
9009cc24
PP
75 cfg_connection->downstream_comp_name = g_string_new(NULL);
76 if (!cfg_connection->downstream_comp_name) {
ebba3338
PP
77 goto error;
78 }
79
9009cc24
PP
80 cfg_connection->upstream_port_glob = g_string_new("*");
81 if (!cfg_connection->upstream_port_glob) {
ebba3338
PP
82 goto error;
83 }
84
9009cc24
PP
85 cfg_connection->downstream_port_glob = g_string_new("*");
86 if (!cfg_connection->downstream_port_glob) {
ebba3338
PP
87 goto error;
88 }
89
90 cfg_connection->arg = g_string_new(arg);
91 if (!cfg_connection->arg) {
92 goto error;
93 }
94
95 goto end;
96
97error:
98 g_free(cfg_connection);
99 cfg_connection = NULL;
100
101end:
102 return cfg_connection;
103}
104
9009cc24
PP
105static bool validate_port_glob(const char *port_glob)
106{
107 bool is_valid = true;
108 const char *ch = port_glob;
109
f6ccaed9 110 BT_ASSERT(port_glob);
9009cc24
PP
111
112 while (*ch != '\0') {
113 switch (*ch) {
114 case '\\':
115 switch (ch[1]) {
116 case '\0':
117 goto end;
118 default:
119 ch += 2;
120 continue;
121 }
122 case '?':
123 case '[':
124 /*
125 * This is reserved for future use, to support
126 * full globbing patterns. Those characters must
127 * be escaped with `\`.
128 */
129 is_valid = false;
130 goto end;
131 default:
132 ch++;
133 break;
134 }
135 }
136
137end:
138 return is_valid;
139}
140
141static int normalize_glob_pattern(GString *glob_pattern_gs)
142{
143 int ret = 0;
144 char *glob_pattern = strdup(glob_pattern_gs->str);
145
146 if (!glob_pattern) {
147 ret = -1;
148 goto end;
149 }
150
151 bt_common_normalize_star_glob_pattern(glob_pattern);
152 g_string_assign(glob_pattern_gs, glob_pattern);
153 free(glob_pattern);
154
155end:
156 return ret;
157}
158
ebba3338
PP
159static struct bt_config_connection *cfg_connection_from_arg(const char *arg)
160{
db0f160a
PP
161 const char *at = arg;
162 size_t end_pos;
163 struct bt_config_connection *cfg_conn = NULL;
164 GString *gs = NULL;
ebba3338 165 enum {
9009cc24
PP
166 UPSTREAM_NAME,
167 DOWNSTREAM_NAME,
168 UPSTREAM_PORT_GLOB,
169 DOWNSTREAM_PORT_GLOB,
170 } state = UPSTREAM_NAME;
db0f160a
PP
171
172 if (!bt_common_string_is_printable(arg)) {
ebba3338
PP
173 goto error;
174 }
175
db0f160a
PP
176 cfg_conn = bt_config_connection_create(arg);
177 if (!cfg_conn) {
ebba3338
PP
178 goto error;
179 }
180
ebba3338 181 while (true) {
ebba3338 182 switch (state) {
9009cc24 183 case UPSTREAM_NAME:
db0f160a
PP
184 gs = bt_common_string_until(at, ".:\\", ".:", &end_pos);
185 if (!gs || gs->len == 0) {
ebba3338
PP
186 goto error;
187 }
188
9009cc24
PP
189 g_string_free(cfg_conn->upstream_comp_name, TRUE);
190 cfg_conn->upstream_comp_name = gs;
db0f160a 191 gs = NULL;
ebba3338 192
db0f160a 193 if (at[end_pos] == ':') {
9009cc24 194 state = DOWNSTREAM_NAME;
db0f160a 195 } else if (at[end_pos] == '.') {
9009cc24 196 state = UPSTREAM_PORT_GLOB;
db0f160a 197 } else {
ebba3338
PP
198 goto error;
199 }
200
db0f160a 201 at += end_pos + 1;
ebba3338 202 break;
9009cc24 203 case DOWNSTREAM_NAME:
db0f160a
PP
204 gs = bt_common_string_until(at, ".:\\", ".:", &end_pos);
205 if (!gs || gs->len == 0) {
ebba3338
PP
206 goto error;
207 }
208
9009cc24
PP
209 g_string_free(cfg_conn->downstream_comp_name, TRUE);
210 cfg_conn->downstream_comp_name = gs;
db0f160a
PP
211 gs = NULL;
212
213 if (at[end_pos] == '.') {
9009cc24 214 state = DOWNSTREAM_PORT_GLOB;
db0f160a
PP
215 } else if (at[end_pos] == '\0') {
216 goto end;
217 } else {
ebba3338
PP
218 goto error;
219 }
220
db0f160a 221 at += end_pos + 1;
ebba3338 222 break;
9009cc24
PP
223 case UPSTREAM_PORT_GLOB:
224 gs = bt_common_string_until(at, ".:", ".:", &end_pos);
db0f160a 225 if (!gs || gs->len == 0) {
ebba3338
PP
226 goto error;
227 }
228
9009cc24
PP
229 if (!validate_port_glob(gs->str)) {
230 goto error;
231 }
232
233 if (normalize_glob_pattern(gs)) {
234 goto error;
235 }
236
237 g_string_free(cfg_conn->upstream_port_glob, TRUE);
238 cfg_conn->upstream_port_glob = gs;
db0f160a
PP
239 gs = NULL;
240
241 if (at[end_pos] == ':') {
9009cc24 242 state = DOWNSTREAM_NAME;
db0f160a 243 } else {
ebba3338
PP
244 goto error;
245 }
246
db0f160a 247 at += end_pos + 1;
ebba3338 248 break;
9009cc24
PP
249 case DOWNSTREAM_PORT_GLOB:
250 gs = bt_common_string_until(at, ".:", ".:", &end_pos);
db0f160a 251 if (!gs || gs->len == 0) {
ebba3338
PP
252 goto error;
253 }
254
9009cc24
PP
255 if (!validate_port_glob(gs->str)) {
256 goto error;
257 }
258
259 if (normalize_glob_pattern(gs)) {
260 goto error;
261 }
262
263 g_string_free(cfg_conn->downstream_port_glob, TRUE);
264 cfg_conn->downstream_port_glob = gs;
db0f160a
PP
265 gs = NULL;
266
267 if (at[end_pos] == '\0') {
268 goto end;
269 } else {
270 goto error;
271 }
ebba3338
PP
272 break;
273 default:
0fbb9a9f 274 abort();
ebba3338
PP
275 }
276 }
277
ebba3338 278error:
db0f160a
PP
279 bt_config_connection_destroy(cfg_conn);
280 cfg_conn = NULL;
ebba3338
PP
281
282end:
db0f160a
PP
283 if (gs) {
284 g_string_free(gs, TRUE);
ebba3338
PP
285 }
286
db0f160a 287 return cfg_conn;
ebba3338
PP
288}
289
290static struct bt_config_component *find_component_in_array(GPtrArray *comps,
291 const char *name)
292{
293 size_t i;
294 struct bt_config_component *found_comp = NULL;
295
296 for (i = 0; i < comps->len; i++) {
297 struct bt_config_component *comp = g_ptr_array_index(comps, i);
298
299 if (strcmp(name, comp->instance_name->str) == 0) {
398454ed
PP
300 found_comp = comp;
301 bt_object_get_ref(found_comp);
ebba3338
PP
302 goto end;
303 }
304 }
305
306end:
307 return found_comp;
308}
309
310static struct bt_config_component *find_component(struct bt_config *cfg,
90de159b 311 const char *name)
ebba3338
PP
312{
313 struct bt_config_component *comp;
314
db0f160a 315 comp = find_component_in_array(cfg->cmd_data.run.sources, name);
ebba3338 316 if (comp) {
ebba3338
PP
317 goto end;
318 }
319
db0f160a 320 comp = find_component_in_array(cfg->cmd_data.run.filters, name);
ebba3338 321 if (comp) {
ebba3338
PP
322 goto end;
323 }
324
db0f160a 325 comp = find_component_in_array(cfg->cmd_data.run.sinks, name);
ebba3338 326 if (comp) {
ebba3338
PP
327 goto end;
328 }
329
330end:
331 return comp;
332}
333
334static int validate_all_endpoints_exist(struct bt_config *cfg, char *error_buf,
335 size_t error_buf_size)
336{
337 size_t i;
338 int ret = 0;
339
db0f160a 340 for (i = 0; i < cfg->cmd_data.run.connections->len; i++) {
ebba3338 341 struct bt_config_connection *connection =
db0f160a 342 g_ptr_array_index(cfg->cmd_data.run.connections, i);
ebba3338 343 struct bt_config_component *comp;
ebba3338 344
9009cc24 345 comp = find_component(cfg, connection->upstream_comp_name->str);
65300d60 346 bt_object_put_ref(comp);
ebba3338 347 if (!comp) {
db0f160a
PP
348 snprintf(error_buf, error_buf_size,
349 "Invalid connection: cannot find upstream component `%s`:\n %s\n",
9009cc24 350 connection->upstream_comp_name->str,
db0f160a
PP
351 connection->arg->str);
352 ret = -1;
353 goto end;
354 }
355
9009cc24 356 comp = find_component(cfg, connection->downstream_comp_name->str);
65300d60 357 bt_object_put_ref(comp);
db0f160a
PP
358 if (!comp) {
359 snprintf(error_buf, error_buf_size,
360 "Invalid connection: cannot find downstream component `%s`:\n %s\n",
9009cc24 361 connection->downstream_comp_name->str,
db0f160a
PP
362 connection->arg->str);
363 ret = -1;
364 goto end;
ebba3338
PP
365 }
366 }
367
368end:
369 return ret;
370}
371
372static int validate_connection_directions(struct bt_config *cfg,
373 char *error_buf, size_t error_buf_size)
374{
375 size_t i;
376 int ret = 0;
377 struct bt_config_component *src_comp = NULL;
378 struct bt_config_component *dst_comp = NULL;
379
db0f160a 380 for (i = 0; i < cfg->cmd_data.run.connections->len; i++) {
ebba3338 381 struct bt_config_connection *connection =
db0f160a 382 g_ptr_array_index(cfg->cmd_data.run.connections, i);
ebba3338
PP
383
384 src_comp = find_component(cfg,
9009cc24 385 connection->upstream_comp_name->str);
f6ccaed9 386 BT_ASSERT(src_comp);
ebba3338 387 dst_comp = find_component(cfg,
9009cc24 388 connection->downstream_comp_name->str);
f6ccaed9 389 BT_ASSERT(dst_comp);
ebba3338 390
90de159b
PP
391 if (src_comp->type == BT_COMPONENT_CLASS_TYPE_SOURCE) {
392 if (dst_comp->type != BT_COMPONENT_CLASS_TYPE_FILTER &&
393 dst_comp->type != BT_COMPONENT_CLASS_TYPE_SINK) {
ebba3338
PP
394 snprintf(error_buf, error_buf_size,
395 "Invalid connection: source component `%s` not connected to filter or sink component:\n %s\n",
9009cc24 396 connection->upstream_comp_name->str,
ebba3338
PP
397 connection->arg->str);
398 ret = -1;
399 goto end;
400 }
90de159b
PP
401 } else if (src_comp->type == BT_COMPONENT_CLASS_TYPE_FILTER) {
402 if (dst_comp->type != BT_COMPONENT_CLASS_TYPE_FILTER &&
403 dst_comp->type != BT_COMPONENT_CLASS_TYPE_SINK) {
ebba3338
PP
404 snprintf(error_buf, error_buf_size,
405 "Invalid connection: filter component `%s` not connected to filter or sink component:\n %s\n",
9009cc24 406 connection->upstream_comp_name->str,
ebba3338
PP
407 connection->arg->str);
408 ret = -1;
409 goto end;
410 }
411 } else {
412 snprintf(error_buf, error_buf_size,
413 "Invalid connection: cannot connect sink component `%s` to component `%s`:\n %s\n",
9009cc24
PP
414 connection->upstream_comp_name->str,
415 connection->downstream_comp_name->str,
ebba3338
PP
416 connection->arg->str);
417 ret = -1;
418 goto end;
419 }
420
65300d60
PP
421 BT_OBJECT_PUT_REF_AND_RESET(src_comp);
422 BT_OBJECT_PUT_REF_AND_RESET(dst_comp);
ebba3338
PP
423 }
424
425end:
65300d60
PP
426 bt_object_put_ref(src_comp);
427 bt_object_put_ref(dst_comp);
ebba3338
PP
428 return ret;
429}
430
db0f160a
PP
431static int validate_no_cycles_rec(struct bt_config *cfg, GPtrArray *path,
432 char *error_buf, size_t error_buf_size)
433{
434 int ret = 0;
435 size_t conn_i;
436 const char *src_comp_name;
437
f6ccaed9 438 BT_ASSERT(path && path->len > 0);
db0f160a
PP
439 src_comp_name = g_ptr_array_index(path, path->len - 1);
440
441 for (conn_i = 0; conn_i < cfg->cmd_data.run.connections->len; conn_i++) {
442 struct bt_config_connection *conn =
443 g_ptr_array_index(cfg->cmd_data.run.connections, conn_i);
444
9009cc24 445 if (strcmp(conn->upstream_comp_name->str, src_comp_name) == 0) {
db0f160a
PP
446 size_t path_i;
447
448 for (path_i = 0; path_i < path->len; path_i++) {
449 const char *comp_name =
450 g_ptr_array_index(path, path_i);
451
9009cc24 452 if (strcmp(comp_name, conn->downstream_comp_name->str) == 0) {
db0f160a
PP
453 snprintf(error_buf, error_buf_size,
454 "Invalid connection: connection forms a cycle:\n %s\n",
455 conn->arg->str);
456 ret = -1;
457 goto end;
458 }
459 }
460
9009cc24 461 g_ptr_array_add(path, conn->downstream_comp_name->str);
db0f160a
PP
462 ret = validate_no_cycles_rec(cfg, path, error_buf,
463 error_buf_size);
464 if (ret) {
465 goto end;
466 }
467
468 g_ptr_array_remove_index(path, path->len - 1);
469 }
470 }
471
472end:
473 return ret;
474}
475
476static int validate_no_cycles(struct bt_config *cfg, char *error_buf,
ebba3338
PP
477 size_t error_buf_size)
478{
479 size_t i;
480 int ret = 0;
db0f160a 481 GPtrArray *path;
ebba3338 482
db0f160a
PP
483 path = g_ptr_array_new();
484 if (!path) {
485 ret = -1;
486 goto end;
487 }
ebba3338 488
db0f160a
PP
489 g_ptr_array_add(path, NULL);
490
491 for (i = 0; i < cfg->cmd_data.run.connections->len; i++) {
492 struct bt_config_connection *conn =
493 g_ptr_array_index(cfg->cmd_data.run.connections, i);
494
9009cc24 495 g_ptr_array_index(path, 0) = conn->upstream_comp_name->str;
db0f160a
PP
496 ret = validate_no_cycles_rec(cfg, path,
497 error_buf, error_buf_size);
498 if (ret) {
ebba3338
PP
499 goto end;
500 }
501 }
502
503end:
db0f160a
PP
504 if (path) {
505 g_ptr_array_free(path, TRUE);
506 }
507
ebba3338
PP
508 return ret;
509}
510
511static int validate_all_components_connected_in_array(GPtrArray *comps,
b19ff26f 512 const bt_value *connected_components,
ebba3338
PP
513 char *error_buf, size_t error_buf_size)
514{
515 int ret = 0;
516 size_t i;
517
518 for (i = 0; i < comps->len; i++) {
519 struct bt_config_component *comp = g_ptr_array_index(comps, i);
520
07208d85 521 if (!bt_value_map_has_entry(connected_components,
ebba3338
PP
522 comp->instance_name->str)) {
523 snprintf(error_buf, error_buf_size,
524 "Component `%s` is not connected\n",
525 comp->instance_name->str);
526 ret = -1;
527 goto end;
528 }
529 }
530
531end:
532 return ret;
533}
534
535static int validate_all_components_connected(struct bt_config *cfg,
536 char *error_buf, size_t error_buf_size)
537{
538 size_t i;
539 int ret = 0;
b19ff26f 540 bt_value *connected_components = bt_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
05e21286 551 ret = bt_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
05e21286 557 ret = bt_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,
05e21286 566 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,
05e21286 574 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,
05e21286 582 connected_components,
ebba3338
PP
583 error_buf, error_buf_size);
584 if (ret) {
585 goto end;
586 }
587
588end:
c5b9b441 589 bt_value_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;
b19ff26f 598 bt_value *flat_connection_names =
05e21286 599 bt_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
05e21286
PP
623 if (bt_value_map_has_entry(flat_connection_names,
624 flat_connection_name->str)) {
ebba3338
PP
625 snprintf(error_buf, error_buf_size,
626 "Duplicate connection:\n %s\n",
627 connection->arg->str);
628 ret = -1;
629 goto end;
630 }
631
05e21286 632 ret = bt_value_map_insert_entry(flat_connection_names,
ebba3338
PP
633 flat_connection_name->str, bt_value_null);
634 if (ret) {
635 goto end;
636 }
637 }
638
639end:
c5b9b441 640 bt_value_put_ref(flat_connection_names);
ebba3338
PP
641
642 if (flat_connection_name) {
643 g_string_free(flat_connection_name, TRUE);
644 }
645
646 return ret;
647}
648
649static int validate_connections(struct bt_config *cfg, char *error_buf,
650 size_t error_buf_size)
651{
652 int ret;
653
654 ret = validate_all_endpoints_exist(cfg, error_buf, error_buf_size);
655 if (ret) {
656 goto end;
657 }
658
659 ret = validate_connection_directions(cfg, error_buf, error_buf_size);
660 if (ret) {
661 goto end;
662 }
663
ebba3338
PP
664 ret = validate_all_components_connected(cfg, error_buf, error_buf_size);
665 if (ret) {
666 goto end;
667 }
668
669 ret = validate_no_duplicate_connection(cfg, error_buf, error_buf_size);
670 if (ret) {
671 goto end;
672 }
673
db0f160a 674 ret = validate_no_cycles(cfg, error_buf, error_buf_size);
ebba3338
PP
675 if (ret) {
676 goto end;
677 }
678
ebba3338 679end:
ebba3338
PP
680 return ret;
681}
682
9009cc24 683int bt_config_cli_args_create_connections(struct bt_config *cfg,
b19ff26f 684 const bt_value *connection_args,
ebba3338
PP
685 char *error_buf, size_t error_buf_size)
686{
687 int ret;
688 size_t i;
689
db0f160a
PP
690 if (!all_named_and_printable(cfg)) {
691 snprintf(error_buf, error_buf_size,
692 "One or more components are unnamed (use --name) or contain a non-printable character\n");
ebba3338
PP
693 goto error;
694 }
695
07208d85 696 for (i = 0; i < bt_value_array_get_size(connection_args); i++) {
b19ff26f 697 const bt_value *arg_value =
05e21286 698 bt_value_array_borrow_element_by_index_const(
07208d85 699 connection_args, i);
ebba3338
PP
700 const char *arg;
701 struct bt_config_connection *cfg_connection;
702
601b0d3c 703 arg = bt_value_string_get(arg_value);
ebba3338
PP
704 cfg_connection = cfg_connection_from_arg(arg);
705 if (!cfg_connection) {
706 snprintf(error_buf, error_buf_size, "Cannot parse --connect option's argument:\n %s\n",
707 arg);
708 goto error;
709 }
710
db0f160a 711 g_ptr_array_add(cfg->cmd_data.run.connections,
ebba3338
PP
712 cfg_connection);
713 }
714
715
716 ret = validate_connections(cfg, error_buf, error_buf_size);
717 if (ret) {
718 goto error;
719 }
720
721 goto end;
722
723error:
724 ret = -1;
725
726end:
727 return ret;
728}
This page took 0.069468 seconds and 4 git commands to generate.