Commit Graph

393 Commits

Author SHA1 Message Date
Andrey Semashev
84f70b0a2a Added a new test case for absolute() with UNC path on Windows. 2022-12-03 00:01:40 +03:00
Andrey Semashev
5d4c1caaab Added basic path compare tests. 2022-08-31 23:15:53 +03:00
Andrey Semashev
b219d9fb8a Added support for string views and boost::container::string.
Path traits and relevant path members were reworked to better support
wider range of types that are compatible with path constructors, assignment
and appending members. Added support for C++17 std::string_view,
boost::string_view and boost::container::string as the possible string
types accepted by path members.

Also extended support for types convertible to one of the string types.
Previously, user's type had to be convertible to a string with a character
type that matches the native path character type. Now all supported character
types are acceptable.

Additionally, restricted members accepting a pair of iterators to only accept
iterators whose value types are one of the supported path character types.

Lastly, path::compare and comparison operators now only accept path arguments,
relying on path conversion constructors to do the job of supporting various
source types. Also removed noexcept from compare as it is using lex_compare
and iterators internally and those can throw.

Closes https://github.com/boostorg/filesystem/issues/208.
2022-08-31 09:52:30 +03:00
Andrey Semashev
054b842a58 Added a test for path construction/assignment/appending from a custom string.
This should test path compatibility with user-defined custom string-like types,
including string views.
2022-08-21 19:06:42 +03:00
Andrey Semashev
349daee54b Moved path_traits.hpp to detail.
The public path_traits.hpp header is deprecated and will be removed. Its
contents are path implementation details and are now in detail.
2022-08-21 18:45:59 +03:00
Andrey Semashev
2e9e66e843 Marked previously deprecated APIs with attributes to generate warnings.
The warnings can be suppressed by defining BOOST_FILESYSTEM_ALLOW_DEPRECATED
macro when compiling user's code.
2022-08-14 19:52:38 +03:00
Andrey Semashev
d829a46b31 Deprecated path construction/assignment/appending from container types.
Users are advised to use string types and iterators instead of containers
to construct/assign/append to paths.

In v4, the support for containers is removed.
2022-08-14 19:14:42 +03:00
Andrey Semashev
1c4e1c01a6 Added a few tests involving Windows long paths. 2022-08-10 01:06:57 +03:00
Andrey Semashev
7cd11c770b Moved header that is used in tests to tests. 2022-07-07 23:34:35 +03:00
Andrey Semashev
a187a9f10f Added symlink_status test for a system directory. 2022-05-09 20:04:23 +03:00
Andrey Semashev
4bdac43bd9 Use GetFileAttributesW in symlink_status if CreateFileW fails.
For some system files and folders like "System Volume Information"
CreateFileW fails with ERROR_ACCESS_DENIED while GetFileAttributesW
succeeds. GetFileAttributesW doesn't allow to discover whether the
file is a symlink or some other kind of a reparse point, so this
fallback will only work for files that are not reparse points,
symlinks or not. For reparse points continue to report error.

Closes https://github.com/boostorg/filesystem/issues/234.
2022-05-09 20:00:50 +03:00
Andrey Semashev
f7930053c8 Corrected error handling and aded checks for exceptions. 2022-02-21 14:38:20 +03:00
Andrey Semashev
266e1ac892 Moved string_file.hpp tests to deprecated tests.
Turns out string_file.hpp was tested in operations_unit_test, though not
included directly. Since string_file.hpp contents are disabled when the
test is compiled (as any other deprecated functionality), the test failed
to compile.

Moved the string_file.hpp test to deprecated_test, which explicitly enables
deprecated functionality. Also, include string_file.hpp in filesystem.hpp
if explicitly requested by defining BOOST_FILESYSTEM_DEPRECATED.
2022-02-08 22:45:52 +03:00
Andrey Semashev
7edd9eb612 Use explicit operator+= and operator/= overloads for path and string types.
This is necessary to allow to pass arguments convertible to path and
compatible string types to these operators.

