diff --git a/rcl/include/rcl/remap.h b/rcl/include/rcl/remap.h index a7b10ea93..82f0b0e04 100644 --- a/rcl/include/rcl/remap.h +++ b/rcl/include/rcl/remap.h @@ -247,6 +247,31 @@ rcl_remap_node_namespace( rcl_allocator_t allocator, char ** output_namespace); +/// Copy one remap structure into another. +/** + *
+ * Attribute | Adherence + * ------------------ | ------------- + * Allocates Memory | Yes + * Thread-Safe | No + * Uses Atomics | No + * Lock-Free | Yes + * + * \param[in] rule The structure to be copied. + * Its allocator is used to copy memory into the new structure. + * \param[out] rule_out A zero-initialized rcl_remap_t structure to be copied into. + * \return `RCL_RET_OK` if the structure was copied successfully, or + * \return `RCL_RET_INVALID_ARGUMENT` if any function arguments are invalid, or + * \return `RCL_RET_BAD_ALLOC` if allocating memory failed, or + * \return `RCL_RET_ERROR` if an unspecified error occurs. + */ +RCL_PUBLIC +RCL_WARN_UNUSED +rcl_ret_t +rcl_remap_copy( + const rcl_remap_t * rule, + rcl_remap_t * rule_out); + /// Reclaim resources held inside rcl_remap_t structure. /** *
diff --git a/rcl/src/rcl/remap_impl.h b/rcl/src/rcl/remap_impl.h index de8e835f8..898e58cb7 100644 --- a/rcl/src/rcl/remap_impl.h +++ b/rcl/src/rcl/remap_impl.h @@ -51,57 +51,6 @@ typedef struct rcl_remap_impl_t rcl_allocator_t allocator; } rcl_remap_impl_t; -/// Get an rcl_remap_t structure initialized with NULL. -rcl_remap_t -rcl_remap_get_zero_initialized(); - -/// Copy one remap structure into another. -/** - *
- * Attribute | Adherence - * ------------------ | ------------- - * Allocates Memory | Yes - * Thread-Safe | No - * Uses Atomics | No - * Lock-Free | Yes - * - * \param[in] rule The structure to be copied. - * Its allocator is used to copy memory into the new structure. - * \param[out] rule_out A zero-initialized rcl_remap_t structure to be copied into. - * \return `RCL_RET_OK` if the structure was copied successfully, or - * \return `RCL_RET_INVALID_ARGUMENT` if any function arguments are invalid, or - * \return `RCL_RET_BAD_ALLOC` if allocating memory failed, or - * \return `RCL_RET_ERROR` if an unspecified error occurs. - */ -RCL_PUBLIC -RCL_WARN_UNUSED -rcl_ret_t -rcl_remap_copy( - const rcl_remap_t * rule, - rcl_remap_t * rule_out); - -/// Reclaim resources used in an rcl_remap_t structure. -/** - *
- * Attribute | Adherence - * ------------------ | ------------- - * Allocates Memory | No - * Thread-Safe | Yes - * Uses Atomics | No - * Lock-Free | Yes - * - * \param[in] rule A rule to deallocate back to a zero initialized state. - * \return `RCL_RET_OK` if the structure was free'd, or - * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or - * \return `RCL_RET_BAD_ALLOC` if allocating memory failed, or - * \return `RCL_RET_NODE_INVALID_NAME` if the name is invalid, or - * \return `RCL_RET_ERROR` if an unspecified error occurs. - */ -RCL_WARN_UNUSED -rcl_ret_t -rcl_remap_fini( - rcl_remap_t * rule); - #ifdef __cplusplus } #endif diff --git a/rcl/test/rcl/test_remap.cpp b/rcl/test/rcl/test_remap.cpp index 1b0d2eb0e..f2dca9dbe 100644 --- a/rcl/test/rcl/test_remap.cpp +++ b/rcl/test/rcl/test_remap.cpp @@ -19,10 +19,9 @@ #include "rcl/remap.h" #include "rcl/error_handling.h" +#include "./allocator_testing_utils.h" #include "./arg_macros.hpp" #include "./arguments_impl.h" -#include "./allocator_testing_utils.h" -#include "./remap_impl.h" #ifdef RMW_IMPLEMENTATION # define CLASSNAME_(NAME, SUFFIX) NAME ## __ ## SUFFIX @@ -574,3 +573,43 @@ TEST_F(CLASSNAME(TestRemapFixture, RMW_IMPLEMENTATION), _rcl_remap_name_bad_arg) EXPECT_EQ(RCL_RET_ERROR, ret); rcl_reset_error(); } + +TEST_F(CLASSNAME(TestRemapFixture, RMW_IMPLEMENTATION), internal_remap_use) { + // Easiest way to init a rcl_remap is through the arguments API + const char * argv[] = { + "process_name", "--ros-args", "-r", "__ns:=/namespace", "random:=arg" + }; + 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 = rcl_parse_arguments(argc, argv, alloc, &parsed_args); + ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; + OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT( + { + EXPECT_EQ(RCL_RET_OK, rcl_arguments_fini(&parsed_args)); + }); + + // Bad alloc + rcl_remap_t remap_dst = rcl_get_zero_initialized_remap(); + parsed_args.impl->remap_rules->impl->allocator = get_failing_allocator(); + EXPECT_EQ(RCL_RET_BAD_ALLOC, rcl_remap_copy(parsed_args.impl->remap_rules, &remap_dst)); + parsed_args.impl->remap_rules->impl->allocator = alloc; + + // Expected usage + EXPECT_EQ(RCL_RET_OK, rcl_remap_copy(parsed_args.impl->remap_rules, &remap_dst)); + + // Copy twice + EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, rcl_remap_copy(parsed_args.impl->remap_rules, &remap_dst)); + rcl_reset_error(); + + // Fini + EXPECT_EQ(RCL_RET_OK, rcl_remap_fini(&remap_dst)); + + // Fini twice + EXPECT_EQ(RCL_RET_ERROR, rcl_remap_fini(&remap_dst)); + rcl_reset_error(); + + // Bad fini + EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, rcl_remap_fini(nullptr)); +}