]> git.ipfire.org Git - thirdparty/gcc.git/blame_incremental - libstdc++-v3/testsuite/experimental/filesystem/iterators/recursive_directory_iterator.cc
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / experimental / filesystem / iterators / recursive_directory_iterator.cc
... / ...
CommitLineData
1// Copyright (C) 2015-2024 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 "-DUSE_FILESYSTEM_TS -lstdc++fs" }
19// { dg-do run { target c++11 } }
20// { dg-require-filesystem-ts "" }
21
22#include <experimental/filesystem>
23#include <testsuite_hooks.h>
24#include <testsuite_fs.h>
25
26namespace fs = std::experimental::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 != end(iter) );
60 VERIFY( iter->path() == p/"d1/d2" );
61 ++iter;
62 VERIFY( iter == end(iter) );
63
64 if (__gnu_test::permissions_are_testable())
65 {
66 // Test inaccessible directory.
67 ec = bad_ec;
68 permissions(p, fs::perms::none, ec);
69 VERIFY( !ec );
70 iter = fs::recursive_directory_iterator(p, ec);
71 VERIFY( ec );
72 VERIFY( iter == end(iter) );
73
74 // Test inaccessible directory, skipping permission denied.
75 const auto opts = fs::directory_options::skip_permission_denied;
76 ec = bad_ec;
77 iter = fs::recursive_directory_iterator(p, opts, ec);
78 VERIFY( !ec );
79 VERIFY( iter == end(iter) );
80
81 // Test inaccessible sub-directory.
82 ec = bad_ec;
83 permissions(p, fs::perms::owner_all, ec);
84 VERIFY( !ec );
85 ec = bad_ec;
86 permissions(p/"d1/d2", fs::perms::none, ec);
87 VERIFY( !ec );
88 ec = bad_ec;
89 iter = fs::recursive_directory_iterator(p, ec);
90 VERIFY( !ec );
91 VERIFY( iter != end(iter) );
92 VERIFY( iter->path() == p/"d1" );
93 ++iter; // should recurse into d1
94 VERIFY( iter != end(iter) );
95 VERIFY( iter->path() == p/"d1/d2" );
96 iter.increment(ec); // should fail to recurse into p/d1/d2
97 VERIFY( ec );
98 VERIFY( iter == end(iter) );
99
100 // Test inaccessible sub-directory, skipping permission denied.
101 ec = bad_ec;
102 iter = fs::recursive_directory_iterator(p, opts, ec);
103 VERIFY( !ec );
104 VERIFY( iter != end(iter) );
105 VERIFY( iter->path() == p/"d1" );
106 ++iter; // should recurse into d1
107 VERIFY( iter->path() == p/"d1/d2" );
108 ec = bad_ec;
109 iter.increment(ec); // should fail to recurse into p/d1/d2, so skip it
110 VERIFY( !ec );
111 VERIFY( iter == end(iter) );
112
113 permissions(p/"d1/d2", fs::perms::owner_all, ec);
114 }
115
116 remove_all(p, ec);
117}
118
119void
120test02()
121{
122 const std::error_code bad_ec = make_error_code(std::errc::invalid_argument);
123 std::error_code ec;
124 const auto p = __gnu_test::nonexistent_path();
125 ec = bad_ec;
126 create_directories(p / "d1/d2", ec);
127 VERIFY( !ec );
128
129 // Test post-increment (libstdc++/71005)
130 ec = bad_ec;
131 auto iter = fs::recursive_directory_iterator(p, ec);
132 VERIFY( !ec );
133 VERIFY( iter != end(iter) );
134 const auto entry1 = *iter;
135 const auto entry2 = *iter++;
136 VERIFY( entry1 == entry2 );
137 VERIFY( entry1.path() == p/"d1" );
138 const auto entry3 = *iter;
139 const auto entry4 = *iter++;
140 VERIFY( entry3 == entry4 );
141 VERIFY( entry3.path() == p/"d1/d2" );
142 VERIFY( iter == end(iter) );
143
144 remove_all(p, ec);
145}
146
147void
148test03()
149{
150 std::error_code ec = make_error_code(std::errc::invalid_argument);
151 const auto p = __gnu_test::nonexistent_path();
152 create_directories(p / "longer_than_small_string_buffer", ec);
153 VERIFY( !ec );
154
155 // Test for no reallocation on each dereference (this is a GNU extension)
156 auto iter = fs::recursive_directory_iterator(p, ec);
157 const auto* s1 = iter->path().c_str();
158 const auto* s2 = iter->path().c_str();
159 VERIFY( s1 == s2 );
160
161 remove_all(p, ec);
162}
163
164void
165test04()
166{
167 // libstdc++/71004
168 const fs::recursive_directory_iterator it;
169 VERIFY( it == end(it) );
170}
171
172void
173test05()
174{
175 auto p = __gnu_test::nonexistent_path();
176 create_directory(p);
177 create_directory(p / "x");
178 fs::recursive_directory_iterator it(p), endit;
179 VERIFY( begin(it) == it );
180 static_assert( noexcept(begin(it)), "begin is noexcept" );
181 VERIFY( end(it) == endit );
182 static_assert( noexcept(end(it)), "end is noexcept" );
183
184 std::error_code ec;
185 remove_all(p, ec);
186}
187
188void
189test06()
190{
191#ifndef NO_SYMLINKS
192 auto p = __gnu_test::nonexistent_path();
193 create_directories(p/"d1/d2");
194 create_directory_symlink("d1", p/"link");
195 fs::recursive_directory_iterator it(p), endit;
196 VERIFY( std::distance(it, endit) == 3 ); // d1 and d2 and link
197
198 it = fs::recursive_directory_iterator(p, fs::directory_options::follow_directory_symlink);
199 VERIFY( std::distance(it, endit) == 4 ); // d1 and d1/d2 and link and link/d2
200
201 std::error_code ec;
202 remove_all(p, ec);
203#endif
204}
205
206int
207main()
208{
209 test01();
210 test02();
211 test03();
212 test04();
213 test05();
214 test06();
215}