]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/testsuite/27_io/filesystem/iterators/recursive_directory_iterator.cc
Implement C++17 Filesystem library
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / 27_io / filesystem / iterators / recursive_directory_iterator.cc
CommitLineData
641cb5a6
JW
1// Copyright (C) 2015-2017 Free Software Foundation, Inc.
2//
3// This file is part of the GNU ISO C++ Library. This library is free
4// software; you can redistribute it and/or modify it under the
5// terms of the GNU General Public License as published by the
6// Free Software Foundation; either version 3, or (at your option)
7// any later version.
8
9// This library is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License along
15// with this library; see the file COPYING3. If not see
16// <http://www.gnu.org/licenses/>.
17
18// { dg-options "-std=gnu++17 -lstdc++fs" }
19// { dg-do run { target c++17 } }
20// { dg-require-filesystem-ts "" }
21
22#include <filesystem>
23#include <testsuite_hooks.h>
24#include <testsuite_fs.h>
25
26namespace fs = std::filesystem;
27
28void
29test01()
30{
31 const std::error_code bad_ec = make_error_code(std::errc::invalid_argument);
32 std::error_code ec;
33
34 // Test non-existent path.
35 const auto p = __gnu_test::nonexistent_path();
36 fs::recursive_directory_iterator iter(p, ec);
37 VERIFY( ec );
38 VERIFY( iter == end(iter) );
39
40 // Test empty directory.
41 ec = bad_ec;
42 create_directory(p, fs::current_path(), ec);
43 VERIFY( !ec );
44 ec = bad_ec;
45 iter = fs::recursive_directory_iterator(p, ec);
46 VERIFY( !ec );
47 VERIFY( iter == end(iter) );
48
49 // Test non-empty directory.
50 ec = bad_ec;
51 create_directories(p / "d1/d2", ec);
52 VERIFY( !ec );
53 ec = bad_ec;
54 iter = fs::recursive_directory_iterator(p, ec);
55 VERIFY( !ec );
56 VERIFY( iter != end(iter) );
57 VERIFY( iter->path() == p/"d1" );
58 ++iter;
59 VERIFY( iter->path() == p/"d1/d2" );
60 ++iter;
61 VERIFY( iter == end(iter) );
62
63 // Test inaccessible directory.
64 ec = bad_ec;
65 permissions(p, fs::perms::none, ec);
66 VERIFY( !ec );
67 iter = fs::recursive_directory_iterator(p, ec);
68 VERIFY( ec );
69 VERIFY( iter == end(iter) );
70
71 // Test inaccessible directory, skipping permission denied.
72 const auto opts = fs::directory_options::skip_permission_denied;
73 iter = fs::recursive_directory_iterator(p, opts, ec);
74 VERIFY( !ec );
75 VERIFY( iter == end(iter) );
76
77 // Test inaccessible sub-directory.
78 ec = bad_ec;
79 permissions(p, fs::perms::owner_all, ec);
80 VERIFY( !ec );
81 ec = bad_ec;
82 permissions(p/"d1/d2", fs::perms::none, ec);
83 VERIFY( !ec );
84 ec = bad_ec;
85 iter = fs::recursive_directory_iterator(p, ec);
86 VERIFY( !ec );
87 VERIFY( iter != end(iter) );
88 VERIFY( iter->path() == p/"d1" );
89 ++iter; // should recurse into d1
90 VERIFY( iter->path() == p/"d1/d2" );
91 iter.increment(ec); // should fail to recurse into p/d1/d2
92 VERIFY( ec );
93 VERIFY( iter == end(iter) );
94
95 // Test inaccessible sub-directory, skipping permission denied.
96 ec = bad_ec;
97 iter = fs::recursive_directory_iterator(p, opts, ec);
98 VERIFY( !ec );
99 VERIFY( iter != end(iter) );
100 VERIFY( iter->path() == p/"d1" );
101 ++iter; // should recurse into d1
102 VERIFY( iter->path() == p/"d1/d2" );
103 ec = bad_ec;
104 iter.increment(ec); // should fail to recurse into p/d1/d2, so skip it
105 VERIFY( !ec );
106 VERIFY( iter == end(iter) );
107
108 permissions(p/"d1/d2", fs::perms::owner_all, ec);
109 remove_all(p, ec);
110}
111
112void
113test02()
114{
115 const std::error_code bad_ec = make_error_code(std::errc::invalid_argument);
116 std::error_code ec;
117 const auto p = __gnu_test::nonexistent_path();
118 ec = bad_ec;
119 create_directories(p / "d1/d2", ec);
120 VERIFY( !ec );
121
122 // Test post-increment (libstdc++/71005)
123 ec = bad_ec;
124 auto iter = fs::recursive_directory_iterator(p, ec);
125 VERIFY( !ec );
126 VERIFY( iter != end(iter) );
127 const auto entry1 = *iter;
128 const auto entry2 = *iter++;
129 VERIFY( entry1 == entry2 );
130 VERIFY( entry1.path() == p/"d1" );
131 const auto entry3 = *iter;
132 const auto entry4 = *iter++;
133 VERIFY( entry3 == entry4 );
134 VERIFY( entry3.path() == p/"d1/d2" );
135 VERIFY( iter == end(iter) );
136
137 remove_all(p, ec);
138}
139
140void
141test03()
142{
143 const std::error_code bad_ec = make_error_code(std::errc::invalid_argument);
144 std::error_code ec;
145 const auto p = __gnu_test::nonexistent_path();
146 ec = bad_ec;
147 create_directories(p / "longer_than_small_string_buffer", ec);
148 VERIFY( !ec );
149
150 // Test for no reallocation on each dereference (this is a GNU extension)
151 auto iter = fs::recursive_directory_iterator(p, ec);
152 const auto* s1 = iter->path().c_str();
153 const auto* s2 = iter->path().c_str();
154 VERIFY( s1 == s2 );
155
156 remove_all(p, ec);
157}
158
159void
160test04()
161{
162 // libstdc++/71004
163 const fs::recursive_directory_iterator it;
164 VERIFY( it == end(it) );
165}
166
167void
168test05()
169{
170 auto p = __gnu_test::nonexistent_path();
171 create_directory(p);
172 create_directory_symlink(p, p / "l");
173 fs::recursive_directory_iterator it(p), endit;
174 VERIFY( begin(it) == it );
175 static_assert( noexcept(begin(it)), "begin is noexcept" );
176 VERIFY( end(it) == endit );
177 static_assert( noexcept(end(it)), "end is noexcept" );
178}
179
180int
181main()
182{
183 test01();
184 test02();
185 test03();
186 test04();
187 test05();
188}