Fixes https://github.com/boostorg/filesystem/issues/223.
2021-12-23 14:06:43 +03:00
Andrey Semashev
fb3992a7df Added path concatenation tests. 2021-12-23 13:38:26 +03:00
Andrey Semashev
18a8a3430d Added support for removing read-only files on Windows.
Reworked remove() operation to separate POSIX and Windows implementations.
On Windows, if the file to be removed is read-only, try to reset the read-only
attribute before deleting the file. If deleting fails (other than because the
file is already deleted), try to restore the read-only attribute.

As a side effect, we were able to remove an implementation detail value from
the file_type enum that was used by the old remove() implementation.

Added a test for remove() on a read-only file on Windows. Also added tests
for remove_all(), including for cases with symlinks, hardlinks and read-only
files.

Also, corrected mklink /J argument in tests. The command accepts /j (lowercase)
to the same effect, but the formal help lists /J (uppercase) to create junctions.

Reported in https://github.com/boostorg/filesystem/issues/216.
2021-11-18 14:54:17 +03:00
Andrey Semashev
0307f58a8b Don't append trailing dot in lexically_normal, convert separators in root name.
In v4 path::lexically_normal, don't generate a trailing dot element if the
original path ends with a directory separator or dot. Also omit the trailing
directory separator the normalized path ends with a dot-dot element.

Additionally, convert directory separators to preferred separators in
root name on Windows (in v3 and v4). This may be significant for UNC paths.
2021-11-06 03:57:50 +03:00
Andrey Semashev
0aee13c162 Append a trailing directory separator when appending an empty path in v4.
If the source path ends with a non-empty filename, and the appended path
is empty, C++17 std::filesystem requires to add a trailing directory
separator.
2021-11-06 00:31:19 +03:00
Andrey Semashev
cc763cb48e Reworked absolute() to fix appending root directory.
Because of the changed semantics of appending operations in v4, path
composition in absolute() would produce incorrect results because at some
point it would append root directory and therefore discard root name
that was potentially added before. The updated implementation fixes that,
and also fixes the case when the input path is already absolute and
starts with a root directory, and the base path has a root name.
Previously, the returned path would contain the root name from the
base path, while the correct thing to do is to return the input path
as is.
2021-11-05 23:41:31 +03:00
Andrey Semashev
0d413a5e4f Changed v4 path appends for absolute appended paths to match C++17.
Appending an absolute path now results in assigning the path, as
specified in C++17. This change is made for consistency with C++
and other languages that implement path manipulation (e.g. Python).
2021-11-05 23:40:57 +03:00
Andrey Semashev
ecbab750b2 Construct paths in BOOST_TEST_EQ macros from string literals.
This works around lightweight_test bug that it doesn't print C strings
in case of test failures.

Related to https://github.com/boostorg/core/issues/91.
2021-11-05 19:08:38 +03:00
Andrey Semashev
d13461be0f Implemented root-aware path appending in v4.
In Boost.Filesystem v3 path appending mostly worked as a slight upgrade
of concatenation, where appending would only add directory separators
when necessary, but not consider semantics of the root name and root
directory of the appended paths. This would work well for relative paths,
but produce unexpected results for paths with root names.

In v4, we now implement appending that is aware of root name and directory
of the appendedn paths. This means that appending a path with a root name
and/or directory no longer concatenates the paths, but rather rebases the
appended path on top of the source path. In particular, if the appended path
has a root name different from the source path, the append operation will
act as assignment.

This is closer to C++20 std::filesystem but not exactly the same. The
difference is for the case when the appended path is absolute. The C++20
spec requires assignment in this case, Boost.Filesystem v4 deliberately
omits this check. This is to ensure the correct result for UNC paths on
POSIX systems, where "//net/foo" / "/bar" is expected to produce "//net/bar",
not "/bar".

As part of this work, refactored path constructors and operators for more
optimal implementation and reducing the number of overloads.

Closes https://github.com/boostorg/filesystem/issues/214.
2021-11-05 02:21:55 +03:00
Andrey Semashev
667f785e93 Disable deprecated CRT warnings on Windows also in tests. 2021-10-26 20:06:48 +03:00
Andrey Semashev
fc2da43e81 Stop testing exception message contents.
The contents is (a) language dependent and (b) is modified by some
standard libraries (e.g. libstdc++ and Dinkumware) and possibly OS,
which causes test failures on AppVeyor.
2021-10-17 22:54:58 +03:00
Andrey Semashev
3a323cae2d Removed implicit trailing dot element of the path in v4.
When the path ends with a non-root directory separator, no longer
produce a trailing dot element (filename). Instead, return an empty
path.

