libcxx

libcxx mirror with random patches
git clone https://git.neptards.moe/neptards/libcxx.git
Log | Files | Refs

lexically_normal.pass.cpp (4463B)


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