22 #include "./arguments_impl.h"
23 #include "./remap_impl.h"
24 #include "rcl/error_handling.h"
27 #include "rcl_yaml_param_parser/parser.h"
28 #include "rcl_yaml_param_parser/types.h"
29 #include "rcutils/allocator.h"
30 #include "rcutils/error_handling.h"
31 #include "rcutils/format_string.h"
32 #include "rcutils/logging.h"
33 #include "rcutils/logging_macros.h"
34 #include "rcutils/strdup.h"
48 _rcl_parse_remap_rule(
65 _rcl_parse_param_rule(
67 rcl_params_t * params);
73 char *** parameter_files)
79 *(parameter_files) = allocator.allocate(
81 if (NULL == *parameter_files) {
86 if (NULL == (*parameter_files)[i]) {
88 for (
int r = i; r >= 0; --r) {
89 allocator.deallocate((*parameter_files)[r], allocator.state);
91 allocator.deallocate((*parameter_files), allocator.state);
92 (*parameter_files) = NULL;
103 if (NULL == args || NULL == args->
impl) {
112 rcl_params_t ** parameter_overrides)
118 if (NULL != *parameter_overrides) {
119 RCL_SET_ERROR_MSG(
"Output parameter override pointer is not null. May leak memory.");
122 *parameter_overrides = NULL;
125 if (NULL == *parameter_overrides) {
157 _rcl_parse_log_level(
172 _rcl_parse_external_log_file_name(
175 char ** log_file_name_prefix);
188 _rcl_parse_external_log_config_file(
191 char ** log_config_file);
206 _rcl_parse_param_file(
209 rcl_params_t * params,
228 #define RCL_ENABLE_FLAG_PREFIX "--enable-"
229 #define RCL_DISABLE_FLAG_PREFIX "--disable-"
241 _rcl_parse_disabling_flag(
259 const char *
const * argv,
265 RCL_SET_ERROR_MSG(
"Argument count cannot be negative");
267 }
else if (argc > 0) {
272 if (args_output->
impl != NULL) {
273 RCL_SET_ERROR_MSG(
"Parse output is not zero-initialized");
280 ret = _rcl_allocate_initialized_arguments_impl(args_output, &allocator);
304 args_impl->
parameter_files = allocator.allocate(
sizeof(
char *) * argc, allocator.state);
309 args_impl->
unparsed_ros_args = allocator.allocate(
sizeof(
int) * argc, allocator.state);
314 args_impl->
unparsed_args = allocator.allocate(
sizeof(
int) * argc, allocator.state);
326 bool parsing_ros_args =
false;
327 for (
int i = 0; i < argc; ++i) {
328 if (parsing_ros_args) {
336 parsing_ros_args =
false;
345 RCUTILS_LOG_DEBUG_NAMED(
346 ROS_PACKAGE_NAME,
"Got param override rule : %s\n", argv[i + 1]);
350 rcl_error_string_t prev_error_string = rcl_get_error_string();
352 RCL_SET_ERROR_MSG_WITH_FORMAT_STRING(
353 "Couldn't parse parameter override rule: '%s %s'. Error: %s", argv[i], argv[i + 1],
354 prev_error_string.str);
356 RCL_SET_ERROR_MSG_WITH_FORMAT_STRING(
357 "Couldn't parse trailing %s flag. No parameter override rule found.", argv[i]);
362 RCUTILS_LOG_DEBUG_NAMED(
363 ROS_PACKAGE_NAME,
"Arg %d (%s) is not a %s nor a %s flag.",
372 if (
RCL_RET_OK == _rcl_parse_remap_rule(argv[i + 1], allocator, rule)) {
374 RCUTILS_LOG_DEBUG_NAMED(ROS_PACKAGE_NAME,
"Got remap rule : %s\n", argv[i + 1]);
378 rcl_error_string_t prev_error_string = rcl_get_error_string();
380 RCL_SET_ERROR_MSG_WITH_FORMAT_STRING(
381 "Couldn't parse remap rule: '%s %s'. Error: %s", argv[i], argv[i + 1],
382 prev_error_string.str);
384 RCL_SET_ERROR_MSG_WITH_FORMAT_STRING(
385 "Couldn't parse trailing %s flag. No remap rule found.", argv[i]);
390 RCUTILS_LOG_DEBUG_NAMED(
391 ROS_PACKAGE_NAME,
"Arg %d (%s) is not a %s nor a %s flag.",
405 RCUTILS_LOG_DEBUG_NAMED(
407 "Got params file : %s\ntotal num param files %d",
413 rcl_error_string_t prev_error_string = rcl_get_error_string();
415 RCL_SET_ERROR_MSG_WITH_FORMAT_STRING(
416 "Couldn't parse params file: '%s %s'. Error: %s", argv[i], argv[i + 1],
417 prev_error_string.str);
419 RCL_SET_ERROR_MSG_WITH_FORMAT_STRING(
420 "Couldn't parse trailing %s flag. No file path provided.", argv[i]);
425 RCUTILS_LOG_DEBUG_NAMED(
426 ROS_PACKAGE_NAME,
"Arg %d (%s) is not a %s flag.",
433 _rcl_parse_log_level(argv[i + 1], &args_impl->
log_levels))
435 RCUTILS_LOG_DEBUG_NAMED(ROS_PACKAGE_NAME,
"Got log level: %s\n", argv[i + 1]);
439 rcl_error_string_t prev_error_string = rcl_get_error_string();
441 RCL_SET_ERROR_MSG_WITH_FORMAT_STRING(
442 "Couldn't parse log level: '%s %s'. Error: %s", argv[i], argv[i + 1],
443 prev_error_string.str);
445 RCL_SET_ERROR_MSG_WITH_FORMAT_STRING(
446 "Couldn't parse trailing log level flag: '%s'. No log level provided.", argv[i]);
451 RCUTILS_LOG_DEBUG_NAMED(
452 ROS_PACKAGE_NAME,
"Arg %d (%s) is not a %s flag.",
459 RCUTILS_LOG_DEBUG_NAMED(
460 ROS_PACKAGE_NAME,
"Overriding log file name : %s\n",
465 if (
RCL_RET_OK == _rcl_parse_external_log_file_name(
468 RCUTILS_LOG_DEBUG_NAMED(
469 ROS_PACKAGE_NAME,
"Got log file name prefix : %s\n",
474 rcl_error_string_t prev_error_string = rcl_get_error_string();
476 RCL_SET_ERROR_MSG_WITH_FORMAT_STRING(
477 "Couldn't parse log file name prefix: '%s %s'. Error: %s", argv[i], argv[i + 1],
478 prev_error_string.str);
480 RCL_SET_ERROR_MSG_WITH_FORMAT_STRING(
481 "Couldn't parse trailing %s flag. No string prefix provided.", argv[i]);
486 RCUTILS_LOG_DEBUG_NAMED(
487 ROS_PACKAGE_NAME,
"Arg %d (%s) is not a %s flag.",
494 RCUTILS_LOG_DEBUG_NAMED(
495 ROS_PACKAGE_NAME,
"Overriding log configuration file : %s\n",
500 if (
RCL_RET_OK == _rcl_parse_external_log_config_file(
503 RCUTILS_LOG_DEBUG_NAMED(
504 ROS_PACKAGE_NAME,
"Got log configuration file : %s\n",
509 rcl_error_string_t prev_error_string = rcl_get_error_string();
511 RCL_SET_ERROR_MSG_WITH_FORMAT_STRING(
512 "Couldn't parse log configuration file: '%s %s'. Error: %s", argv[i], argv[i + 1],
513 prev_error_string.str);
515 RCL_SET_ERROR_MSG_WITH_FORMAT_STRING(
516 "Couldn't parse trailing %s flag. No file path provided.", argv[i]);
521 RCUTILS_LOG_DEBUG_NAMED(
522 ROS_PACKAGE_NAME,
"Arg %d (%s) is not a %s flag.",
528 if (NULL != args_impl->
enclave) {
529 RCUTILS_LOG_DEBUG_NAMED(
530 ROS_PACKAGE_NAME,
"Overriding security enclave : %s\n",
532 allocator.deallocate(args_impl->
enclave, allocator.state);
536 argv[i + 1], allocator, &args_impl->
enclave))
538 RCUTILS_LOG_DEBUG_NAMED(
539 ROS_PACKAGE_NAME,
"Got enclave: %s\n",
544 rcl_error_string_t prev_error_string = rcl_get_error_string();
546 RCL_SET_ERROR_MSG_WITH_FORMAT_STRING(
547 "Couldn't parse enclave name: '%s %s'. Error: %s", argv[i], argv[i + 1],
548 prev_error_string.str);
550 RCL_SET_ERROR_MSG_WITH_FORMAT_STRING(
551 "Couldn't parse trailing %s flag. No enclave path provided.", argv[i]);
556 RCUTILS_LOG_DEBUG_NAMED(
557 ROS_PACKAGE_NAME,
"Arg %d (%s) is not a %s flag.",
561 ret = _rcl_parse_disabling_flag(
564 RCUTILS_LOG_DEBUG_NAMED(
565 ROS_PACKAGE_NAME,
"Disable log stdout ? %s\n",
569 RCUTILS_LOG_DEBUG_NAMED(
571 "Couldn't parse arg %d (%s) as %s%s or %s%s flag. Error: %s",
577 ret = _rcl_parse_disabling_flag(
580 RCUTILS_LOG_DEBUG_NAMED(
581 ROS_PACKAGE_NAME,
"Disable log rosout ? %s\n",
585 RCUTILS_LOG_DEBUG_NAMED(
587 "Couldn't parse arg %d (%s) as %s%s or %s%s flag. Error: %s",
593 ret = _rcl_parse_disabling_flag(
596 RCUTILS_LOG_DEBUG_NAMED(
597 ROS_PACKAGE_NAME,
"Disable log external lib ? %s\n",
601 RCUTILS_LOG_DEBUG_NAMED(
603 "Couldn't parse arg %d (%s) as %s%s or %s%s flag. Error: %s",
614 parsing_ros_args =
true;
621 if (
RCL_RET_OK == _rcl_parse_remap_rule(argv[i], allocator, rule)) {
622 RCUTILS_LOG_WARN_NAMED(
624 "Found remap rule '%s'. This syntax is deprecated. Use '%s %s %s' instead.",
626 RCUTILS_LOG_DEBUG_NAMED(ROS_PACKAGE_NAME,
"Got remap rule : %s\n", argv[i + 1]);
630 RCUTILS_LOG_DEBUG_NAMED(
632 "Couldn't parse arg %d (%s) as a remap rule in its deprecated form. Error: %s",
633 i, argv[i], rcl_get_error_string().str);
645 allocator.deallocate(args_impl->
remap_rules, allocator.state);
648 rcl_remap_t * new_remap_rules = allocator.reallocate(
652 if (NULL == new_remap_rules) {
664 char ** new_parameter_files = allocator.reallocate(
668 if (NULL == new_parameter_files) {
698 allocator.deallocate(args_impl->
unparsed_args, allocator.state);
718 if (NULL != args_impl) {
721 RCUTILS_LOG_ERROR_NAMED(ROS_PACKAGE_NAME,
"Failed to fini arguments after earlier failure");
731 if (NULL == args || NULL == args->
impl) {
741 int ** output_unparsed_indices)
748 *output_unparsed_indices = NULL;
750 *output_unparsed_indices = allocator.allocate(
752 if (NULL == *output_unparsed_indices) {
766 if (NULL == args || NULL == args->
impl) {
776 int ** output_unparsed_ros_indices)
783 *output_unparsed_ros_indices = NULL;
785 *output_unparsed_ros_indices = allocator.allocate(
787 if (NULL == *output_unparsed_ros_indices) {
803 return default_arguments;
808 const char *
const * argv,
812 const char *** nonros_argv)
818 if (NULL != *nonros_argv) {
819 RCL_SET_ERROR_MSG(
"Output nonros_argv pointer is not null. May leak memory.");
824 if (*nonros_argc < 0) {
825 RCL_SET_ERROR_MSG(
"Failed to get unparsed non ROS specific arguments count.");
827 }
else if (*nonros_argc > 0) {
832 if (0 == *nonros_argc) {
836 int * unparsed_indices = NULL;
843 size_t alloc_size =
sizeof(
char *) * *nonros_argc;
844 *nonros_argv = allocator.allocate(alloc_size, allocator.state);
845 if (NULL == *nonros_argv) {
846 allocator.deallocate(unparsed_indices, allocator.state);
849 for (
int i = 0; i < *nonros_argc; ++i) {
850 (*nonros_argv)[i] = argv[unparsed_indices[i]];
853 allocator.deallocate(unparsed_indices, allocator.state);
868 if (NULL != args_out->
impl) {
869 RCL_SET_ERROR_MSG(
"args_out must be zero initialized");
875 rcl_ret_t ret = _rcl_allocate_initialized_arguments_impl(args_out, &allocator);
886 RCL_SET_ERROR_MSG(
"Error while finalizing arguments due to another error");
902 RCL_SET_ERROR_MSG(
"Error while finalizing arguments due to another error");
918 RCL_SET_ERROR_MSG(
"Error while finalizing arguments due to another error");
928 RCL_SET_ERROR_MSG(
"Error while finalizing arguments due to another error");
948 RCL_SET_ERROR_MSG(
"Error while finalizing arguments due to another error");
957 RCL_SET_ERROR_MSG(
"Error while finalizing arguments due to another error");
964 char * enclave_copy = rcutils_strdup(args->
impl->
enclave, allocator);
967 RCL_SET_ERROR_MSG(
"Error while finalizing arguments due to another error");
969 RCL_SET_ERROR_MSG(
"Error while copying enclave argument");
989 RCUTILS_LOG_ERROR_NAMED(
991 "Failed to finalize remap rule while finalizing arguments. Continuing...");
1001 ret = log_levels_ret;
1002 RCUTILS_LOG_ERROR_NAMED(
1004 "Failed to finalize log levels while finalizing arguments. Continuing...");
1047 RCL_SET_ERROR_MSG(
"rcl_arguments_t finalized twice");
1057 _rcl_parse_remap_fully_qualified_namespace(
1063 assert(NULL != lex_lookahead);
1099 assert(NULL != lex_lookahead);
1111 RCL_SET_ERROR_MSG(
"Backreferences are not implemented");
1128 _rcl_parse_remap_replacement_name(
1136 assert(NULL != lex_lookahead);
1137 assert(NULL != rule);
1140 if (NULL == replacement_start) {
1141 RCL_SET_ERROR_MSG(
"failed to get start of replacement");
1158 ret = _rcl_parse_remap_replacement_token(lex_lookahead);
1171 ret = _rcl_parse_remap_replacement_token(lex_lookahead);
1183 size_t length = (size_t)(replacement_end - replacement_start);
1187 RCL_SET_ERROR_MSG(
"failed to copy replacement");
1206 assert(NULL != lex_lookahead);
1216 RCL_SET_ERROR_MSG(
"Wildcard '*' is not implemented");
1219 RCL_SET_ERROR_MSG(
"Wildcard '**' is not implemented");
1222 RCL_SET_ERROR_MSG(
"Expecting token or wildcard");
1235 _rcl_parse_resource_match(
1238 char ** resource_match)
1244 assert(NULL != lex_lookahead);
1245 assert(rcutils_allocator_is_valid(&allocator));
1246 assert(NULL != resource_match);
1247 assert(NULL == *resource_match);
1250 if (NULL == match_start) {
1251 RCL_SET_ERROR_MSG(
"failed to get start of match");
1268 ret = _rcl_parse_resource_match_token(lex_lookahead);
1281 ret = _rcl_parse_resource_match_token(lex_lookahead);
1293 const size_t length = (size_t)(match_end - match_start);
1294 *resource_match = rcutils_strndup(match_start, length, allocator);
1295 if (NULL == *resource_match) {
1296 RCL_SET_ERROR_MSG(
"failed to copy match");
1311 assert(NULL != lex_lookahead);
1319 RCL_SET_ERROR_MSG(
"Wildcard '*' is not implemented");
1322 RCL_SET_ERROR_MSG(
"Wildcard '**' is not implemented");
1325 RCL_SET_ERROR_MSG(
"Expecting token or wildcard");
1350 _rcl_parse_param_name(
1359 assert(NULL != lex_lookahead);
1360 assert(rcutils_allocator_is_valid(&allocator));
1361 assert(NULL != param_name);
1362 assert(NULL == *param_name);
1365 if (NULL == name_start) {
1366 RCL_SET_ERROR_MSG(
"failed to get start of param name");
1371 ret = _rcl_parse_param_name_token(lex_lookahead);
1384 ret = _rcl_parse_param_name_token(lex_lookahead);
1396 const size_t length = (size_t)(name_end - name_start);
1397 *param_name = rcutils_strndup(name_start, length, allocator);
1398 if (NULL == *param_name) {
1399 RCL_SET_ERROR_MSG(
"failed to copy param name");
1413 _rcl_parse_remap_match_name(
1421 assert(NULL != lex_lookahead);
1422 assert(NULL != rule);
1430 rule->
impl->
type = RCL_SERVICE_REMAP;
1433 rule->
impl->
type = RCL_TOPIC_REMAP;
1436 rule->
impl->
type = (RCL_TOPIC_REMAP | RCL_SERVICE_REMAP);
1442 ret = _rcl_parse_resource_match(
1456 _rcl_parse_remap_name_remap(
1463 assert(NULL != lex_lookahead);
1464 assert(NULL != rule);
1467 ret = _rcl_parse_remap_match_name(lex_lookahead, rule);
1477 ret = _rcl_parse_remap_replacement_name(lex_lookahead, rule);
1491 _rcl_parse_remap_namespace_replacement(
1498 assert(NULL != lex_lookahead);
1499 assert(NULL != rule);
1513 if (NULL == ns_start) {
1514 RCL_SET_ERROR_MSG(
"failed to get start of namespace");
1517 ret = _rcl_parse_remap_fully_qualified_namespace(lex_lookahead);
1521 RCUTILS_LOG_WARN_NAMED(
1522 ROS_PACKAGE_NAME,
"Namespace not remapped to a fully qualified name (found: %s)", ns_start);
1530 RCUTILS_LOG_WARN_NAMED(
1531 ROS_PACKAGE_NAME,
"Namespace not remapped to a fully qualified name (found: %s)", ns_start);
1537 size_t length = (size_t)(ns_end - ns_start);
1540 RCL_SET_ERROR_MSG(
"failed to copy namespace");
1544 rule->
impl->
type = RCL_NAMESPACE_REMAP;
1554 _rcl_parse_remap_nodename_replacement(
1559 const char * node_name;
1563 assert(NULL != lex_lookahead);
1564 assert(NULL != rule);
1580 RCUTILS_LOG_WARN_NAMED(
1581 ROS_PACKAGE_NAME,
"Node name not remapped to invalid name: '%s'", node_name);
1590 RCL_SET_ERROR_MSG(
"failed to allocate node name");
1594 rule->
impl->
type = RCL_NODENAME_REMAP;
1601 _rcl_parse_nodename_prefix(
1607 const char * token = NULL;
1610 assert(NULL != lex_lookahead);
1611 assert(rcutils_allocator_is_valid(&allocator));
1612 assert(NULL != node_name);
1613 assert(NULL == *node_name);
1627 *node_name = rcutils_strndup(token, length, allocator);
1628 if (NULL == *node_name) {
1629 RCL_SET_ERROR_MSG(
"failed to allocate node name");
1643 _rcl_parse_remap_nodename_prefix(
1648 assert(NULL != lex_lookahead);
1649 assert(NULL != rule);
1651 rcl_ret_t ret = _rcl_parse_nodename_prefix(
1670 _rcl_parse_remap_begin_remap_rule(
1679 assert(NULL != lex_lookahead);
1680 assert(NULL != rule);
1688 ret = _rcl_parse_remap_nodename_prefix(lex_lookahead, rule);
1701 ret = _rcl_parse_remap_nodename_replacement(lex_lookahead, rule);
1706 ret = _rcl_parse_remap_namespace_replacement(lex_lookahead, rule);
1711 ret = _rcl_parse_remap_name_remap(lex_lookahead, rule);
1727 _rcl_parse_log_level_name(
1730 char ** logger_name)
1735 assert(NULL != lex_lookahead);
1736 assert(rcutils_allocator_is_valid(allocator));
1737 assert(NULL != logger_name);
1738 assert(NULL == *logger_name);
1741 if (NULL == name_start) {
1742 RCL_SET_ERROR_MSG(
"failed to get start of logger name");
1770 const size_t length = (size_t)(name_end - name_start);
1771 *logger_name = rcutils_strndup(name_start, length, *allocator);
1772 if (NULL == *logger_name) {
1773 RCL_SET_ERROR_MSG(
"failed to copy logger name");
1781 _rcl_parse_log_level(
1792 char * logger_name = NULL;
1794 rcutils_ret_t rcutils_ret = RCUTILS_RET_OK;
1803 ret = _rcl_parse_log_level_name(&lex_lookahead, allocator, &logger_name);
1805 if (strlen(logger_name) == 0) {
1806 RCL_SET_ERROR_MSG(
"Argument has an invalid logger item that name is empty");
1817 const char * level_token;
1818 size_t level_token_length;
1832 rcutils_ret = rcutils_logging_severity_level_from_string(
1833 level_token, *allocator, &level);
1834 if (RCUTILS_RET_OK == rcutils_ret) {
1842 rcutils_ret = rcutils_logging_severity_level_from_string(
1843 arg, *allocator, &level);
1844 if (RCUTILS_RET_OK == rcutils_ret) {
1847 RCUTILS_LOG_DEBUG_NAMED(
1848 ROS_PACKAGE_NAME,
"Minimum default log level will be replaced from %d to %d",
1857 if (RCUTILS_RET_OK != rcutils_ret) {
1858 RCL_SET_ERROR_MSG(
"Argument does not use a valid severity level");
1864 allocator->deallocate(logger_name, allocator->state);
1869 RCUTILS_LOG_ERROR_NAMED(ROS_PACKAGE_NAME,
"Failed to fini lookahead2 after error occurred");
1879 _rcl_parse_remap_rule(
1889 if (NULL == output_rule->
impl) {
1893 output_rule->
impl->
type = RCL_UNKNOWN_REMAP;
1902 ret = _rcl_parse_remap_begin_remap_rule(&lex_lookahead, output_rule);
1907 RCUTILS_LOG_ERROR_NAMED(
1908 ROS_PACKAGE_NAME,
"Failed to fini lookahead2 after error occurred");
1920 RCUTILS_LOG_ERROR_NAMED(
1921 ROS_PACKAGE_NAME,
"Failed to fini remap rule after error occurred");
1928 _rcl_parse_param_rule(
1930 rcl_params_t * params)
1944 char * node_name = NULL;
1945 char * param_name = NULL;
1954 ret = _rcl_parse_nodename_prefix(&lex_lookahead, params->allocator, &node_name);
1962 node_name = rcutils_strdup(
"/**", params->allocator);
1963 if (NULL == node_name) {
1971 ret = _rcl_parse_param_name(&lex_lookahead, params->allocator, ¶m_name);
1986 if (!rcl_parse_yaml_value(node_name, param_name, yaml_value, params)) {
1992 params->allocator.deallocate(param_name, params->allocator.state);
1993 params->allocator.deallocate(node_name, params->allocator.state);
1996 RCUTILS_LOG_ERROR_NAMED(ROS_PACKAGE_NAME,
"Failed to fini lookahead2 after error occurred");
2005 _rcl_parse_param_file(
2008 rcl_params_t * params,
2014 *param_file = rcutils_strdup(arg, allocator);
2015 if (NULL == *param_file) {
2016 RCL_SET_ERROR_MSG(
"Failed to allocate memory for parameters file path");
2019 if (!rcl_parse_yaml_file(*param_file, params)) {
2020 allocator.deallocate(*param_file, allocator.state);
2029 _rcl_parse_external_log_file_name(
2032 char ** log_file_name_prefix)
2037 *log_file_name_prefix = rcutils_strdup(arg, allocator);
2038 if (NULL == *log_file_name_prefix) {
2039 RCL_SET_ERROR_MSG(
"Failed to allocate memory for external log file name prefix");
2046 _rcl_parse_external_log_config_file(
2049 char ** log_config_file)
2054 *log_config_file = rcutils_strdup(arg, allocator);
2056 if (NULL == *log_config_file) {
2057 RCL_SET_ERROR_MSG(
"Failed to allocate memory for external log config file");
2072 *enclave = rcutils_strdup(arg, allocator);
2073 if (NULL == *enclave) {
2074 RCL_SET_ERROR_MSG(
"Failed to allocate memory for enclave name");
2081 _rcl_parse_disabling_flag(
2083 const char * suffix,
2090 const size_t enable_prefix_len = strlen(RCL_ENABLE_FLAG_PREFIX);
2092 strncmp(RCL_ENABLE_FLAG_PREFIX, arg, enable_prefix_len) == 0 &&
2093 strcmp(suffix, arg + enable_prefix_len) == 0)
2099 const size_t disable_prefix_len = strlen(RCL_DISABLE_FLAG_PREFIX);
2101 strncmp(RCL_DISABLE_FLAG_PREFIX, arg, disable_prefix_len) == 0 &&
2102 strcmp(suffix, arg + disable_prefix_len) == 0)
2108 RCL_SET_ERROR_MSG_WITH_FORMAT_STRING(
2109 "Argument is not a %s%s nor a %s%s flag.",
2110 RCL_ENABLE_FLAG_PREFIX, suffix,
2111 RCL_DISABLE_FLAG_PREFIX, suffix);
2119 if (NULL == args->
impl) {
#define RCL_CHECK_ALLOCATOR_WITH_MSG(allocator, msg, fail_statement)
Check that the given allocator is initialized, or fail with a message.
rcutils_allocator_t rcl_allocator_t
Encapsulation of an allocator.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_arguments_get_unparsed_ros(const rcl_arguments_t *args, rcl_allocator_t allocator, int **output_unparsed_ros_indices)
Return a list of indices to unknown ROS specific arguments that were left unparsed.
#define RCL_ROS_ARGS_EXPLICIT_END_TOKEN
The token that delineates the explicit end of ROS arguments.
RCL_PUBLIC RCL_WARN_UNUSED int rcl_arguments_get_count_unparsed(const rcl_arguments_t *args)
Return the number of arguments that were not ROS specific arguments.
#define RCL_LOG_LEVEL_FLAG
The ROS flag that precedes the ROS logging level to set.
#define RCL_LOG_ROSOUT_FLAG_SUFFIX
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_arguments_get_param_files(const rcl_arguments_t *arguments, rcl_allocator_t allocator, char ***parameter_files)
Return a list of yaml parameter file paths specified on the command line.
#define RCL_EXTERNAL_LOG_FILE_NAME_PREFIX
The ROS log file name prefix to configure external logging.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_arguments_copy(const rcl_arguments_t *args, rcl_arguments_t *args_out)
Copy one arguments structure into another.
#define RCL_PARAM_FLAG
The ROS flag that precedes the setting of a ROS parameter.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_arguments_get_param_overrides(const rcl_arguments_t *arguments, rcl_params_t **parameter_overrides)
Return all parameter overrides parsed from the command line.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_arguments_get_log_levels(const rcl_arguments_t *arguments, rcl_log_levels_t *log_levels)
Return log levels parsed from the command line.
#define RCL_ROS_ARGS_FLAG
The command-line flag that delineates the start of ROS arguments.
#define RCL_LOG_EXT_LIB_FLAG_SUFFIX
#define RCL_SHORT_PARAM_FLAG
The short version of the ROS flag that precedes the setting of a ROS parameter.
#define RCL_ENCLAVE_FLAG
The ROS flag that precedes the name of a ROS security enclave.
#define RCL_LOG_STDOUT_FLAG_SUFFIX
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_parse_arguments(int argc, const char *const *argv, rcl_allocator_t allocator, rcl_arguments_t *args_output)
Parse command line arguments into a structure usable by code.
#define RCL_REMAP_FLAG
The ROS flag that precedes a ROS remapping rule.
#define RCL_EXTERNAL_LOG_CONFIG_FLAG
The ROS flag that precedes the name of a configuration file to configure logging.
#define RCL_SHORT_REMAP_FLAG
The short version of the ROS flag that precedes a ROS remapping rule.
#define RCL_SHORT_ENCLAVE_FLAG
The short version of the ROS flag that precedes the name of a ROS security enclave.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_arguments_fini(rcl_arguments_t *args)
Reclaim resources held inside rcl_arguments_t structure.
RCL_PUBLIC RCL_WARN_UNUSED int rcl_arguments_get_param_files_count(const rcl_arguments_t *args)
Return the number of parameter yaml files given in the arguments.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_arguments_get_unparsed(const rcl_arguments_t *args, rcl_allocator_t allocator, int **output_unparsed_indices)
Return a list of indices to non ROS specific arguments.
RCL_PUBLIC RCL_WARN_UNUSED int rcl_arguments_get_count_unparsed_ros(const rcl_arguments_t *args)
Return the number of ROS specific arguments that were not successfully parsed.
#define RCL_PARAM_FILE_FLAG
The ROS flag that precedes a path to a file containing ROS parameters.
RCL_PUBLIC RCL_WARN_UNUSED rcl_arguments_t rcl_get_zero_initialized_arguments(void)
Return a rcl_arguments_t struct with members initialized to NULL.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_remove_ros_arguments(const char *const *argv, const rcl_arguments_t *args, rcl_allocator_t allocator, int *nonros_argc, const char ***nonros_argv)
Return a list of arguments with ROS-specific arguments removed.
@ RCL_LEXEME_TOKEN
a name between slashes, must match (([a-zA-Z](_)?)|_)([0-9a-zA-Z](_)?)*
@ RCL_LEXEME_EOF
Indicates end of input has been reached.
@ RCL_LEXEME_URL_TOPIC
rostopic://
@ RCL_LEXEME_URL_SERVICE
rosservice://
@ RCL_LEXEME_TILDE_SLASH
~/
@ RCL_LEXEME_FORWARD_SLASH
/
@ RCL_LEXEME_NODE
__node or __name
@ RCL_LEXEME_WILD_MULTI
**
enum rcl_lexeme_e rcl_lexeme_t
Type of lexeme found by lexical analysis.
RCL_PUBLIC RCL_WARN_UNUSED rcl_lexer_lookahead2_t rcl_get_zero_initialized_lexer_lookahead2(void)
Get a zero initialized rcl_lexer_lookahead2_t instance.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_lexer_lookahead2_fini(rcl_lexer_lookahead2_t *buffer)
Finalize an instance of an rcl_lexer_lookahead2_t structure.
RCL_PUBLIC RCL_WARN_UNUSED const char * rcl_lexer_lookahead2_get_text(const rcl_lexer_lookahead2_t *buffer)
Get the text at the point where it is currently being analyzed.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_lexer_lookahead2_peek2(rcl_lexer_lookahead2_t *buffer, rcl_lexeme_t *next_type1, rcl_lexeme_t *next_type2)
Look ahead at the next two lexemes in the string.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_lexer_lookahead2_accept(rcl_lexer_lookahead2_t *buffer, const char **lexeme_text, size_t *lexeme_text_length)
Accept a lexeme and advance analysis.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_lexer_lookahead2_expect(rcl_lexer_lookahead2_t *buffer, rcl_lexeme_t type, const char **lexeme_text, size_t *lexeme_text_length)
Require the next lexeme to be a certain type and advance analysis.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_lexer_lookahead2_peek(rcl_lexer_lookahead2_t *buffer, rcl_lexeme_t *next_type)
Look ahead at the next lexeme in the string.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_lexer_lookahead2_init(rcl_lexer_lookahead2_t *buffer, const char *text, rcl_allocator_t allocator)
Initialize an rcl_lexer_lookahead2_t instance.
RCL_PUBLIC rcl_ret_t rcl_log_levels_fini(rcl_log_levels_t *log_levels)
Reclaim resources held inside rcl_log_levels_t structure.
enum RCUTILS_LOG_SEVERITY rcl_log_severity_t
typedef for RCUTILS_LOG_SEVERITY;
RCL_PUBLIC rcl_ret_t rcl_log_levels_add_logger_setting(rcl_log_levels_t *log_levels, const char *logger_name, rcl_log_severity_t log_level)
Add logger setting with a name and a level.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_log_levels_init(rcl_log_levels_t *log_levels, const rcl_allocator_t *allocator, size_t logger_count)
Initialize a log levels structure.
RCL_PUBLIC rcl_ret_t rcl_log_levels_shrink_to_size(rcl_log_levels_t *log_levels)
Shrink log levels structure.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_log_levels_copy(const rcl_log_levels_t *src, rcl_log_levels_t *dst)
Copy one log levels structure into another.
RCL_PUBLIC RCL_WARN_UNUSED rcl_log_levels_t rcl_get_zero_initialized_log_levels(void)
Return a rcl_log_levels_t struct with members initialized to zero value.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_remap_fini(rcl_remap_t *remap)
Reclaim resources held inside rcl_remap_t structure.
RCL_PUBLIC RCL_WARN_UNUSED rcl_remap_t rcl_get_zero_initialized_remap(void)
Return a rcl_remap_t struct with members initialized to NULL.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_remap_copy(const rcl_remap_t *rule, rcl_remap_t *rule_out)
Copy one remap structure into another.
char * external_log_config_file
A file used to configure the external logging library.
rcl_log_levels_t log_levels
Log levels parsed from arguments.
rcl_params_t * parameter_overrides
Parameter override rules parsed from arguments.
int num_unparsed_args
Length of unparsed_args.
int num_param_files_args
Length of parameter_files.
bool log_rosout_disabled
A boolean value indicating if the rosout topic handler should be used for log output.
bool log_stdout_disabled
A boolean value indicating if the standard out handler should be used for log output.
rcl_allocator_t allocator
Allocator used to allocate objects in this struct.
int * unparsed_args
Array of indices to non-ROS arguments.
int * unparsed_ros_args
Array of indices to unknown ROS specific arguments.
char * enclave
Enclave to be used.
bool log_ext_lib_disabled
A boolean value indicating if the external lib handler should be used for log output.
rcl_remap_t * remap_rules
Array of rules for name remapping.
int num_remap_rules
Length of remap_rules.
int num_unparsed_ros_args
Length of unparsed_ros_args.
char * external_log_file_name_prefix
A prefix used to external log file name.
char ** parameter_files
Array of yaml parameter file paths.
Hold output of parsing command line arguments.
rcl_arguments_impl_t * impl
Private implementation pointer.
Track lexical analysis and allow looking ahead 2 lexemes.
Hold default logger level and other logger setting.
rcl_allocator_t allocator
Allocator used to allocate objects in this struct.
rcl_logger_setting_t * logger_settings
Array of logger setting.
rcl_log_severity_t default_logger_level
Minimum default logger level severity.
char * replacement
Replacement portion of a rule.
char * node_name
A node name that this rule is limited to, or NULL if it applies to any node.
rcl_allocator_t allocator
Allocator used to allocate objects in this struct.
char * match
Match portion of a rule, or NULL if node name or namespace replacement.
rcl_remap_type_t type
Bitmask indicating what type of rule this is.
rcl_remap_impl_t * impl
Private implementation pointer.
#define RCL_RET_INVALID_LOG_LEVEL_RULE
Argument is not a valid log level rule.
#define RCL_RET_INVALID_PARAM_RULE
Argument is not a valid parameter rule.
#define RCL_RET_WRONG_LEXEME
Expected one type of lexeme but got another.
#define RCL_RET_INVALID_ROS_ARGS
Found invalid ros argument while parsing.
#define RCL_RET_INVALID_REMAP_RULE
Argument is not a valid remap rule.
#define RCL_RET_OK
Success return code.
#define RCL_RET_BAD_ALLOC
Failed to allocate memory return code.
#define RCL_RET_INVALID_ARGUMENT
Invalid argument return code.
#define RCL_RET_ERROR
Unspecified error return code.
rmw_ret_t rcl_ret_t
The type that holds an rcl return code.