This affects not only path iterators and path::filename, but also any
other APIs that rely on them.

Closes https://github.com/boostorg/filesystem/issues/193.
2021-10-17 21:40:19 +03:00
Andrey Semashev
b4c39093cc Reimplemented create_directories for compatibility with v4 paths.
The new implementation is prepared for the removal of the implicit
trailing dots in v4 path. It also no longer uses recursion
internally and therefore is better protected against stack overflows.

As a side effect of this rewrite, create_directories no longer reports
error if the input path consists entirely of dot and dot-dot elements.
This is in line with C++20 std::filesystem behavior.
2021-10-17 21:38:28 +03:00
Andrey Semashev
6c3e0bc75d Disable create_directories test that depends on user permissions.
One of the create_directories tests depends on the function failing
to create directories in the root directory. This normally fails
when the tests run under a normal user, but not when running as
root, which is the case when running GitHub Actions in a container.
2021-09-05 22:25:04 +03:00
Andrey Semashev
87d3c1fd8a Fix weakly_canonical on Windows if the path contains non-existing elements.
Windows APIs such as GetFileAttributesW perform lexical path normalization
internally, which means e.g. "C:\a\.." resolves to an existing path
even if "C:\a" doesn't. This breaks depection of the longest sequence
of existing path elements in weakly_canonical and results in an error
in canonical that is called on that sequence.

As a workaround, perform forward iteration on Windows, so that we
stop on the first path element that doesn't exist.

Also, while at it, corrected error code reported from weakly_canonical
when status fails with an error.

Closes https://github.com/boostorg/filesystem/issues/201.
2021-07-28 20:05:17 +03:00
Andrey Semashev
d418858839 Convert root dir to preferred separator in path::lexically_normal.
This is consistent with std::filesystem and behavior before
16bd89b7c0.

Closes https://github.com/boostorg/filesystem/issues/200.
2021-07-20 11:42:55 +03:00
Andrey Semashev
ac9d62346f Fixed path_test_v3 on Windows 2021-06-13 13:48:15 +03:00
Andrey Semashev
7339882ccf Added BOOST_FILESYSTEM_VERSION 4 and moved breaking path changes to v4.
Boost.Filesystem v4 will contain breaking changes from v3 that are required
for better compatibility with C++17 std::filesystem. It will also remove
the deprecated features of v3.

Updated docs to reflect the differences between v3 and v4. Updated tests
to verify both v3 and v4 where the differences are present.
2021-06-13 03:20:30 +03:00
Andrey Semashev
60e908dfcf Don't return root directory from path::filename().
This is a breaking change.

path::filename accessor now only returns the actual filename or the implied
trailing dot element of the path, if it ends with a separator other than
root directory. This makes boost::filesystem::path behavior closer to that
of std::filesystem::path.

Updated tests and docs accordingly.

Closes https://github.com/boostorg/filesystem/issues/194.
2021-06-10 03:49:30 +03:00
Andrey Semashev
29ef7d683d Reverted using std::filesystem::path to pass paths to file streams.
This doesn't compile with gcc 8 on MinGW-w64, and fails in runtime with
gcc 10.2 and clang 8.0.1 on Cygwin64 because character code conversion errors,
so basically std::filesystem never works with wide paths on Windows.

We still use wide paths as `const wchar_t*` with libc++ though.

Also, changed BOOST_FILESYSTEM_C_STR definition to accept the path as
an argument and use that definition in the tests rather than duplicating it.

Related to https://github.com/boostorg/filesystem/issues/181.
2021-06-09 18:28:28 +03:00
Andrey Semashev
915a5739be Made wide character concatenation more explicit. 2021-06-09 15:23:57 +03:00
Andrey Semashev
8328bb277b Treat filenames starting with a dot as filenames rather than extension.
Filenames starting with a dot (and no other dots) are commonly treated
as filenames with no extension rather than an extension. This is also
the behavior mandated in C++17 filesystem.

