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) {
802 return zero_arguments;
807 const char *
const * argv,
811 const char *** nonros_argv)
817 if (NULL != *nonros_argv) {
818 RCL_SET_ERROR_MSG(
"Output nonros_argv pointer is not null. May leak memory.");
823 if (*nonros_argc < 0) {
824 RCL_SET_ERROR_MSG(
"Failed to get unparsed non ROS specific arguments count.");
826 }
else if (*nonros_argc > 0) {
831 if (0 == *nonros_argc) {
835 int * unparsed_indices = NULL;
842 size_t alloc_size =
sizeof(
char *) * *nonros_argc;
843 *nonros_argv = allocator.allocate(alloc_size, allocator.state);
844 if (NULL == *nonros_argv) {
845 allocator.deallocate(unparsed_indices, allocator.state);
848 for (
int i = 0; i < *nonros_argc; ++i) {
849 (*nonros_argv)[i] = argv[unparsed_indices[i]];
852 allocator.deallocate(unparsed_indices, allocator.state);
867 if (NULL != args_out->
impl) {
868 RCL_SET_ERROR_MSG(
"args_out must be zero initialized");
874 rcl_ret_t ret = _rcl_allocate_initialized_arguments_impl(args_out, &allocator);
885 RCL_SET_ERROR_MSG(
"Error while finalizing arguments due to another error");
901 RCL_SET_ERROR_MSG(
"Error while finalizing arguments due to another error");
917 RCL_SET_ERROR_MSG(
"Error while finalizing arguments due to another error");
927 RCL_SET_ERROR_MSG(
"Error while finalizing arguments due to another error");
947 RCL_SET_ERROR_MSG(
"Error while finalizing arguments due to another error");
956 RCL_SET_ERROR_MSG(
"Error while finalizing arguments due to another error");
963 char * enclave_copy = rcutils_strdup(args->
impl->
enclave, allocator);
966 RCL_SET_ERROR_MSG(
"Error while finalizing arguments due to another error");
968 RCL_SET_ERROR_MSG(
"Error while copying enclave argument");
988 RCUTILS_LOG_ERROR_NAMED(
990 "Failed to finalize remap rule while finalizing arguments. Continuing...");
1000 ret = log_levels_ret;
1001 RCUTILS_LOG_ERROR_NAMED(
1003 "Failed to finalize log levels while finalizing arguments. Continuing...");
1046 RCL_SET_ERROR_MSG(
"rcl_arguments_t finalized twice");
1056 _rcl_parse_remap_fully_qualified_namespace(
1062 assert(NULL != lex_lookahead);
1098 assert(NULL != lex_lookahead);
1110 RCL_SET_ERROR_MSG(
"Backreferences are not implemented");
1127 _rcl_parse_remap_replacement_name(
1135 assert(NULL != lex_lookahead);
1136 assert(NULL != rule);
1139 if (NULL == replacement_start) {
1140 RCL_SET_ERROR_MSG(
"failed to get start of replacement");
1157 ret = _rcl_parse_remap_replacement_token(lex_lookahead);
1170 ret = _rcl_parse_remap_replacement_token(lex_lookahead);
1182 size_t length = (size_t)(replacement_end - replacement_start);
1186 RCL_SET_ERROR_MSG(
"failed to copy replacement");
1205 assert(NULL != lex_lookahead);
1215 RCL_SET_ERROR_MSG(
"Wildcard '*' is not implemented");
1218 RCL_SET_ERROR_MSG(
"Wildcard '**' is not implemented");
1221 RCL_SET_ERROR_MSG(
"Expecting token or wildcard");
1234 _rcl_parse_resource_match(
1237 char ** resource_match)
1243 assert(NULL != lex_lookahead);
1244 assert(rcutils_allocator_is_valid(&allocator));
1245 assert(NULL != resource_match);
1246 assert(NULL == *resource_match);
1249 if (NULL == match_start) {
1250 RCL_SET_ERROR_MSG(
"failed to get start of match");
1267 ret = _rcl_parse_resource_match_token(lex_lookahead);
1283 ret = _rcl_parse_resource_match_token(lex_lookahead);
1295 const size_t length = (size_t)(match_end - match_start);
1296 *resource_match = rcutils_strndup(match_start, length, allocator);
1297 if (NULL == *resource_match) {
1298 RCL_SET_ERROR_MSG(
"failed to copy match");
1313 assert(NULL != lex_lookahead);
1321 RCL_SET_ERROR_MSG(
"Wildcard '*' is not implemented");
1324 RCL_SET_ERROR_MSG(
"Wildcard '**' is not implemented");
1327 RCL_SET_ERROR_MSG(
"Expecting token or wildcard");
1352 _rcl_parse_param_name(
1361 assert(NULL != lex_lookahead);
1362 assert(rcutils_allocator_is_valid(&allocator));
1363 assert(NULL != param_name);
1364 assert(NULL == *param_name);
1367 if (NULL == name_start) {
1368 RCL_SET_ERROR_MSG(
"failed to get start of param name");
1373 ret = _rcl_parse_param_name_token(lex_lookahead);
1386 ret = _rcl_parse_param_name_token(lex_lookahead);
1398 const size_t length = (size_t)(name_end - name_start);
1399 *param_name = rcutils_strndup(name_start, length, allocator);
1400 if (NULL == *param_name) {
1401 RCL_SET_ERROR_MSG(
"failed to copy param name");
1415 _rcl_parse_remap_match_name(
1423 assert(NULL != lex_lookahead);
1424 assert(NULL != rule);
1432 rule->
impl->
type = RCL_SERVICE_REMAP;
1435 rule->
impl->
type = RCL_TOPIC_REMAP;
1438 rule->
impl->
type = (RCL_TOPIC_REMAP | RCL_SERVICE_REMAP);
1444 ret = _rcl_parse_resource_match(
1458 _rcl_parse_remap_name_remap(
1465 assert(NULL != lex_lookahead);
1466 assert(NULL != rule);
1469 ret = _rcl_parse_remap_match_name(lex_lookahead, rule);
1479 ret = _rcl_parse_remap_replacement_name(lex_lookahead, rule);
1493 _rcl_parse_remap_namespace_replacement(
1500 assert(NULL != lex_lookahead);
1501 assert(NULL != rule);
1515 if (NULL == ns_start) {
1516 RCL_SET_ERROR_MSG(
"failed to get start of namespace");
1519 ret = _rcl_parse_remap_fully_qualified_namespace(lex_lookahead);
1523 RCUTILS_LOG_WARN_NAMED(
1524 ROS_PACKAGE_NAME,
"Namespace not remapped to a fully qualified name (found: %s)", ns_start);
1532 RCUTILS_LOG_WARN_NAMED(
1533 ROS_PACKAGE_NAME,
"Namespace not remapped to a fully qualified name (found: %s)", ns_start);
1539 size_t length = (size_t)(ns_end - ns_start);
1542 RCL_SET_ERROR_MSG(
"failed to copy namespace");
1546 rule->
impl->
type = RCL_NAMESPACE_REMAP;
1556 _rcl_parse_remap_nodename_replacement(
1561 const char * node_name;
1565 assert(NULL != lex_lookahead);
1566 assert(NULL != rule);
1582 RCUTILS_LOG_WARN_NAMED(
1583 ROS_PACKAGE_NAME,
"Node name not remapped to invalid name: '%s'", node_name);
1592 RCL_SET_ERROR_MSG(
"failed to allocate node name");
1596 rule->
impl->
type = RCL_NODENAME_REMAP;
1603 _rcl_parse_nodename_prefix(
1609 const char * token = NULL;
1612 assert(NULL != lex_lookahead);
1613 assert(rcutils_allocator_is_valid(&allocator));
1614 assert(NULL != node_name);
1615 assert(NULL == *node_name);
1629 *node_name = rcutils_strndup(token, length, allocator);
1630 if (NULL == *node_name) {
1631 RCL_SET_ERROR_MSG(
"failed to allocate node name");
1645 _rcl_parse_remap_nodename_prefix(
1650 assert(NULL != lex_lookahead);
1651 assert(NULL != rule);
1653 rcl_ret_t ret = _rcl_parse_nodename_prefix(
1672 _rcl_parse_remap_begin_remap_rule(
1681 assert(NULL != lex_lookahead);
1682 assert(NULL != rule);
1690 ret = _rcl_parse_remap_nodename_prefix(lex_lookahead, rule);
1703 ret = _rcl_parse_remap_nodename_replacement(lex_lookahead, rule);
1708 ret = _rcl_parse_remap_namespace_replacement(lex_lookahead, rule);
1713 ret = _rcl_parse_remap_name_remap(lex_lookahead, rule);
1729 _rcl_parse_log_level_name(
1732 char ** logger_name)
1737 assert(NULL != lex_lookahead);
1738 assert(rcutils_allocator_is_valid(allocator));
1739 assert(NULL != logger_name);
1740 assert(NULL == *logger_name);
1743 if (NULL == name_start) {
1744 RCL_SET_ERROR_MSG(
"failed to get start of logger name");
1772 const size_t length = (size_t)(name_end - name_start);
1773 *logger_name = rcutils_strndup(name_start, length, *allocator);
1774 if (NULL == *logger_name) {
1775 RCL_SET_ERROR_MSG(
"failed to copy logger name");
1783 _rcl_parse_log_level(
1794 char * logger_name = NULL;
1796 rcutils_ret_t rcutils_ret = RCUTILS_RET_OK;
1805 ret = _rcl_parse_log_level_name(&lex_lookahead, allocator, &logger_name);
1807 if (strlen(logger_name) == 0) {
1808 RCL_SET_ERROR_MSG(
"Argument has an invalid logger item that name is empty");
1819 const char * level_token;
1820 size_t level_token_length;
1834 rcutils_ret = rcutils_logging_severity_level_from_string(
1835 level_token, *allocator, &level);
1836 if (RCUTILS_RET_OK == rcutils_ret) {
1844 rcutils_ret = rcutils_logging_severity_level_from_string(
1845 arg, *allocator, &level);
1846 if (RCUTILS_RET_OK == rcutils_ret) {
1849 RCUTILS_LOG_DEBUG_NAMED(
1850 ROS_PACKAGE_NAME,
"Minimum default log level will be replaced from %d to %d",
1859 if (RCUTILS_RET_OK != rcutils_ret) {
1860 RCL_SET_ERROR_MSG(
"Argument does not use a valid severity level");
1866 allocator->deallocate(logger_name, allocator->state);
1871 RCUTILS_LOG_ERROR_NAMED(ROS_PACKAGE_NAME,
"Failed to fini lookahead2 after error occurred");
1881 _rcl_parse_remap_rule(
1891 if (NULL == output_rule->
impl) {
1895 output_rule->
impl->
type = RCL_UNKNOWN_REMAP;
1904 ret = _rcl_parse_remap_begin_remap_rule(&lex_lookahead, output_rule);
1909 RCUTILS_LOG_ERROR_NAMED(
1910 ROS_PACKAGE_NAME,
"Failed to fini lookahead2 after error occurred");
1922 RCUTILS_LOG_ERROR_NAMED(
1923 ROS_PACKAGE_NAME,
"Failed to fini remap rule after error occurred");
1930 _rcl_parse_param_rule(
1932 rcl_params_t * params)
1946 char * node_name = NULL;
1947 char * param_name = NULL;
1956 ret = _rcl_parse_nodename_prefix(&lex_lookahead, params->allocator, &node_name);
1964 node_name = rcutils_strdup(
"/**", params->allocator);
1965 if (NULL == node_name) {
1973 ret = _rcl_parse_param_name(&lex_lookahead, params->allocator, ¶m_name);
1988 if (!rcl_parse_yaml_value(node_name, param_name, yaml_value, params)) {
1994 params->allocator.deallocate(param_name, params->allocator.state);
1995 params->allocator.deallocate(node_name, params->allocator.state);
1998 RCUTILS_LOG_ERROR_NAMED(ROS_PACKAGE_NAME,
"Failed to fini lookahead2 after error occurred");
2007 _rcl_parse_param_file(
2010 rcl_params_t * params,
2016 *param_file = rcutils_strdup(arg, allocator);
2017 if (NULL == *param_file) {
2018 RCL_SET_ERROR_MSG(
"Failed to allocate memory for parameters file path");
2021 if (!rcl_parse_yaml_file(*param_file, params)) {
2022 allocator.deallocate(*param_file, allocator.state);
2031 _rcl_parse_external_log_file_name(
2034 char ** log_file_name_prefix)
2039 *log_file_name_prefix = rcutils_strdup(arg, allocator);
2040 if (NULL == *log_file_name_prefix) {
2041 RCL_SET_ERROR_MSG(
"Failed to allocate memory for external log file name prefix");
2048 _rcl_parse_external_log_config_file(
2051 char ** log_config_file)
2056 *log_config_file = rcutils_strdup(arg, allocator);
2058 if (NULL == *log_config_file) {
2059 RCL_SET_ERROR_MSG(
"Failed to allocate memory for external log config file");
2074 *enclave = rcutils_strdup(arg, allocator);
2075 if (NULL == *enclave) {
2076 RCL_SET_ERROR_MSG(
"Failed to allocate memory for enclave name");
2083 _rcl_parse_disabling_flag(
2085 const char * suffix,
2092 const size_t enable_prefix_len = strlen(RCL_ENABLE_FLAG_PREFIX);
2094 strncmp(RCL_ENABLE_FLAG_PREFIX, arg, enable_prefix_len) == 0 &&
2095 strcmp(suffix, arg + enable_prefix_len) == 0)
2101 const size_t disable_prefix_len = strlen(RCL_DISABLE_FLAG_PREFIX);
2103 strncmp(RCL_DISABLE_FLAG_PREFIX, arg, disable_prefix_len) == 0 &&
2104 strcmp(suffix, arg + disable_prefix_len) == 0)
2110 RCL_SET_ERROR_MSG_WITH_FORMAT_STRING(
2111 "Argument is not a %s%s nor a %s%s flag.",
2112 RCL_ENABLE_FLAG_PREFIX, suffix,
2113 RCL_DISABLE_FLAG_PREFIX, suffix);
2121 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.