Fix filesystem::path::lexically_normal algorithm
authorJonathan Wakely <jwakely@redhat.com>
Wed, 25 Oct 2017 12:42:53 +0000 (13:42 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Wed, 25 Oct 2017 12:42:53 +0000 (13:42 +0100)
* src/filesystem/std-path.cc (path::lexically_normal): Add missing
step to algorithm, for removing dot-dot elements after root-directory.
* testsuite/27_io/filesystem/operations/canonical.cc: Use
compare_paths for more exhaustive checks.
* testsuite/27_io/filesystem/operations/proximate.cc: Likewise.
* testsuite/27_io/filesystem/path/append/path.cc: Likewise.
* testsuite/27_io/filesystem/path/concat/path.cc: Likewise.
* testsuite/27_io/filesystem/path/concat/strings.cc: Fix comment.
* testsuite/27_io/filesystem/path/construct/locale.cc: Likewise.
* testsuite/27_io/filesystem/path/decompose/root_directory.cc:
Likewise.
* testsuite/27_io/filesystem/path/generation/normal.cc: Use
compare_paths for more exhaustive checks. Add extra testcases.
* testsuite/27_io/filesystem/path/generation/proximate.cc: Use
compare_paths for more exhaustive checks.
* testsuite/27_io/filesystem/path/generation/relative.cc: Likewise.
* testsuite/27_io/filesystem/path/generic/generic_string.cc: Remove
unused header.
* testsuite/27_io/filesystem/path/modifiers/make_preferred.cc: Fix
comment.
* testsuite/27_io/filesystem/path/modifiers/remove_filename.cc: Use
compare_paths for more exhaustive checks.
* testsuite/27_io/filesystem/path/modifiers/replace_extension.cc:
Likewise.
* testsuite/27_io/filesystem/path/modifiers/replace_filename.cc:
Likewise.
* testsuite/util/testsuite_fs.h (compare_paths): Also compare native
strings.

From-SVN: r254075

18 files changed:
libstdc++-v3/ChangeLog
libstdc++-v3/src/filesystem/std-path.cc
libstdc++-v3/testsuite/27_io/filesystem/operations/canonical.cc
libstdc++-v3/testsuite/27_io/filesystem/operations/proximate.cc
libstdc++-v3/testsuite/27_io/filesystem/path/append/path.cc
libstdc++-v3/testsuite/27_io/filesystem/path/concat/path.cc
libstdc++-v3/testsuite/27_io/filesystem/path/concat/strings.cc
libstdc++-v3/testsuite/27_io/filesystem/path/construct/locale.cc
libstdc++-v3/testsuite/27_io/filesystem/path/decompose/root_directory.cc
libstdc++-v3/testsuite/27_io/filesystem/path/generation/normal.cc
libstdc++-v3/testsuite/27_io/filesystem/path/generation/proximate.cc
libstdc++-v3/testsuite/27_io/filesystem/path/generation/relative.cc
libstdc++-v3/testsuite/27_io/filesystem/path/generic/generic_string.cc
libstdc++-v3/testsuite/27_io/filesystem/path/modifiers/make_preferred.cc
libstdc++-v3/testsuite/27_io/filesystem/path/modifiers/remove_filename.cc
libstdc++-v3/testsuite/27_io/filesystem/path/modifiers/replace_extension.cc
libstdc++-v3/testsuite/27_io/filesystem/path/modifiers/replace_filename.cc
libstdc++-v3/testsuite/util/testsuite_fs.h

index dadec85c093f86b6e4d5de93ece68de8c92a0d88..5a694c74675a7e38abdcda02eef010c802d493b0 100644 (file)
@@ -1,5 +1,34 @@
 2017-10-25  Jonathan Wakely  <jwakely@redhat.com>
 
+       * src/filesystem/std-path.cc (path::lexically_normal): Add missing
+       step to algorithm, for removing dot-dot elements after root-directory.
+       * testsuite/27_io/filesystem/operations/canonical.cc: Use
+       compare_paths for more exhaustive checks.
+       * testsuite/27_io/filesystem/operations/proximate.cc: Likewise.
+       * testsuite/27_io/filesystem/path/append/path.cc: Likewise.
+       * testsuite/27_io/filesystem/path/concat/path.cc: Likewise.
+       * testsuite/27_io/filesystem/path/concat/strings.cc: Fix comment.
+       * testsuite/27_io/filesystem/path/construct/locale.cc: Likewise.
+       * testsuite/27_io/filesystem/path/decompose/root_directory.cc:
+       Likewise.
+       * testsuite/27_io/filesystem/path/generation/normal.cc: Use
+       compare_paths for more exhaustive checks. Add extra testcases.
+       * testsuite/27_io/filesystem/path/generation/proximate.cc: Use
+       compare_paths for more exhaustive checks.
+       * testsuite/27_io/filesystem/path/generation/relative.cc: Likewise.
+       * testsuite/27_io/filesystem/path/generic/generic_string.cc: Remove
+       unused header.
+       * testsuite/27_io/filesystem/path/modifiers/make_preferred.cc: Fix
+       comment.
+       * testsuite/27_io/filesystem/path/modifiers/remove_filename.cc: Use
+       compare_paths for more exhaustive checks.
+       * testsuite/27_io/filesystem/path/modifiers/replace_extension.cc:
+       Likewise.
+       * testsuite/27_io/filesystem/path/modifiers/replace_filename.cc:
+       Likewise.
+       * testsuite/util/testsuite_fs.h (compare_paths): Also compare native
+       strings.
+
        PR libstdc++/82706
        * testsuite/27_io/filesystem/operations/permissions.cc: Fix test.
 
index b5dd36d6ad1876f0b6f4e700bacf200f02b994b1..1e2a8fad584ad322d99337fc56bb9f63291fa5cc 100644 (file)
@@ -365,6 +365,8 @@ path::lexically_normal() const
   - As long as any appear, remove a non-dot-dot filename immediately followed
     by a directory-separator and a dot-dot filename, along with any immediately
     following directory-separator.
+  - If there is a root-directory, remove all dot-dot filenames and any
+    directory-separators immediately following them.
   - If the last filename is dot-dot, remove any trailing directory-separator.
   - If the path is empty, add a dot.
   */
@@ -388,7 +390,7 @@ path::lexically_normal() const
        {
          if (ret.has_filename() && !is_dotdot(ret.filename()))
            ret.remove_filename();
-         else
+         else if (ret.has_filename() || !ret.has_root_directory())
            ret /= p;
        }
       else if (is_dot(p))
index 646c37c4c3ccffd0c7944a383342bab55a174f97..47305a8f5273179274955a932b4d0b57f0488c4c 100644 (file)
@@ -24,6 +24,7 @@
 #include <testsuite_fs.h>
 
 namespace fs = std::filesystem;
+using __gnu_test::compare_paths;
 
 void
 test01()
@@ -36,42 +37,42 @@ test01()
 
   create_directory(p);
   auto p2 = canonical( p, ec );
-  VERIFY( p2 == fs::current_path()/p );
+  compare_paths( p2, fs::current_path()/p );
   VERIFY( !ec );
 
   ec = bad_ec;
   p2 = canonical( fs::current_path() / "." / (p.native() + "////././."), ec );
-  VERIFY( p2 == fs::current_path()/p );
+  compare_paths( p2, fs::current_path()/p );
   VERIFY( !ec );
 
   ec = bad_ec;
   p = fs::current_path();
   p2 = canonical( p, ec );
-  VERIFY( p2 == p );
+  compare_paths( p2, p );
   VERIFY( !ec );
 
   ec = bad_ec;
   p = "/";
   p = canonical( p, ec );
-  VERIFY( p == "/" );
+  compare_paths( p, "/" );
   VERIFY( !ec );
 
   ec = bad_ec;
   p = "/.";
   p = canonical( p, ec );
-  VERIFY( p == "/" );
+  compare_paths( p, "/" );
   VERIFY( !ec );
 
   ec = bad_ec;
   p = "/..";
   p = canonical( p, ec );
-  VERIFY( p == "/" );
+  compare_paths( p, "/" );
   VERIFY( !ec );
 
   ec = bad_ec;
   p = "/../.././.";
   p = canonical( p, ec );
-  VERIFY( p == "/" );
+  compare_paths( p, "/" );
   VERIFY( !ec );
 }
 
