]>
Commit | Line | Data |
---|---|---|
de4db54f | 1 | // { dg-options "-std=gnu++17" } |
641cb5a6 JW |
2 | // { dg-do run { target c++17 } } |
3 | // { dg-require-filesystem-ts "" } | |
4 | ||
99dee823 | 5 | // Copyright (C) 2014-2021 Free Software Foundation, Inc. |
641cb5a6 JW |
6 | // |
7 | // This file is part of the GNU ISO C++ Library. This library is free | |
8 | // software; you can redistribute it and/or modify it under the | |
9 | // terms of the GNU General Public License as published by the | |
10 | // Free Software Foundation; either version 3, or (at your option) | |
11 | // any later version. | |
12 | ||
13 | // This library is distributed in the hope that it will be useful, | |
14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | // GNU General Public License for more details. | |
17 | ||
18 | // You should have received a copy of the GNU General Public License along | |
19 | // with this library; see the file COPYING3. If not see | |
20 | // <http://www.gnu.org/licenses/>. | |
21 | ||
22 | // 15.3 Copy [fs.op.copy] | |
23 | ||
24 | #include <filesystem> | |
25 | #include <testsuite_fs.h> | |
26 | #include <testsuite_hooks.h> | |
27 | ||
28 | namespace fs = std::filesystem; | |
29 | ||
30 | // Test error conditions. | |
31 | void | |
32 | test01() | |
33 | { | |
34 | auto p = __gnu_test::nonexistent_path(); | |
35 | std::error_code ec; | |
36 | ||
37 | VERIFY( !fs::exists(p) ); | |
38 | fs::copy(p, ".", fs::copy_options::none, ec); | |
39 | VERIFY( ec ); | |
40 | ||
41 | ec.clear(); | |
42 | fs::copy(".", ".", fs::copy_options::none, ec); | |
43 | VERIFY( ec ); | |
44 | ||
45 | __gnu_test::scoped_file f(p); | |
46 | VERIFY( fs::is_directory(".") ); | |
47 | VERIFY( fs::is_regular_file(p) ); | |
48 | ec.clear(); | |
49 | fs::copy(".", p, fs::copy_options::none, ec); | |
50 | VERIFY( ec ); | |
51 | ||
52 | auto to = __gnu_test::nonexistent_path(); | |
53 | ec.clear(); | |
54 | auto opts = fs::copy_options::create_symlinks; | |
55 | fs::copy("/", to, opts, ec); | |
56 | VERIFY( ec == std::make_error_code(std::errc::is_a_directory) ); | |
57 | VERIFY( !exists(to) ); | |
58 | ||
59 | ec.clear(); | |
9412b35a | 60 | opts |= fs::copy_options::recursive; |
641cb5a6 JW |
61 | fs::copy("/", to, opts, ec); |
62 | VERIFY( ec == std::make_error_code(std::errc::is_a_directory) ); | |
63 | VERIFY( !exists(to) ); | |
64 | } | |
65 | ||
66 | // Test is_symlink(f) case. | |
67 | void | |
68 | test02() | |
69 | { | |
edfe833a JW |
70 | #if defined(__MINGW32__) || defined(__MINGW64__) |
71 | // No symlink support | |
72 | return; | |
73 | #endif | |
74 | ||
641cb5a6 JW |
75 | const std::error_code bad_ec = make_error_code(std::errc::invalid_argument); |
76 | auto from = __gnu_test::nonexistent_path(); | |
77 | auto to = __gnu_test::nonexistent_path(); | |
78 | std::error_code ec; | |
79 | ||
80 | ec = bad_ec; | |
81 | fs::create_symlink(".", from, ec); | |
82 | VERIFY( !ec ); | |
83 | VERIFY( fs::exists(from) ); | |
84 | ||
85 | ec = bad_ec; | |
86 | fs::copy(from, to, fs::copy_options::skip_symlinks, ec); | |
87 | VERIFY( !ec ); | |
88 | VERIFY( !fs::exists(to) ); | |
89 | ||
90 | ec = bad_ec; | |
91 | fs::copy(from, to, fs::copy_options::skip_symlinks, ec); | |
92 | VERIFY( !ec ); | |
93 | VERIFY( !fs::exists(to) ); | |
94 | ||
95 | ec = bad_ec; | |
96 | fs::copy(from, to, | |
97 | fs::copy_options::skip_symlinks|fs::copy_options::copy_symlinks, | |
98 | ec); | |
99 | VERIFY( !ec ); | |
100 | VERIFY( !fs::exists(to) ); | |
101 | ||
102 | ec = bad_ec; | |
103 | fs::copy(from, to, fs::copy_options::copy_symlinks, ec); | |
104 | VERIFY( !ec ); | |
105 | VERIFY( fs::exists(to) ); | |
106 | VERIFY( is_symlink(to) ); | |
107 | ||
108 | ec.clear(); | |
109 | fs::copy(from, to, fs::copy_options::copy_symlinks, ec); | |
110 | VERIFY( ec ); | |
111 | ||
112 | remove(from, ec); | |
113 | remove(to, ec); | |
114 | } | |
115 | ||
116 | // Test is_regular_file(f) case. | |
117 | void | |
118 | test03() | |
119 | { | |
120 | auto from = __gnu_test::nonexistent_path(); | |
121 | auto to = __gnu_test::nonexistent_path(); | |
122 | ||
123 | // test empty file | |
9534a5e6 | 124 | std::ofstream{from}; |
641cb5a6 JW |
125 | VERIFY( fs::exists(from) ); |
126 | VERIFY( fs::file_size(from) == 0 ); | |
127 | fs::copy(from, to); | |
128 | VERIFY( fs::exists(to) ); | |
129 | VERIFY( fs::file_size(to) == 0 ); | |
130 | ||
131 | remove(to); | |
132 | VERIFY( !fs::exists(to) ); | |
9534a5e6 | 133 | std::ofstream{from} << "Hello, filesystem!"; |
641cb5a6 JW |
134 | VERIFY( fs::file_size(from) != 0 ); |
135 | fs::copy(from, to); | |
136 | VERIFY( fs::exists(to) ); | |
137 | VERIFY( fs::file_size(to) == fs::file_size(from) ); | |
138 | ||
139 | remove(from); | |
140 | remove(to); | |
141 | } | |
142 | ||
143 | // Test is_directory(f) case. | |
144 | void | |
145 | test04() | |
146 | { | |
147 | const std::error_code bad_ec = make_error_code(std::errc::invalid_argument); | |
148 | auto from = __gnu_test::nonexistent_path(); | |
149 | auto to = __gnu_test::nonexistent_path(); | |
150 | std::error_code ec; | |
151 | ||
152 | create_directories(from/"a/b/c"); | |
153 | ||
154 | { | |
155 | __gnu_test::scoped_file f(to); | |
156 | copy(from, to, ec); | |
157 | VERIFY( ec ); | |
158 | } | |
159 | ||
160 | __gnu_test::scoped_file f1(from/"a/f1"); | |
161 | std::ofstream{f1.path} << "file one"; | |
162 | __gnu_test::scoped_file f2(from/"a/b/f2"); | |
163 | std::ofstream{f2.path} << "file two"; | |
164 | ||
165 | copy(from, to, ec); | |
166 | VERIFY( !ec ); | |
167 | VERIFY( exists(to) && is_empty(to) ); | |
168 | remove(to); | |
169 | ||
170 | ec = bad_ec; | |
171 | copy(from, to, fs::copy_options::recursive, ec); | |
172 | VERIFY( !ec ); | |
173 | VERIFY( exists(to) && !is_empty(to) ); | |
174 | VERIFY( is_regular_file(to/"a/f1") && !is_empty(to/"a/f1") ); | |
175 | VERIFY( file_size(from/"a/f1") == file_size(to/"a/f1") ); | |
176 | VERIFY( is_regular_file(to/"a/b/f2") && !is_empty(to/"a/b/f2") ); | |
177 | VERIFY( file_size(from/"a/b/f2") == file_size(to/"a/b/f2") ); | |
178 | VERIFY( is_directory(to/"a/b/c") && is_empty(to/"a/b/c") ); | |
179 | ||
180 | f1.path.clear(); | |
181 | f2.path.clear(); | |
182 | remove_all(from, ec); | |
183 | remove_all(to, ec); | |
184 | } | |
185 | ||
186 | // Test no-op cases. | |
187 | void | |
188 | test05() | |
189 | { | |
190 | auto to = __gnu_test::nonexistent_path(); | |
191 | std::error_code ec = std::make_error_code(std::errc::invalid_argument); | |
192 | ||
193 | fs::copy("/", to, fs::copy_options::copy_symlinks, ec); | |
194 | VERIFY( !ec ); // Previous value should be cleared (LWG 2683) | |
195 | } | |
196 | ||
197 | int | |
198 | main() | |
199 | { | |
200 | test01(); | |
201 | test02(); | |
202 | test03(); | |
203 | test04(); | |
204 | test05(); | |
205 | } |