From 0ddc17a042111779ab204a4d92ff582459f3035b Mon Sep 17 00:00:00 2001 From: Michel Hidalgo Date: Fri, 13 Sep 2019 10:20:02 -0700 Subject: [PATCH] Bring back deprecated CLI arguments (#496) * Bring back deprecated CLI arguments. Signed-off-by: Michel Hidalgo * Remove extra vertical space. Signed-off-by: Michel Hidalgo --- rcl/include/rcl/arguments.h | 7 + rcl/include/rcl/types.h | 2 +- rcl/src/rcl/arguments.c | 330 +++++++++++++++++++++++++++++++- rcl/test/rcl/test_arguments.cpp | 117 ++++++++++- 4 files changed, 453 insertions(+), 3 deletions(-) diff --git a/rcl/include/rcl/arguments.h b/rcl/include/rcl/arguments.h index c88072633..80cee984d 100644 --- a/rcl/include/rcl/arguments.h +++ b/rcl/include/rcl/arguments.h @@ -49,6 +49,13 @@ typedef struct rcl_arguments_t #define RCL_LOG_ROSOUT_FLAG_SUFFIX "rosout-logs" #define RCL_LOG_EXT_LIB_FLAG_SUFFIX "external-lib-logs" +// \deprecated to be removed in F-Turtle +#define RCL_LOG_LEVEL_ARG_RULE "__log_level:=" +#define RCL_EXTERNAL_LOG_CONFIG_ARG_RULE "__log_config_file:=" +#define RCL_LOG_DISABLE_STDOUT_ARG_RULE "__log_disable_stdout:=" +#define RCL_LOG_DISABLE_ROSOUT_ARG_RULE "__log_disable_rosout:=" +#define RCL_LOG_DISABLE_EXT_LIB_ARG_RULE "__log_disable_external_lib:=" +#define RCL_PARAM_FILE_ARG_RULE "__params:=" /// Return a rcl_arguments_t struct with members initialized to `NULL`. RCL_PUBLIC diff --git a/rcl/include/rcl/types.h b/rcl/include/rcl/types.h index b552a0c2a..86f988823 100644 --- a/rcl/include/rcl/types.h +++ b/rcl/include/rcl/types.h @@ -101,7 +101,7 @@ typedef rmw_ret_t rcl_ret_t; /// Argument is not a valid parameter rule #define RCL_RET_INVALID_PARAM_RULE 1010 /// Argument is not a valid log level rule -#define RCL_RET_INVALID_LOG_LEVEL 1020 +#define RCL_RET_INVALID_LOG_LEVEL_RULE 1020 // rcl event specific ret codes in 20XX /// Invalid rcl_event_t given return code. diff --git a/rcl/src/rcl/arguments.c b/rcl/src/rcl/arguments.c index bc716e681..d25620fdd 100644 --- a/rcl/src/rcl/arguments.c +++ b/rcl/src/rcl/arguments.c @@ -152,6 +152,24 @@ _rcl_parse_log_level( rcl_allocator_t allocator, int * log_level); +/// Parse an argument that may or may not be a log level rule. +/** + * \param[in] arg the argument to parse + * \param[in] allocator an allocator to use + * \param[in,out] log_level parsed log level represented by `RCUTILS_LOG_SEVERITY` enum + * \return RCL_RET_OK if a valid log level was parsed, or + * \return RCL_RET_INVALID_LOG_LEVEL_RULE if the argument is not a valid rule, or + * \return RCL_RET_BAD_ALLOC if an allocation failed, or + * \return RLC_RET_ERROR if an unspecified error occurred. + * \deprecated to be removed in F-Turtle + */ +RCL_LOCAL +rcl_ret_t +_rcl_parse_log_level_rule( + const char * arg, + rcl_allocator_t allocator, + int * log_level); + /// Parse an argument that may or may not be a log configuration file. /** * \param[in] arg the argument to parse @@ -168,6 +186,23 @@ _rcl_parse_external_log_config_file( rcl_allocator_t allocator, char ** log_config_file); +/// Parse an argument that may or may not be a log file rule. +/** + * \param[in] arg the argument to parse + * \param[in] allocator an allocator to use + * \param[in,out] log_config_file parsed log configuration file + * \return RCL_RET_OK if a valid log config file was parsed, or + * \return RCL_RET_BAD_ALLOC if an allocation failed, or + * \return RLC_RET_ERROR if an unspecified error occurred. + * \deprecated to be removed in F-Turtle + */ +RCL_LOCAL +rcl_ret_t +_rcl_parse_external_log_config_file_rule( + const char * arg, + rcl_allocator_t allocator, + char ** log_config_file); + /// Parse an argument that may or may not be a parameter file. /** * The syntax of the file name is not validated. @@ -185,6 +220,25 @@ _rcl_parse_param_file( rcl_allocator_t allocator, char ** param_file); +/// Parse an argument that may or may not be a parameter file rule. +/** + * The syntax of the file name is not validated. + * \param[in] arg the argument to parse + * \param[in] allocator an allocator to use + * \param[in,out] param_file string that could be a parameter file name + * \return RCL_RET_OK if the rule was parsed correctly, or + * \return RCL_RET_INVALID_PARAM_RULE if the argument is not a valid rule, or + * \return RCL_RET_BAD_ALLOC if an allocation failed, or + * \return RLC_RET_ERROR if an unspecified error occurred. + * \deprecated to be removed in F-Turtle + */ +RCL_LOCAL +rcl_ret_t +_rcl_parse_param_file_rule( + const char * arg, + rcl_allocator_t allocator, + char ** param_file); + #define RCL_ENABLE_FLAG_PREFIX "--enable-" #define RCL_DISABLE_FLAG_PREFIX "--disable-" @@ -203,6 +257,42 @@ _rcl_parse_disabling_flag( const char * key, bool * value); +/// Parse a bool argument that may or may not be for the provided key rule. +/** + * \param[in] arg the argument to parse + * \param[in] key the key for the argument to parse. Should be a null terminated string + * \param[in,out] value parsed boolean value + * \return RCL_RET_OK if the bool argument was parsed successfully, or + * \return RLC_RET_ERROR if an unspecified error occurred. + * \deprecated to be removed in F-Turtle + */ +RCL_LOCAL +rcl_ret_t +_rcl_parse_bool_arg( + const char * arg, + const char * key, + bool * value); + +/// Parse a null terminated string to a boolean value. +/** + * The case sensitive values: "T", "t", "True", "true", "Y", "y", "Yes", "yes", + * and "1" will all map to true. + * The case sensitive values: "F", "f", "False", "false", "N", "n", "No", "no", + * and "0" will all map to false. + * + * \param[in] str a null terminated string to be parsed into a boolean + * \param[in,out] val the boolean value parsed from the string. + * Left unchanged if string cannot be parsed to a valid bool. + * \return RCL_RET_OK if a valid boolean parsed, or + * \return RLC_RET_ERROR if an unspecified error occurred. + * \deprecated to be removed in F-Turtle + */ +RCL_LOCAL +rcl_ret_t +_atob( + const char * str, + bool * val); + rcl_ret_t rcl_parse_arguments( int argc, @@ -496,6 +586,130 @@ rcl_parse_arguments( continue; } + // Attempt to parse argument as remap rule in its deprecated form + rcl_remap_t * rule = &(args_impl->remap_rules[args_impl->num_remap_rules]); + *rule = rcl_get_zero_initialized_remap(); + if (RCL_RET_OK == _rcl_parse_remap_rule(argv[i], allocator, rule)) { + RCUTILS_LOG_WARN_NAMED(ROS_PACKAGE_NAME, + "Found remap rule '%s'. This syntax is deprecated. Use '%s %s %s' instead.", + argv[i], RCL_ROS_ARGS_FLAG, RCL_REMAP_FLAG, argv[i]); + RCUTILS_LOG_DEBUG_NAMED(ROS_PACKAGE_NAME, "Got remap rule : %s\n", argv[i + 1]); + ++(args_impl->num_remap_rules); + continue; + } + RCUTILS_LOG_DEBUG_NAMED(ROS_PACKAGE_NAME, + "Couldn't parse arg %d (%s) as a remap rule in its deprecated form. Error: %s", + i, argv[i], rcl_get_error_string().str); + rcl_reset_error(); + + // Attempt to parse argument as parameter file rule + args_impl->parameter_files[args_impl->num_param_files_args] = NULL; + if ( + RCL_RET_OK == _rcl_parse_param_file_rule( + argv[i], allocator, &(args_impl->parameter_files[args_impl->num_param_files_args]))) + { + ++(args_impl->num_param_files_args); + RCUTILS_LOG_WARN_NAMED(ROS_PACKAGE_NAME, + "Found parameter file rule '%s'. This syntax is deprecated. Use '%s %s %s' instead.", + argv[i], RCL_ROS_ARGS_FLAG, RCL_PARAM_FILE_FLAG, + args_impl->parameter_files[args_impl->num_param_files_args - 1]); + RCUTILS_LOG_DEBUG_NAMED(ROS_PACKAGE_NAME, + "params rule : %s\n total num param rules %d", + args_impl->parameter_files[args_impl->num_param_files_args - 1], + args_impl->num_param_files_args); + continue; + } + RCUTILS_LOG_DEBUG_NAMED(ROS_PACKAGE_NAME, + "Couldn't parse arg %d (%s) as a deprecated parameter file rule. Error: %s", + i, argv[i], rcl_get_error_string().str); + rcl_reset_error(); + + // Attempt to parse argument as log level configuration + int log_level; + if (RCL_RET_OK == _rcl_parse_log_level_rule(argv[i], allocator, &log_level)) { + RCUTILS_LOG_WARN_NAMED(ROS_PACKAGE_NAME, + "Found log level rule '%s'. This syntax is deprecated. Use '%s %s %s' instead.", + argv[i], RCL_ROS_ARGS_FLAG, RCL_LOG_LEVEL_FLAG, g_rcutils_log_severity_names[log_level]); + args_impl->log_level = log_level; + continue; + } + RCUTILS_LOG_DEBUG_NAMED(ROS_PACKAGE_NAME, + "Couldn't parse arg %d (%s) as a deprecated log level rule. Error: %s", + i, argv[i], rcl_get_error_string().str); + rcl_reset_error(); + + // Attempt to parse argument as log configuration file rule + rcl_ret_t ret = _rcl_parse_external_log_config_file_rule( + argv[i], allocator, &args_impl->external_log_config_file); + if (RCL_RET_OK == ret) { + RCUTILS_LOG_WARN_NAMED(ROS_PACKAGE_NAME, + "Found log config rule '%s'. This syntax is deprecated. Use '%s %s %s' instead.", + argv[i], RCL_ROS_ARGS_FLAG, RCL_EXTERNAL_LOG_CONFIG_FLAG, + args_impl->external_log_config_file); + RCUTILS_LOG_DEBUG_NAMED(ROS_PACKAGE_NAME, + "Got log configuration file : %s\n", + args_impl->external_log_config_file); + continue; + } + RCUTILS_LOG_DEBUG_NAMED(ROS_PACKAGE_NAME, + "Couldn't parse arg %d (%s) as a deprecated log config rule. Error: %s", + i, argv[i], rcl_get_error_string().str); + rcl_reset_error(); + + // Attempt to parse argument as log_stdout_disabled + ret = _rcl_parse_bool_arg( + argv[i], RCL_LOG_DISABLE_STDOUT_ARG_RULE, &args_impl->log_stdout_disabled); + if (RCL_RET_OK == ret) { + const char * flag_prefix = + args_impl->log_stdout_disabled ? RCL_DISABLE_FLAG_PREFIX : RCL_ENABLE_FLAG_PREFIX; + RCUTILS_LOG_WARN_NAMED(ROS_PACKAGE_NAME, + "Found '%s'. This syntax is deprecated. Use '%s %s%s' instead.", + argv[i], RCL_ROS_ARGS_FLAG, flag_prefix, RCL_LOG_STDOUT_FLAG_SUFFIX); + RCUTILS_LOG_DEBUG_NAMED(ROS_PACKAGE_NAME, + "Disable log stdout ? %s\n", args_impl->log_stdout_disabled ? "true" : "false"); + continue; + } + RCUTILS_LOG_DEBUG_NAMED(ROS_PACKAGE_NAME, + "Couldn't parse arg %d (%s) as a deprecated log_stdout_disabled rule. Error: %s", + i, argv[i], rcl_get_error_string().str); + rcl_reset_error(); + + // Attempt to parse argument as log_rosout_disabled + ret = _rcl_parse_bool_arg( + argv[i], RCL_LOG_DISABLE_ROSOUT_ARG_RULE, &args_impl->log_rosout_disabled); + if (RCL_RET_OK == ret) { + const char * flag_prefix = + args_impl->log_rosout_disabled ? RCL_DISABLE_FLAG_PREFIX : RCL_ENABLE_FLAG_PREFIX; + RCUTILS_LOG_WARN_NAMED(ROS_PACKAGE_NAME, + "Found '%s'. This syntax is deprecated. Use '%s %s%s' instead.", + argv[i], RCL_ROS_ARGS_FLAG, flag_prefix, RCL_LOG_ROSOUT_FLAG_SUFFIX); + RCUTILS_LOG_DEBUG_NAMED(ROS_PACKAGE_NAME, + "Disable log rosout ? %s\n", args_impl->log_rosout_disabled ? "true" : "false"); + continue; + } + RCUTILS_LOG_DEBUG_NAMED(ROS_PACKAGE_NAME, + "Couldn't parse arg %d (%s) as a deprecated log_rosout_disabled rule. Error: %s", + i, argv[i], rcl_get_error_string().str); + rcl_reset_error(); + + // Attempt to parse argument as log_ext_lib_disabled + ret = _rcl_parse_bool_arg( + argv[i], RCL_LOG_DISABLE_EXT_LIB_ARG_RULE, &args_impl->log_ext_lib_disabled); + if (RCL_RET_OK == ret) { + const char * flag_prefix = + args_impl->log_ext_lib_disabled ? RCL_DISABLE_FLAG_PREFIX : RCL_ENABLE_FLAG_PREFIX; + RCUTILS_LOG_WARN_NAMED(ROS_PACKAGE_NAME, + "Found '%s'. This syntax is deprecated. Use '%s %s%s' instead.", + argv[i], RCL_ROS_ARGS_FLAG, flag_prefix, RCL_LOG_EXT_LIB_FLAG_SUFFIX); + RCUTILS_LOG_DEBUG_NAMED(ROS_PACKAGE_NAME, + "Disable log external lib ? %s\n", args_impl->log_ext_lib_disabled ? "true" : "false"); + continue; + } + RCUTILS_LOG_DEBUG_NAMED(ROS_PACKAGE_NAME, + "Couldn't parse arg %d (%s) as a deprecated log_ext_lib_disabled rule. Error: %s", + i, argv[i], rcl_get_error_string().str); + rcl_reset_error(); + // Argument is not a ROS specific argument args_impl->unparsed_args[args_impl->num_unparsed_args] = i; ++(args_impl->num_unparsed_args); @@ -1448,9 +1662,32 @@ _rcl_parse_log_level( return RCL_RET_OK; } RCL_SET_ERROR_MSG("Argument does not use a valid severity level"); - return RCL_RET_INVALID_LOG_LEVEL; + return RCL_RET_ERROR; +} + +rcl_ret_t +_rcl_parse_log_level_rule( + const char * arg, + rcl_allocator_t allocator, + int * log_level) +{ + RCL_CHECK_ARGUMENT_FOR_NULL(arg, RCL_RET_INVALID_ARGUMENT); + RCL_CHECK_ARGUMENT_FOR_NULL(log_level, RCL_RET_INVALID_ARGUMENT); + + if (strncmp(RCL_LOG_LEVEL_ARG_RULE, arg, strlen(RCL_LOG_LEVEL_ARG_RULE)) != 0) { + RCL_SET_ERROR_MSG("Argument does not start with '" RCL_LOG_LEVEL_ARG_RULE "'"); + return RCL_RET_INVALID_LOG_LEVEL_RULE; + } + rcutils_ret_t ret = rcutils_logging_severity_level_from_string( + arg + strlen(RCL_LOG_LEVEL_ARG_RULE), allocator, log_level); + if (RCUTILS_RET_OK == ret) { + return RCL_RET_OK; + } + RCL_SET_ERROR_MSG("Argument does not use a valid severity level"); + return RCL_RET_INVALID_LOG_LEVEL_RULE; } + rcl_ret_t _rcl_parse_remap_rule( const char * arg, @@ -1587,6 +1824,29 @@ _rcl_parse_param_file( return RCL_RET_OK; } +rcl_ret_t +_rcl_parse_param_file_rule( + const char * arg, + rcl_allocator_t allocator, + char ** param_file) +{ + RCL_CHECK_ARGUMENT_FOR_NULL(arg, RCL_RET_INVALID_ARGUMENT); + + const size_t param_prefix_len = strlen(RCL_PARAM_FILE_ARG_RULE); + if (strncmp(RCL_PARAM_FILE_ARG_RULE, arg, param_prefix_len) == 0) { + size_t outlen = strlen(arg) - param_prefix_len; + *param_file = allocator.allocate(sizeof(char) * (outlen + 1), allocator.state); + if (NULL == *param_file) { + RCL_SET_ERROR_MSG("Failed to allocate memory for parameters file path"); + return RCL_RET_BAD_ALLOC; + } + snprintf(*param_file, outlen + 1, "%s", arg + param_prefix_len); + return RCL_RET_OK; + } + RCL_SET_ERROR_MSG("Argument does not start with '" RCL_PARAM_FILE_ARG_RULE "'"); + return RCL_RET_INVALID_PARAM_RULE; +} + rcl_ret_t _rcl_parse_external_log_config_file( const char * arg, @@ -1605,6 +1865,30 @@ _rcl_parse_external_log_config_file( return RCL_RET_OK; } +rcl_ret_t +_rcl_parse_external_log_config_file_rule( + const char * arg, + rcl_allocator_t allocator, + char ** log_config_file) +{ + RCL_CHECK_ARGUMENT_FOR_NULL(arg, RCL_RET_INVALID_ARGUMENT); + RCL_CHECK_ARGUMENT_FOR_NULL(log_config_file, RCL_RET_INVALID_ARGUMENT); + + const size_t param_prefix_len = sizeof(RCL_EXTERNAL_LOG_CONFIG_ARG_RULE) - 1; + if (strncmp(RCL_EXTERNAL_LOG_CONFIG_ARG_RULE, arg, param_prefix_len) == 0) { + size_t outlen = strlen(arg) - param_prefix_len; + *log_config_file = rcutils_format_string_limit(allocator, outlen, "%s", arg + param_prefix_len); + if (NULL == *log_config_file) { + RCL_SET_ERROR_MSG("Failed to allocate memory for external log config file"); + return RCL_RET_BAD_ALLOC; + } + return RCL_RET_OK; + } + + RCL_SET_ERROR_MSG("Argument does not start with '" RCL_EXTERNAL_LOG_CONFIG_ARG_RULE "'"); + return RCL_RET_INVALID_PARAM_RULE; +} + rcl_ret_t _rcl_parse_disabling_flag( const char * arg, @@ -1640,6 +1924,50 @@ _rcl_parse_disabling_flag( return RCL_RET_ERROR; } +rcl_ret_t +_rcl_parse_bool_arg( + const char * arg, + const char * key, + bool * value) +{ + RCL_CHECK_ARGUMENT_FOR_NULL(arg, RCL_RET_INVALID_ARGUMENT); + RCL_CHECK_ARGUMENT_FOR_NULL(key, RCL_RET_INVALID_ARGUMENT); + + const size_t param_prefix_len = strlen(key); + if (strncmp(key, arg, param_prefix_len) == 0) { + return _atob(arg + param_prefix_len, value); + } + + RCL_SET_ERROR_MSG("Argument does not start with key"); + return RCL_RET_INVALID_PARAM_RULE; +} + +rcl_ret_t +_atob( + const char * str, + bool * val) +{ + RCL_CHECK_ARGUMENT_FOR_NULL(str, RCL_RET_INVALID_ARGUMENT); + RCL_CHECK_ARGUMENT_FOR_NULL(val, RCL_RET_INVALID_ARGUMENT); + const char * true_values[] = {"y", "Y", "yes", "Yes", "t", "T", "true", "True", "1"}; + const char * false_values[] = {"n", "N", "no", "No", "f", "F", "false", "False", "0"}; + + for (size_t idx = 0; idx < sizeof(true_values) / sizeof(char *); idx++) { + if (0 == strncmp(true_values[idx], str, strlen(true_values[idx]))) { + *val = true; + return RCL_RET_OK; + } + } + + for (size_t idx = 0; idx < sizeof(false_values) / sizeof(char *); idx++) { + if (0 == strncmp(false_values[idx], str, strlen(false_values[idx]))) { + *val = false; + return RCL_RET_OK; + } + } + return RCL_RET_ERROR; +} + #ifdef __cplusplus } #endif diff --git a/rcl/test/rcl/test_arguments.cpp b/rcl/test/rcl/test_arguments.cpp index 6fbf59d27..6cd5b7881 100644 --- a/rcl/test/rcl/test_arguments.cpp +++ b/rcl/test/rcl/test_arguments.cpp @@ -181,6 +181,53 @@ TEST_F(CLASSNAME(TestArgumentsFixture, RMW_IMPLEMENTATION), check_known_vs_unkno EXPECT_FALSE(are_known_ros_args({"--ros-args", "external-lib-logs"})); } +// \deprecated to be removed in F-Turtle +TEST_F(CLASSNAME(TestArgumentsFixture, RMW_IMPLEMENTATION), check_known_deprecated_args) { + EXPECT_TRUE(are_known_ros_args({"__node:=node_name"})); + EXPECT_TRUE(are_known_ros_args({"old_name:__node:=node_name"})); + EXPECT_TRUE(are_known_ros_args({"old_name:__node:=nodename123"})); + EXPECT_TRUE(are_known_ros_args({"__node:=nodename123"})); + EXPECT_TRUE(are_known_ros_args({"__ns:=/foo/bar"})); + EXPECT_TRUE(are_known_ros_args({"__ns:=/"})); + EXPECT_TRUE(are_known_ros_args({"_:=kq"})); + EXPECT_TRUE(are_known_ros_args({"nodename:__ns:=/foobar"})); + EXPECT_TRUE(are_known_ros_args({"foo:=bar"})); + EXPECT_TRUE(are_known_ros_args({"~/foo:=~/bar"})); + EXPECT_TRUE(are_known_ros_args({"/foo/bar:=bar"})); + EXPECT_TRUE(are_known_ros_args({"foo:=/bar"})); + EXPECT_TRUE(are_known_ros_args({"/foo123:=/bar123"})); + EXPECT_TRUE(are_known_ros_args({"node:/foo123:=/bar123"})); + EXPECT_TRUE(are_known_ros_args({"rostopic:=/foo/bar"})); + EXPECT_TRUE(are_known_ros_args({"rosservice:=baz"})); + EXPECT_TRUE(are_known_ros_args({"rostopic://rostopic:=rosservice"})); + EXPECT_TRUE(are_known_ros_args({"rostopic:///rosservice:=rostopic"})); + EXPECT_TRUE(are_known_ros_args({"rostopic:///foo/bar:=baz"})); + + // Setting params file + EXPECT_TRUE(are_known_ros_args({"__params:=file_name.yaml"})); + + // Setting config logging file + EXPECT_TRUE(are_known_ros_args({"__log_config_file:=file.config"})); + + // Setting logger level + EXPECT_TRUE(are_known_ros_args({"__log_level:=UNSET"})); + EXPECT_TRUE(are_known_ros_args({"__log_level:=DEBUG"})); + EXPECT_TRUE(are_known_ros_args({"__log_level:=INFO"})); + EXPECT_TRUE(are_known_ros_args({"__log_level:=WARN"})); + EXPECT_TRUE(are_known_ros_args({"__log_level:=ERROR"})); + EXPECT_TRUE(are_known_ros_args({"__log_level:=FATAL"})); + EXPECT_TRUE(are_known_ros_args({"__log_level:=debug"})); + EXPECT_TRUE(are_known_ros_args({"__log_level:=Info"})); + + // Disabling logging + EXPECT_TRUE(are_known_ros_args({"__log_disable_rosout:=false"})); + EXPECT_TRUE(are_known_ros_args({"__log_disable_rosout:=true"})); + EXPECT_TRUE(are_known_ros_args({"__log_disable_stdout:=false"})); + EXPECT_TRUE(are_known_ros_args({"__log_disable_stdout:=true"})); + EXPECT_TRUE(are_known_ros_args({"__log_disable_external_lib:=false"})); + EXPECT_TRUE(are_known_ros_args({"__log_disable_external_lib:=true"})); +} + bool are_valid_ros_args(std::vector argv) { @@ -514,7 +561,7 @@ TEST_F(CLASSNAME(TestArgumentsFixture, RMW_IMPLEMENTATION), test_fini_twice) { TEST_F(CLASSNAME(TestArgumentsFixture, RMW_IMPLEMENTATION), test_remove_ros_args) { const char * argv[] = { "process_name", "-d", "--ros-args", "-r", "__ns:=/foo/bar", "-r", "__ns:=/fiz/buz", "--", - "--foo=bar", "--baz", "--ros-args", "--ros-args", "-p", "bar:=baz", "--", "--", "arg" + "--foo=bar", "--baz", "--ros-args", "--ros-args", "-p", "bar:=baz", "--", "--", "arg", }; int argc = sizeof(argv) / sizeof(const char *); @@ -549,6 +596,45 @@ TEST_F(CLASSNAME(TestArgumentsFixture, RMW_IMPLEMENTATION), test_remove_ros_args } } +// \deprecated to be removed in F-Turtle +TEST_F(CLASSNAME(TestArgumentsFixture, RMW_IMPLEMENTATION), test_remove_deprecated_ros_args) { + const char * argv[] = { + "process_name", "-d", "__ns:=/foo/bar", "--foo=bar", "__log_config_file:=my.config", + "__log_level:=INFO", "__log_disable_rosout:=true", "--bar=baz", "__log_disable_stdout:=true", + "arg", "__log_disable_external_lib:=false" + }; + int argc = sizeof(argv) / sizeof(const char *); + + rcl_allocator_t alloc = rcl_get_default_allocator(); + rcl_arguments_t parsed_args = rcl_get_zero_initialized_arguments(); + rcl_ret_t ret; + ret = rcl_parse_arguments(argc, argv, alloc, &parsed_args); + ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; + + int nonros_argc = 0; + const char ** nonros_argv = NULL; + + ret = rcl_remove_ros_arguments( + argv, + &parsed_args, + alloc, + &nonros_argc, + &nonros_argv); + + EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; + ASSERT_EQ(nonros_argc, 5); + EXPECT_STREQ(nonros_argv[0], "process_name"); + EXPECT_STREQ(nonros_argv[1], "-d"); + EXPECT_STREQ(nonros_argv[2], "--foo=bar"); + EXPECT_STREQ(nonros_argv[3], "--bar=baz"); + EXPECT_STREQ(nonros_argv[4], "arg"); + EXPECT_EQ(RCL_RET_OK, rcl_arguments_fini(&parsed_args)); + + if (NULL != nonros_argv) { + alloc.deallocate(nonros_argv, alloc.state); + } +} + TEST_F(CLASSNAME(TestArgumentsFixture, RMW_IMPLEMENTATION), test_remove_ros_args_zero) { const char * argv[] = {""}; rcl_ret_t ret; @@ -617,6 +703,35 @@ TEST_F(CLASSNAME(TestArgumentsFixture, RMW_IMPLEMENTATION), test_param_argument_ EXPECT_EQ(RCL_RET_OK, rcl_arguments_fini(&parsed_args)); } +// \deprecated to be removed in F-Turtle +TEST_F(CLASSNAME(TestArgumentsFixture, RMW_IMPLEMENTATION), test_deprecated_param_argument_single) { + const char * argv[] = { + "process_name", "--ros-args", "-r", "__ns:=/namespace", "random:=arg", "--", + "__params:=parameter_filepath" + }; + int argc = sizeof(argv) / sizeof(const char *); + rcl_ret_t ret; + + rcl_allocator_t alloc = rcl_get_default_allocator(); + rcl_arguments_t parsed_args = rcl_get_zero_initialized_arguments(); + + ret = rcl_parse_arguments(argc, argv, alloc, &parsed_args); + ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; + + int parameter_filecount = rcl_arguments_get_param_files_count(&parsed_args); + EXPECT_EQ(1, parameter_filecount); + char ** parameter_files = NULL; + ret = rcl_arguments_get_param_files(&parsed_args, alloc, ¶meter_files); + ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; + EXPECT_STREQ("parameter_filepath", parameter_files[0]); + + for (int i = 0; i < parameter_filecount; ++i) { + alloc.deallocate(parameter_files[i], alloc.state); + } + alloc.deallocate(parameter_files, alloc.state); + EXPECT_EQ(RCL_RET_OK, rcl_arguments_fini(&parsed_args)); +} + TEST_F(CLASSNAME(TestArgumentsFixture, RMW_IMPLEMENTATION), test_param_argument_multiple) { const char * argv[] = { "process_name", "--ros-args", "--params-file", "parameter_filepath1",