@@ -115,17 +116,17 @@ test03()
   auto barc = canonical(bar);
 
   auto p1 = fs::canonical(dir/"foo//.///..//./");
-  VERIFY( p1 == dirc );
+  compare_paths( p1, dirc );
   auto p2 = fs::canonical(dir/"foo//./baz///..//./");
-  VERIFY( p2 == dirc );
+  compare_paths( p2, dirc );
   auto p3 = fs::canonical(dir/"foo//./baz////./");
-  VERIFY( p3 == barc );
+  compare_paths( p3, barc );
   auto p4 = fs::canonical(dir/"foo//./baz///..//./bar");
-  VERIFY( p4 == barc );
+  compare_paths( p4, barc );
   auto p5 = fs::canonical(dir/"foo//./baz///..//./bar/");
-  VERIFY( p5 == p4 );
+  compare_paths( p5, p4 );
   auto p6 = fs::canonical(dir/"foo//./baz///..//./bar/.");
-  VERIFY( p6 == p4 );
+  compare_paths( p6, p4 );
 
   remove_all(dir);
 }
index 02da2507d4636c4ea66c5befe46726163f83880a..99b6568abeb5c9e3cd88e78b1fb3a1865b7c1d53 100644 (file)
 
 #include <filesystem>
 #include <testsuite_hooks.h>
