Support CLI parameter overrides using dots instead of slashes. (#530)
Signed-off-by: Michel Hidalgo <michel@ekumenlabs.com>
This commit is contained in:
parent
3d3b77c1fd
commit
513a185d1b
4 changed files with 94 additions and 7 deletions
|
@ -73,7 +73,11 @@ typedef enum rcl_lexeme_t
|
||||||
/// *
|
/// *
|
||||||
RCL_LEXEME_WILD_ONE = 20,
|
RCL_LEXEME_WILD_ONE = 20,
|
||||||
/// **
|
/// **
|
||||||
RCL_LEXEME_WILD_MULTI = 21
|
RCL_LEXEME_WILD_MULTI = 21,
|
||||||
|
// TODO(hidmic): remove when parameter names are standardized to
|
||||||
|
// use slashes in lieu of dots
|
||||||
|
/// .
|
||||||
|
RCL_LEXEME_DOT = 22,
|
||||||
} rcl_lexeme_t;
|
} rcl_lexeme_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1351,6 +1351,70 @@ _rcl_parse_resource_match(
|
||||||
return RCL_RET_OK;
|
return RCL_RET_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Parse a parameter name in a parameter override rule (ex: `foo.bar`)
|
||||||
|
/**
|
||||||
|
* \sa _rcl_parse_param_rule()
|
||||||
|
*/
|
||||||
|
// TODO(hidmic): remove when parameter names are standardized to use slashes
|
||||||
|
// in lieu of dots.
|
||||||
|
RCL_LOCAL
|
||||||
|
rcl_ret_t
|
||||||
|
_rcl_parse_param_name(
|
||||||
|
rcl_lexer_lookahead2_t * lex_lookahead,
|
||||||
|
rcl_allocator_t allocator,
|
||||||
|
char ** param_name)
|
||||||
|
{
|
||||||
|
rcl_ret_t ret;
|
||||||
|
rcl_lexeme_t lexeme;
|
||||||
|
|
||||||
|
// Check arguments sanity
|
||||||
|
assert(NULL != lex_lookahead);
|
||||||
|
assert(rcutils_allocator_is_valid(&allocator));
|
||||||
|
assert(NULL != param_name);
|
||||||
|
assert(NULL == *param_name);
|
||||||
|
|
||||||
|
const char * name_start = rcl_lexer_lookahead2_get_text(lex_lookahead);
|
||||||
|
if (NULL == name_start) {
|
||||||
|
RCL_SET_ERROR_MSG("failed to get start of param name");
|
||||||
|
return RCL_RET_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// token ( '.' token )*
|
||||||
|
ret = _rcl_parse_resource_match_token(lex_lookahead);
|
||||||
|
if (RCL_RET_OK != ret) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
ret = rcl_lexer_lookahead2_peek(lex_lookahead, &lexeme);
|
||||||
|
if (RCL_RET_OK != ret) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
while (RCL_LEXEME_SEPARATOR != lexeme) {
|
||||||
|
ret = rcl_lexer_lookahead2_expect(lex_lookahead, RCL_LEXEME_DOT, NULL, NULL);
|
||||||
|
if (RCL_RET_WRONG_LEXEME == ret) {
|
||||||
|
return RCL_RET_INVALID_REMAP_RULE;
|
||||||
|
}
|
||||||
|
ret = _rcl_parse_resource_match_token(lex_lookahead);
|
||||||
|
if (RCL_RET_OK != ret) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
ret = rcl_lexer_lookahead2_peek(lex_lookahead, &lexeme);
|
||||||
|
if (RCL_RET_OK != ret) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy param name
|
||||||
|
const char * name_end = rcl_lexer_lookahead2_get_text(lex_lookahead);
|
||||||
|
const size_t length = (size_t)(name_end - name_start);
|
||||||
|
*param_name = rcutils_strndup(name_start, length, allocator);
|
||||||
|
if (NULL == *param_name) {
|
||||||
|
RCL_SET_ERROR_MSG("failed to copy param name");
|
||||||
|
return RCL_RET_BAD_ALLOC;
|
||||||
|
}
|
||||||
|
|
||||||
|
return RCL_RET_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Parse the match side of a name remapping rule (ex: `rostopic://foo`)
|
/// Parse the match side of a name remapping rule (ex: `rostopic://foo`)
|
||||||
/**
|
/**
|
||||||
|
@ -1796,7 +1860,9 @@ _rcl_parse_param_rule(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = _rcl_parse_resource_match(&lex_lookahead, params->allocator, ¶m_name);
|
// TODO(hidmic): switch to _rcl_parse_resource_match() when parameter names
|
||||||
|
// are standardized to use slashes in lieu of dots.
|
||||||
|
ret = _rcl_parse_param_name(&lex_lookahead, params->allocator, ¶m_name);
|
||||||
if (RCL_RET_OK != ret) {
|
if (RCL_RET_OK != ret) {
|
||||||
if (RCL_RET_WRONG_LEXEME == ret) {
|
if (RCL_RET_WRONG_LEXEME == ret) {
|
||||||
ret = RCL_RET_INVALID_PARAM_RULE;
|
ret = RCL_RET_INVALID_PARAM_RULE;
|
||||||
|
|
|
@ -57,8 +57,10 @@ digraph remapping_lexer {
|
||||||
T_WILD_MULTI
|
T_WILD_MULTI
|
||||||
T_EOF
|
T_EOF
|
||||||
T_NONE
|
T_NONE
|
||||||
|
T_DOT
|
||||||
node [shape = circle];
|
node [shape = circle];
|
||||||
S0 -> T_FORWARD_SLASH [ label = "/"];
|
S0 -> T_FORWARD_SLASH [ label = "/"];
|
||||||
|
S0 -> T_DOT [ label = "."];
|
||||||
S0 -> S1 [ label = "\\"];
|
S0 -> S1 [ label = "\\"];
|
||||||
S0 -> S2 [ label = "~"];
|
S0 -> S2 [ label = "~"];
|
||||||
S0 -> S3 [ label = "_" ];
|
S0 -> S3 [ label = "_" ];
|
||||||
|
@ -155,7 +157,7 @@ typedef struct rcl_lexer_state_t
|
||||||
/// Movement associated with taking else state
|
/// Movement associated with taking else state
|
||||||
const unsigned char else_movement;
|
const unsigned char else_movement;
|
||||||
/// Transitions in the state machine (NULL value at end of array)
|
/// Transitions in the state machine (NULL value at end of array)
|
||||||
const rcl_lexer_transition_t transitions[11];
|
const rcl_lexer_transition_t transitions[12];
|
||||||
} rcl_lexer_state_t;
|
} rcl_lexer_state_t;
|
||||||
|
|
||||||
#define S0 0u
|
#define S0 0u
|
||||||
|
@ -213,6 +215,7 @@ typedef struct rcl_lexer_state_t
|
||||||
#define T_WILD_MULTI 50u
|
#define T_WILD_MULTI 50u
|
||||||
#define T_EOF 51u
|
#define T_EOF 51u
|
||||||
#define T_NONE 52u
|
#define T_NONE 52u
|
||||||
|
#define T_DOT 53u
|
||||||
|
|
||||||
// used to figure out if a state is terminal or not
|
// used to figure out if a state is terminal or not
|
||||||
#define FIRST_TERMINAL T_TILDE_SLASH
|
#define FIRST_TERMINAL T_TILDE_SLASH
|
||||||
|
@ -229,6 +232,7 @@ static const rcl_lexer_state_t g_states[LAST_STATE + 1] =
|
||||||
0u,
|
0u,
|
||||||
{
|
{
|
||||||
{T_FORWARD_SLASH, '/', '/'},
|
{T_FORWARD_SLASH, '/', '/'},
|
||||||
|
{T_DOT, '.', '.'},
|
||||||
{S1, '\\', '\\'},
|
{S1, '\\', '\\'},
|
||||||
{S2, '~', '~'},
|
{S2, '~', '~'},
|
||||||
{S3, '_', '_'},
|
{S3, '_', '_'},
|
||||||
|
@ -573,6 +577,8 @@ static const rcl_lexeme_t g_terminals[LAST_TERMINAL + 1] = {
|
||||||
RCL_LEXEME_EOF,
|
RCL_LEXEME_EOF,
|
||||||
// 21
|
// 21
|
||||||
RCL_LEXEME_NONE,
|
RCL_LEXEME_NONE,
|
||||||
|
// 22
|
||||||
|
RCL_LEXEME_DOT
|
||||||
};
|
};
|
||||||
|
|
||||||
rcl_ret_t
|
rcl_ret_t
|
||||||
|
|
|
@ -144,10 +144,15 @@ TEST_F(CLASSNAME(TestArgumentsFixture, RMW_IMPLEMENTATION), check_known_vs_unkno
|
||||||
EXPECT_TRUE(are_known_ros_args({"--ros-args", "-r", "rostopic:///rosservice:=rostopic"}));
|
EXPECT_TRUE(are_known_ros_args({"--ros-args", "-r", "rostopic:///rosservice:=rostopic"}));
|
||||||
EXPECT_TRUE(are_known_ros_args({"--ros-args", "-r", "rostopic:///foo/bar:=baz"}));
|
EXPECT_TRUE(are_known_ros_args({"--ros-args", "-r", "rostopic:///foo/bar:=baz"}));
|
||||||
EXPECT_TRUE(are_known_ros_args({"--ros-args", "-p", "foo:=bar"}));
|
EXPECT_TRUE(are_known_ros_args({"--ros-args", "-p", "foo:=bar"}));
|
||||||
EXPECT_TRUE(are_known_ros_args({"--ros-args", "-p", "~/foo:=~/bar"}));
|
// TODO(hidmic): restore tests (and drop the following ones) when parameter names
|
||||||
EXPECT_TRUE(are_known_ros_args({"--ros-args", "-p", "/foo/bar:=bar"}));
|
// are standardized to use slashes in lieu of dots.
|
||||||
EXPECT_TRUE(are_known_ros_args({"--ros-args", "-p", "foo:=/bar"}));
|
// EXPECT_TRUE(are_known_ros_args({"--ros-args", "-p", "~/foo:=~/bar"}));
|
||||||
EXPECT_TRUE(are_known_ros_args({"--ros-args", "-p", "/foo123:=/bar123"}));
|
// EXPECT_TRUE(are_known_ros_args({"--ros-args", "-p", "/foo/bar:=bar"}));
|
||||||
|
// EXPECT_TRUE(are_known_ros_args({"--ros-args", "-p", "foo:=/bar"}));
|
||||||
|
// EXPECT_TRUE(are_known_ros_args({"--ros-args", "-p", "/foo123:=/bar123"}));
|
||||||
|
EXPECT_TRUE(are_known_ros_args({"--ros-args", "-p", "foo.bar:=bar"}));
|
||||||
|
EXPECT_TRUE(are_known_ros_args({"--ros-args", "-p", "node:foo:=bar"}));
|
||||||
|
EXPECT_TRUE(are_known_ros_args({"--ros-args", "-p", "fizz123:=buzz456"}));
|
||||||
|
|
||||||
const std::string parameters_filepath = (test_path / "test_parameters.1.yaml").string();
|
const std::string parameters_filepath = (test_path / "test_parameters.1.yaml").string();
|
||||||
EXPECT_TRUE(are_known_ros_args({"--ros-args", "--params-file", parameters_filepath.c_str()}));
|
EXPECT_TRUE(are_known_ros_args({"--ros-args", "--params-file", parameters_filepath.c_str()}));
|
||||||
|
@ -998,6 +1003,7 @@ TEST_F(CLASSNAME(TestArgumentsFixture, RMW_IMPLEMENTATION), test_param_overrides
|
||||||
"process_name", "--ros-args",
|
"process_name", "--ros-args",
|
||||||
"--params-file", parameters_filepath.c_str(),
|
"--params-file", parameters_filepath.c_str(),
|
||||||
"--param", "string_param:=bar",
|
"--param", "string_param:=bar",
|
||||||
|
"-p", "some.bool_param:=false",
|
||||||
"-p", "some_node:int_param:=4"
|
"-p", "some_node:int_param:=4"
|
||||||
};
|
};
|
||||||
int argc = sizeof(argv) / sizeof(const char *);
|
int argc = sizeof(argv) / sizeof(const char *);
|
||||||
|
@ -1025,6 +1031,11 @@ TEST_F(CLASSNAME(TestArgumentsFixture, RMW_IMPLEMENTATION), test_param_overrides
|
||||||
ASSERT_TRUE(NULL != param_value->string_value);
|
ASSERT_TRUE(NULL != param_value->string_value);
|
||||||
EXPECT_STREQ("bar", param_value->string_value);
|
EXPECT_STREQ("bar", param_value->string_value);
|
||||||
|
|
||||||
|
param_value = rcl_yaml_node_struct_get("/**", "some.bool_param", params);
|
||||||
|
ASSERT_TRUE(NULL != param_value);
|
||||||
|
ASSERT_TRUE(NULL != param_value->bool_value);
|
||||||
|
EXPECT_FALSE(*(param_value->bool_value));
|
||||||
|
|
||||||
param_value = rcl_yaml_node_struct_get("some_node", "int_param", params);
|
param_value = rcl_yaml_node_struct_get("some_node", "int_param", params);
|
||||||
ASSERT_TRUE(NULL != param_value);
|
ASSERT_TRUE(NULL != param_value);
|
||||||
ASSERT_TRUE(NULL != param_value->integer_value);
|
ASSERT_TRUE(NULL != param_value->integer_value);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue