diff --git a/include/rcutils/filesystem.h b/include/rcutils/filesystem.h index 0e7632e8..23a81c4f 100644 --- a/include/rcutils/filesystem.h +++ b/include/rcutils/filesystem.h @@ -126,6 +126,24 @@ rcutils_join_path( const char * right_hand_path, rcutils_allocator_t allocator); +/// Return newly allocated string with all argument's "/" replaced by platform specific separator. +/** + * This function allocates memory and returns it to the caller. + * It is up to the caller to release the memory once it is done with it by + * calling `deallocate` on the same allocator passed here. + * + * \param[in] path + * \param[in] allocator + * \return char * path using platform specific delimiters on success + * NULL on invalid arguments + * NULL on failure + */ +RCUTILS_PUBLIC +char * +rcutils_to_native_path( + const char * path, + rcutils_allocator_t allocator); + #ifdef __cplusplus } #endif diff --git a/src/filesystem.c b/src/filesystem.c index 2e84755c..0c360614 100644 --- a/src/filesystem.c +++ b/src/filesystem.c @@ -29,6 +29,13 @@ extern "C" #endif // _WIN32 #include "rcutils/format_string.h" +#include "rcutils/repl_str.h" + +#ifdef _WIN32 +# define RCUTILS_PATH_DELIMITER "\\" +#else +# define RCUTILS_PATH_DELIMITER "/" +#endif // _WIN32 bool rcutils_get_cwd(char * buffer, size_t max_length) @@ -152,13 +159,22 @@ rcutils_join_path( return NULL; } -#ifdef _WIN32 - const char * delimiter = "\\"; -#else - const char * delimiter = "/"; -#endif // _WIN32 + return rcutils_format_string( + allocator, + "%s%s%s", + left_hand_path, RCUTILS_PATH_DELIMITER, right_hand_path); +} + +char * +rcutils_to_native_path( + const char * path, + rcutils_allocator_t allocator) +{ + if (NULL == path) { + return NULL; + } - return rcutils_format_string(allocator, "%s%s%s", left_hand_path, delimiter, right_hand_path); + return rcutils_repl_str(path, "/", RCUTILS_PATH_DELIMITER, &allocator); } #ifdef __cplusplus diff --git a/test/test_filesystem.cpp b/test/test_filesystem.cpp index c7a1ac15..593d6f51 100644 --- a/test/test_filesystem.cpp +++ b/test/test_filesystem.cpp @@ -59,6 +59,35 @@ TEST_F(TestFilesystemFixture, join_path) { EXPECT_STREQ(ref_str, path); } +TEST_F(TestFilesystemFixture, to_native_path) { + { + char * path = rcutils_to_native_path("/foo/bar/baz", g_allocator); + OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT({ + g_allocator.deallocate(path, g_allocator.state); + }); +#ifdef _WIN32 + const char * ref_str = "\\foo\\bar\\baz"; +#else + const char * ref_str = "/foo/bar/baz"; +#endif // _WIN32 + ASSERT_FALSE(nullptr == path); + EXPECT_STREQ(ref_str, path); + } + { + char * path = rcutils_to_native_path("/foo//bar/baz", g_allocator); + OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT({ + g_allocator.deallocate(path, g_allocator.state); + }); +#ifdef _WIN32 + const char * ref_str = "\\foo\\\\bar\\baz"; +#else + const char * ref_str = "/foo//bar/baz"; +#endif // _WIN32 + ASSERT_FALSE(nullptr == path); + EXPECT_STREQ(ref_str, path); + } +} + TEST_F(TestFilesystemFixture, exists) { { char * path = rcutils_join_path(this->test_path, "dummy_readable_file.txt", g_allocator);