+#include <testsuite_fs.h>
 
 using std::filesystem::proximate;
+using __gnu_test::compare_paths;
 
 void
 test01()
 {
-  VERIFY( proximate("/a/d", "/a/b/c") == "../../d" );
-  VERIFY( proximate("/a/b/c", "/a/d") == "../b/c" );
-  VERIFY( proximate("a/b/c", "a") == "b/c" );
-  VERIFY( proximate("a/b/c", "a/b/c/x/y") == "../.." );
-  VERIFY( proximate("a/b/c", "a/b/c") == "." );
-  VERIFY( proximate("a/b", "c/d") == "../../a/b" );
+  compare_paths( proximate("/a/d", "/a/b/c"), "../../d" );
+  compare_paths( proximate("/a/b/c", "/a/d"), "../b/c" );
+  compare_paths( proximate("a/b/c", "a"), "b/c" );
+  compare_paths( proximate("a/b/c", "a/b/c/x/y"), "../.." );
+  compare_paths( proximate("a/b/c", "a/b/c"), "." );
+  compare_paths( proximate("a/b", "c/d"), "../../a/b" );
 }
 
 void
@@ -40,22 +42,22 @@ test02()
 {
   const std::error_code bad_ec = make_error_code(std::errc::invalid_argument);
   std::error_code ec = bad_ec;
-  VERIFY( proximate("/a/d", "/a/b/c", ec) == "../../d" );
+  compare_paths( proximate("/a/d", "/a/b/c", ec), "../../d" );
   VERIFY( !ec );
   ec = bad_ec;
-  VERIFY( proximate("/a/b/c", "/a/d", ec) == "../b/c" );
+  compare_paths( proximate("/a/b/c", "/a/d", ec), "../b/c" );
   VERIFY( !ec );
   ec = bad_ec;
-  VERIFY( proximate("a/b/c", "a", ec) == "b/c" );
+  compare_paths( proximate("a/b/c", "a", ec), "b/c" );
   VERIFY( !ec );
   ec = bad_ec;
-  VERIFY( proximate("a/b/c", "a/b/c/x/y", ec) == "../.." );
+  compare_paths( proximate("a/b/c", "a/b/c/x/y", ec), "../.." );
   VERIFY( !ec );
   ec = bad_ec;
-  VERIFY( proximate("a/b/c", "a/b/c", ec) == "." );
+  compare_paths( proximate("a/b/c", "a/b/c", ec), "." );
   VERIFY( !ec );
   ec = bad_ec;
-  VERIFY( proximate("a/b", "c/d", ec) == "../../a/b" );
+  compare_paths( proximate("a/b", "c/d", ec), "../../a/b" );
   VERIFY( !ec );
 }
 