Reported in https://github.com/boostorg/filesystem/issues/88.
2021-06-06 18:31:41 +03:00
Andrey Semashev
c11764e38a Fixed path_test on POSIX systems. 2021-06-06 12:25:55 +03:00
Andrey Semashev
16bd89b7c0 Reworked path::lexically_normal to remove some redundant dot path elements.
The new implementation is also not relying on the root name format and
is more pertormant as it avoids unnecessarily copying path elements during
operation.

Note that this commit does not remove the trailing dot elements in the
normalized paths.
2021-06-05 23:34:49 +03:00
Andrey Semashev
4b84226783 Refactored path implementation for better support Windows path prefixes.
- Unified root name and root directory parsing that was scattered and
  duplicated across different algorithms. The new implementation is
  consolidated in a single function for parsing root name and root
  directory, which is used from various algorithms.

- The new root name parsing now supports Windows local device ("\\.\")
  and NT path ("\??\") prefixes. It also adds support for filesystem
  ("\\?\") prefix to some of the higher level algorithms that were
  using custom parsing previously. Tests updated to verify these prefixes.

- Some of the path decomposition methods were unified with presence checking
  methods (e.g. root_name with has_root_name). This makes these methods
  work consistently and also makes the has_* methods less expensive as
  they no longer have to construct a path only to check if it is empty.

- The filename accessor no longer returns root name if the whole path
  only consists of a root name. This also affects stem and extension as
  those accessors are based on filename. This is a breaking change.

- Cleaned up code:
  - Removed redundant checks for std::wstring support.
  - Added header/footer headers to globally disable compiler warnings.
  - Removed commented out super-deprecated code.
  - Added missing includes and removed includes that are not needed.
  - Nonessential code formatting.
2021-06-05 19:52:33 +03:00
Andrey Semashev
45606c2f23 Disable building examples in tests by default. 2021-05-20 23:39:06 +03:00
Andrey Semashev
d5360cf925 Added copy_sile tests for multi-stream files on Windows. 2021-05-20 23:33:31 +03:00
Andrey Semashev
4849b6c506 Added building examples in CI. 2021-05-19 03:19:08 +03:00
Andrey Semashev
2accecc330 Removed machine-specific scripts that are not used anymore. 2021-05-19 03:19:08 +03:00
Andrey Semashev
8dbb31f686 Removed files with test results. 2021-05-19 03:19:08 +03:00
Andrey Semashev
87181d517d Removed MSVC projects as they are not maintained. 2021-05-19 03:19:08 +03:00
Andrey Semashev
88c2a2df8c Check the source filesystem type before using sendfile/copy_file_range.
Some filesystems have regular files with generated content. Such files have
arbitrary size, including zero, but have actual content. Linux system calls
sendfile or copy_file_range will not copy contents of such files, so we must
use a read/write loop to handle them.

Check the type of the source filesystem before using sendfile or
copy_file_range and fallback to the read/write loop if it matches one of
the blacklisted filesystems: procfs, sysfs, tracefs or debugfs.

Also, added a test to verify that copy_file works on procfs.
2021-05-19 01:43:22 +03:00
Andrey Semashev
e320bfaa01 Added tests for copy_options::synchronize(_data). 2021-05-17 21:52:46 +03:00
Andrey Semashev
1b27455cb2 Removed unused variables in path_unit_test. 2021-04-24 23:59:24 +03:00
Andrey Semashev
c03249c375 Reformatted code for more consistent look and better readability. 2021-04-24 22:37:57 +03:00
Andrey Semashev
cc57d28995 Fixed an exception being thrown by path::remove_filename if the path is "////".
Also added tests verifying the case.

Fixes https://github.com/boostorg/filesystem/issues/176.
2021-02-26 14:51:04 +03:00
Andrey Semashev
cc13e916f9 Added pauses in creation_time_tests to avoid spurious failures on Windows.
Presumably, there's some sort of mismatch between times returned by time()
and file creation timestamps when converted to time_t, which can sometimes
result in a test failure. The pauses ensure there's enough distance
between start, finish and file creation timestamps for the discrepancy
to not matter. Also added debug output.
2020-12-23 10:55:00 +03:00