diff --git a/Foundation/include/Poco/Path.h b/Foundation/include/Poco/Path.h index 6534e6915..73f5a4a05 100644 --- a/Foundation/include/Poco/Path.h +++ b/Foundation/include/Poco/Path.h @@ -290,6 +290,22 @@ public: /// this is the semicolon ';'. On OpenVMS systems, this is the /// comma ','. + static std::string addDirectorySeparator(const std::string& path); + /// Adds a separator to the end of a string to create the correct syntax for a path. + /// If the source path already has a trailing separator, no separator will be added. + /// + /// On Unix systems, this is the slash '/'. On Windows systems, + /// this is the backslash '\'. On OpenVMS systems, this is the + /// period '.'. + + static std::string addDirectorySeparator(const std::string& path, Style style); + /// Adds a separator to the end of a string to create the correct syntax for a path. + /// If the source path already has a trailing separator, no separator will be added. + /// + /// On Unix systems, this is the slash '/'. On Windows systems, + /// this is the backslash '\'. On OpenVMS systems, this is the + /// period '.'. + static std::string self(); /// Return path to the executable file, empty string if failed. /// The path is absolute one. diff --git a/Foundation/src/Path.cpp b/Foundation/src/Path.cpp index d69c40318..a26b234ed 100644 --- a/Foundation/src/Path.cpp +++ b/Foundation/src/Path.cpp @@ -298,14 +298,14 @@ bool Path::tryParse(const std::string& path, Style style) Path& Path::parseDirectory(const std::string& path) { - assign(path); + assign(addDirectorySeparator(path)); return makeDirectory(); } Path& Path::parseDirectory(const std::string& path, Style style) { - assign(path, style); + assign(addDirectorySeparator(path, style), style); return makeDirectory(); } @@ -574,6 +574,49 @@ Path& Path::clear() } +std::string Path::addDirectorySeparator(const std::string& path) +{ + poco_assert(!path.empty()); + + if (path.back() != separator()) + { + return path + separator(); + } + return path; +} + + +std::string Path::addDirectorySeparator(const std::string& path, Style style) +{ + poco_assert(!path.empty()); + + char ch = '\0'; + switch (style) + { + case PATH_UNIX: + ch = '/'; + break; + case PATH_WINDOWS: + ch = '\\'; + break; + case PATH_VMS: + ch = '.'; + break; + case PATH_NATIVE: + ch = separator(); + break; + default: + poco_bugcheck(); + } + + if (path.back() != ch) + { + return path + ch; + } + return path; +} + + std::string Path::self() { return PathImpl::selfImpl(); diff --git a/Foundation/testsuite/src/PathTest.cpp b/Foundation/testsuite/src/PathTest.cpp index 15cca8b6f..af42a0687 100644 --- a/Foundation/testsuite/src/PathTest.cpp +++ b/Foundation/testsuite/src/PathTest.cpp @@ -1502,6 +1502,40 @@ void PathTest::testForDirectory() p = Path::forDirectory("/usr/local/include/", Path::PATH_UNIX); assertTrue (p.toString(Path::PATH_UNIX) == "/usr/local/include/"); + + p = Path::forDirectory("C:", Path::PATH_WINDOWS); + assertTrue (p.toString(Path::PATH_WINDOWS) == "C:\\"); + + p = Path::forDirectory("C:\\", Path::PATH_WINDOWS); + assertTrue (p.toString(Path::PATH_WINDOWS) == "C:\\"); + + p = Path::forDirectory("C:\\abc", Path::PATH_WINDOWS); + assertTrue (p.toString(Path::PATH_WINDOWS) == "C:\\abc\\"); + + p = Path::forDirectory("C:\\abc\\", Path::PATH_WINDOWS); + assertTrue (p.toString(Path::PATH_WINDOWS) == "C:\\abc\\"); +} + + +void PathTest::testAddDirectorySeparator() +{ + std::string path = Path::addDirectorySeparator("C:", Path::PATH_WINDOWS); + assertTrue (path == "C:\\"); + + path = Path::addDirectorySeparator("C:\\", Path::PATH_WINDOWS); + assertTrue (path == "C:\\"); + + path = Path::addDirectorySeparator("C:\\abc", Path::PATH_WINDOWS); + assertTrue (path == "C:\\abc\\"); + + path = Path::addDirectorySeparator("C:\\abc\\", Path::PATH_WINDOWS); + assertTrue (path == "C:\\abc\\"); + + path = Path::addDirectorySeparator("/usr/local/include", Path::PATH_UNIX); + assertTrue (path == "/usr/local/include/"); + + path = Path::addDirectorySeparator("/usr/local/include/", Path::PATH_UNIX); + assertTrue (path == "/usr/local/include/"); } @@ -1675,6 +1709,7 @@ CppUnit::Test* PathTest::suite() CppUnit_addTest(pSuite, PathTest, testRobustness); CppUnit_addTest(pSuite, PathTest, testParent); CppUnit_addTest(pSuite, PathTest, testForDirectory); + CppUnit_addTest(pSuite, PathTest, testAddDirectorySeparator); CppUnit_addTest(pSuite, PathTest, testExpand); CppUnit_addTest(pSuite, PathTest, testListRoots); CppUnit_addTest(pSuite, PathTest, testFind); diff --git a/Foundation/testsuite/src/PathTest.h b/Foundation/testsuite/src/PathTest.h index f05f224b4..d29336693 100644 --- a/Foundation/testsuite/src/PathTest.h +++ b/Foundation/testsuite/src/PathTest.h @@ -45,6 +45,7 @@ public: void testRobustness(); void testParent(); void testForDirectory(); + void testAddDirectorySeparator(); void testExpand(); void testListRoots(); void testFind();