index 64c638ed1e395c6a153080d8c02bdd6759841158..0942d6fdf7e12d034665a3823b1c6b5df6d4cbea 100644 (file)
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// 8.4.3 path appends [path.append]
+// 30.10.7.4.3 path appends [fs.path.append]
 
 #include <filesystem>
 #include <testsuite_hooks.h>
 #include <testsuite_fs.h>
 
 using std::filesystem::path;
+using __gnu_test::compare_paths;
 
 void
 test01()
@@ -34,16 +35,16 @@ test01()
 
   path pp = p;
   pp /= p;
-  VERIFY( pp.native() == p.native() );
+  compare_paths( pp, p );
 
   path q("baz");
 
   path qq = q;
   qq /= q;
-  VERIFY( qq.native() == "baz/baz" );
+  compare_paths( qq, "baz/baz" );
 
   q /= p;
-  VERIFY( q.native() == p.native() );
+  compare_paths( q, p );
 
   path r = "";
   r /= path();
@@ -54,11 +55,11 @@ test01()
 
   path s = "dir/";
   s /= path("/file");
-  VERIFY( s.native() == "/file" );
+  compare_paths( s, "/file" );
 
   s = "dir/";
   s /= path("file");
-  VERIFY( s.native() == "dir/file" );
+  compare_paths( s, "dir/file" );
 }
 
 void
@@ -67,16 +68,16 @@ test02()
   // C++17 [fs.path.append] p4
 
   path p = path("//host") / "foo";
-  VERIFY( p == "//host/foo" );
+  compare_paths( p, "//host/foo" );
 
   path pp = path("//host/") / "foo";
-  VERIFY( pp == "//host/foo" );
+  compare_paths( pp, "//host/foo" );
 
   path q = path("foo") / "";
-  VERIFY( q == "foo/" );
+  compare_paths( q, "foo/" );
 
   path qq = path("foo") / "/bar";
-  VERIFY( qq == "/bar" );
+  compare_paths( qq, "/bar" );
 }
 
 int
index 46cf09abe164f9ca59c501512a06d50e9e6a971c..1a987c1966b4c6d1a7fdf2765d02db930efd041b 100644 (file)
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// 8.4.4 path concatenation [path.concat]
+// 30.10.7.4.4 path concatenation [fs.path.concat]
 
 #include <filesystem>
 #include <testsuite_hooks.h>
 #include <testsuite_fs.h>
 
 using std::filesystem::path;
+using __gnu_test::compare_paths;
 
 void
 test01()
@@ -34,19 +35,16 @@ test01()
 
   path pp = p;
   pp += p;
-  VERIFY( pp.native() == "/foo/bar/foo/bar" );
-  VERIFY( std::distance(pp.begin(), pp.end()) == 5 );
+  compare_paths( pp, "/foo/bar/foo/bar" );
 
   path q("foo/bar");
 
   path qq = q;
   qq += q;
-  VERIFY( qq.native() == "foo/barfoo/bar" );
-  VERIFY( std::distance(qq.begin(), qq.end()) == 3 );
+  compare_paths( qq, "foo/barfoo/bar" );
 
   q += p;
-  VERIFY( q.native() == "foo/bar/foo/bar" );
-  VERIFY( std::distance(q.begin(), q.end()) == 4 );
+  compare_paths( q, "foo/bar/foo/bar" );
 }
 
 void
index 3eb4d1a3cb1af8027df2170d3126bf662f8eaa4a..8d298f8a57d7328b26105f793a0c0e2ae76a1d61 100644 (file)
@@ -19,7 +19,7 @@
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// 8.4.4 path concatenation [path.concat]
+// 30.10.7.4.4 path concatenation [fs.path.concat]
 
 #include <filesystem>
 #include <testsuite_hooks.h>
index e313412386d175f07ad1c00d3ef7d7b532a9b416..8bbff810652c043dc69e29b5f1f5ddbd9dab4648 100644 (file)
@@ -19,7 +19,7 @@
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// 8.4.1 path constructors [path.construct]
+// 30.10.7.4.1 path constructors [fs.path.construct]
 
 #include <filesystem>
 #include <testsuite_hooks.h>
@@ -30,7 +30,7 @@ void
 test01()
 {
   path p("/foo/bar", std::locale::classic());
-  VERIFY( p.string() == "/foo/bar" );
+  VERIFY( p.native() == "/foo/bar" );
 }
 
 int
index 8220c589efcf037c5695b4dcf283063dced24eca..8cd1976a9469610e14d3ade2e43f4efe958c1674 100644 (file)
@@ -19,7 +19,7 @@
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// 8.4.9 path decomposition [path.decompose]
+// 30.10.7.4.9 path decomposition [fs.path.decompose]
 
 #include <filesystem>
 #include <testsuite_hooks.h>
index 2e4ec5bc98ed7a6c389da82111698de57cd54d4a..789ce186f82a8eeb4c5baba94ebc2b306cb7bccc 100644 (file)
 // { dg-require-filesystem-ts "" }
 
 #include <filesystem>
+#include <testsuite_fs.h>
 #include <testsuite_hooks.h>
 
 using std::filesystem::path;
+using __gnu_test::compare_paths;
 
 void
 test01()
 {
   // C++17 [fs.path.gen] p2
-  VERIFY( path("foo/./bar/..").lexically_normal() == "foo/" );
-  VERIFY( path("foo/.///bar/../").lexically_normal() == "foo/" );
+  compare_paths( path("foo/./bar/..").lexically_normal(), "foo/" );
+  compare_paths( path("foo/.///bar/../").lexically_normal(), "foo/" );
 }
 
 void
 test02()
 {
-  VERIFY( path("foo/../bar").lexically_normal() == "bar" );
-  VERIFY( path("../foo/../bar").lexically_normal() == "../bar" );
-  VERIFY( path("foo/../").lexically_normal() == "." );
-  VERIFY( path("../../").lexically_normal() == "../.." );
-  VERIFY( path("../").lexically_normal() == ".." );
-  VERIFY( path("./").lexically_normal() == "." );
-  VERIFY( path().lexically_normal() == "" );
+  compare_paths( path("foo/../bar").lexically_normal(), "bar" );
+  compare_paths( path("../foo/../bar").lexically_normal(), "../bar" );
+  compare_paths( path("foo/../").lexically_normal(), "." );
+  compare_paths( path("../../").lexically_normal(), "../.." );
+  compare_paths( path("../").lexically_normal(), ".." );
+  compare_paths( path("./").lexically_normal(), "." );
+  compare_paths( path().lexically_normal(), "" );
+
+  compare_paths( path("/..").lexically_normal(), "/" );
+}
+
+void
+test03()
+{
+  struct
+  {
+    const char* input;
+    const char* normalized;
+  } testcases[] = {
+    {""            , "" },
+    {"."           , "."  },
+    {".."          , ".." },
+    {"/"           , "/" },
+    {"//"          , "//" },
+
+    {"/foo"        , "/foo" },
+    {"/foo/"       , "/foo/" },
+    {"/foo/."      , "/foo/" },
+    {"/foo/bar/.." , "/foo/" },
+    {"/foo/.."     , "/" },
+
+    {"/."          , "/" },
+    {"/./"         , "/" },
+    {"/./."        , "/" },
+    {"/././"       , "/" },
+    {"/././."      , "/" },
+
+    {"./"          , "." },
+    {"./."         , "." },
+    {"././"        , "." },
+    {"././."       , "." },
+    {"./././"      , "." },
+    {"./././."     , "." },
+
+    {"foo/.."      , "." },
+    {"foo/../"     , "." },
+    {"foo/../.."   , ".." },
+
+    // with root name (OS-dependent):
+#if defined(_WIN32) && !defined(__CYGWIN__)
+    {"C:bar/.."    , "C:." },
+#else
+    {"C:bar/.."    , "." },
+#endif
+    {"C:/bar/.."   , "C:/" },
+    {"C:"          , "C:" },
+#ifdef __CYGWIN__
+    {"//host/bar/.." , "//host/" },
+    {"//host"        , "//host" },
+#else
+    {"//host/bar/.." , "/host/" },
+    {"//host"        , "/host" },
+#endif
+
+    // a few others:
+    {"foo/../foo/.."   , "." },
+    {"foo/../foo/../.."   , ".." },
+    {"../foo/../foo/.."   , ".." },
+    {"../.f/../f"   , "../f" },
+    {"../f/../.f"   , "../.f" },
+    {".././../."    , "../.." },
+    {".././.././"   , "../.." },
+    {"/.."          , "/" },
+  };
+  for (auto& test : testcases)
+    compare_paths( path(test.input).lexically_normal(), test.normalized );
 }
 
 int
@@ -49,4 +120,5 @@ main()
 {
   test01();
   test02();
+  test03();
 }
index 7a25f7b417d92340568e6633e4c1945a3654b88e..ee77e16d1f82d79891cd322085a0e33fe89e4c5b 100644 (file)
 
 #include <filesystem>
 #include <testsuite_hooks.h>
+#include <testsuite_fs.h>
 
 using std::filesystem::path;
+using __gnu_test::compare_paths;
 
 void
 test01()
 {
   // C++17 [fs.path.gen] p5
-  VERIFY( path("/a/d").lexically_proximate("/a/b/c") == "../../d" );
-  VERIFY( path("/a/b/c").lexically_proximate("/a/d") == "../b/c" );
-  VERIFY( path("a/b/c").lexically_proximate("a") == "b/c" );
-  VERIFY( path("a/b/c").lexically_proximate("a/b/c/x/y") == "../.." );
-  VERIFY( path("a/b/c").lexically_proximate("a/b/c") == "." );
-  VERIFY( path("a/b").lexically_proximate("c/d") == "../../a/b" );
+  compare_paths( path("/a/d").lexically_proximate("/a/b/c"), "../../d" );
+  compare_paths( path("/a/b/c").lexically_proximate("/a/d"), "../b/c" );
+  compare_paths( path("a/b/c").lexically_proximate("a"), "b/c" );
+  compare_paths( path("a/b/c").lexically_proximate("a/b/c/x/y"), "../.." );
+  compare_paths( path("a/b/c").lexically_proximate("a/b/c"), "." );
+  compare_paths( path("a/b").lexically_proximate("c/d"), "../../a/b" );
 }
 
 void
 test02()
 {
   path p = "a/b/c";
-  VERIFY( p.lexically_proximate(p) == "." );
-  VERIFY( p.lexically_proximate("a/../a/b/../b/c/../c/.") == "../../b/c" );
-  VERIFY( p.lexically_proximate("../../../") == p );
+  compare_paths( p.lexically_proximate(p), "." );
+  compare_paths( p.lexically_proximate("a/../a/b/../b/c/../c/."), "../../b/c" );
+  compare_paths( p.lexically_proximate("../../../"), p );
 }
 
 int
