From 066087b383d281a64c9e3fbf5294e480bf4ab41a Mon Sep 17 00:00:00 2001 From: gabime Date: Fri, 25 Oct 2019 14:14:50 +0300 Subject: [PATCH] Update create_dir --- include/spdlog/details/os-inl.h | 43 +++++++++++++------------ tests/test_create_dir.cpp | 56 ++++++++++++++++++++------------- 2 files changed, 55 insertions(+), 44 deletions(-) diff --git a/include/spdlog/details/os-inl.h b/include/spdlog/details/os-inl.h index 590e35a1..1764eeeb 100644 --- a/include/spdlog/details/os-inl.h +++ b/include/spdlog/details/os-inl.h @@ -485,27 +485,30 @@ SPDLOG_INLINE bool create_dir(filename_t path) { return true; } - using char_type = filename_t::value_type; - std::basic_istringstream istream(path); - filename_t token; - filename_t cur_dir; - + #ifdef _WIN32 // support forward slash in windows std::replace(path.begin(), path.end(), '/', folder_sep); -#endif - while (std::getline(istream, token, folder_sep)) - { - if (!token.empty()) - { - cur_dir += token; - if (!file_exists(cur_dir) && !mkdir_(cur_dir)) - { - return false; - } - } - cur_dir += folder_sep; - } +#endif + + size_t search_offset = 0; + do + { + auto token_pos = path.find(folder_sep, search_offset); + // treat the entire path as a folder if no folder separator not found + if (token_pos == filename_t::npos) + { + token_pos = path.size(); + } + + auto subdir = path.substr(0, token_pos); + + if (!subdir.empty() && !file_exists(subdir) && !mkdir_(subdir)) + { + return false; // return error if failed creating dir + } + search_offset = token_pos + 1; + } while (search_offset < path.size()); return true; } @@ -517,10 +520,6 @@ SPDLOG_INLINE bool create_dir(filename_t path) // "abc///" => "abc//" SPDLOG_INLINE filename_t dir_name(filename_t path) { -#ifdef _WIN32 - // support forward slash in windows - std::replace(path.begin(), path.end(), '/', folder_sep); -#endif auto pos = path.find_last_of(folder_sep); return pos != filename_t::npos ? path.substr(0, pos) : filename_t{}; } diff --git a/tests/test_create_dir.cpp b/tests/test_create_dir.cpp index 3849e2fe..1c20e5c1 100644 --- a/tests/test_create_dir.cpp +++ b/tests/test_create_dir.cpp @@ -8,6 +8,7 @@ using spdlog::details::os::file_exists; void test_create_dir(const char *path, const char *normalized_path) { + printf("Test Create dir %s\n", path); auto rv = create_dir(path); REQUIRE(rv == true); REQUIRE(file_exists(normalized_path)); @@ -18,11 +19,23 @@ void test_create_dir(const char *path, const char *normalized_path) TEST_CASE("create_dir", "[create_dir]") { prepare_logdir(); - test_create_dir("test_logs/dir1/dir1", "test_logs/dir1/dir1"); - test_create_dir("test_logs/dir1///dir2", "test_logs/dir1/dir2"); - test_create_dir("./test_logs/dir1/dir3", "test_logs/dir1/dir3"); - test_create_dir("test_logs/../test_logs/dir1/dir4", "test_logs/dir1/dir4"); - test_create_dir("./test_logs/dir1/dir2/dir99/../dir23", "test_logs/dir1/dir2/dir23"); +#ifdef WIN32 + test_create_dir("test_logs/dir1/dir1", "test_logs\\dir1\\dir1"); + test_create_dir("test_logs/dir1/dir1", "test_logs\\dir1\\dir1"); //test existing + test_create_dir("test_logs/dir1///dir2//", "test_logs\\dir1\\dir2"); + test_create_dir("./test_logs/dir1/dir3", "test_logs\\dir1\\dir3"); + test_create_dir("test_logs/../test_logs/dir1/dir4", "test_logs\\dir1\\dir4"); + // test backslash + test_create_dir("test_logs\\dir1\\dir222", "test_logs\\dir1\\dir222"); + test_create_dir("test_logs\\dir1\\dir223\\", "test_logs\\dir1\\dir223\\"); + test_create_dir(".\\test_logs\\dir1\\dir2\\dir99\\..\\dir23", "test_logs\\dir1\\dir2\\dir23"); +#else + test_create_dir("test_logs/dir1/dir1", "test_logs/dir1/dir1"); + test_create_dir("test_logs/dir1/dir1", "test_logs/dir1/dir1"); // test existing + test_create_dir("test_logs/dir1///dir2", "test_logs/dir1/dir2"); + test_create_dir("./test_logs/dir1/dir3", "test_logs/dir1/dir3"); + test_create_dir("test_logs/../test_logs/dir1/dir4", "test_logs/dir1/dir4"); +#endif } TEST_CASE("dir_name", "[create_dir]") @@ -30,29 +43,28 @@ TEST_CASE("dir_name", "[create_dir]") using spdlog::details::os::dir_name; REQUIRE(dir_name("").empty()); REQUIRE(dir_name("dir").empty()); - REQUIRE(dir_name("dir/") == "dir"); - REQUIRE(dir_name("dir///") == "dir//"); - REQUIRE(dir_name("dir/file") == "dir"); - REQUIRE(dir_name("dir/file.txt") == "dir"); - REQUIRE(dir_name("dir/file.txt/") == "dir/file.txt"); - REQUIRE(dir_name("/dir/file.txt") == "/dir"); - REQUIRE(dir_name("//dir/file.txt") == "//dir"); - REQUIRE(dir_name("//dir/file.txt") == "//dir"); - REQUIRE(dir_name("../file.txt") == ".."); - REQUIRE(dir_name("./file.txt") == "."); + #ifdef WIN32 REQUIRE(dir_name(R"(dir\)") == "dir"); - REQUIRE(dir_name(R"(dir\\\)") == "dir//"); + REQUIRE(dir_name(R"(dir\\\)") == R"(dir\\)"); REQUIRE(dir_name(R"(dir\file)") == "dir"); REQUIRE(dir_name(R"(dir\file.txt)") == "dir"); - REQUIRE(dir_name(R"(dir\file.txt\)") == "dir/file.txt"); - REQUIRE(dir_name(R"(\dir\file.txt)") == "/dir"); - REQUIRE(dir_name(R"(\\dir\file.txt)") == "//dir"); - REQUIRE(dir_name(R"(\\dir\file.txt)") == "//dir"); + REQUIRE(dir_name(R"(dir\file.txt\)") == R"(dir\file.txt)"); + REQUIRE(dir_name(R"(\dir\file.txt)") == R"(\dir)"); + REQUIRE(dir_name(R"(\\dir\file.txt)") == R"(\\dir)"); REQUIRE(dir_name(R"(..\file.txt)") == ".."); REQUIRE(dir_name(R"(.\file.txt)") == "."); - REQUIRE(dir_name(R"(c:\\a\b\c\d\file.txt)") == "c://a/b/c/d"); - //REQUIRE(dir_name(R"(c:\\a)") == "c://"); + REQUIRE(dir_name(R"(c:\\a\b\c\d\file.txt)") == R"(c:\\a\b\c\d)"); +#else + REQUIRE(dir_name("dir/") == "dir"); + REQUIRE(dir_name("dir///") == "dir//"); + REQUIRE(dir_name("dir/file") == "dir"); + REQUIRE(dir_name("dir/file.txt") == "dir"); + REQUIRE(dir_name("dir/file.txt/") == "dir/file.txt"); + REQUIRE(dir_name("/dir/file.txt") == "/dir"); + REQUIRE(dir_name("//dir/file.txt") == "//dir"); + REQUIRE(dir_name("../file.txt") == ".."); + REQUIRE(dir_name("./file.txt") == "."); #endif }