diff --git a/rcl/include/rcl/remap.h b/rcl/include/rcl/remap.h index 82f0b0e04..add0c5ec6 100644 --- a/rcl/include/rcl/remap.h +++ b/rcl/include/rcl/remap.h @@ -187,6 +187,7 @@ rcl_remap_service_name( * \param[in] global_arguments Command line arguments to use if no local rules matched, or * `NULL` or zero-initialized to ignore global arguments. * \param[in] node_name The current name of the node. + * \param[in] node_namespace The namespace of a node to which name belongs. * \param[in] allocator A valid allocator to use. * \param[out] output_name Either an allocated string with the remapped name, or * `NULL` if no remap rules matched the name. @@ -203,6 +204,7 @@ rcl_remap_node_name( const rcl_arguments_t * local_arguments, const rcl_arguments_t * global_arguments, const char * node_name, + const char * node_namespace, rcl_allocator_t allocator, char ** output_name); @@ -228,6 +230,7 @@ rcl_remap_node_name( * \param[in] global_arguments Command line arguments to use if no local rules matched, or * `NULL` or zero-initialized to ignore global arguments. * \param[in] node_name The name of the node whose namespace is being remapped. + * \param[in] node_namespace The namespace of a node to which name belongs. * \param[in] allocator A valid allocator to be used. * \param[out] output_namespace Either an allocated string with the remapped namespace, or * `NULL` if no remap rules matched the name. @@ -244,6 +247,7 @@ rcl_remap_node_namespace( const rcl_arguments_t * local_arguments, const rcl_arguments_t * global_arguments, const char * node_name, + const char * node_namespace, rcl_allocator_t allocator, char ** output_namespace); diff --git a/rcl/src/rcl/node.c b/rcl/src/rcl/node.c index fe8a947fb..228e2205f 100644 --- a/rcl/src/rcl/node.c +++ b/rcl/src/rcl/node.c @@ -218,7 +218,7 @@ rcl_node_init( global_args = &(node->context->global_arguments); } ret = rcl_remap_node_name( - &(node->impl->options.arguments), global_args, name, *allocator, + &(node->impl->options.arguments), global_args, name, local_namespace_, *allocator, &remapped_node_name); if (RCL_RET_OK != ret) { goto fail; @@ -227,7 +227,7 @@ rcl_node_init( } char * remapped_namespace = NULL; ret = rcl_remap_node_namespace( - &(node->impl->options.arguments), global_args, name, + &(node->impl->options.arguments), global_args, name, local_namespace_, *allocator, &remapped_namespace); if (RCL_RET_OK != ret) { goto fail; diff --git a/rcl/src/rcl/remap.c b/rcl/src/rcl/remap.c index 1af77be74..ea90405bb 100644 --- a/rcl/src/rcl/remap.c +++ b/rcl/src/rcl/remap.c @@ -312,6 +312,7 @@ rcl_remap_node_name( const rcl_arguments_t * local_arguments, const rcl_arguments_t * global_arguments, const char * node_name, + const char * node_namespace, rcl_allocator_t allocator, char ** output_name) { @@ -322,7 +323,7 @@ rcl_remap_node_name( RCL_CHECK_ALLOCATOR_WITH_MSG(&allocator, "allocator is invalid", return RCL_RET_INVALID_ARGUMENT); return _rcl_remap_name( - local_arguments, global_arguments, RCL_NODENAME_REMAP, NULL, node_name, NULL, NULL, + local_arguments, global_arguments, RCL_NODENAME_REMAP, NULL, node_name, node_namespace, NULL, allocator, output_name); } @@ -331,6 +332,7 @@ rcl_remap_node_namespace( const rcl_arguments_t * local_arguments, const rcl_arguments_t * global_arguments, const char * node_name, + const char * node_namespace, rcl_allocator_t allocator, char ** output_namespace) { @@ -341,7 +343,7 @@ rcl_remap_node_namespace( RCL_CHECK_ALLOCATOR_WITH_MSG(&allocator, "allocator is invalid", return RCL_RET_INVALID_ARGUMENT); return _rcl_remap_name( - local_arguments, global_arguments, RCL_NAMESPACE_REMAP, NULL, node_name, NULL, NULL, + local_arguments, global_arguments, RCL_NAMESPACE_REMAP, NULL, node_name, node_namespace, NULL, allocator, output_namespace); } diff --git a/rcl/test/rcl/test_remap.cpp b/rcl/test/rcl/test_remap.cpp index 2a8209b46..e146ded7e 100644 --- a/rcl/test/rcl/test_remap.cpp +++ b/rcl/test/rcl/test_remap.cpp @@ -49,7 +49,7 @@ TEST_F(CLASSNAME(TestRemapFixture, RMW_IMPLEMENTATION), global_namespace_replace char * output = NULL; ret = rcl_remap_node_namespace( - NULL, &global_arguments, "NodeName", rcl_get_default_allocator(), &output); + NULL, &global_arguments, "NodeName", "/", rcl_get_default_allocator(), &output); EXPECT_EQ(RCL_RET_OK, ret); EXPECT_STREQ("/foo/bar", output); rcl_get_default_allocator().deallocate(output, rcl_get_default_allocator().state); @@ -64,12 +64,14 @@ TEST_F(CLASSNAME(TestRemapFixture, RMW_IMPLEMENTATION), nodename_prefix_namespac "--ros-args", "-r", "Node1:__ns:=/foo/bar", "-r", "Node2:__ns:=/this_one", - "-r", "Node3:__ns:=/bar/foo"); + "-r", "Node3:__ns:=/bar/foo", + "-r", "/Node4:__ns:=/bar/foo", + "-r", "/ns1/Node5:__ns:=/bar/foo"); { char * output = NULL; ret = rcl_remap_node_namespace( - NULL, &global_arguments, "Node1", rcl_get_default_allocator(), &output); + NULL, &global_arguments, "Node1", "/", rcl_get_default_allocator(), &output); EXPECT_EQ(RCL_RET_OK, ret); EXPECT_STREQ("/foo/bar", output); rcl_get_default_allocator().deallocate(output, rcl_get_default_allocator().state); @@ -77,7 +79,7 @@ TEST_F(CLASSNAME(TestRemapFixture, RMW_IMPLEMENTATION), nodename_prefix_namespac { char * output = NULL; ret = rcl_remap_node_namespace( - NULL, &global_arguments, "Node2", rcl_get_default_allocator(), &output); + NULL, &global_arguments, "Node2", "/", rcl_get_default_allocator(), &output); EXPECT_EQ(RCL_RET_OK, ret); EXPECT_STREQ("/this_one", output); rcl_get_default_allocator().deallocate(output, rcl_get_default_allocator().state); @@ -85,7 +87,23 @@ TEST_F(CLASSNAME(TestRemapFixture, RMW_IMPLEMENTATION), nodename_prefix_namespac { char * output = NULL; ret = rcl_remap_node_namespace( - NULL, &global_arguments, "Node3", rcl_get_default_allocator(), &output); + NULL, &global_arguments, "Node3", "/", rcl_get_default_allocator(), &output); + EXPECT_EQ(RCL_RET_OK, ret); + EXPECT_STREQ("/bar/foo", output); + rcl_get_default_allocator().deallocate(output, rcl_get_default_allocator().state); + } + { + char * output = NULL; + ret = rcl_remap_node_namespace( + NULL, &global_arguments, "Node4", "/", rcl_get_default_allocator(), &output); + EXPECT_EQ(RCL_RET_OK, ret); + EXPECT_STREQ("/bar/foo", output); + rcl_get_default_allocator().deallocate(output, rcl_get_default_allocator().state); + } + { + char * output = NULL; + ret = rcl_remap_node_namespace( + NULL, &global_arguments, "Node5", "/ns1", rcl_get_default_allocator(), &output); EXPECT_EQ(RCL_RET_OK, ret); EXPECT_STREQ("/bar/foo", output); rcl_get_default_allocator().deallocate(output, rcl_get_default_allocator().state); @@ -99,7 +117,7 @@ TEST_F(CLASSNAME(TestRemapFixture, RMW_IMPLEMENTATION), no_namespace_replacement char * output = NULL; ret = rcl_remap_node_namespace( - NULL, &global_arguments, "NodeName", rcl_get_default_allocator(), &output); + NULL, &global_arguments, "NodeName", "/", rcl_get_default_allocator(), &output); EXPECT_EQ(RCL_RET_OK, ret); EXPECT_EQ(NULL, output); } @@ -113,7 +131,7 @@ TEST_F(CLASSNAME(TestRemapFixture, RMW_IMPLEMENTATION), local_namespace_replacem char * output = NULL; ret = rcl_remap_node_namespace( - &local_arguments, &global_arguments, "NodeName", rcl_get_default_allocator(), &output); + &local_arguments, &global_arguments, "NodeName", "/", rcl_get_default_allocator(), &output); EXPECT_EQ(RCL_RET_OK, ret); EXPECT_STREQ("/local_args", output); rcl_get_default_allocator().deallocate(output, rcl_get_default_allocator().state); @@ -126,7 +144,7 @@ TEST_F(CLASSNAME(TestRemapFixture, RMW_IMPLEMENTATION), no_use_global_namespace_ char * output = NULL; ret = rcl_remap_node_namespace( - &local_arguments, NULL, "NodeName", rcl_get_default_allocator(), &output); + &local_arguments, NULL, "NodeName", "/", rcl_get_default_allocator(), &output); EXPECT_EQ(RCL_RET_OK, ret); EXPECT_EQ(NULL, output); } @@ -144,12 +162,67 @@ TEST_F(CLASSNAME(TestRemapFixture, RMW_IMPLEMENTATION), other_rules_before_names rcl_allocator_t allocator = rcl_get_default_allocator(); char * output = NULL; - ret = rcl_remap_node_namespace(NULL, &global_arguments, "NodeName", allocator, &output); + ret = rcl_remap_node_namespace(NULL, &global_arguments, "NodeName", "/", allocator, &output); EXPECT_EQ(RCL_RET_OK, ret); EXPECT_STREQ("/namespace", output); allocator.deallocate(output, allocator.state); } +TEST_F(CLASSNAME(TestRemapFixture, RMW_IMPLEMENTATION), nodename_prefix_nodename_remap) { + rcl_ret_t ret; + rcl_arguments_t global_arguments; + SCOPE_ARGS( + global_arguments, + "process_name", + "--ros-args", + "-r", "Node1:__node:=foo_bar", + "-r", "Node2:__node:=this_one", + "-r", "Node3:__node:=bar_foo", + "-r", "/Node4:__node:=bar_foo", + "-r", "/ns1/Node5:__node:=bar_foo"); + + { + char * output = NULL; + ret = rcl_remap_node_name( + NULL, &global_arguments, "Node1", "/", rcl_get_default_allocator(), &output); + EXPECT_EQ(RCL_RET_OK, ret); + EXPECT_STREQ("foo_bar", output); + rcl_get_default_allocator().deallocate(output, rcl_get_default_allocator().state); + } + { + char * output = NULL; + ret = rcl_remap_node_name( + NULL, &global_arguments, "Node2", "/", rcl_get_default_allocator(), &output); + EXPECT_EQ(RCL_RET_OK, ret); + EXPECT_STREQ("this_one", output); + rcl_get_default_allocator().deallocate(output, rcl_get_default_allocator().state); + } + { + char * output = NULL; + ret = rcl_remap_node_name( + NULL, &global_arguments, "Node3", "/", rcl_get_default_allocator(), &output); + EXPECT_EQ(RCL_RET_OK, ret); + EXPECT_STREQ("bar_foo", output); + rcl_get_default_allocator().deallocate(output, rcl_get_default_allocator().state); + } + { + char * output = NULL; + ret = rcl_remap_node_name( + NULL, &global_arguments, "Node4", "/", rcl_get_default_allocator(), &output); + EXPECT_EQ(RCL_RET_OK, ret); + EXPECT_STREQ("bar_foo", output); + rcl_get_default_allocator().deallocate(output, rcl_get_default_allocator().state); + } + { + char * output = NULL; + ret = rcl_remap_node_name( + NULL, &global_arguments, "Node5", "/ns1", rcl_get_default_allocator(), &output); + EXPECT_EQ(RCL_RET_OK, ret); + EXPECT_STREQ("bar_foo", output); + rcl_get_default_allocator().deallocate(output, rcl_get_default_allocator().state); + } +} + TEST_F(CLASSNAME(TestRemapFixture, RMW_IMPLEMENTATION), global_topic_name_replacement) { rcl_ret_t ret; rcl_arguments_t global_arguments; @@ -458,7 +531,7 @@ TEST_F(CLASSNAME(TestRemapFixture, RMW_IMPLEMENTATION), global_nodename_replacem rcl_allocator_t allocator = rcl_get_default_allocator(); char * output = NULL; - ret = rcl_remap_node_name(NULL, &global_arguments, "NodeName", allocator, &output); + ret = rcl_remap_node_name(NULL, &global_arguments, "NodeName", "/", allocator, &output); EXPECT_EQ(RCL_RET_OK, ret); EXPECT_STREQ("globalname", output); allocator.deallocate(output, allocator.state); @@ -471,7 +544,7 @@ TEST_F(CLASSNAME(TestRemapFixture, RMW_IMPLEMENTATION), no_nodename_replacement) char * output = NULL; ret = rcl_remap_node_name( - NULL, &global_arguments, "NodeName", rcl_get_default_allocator(), &output); + NULL, &global_arguments, "NodeName", NULL, rcl_get_default_allocator(), &output); EXPECT_EQ(RCL_RET_OK, ret); EXPECT_EQ(NULL, output); } @@ -485,7 +558,7 @@ TEST_F(CLASSNAME(TestRemapFixture, RMW_IMPLEMENTATION), local_nodename_replaceme char * output = NULL; ret = rcl_remap_node_name( - &local_arguments, &global_arguments, "NodeName", rcl_get_default_allocator(), &output); + &local_arguments, &global_arguments, "NodeName", "/", rcl_get_default_allocator(), &output); EXPECT_EQ(RCL_RET_OK, ret); EXPECT_STREQ("local_name", output); rcl_get_default_allocator().deallocate(output, rcl_get_default_allocator().state); @@ -498,7 +571,7 @@ TEST_F(CLASSNAME(TestRemapFixture, RMW_IMPLEMENTATION), no_use_global_nodename_r char * output = NULL; ret = rcl_remap_node_name( - &local_arguments, NULL, "NodeName", rcl_get_default_allocator(), &output); + &local_arguments, NULL, "NodeName", "/", rcl_get_default_allocator(), &output); EXPECT_EQ(RCL_RET_OK, ret); EXPECT_EQ(NULL, output); } @@ -515,7 +588,7 @@ TEST_F(CLASSNAME(TestRemapFixture, RMW_IMPLEMENTATION), use_first_nodename_rule) rcl_allocator_t allocator = rcl_get_default_allocator(); char * output = NULL; - ret = rcl_remap_node_name(NULL, &global_arguments, "NodeName", allocator, &output); + ret = rcl_remap_node_name(NULL, &global_arguments, "NodeName", "/", allocator, &output); EXPECT_EQ(RCL_RET_OK, ret); EXPECT_STREQ("firstname", output); allocator.deallocate(output, allocator.state); @@ -534,7 +607,7 @@ TEST_F(CLASSNAME(TestRemapFixture, RMW_IMPLEMENTATION), other_rules_before_noden rcl_allocator_t allocator = rcl_get_default_allocator(); char * output = NULL; - ret = rcl_remap_node_name(NULL, &global_arguments, "NodeName", allocator, &output); + ret = rcl_remap_node_name(NULL, &global_arguments, "NodeName", "/", allocator, &output); EXPECT_EQ(RCL_RET_OK, ret); EXPECT_STREQ("remap_name", output); allocator.deallocate(output, allocator.state); @@ -588,24 +661,24 @@ TEST_F(CLASSNAME(TestRemapFixture, RMW_IMPLEMENTATION), _rcl_remap_name_bad_arg) // Expected usage local_args, global not init is OK rcl_ret_t ret = rcl_remap_node_name( - &local_arguments, &zero_init_global_arguments, "NodeName", allocator, &output); + &local_arguments, &zero_init_global_arguments, "NodeName", "/", allocator, &output); EXPECT_EQ(RCL_RET_OK, ret); EXPECT_STREQ("local_name", output); allocator.deallocate(output, allocator.state); // Expected usage global_args, local not null is OK - ret = rcl_remap_node_name(nullptr, &global_arguments, "NodeName", allocator, &output); + ret = rcl_remap_node_name(nullptr, &global_arguments, "NodeName", "/", allocator, &output); EXPECT_EQ(RCL_RET_OK, ret); EXPECT_STREQ("global_name", output); allocator.deallocate(output, allocator.state); // Both local and global arguments, not valid - ret = rcl_remap_node_name(nullptr, nullptr, "NodeName", allocator, &output); + ret = rcl_remap_node_name(nullptr, nullptr, "NodeName", "/", allocator, &output); EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret); rcl_reset_error(); // Bad allocator - ret = rcl_remap_node_name(nullptr, &global_arguments, "NodeName", bad_allocator, &output); + ret = rcl_remap_node_name(nullptr, &global_arguments, "NodeName", NULL, bad_allocator, &output); EXPECT_EQ(RCL_RET_ERROR, ret); rcl_reset_error(); }