index 64770fb1fe53d8f803b6f4b89cd0d1419d22a179..3e78344a6186c3e66369a6ab6de6d2adfd46cd69 100644 (file)
 
 #include <filesystem>
 #include <testsuite_hooks.h>
+#include <testsuite_fs.h>
 
 using std::filesystem::path;
+using __gnu_test::compare_paths;
 
 void
 test01()
 {
   // C++17 [fs.path.gen] p5
-  VERIFY( path("/a/d").lexically_relative("/a/b/c") == "../../d" );
-  VERIFY( path("/a/b/c").lexically_relative("/a/d") == "../b/c" );
-  VERIFY( path("a/b/c").lexically_relative("a") == "b/c" );
-  VERIFY( path("a/b/c").lexically_relative("a/b/c/x/y") == "../.." );
-  VERIFY( path("a/b/c").lexically_relative("a/b/c") == "." );
-  VERIFY( path("a/b").lexically_relative("c/d") == "../../a/b" );
+  compare_paths( path("/a/d").lexically_relative("/a/b/c"), "../../d" );
+  compare_paths( path("/a/b/c").lexically_relative("/a/d"), "../b/c" );
+  compare_paths( path("a/b/c").lexically_relative("a"), "b/c" );
+  compare_paths( path("a/b/c").lexically_relative("a/b/c/x/y"), "../.." );
+  compare_paths( path("a/b/c").lexically_relative("a/b/c"), "." );
+  compare_paths( path("a/b").lexically_relative("c/d"), "../../a/b" );
 }
 
 void
 test02()
 {
   path p = "a/b/c";
-  VERIFY( p.lexically_relative(p) == "." );
-  VERIFY( p.lexically_relative("a/../a/b/../b/c/../c/.") == "../../b/c" );
-  VERIFY( p.lexically_relative("../../../") == "" );
+  compare_paths( p.lexically_relative(p), "." );
+  compare_paths( p.lexically_relative("a/../a/b/../b/c/../c/."), "../../b/c" );
+  compare_paths( p.lexically_relative("../../../"), "" );
 }
 
 int
index d25d5056c607320183187a9cdc3c5d2c89bea187..78224339b42517f7f91a137c8ca872e9118f95af 100644 (file)
@@ -22,7 +22,6 @@
 // C++17 30.10.7.4.7 path generic format observers [fs.path.generic.obs]
 
 #include <filesystem>
-#include <testsuite_fs.h>
 #include <testsuite_hooks.h>
 
 using std::filesystem::path;
index 1df10093777e26ea55f8318b8aac1003576989b3..6e306a41c2b7891ee8b68358ff0a95d63c0bbe3e 100644 (file)
@@ -19,7 +19,7 @@
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// 8.4.5 path modifiers [path.modifiers]
+// 30.10.7.4.5 path modifiers [fs.path.modifiers]
 
 #include <filesystem>
 #include <testsuite_fs.h>
index 02e1b05cd411c5909b89d1e620da4ccfbc431ce4..cb764cd158560c568b7c8d275508f662d2ec3e2a 100644 (file)
 #include <testsuite_hooks.h>
 
 using std::filesystem::path;
+using __gnu_test::compare_paths;
 
 void
 test01()
 {
   // C++17 [fs.path.modifiers] p8
-  VERIFY( path("foo/bar").remove_filename() == "foo/" );
-  VERIFY( path("foo/").remove_filename()    == "foo/" );
-  VERIFY( path("/foo").remove_filename()    == "/" );
-  VERIFY( path("/").remove_filename()       == "/" );
+  compare_paths( path("foo/bar").remove_filename(), "foo/" );
+  compare_paths( path("foo/").remove_filename()   , "foo/" );
+  compare_paths( path("/foo").remove_filename()   , "/" );
+  compare_paths( path("/").remove_filename()      , "/" );
 }
 
