lexically_normal.pass.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. //===----------------------------------------------------------------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is dual licensed under the MIT and the University of Illinois Open
  6. // Source Licenses. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. // UNSUPPORTED: c++98, c++03
  10. // <experimental/filesystem>
  11. // class path
  12. // path lexically_normal() const;
  13. #include "filesystem_include.hpp"
  14. #include <type_traits>
  15. #include <vector>
  16. #include <iostream>
  17. #include <cassert>
  18. #include "test_macros.h"
  19. #include "test_iterators.h"
  20. #include "count_new.hpp"
  21. #include "filesystem_test_helper.hpp"
  22. int main() {
  23. // clang-format off
  24. struct {
  25. std::string input;
  26. std::string expect;
  27. } TestCases[] = {
  28. {"", ""},
  29. {"/a/b/c", "/a/b/c"},
  30. {"/a/b//c", "/a/b/c"},
  31. {"foo/./bar/..", "foo/"},
  32. {"foo/.///bar/../", "foo/"},
  33. {"/a/b/", "/a/b/"},
  34. {"a/b", "a/b"},
  35. {"a/b/.", "a/b/"},
  36. {"a/b/./", "a/b/"},
  37. {"a/..", "."},
  38. {".", "."},
  39. {"./", "."},
  40. {"./.", "."},
  41. {"./..", ".."},
  42. {"..", ".."},
  43. {"../..", "../.."},
  44. {"/../", "/"},
  45. {"/../..", "/"},
  46. {"/../../", "/"},
  47. {"..", ".."},
  48. {"../", ".."},
  49. {"/a/b/c/../", "/a/b/"},
  50. {"/a/b/./", "/a/b/"},
  51. {"/a/b/c/../d", "/a/b/d"},
  52. {"/a/b/c/../d/", "/a/b/d/"},
  53. {"//a/", "/a/"},
  54. {"//a/b/", "/a/b/"},
  55. {"//a/b/.", "/a/b/"},
  56. {"//a/..", "/"},
  57. ///===---------------------------------------------------------------===//
  58. /// Tests specifically for the clauses under [fs.path.generic]p6
  59. ///===---------------------------------------------------------------===//
  60. // p1: If the path is empty, stop.
  61. {"", ""},
  62. // p2: Replace each slash character in the root-name with a preferred
  63. // separator.
  64. {"NO_ROOT_NAME_ON_LINUX", "NO_ROOT_NAME_ON_LINUX"},
  65. // p3: Replace each directory-separator with a preferred-separator.
  66. // [ Note: The generic pathname grammar ([fs.path.generic]) defines
  67. // directory-separator as one or more slashes and preferred-separators.
  68. // — end note ]
  69. {"/", "/"},
  70. {"//", "/"},
  71. {"///", "/"},
  72. {"a/b", "a/b"},
  73. {"a//b", "a/b"},
  74. {"a///b", "a/b"},
  75. {"a/b/", "a/b/"},
  76. {"a/b//", "a/b/"},
  77. {"a/b///", "a/b/"},
  78. {"///a////b//////", "/a/b/"},
  79. // p4: Remove each dot filename and any immediately following directory
  80. // separators
  81. {"foo/.", "foo/"},
  82. {"foo/./bar/.", "foo/bar/"},
  83. {"./foo/././bar/./", "foo/bar/"},
  84. {".///foo//.////./bar/.///", "foo/bar/"},
  85. // p5: As long as any appear, remove a non-dot-dot filename immediately
  86. // followed by a directory-separator and a dot-dot filename, along with
  87. // any immediately following directory separator.
  88. {"foo/..", "."},
  89. {"foo/../", "."},
  90. {"foo/bar/..", "foo/"},
  91. {"foo/bar/../", "foo/"},
  92. {"foo/bar/../..", "."},
  93. {"foo/bar/../../", "."},
  94. {"foo/bar/baz/../..", "foo/"},
  95. {"foo/bar/baz/../../", "foo/"},
  96. {"foo/bar/./..", "foo/"},
  97. {"foo/bar/./../", "foo/"},
  98. // p6: If there is a root-directory, remove all dot-dot filenames and any
  99. // directory-separators immediately following them. [ Note: These dot-dot
  100. // filenames attempt to refer to nonexistent parent directories. — end note ]
  101. {"/..", "/"},
  102. {"/../", "/"},
  103. {"/foo/../..", "/"},
  104. {"/../foo", "/foo"},
  105. {"/../foo/../..", "/"},
  106. // p7: If the last filename is dot-dot, remove any trailing
  107. // directory-separator.
  108. {"../", ".."},
  109. {"../../", "../.."},
  110. {"foo/../bar/../..///", ".."},
  111. {"foo/../bar/..//..///../", "../.."},
  112. // p8: If the path is empty, add a dot
  113. {".", "."},
  114. {"./", "."},
  115. {"foo/..", "."}
  116. };
  117. // clang-format on
  118. int ID = 0;
  119. bool Failed = false;
  120. for (auto& TC : TestCases) {
  121. ++ID;
  122. fs::path p(TC.input);
  123. const fs::path output = p.lexically_normal();
  124. if (!PathEq(output, TC.expect)) {
  125. Failed = true;
  126. std::cerr << "TEST CASE #" << ID << " FAILED: \n";
  127. std::cerr << " Input: '" << TC.input << "'\n";
  128. std::cerr << " Expected: '" << TC.expect << "'\n";
  129. std::cerr << " Output: '" << output.native() << "'";
  130. std::cerr << std::endl;
  131. }
  132. }
  133. return Failed;
  134. }