-#undef VERIFY
-#define VERIFY(X) do { if (!(X)) { __builtin_puts("FAIL: " #X); } } while(false)
-#define DUMP(X, Y) do { if (!(X == Y)) { __builtin_printf("%s %s\n", X.c_str(), Y.c_str()); } } while(false)
-
 void
 test02()
 {
@@ -49,8 +46,7 @@ test02()
     path p2(p);
     p2.remove_filename();
     p2 /= p.filename();
-    VERIFY( p2 == p );
-    DUMP( p2 , p );
+    compare_paths( p2, p );
   }
 }
 
index cf7ca094c0f7874c7531fe24d08ee592e443cc62..fca189ce040542a028b3c9896fcc9b5d895d7a3b 100644 (file)
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// 8.4.5 path modifiers [path.modifiers]
+// 30.10.7.4.5 path modifiers [fs.path.modifiers]
 
 #include <filesystem>
 #include <testsuite_fs.h>
 #include <testsuite_hooks.h>
 
 using std::filesystem::path;
+using __gnu_test::compare_paths;
 
 void
 test01()
 {
-  VERIFY( path("/foo.txt").replace_extension("cpp") == "/foo.cpp" );
-  VERIFY( path("/foo.txt").replace_extension(".cpp") == "/foo.cpp" );
-  VERIFY( path("/").replace_extension("bar") == "/.bar" );
+  compare_paths( path("/foo.txt").replace_extension("cpp"), "/foo.cpp" );
+  compare_paths( path("/foo.txt").replace_extension(".cpp"), "/foo.cpp" );
+  compare_paths( path("/").replace_extension("bar"), "/.bar" );
 }
 
 void
@@ -41,7 +42,7 @@ test02()
   for (const path& p : __gnu_test::test_paths)
   {
     path p2 = p;
-    VERIFY(p2.replace_extension(p2.extension()) == p);
+    compare_paths( p2.replace_extension(p2.extension()), p );
   }
 }
 
index 6d3b9b70d079dd04926e870f8ee3ea1ea083a10e..d5c36565aca667959c811bf696d71f85eb6912ac 100644 (file)
 #include <testsuite_hooks.h>
 
 using std::filesystem::path;
+using __gnu_test::compare_paths;
 
 void
 test01()
 {
   // C++17 [fs.path.modifiers] p11
-  VERIFY( path("/foo").replace_filename("bar") == "/bar" );
-  VERIFY( path("/").replace_filename("bar")    == "/bar" );
+  compare_paths( path("/foo").replace_filename("bar"), "/bar" );
+  compare_paths( path("/").replace_filename("bar")   , "/bar" );
 }
 
-#undef VERIFY
-#define VERIFY(X) do { if (!(X)) { __builtin_puts("FAIL: " #X); } } while(false)
-#define DUMP(X, Y) do { if (!(X == Y)) { __builtin_printf("%s %s\n", X.c_str(), Y.c_str()); } } while(false)
-
 void
 test02()
 {
@@ -46,8 +43,7 @@ test02()
   {
     path p2(p);
     p2.replace_filename(p.filename());
-    VERIFY( p2 == p );
-    DUMP( p2 , p );
+    compare_paths( p2, p );
   }
 }
 
index e0db46ca1560b4cff72d6182c4c956e7d798dd35..47f56090b4755772709cc35d3a646f43f8558da1 100644 (file)
@@ -47,6 +47,7 @@ namespace __gnu_test
   compare_paths(const test_fs::path& p1,
                const test_fs::path& p2)
   {
+    PATH_CHK( p1, p2, native );
     PATH_CHK( p1, p2, string );
     PATH_CHK( p1, p2, empty );
     PATH_CHK( p1, p2, has_root_path );