diff options
author | thegeorg <thegeorg@yandex-team.com> | 2023-01-12 19:17:36 +0300 |
---|---|---|
committer | thegeorg <thegeorg@yandex-team.com> | 2023-01-12 19:17:36 +0300 |
commit | 4229f87c89bfb36eded667ec1e64f41b1aeb88b9 (patch) | |
tree | 9dd29a868ccac7990c4502957848ca07acd12ac6 | |
parent | b48a7948c3aec8c078a24714d4da420a6225d09f (diff) | |
download | ydb-4229f87c89bfb36eded667ec1e64f41b1aeb88b9.tar.gz |
Update contrib/restricted/boost/spirit to 1.81.0
48 files changed, 1 insertions, 14513 deletions
diff --git a/contrib/libs/linux-headers/linux/stat.h b/contrib/libs/linux-headers/linux/stat.h deleted file mode 100644 index 31bef96f03..0000000000 --- a/contrib/libs/linux-headers/linux/stat.h +++ /dev/null @@ -1,174 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -#ifndef _LINUX_STAT_H -#define _LINUX_STAT_H - -#include <linux/types.h> - -#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) - -#define S_IFMT 00170000 -#define S_IFSOCK 0140000 -#define S_IFLNK 0120000 -#define S_IFREG 0100000 -#define S_IFBLK 0060000 -#define S_IFDIR 0040000 -#define S_IFCHR 0020000 -#define S_IFIFO 0010000 -#define S_ISUID 0004000 -#define S_ISGID 0002000 -#define S_ISVTX 0001000 - -#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) -#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) -#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) -#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) -#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK) -#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) -#define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK) - -#define S_IRWXU 00700 -#define S_IRUSR 00400 -#define S_IWUSR 00200 -#define S_IXUSR 00100 - -#define S_IRWXG 00070 -#define S_IRGRP 00040 -#define S_IWGRP 00020 -#define S_IXGRP 00010 - -#define S_IRWXO 00007 -#define S_IROTH 00004 -#define S_IWOTH 00002 -#define S_IXOTH 00001 - -#endif - -/* - * Timestamp structure for the timestamps in struct statx. - * - * tv_sec holds the number of seconds before (negative) or after (positive) - * 00:00:00 1st January 1970 UTC. - * - * tv_nsec holds a number of nanoseconds (0..999,999,999) after the tv_sec time. - * - * __reserved is held in case we need a yet finer resolution. - */ -struct statx_timestamp { - __s64 tv_sec; - __u32 tv_nsec; - __s32 __reserved; -}; - -/* - * Structures for the extended file attribute retrieval system call - * (statx()). - * - * The caller passes a mask of what they're specifically interested in as a - * parameter to statx(). What statx() actually got will be indicated in - * st_mask upon return. - * - * For each bit in the mask argument: - * - * - if the datum is not supported: - * - * - the bit will be cleared, and - * - * - the datum will be set to an appropriate fabricated value if one is - * available (eg. CIFS can take a default uid and gid), otherwise - * - * - the field will be cleared; - * - * - otherwise, if explicitly requested: - * - * - the datum will be synchronised to the server if AT_STATX_FORCE_SYNC is - * set or if the datum is considered out of date, and - * - * - the field will be filled in and the bit will be set; - * - * - otherwise, if not requested, but available in approximate form without any - * effort, it will be filled in anyway, and the bit will be set upon return - * (it might not be up to date, however, and no attempt will be made to - * synchronise the internal state first); - * - * - otherwise the field and the bit will be cleared before returning. - * - * Items in STATX_BASIC_STATS may be marked unavailable on return, but they - * will have values installed for compatibility purposes so that stat() and - * co. can be emulated in userspace. - */ -struct statx { - /* 0x00 */ - __u32 stx_mask; /* What results were written [uncond] */ - __u32 stx_blksize; /* Preferred general I/O size [uncond] */ - __u64 stx_attributes; /* Flags conveying information about the file [uncond] */ - /* 0x10 */ - __u32 stx_nlink; /* Number of hard links */ - __u32 stx_uid; /* User ID of owner */ - __u32 stx_gid; /* Group ID of owner */ - __u16 stx_mode; /* File mode */ - __u16 __spare0[1]; - /* 0x20 */ - __u64 stx_ino; /* Inode number */ - __u64 stx_size; /* File size */ - __u64 stx_blocks; /* Number of 512-byte blocks allocated */ - __u64 stx_attributes_mask; /* Mask to show what's supported in stx_attributes */ - /* 0x40 */ - struct statx_timestamp stx_atime; /* Last access time */ - struct statx_timestamp stx_btime; /* File creation time */ - struct statx_timestamp stx_ctime; /* Last attribute change time */ - struct statx_timestamp stx_mtime; /* Last data modification time */ - /* 0x80 */ - __u32 stx_rdev_major; /* Device ID of special file [if bdev/cdev] */ - __u32 stx_rdev_minor; - __u32 stx_dev_major; /* ID of device containing file [uncond] */ - __u32 stx_dev_minor; - /* 0x90 */ - __u64 __spare2[14]; /* Spare space for future expansion */ - /* 0x100 */ -}; - -/* - * Flags to be stx_mask - * - * Query request/result mask for statx() and struct statx::stx_mask. - * - * These bits should be set in the mask argument of statx() to request - * particular items when calling statx(). - */ -#define STATX_TYPE 0x00000001U /* Want/got stx_mode & S_IFMT */ -#define STATX_MODE 0x00000002U /* Want/got stx_mode & ~S_IFMT */ -#define STATX_NLINK 0x00000004U /* Want/got stx_nlink */ -#define STATX_UID 0x00000008U /* Want/got stx_uid */ -#define STATX_GID 0x00000010U /* Want/got stx_gid */ -#define STATX_ATIME 0x00000020U /* Want/got stx_atime */ -#define STATX_MTIME 0x00000040U /* Want/got stx_mtime */ -#define STATX_CTIME 0x00000080U /* Want/got stx_ctime */ -#define STATX_INO 0x00000100U /* Want/got stx_ino */ -#define STATX_SIZE 0x00000200U /* Want/got stx_size */ -#define STATX_BLOCKS 0x00000400U /* Want/got stx_blocks */ -#define STATX_BASIC_STATS 0x000007ffU /* The stuff in the normal stat struct */ -#define STATX_BTIME 0x00000800U /* Want/got stx_btime */ -#define STATX_ALL 0x00000fffU /* All currently supported flags */ -#define STATX__RESERVED 0x80000000U /* Reserved for future struct statx expansion */ - -/* - * Attributes to be found in stx_attributes and masked in stx_attributes_mask. - * - * These give information about the features or the state of a file that might - * be of use to ordinary userspace programs such as GUIs or ls rather than - * specialised tools. - * - * Note that the flags marked [I] correspond to generic FS_IOC_FLAGS - * semantically. Where possible, the numerical value is picked to correspond - * also. - */ -#define STATX_ATTR_COMPRESSED 0x00000004 /* [I] File is compressed by the fs */ -#define STATX_ATTR_IMMUTABLE 0x00000010 /* [I] File is marked immutable */ -#define STATX_ATTR_APPEND 0x00000020 /* [I] File is append-only */ -#define STATX_ATTR_NODUMP 0x00000040 /* [I] File is not to be dumped */ -#define STATX_ATTR_ENCRYPTED 0x00000800 /* [I] File requires key to decrypt in fs */ -#define STATX_ATTR_AUTOMOUNT 0x00001000 /* Dir: Automount trigger */ -#define STATX_ATTR_VERITY 0x00100000 /* [I] Verity protected file */ - - -#endif /* _LINUX_STAT_H */ diff --git a/contrib/restricted/boost/CMakeLists.darwin.txt b/contrib/restricted/boost/CMakeLists.darwin.txt index e4950f30a9..ab559eeff5 100644 --- a/contrib/restricted/boost/CMakeLists.darwin.txt +++ b/contrib/restricted/boost/CMakeLists.darwin.txt @@ -31,7 +31,6 @@ add_subdirectory(detail) add_subdirectory(dynamic_bitset) add_subdirectory(endian) add_subdirectory(exception) -add_subdirectory(filesystem) add_subdirectory(foreach) add_subdirectory(format) add_subdirectory(function) diff --git a/contrib/restricted/boost/CMakeLists.linux-aarch64.txt b/contrib/restricted/boost/CMakeLists.linux-aarch64.txt index e1a8ada75b..3e9f371832 100644 --- a/contrib/restricted/boost/CMakeLists.linux-aarch64.txt +++ b/contrib/restricted/boost/CMakeLists.linux-aarch64.txt @@ -30,7 +30,6 @@ add_subdirectory(detail) add_subdirectory(dynamic_bitset) add_subdirectory(endian) add_subdirectory(exception) -add_subdirectory(filesystem) add_subdirectory(foreach) add_subdirectory(format) add_subdirectory(function) @@ -71,7 +70,6 @@ add_subdirectory(system) add_subdirectory(thread) add_subdirectory(throw_exception) add_subdirectory(tokenizer) -add_subdirectory(tti) add_subdirectory(tuple) add_subdirectory(type_index) add_subdirectory(type_traits) diff --git a/contrib/restricted/boost/CMakeLists.linux.txt b/contrib/restricted/boost/CMakeLists.linux.txt index e4950f30a9..ab559eeff5 100644 --- a/contrib/restricted/boost/CMakeLists.linux.txt +++ b/contrib/restricted/boost/CMakeLists.linux.txt @@ -31,7 +31,6 @@ add_subdirectory(detail) add_subdirectory(dynamic_bitset) add_subdirectory(endian) add_subdirectory(exception) -add_subdirectory(filesystem) add_subdirectory(foreach) add_subdirectory(format) add_subdirectory(function) diff --git a/contrib/restricted/boost/detail/include/boost/detail/bitmask.hpp b/contrib/restricted/boost/detail/include/boost/detail/bitmask.hpp deleted file mode 100644 index 63d4fac0c2..0000000000 --- a/contrib/restricted/boost/detail/include/boost/detail/bitmask.hpp +++ /dev/null @@ -1,58 +0,0 @@ -// boost/detail/bitmask.hpp ------------------------------------------------// - -// Copyright Beman Dawes 2006 - -// Distributed under the Boost Software License, Version 1.0 -// http://www.boost.org/LICENSE_1_0.txt - -// Usage: enum foo { a=1, b=2, c=4 }; -// BOOST_BITMASK( foo ) -// -// void f( foo arg ); -// ... -// f( a | c ); -// -// See [bitmask.types] in the C++ standard for the formal specification - -#ifndef BOOST_BITMASK_HPP -#define BOOST_BITMASK_HPP - -#include <boost/config.hpp> -#include <boost/cstdint.hpp> - -#define BOOST_BITMASK(Bitmask) \ - \ - inline BOOST_CONSTEXPR Bitmask operator| (Bitmask x , Bitmask y ) \ - { return static_cast<Bitmask>( static_cast<boost::int_least32_t>(x) \ - | static_cast<boost::int_least32_t>(y)); } \ - \ - inline BOOST_CONSTEXPR Bitmask operator& (Bitmask x , Bitmask y ) \ - { return static_cast<Bitmask>( static_cast<boost::int_least32_t>(x) \ - & static_cast<boost::int_least32_t>(y)); } \ - \ - inline BOOST_CONSTEXPR Bitmask operator^ (Bitmask x , Bitmask y ) \ - { return static_cast<Bitmask>( static_cast<boost::int_least32_t>(x) \ - ^ static_cast<boost::int_least32_t>(y)); } \ - \ - inline BOOST_CONSTEXPR Bitmask operator~ (Bitmask x ) \ - { return static_cast<Bitmask>(~static_cast<boost::int_least32_t>(x)); } \ - \ - inline Bitmask & operator&=(Bitmask& x , Bitmask y) \ - { x = x & y ; return x ; } \ - \ - inline Bitmask & operator|=(Bitmask& x , Bitmask y) \ - { x = x | y ; return x ; } \ - \ - inline Bitmask & operator^=(Bitmask& x , Bitmask y) \ - { x = x ^ y ; return x ; } \ - \ - /* Boost extensions to [bitmask.types] */ \ - \ - inline BOOST_CONSTEXPR bool operator!(Bitmask x) \ - { return !static_cast<int>(x); } \ - \ - inline BOOST_CONSTEXPR bool bitmask_set(Bitmask x) \ - { return !!x; } - -#endif // BOOST_BITMASK_HPP - diff --git a/contrib/restricted/boost/filesystem/CMakeLists.darwin.txt b/contrib/restricted/boost/filesystem/CMakeLists.darwin.txt deleted file mode 100644 index 167b59b73e..0000000000 --- a/contrib/restricted/boost/filesystem/CMakeLists.darwin.txt +++ /dev/null @@ -1,45 +0,0 @@ - -# This file was gererated by the build system used internally in the Yandex monorepo. -# Only simple modifications are allowed (adding source-files to targets, adding simple properties -# like target_include_directories). These modifications will be ported to original -# ya.make files by maintainers. Any complex modifications which can't be ported back to the -# original buildsystem will not be accepted. - - - -add_library(restricted-boost-filesystem) -target_compile_options(restricted-boost-filesystem PRIVATE - -DBOOST_FILESYSTEM_NO_CXX20_ATOMIC_REF - -Wno-everything -) -target_include_directories(restricted-boost-filesystem PUBLIC - ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/include -) -target_link_libraries(restricted-boost-filesystem PUBLIC - contrib-libs-cxxsupp - restricted-boost-assert - restricted-boost-atomic - restricted-boost-config - restricted-boost-container_hash - restricted-boost-core - restricted-boost-detail - restricted-boost-io - restricted-boost-iterator - restricted-boost-range - restricted-boost-smart_ptr - restricted-boost-static_assert - restricted-boost-system - restricted-boost-type_traits -) -target_sources(restricted-boost-filesystem PRIVATE - ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/codecvt_error_category.cpp - ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/directory.cpp - ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/exception.cpp - ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/operations.cpp - ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/path.cpp - ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/path_traits.cpp - ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/portability.cpp - ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/unique_path.cpp - ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/utf8_codecvt_facet.cpp - ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/windows_file_codecvt.cpp -) diff --git a/contrib/restricted/boost/filesystem/CMakeLists.linux-aarch64.txt b/contrib/restricted/boost/filesystem/CMakeLists.linux-aarch64.txt deleted file mode 100644 index 4bf37af7bf..0000000000 --- a/contrib/restricted/boost/filesystem/CMakeLists.linux-aarch64.txt +++ /dev/null @@ -1,49 +0,0 @@ - -# This file was gererated by the build system used internally in the Yandex monorepo. -# Only simple modifications are allowed (adding source-files to targets, adding simple properties -# like target_include_directories). These modifications will be ported to original -# ya.make files by maintainers. Any complex modifications which can't be ported back to the -# original buildsystem will not be accepted. - - - -add_library(restricted-boost-filesystem) -target_compile_options(restricted-boost-filesystem PUBLIC - -DBOOST_FILESYSTEM_HAS_POSIX_AT_APIS -) -target_compile_options(restricted-boost-filesystem PRIVATE - -DBOOST_FILESYSTEM_NO_CXX20_ATOMIC_REF - -Wno-everything -) -target_include_directories(restricted-boost-filesystem PUBLIC - ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/include -) -target_link_libraries(restricted-boost-filesystem PUBLIC - contrib-libs-linux-headers - contrib-libs-cxxsupp - restricted-boost-assert - restricted-boost-atomic - restricted-boost-config - restricted-boost-container_hash - restricted-boost-core - restricted-boost-detail - restricted-boost-io - restricted-boost-iterator - restricted-boost-range - restricted-boost-smart_ptr - restricted-boost-static_assert - restricted-boost-system - restricted-boost-type_traits -) -target_sources(restricted-boost-filesystem PRIVATE - ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/codecvt_error_category.cpp - ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/directory.cpp - ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/exception.cpp - ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/operations.cpp - ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/path.cpp - ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/path_traits.cpp - ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/portability.cpp - ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/unique_path.cpp - ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/utf8_codecvt_facet.cpp - ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/windows_file_codecvt.cpp -) diff --git a/contrib/restricted/boost/filesystem/CMakeLists.linux.txt b/contrib/restricted/boost/filesystem/CMakeLists.linux.txt deleted file mode 100644 index 4bf37af7bf..0000000000 --- a/contrib/restricted/boost/filesystem/CMakeLists.linux.txt +++ /dev/null @@ -1,49 +0,0 @@ - -# This file was gererated by the build system used internally in the Yandex monorepo. -# Only simple modifications are allowed (adding source-files to targets, adding simple properties -# like target_include_directories). These modifications will be ported to original -# ya.make files by maintainers. Any complex modifications which can't be ported back to the -# original buildsystem will not be accepted. - - - -add_library(restricted-boost-filesystem) -target_compile_options(restricted-boost-filesystem PUBLIC - -DBOOST_FILESYSTEM_HAS_POSIX_AT_APIS -) -target_compile_options(restricted-boost-filesystem PRIVATE - -DBOOST_FILESYSTEM_NO_CXX20_ATOMIC_REF - -Wno-everything -) -target_include_directories(restricted-boost-filesystem PUBLIC - ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/include -) -target_link_libraries(restricted-boost-filesystem PUBLIC - contrib-libs-linux-headers - contrib-libs-cxxsupp - restricted-boost-assert - restricted-boost-atomic - restricted-boost-config - restricted-boost-container_hash - restricted-boost-core - restricted-boost-detail - restricted-boost-io - restricted-boost-iterator - restricted-boost-range - restricted-boost-smart_ptr - restricted-boost-static_assert - restricted-boost-system - restricted-boost-type_traits -) -target_sources(restricted-boost-filesystem PRIVATE - ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/codecvt_error_category.cpp - ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/directory.cpp - ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/exception.cpp - ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/operations.cpp - ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/path.cpp - ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/path_traits.cpp - ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/portability.cpp - ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/unique_path.cpp - ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/utf8_codecvt_facet.cpp - ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/windows_file_codecvt.cpp -) diff --git a/contrib/restricted/boost/filesystem/CMakeLists.txt b/contrib/restricted/boost/filesystem/CMakeLists.txt deleted file mode 100644 index 3e0811fb22..0000000000 --- a/contrib/restricted/boost/filesystem/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ - -# This file was gererated by the build system used internally in the Yandex monorepo. -# Only simple modifications are allowed (adding source-files to targets, adding simple properties -# like target_include_directories). These modifications will be ported to original -# ya.make files by maintainers. Any complex modifications which can't be ported back to the -# original buildsystem will not be accepted. - - -if (CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" AND UNIX AND NOT APPLE AND NOT ANDROID) - include(CMakeLists.linux-aarch64.txt) -elseif (APPLE) - include(CMakeLists.darwin.txt) -elseif (CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND UNIX AND NOT APPLE AND NOT ANDROID) - include(CMakeLists.linux.txt) -endif() diff --git a/contrib/restricted/boost/filesystem/README.md b/contrib/restricted/boost/filesystem/README.md deleted file mode 100644 index 9af3f0140d..0000000000 --- a/contrib/restricted/boost/filesystem/README.md +++ /dev/null @@ -1,28 +0,0 @@ -# Boost.Filesystem - -Boost.Filesystem, part of collection of the [Boost C++ Libraries](https://github.com/boostorg), provides facilities to manipulate files and directories, and the paths that identify them. - -### Directories - -* **doc** - Documentation sources -* **include** - Interface headers of Boost.Filesystem -* **src** - Compilable source files of Boost.Filesystem -* **test** - Boost.Filesystem unit tests -* **example** - Boost.Filesystem usage examples - -### More information - -* [Documentation](https://boost.org/libs/filesystem) -* [Report bugs](https://github.com/boostorg/filesystem/issues/new). Be sure to mention Boost version, platform and compiler you're using. A small compilable code sample to reproduce the problem is always good as well. -* Submit your patches as [pull requests](https://github.com/boostorg/filesystem/compare) against **develop** branch. Note that by submitting patches you agree to license your modifications under the [Boost Software License, Version 1.0](https://www.boost.org/LICENSE_1_0.txt). - -### Build status - -Branch | GitHub Actions | AppVeyor | Test Matrix | Dependencies | -:-------------: | -------------- | -------- | ----------- | ------------ | -[`master`](https://github.com/boostorg/filesystem/tree/master) | [![GitHub Actions](https://github.com/boostorg/filesystem/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/boostorg/filesystem/actions?query=branch%3Amaster) | [![AppVeyor](https://ci.appveyor.com/api/projects/status/nx3e7bcavvn3q953/branch/master?svg=true)](https://ci.appveyor.com/project/Lastique/filesystem/branch/master) | [![Tests](https://img.shields.io/badge/matrix-master-brightgreen.svg)](http://www.boost.org/development/tests/master/developer/filesystem.html) | [![Dependencies](https://img.shields.io/badge/deps-master-brightgreen.svg)](https://pdimov.github.io/boostdep-report/master/filesystem.html) -[`develop`](https://github.com/boostorg/filesystem/tree/develop) | [![GitHub Actions](https://github.com/boostorg/filesystem/actions/workflows/ci.yml/badge.svg?branch=develop)](https://github.com/boostorg/filesystem/actions?query=branch%3Adevelop) | [![AppVeyor](https://ci.appveyor.com/api/projects/status/nx3e7bcavvn3q953/branch/develop?svg=true)](https://ci.appveyor.com/project/Lastique/filesystem/branch/develop) | [![Tests](https://img.shields.io/badge/matrix-develop-brightgreen.svg)](http://www.boost.org/development/tests/develop/developer/filesystem.html) | [![Dependencies](https://img.shields.io/badge/deps-develop-brightgreen.svg)](https://pdimov.github.io/boostdep-report/develop/filesystem.html) - -### License - -Distributed under the [Boost Software License, Version 1.0](https://www.boost.org/LICENSE_1_0.txt). diff --git a/contrib/restricted/boost/filesystem/include/boost/filesystem/config.hpp b/contrib/restricted/boost/filesystem/include/boost/filesystem/config.hpp deleted file mode 100644 index 68d0557fb4..0000000000 --- a/contrib/restricted/boost/filesystem/include/boost/filesystem/config.hpp +++ /dev/null @@ -1,125 +0,0 @@ -// boost/filesystem/v3/config.hpp ----------------------------------------------------// - -// Copyright Beman Dawes 2003 -// Copyright Andrey Semashev 2021 - -// Distributed under the Boost Software License, Version 1.0. -// See http://www.boost.org/LICENSE_1_0.txt - -// Library home page: http://www.boost.org/libs/filesystem - -//--------------------------------------------------------------------------------------// - -#ifndef BOOST_FILESYSTEM_CONFIG_HPP -#define BOOST_FILESYSTEM_CONFIG_HPP - -// This header implements separate compilation features as described in -// http://www.boost.org/more/separate_compilation.html - -#include <boost/config.hpp> -#include <boost/system/api_config.hpp> // for BOOST_POSIX_API or BOOST_WINDOWS_API -#include <boost/detail/workaround.hpp> - -#if defined(BOOST_FILESYSTEM_VERSION) && BOOST_FILESYSTEM_VERSION != 3 && BOOST_FILESYSTEM_VERSION != 4 -#error Compiling Boost.Filesystem file with BOOST_FILESYSTEM_VERSION defined != 3 or 4 -#endif - -#if defined(BOOST_FILESYSTEM_SOURCE) -#undef BOOST_FILESYSTEM_VERSION -#define BOOST_FILESYSTEM_VERSION 4 -#elif !defined(BOOST_FILESYSTEM_VERSION) -#define BOOST_FILESYSTEM_VERSION 3 -#endif - -#define BOOST_FILESYSTEM_VERSIONED_SYM(sym) BOOST_JOIN(sym, BOOST_JOIN(_v, BOOST_FILESYSTEM_VERSION)) - -#if BOOST_FILESYSTEM_VERSION == 4 -#undef BOOST_FILESYSTEM_DEPRECATED -#if !defined(BOOST_FILESYSTEM_NO_DEPRECATED) -#define BOOST_FILESYSTEM_NO_DEPRECATED -#endif -#endif - -#define BOOST_FILESYSTEM_I18N // aid users wishing to compile several versions - -// BOOST_FILESYSTEM_DEPRECATED needed for source compiles -----------------------------// - -#ifdef BOOST_FILESYSTEM_SOURCE -#define BOOST_FILESYSTEM_DEPRECATED -#undef BOOST_FILESYSTEM_NO_DEPRECATED // fixes #9454, src bld fails if NO_DEP defined -#endif - -#if defined(BOOST_FILESYSTEM_DEPRECATED) && defined(BOOST_FILESYSTEM_NO_DEPRECATED) -#error Both BOOST_FILESYSTEM_DEPRECATED and BOOST_FILESYSTEM_NO_DEPRECATED are defined -#endif - -// throw an exception ----------------------------------------------------------------// -// -// Exceptions were originally thrown via boost::throw_exception(). -// As throw_exception() became more complex, it caused user error reporting -// to be harder to interpret, since the exception reported became much more complex. -// The immediate fix was to throw directly, wrapped in a macro to make any later change -// easier. - -#define BOOST_FILESYSTEM_THROW(EX) throw EX - -#if defined(BOOST_NO_STD_WSTRING) -#error Configuration not supported: Boost.Filesystem V3 and later requires std::wstring support -#endif - -// This header implements separate compilation features as described in -// http://www.boost.org/more/separate_compilation.html - -// normalize macros ------------------------------------------------------------------// - -#if !defined(BOOST_FILESYSTEM_DYN_LINK) && !defined(BOOST_FILESYSTEM_STATIC_LINK) && !defined(BOOST_ALL_DYN_LINK) && !defined(BOOST_ALL_STATIC_LINK) -#define BOOST_FILESYSTEM_STATIC_LINK -#endif - -#if defined(BOOST_ALL_DYN_LINK) && !defined(BOOST_FILESYSTEM_DYN_LINK) -#define BOOST_FILESYSTEM_DYN_LINK -#elif defined(BOOST_ALL_STATIC_LINK) && !defined(BOOST_FILESYSTEM_STATIC_LINK) -#define BOOST_FILESYSTEM_STATIC_LINK -#endif - -#if defined(BOOST_FILESYSTEM_DYN_LINK) && defined(BOOST_FILESYSTEM_STATIC_LINK) -#error Must not define both BOOST_FILESYSTEM_DYN_LINK and BOOST_FILESYSTEM_STATIC_LINK -#endif - -#if defined(BOOST_ALL_NO_LIB) && !defined(BOOST_FILESYSTEM_NO_LIB) -#define BOOST_FILESYSTEM_NO_LIB -#endif - -// enable dynamic linking ------------------------------------------------------------// - -#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_FILESYSTEM_DYN_LINK) -#if defined(BOOST_FILESYSTEM_SOURCE) -#define BOOST_FILESYSTEM_DECL BOOST_SYMBOL_EXPORT -#else -#define BOOST_FILESYSTEM_DECL BOOST_SYMBOL_IMPORT -#endif -#else -#define BOOST_FILESYSTEM_DECL -#endif - -// enable automatic library variant selection ----------------------------------------// - -#if !defined(BOOST_FILESYSTEM_SOURCE) && !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_FILESYSTEM_NO_LIB) -// -// Set the name of our library, this will get undef'ed by auto_link.hpp -// once it's done with it: -// -#define BOOST_LIB_NAME boost_filesystem -// -// If we're importing code from a dll, then tell auto_link.hpp about it: -// -#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_FILESYSTEM_DYN_LINK) -#define BOOST_DYN_LINK -#endif -// -// And include the header that does the work: -// -#include <boost/config/auto_link.hpp> -#endif // auto-linking disabled - -#endif // BOOST_FILESYSTEM_CONFIG_HPP diff --git a/contrib/restricted/boost/filesystem/include/boost/filesystem/detail/footer.hpp b/contrib/restricted/boost/filesystem/include/boost/filesystem/detail/footer.hpp deleted file mode 100644 index ce4bc1feed..0000000000 --- a/contrib/restricted/boost/filesystem/include/boost/filesystem/detail/footer.hpp +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright Andrey Semashev 2021. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - */ - -#if !defined(BOOST_FILESYSTEM_ENABLE_WARNINGS) - -#if defined(_MSC_VER) && !defined(__clang__) - -#pragma warning(pop) - -#elif (defined(__GNUC__) && !(defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || defined(__ECC)) \ - && (__GNUC__ * 100 + __GNUC_MINOR__) >= 406) || defined(__clang__) - -#pragma GCC diagnostic pop - -#endif - -#endif // !defined(BOOST_FILESYSTEM_ENABLE_WARNINGS) - -#include <boost/config/abi_suffix.hpp> diff --git a/contrib/restricted/boost/filesystem/include/boost/filesystem/detail/header.hpp b/contrib/restricted/boost/filesystem/include/boost/filesystem/detail/header.hpp deleted file mode 100644 index 10f49a658e..0000000000 --- a/contrib/restricted/boost/filesystem/include/boost/filesystem/detail/header.hpp +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright Andrey Semashev 2021. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - */ - -#include <boost/config/abi_prefix.hpp> - -#if !defined(BOOST_FILESYSTEM_ENABLE_WARNINGS) - -#if defined(_MSC_VER) && !defined(__clang__) - -#pragma warning(push, 3) -// 'm_A' : class 'A' needs to have dll-interface to be used by clients of class 'B' -#pragma warning(disable: 4251) -// non dll-interface class 'A' used as base for dll-interface class 'B' -#pragma warning(disable: 4275) -// 'int' : forcing value to bool 'true' or 'false' (performance warning) -#pragma warning(disable: 4800) -// unreferenced formal parameter -#pragma warning(disable: 4100) -// conditional expression is constant -#pragma warning(disable: 4127) -// function marked as __forceinline not inlined -#pragma warning(disable: 4714) -// decorated name length exceeded, name was truncated -#pragma warning(disable: 4503) -// 'X': This function or variable may be unsafe. Consider using Y instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. -#pragma warning(disable: 4996) - -#elif (defined(__GNUC__) && !(defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || defined(__ECC)) \ - && (__GNUC__ * 100 + __GNUC_MINOR__) >= 406) || defined(__clang__) - -// Note: clang-cl goes here as well, as it seems to support gcc-style warning control pragmas. - -#pragma GCC diagnostic push -// unused parameter 'arg' -#pragma GCC diagnostic ignored "-Wunused-parameter" -// unused function 'foo' -#pragma GCC diagnostic ignored "-Wunused-function" - -#endif - -#endif // !defined(BOOST_FILESYSTEM_ENABLE_WARNINGS) diff --git a/contrib/restricted/boost/filesystem/include/boost/filesystem/detail/utf8_codecvt_facet.hpp b/contrib/restricted/boost/filesystem/include/boost/filesystem/detail/utf8_codecvt_facet.hpp deleted file mode 100644 index 4df9a7c620..0000000000 --- a/contrib/restricted/boost/filesystem/include/boost/filesystem/detail/utf8_codecvt_facet.hpp +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) 2001 Ronald Garcia, Indiana University (garcia@osl.iu.edu) -// Andrew Lumsdaine, Indiana University (lums@osl.iu.edu). - -// Distributed under the Boost Software License, Version 1.0. -// (See http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_FILESYSTEM_UTF8_CODECVT_FACET_HPP -#define BOOST_FILESYSTEM_UTF8_CODECVT_FACET_HPP - -#include <boost/filesystem/config.hpp> - -#include <boost/filesystem/detail/header.hpp> - -#define BOOST_UTF8_BEGIN_NAMESPACE \ - namespace boost { \ - namespace filesystem { \ - namespace detail { - -#define BOOST_UTF8_END_NAMESPACE \ - } \ - } \ - } -#define BOOST_UTF8_DECL BOOST_FILESYSTEM_DECL - -#include <boost/detail/utf8_codecvt_facet.hpp> - -#undef BOOST_UTF8_BEGIN_NAMESPACE -#undef BOOST_UTF8_END_NAMESPACE -#undef BOOST_UTF8_DECL - -#include <boost/filesystem/detail/footer.hpp> - -#endif // BOOST_FILESYSTEM_UTF8_CODECVT_FACET_HPP diff --git a/contrib/restricted/boost/filesystem/include/boost/filesystem/directory.hpp b/contrib/restricted/boost/filesystem/include/boost/filesystem/directory.hpp deleted file mode 100644 index 68b13638e1..0000000000 --- a/contrib/restricted/boost/filesystem/include/boost/filesystem/directory.hpp +++ /dev/null @@ -1,737 +0,0 @@ -// boost/filesystem/directory.hpp ---------------------------------------------------// - -// Copyright Beman Dawes 2002-2009 -// Copyright Jan Langer 2002 -// Copyright Dietmar Kuehl 2001 -// Copyright Vladimir Prus 2002 -// Copyright Andrey Semashev 2019 - -// Distributed under the Boost Software License, Version 1.0. -// See http://www.boost.org/LICENSE_1_0.txt - -// Library home page: http://www.boost.org/libs/filesystem - -//--------------------------------------------------------------------------------------// - -#ifndef BOOST_FILESYSTEM_DIRECTORY_HPP -#define BOOST_FILESYSTEM_DIRECTORY_HPP - -#include <boost/filesystem/config.hpp> -#include <boost/filesystem/path.hpp> -#include <boost/filesystem/file_status.hpp> - -#include <cstddef> -#include <string> -#include <vector> -#include <utility> // std::move - -#include <boost/assert.hpp> -#include <boost/core/scoped_enum.hpp> -#include <boost/detail/bitmask.hpp> -#include <boost/system/error_code.hpp> -#include <boost/smart_ptr/intrusive_ptr.hpp> -#include <boost/smart_ptr/intrusive_ref_counter.hpp> -#include <boost/iterator/iterator_facade.hpp> -#include <boost/iterator/iterator_categories.hpp> - -#include <boost/filesystem/detail/header.hpp> // must be the last #include - -//--------------------------------------------------------------------------------------// - -namespace boost { -namespace filesystem { - -//--------------------------------------------------------------------------------------// -// // -// directory_entry // -// // -//--------------------------------------------------------------------------------------// - -// GCC has a problem with a member function named path within a namespace or -// sub-namespace that also has a class named path. The workaround is to always -// fully qualify the name path when it refers to the class name. - -class directory_entry -{ -public: - typedef boost::filesystem::path::value_type value_type; // enables class path ctor taking directory_entry - - directory_entry() BOOST_NOEXCEPT {} - - explicit directory_entry(boost::filesystem::path const& p) : - m_path(p), m_status(file_status()), m_symlink_status(file_status()) - { - } - - directory_entry(boost::filesystem::path const& p, file_status st, file_status symlink_st = file_status()) : - m_path(p), m_status(st), m_symlink_status(symlink_st) - { - } - - directory_entry(directory_entry const& rhs) : - m_path(rhs.m_path), m_status(rhs.m_status), m_symlink_status(rhs.m_symlink_status) - { - } - - directory_entry& operator=(directory_entry const& rhs) - { - m_path = rhs.m_path; - m_status = rhs.m_status; - m_symlink_status = rhs.m_symlink_status; - return *this; - } - - // As of October 2015 the interaction between noexcept and =default is so troublesome - // for VC++, GCC, and probably other compilers, that =default is not used with noexcept - // functions. GCC is not even consistent for the same release on different platforms. - -#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) - directory_entry(directory_entry&& rhs) BOOST_NOEXCEPT : - m_path(std::move(rhs.m_path)), - m_status(std::move(rhs.m_status)), - m_symlink_status(std::move(rhs.m_symlink_status)) - { - } - - directory_entry& operator=(directory_entry&& rhs) BOOST_NOEXCEPT - { - m_path = std::move(rhs.m_path); - m_status = std::move(rhs.m_status); - m_symlink_status = std::move(rhs.m_symlink_status); - return *this; - } -#endif - - void assign(boost::filesystem::path const& p, file_status st = file_status(), file_status symlink_st = file_status()) - { - m_path = p; - m_status = st; - m_symlink_status = symlink_st; - } - - void replace_filename(boost::filesystem::path const& p, file_status st = file_status(), file_status symlink_st = file_status()) - { - m_path.remove_filename(); - m_path /= p; - m_status = st; - m_symlink_status = symlink_st; - } - -#ifndef BOOST_FILESYSTEM_NO_DEPRECATED - void replace_leaf(boost::filesystem::path const& p, file_status st, file_status symlink_st) - { - replace_filename(p, st, symlink_st); - } -#endif - - boost::filesystem::path const& path() const BOOST_NOEXCEPT - { - return m_path; - } - operator boost::filesystem::path const&() const BOOST_NOEXCEPT { return m_path; } - file_status status() const { return get_status(); } - file_status status(system::error_code& ec) const BOOST_NOEXCEPT { return get_status(&ec); } - file_status symlink_status() const { return get_symlink_status(); } - file_status symlink_status(system::error_code& ec) const BOOST_NOEXCEPT { return get_symlink_status(&ec); } - - bool operator==(directory_entry const& rhs) const BOOST_NOEXCEPT { return m_path == rhs.m_path; } - bool operator!=(directory_entry const& rhs) const BOOST_NOEXCEPT { return m_path != rhs.m_path; } - bool operator<(directory_entry const& rhs) const BOOST_NOEXCEPT { return m_path < rhs.m_path; } - bool operator<=(directory_entry const& rhs) const BOOST_NOEXCEPT { return m_path <= rhs.m_path; } - bool operator>(directory_entry const& rhs) const BOOST_NOEXCEPT { return m_path > rhs.m_path; } - bool operator>=(directory_entry const& rhs) const BOOST_NOEXCEPT { return m_path >= rhs.m_path; } - -private: - BOOST_FILESYSTEM_DECL file_status get_status(system::error_code* ec = NULL) const; - BOOST_FILESYSTEM_DECL file_status get_symlink_status(system::error_code* ec = NULL) const; - -private: - boost::filesystem::path m_path; - mutable file_status m_status; // stat()-like - mutable file_status m_symlink_status; // lstat()-like -}; // directory_entry - -//--------------------------------------------------------------------------------------// -// // -// directory_entry overloads // -// // -//--------------------------------------------------------------------------------------// - -// Without these functions, calling (for example) 'is_directory' with a 'directory_entry' results in: -// - a conversion to 'path' using 'operator boost::filesystem::path const&()', -// - then a call to 'is_directory(path const& p)' which recomputes the status with 'detail::status(p)'. -// -// These functions avoid a costly recomputation of the status if one calls 'is_directory(e)' instead of 'is_directory(e.status())' - -inline file_status status(directory_entry const& e) -{ - return e.status(); -} -inline file_status status(directory_entry const& e, system::error_code& ec) BOOST_NOEXCEPT -{ - return e.status(ec); -} -inline bool type_present(directory_entry const& e) -{ - return filesystem::type_present(e.status()); -} -inline bool type_present(directory_entry const& e, system::error_code& ec) BOOST_NOEXCEPT -{ - return filesystem::type_present(e.status(ec)); -} -inline bool status_known(directory_entry const& e) -{ - return filesystem::status_known(e.status()); -} -inline bool status_known(directory_entry const& e, system::error_code& ec) BOOST_NOEXCEPT -{ - return filesystem::status_known(e.status(ec)); -} -inline bool exists(directory_entry const& e) -{ - return filesystem::exists(e.status()); -} -inline bool exists(directory_entry const& e, system::error_code& ec) BOOST_NOEXCEPT -{ - return filesystem::exists(e.status(ec)); -} -inline bool is_regular_file(directory_entry const& e) -{ - return filesystem::is_regular_file(e.status()); -} -inline bool is_regular_file(directory_entry const& e, system::error_code& ec) BOOST_NOEXCEPT -{ - return filesystem::is_regular_file(e.status(ec)); -} -inline bool is_directory(directory_entry const& e) -{ - return filesystem::is_directory(e.status()); -} -inline bool is_directory(directory_entry const& e, system::error_code& ec) BOOST_NOEXCEPT -{ - return filesystem::is_directory(e.status(ec)); -} -inline bool is_symlink(directory_entry const& e) -{ - return filesystem::is_symlink(e.symlink_status()); -} -inline bool is_symlink(directory_entry const& e, system::error_code& ec) BOOST_NOEXCEPT -{ - return filesystem::is_symlink(e.symlink_status(ec)); -} -inline bool is_other(directory_entry const& e) -{ - return filesystem::is_other(e.status()); -} -inline bool is_other(directory_entry const& e, system::error_code& ec) BOOST_NOEXCEPT -{ - return filesystem::is_other(e.status(ec)); -} -#ifndef BOOST_FILESYSTEM_NO_DEPRECATED -inline bool is_regular(directory_entry const& e) -{ - return filesystem::is_regular(e.status()); -} -#endif - -//--------------------------------------------------------------------------------------// -// // -// directory_iterator helpers // -// // -//--------------------------------------------------------------------------------------// - -BOOST_SCOPED_ENUM_UT_DECLARE_BEGIN(directory_options, unsigned int) -{ - none = 0u, - skip_permission_denied = 1u, // if a directory cannot be opened because of insufficient permissions, pretend that the directory is empty - follow_directory_symlink = 1u << 1, // recursive_directory_iterator: follow directory symlinks - skip_dangling_symlinks = 1u << 2, // non-standard extension for recursive_directory_iterator: don't follow dangling directory symlinks, - pop_on_error = 1u << 3, // non-standard extension for recursive_directory_iterator: instead of producing an end iterator on errors, - // repeatedly invoke pop() until it succeeds or the iterator becomes equal to end iterator - _detail_no_follow = 1u << 4, // internal use only - _detail_no_push = 1u << 5 // internal use only -} -BOOST_SCOPED_ENUM_DECLARE_END(directory_options) - -BOOST_BITMASK(BOOST_SCOPED_ENUM_NATIVE(directory_options)) - -class directory_iterator; - -namespace detail { - -struct dir_itr_imp : - public boost::intrusive_ref_counter< dir_itr_imp > -{ -#ifdef BOOST_WINDOWS_API - bool close_handle; - unsigned char extra_data_format; - std::size_t current_offset; -#endif - directory_entry dir_entry; - void* handle; - - dir_itr_imp() BOOST_NOEXCEPT : -#ifdef BOOST_WINDOWS_API - close_handle(false), - extra_data_format(0u), - current_offset(0u), -#endif - handle(NULL) - { - } - BOOST_FILESYSTEM_DECL ~dir_itr_imp() BOOST_NOEXCEPT; - - BOOST_FILESYSTEM_DECL static void* operator new(std::size_t class_size, std::size_t extra_size) BOOST_NOEXCEPT; - BOOST_FILESYSTEM_DECL static void operator delete(void* p, std::size_t extra_size) BOOST_NOEXCEPT; - BOOST_FILESYSTEM_DECL static void operator delete(void* p) BOOST_NOEXCEPT; -}; - -struct directory_iterator_params; - -BOOST_FILESYSTEM_DECL void directory_iterator_construct(directory_iterator& it, path const& p, unsigned int opts, directory_iterator_params* params, system::error_code* ec); -BOOST_FILESYSTEM_DECL void directory_iterator_increment(directory_iterator& it, system::error_code* ec); - -} // namespace detail - -//--------------------------------------------------------------------------------------// -// // -// directory_iterator // -// // -//--------------------------------------------------------------------------------------// - -class directory_iterator : - public boost::iterator_facade< - directory_iterator, - directory_entry, - boost::single_pass_traversal_tag - > -{ - friend class boost::iterator_core_access; - - friend BOOST_FILESYSTEM_DECL void detail::directory_iterator_construct(directory_iterator& it, path const& p, unsigned int opts, detail::directory_iterator_params* params, system::error_code* ec); - friend BOOST_FILESYSTEM_DECL void detail::directory_iterator_increment(directory_iterator& it, system::error_code* ec); - -public: - directory_iterator() BOOST_NOEXCEPT {} // creates the "end" iterator - - // iterator_facade derived classes don't seem to like implementations in - // separate translation unit dll's, so forward to detail functions - explicit directory_iterator(path const& p, BOOST_SCOPED_ENUM_NATIVE(directory_options) opts = directory_options::none) - { - detail::directory_iterator_construct(*this, p, static_cast< unsigned int >(opts), NULL, NULL); - } - - directory_iterator(path const& p, system::error_code& ec) BOOST_NOEXCEPT - { - detail::directory_iterator_construct(*this, p, static_cast< unsigned int >(directory_options::none), NULL, &ec); - } - - directory_iterator(path const& p, BOOST_SCOPED_ENUM_NATIVE(directory_options) opts, system::error_code& ec) BOOST_NOEXCEPT - { - detail::directory_iterator_construct(*this, p, static_cast< unsigned int >(opts), NULL, &ec); - } - - BOOST_DEFAULTED_FUNCTION(directory_iterator(directory_iterator const& that), : m_imp(that.m_imp) {}) - BOOST_DEFAULTED_FUNCTION(directory_iterator& operator=(directory_iterator const& that), { m_imp = that.m_imp; return *this; }) - -#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) - directory_iterator(directory_iterator&& that) BOOST_NOEXCEPT : - m_imp(std::move(that.m_imp)) - { - } - - directory_iterator& operator=(directory_iterator&& that) BOOST_NOEXCEPT - { - m_imp = std::move(that.m_imp); - return *this; - } -#endif // !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) - - directory_iterator& increment(system::error_code& ec) BOOST_NOEXCEPT - { - detail::directory_iterator_increment(*this, &ec); - return *this; - } - -private: - boost::iterator_facade< - directory_iterator, - directory_entry, - boost::single_pass_traversal_tag - >::reference dereference() const - { - BOOST_ASSERT_MSG(!is_end(), "attempt to dereference end directory iterator"); - return m_imp->dir_entry; - } - - void increment() { detail::directory_iterator_increment(*this, NULL); } - - bool equal(directory_iterator const& rhs) const BOOST_NOEXCEPT - { - return m_imp == rhs.m_imp || (is_end() && rhs.is_end()); - } - - bool is_end() const BOOST_NOEXCEPT - { - // Note: The check for handle is needed because the iterator can be copied and the copy - // can be incremented to end while the original iterator still refers to the same dir_itr_imp. - return !m_imp || !m_imp->handle; - } - -private: - // intrusive_ptr provides the shallow-copy semantics required for single pass iterators - // (i.e. InputIterators). The end iterator is indicated by is_end(). - boost::intrusive_ptr< detail::dir_itr_imp > m_imp; -}; - -// enable directory_iterator C++11 range-based for statement use --------------------// - -// begin() and end() are only used by a range-based for statement in the context of -// auto - thus the top-level const is stripped - so returning const is harmless and -// emphasizes begin() is just a pass through. -inline directory_iterator const& begin(directory_iterator const& iter) BOOST_NOEXCEPT -{ - return iter; -} - -inline directory_iterator end(directory_iterator const&) BOOST_NOEXCEPT -{ - return directory_iterator(); -} - -// enable C++14 generic accessors for range const iterators -inline directory_iterator const& cbegin(directory_iterator const& iter) BOOST_NOEXCEPT -{ - return iter; -} - -inline directory_iterator cend(directory_iterator const&) BOOST_NOEXCEPT -{ - return directory_iterator(); -} - -// enable directory_iterator BOOST_FOREACH -----------------------------------------// - -inline directory_iterator& range_begin(directory_iterator& iter) BOOST_NOEXCEPT -{ - return iter; -} - -inline directory_iterator range_begin(directory_iterator const& iter) BOOST_NOEXCEPT -{ - return iter; -} - -inline directory_iterator range_end(directory_iterator&) BOOST_NOEXCEPT -{ - return directory_iterator(); -} - -inline directory_iterator range_end(directory_iterator const&) BOOST_NOEXCEPT -{ - return directory_iterator(); -} - -} // namespace filesystem - -// namespace boost template specializations -template< typename C, typename Enabler > -struct range_mutable_iterator; - -template<> -struct range_mutable_iterator< boost::filesystem::directory_iterator, void > -{ - typedef boost::filesystem::directory_iterator type; -}; - -template< typename C, typename Enabler > -struct range_const_iterator; - -template<> -struct range_const_iterator< boost::filesystem::directory_iterator, void > -{ - typedef boost::filesystem::directory_iterator type; -}; - -namespace filesystem { - -//--------------------------------------------------------------------------------------// -// // -// recursive_directory_iterator helpers // -// // -//--------------------------------------------------------------------------------------// - -#if !defined(BOOST_FILESYSTEM_NO_DEPRECATED) -// Deprecated enum, use directory_options instead -BOOST_SCOPED_ENUM_UT_DECLARE_BEGIN(symlink_option, unsigned int) -{ - none = static_cast< unsigned int >(directory_options::none), - no_recurse = none, // don't follow directory symlinks (default behavior) - recurse = static_cast< unsigned int >(directory_options::follow_directory_symlink), // follow directory symlinks - _detail_no_push = static_cast< unsigned int >(directory_options::_detail_no_push) // internal use only -} -BOOST_SCOPED_ENUM_DECLARE_END(symlink_option) - -BOOST_BITMASK(BOOST_SCOPED_ENUM_NATIVE(symlink_option)) -#endif // BOOST_FILESYSTEM_NO_DEPRECATED - -class recursive_directory_iterator; - -namespace detail { - -struct recur_dir_itr_imp : - public boost::intrusive_ref_counter< recur_dir_itr_imp > -{ - typedef directory_iterator element_type; - std::vector< element_type > m_stack; - // directory_options values, declared as unsigned int for ABI compatibility - unsigned int m_options; - - explicit recur_dir_itr_imp(unsigned int opts) BOOST_NOEXCEPT : m_options(opts) {} -}; - -BOOST_FILESYSTEM_DECL void recursive_directory_iterator_construct(recursive_directory_iterator& it, path const& dir_path, unsigned int opts, system::error_code* ec); -BOOST_FILESYSTEM_DECL void recursive_directory_iterator_increment(recursive_directory_iterator& it, system::error_code* ec); -BOOST_FILESYSTEM_DECL void recursive_directory_iterator_pop(recursive_directory_iterator& it, system::error_code* ec); - -} // namespace detail - -//--------------------------------------------------------------------------------------// -// // -// recursive_directory_iterator // -// // -//--------------------------------------------------------------------------------------// - -class recursive_directory_iterator : - public boost::iterator_facade< - recursive_directory_iterator, - directory_entry, - boost::single_pass_traversal_tag - > -{ - friend class boost::iterator_core_access; - - friend BOOST_FILESYSTEM_DECL void detail::recursive_directory_iterator_construct(recursive_directory_iterator& it, path const& dir_path, unsigned int opts, system::error_code* ec); - friend BOOST_FILESYSTEM_DECL void detail::recursive_directory_iterator_increment(recursive_directory_iterator& it, system::error_code* ec); - friend BOOST_FILESYSTEM_DECL void detail::recursive_directory_iterator_pop(recursive_directory_iterator& it, system::error_code* ec); - -public: - recursive_directory_iterator() BOOST_NOEXCEPT {} // creates the "end" iterator - - explicit recursive_directory_iterator(path const& dir_path) - { - detail::recursive_directory_iterator_construct(*this, dir_path, static_cast< unsigned int >(directory_options::none), NULL); - } - - recursive_directory_iterator(path const& dir_path, system::error_code& ec) - { - detail::recursive_directory_iterator_construct(*this, dir_path, static_cast< unsigned int >(directory_options::none), &ec); - } - - recursive_directory_iterator(path const& dir_path, BOOST_SCOPED_ENUM_NATIVE(directory_options) opts) - { - detail::recursive_directory_iterator_construct(*this, dir_path, static_cast< unsigned int >(opts), NULL); - } - - recursive_directory_iterator(path const& dir_path, BOOST_SCOPED_ENUM_NATIVE(directory_options) opts, system::error_code& ec) - { - detail::recursive_directory_iterator_construct(*this, dir_path, static_cast< unsigned int >(opts), &ec); - } - -#if !defined(BOOST_FILESYSTEM_NO_DEPRECATED) - // Deprecated constructors - recursive_directory_iterator(path const& dir_path, BOOST_SCOPED_ENUM_NATIVE(symlink_option) opts) - { - detail::recursive_directory_iterator_construct(*this, dir_path, static_cast< unsigned int >(opts), NULL); - } - - recursive_directory_iterator(path const& dir_path, BOOST_SCOPED_ENUM_NATIVE(symlink_option) opts, system::error_code& ec) BOOST_NOEXCEPT - { - detail::recursive_directory_iterator_construct(*this, dir_path, static_cast< unsigned int >(opts), &ec); - } -#endif // BOOST_FILESYSTEM_NO_DEPRECATED - - BOOST_DEFAULTED_FUNCTION(recursive_directory_iterator(recursive_directory_iterator const& that), : m_imp(that.m_imp) {}) - BOOST_DEFAULTED_FUNCTION(recursive_directory_iterator& operator=(recursive_directory_iterator const& that), { m_imp = that.m_imp; return *this; }) - -#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) - recursive_directory_iterator(recursive_directory_iterator&& that) BOOST_NOEXCEPT : - m_imp(std::move(that.m_imp)) - { - } - - recursive_directory_iterator& operator=(recursive_directory_iterator&& that) BOOST_NOEXCEPT - { - m_imp = std::move(that.m_imp); - return *this; - } -#endif // !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) - - recursive_directory_iterator& increment(system::error_code& ec) BOOST_NOEXCEPT - { - detail::recursive_directory_iterator_increment(*this, &ec); - return *this; - } - - int depth() const BOOST_NOEXCEPT - { - BOOST_ASSERT_MSG(!is_end(), "depth() on end recursive_directory_iterator"); - return static_cast< int >(m_imp->m_stack.size() - 1u); - } - - bool recursion_pending() const BOOST_NOEXCEPT - { - BOOST_ASSERT_MSG(!is_end(), "recursion_pending() on end recursive_directory_iterator"); - return (m_imp->m_options & static_cast< unsigned int >(directory_options::_detail_no_push)) == 0u; - } - -#ifndef BOOST_FILESYSTEM_NO_DEPRECATED - int level() const BOOST_NOEXCEPT - { - return depth(); - } - bool no_push_pending() const BOOST_NOEXCEPT { return !recursion_pending(); } - bool no_push_request() const BOOST_NOEXCEPT { return !recursion_pending(); } -#endif - - void pop() - { - detail::recursive_directory_iterator_pop(*this, NULL); - } - - void pop(system::error_code& ec) BOOST_NOEXCEPT - { - detail::recursive_directory_iterator_pop(*this, &ec); - } - - void disable_recursion_pending(bool value = true) BOOST_NOEXCEPT - { - BOOST_ASSERT_MSG(!is_end(), "disable_recursion_pending() on end recursive_directory_iterator"); - if (value) - m_imp->m_options |= static_cast< unsigned int >(directory_options::_detail_no_push); - else - m_imp->m_options &= ~static_cast< unsigned int >(directory_options::_detail_no_push); - } - -#ifndef BOOST_FILESYSTEM_NO_DEPRECATED - void no_push(bool value = true) BOOST_NOEXCEPT - { - disable_recursion_pending(value); - } -#endif - - file_status status() const - { - BOOST_ASSERT_MSG(!is_end(), "status() on end recursive_directory_iterator"); - return m_imp->m_stack.back()->status(); - } - - file_status symlink_status() const - { - BOOST_ASSERT_MSG(!is_end(), "symlink_status() on end recursive_directory_iterator"); - return m_imp->m_stack.back()->symlink_status(); - } - -private: - boost::iterator_facade< - recursive_directory_iterator, - directory_entry, - boost::single_pass_traversal_tag - >::reference dereference() const - { - BOOST_ASSERT_MSG(!is_end(), "dereference of end recursive_directory_iterator"); - return *m_imp->m_stack.back(); - } - - void increment() { detail::recursive_directory_iterator_increment(*this, NULL); } - - bool equal(recursive_directory_iterator const& rhs) const BOOST_NOEXCEPT - { - return m_imp == rhs.m_imp || (is_end() && rhs.is_end()); - } - - bool is_end() const BOOST_NOEXCEPT - { - // Note: The check for m_stack.empty() is needed because the iterator can be copied and the copy - // can be incremented to end while the original iterator still refers to the same recur_dir_itr_imp. - return !m_imp || m_imp->m_stack.empty(); - } - -private: - // intrusive_ptr provides the shallow-copy semantics required for single pass iterators - // (i.e. InputIterators). The end iterator is indicated by is_end(). - boost::intrusive_ptr< detail::recur_dir_itr_imp > m_imp; -}; - -#if !defined(BOOST_FILESYSTEM_NO_DEPRECATED) -typedef recursive_directory_iterator wrecursive_directory_iterator; -#endif - -// enable recursive directory iterator C++11 range-base for statement use ----------// - -// begin() and end() are only used by a range-based for statement in the context of -// auto - thus the top-level const is stripped - so returning const is harmless and -// emphasizes begin() is just a pass through. -inline recursive_directory_iterator const& begin(recursive_directory_iterator const& iter) BOOST_NOEXCEPT -{ - return iter; -} - -inline recursive_directory_iterator end(recursive_directory_iterator const&) BOOST_NOEXCEPT -{ - return recursive_directory_iterator(); -} - -// enable C++14 generic accessors for range const iterators -inline recursive_directory_iterator const& cbegin(recursive_directory_iterator const& iter) BOOST_NOEXCEPT -{ - return iter; -} - -inline recursive_directory_iterator cend(recursive_directory_iterator const&) BOOST_NOEXCEPT -{ - return recursive_directory_iterator(); -} - -// enable recursive directory iterator BOOST_FOREACH -------------------------------// - -inline recursive_directory_iterator& range_begin(recursive_directory_iterator& iter) BOOST_NOEXCEPT -{ - return iter; -} - -inline recursive_directory_iterator range_begin(recursive_directory_iterator const& iter) BOOST_NOEXCEPT -{ - return iter; -} - -inline recursive_directory_iterator range_end(recursive_directory_iterator&) BOOST_NOEXCEPT -{ - return recursive_directory_iterator(); -} - -inline recursive_directory_iterator range_end(recursive_directory_iterator const&) BOOST_NOEXCEPT -{ - return recursive_directory_iterator(); -} - -} // namespace filesystem - -// namespace boost template specializations -template<> -struct range_mutable_iterator< boost::filesystem::recursive_directory_iterator, void > -{ - typedef boost::filesystem::recursive_directory_iterator type; -}; - -template<> -struct range_const_iterator< boost::filesystem::recursive_directory_iterator, void > -{ - typedef boost::filesystem::recursive_directory_iterator type; -}; - -} // namespace boost - -#include <boost/filesystem/detail/footer.hpp> - -#endif // BOOST_FILESYSTEM_DIRECTORY_HPP diff --git a/contrib/restricted/boost/filesystem/include/boost/filesystem/exception.hpp b/contrib/restricted/boost/filesystem/include/boost/filesystem/exception.hpp deleted file mode 100644 index 59807762e3..0000000000 --- a/contrib/restricted/boost/filesystem/include/boost/filesystem/exception.hpp +++ /dev/null @@ -1,92 +0,0 @@ -// boost/filesystem/exception.hpp -----------------------------------------------------// - -// Copyright Beman Dawes 2003 -// Copyright Andrey Semashev 2019 - -// Distributed under the Boost Software License, Version 1.0. -// See http://www.boost.org/LICENSE_1_0.txt - -// Library home page: http://www.boost.org/libs/filesystem - -#ifndef BOOST_FILESYSTEM_EXCEPTION_HPP -#define BOOST_FILESYSTEM_EXCEPTION_HPP - -#include <boost/filesystem/config.hpp> -#include <boost/filesystem/path.hpp> - -#include <string> -#include <boost/system/error_code.hpp> -#include <boost/system/system_error.hpp> -#include <boost/smart_ptr/intrusive_ptr.hpp> -#include <boost/smart_ptr/intrusive_ref_counter.hpp> - -#include <boost/filesystem/detail/header.hpp> // must be the last #include - -namespace boost { -namespace filesystem { - -//--------------------------------------------------------------------------------------// -// // -// class filesystem_error // -// // -//--------------------------------------------------------------------------------------// - -class BOOST_SYMBOL_VISIBLE filesystem_error : - public system::system_error -{ - // see http://www.boost.org/more/error_handling.html for design rationale - -public: - BOOST_FILESYSTEM_DECL filesystem_error(const char* what_arg, system::error_code ec); - BOOST_FILESYSTEM_DECL filesystem_error(std::string const& what_arg, system::error_code ec); - BOOST_FILESYSTEM_DECL filesystem_error(const char* what_arg, path const& path1_arg, system::error_code ec); - BOOST_FILESYSTEM_DECL filesystem_error(std::string const& what_arg, path const& path1_arg, system::error_code ec); - BOOST_FILESYSTEM_DECL filesystem_error(const char* what_arg, path const& path1_arg, path const& path2_arg, system::error_code ec); - BOOST_FILESYSTEM_DECL filesystem_error(std::string const& what_arg, path const& path1_arg, path const& path2_arg, system::error_code ec); - - BOOST_FILESYSTEM_DECL filesystem_error(filesystem_error const& that); - BOOST_FILESYSTEM_DECL filesystem_error& operator=(filesystem_error const& that); - - BOOST_FILESYSTEM_DECL ~filesystem_error() BOOST_NOEXCEPT_OR_NOTHROW; - - path const& path1() const BOOST_NOEXCEPT - { - return m_imp_ptr.get() ? m_imp_ptr->m_path1 : get_empty_path(); - } - path const& path2() const BOOST_NOEXCEPT - { - return m_imp_ptr.get() ? m_imp_ptr->m_path2 : get_empty_path(); - } - - BOOST_FILESYSTEM_DECL const char* what() const BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE; - -private: - BOOST_FILESYSTEM_DECL static path const& get_empty_path() BOOST_NOEXCEPT; - -private: - struct impl : - public boost::intrusive_ref_counter< impl > - { - path m_path1; // may be empty() - path m_path2; // may be empty() - std::string m_what; // not built until needed - - BOOST_DEFAULTED_FUNCTION(impl(), {}) - explicit impl(path const& path1) : - m_path1(path1) - { - } - impl(path const& path1, path const& path2) : - m_path1(path1), m_path2(path2) - { - } - }; - boost::intrusive_ptr< impl > m_imp_ptr; -}; - -} // namespace filesystem -} // namespace boost - -#include <boost/filesystem/detail/footer.hpp> - -#endif // BOOST_FILESYSTEM_EXCEPTION_HPP diff --git a/contrib/restricted/boost/filesystem/include/boost/filesystem/file_status.hpp b/contrib/restricted/boost/filesystem/include/boost/filesystem/file_status.hpp deleted file mode 100644 index 90eca99e84..0000000000 --- a/contrib/restricted/boost/filesystem/include/boost/filesystem/file_status.hpp +++ /dev/null @@ -1,243 +0,0 @@ -// boost/filesystem/file_status.hpp --------------------------------------------------// - -// Copyright Beman Dawes 2002-2009 -// Copyright Jan Langer 2002 -// Copyright Dietmar Kuehl 2001 -// Copyright Vladimir Prus 2002 -// Copyright Andrey Semashev 2019 - -// Distributed under the Boost Software License, Version 1.0. -// See http://www.boost.org/LICENSE_1_0.txt - -// Library home page: http://www.boost.org/libs/filesystem - -//--------------------------------------------------------------------------------------// - -#ifndef BOOST_FILESYSTEM_FILE_STATUS_HPP -#define BOOST_FILESYSTEM_FILE_STATUS_HPP - -#include <boost/filesystem/config.hpp> -#include <boost/detail/bitmask.hpp> - -#include <boost/filesystem/detail/header.hpp> // must be the last #include - -//--------------------------------------------------------------------------------------// - -namespace boost { -namespace filesystem { - -//--------------------------------------------------------------------------------------// -// file_type // -//--------------------------------------------------------------------------------------// - -enum file_type -{ - status_error, -#ifndef BOOST_FILESYSTEM_NO_DEPRECATED - status_unknown = status_error, -#endif - file_not_found, - regular_file, - directory_file, - // the following may not apply to some operating systems or file systems - symlink_file, - block_file, - character_file, - fifo_file, - socket_file, - reparse_file, // Windows: FILE_ATTRIBUTE_REPARSE_POINT that is not a symlink - type_unknown // file does exist, but isn't one of the above types or - // we don't have strong enough permission to find its type -}; - -//--------------------------------------------------------------------------------------// -// perms // -//--------------------------------------------------------------------------------------// - -enum perms -{ - no_perms = 0, // file_not_found is no_perms rather than perms_not_known - - // POSIX equivalent macros given in comments. - // Values are from POSIX and are given in octal per the POSIX standard. - - // permission bits - - owner_read = 0400, // S_IRUSR, Read permission, owner - owner_write = 0200, // S_IWUSR, Write permission, owner - owner_exe = 0100, // S_IXUSR, Execute/search permission, owner - owner_all = 0700, // S_IRWXU, Read, write, execute/search by owner - - group_read = 040, // S_IRGRP, Read permission, group - group_write = 020, // S_IWGRP, Write permission, group - group_exe = 010, // S_IXGRP, Execute/search permission, group - group_all = 070, // S_IRWXG, Read, write, execute/search by group - - others_read = 04, // S_IROTH, Read permission, others - others_write = 02, // S_IWOTH, Write permission, others - others_exe = 01, // S_IXOTH, Execute/search permission, others - others_all = 07, // S_IRWXO, Read, write, execute/search by others - - all_all = 0777, // owner_all|group_all|others_all - - // other POSIX bits - - set_uid_on_exe = 04000, // S_ISUID, Set-user-ID on execution - set_gid_on_exe = 02000, // S_ISGID, Set-group-ID on execution - sticky_bit = 01000, // S_ISVTX, - // (POSIX XSI) On directories, restricted deletion flag - // (V7) 'sticky bit': save swapped text even after use - // (SunOS) On non-directories: don't cache this file - // (SVID-v4.2) On directories: restricted deletion flag - // Also see http://en.wikipedia.org/wiki/Sticky_bit - - perms_mask = 07777, // all_all|set_uid_on_exe|set_gid_on_exe|sticky_bit - - perms_not_known = 0xFFFF, // present when directory_entry cache not loaded - - // options for permissions() function - - add_perms = 0x1000, // adds the given permission bits to the current bits - remove_perms = 0x2000, // removes the given permission bits from the current bits; - // choose add_perms or remove_perms, not both; if neither add_perms - // nor remove_perms is given, replace the current bits with - // the given bits. - - symlink_perms = 0x4000, // on POSIX, don't resolve symlinks; implied on Windows - - // BOOST_BITMASK op~ casts to int32_least_t, producing invalid enum values - _detail_extend_perms_32_1 = 0x7fffffff, - _detail_extend_perms_32_2 = -0x7fffffff - 1 -}; - -BOOST_BITMASK(perms) - -//--------------------------------------------------------------------------------------// -// file_status // -//--------------------------------------------------------------------------------------// - -class file_status -{ -public: - BOOST_CONSTEXPR file_status() BOOST_NOEXCEPT : - m_value(status_error), - m_perms(perms_not_known) - { - } - explicit BOOST_CONSTEXPR file_status(file_type v) BOOST_NOEXCEPT : - m_value(v), - m_perms(perms_not_known) - { - } - BOOST_CONSTEXPR file_status(file_type v, perms prms) BOOST_NOEXCEPT : - m_value(v), - m_perms(prms) - { - } - - // As of October 2015 the interaction between noexcept and =default is so troublesome - // for VC++, GCC, and probably other compilers, that =default is not used with noexcept - // functions. GCC is not even consistent for the same release on different platforms. - - BOOST_CONSTEXPR file_status(file_status const& rhs) BOOST_NOEXCEPT : - m_value(rhs.m_value), - m_perms(rhs.m_perms) - { - } - BOOST_CXX14_CONSTEXPR file_status& operator=(file_status const& rhs) BOOST_NOEXCEPT - { - m_value = rhs.m_value; - m_perms = rhs.m_perms; - return *this; - } - -#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) - // Note: std::move is not constexpr in C++11, that's why we're not using it here - BOOST_CONSTEXPR file_status(file_status&& rhs) BOOST_NOEXCEPT : - m_value(static_cast< file_type&& >(rhs.m_value)), - m_perms(static_cast< enum perms&& >(rhs.m_perms)) - { - } - BOOST_CXX14_CONSTEXPR file_status& operator=(file_status&& rhs) BOOST_NOEXCEPT - { - m_value = static_cast< file_type&& >(rhs.m_value); - m_perms = static_cast< enum perms&& >(rhs.m_perms); - return *this; - } -#endif - - // observers - BOOST_CONSTEXPR file_type type() const BOOST_NOEXCEPT { return m_value; } - BOOST_CONSTEXPR perms permissions() const BOOST_NOEXCEPT { return m_perms; } - - // modifiers - BOOST_CXX14_CONSTEXPR void type(file_type v) BOOST_NOEXCEPT { m_value = v; } - BOOST_CXX14_CONSTEXPR void permissions(perms prms) BOOST_NOEXCEPT { m_perms = prms; } - - BOOST_CONSTEXPR bool operator==(const file_status& rhs) const BOOST_NOEXCEPT - { - return type() == rhs.type() && permissions() == rhs.permissions(); - } - BOOST_CONSTEXPR bool operator!=(const file_status& rhs) const BOOST_NOEXCEPT - { - return !(*this == rhs); - } - -private: - file_type m_value; - enum perms m_perms; -}; - -inline BOOST_CONSTEXPR bool type_present(file_status f) BOOST_NOEXCEPT -{ - return f.type() != status_error; -} - -inline BOOST_CONSTEXPR bool permissions_present(file_status f) BOOST_NOEXCEPT -{ - return f.permissions() != perms_not_known; -} - -inline BOOST_CONSTEXPR bool status_known(file_status f) BOOST_NOEXCEPT -{ - return filesystem::type_present(f) && filesystem::permissions_present(f); -} - -inline BOOST_CONSTEXPR bool exists(file_status f) BOOST_NOEXCEPT -{ - return f.type() != status_error && f.type() != file_not_found; -} - -inline BOOST_CONSTEXPR bool is_regular_file(file_status f) BOOST_NOEXCEPT -{ - return f.type() == regular_file; -} - -inline BOOST_CONSTEXPR bool is_directory(file_status f) BOOST_NOEXCEPT -{ - return f.type() == directory_file; -} - -inline BOOST_CONSTEXPR bool is_symlink(file_status f) BOOST_NOEXCEPT -{ - return f.type() == symlink_file; -} - -inline BOOST_CONSTEXPR bool is_other(file_status f) BOOST_NOEXCEPT -{ - return filesystem::exists(f) && !filesystem::is_regular_file(f) && !filesystem::is_directory(f) && !filesystem::is_symlink(f); -} - -#ifndef BOOST_FILESYSTEM_NO_DEPRECATED -inline bool is_regular(file_status f) BOOST_NOEXCEPT -{ - return filesystem::is_regular_file(f); -} -#endif - -} // namespace filesystem -} // namespace boost - -#include <boost/filesystem/detail/footer.hpp> // pops abi_prefix.hpp pragmas - -#endif // BOOST_FILESYSTEM_FILE_STATUS_HPP diff --git a/contrib/restricted/boost/filesystem/include/boost/filesystem/operations.hpp b/contrib/restricted/boost/filesystem/include/boost/filesystem/operations.hpp deleted file mode 100644 index 856de7c1a5..0000000000 --- a/contrib/restricted/boost/filesystem/include/boost/filesystem/operations.hpp +++ /dev/null @@ -1,720 +0,0 @@ -// boost/filesystem/operations.hpp ---------------------------------------------------// - -// Copyright Beman Dawes 2002-2009 -// Copyright Jan Langer 2002 -// Copyright Dietmar Kuehl 2001 -// Copyright Vladimir Prus 2002 -// Copyright Andrey Semashev 2020-2021 - -// Distributed under the Boost Software License, Version 1.0. -// See http://www.boost.org/LICENSE_1_0.txt - -// Library home page: http://www.boost.org/libs/filesystem - -//--------------------------------------------------------------------------------------// - -#ifndef BOOST_FILESYSTEM_OPERATIONS_HPP -#define BOOST_FILESYSTEM_OPERATIONS_HPP - -#include <boost/filesystem/config.hpp> -#include <boost/filesystem/path.hpp> -#include <boost/filesystem/file_status.hpp> - -#ifndef BOOST_FILESYSTEM_NO_DEPRECATED -// These includes are left for backward compatibility and should be included directly by users, as needed -#include <boost/filesystem/exception.hpp> -#include <boost/filesystem/directory.hpp> -#endif - -#include <boost/detail/bitmask.hpp> -#include <boost/core/scoped_enum.hpp> -#include <boost/system/error_code.hpp> -#include <boost/cstdint.hpp> -#include <cstddef> -#include <ctime> -#include <string> - -#include <boost/filesystem/detail/header.hpp> // must be the last #include - -//--------------------------------------------------------------------------------------// - -namespace boost { -namespace filesystem { - -struct space_info -{ - // all values are byte counts - boost::uintmax_t capacity; - boost::uintmax_t free; // <= capacity - boost::uintmax_t available; // <= free -}; - -BOOST_SCOPED_ENUM_UT_DECLARE_BEGIN(copy_options, unsigned int) -{ - none = 0u, // Default. For copy_file: error if the target file exists. For copy: do not recurse, follow symlinks, copy file contents. - - // copy_file options: - skip_existing = 1u, // Don't overwrite the existing target file, don't report an error - overwrite_existing = 1u << 1, // Overwrite existing file - update_existing = 1u << 2, // Overwrite existing file if its last write time is older than the replacement file - synchronize_data = 1u << 3, // Flush all buffered data written to the target file to permanent storage - synchronize = 1u << 4, // Flush all buffered data and attributes written to the target file to permanent storage - - // copy options: - recursive = 1u << 8, // Recurse into sub-directories - copy_symlinks = 1u << 9, // Copy symlinks as symlinks instead of copying the referenced file - skip_symlinks = 1u << 10, // Don't copy symlinks - directories_only = 1u << 11, // Only copy directory structure, do not copy non-directory files - create_symlinks = 1u << 12, // Create symlinks instead of copying files - create_hard_links = 1u << 13, // Create hard links instead of copying files - _detail_recursing = 1u << 14 // Internal use only, do not use -} -BOOST_SCOPED_ENUM_DECLARE_END(copy_options) - -BOOST_BITMASK(BOOST_SCOPED_ENUM_NATIVE(copy_options)) - -#if !defined(BOOST_FILESYSTEM_NO_DEPRECATED) -BOOST_SCOPED_ENUM_DECLARE_BEGIN(copy_option) -{ - none = static_cast< unsigned int >(copy_options::none), - fail_if_exists = none, - overwrite_if_exists = static_cast< unsigned int >(copy_options::overwrite_existing) -} -BOOST_SCOPED_ENUM_DECLARE_END(copy_option) -#endif - -//--------------------------------------------------------------------------------------// -// implementation details // -//--------------------------------------------------------------------------------------// - -namespace detail { - -BOOST_FILESYSTEM_DECL -path absolute(path const& p, path const& base, system::error_code* ec = NULL); -BOOST_FILESYSTEM_DECL -file_status status(path const& p, system::error_code* ec = NULL); -BOOST_FILESYSTEM_DECL -file_status symlink_status(path const& p, system::error_code* ec = NULL); -BOOST_FILESYSTEM_DECL -bool is_empty(path const& p, system::error_code* ec = NULL); -BOOST_FILESYSTEM_DECL -path initial_path(system::error_code* ec = NULL); -BOOST_FILESYSTEM_DECL -path canonical(path const& p, path const& base, system::error_code* ec = NULL); -BOOST_FILESYSTEM_DECL -void copy(path const& from, path const& to, unsigned int options, system::error_code* ec = NULL); -#if !defined(BOOST_FILESYSTEM_NO_DEPRECATED) -BOOST_FILESYSTEM_DECL -void copy_directory(path const& from, path const& to, system::error_code* ec = NULL); -#endif -BOOST_FILESYSTEM_DECL -bool copy_file(path const& from, path const& to, // See ticket #2925 - unsigned int options, system::error_code* ec = NULL); // see copy_options for options -BOOST_FILESYSTEM_DECL -void copy_symlink(path const& existing_symlink, path const& new_symlink, system::error_code* ec = NULL); -BOOST_FILESYSTEM_DECL -bool create_directories(path const& p, system::error_code* ec = NULL); -BOOST_FILESYSTEM_DECL -bool create_directory(path const& p, const path* existing, system::error_code* ec = NULL); -BOOST_FILESYSTEM_DECL -void create_directory_symlink(path const& to, path const& from, system::error_code* ec = NULL); -BOOST_FILESYSTEM_DECL -void create_hard_link(path const& to, path const& from, system::error_code* ec = NULL); -BOOST_FILESYSTEM_DECL -void create_symlink(path const& to, path const& from, system::error_code* ec = NULL); -BOOST_FILESYSTEM_DECL -path current_path(system::error_code* ec = NULL); -BOOST_FILESYSTEM_DECL -void current_path(path const& p, system::error_code* ec = NULL); -BOOST_FILESYSTEM_DECL -bool equivalent(path const& p1, path const& p2, system::error_code* ec = NULL); -BOOST_FILESYSTEM_DECL -boost::uintmax_t file_size(path const& p, system::error_code* ec = NULL); -BOOST_FILESYSTEM_DECL -boost::uintmax_t hard_link_count(path const& p, system::error_code* ec = NULL); -BOOST_FILESYSTEM_DECL -std::time_t creation_time(path const& p, system::error_code* ec = NULL); -BOOST_FILESYSTEM_DECL -std::time_t last_write_time(path const& p, system::error_code* ec = NULL); -BOOST_FILESYSTEM_DECL -void last_write_time(path const& p, const std::time_t new_time, system::error_code* ec = NULL); -BOOST_FILESYSTEM_DECL -void permissions(path const& p, perms prms, system::error_code* ec = NULL); -BOOST_FILESYSTEM_DECL -path read_symlink(path const& p, system::error_code* ec = NULL); -BOOST_FILESYSTEM_DECL -path relative(path const& p, path const& base, system::error_code* ec = NULL); -BOOST_FILESYSTEM_DECL -bool remove(path const& p, system::error_code* ec = NULL); -BOOST_FILESYSTEM_DECL -boost::uintmax_t remove_all(path const& p, system::error_code* ec = NULL); -BOOST_FILESYSTEM_DECL -void rename(path const& old_p, path const& new_p, system::error_code* ec = NULL); -BOOST_FILESYSTEM_DECL -void resize_file(path const& p, uintmax_t size, system::error_code* ec = NULL); -BOOST_FILESYSTEM_DECL -space_info space(path const& p, system::error_code* ec = NULL); -BOOST_FILESYSTEM_DECL -path system_complete(path const& p, system::error_code* ec = NULL); -BOOST_FILESYSTEM_DECL -path temp_directory_path(system::error_code* ec = NULL); -BOOST_FILESYSTEM_DECL -path unique_path(path const& p, system::error_code* ec = NULL); -BOOST_FILESYSTEM_DECL -path weakly_canonical(path const& p, path const& base, system::error_code* ec = NULL); - -} // namespace detail - -//--------------------------------------------------------------------------------------// -// // -// status query functions // -// // -//--------------------------------------------------------------------------------------// - -inline file_status status(path const& p) -{ - return detail::status(p); -} - -inline file_status status(path const& p, system::error_code& ec) -{ - return detail::status(p, &ec); -} - -inline file_status symlink_status(path const& p) -{ - return detail::symlink_status(p); -} - -inline file_status symlink_status(path const& p, system::error_code& ec) -{ - return detail::symlink_status(p, &ec); -} - -inline bool exists(path const& p) -{ - return exists(detail::status(p)); -} - -inline bool exists(path const& p, system::error_code& ec) -{ - return exists(detail::status(p, &ec)); -} - -inline bool is_directory(path const& p) -{ - return is_directory(detail::status(p)); -} - -inline bool is_directory(path const& p, system::error_code& ec) -{ - return is_directory(detail::status(p, &ec)); -} - -inline bool is_regular_file(path const& p) -{ - return is_regular_file(detail::status(p)); -} - -inline bool is_regular_file(path const& p, system::error_code& ec) -{ - return is_regular_file(detail::status(p, &ec)); -} - -inline bool is_other(path const& p) -{ - return is_other(detail::status(p)); -} - -inline bool is_other(path const& p, system::error_code& ec) -{ - return is_other(detail::status(p, &ec)); -} - -inline bool is_symlink(path const& p) -{ - return is_symlink(detail::symlink_status(p)); -} - -inline bool is_symlink(path const& p, system::error_code& ec) -{ - return is_symlink(detail::symlink_status(p, &ec)); -} - -#ifndef BOOST_FILESYSTEM_NO_DEPRECATED -inline bool is_regular(path const& p) -{ - return is_regular(detail::status(p)); -} - -inline bool is_regular(path const& p, system::error_code& ec) -{ - return is_regular(detail::status(p, &ec)); -} -#endif - -inline bool is_empty(path const& p) -{ - return detail::is_empty(p); -} - -inline bool is_empty(path const& p, system::error_code& ec) -{ - return detail::is_empty(p, &ec); -} - -//--------------------------------------------------------------------------------------// -// // -// operational functions // -// // -//--------------------------------------------------------------------------------------// - -inline path initial_path() -{ - return detail::initial_path(); -} - -inline path initial_path(system::error_code& ec) -{ - return detail::initial_path(&ec); -} - -template< class Path > -path initial_path() -{ - return initial_path(); -} -template< class Path > -path initial_path(system::error_code& ec) -{ - return detail::initial_path(&ec); -} - -inline path current_path() -{ - return detail::current_path(); -} - -inline path current_path(system::error_code& ec) -{ - return detail::current_path(&ec); -} - -inline void current_path(path const& p) -{ - detail::current_path(p); -} - -inline void current_path(path const& p, system::error_code& ec) BOOST_NOEXCEPT -{ - detail::current_path(p, &ec); -} - -inline path absolute(path const& p, path const& base = current_path()) -{ - return detail::absolute(p, base); -} - -inline path absolute(path const& p, system::error_code& ec) -{ - path base = current_path(ec); - if (ec) - return path(); - return detail::absolute(p, base, &ec); -} - -inline path absolute(path const& p, path const& base, system::error_code& ec) -{ - return detail::absolute(p, base, &ec); -} - -inline path canonical(path const& p, path const& base = current_path()) -{ - return detail::canonical(p, base); -} - -inline path canonical(path const& p, system::error_code& ec) -{ - path base = current_path(ec); - if (ec) - return path(); - return detail::canonical(p, base, &ec); -} - -inline path canonical(path const& p, path const& base, system::error_code& ec) -{ - return detail::canonical(p, base, &ec); -} - -#ifndef BOOST_FILESYSTEM_NO_DEPRECATED -inline path complete(path const& p) -{ - return absolute(p, initial_path()); -} - -inline path complete(path const& p, path const& base) -{ - return absolute(p, base); -} -#endif - -inline void copy(path const& from, path const& to) -{ - detail::copy(from, to, static_cast< unsigned int >(copy_options::none)); -} - -inline void copy(path const& from, path const& to, system::error_code& ec) BOOST_NOEXCEPT -{ - detail::copy(from, to, static_cast< unsigned int >(copy_options::none), &ec); -} - -inline void copy(path const& from, path const& to, BOOST_SCOPED_ENUM_NATIVE(copy_options) options) -{ - detail::copy(from, to, static_cast< unsigned int >(options)); -} - -inline void copy(path const& from, path const& to, BOOST_SCOPED_ENUM_NATIVE(copy_options) options, system::error_code& ec) BOOST_NOEXCEPT -{ - detail::copy(from, to, static_cast< unsigned int >(options), &ec); -} - -#if !defined(BOOST_FILESYSTEM_NO_DEPRECATED) -inline void copy_directory(path const& from, path const& to) -{ - detail::copy_directory(from, to); -} - -inline void copy_directory(path const& from, path const& to, system::error_code& ec) BOOST_NOEXCEPT -{ - detail::copy_directory(from, to, &ec); -} -#endif - -inline bool copy_file(path const& from, path const& to) -{ - return detail::copy_file(from, to, static_cast< unsigned int >(copy_options::none)); -} - -inline bool copy_file(path const& from, path const& to, system::error_code& ec) BOOST_NOEXCEPT -{ - return detail::copy_file(from, to, static_cast< unsigned int >(copy_options::none), &ec); -} - -inline bool copy_file(path const& from, path const& to, // See ticket #2925 - BOOST_SCOPED_ENUM_NATIVE(copy_options) options) -{ - return detail::copy_file(from, to, static_cast< unsigned int >(options)); -} - -inline bool copy_file(path const& from, path const& to, // See ticket #2925 - BOOST_SCOPED_ENUM_NATIVE(copy_options) options, system::error_code& ec) BOOST_NOEXCEPT -{ - return detail::copy_file(from, to, static_cast< unsigned int >(options), &ec); -} - -#if !defined(BOOST_FILESYSTEM_NO_DEPRECATED) -inline bool copy_file(path const& from, path const& to, // See ticket #2925 - BOOST_SCOPED_ENUM_NATIVE(copy_option) options) -{ - return detail::copy_file(from, to, static_cast< unsigned int >(options)); -} - -inline bool copy_file(path const& from, path const& to, // See ticket #2925 - BOOST_SCOPED_ENUM_NATIVE(copy_option) options, system::error_code& ec) BOOST_NOEXCEPT -{ - return detail::copy_file(from, to, static_cast< unsigned int >(options), &ec); -} -#endif // !defined(BOOST_FILESYSTEM_NO_DEPRECATED) - -inline void copy_symlink(path const& existing_symlink, path const& new_symlink) -{ - detail::copy_symlink(existing_symlink, new_symlink); -} - -inline void copy_symlink(path const& existing_symlink, path const& new_symlink, system::error_code& ec) BOOST_NOEXCEPT -{ - detail::copy_symlink(existing_symlink, new_symlink, &ec); -} - -inline bool create_directories(path const& p) -{ - return detail::create_directories(p); -} - -inline bool create_directories(path const& p, system::error_code& ec) BOOST_NOEXCEPT -{ - return detail::create_directories(p, &ec); -} - -inline bool create_directory(path const& p) -{ - return detail::create_directory(p, NULL); -} - -inline bool create_directory(path const& p, system::error_code& ec) BOOST_NOEXCEPT -{ - return detail::create_directory(p, NULL, &ec); -} - -inline bool create_directory(path const& p, path const& existing) -{ - return detail::create_directory(p, &existing); -} - -inline bool create_directory(path const& p, path const& existing, system::error_code& ec) BOOST_NOEXCEPT -{ - return detail::create_directory(p, &existing, &ec); -} - -inline void create_directory_symlink(path const& to, path const& from) -{ - detail::create_directory_symlink(to, from); -} - -inline void create_directory_symlink(path const& to, path const& from, system::error_code& ec) BOOST_NOEXCEPT -{ - detail::create_directory_symlink(to, from, &ec); -} - -inline void create_hard_link(path const& to, path const& new_hard_link) -{ - detail::create_hard_link(to, new_hard_link); -} - -inline void create_hard_link(path const& to, path const& new_hard_link, system::error_code& ec) BOOST_NOEXCEPT -{ - detail::create_hard_link(to, new_hard_link, &ec); -} - -inline void create_symlink(path const& to, path const& new_symlink) -{ - detail::create_symlink(to, new_symlink); -} - -inline void create_symlink(path const& to, path const& new_symlink, system::error_code& ec) BOOST_NOEXCEPT -{ - detail::create_symlink(to, new_symlink, &ec); -} - -inline bool equivalent(path const& p1, path const& p2) -{ - return detail::equivalent(p1, p2); -} - -inline bool equivalent(path const& p1, path const& p2, system::error_code& ec) BOOST_NOEXCEPT -{ - return detail::equivalent(p1, p2, &ec); -} - -inline boost::uintmax_t file_size(path const& p) -{ - return detail::file_size(p); -} - -inline boost::uintmax_t file_size(path const& p, system::error_code& ec) BOOST_NOEXCEPT -{ - return detail::file_size(p, &ec); -} - -inline boost::uintmax_t hard_link_count(path const& p) -{ - return detail::hard_link_count(p); -} - -inline boost::uintmax_t hard_link_count(path const& p, system::error_code& ec) BOOST_NOEXCEPT -{ - return detail::hard_link_count(p, &ec); -} - -inline std::time_t creation_time(path const& p) -{ - return detail::creation_time(p); -} - -inline std::time_t creation_time(path const& p, system::error_code& ec) BOOST_NOEXCEPT -{ - return detail::creation_time(p, &ec); -} - -inline std::time_t last_write_time(path const& p) -{ - return detail::last_write_time(p); -} - -inline std::time_t last_write_time(path const& p, system::error_code& ec) BOOST_NOEXCEPT -{ - return detail::last_write_time(p, &ec); -} - -inline void last_write_time(path const& p, const std::time_t new_time) -{ - detail::last_write_time(p, new_time); -} - -inline void last_write_time(path const& p, const std::time_t new_time, system::error_code& ec) BOOST_NOEXCEPT -{ - detail::last_write_time(p, new_time, &ec); -} - -inline void permissions(path const& p, perms prms) -{ - detail::permissions(p, prms); -} - -inline void permissions(path const& p, perms prms, system::error_code& ec) BOOST_NOEXCEPT -{ - detail::permissions(p, prms, &ec); -} - -inline path read_symlink(path const& p) -{ - return detail::read_symlink(p); -} - -inline path read_symlink(path const& p, system::error_code& ec) -{ - return detail::read_symlink(p, &ec); -} - -inline bool remove(path const& p) -{ - return detail::remove(p); -} - -inline bool remove(path const& p, system::error_code& ec) BOOST_NOEXCEPT -{ - return detail::remove(p, &ec); -} - -inline boost::uintmax_t remove_all(path const& p) -{ - return detail::remove_all(p); -} - -inline boost::uintmax_t remove_all(path const& p, system::error_code& ec) BOOST_NOEXCEPT -{ - return detail::remove_all(p, &ec); -} - -inline void rename(path const& old_p, path const& new_p) -{ - detail::rename(old_p, new_p); -} - -inline void rename(path const& old_p, path const& new_p, system::error_code& ec) BOOST_NOEXCEPT -{ - detail::rename(old_p, new_p, &ec); -} - -// name suggested by Scott McMurray -inline void resize_file(path const& p, uintmax_t size) -{ - detail::resize_file(p, size); -} - -inline void resize_file(path const& p, uintmax_t size, system::error_code& ec) BOOST_NOEXCEPT -{ - detail::resize_file(p, size, &ec); -} - -inline path relative(path const& p, path const& base = current_path()) -{ - return detail::relative(p, base); -} - -inline path relative(path const& p, system::error_code& ec) -{ - path base = current_path(ec); - if (ec) - return path(); - return detail::relative(p, base, &ec); -} - -inline path relative(path const& p, path const& base, system::error_code& ec) -{ - return detail::relative(p, base, &ec); -} - -inline space_info space(path const& p) -{ - return detail::space(p); -} - -inline space_info space(path const& p, system::error_code& ec) BOOST_NOEXCEPT -{ - return detail::space(p, &ec); -} - -#ifndef BOOST_FILESYSTEM_NO_DEPRECATED -inline bool symbolic_link_exists(path const& p) -{ - return is_symlink(filesystem::symlink_status(p)); -} -#endif - -inline path system_complete(path const& p) -{ - return detail::system_complete(p); -} - -inline path system_complete(path const& p, system::error_code& ec) -{ - return detail::system_complete(p, &ec); -} - -inline path temp_directory_path() -{ - return detail::temp_directory_path(); -} - -inline path temp_directory_path(system::error_code& ec) -{ - return detail::temp_directory_path(&ec); -} - -inline path unique_path(path const& p = "%%%%-%%%%-%%%%-%%%%") -{ - return detail::unique_path(p); -} - -inline path unique_path(path const& p, system::error_code& ec) -{ - return detail::unique_path(p, &ec); -} - -inline path weakly_canonical(path const& p, path const& base = current_path()) -{ - return detail::weakly_canonical(p, base); -} - -inline path weakly_canonical(path const& p, system::error_code& ec) -{ - path base = current_path(ec); - if (ec) - return path(); - return detail::weakly_canonical(p, base, &ec); -} - -inline path weakly_canonical(path const& p, path const& base, system::error_code& ec) -{ - return detail::weakly_canonical(p, base, &ec); -} - -// test helper -----------------------------------------------------------------------// - -// Not part of the documented interface since false positives are possible; -// there is no law that says that an OS that has large stat.st_size -// actually supports large file sizes. - -namespace detail { - -BOOST_FILESYSTEM_DECL bool possible_large_file_size_support(); - -} // namespace detail - -} // namespace filesystem -} // namespace boost - -#include <boost/filesystem/detail/footer.hpp> - -#endif // BOOST_FILESYSTEM_OPERATIONS_HPP diff --git a/contrib/restricted/boost/filesystem/include/boost/filesystem/path.hpp b/contrib/restricted/boost/filesystem/include/boost/filesystem/path.hpp deleted file mode 100644 index 0554c987a1..0000000000 --- a/contrib/restricted/boost/filesystem/include/boost/filesystem/path.hpp +++ /dev/null @@ -1,1395 +0,0 @@ -// filesystem path.hpp ---------------------------------------------------------------// - -// Copyright Vladimir Prus 2002 -// Copyright Beman Dawes 2002-2005, 2009 -// Copyright Andrey Semashev 2021 - -// Distributed under the Boost Software License, Version 1.0. -// See http://www.boost.org/LICENSE_1_0.txt - -// Library home page: http://www.boost.org/libs/filesystem - -// path::stem(), extension(), and replace_extension() are based on -// basename(), extension(), and change_extension() from the original -// filesystem/convenience.hpp header by Vladimir Prus. - -#ifndef BOOST_FILESYSTEM_PATH_HPP -#define BOOST_FILESYSTEM_PATH_HPP - -#include <boost/assert.hpp> -#include <boost/filesystem/config.hpp> -#include <boost/filesystem/path_traits.hpp> // includes <cwchar> -#include <boost/iterator/iterator_facade.hpp> -#include <boost/iterator/iterator_categories.hpp> -#include <boost/core/enable_if.hpp> -#include <boost/io/quoted.hpp> -#include <boost/functional/hash_fwd.hpp> -#include <boost/type_traits/integral_constant.hpp> -#include <boost/type_traits/is_same.hpp> -#include <boost/type_traits/is_integral.hpp> -#include <boost/type_traits/remove_reference.hpp> -#include <boost/type_traits/remove_cv.hpp> -#include <boost/type_traits/decay.hpp> -#include <cstddef> -#include <cwchar> // for mbstate_t -#include <string> -#include <iosfwd> -#include <iterator> -#include <locale> -#include <utility> - -#include <boost/filesystem/detail/header.hpp> // must be the last #include - -namespace boost { -namespace filesystem { - -class path; - -namespace path_detail { // intentionally don't use filesystem::detail to not bring internal Boost.Filesystem functions into ADL via path_constants - -template< typename Char, Char Separator, Char PreferredSeparator, Char Dot > -struct path_constants -{ - typedef path_constants< Char, Separator, PreferredSeparator, Dot > path_constants_base; - typedef Char value_type; - static BOOST_CONSTEXPR_OR_CONST value_type separator = Separator; - static BOOST_CONSTEXPR_OR_CONST value_type preferred_separator = PreferredSeparator; - static BOOST_CONSTEXPR_OR_CONST value_type dot = Dot; -}; - -#if defined(BOOST_NO_CXX17_INLINE_VARIABLES) -template< typename Char, Char Separator, Char PreferredSeparator, Char Dot > -BOOST_CONSTEXPR_OR_CONST typename path_constants< Char, Separator, PreferredSeparator, Dot >::value_type -path_constants< Char, Separator, PreferredSeparator, Dot >::separator; -template< typename Char, Char Separator, Char PreferredSeparator, Char Dot > -BOOST_CONSTEXPR_OR_CONST typename path_constants< Char, Separator, PreferredSeparator, Dot >::value_type -path_constants< Char, Separator, PreferredSeparator, Dot >::preferred_separator; -template< typename Char, Char Separator, Char PreferredSeparator, Char Dot > -BOOST_CONSTEXPR_OR_CONST typename path_constants< Char, Separator, PreferredSeparator, Dot >::value_type -path_constants< Char, Separator, PreferredSeparator, Dot >::dot; -#endif - -// A struct that denotes a contiguous range of characters in a string. A lightweight alternative to string_view. -struct substring -{ - std::size_t pos; - std::size_t size; -}; - -template< typename T > -struct is_native_char_ptr_impl : public boost::false_type {}; - -#if defined(BOOST_WINDOWS_API) -template< > -struct is_native_char_ptr_impl< wchar_t* > : public boost::true_type {}; -template< > -struct is_native_char_ptr_impl< const wchar_t* > : public boost::true_type {}; -#else // defined(BOOST_WINDOWS_API) -template< > -struct is_native_char_ptr_impl< char* > : public boost::true_type {}; -template< > -struct is_native_char_ptr_impl< const char* > : public boost::true_type {}; -#endif // defined(BOOST_WINDOWS_API) - -template< typename T > -struct is_native_char_ptr : public is_native_char_ptr_impl< typename boost::remove_cv< typename boost::remove_reference< T >::type >::type > {}; - -template< typename T > -struct is_native_pathable_impl : public boost::false_type {}; - -template< typename T > -struct is_native_pathable_impl< T* > : public is_native_char_ptr_impl< T* > {}; - -#if defined(BOOST_WINDOWS_API) -template< > -struct is_native_pathable_impl< const wchar_t[] > : public boost::true_type {}; -template< std::size_t N > -struct is_native_pathable_impl< const wchar_t[N] > : public boost::true_type {}; -template< > -struct is_native_pathable_impl< std::basic_string< wchar_t > > : public boost::true_type {}; -#else // defined(BOOST_WINDOWS_API) -template< > -struct is_native_pathable_impl< const char[] > : public boost::true_type {}; -template< std::size_t N > -struct is_native_pathable_impl< const char[N] > : public boost::true_type {}; -template< > -struct is_native_pathable_impl< std::basic_string< char > > : public boost::true_type {}; -#endif // defined(BOOST_WINDOWS_API) -template< > -struct is_native_pathable_impl< filesystem::path > : public boost::true_type {}; - -template< typename T > -struct is_native_pathable : public is_native_pathable_impl< typename boost::remove_cv< typename boost::remove_reference< T >::type >::type > {}; - -} // namespace path_detail - -//------------------------------------------------------------------------------------// -// // -// class path // -// // -//------------------------------------------------------------------------------------// - -class path : - public filesystem::path_detail::path_constants< -#ifdef BOOST_WINDOWS_API - wchar_t, L'/', L'\\', L'.' -#else - char, '/', '/', '.' -#endif - > -{ -public: - // value_type is the character type used by the operating system API to - // represent paths. - - typedef path_constants_base::value_type value_type; - typedef std::basic_string< value_type > string_type; - typedef std::codecvt< wchar_t, char, std::mbstate_t > codecvt_type; - - // ----- character encoding conversions ----- - - // Following the principle of least astonishment, path input arguments - // passed to or obtained from the operating system via objects of - // class path behave as if they were directly passed to or - // obtained from the O/S API, unless conversion is explicitly requested. - // - // POSIX specfies that path strings are passed unchanged to and from the - // API. Note that this is different from the POSIX command line utilities, - // which convert according to a locale. - // - // Thus for POSIX, char strings do not undergo conversion. wchar_t strings - // are converted to/from char using the path locale or, if a conversion - // argument is given, using a conversion object modeled on - // std::wstring_convert. - // - // The path locale, which is global to the thread, can be changed by the - // imbue() function. It is initialized to an implementation defined locale. - // - // For Windows, wchar_t strings do not undergo conversion. char strings - // are converted using the "ANSI" or "OEM" code pages, as determined by - // the AreFileApisANSI() function, or, if a conversion argument is given, - // using a conversion object modeled on std::wstring_convert. - // - // See m_pathname comments for further important rationale. - - // TODO: rules needed for operating systems that use / or . - // differently, or format directory paths differently from file paths. - // - // ********************************************************************************** - // - // More work needed: How to handle an operating system that may have - // slash characters or dot characters in valid filenames, either because - // it doesn't follow the POSIX standard, or because it allows MBCS - // filename encodings that may contain slash or dot characters. For - // example, ISO/IEC 2022 (JIS) encoding which allows switching to - // JIS x0208-1983 encoding. A valid filename in this set of encodings is - // 0x1B 0x24 0x42 [switch to X0208-1983] 0x24 0x2F [U+304F Kiragana letter KU] - // ^^^^ - // Note that 0x2F is the ASCII slash character - // - // ********************************************************************************** - - // Supported source arguments: half-open iterator range, container, c-array, - // and single pointer to null terminated string. - - // All source arguments except pointers to null terminated byte strings support - // multi-byte character strings which may have embedded nulls. Embedded null - // support is required for some Asian languages on Windows. - - // "const codecvt_type& cvt=codecvt()" default arguments are not used because this - // limits the impact of locale("") initialization failures on POSIX systems to programs - // that actually depend on locale(""). It further ensures that exceptions thrown - // as a result of such failues occur after main() has started, so can be caught. - - // ----- constructors ----- - - path() BOOST_NOEXCEPT {} - path(path const& p) : m_pathname(p.m_pathname) {} - - template< class Source > - path(Source const& source, typename boost::enable_if_c< - path_traits::is_pathable< typename boost::decay< Source >::type >::value && !path_detail::is_native_pathable< Source >::value - >::type* = NULL) - { - path_traits::dispatch(source, m_pathname); - } - - path(const value_type* s) : m_pathname(s) {} - path(string_type const& s) : m_pathname(s) {} - - // As of October 2015 the interaction between noexcept and =default is so troublesome - // for VC++, GCC, and probably other compilers, that =default is not used with noexcept - // functions. GCC is not even consistent for the same release on different platforms. - -#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) - path(path&& p) BOOST_NOEXCEPT : m_pathname(std::move(p.m_pathname)) - { - } - path(path&& p, codecvt_type const&) BOOST_NOEXCEPT : m_pathname(std::move(p.m_pathname)) - { - } - path& operator=(path&& p) BOOST_NOEXCEPT - { - m_pathname = std::move(p.m_pathname); - return *this; - } - path& assign(path&& p) BOOST_NOEXCEPT - { - m_pathname = std::move(p.m_pathname); - return *this; - } - path& assign(path&& p, codecvt_type const&) BOOST_NOEXCEPT - { - m_pathname = std::move(p.m_pathname); - return *this; - } - - path(string_type&& s) BOOST_NOEXCEPT : m_pathname(std::move(s)) - { - } - path(string_type&& s, codecvt_type const&) BOOST_NOEXCEPT : m_pathname(std::move(s)) - { - } - path& operator=(string_type&& p) BOOST_NOEXCEPT - { - m_pathname = std::move(p); - return *this; - } - path& assign(string_type&& p) BOOST_NOEXCEPT - { - m_pathname = std::move(p); - return *this; - } - path& assign(string_type&& p, codecvt_type const&) BOOST_NOEXCEPT - { - m_pathname = std::move(p); - return *this; - } -#endif - - path(path const& p, codecvt_type const&) : m_pathname(p.m_pathname) {} - path(const value_type* s, codecvt_type const&) : m_pathname(s) {} - path(string_type const& s, codecvt_type const&) : m_pathname(s) {} - - template< class Source > - path(Source const& source, codecvt_type const& cvt, typename boost::enable_if_c< - path_traits::is_pathable< typename boost::decay< Source >::type >::value && !path_detail::is_native_pathable< Source >::value - >::type* = NULL) - { - path_traits::dispatch(source, m_pathname, cvt); - } - - path(const value_type* begin, const value_type* end) : m_pathname(begin, end) {} - - template< class InputIterator > - path(InputIterator begin, InputIterator end, typename boost::disable_if< path_detail::is_native_char_ptr< InputIterator > >::type* = NULL) - { - if (begin != end) - { - // convert requires contiguous string, so copy - std::basic_string< typename std::iterator_traits< InputIterator >::value_type > seq(begin, end); - path_traits::convert(seq.c_str(), seq.c_str() + seq.size(), m_pathname); - } - } - - path(const value_type* begin, const value_type* end, codecvt_type const&) : m_pathname(begin, end) {} - - template< class InputIterator > - path(InputIterator begin, InputIterator end, codecvt_type const& cvt, typename boost::disable_if< path_detail::is_native_char_ptr< InputIterator > >::type* = NULL) - { - if (begin != end) - { - // convert requires contiguous string, so copy - std::basic_string< typename std::iterator_traits< InputIterator >::value_type > seq(begin, end); - path_traits::convert(seq.c_str(), seq.c_str() + seq.size(), m_pathname, cvt); - } - } - - // ----- assignments ----- - - // We need to explicitly define copy assignment as otherwise it will be implicitly defined as deleted because there is move assignment - path& operator=(path const& p) - { - return assign(p); - } - - path& operator=(string_type const& s) - { - return assign(s); - } - - path& operator=(const value_type* ptr) - { - return assign(ptr); - } - - template< class Source > - typename boost::enable_if_c< - path_traits::is_pathable< typename boost::decay< Source >::type >::value && !path_detail::is_native_pathable< Source >::value, - path& - >::type operator=(Source const& source) - { - return assign(source); - } - - path& assign(path const& p) - { - m_pathname = p.m_pathname; - return *this; - } - - path& assign(string_type const& s) - { - m_pathname = s; - return *this; - } - - path& assign(const value_type* ptr) - { - m_pathname = ptr; - return *this; - } - - template< class Source > - typename boost::enable_if_c< - path_traits::is_pathable< typename boost::decay< Source >::type >::value && !path_detail::is_native_pathable< Source >::value, - path& - >::type assign(Source const& source) - { - m_pathname.clear(); - path_traits::dispatch(source, m_pathname); - return *this; - } - - path& assign(path const& p, codecvt_type const&) - { - m_pathname = p.m_pathname; - return *this; - } - - path& assign(string_type const& s, codecvt_type const&) - { - m_pathname = s; - return *this; - } - - path& assign(const value_type* ptr, codecvt_type const&) - { - m_pathname = ptr; - return *this; - } - - template< class Source > - typename boost::enable_if_c< - path_traits::is_pathable< typename boost::decay< Source >::type >::value && !path_detail::is_native_pathable< Source >::value, - path& - >::type assign(Source const& source, codecvt_type const& cvt) - { - m_pathname.clear(); - path_traits::dispatch(source, m_pathname, cvt); - return *this; - } - - path& assign(const value_type* begin, const value_type* end) - { - m_pathname.assign(begin, end); - return *this; - } - - template< class InputIterator > - typename boost::disable_if< path_detail::is_native_char_ptr< InputIterator >, path& >::type - assign(InputIterator begin, InputIterator end) - { - m_pathname.clear(); - if (begin != end) - { - std::basic_string< typename std::iterator_traits< InputIterator >::value_type > seq(begin, end); - path_traits::convert(seq.c_str(), seq.c_str() + seq.size(), m_pathname); - } - return *this; - } - - path& assign(const value_type* begin, const value_type* end, codecvt_type const&) - { - m_pathname.assign(begin, end); - return *this; - } - - template< class InputIterator > - typename boost::disable_if< path_detail::is_native_char_ptr< InputIterator >, path& >::type - assign(InputIterator begin, InputIterator end, codecvt_type const& cvt) - { - m_pathname.clear(); - if (begin != end) - { - std::basic_string< typename std::iterator_traits< InputIterator >::value_type > seq(begin, end); - path_traits::convert(seq.c_str(), seq.c_str() + seq.size(), m_pathname, cvt); - } - return *this; - } - - // ----- concatenation ----- - - path& operator+=(path const& p) - { - return concat(p); - } - - path& operator+=(const value_type* ptr) - { - return concat(ptr); - } - - path& operator+=(string_type const& s) - { - return concat(s); - } - - template< class Source > - typename boost::enable_if_c< - path_traits::is_pathable< typename boost::decay< Source >::type >::value && !path_detail::is_native_pathable< Source >::value, - path& - >::type operator+=(Source const& source) - { - return concat(source); - } - - path& operator+=(value_type c) - { - m_pathname.push_back(c); - return *this; - } - - template< class CharT > - typename boost::enable_if< boost::is_integral< CharT >, path& >::type - operator+=(CharT c) - { - CharT tmp[2]; - tmp[0] = c; - tmp[1] = static_cast< CharT >(0); - return concat(tmp); - } - - path& concat(path const& p) - { - m_pathname += p.m_pathname; - return *this; - } - - path& concat(const value_type* ptr) - { - m_pathname += ptr; - return *this; - } - - path& concat(string_type const& s) - { - m_pathname += s; - return *this; - } - - template< class Source > - typename boost::enable_if_c< - path_traits::is_pathable< typename boost::decay< Source >::type >::value && !path_detail::is_native_pathable< Source >::value, - path& - >::type concat(Source const& source) - { - path_traits::dispatch(source, m_pathname); - return *this; - } - - path& concat(path const& p, codecvt_type const&) - { - m_pathname += p.m_pathname; - return *this; - } - - path& concat(const value_type* ptr, codecvt_type const&) - { - m_pathname += ptr; - return *this; - } - - path& concat(string_type const& s, codecvt_type const&) - { - m_pathname += s; - return *this; - } - - template< class Source > - typename boost::enable_if_c< - path_traits::is_pathable< typename boost::decay< Source >::type >::value && !path_detail::is_native_pathable< Source >::value, - path& - >::type concat(Source const& source, codecvt_type const& cvt) - { - path_traits::dispatch(source, m_pathname, cvt); - return *this; - } - - path& concat(const value_type* begin, const value_type* end) - { - m_pathname.append(begin, end); - return *this; - } - - template< class InputIterator > - typename boost::disable_if< path_detail::is_native_char_ptr< InputIterator >, path& >::type - concat(InputIterator begin, InputIterator end) - { - if (begin != end) - { - std::basic_string< typename std::iterator_traits< InputIterator >::value_type > seq(begin, end); - path_traits::convert(seq.c_str(), seq.c_str() + seq.size(), m_pathname); - } - return *this; - } - - path& concat(const value_type* begin, const value_type* end, codecvt_type const&) - { - m_pathname.append(begin, end); - return *this; - } - - template< class InputIterator > - typename boost::disable_if< path_detail::is_native_char_ptr< InputIterator >, path& >::type - concat(InputIterator begin, InputIterator end, codecvt_type const& cvt) - { - if (begin != end) - { - std::basic_string< typename std::iterator_traits< InputIterator >::value_type > seq(begin, end); - path_traits::convert(seq.c_str(), seq.c_str() + seq.size(), m_pathname, cvt); - } - return *this; - } - - // ----- appends ----- - - // if a separator is added, it is the preferred separator for the platform; - // slash for POSIX, backslash for Windows - - path& operator/=(path const& p) - { - return append(p); - } - - path& operator/=(const value_type* ptr) - { - return append(ptr); - } - - path& operator/=(string_type const& s) - { - return append(s); - } - - template< class Source > - BOOST_FORCEINLINE typename boost::enable_if_c< - path_traits::is_pathable< typename boost::decay< Source >::type >::value && !path_detail::is_native_pathable< Source >::value, - path& - >::type operator/=(Source const& source) - { - return append(source); - } - - BOOST_FORCEINLINE path& append(path const& p) - { - BOOST_FILESYSTEM_VERSIONED_SYM(append)(p); - return *this; - } - - BOOST_FORCEINLINE path& append(string_type const& p) - { - BOOST_FILESYSTEM_VERSIONED_SYM(append)(p.c_str(), p.c_str() + p.size()); - return *this; - } - - BOOST_FORCEINLINE path& append(const value_type* ptr) - { - BOOST_FILESYSTEM_VERSIONED_SYM(append)(ptr, ptr + string_type::traits_type::length(ptr)); - return *this; - } - - template< class Source > - typename boost::enable_if_c< - path_traits::is_pathable< typename boost::decay< Source >::type >::value && !path_detail::is_native_pathable< Source >::value, - path& - >::type append(Source const& source) - { - path p; - path_traits::dispatch(source, p.m_pathname); - return append(p); - } - - BOOST_FORCEINLINE path& append(path const& p, codecvt_type const&) - { - BOOST_FILESYSTEM_VERSIONED_SYM(append)(p); - return *this; - } - - BOOST_FORCEINLINE path& append(string_type const& p, codecvt_type const&) - { - BOOST_FILESYSTEM_VERSIONED_SYM(append)(p.c_str(), p.c_str() + p.size()); - return *this; - } - - BOOST_FORCEINLINE path& append(const value_type* ptr, codecvt_type const&) - { - BOOST_FILESYSTEM_VERSIONED_SYM(append)(ptr, ptr + string_type::traits_type::length(ptr)); - return *this; - } - - template< class Source > - typename boost::enable_if_c< - path_traits::is_pathable< typename boost::decay< Source >::type >::value && !path_detail::is_native_pathable< Source >::value, - path& - >::type append(Source const& source, codecvt_type const& cvt) - { - path p; - path_traits::dispatch(source, p.m_pathname, cvt); - return append(p); - } - - BOOST_FORCEINLINE path& append(const value_type* begin, const value_type* end) - { - BOOST_FILESYSTEM_VERSIONED_SYM(append)(begin, end); - return *this; - } - - template< class InputIterator > - typename boost::disable_if< path_detail::is_native_char_ptr< InputIterator >, path& >::type - append(InputIterator begin, InputIterator end) - { - path p; - if (begin != end) - { - std::basic_string< typename std::iterator_traits< InputIterator >::value_type > seq(begin, end); - path_traits::convert(seq.c_str(), seq.c_str() + seq.size(), p.m_pathname); - } - return append(p); - } - - BOOST_FORCEINLINE path& append(const value_type* begin, const value_type* end, codecvt_type const&) - { - BOOST_FILESYSTEM_VERSIONED_SYM(append)(begin, end); - return *this; - } - - template< class InputIterator > - typename boost::disable_if< path_detail::is_native_char_ptr< InputIterator >, path& >::type - append(InputIterator begin, InputIterator end, const codecvt_type& cvt) - { - path p; - if (begin != end) - { - std::basic_string< typename std::iterator_traits< InputIterator >::value_type > seq(begin, end); - path_traits::convert(seq.c_str(), seq.c_str() + seq.size(), p.m_pathname, cvt); - } - return append(p); - } - - // ----- modifiers ----- - - void clear() BOOST_NOEXCEPT { m_pathname.clear(); } -#ifdef BOOST_POSIX_API - path& make_preferred() - { - // No effect on POSIX - return *this; - } -#else // BOOST_WINDOWS_API - BOOST_FILESYSTEM_DECL path& make_preferred(); // change slashes to backslashes -#endif - BOOST_FILESYSTEM_DECL path& remove_filename(); - BOOST_FILESYSTEM_DECL path& remove_trailing_separator(); - BOOST_FORCEINLINE path& replace_extension(path const& new_extension = path()) - { - BOOST_FILESYSTEM_VERSIONED_SYM(replace_extension)(new_extension); - return *this; - } - void swap(path& rhs) BOOST_NOEXCEPT { m_pathname.swap(rhs.m_pathname); } - - // ----- observers ----- - - // For operating systems that format file paths differently than directory - // paths, return values from observers are formatted as file names unless there - // is a trailing separator, in which case returns are formatted as directory - // paths. POSIX and Windows make no such distinction. - - // Implementations are permitted to return const values or const references. - - // The string or path returned by an observer are specified as being formatted - // as "native" or "generic". - // - // For POSIX, these are all the same format; slashes and backslashes are as input and - // are not modified. - // - // For Windows, native: as input; slashes and backslashes are not modified; - // this is the format of the internally stored string. - // generic: backslashes are converted to slashes - - // ----- native format observers ----- - - string_type const& native() const BOOST_NOEXCEPT { return m_pathname; } - const value_type* c_str() const BOOST_NOEXCEPT { return m_pathname.c_str(); } - string_type::size_type size() const BOOST_NOEXCEPT { return m_pathname.size(); } - - template< class String > - String string() const; - - template< class String > - String string(codecvt_type const& cvt) const; - -#ifdef BOOST_WINDOWS_API - std::string string() const - { - std::string tmp; - if (!m_pathname.empty()) - path_traits::convert(m_pathname.c_str(), m_pathname.c_str() + m_pathname.size(), tmp); - return tmp; - } - std::string string(codecvt_type const& cvt) const - { - std::string tmp; - if (!m_pathname.empty()) - path_traits::convert(m_pathname.c_str(), m_pathname.c_str() + m_pathname.size(), tmp, cvt); - return tmp; - } - - // string_type is std::wstring, so there is no conversion - std::wstring const& wstring() const { return m_pathname; } - std::wstring const& wstring(codecvt_type const&) const { return m_pathname; } -#else // BOOST_POSIX_API - // string_type is std::string, so there is no conversion - std::string const& string() const { return m_pathname; } - std::string const& string(codecvt_type const&) const { return m_pathname; } - - std::wstring wstring() const - { - std::wstring tmp; - if (!m_pathname.empty()) - path_traits::convert(m_pathname.c_str(), m_pathname.c_str() + m_pathname.size(), tmp); - return tmp; - } - std::wstring wstring(codecvt_type const& cvt) const - { - std::wstring tmp; - if (!m_pathname.empty()) - path_traits::convert(m_pathname.c_str(), m_pathname.c_str() + m_pathname.size(), tmp, cvt); - return tmp; - } -#endif - - // ----- generic format observers ----- - - // Experimental generic function returning generic formatted path (i.e. separators - // are forward slashes). Motivation: simpler than a family of generic_*string - // functions. -#ifdef BOOST_WINDOWS_API - BOOST_FILESYSTEM_DECL path generic_path() const; -#else - path generic_path() const { return path(*this); } -#endif - - template< class String > - String generic_string() const; - - template< class String > - String generic_string(codecvt_type const& cvt) const; - -#ifdef BOOST_WINDOWS_API - std::string generic_string() const { return generic_path().string(); } - std::string generic_string(codecvt_type const& cvt) const { return generic_path().string(cvt); } - std::wstring generic_wstring() const { return generic_path().wstring(); } - std::wstring generic_wstring(codecvt_type const&) const { return generic_wstring(); } -#else // BOOST_POSIX_API - // On POSIX-like systems, the generic format is the same as the native format - std::string const& generic_string() const { return m_pathname; } - std::string const& generic_string(codecvt_type const&) const { return m_pathname; } - std::wstring generic_wstring() const { return this->wstring(); } - std::wstring generic_wstring(codecvt_type const& cvt) const { return this->wstring(cvt); } -#endif - - // ----- compare ----- - - BOOST_FORCEINLINE int compare(path const& p) const BOOST_NOEXCEPT // generic, lexicographical - { - return BOOST_FILESYSTEM_VERSIONED_SYM(compare)(p); - } - int compare(std::string const& s) const { return compare(path(s)); } - int compare(const value_type* s) const { return compare(path(s)); } - - // ----- decomposition ----- - - path root_path() const { return path(m_pathname.c_str(), m_pathname.c_str() + find_root_path_size()); } - // returns 0 or 1 element path even on POSIX, root_name() is non-empty() for network paths - path root_name() const { return path(m_pathname.c_str(), m_pathname.c_str() + find_root_name_size()); } - - // returns 0 or 1 element path - path root_directory() const - { - path_detail::substring root_dir = find_root_directory(); - const value_type* p = m_pathname.c_str() + root_dir.pos; - return path(p, p + root_dir.size); - } - - path relative_path() const - { - path_detail::substring root_dir = find_relative_path(); - const value_type* p = m_pathname.c_str() + root_dir.pos; - return path(p, p + root_dir.size); - } - - path parent_path() const { return path(m_pathname.c_str(), m_pathname.c_str() + find_parent_path_size()); } - - BOOST_FORCEINLINE path filename() const { return BOOST_FILESYSTEM_VERSIONED_SYM(filename)(); } // returns 0 or 1 element path - BOOST_FORCEINLINE path stem() const { return BOOST_FILESYSTEM_VERSIONED_SYM(stem)(); } // returns 0 or 1 element path - BOOST_FORCEINLINE path extension() const { return BOOST_FILESYSTEM_VERSIONED_SYM(extension)(); } // returns 0 or 1 element path - - // ----- query ----- - - bool empty() const BOOST_NOEXCEPT { return m_pathname.empty(); } - bool filename_is_dot() const; - bool filename_is_dot_dot() const; - bool has_root_path() const { return find_root_path_size() > 0; } - bool has_root_name() const { return find_root_name_size() > 0; } - bool has_root_directory() const { return find_root_directory().size > 0; } - bool has_relative_path() const { return find_relative_path().size > 0; } - bool has_parent_path() const { return find_parent_path_size() > 0; } - BOOST_FORCEINLINE bool has_filename() const { return BOOST_FILESYSTEM_VERSIONED_SYM(has_filename)(); } - bool has_stem() const { return !stem().empty(); } - bool has_extension() const { return !extension().empty(); } - bool is_relative() const { return !is_absolute(); } - bool is_absolute() const - { - // Windows CE has no root name (aka drive letters) -#if defined(BOOST_WINDOWS_API) && !defined(UNDER_CE) - return has_root_name() && has_root_directory(); -#else - return has_root_directory(); -#endif - } - - // ----- lexical operations ----- - - BOOST_FORCEINLINE path lexically_normal() const { return BOOST_FILESYSTEM_VERSIONED_SYM(lexically_normal)(); } - BOOST_FILESYSTEM_DECL path lexically_relative(path const& base) const; - path lexically_proximate(path const& base) const - { - path tmp(lexically_relative(base)); - return tmp.empty() ? *this : tmp; - } - - // ----- iterators ----- - - class iterator; - friend class iterator; - typedef iterator const_iterator; - class reverse_iterator; - typedef reverse_iterator const_reverse_iterator; - - BOOST_FILESYSTEM_DECL iterator begin() const; - BOOST_FILESYSTEM_DECL iterator end() const; - reverse_iterator rbegin() const; - reverse_iterator rend() const; - - // ----- static member functions ----- - - static BOOST_FILESYSTEM_DECL std::locale imbue(std::locale const& loc); - static BOOST_FILESYSTEM_DECL codecvt_type const& codecvt(); - - // ----- deprecated functions ----- - -#if !defined(BOOST_FILESYSTEM_NO_DEPRECATED) - // recently deprecated functions supplied by default - path& normalize() - { - path tmp(lexically_normal()); - m_pathname.swap(tmp.m_pathname); - return *this; - } - path& remove_leaf() { return remove_filename(); } - path leaf() const { return filename(); } - path branch_path() const { return parent_path(); } - path generic() const { return generic_path(); } - bool has_leaf() const { return !m_pathname.empty(); } - bool has_branch_path() const { return !parent_path().empty(); } - bool is_complete() const { return is_absolute(); } -#endif - -#if defined(BOOST_FILESYSTEM_DEPRECATED) - // deprecated functions with enough signature or semantic changes that they are - // not supplied by default - std::string file_string() const { return string(); } - std::string directory_string() const { return string(); } - std::string native_file_string() const { return string(); } - std::string native_directory_string() const { return string(); } - string_type external_file_string() const { return native(); } - string_type external_directory_string() const { return native(); } -#endif - - //--------------------------------------------------------------------------------------// - // class path private members // - //--------------------------------------------------------------------------------------// -private: - bool has_filename_v3() const { return !m_pathname.empty(); } - bool has_filename_v4() const { return find_filename_v4_size() > 0; } - BOOST_FILESYSTEM_DECL path filename_v3() const; - path filename_v4() const - { - string_type::size_type filename_size = find_filename_v4_size(); - string_type::size_type pos = m_pathname.size() - filename_size; - const value_type* p = m_pathname.c_str() + pos; - return path(p, p + filename_size); - } - BOOST_FILESYSTEM_DECL path stem_v3() const; - BOOST_FILESYSTEM_DECL path stem_v4() const; - BOOST_FILESYSTEM_DECL path extension_v3() const; - path extension_v4() const - { - string_type::size_type extension_size = find_extension_v4_size(); - string_type::size_type pos = m_pathname.size() - extension_size; - const value_type* p = m_pathname.c_str() + pos; - return path(p, p + extension_size); - } - - BOOST_FILESYSTEM_DECL void replace_extension_v3(path const& new_extension); - BOOST_FILESYSTEM_DECL void replace_extension_v4(path const& new_extension); - - BOOST_FILESYSTEM_DECL path lexically_normal_v3() const; - BOOST_FILESYSTEM_DECL path lexically_normal_v4() const; - - BOOST_FILESYSTEM_DECL int compare_v3(path const& p) const BOOST_NOEXCEPT; - BOOST_FILESYSTEM_DECL int compare_v4(path const& p) const BOOST_NOEXCEPT; - - BOOST_FILESYSTEM_DECL void append_v3(const value_type* b, const value_type* e); - BOOST_FILESYSTEM_DECL void append_v4(const value_type* b, const value_type* e); - BOOST_FILESYSTEM_DECL void append_v3(path const& p); - BOOST_FILESYSTEM_DECL void append_v4(path const& p); - - // Returns: If separator is to be appended, m_pathname.size() before append. Otherwise 0. - // Note: An append is never performed if size()==0, so a returned 0 is unambiguous. - BOOST_FILESYSTEM_DECL string_type::size_type append_separator_if_needed(); - BOOST_FILESYSTEM_DECL void erase_redundant_separator(string_type::size_type sep_pos); - - BOOST_FILESYSTEM_DECL string_type::size_type find_root_name_size() const; - BOOST_FILESYSTEM_DECL string_type::size_type find_root_path_size() const; - BOOST_FILESYSTEM_DECL path_detail::substring find_root_directory() const; - BOOST_FILESYSTEM_DECL path_detail::substring find_relative_path() const; - BOOST_FILESYSTEM_DECL string_type::size_type find_parent_path_size() const; - BOOST_FILESYSTEM_DECL string_type::size_type find_filename_v4_size() const; - BOOST_FILESYSTEM_DECL string_type::size_type find_extension_v4_size() const; - -private: - /* - * m_pathname has the type, encoding, and format required by the native - * operating system. Thus for POSIX and Windows there is no conversion for - * passing m_pathname.c_str() to the O/S API or when obtaining a path from the - * O/S API. POSIX encoding is unspecified other than for dot and slash - * characters; POSIX just treats paths as a sequence of bytes. Windows - * encoding is UCS-2 or UTF-16 depending on the version. - */ - string_type m_pathname; // Windows: as input; backslashes NOT converted to slashes, - // slashes NOT converted to backslashes -}; - -namespace detail { -BOOST_FILESYSTEM_DECL int lex_compare_v3(path::iterator first1, path::iterator last1, path::iterator first2, path::iterator last2); -BOOST_FILESYSTEM_DECL int lex_compare_v4(path::iterator first1, path::iterator last1, path::iterator first2, path::iterator last2); -BOOST_FILESYSTEM_DECL path const& dot_path(); -BOOST_FILESYSTEM_DECL path const& dot_dot_path(); -} // namespace detail - -#ifndef BOOST_FILESYSTEM_NO_DEPRECATED -typedef path wpath; -#endif - -//------------------------------------------------------------------------------------// -// class path::iterator // -//------------------------------------------------------------------------------------// - -class path::iterator : - public boost::iterator_facade< - path::iterator, - const path, - boost::bidirectional_traversal_tag - > -{ -private: - friend class boost::iterator_core_access; - friend class boost::filesystem::path; - friend class boost::filesystem::path::reverse_iterator; - friend BOOST_FILESYSTEM_DECL int detail::lex_compare_v3(path::iterator first1, path::iterator last1, path::iterator first2, path::iterator last2); - - path const& dereference() const { return m_element; } - - bool equal(iterator const& rhs) const - { - return m_path_ptr == rhs.m_path_ptr && m_pos == rhs.m_pos; - } - - BOOST_FORCEINLINE void increment() { BOOST_FILESYSTEM_VERSIONED_SYM(increment)(); } - BOOST_FORCEINLINE void decrement() { BOOST_FILESYSTEM_VERSIONED_SYM(decrement)(); } - -private: - BOOST_FILESYSTEM_DECL void increment_v3(); - BOOST_FILESYSTEM_DECL void increment_v4(); - BOOST_FILESYSTEM_DECL void decrement_v3(); - BOOST_FILESYSTEM_DECL void decrement_v4(); - -private: - // current element - path m_element; - // path being iterated over - const path* m_path_ptr; - // position of m_element in m_path_ptr->m_pathname. - // if m_element is implicit dot, m_pos is the - // position of the last separator in the path. - // end() iterator is indicated by - // m_pos == m_path_ptr->m_pathname.size() - string_type::size_type m_pos; -}; - -//------------------------------------------------------------------------------------// -// class path::reverse_iterator // -//------------------------------------------------------------------------------------// - -class path::reverse_iterator : - public boost::iterator_facade< - path::reverse_iterator, - const path, - boost::bidirectional_traversal_tag - > -{ -public: - explicit reverse_iterator(iterator itr) : - m_itr(itr) - { - if (itr != itr.m_path_ptr->begin()) - m_element = *--itr; - } - -private: - friend class boost::iterator_core_access; - friend class boost::filesystem::path; - - path const& dereference() const { return m_element; } - bool equal(reverse_iterator const& rhs) const { return m_itr == rhs.m_itr; } - - void increment() - { - --m_itr; - if (m_itr != m_itr.m_path_ptr->begin()) - { - iterator tmp = m_itr; - m_element = *--tmp; - } - } - - void decrement() - { - m_element = *m_itr; - ++m_itr; - } - -private: - iterator m_itr; - path m_element; -}; - -//------------------------------------------------------------------------------------// -// // -// non-member functions // -// // -//------------------------------------------------------------------------------------// - -// std::lexicographical_compare would infinitely recurse because path iterators -// yield paths, so provide a path aware version -inline bool lexicographical_compare(path::iterator first1, path::iterator last1, path::iterator first2, path::iterator last2) -{ - return BOOST_FILESYSTEM_VERSIONED_SYM(detail::lex_compare)(first1, last1, first2, last2) < 0; -} - -inline bool operator==(path const& lhs, path const& rhs) -{ - return lhs.compare(rhs) == 0; -} - -inline bool operator==(path const& lhs, path::string_type const& rhs) -{ - return lhs.compare(rhs) == 0; -} - -inline bool operator==(path::string_type const& lhs, path const& rhs) -{ - return rhs.compare(lhs) == 0; -} - -inline bool operator==(path const& lhs, const path::value_type* rhs) -{ - return lhs.compare(rhs) == 0; -} - -inline bool operator==(const path::value_type* lhs, path const& rhs) -{ - return rhs.compare(lhs) == 0; -} - -inline bool operator!=(path const& lhs, path const& rhs) -{ - return lhs.compare(rhs) != 0; -} - -inline bool operator!=(path const& lhs, path::string_type const& rhs) -{ - return lhs.compare(rhs) != 0; -} - -inline bool operator!=(path::string_type const& lhs, path const& rhs) -{ - return rhs.compare(lhs) != 0; -} - -inline bool operator!=(path const& lhs, const path::value_type* rhs) -{ - return lhs.compare(rhs) != 0; -} - -inline bool operator!=(const path::value_type* lhs, path const& rhs) -{ - return rhs.compare(lhs) != 0; -} - -// TODO: why do == and != have additional overloads, but the others don't? - -inline bool operator<(path const& lhs, path const& rhs) -{ - return lhs.compare(rhs) < 0; -} -inline bool operator<=(path const& lhs, path const& rhs) -{ - return !(rhs < lhs); -} -inline bool operator>(path const& lhs, path const& rhs) -{ - return rhs < lhs; -} -inline bool operator>=(path const& lhs, path const& rhs) -{ - return !(lhs < rhs); -} - -// Note: Declared as a template to delay binding to Boost.ContainerHash functions and make the dependency optional -template< typename T > -inline typename boost::enable_if< boost::is_same< T, path >, std::size_t >::type hash_value(T const& p) BOOST_NOEXCEPT -{ -#ifdef BOOST_WINDOWS_API - std::size_t seed = 0u; - for (typename T::value_type const* it = p.c_str(); *it; ++it) - hash_combine(seed, *it == L'/' ? L'\\' : *it); - return seed; -#else // BOOST_POSIX_API - return hash_range(p.native().begin(), p.native().end()); -#endif -} - -inline void swap(path& lhs, path& rhs) BOOST_NOEXCEPT -{ - lhs.swap(rhs); -} - -inline path operator/(path const& lhs, path const& rhs) -{ - path p = lhs; - p /= rhs; - return p; -} - -#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) -inline path operator/(path&& lhs, path const& rhs) -{ - lhs /= rhs; - return std::move(lhs); -} -#endif - -// inserters and extractors -// use boost::io::quoted() to handle spaces in paths -// use '&' as escape character to ease use for Windows paths - -template< class Char, class Traits > -inline std::basic_ostream< Char, Traits >& -operator<<(std::basic_ostream< Char, Traits >& os, path const& p) -{ - return os << boost::io::quoted(p.template string< std::basic_string< Char > >(), static_cast< Char >('&')); -} - -template< class Char, class Traits > -inline std::basic_istream< Char, Traits >& -operator>>(std::basic_istream< Char, Traits >& is, path& p) -{ - std::basic_string< Char > str; - is >> boost::io::quoted(str, static_cast< Char >('&')); - p = str; - return is; -} - -// name_checks - -// These functions are holdovers from version 1. It isn't clear they have much -// usefulness, or how to generalize them for later versions. - -BOOST_FILESYSTEM_DECL bool portable_posix_name(std::string const& name); -BOOST_FILESYSTEM_DECL bool windows_name(std::string const& name); -BOOST_FILESYSTEM_DECL bool portable_name(std::string const& name); -BOOST_FILESYSTEM_DECL bool portable_directory_name(std::string const& name); -BOOST_FILESYSTEM_DECL bool portable_file_name(std::string const& name); -BOOST_FILESYSTEM_DECL bool native(std::string const& name); - -namespace detail { - -// For POSIX, is_directory_separator() and is_element_separator() are identical since -// a forward slash is the only valid directory separator and also the only valid -// element separator. For Windows, forward slash and back slash are the possible -// directory separators, but colon (example: "c:foo") is also an element separator. -inline bool is_directory_separator(path::value_type c) BOOST_NOEXCEPT -{ - return c == path::separator -#ifdef BOOST_WINDOWS_API - || c == path::preferred_separator -#endif - ; -} - -inline bool is_element_separator(path::value_type c) BOOST_NOEXCEPT -{ - return c == path::separator -#ifdef BOOST_WINDOWS_API - || c == path::preferred_separator || c == L':' -#endif - ; -} - -} // namespace detail - -//------------------------------------------------------------------------------------// -// class path miscellaneous function implementations // -//------------------------------------------------------------------------------------// - -inline path::reverse_iterator path::rbegin() const -{ - return reverse_iterator(end()); -} -inline path::reverse_iterator path::rend() const -{ - return reverse_iterator(begin()); -} - -inline bool path::filename_is_dot() const -{ - // implicit dot is tricky, so actually call filename(); see path::filename() example - // in reference.html - path p(filename()); - return p.size() == 1 && *p.c_str() == dot; -} - -inline bool path::filename_is_dot_dot() const -{ - return size() >= 2 && m_pathname[size() - 1] == dot && m_pathname[size() - 2] == dot && (m_pathname.size() == 2 || detail::is_element_separator(m_pathname[size() - 3])); - // use detail::is_element_separator() rather than detail::is_directory_separator - // to deal with "c:.." edge case on Windows when ':' acts as a separator -} - -//--------------------------------------------------------------------------------------// -// class path member template specializations // -//--------------------------------------------------------------------------------------// - -template<> -inline std::string path::string< std::string >() const -{ - return string(); -} - -template<> -inline std::wstring path::string< std::wstring >() const -{ - return wstring(); -} - -template<> -inline std::string path::string< std::string >(const codecvt_type& cvt) const -{ - return string(cvt); -} - -template<> -inline std::wstring path::string< std::wstring >(const codecvt_type& cvt) const -{ - return wstring(cvt); -} - -template<> -inline std::string path::generic_string< std::string >() const -{ - return generic_string(); -} - -template<> -inline std::wstring path::generic_string< std::wstring >() const -{ - return generic_wstring(); -} - -template<> -inline std::string path::generic_string< std::string >(codecvt_type const& cvt) const -{ - return generic_string(cvt); -} - -template<> -inline std::wstring path::generic_string< std::wstring >(codecvt_type const& cvt) const -{ - return generic_wstring(cvt); -} - -//--------------------------------------------------------------------------------------// -// path_traits convert function implementations // -// requiring path::codecvt() be visable // -//--------------------------------------------------------------------------------------// - -namespace path_traits { // without codecvt - -inline void convert(const char* from, - const char* from_end, // NULL for null terminated MBCS - std::wstring& to) -{ - convert(from, from_end, to, path::codecvt()); -} - -inline void convert(const wchar_t* from, - const wchar_t* from_end, // NULL for null terminated MBCS - std::string& to) -{ - convert(from, from_end, to, path::codecvt()); -} - -inline void convert(const char* from, std::wstring& to) -{ - BOOST_ASSERT(!!from); - convert(from, NULL, to, path::codecvt()); -} - -inline void convert(const wchar_t* from, std::string& to) -{ - BOOST_ASSERT(!!from); - convert(from, NULL, to, path::codecvt()); -} - -} // namespace path_traits -} // namespace filesystem -} // namespace boost - -//----------------------------------------------------------------------------// - -#include <boost/filesystem/detail/footer.hpp> - -#endif // BOOST_FILESYSTEM_PATH_HPP diff --git a/contrib/restricted/boost/filesystem/include/boost/filesystem/path_traits.hpp b/contrib/restricted/boost/filesystem/include/boost/filesystem/path_traits.hpp deleted file mode 100644 index e4f9b52c0d..0000000000 --- a/contrib/restricted/boost/filesystem/include/boost/filesystem/path_traits.hpp +++ /dev/null @@ -1,384 +0,0 @@ -// filesystem path_traits.hpp --------------------------------------------------------// - -// Copyright Beman Dawes 2009 - -// Distributed under the Boost Software License, Version 1.0. -// See http://www.boost.org/LICENSE_1_0.txt - -// Library home page: http://www.boost.org/libs/filesystem - -#ifndef BOOST_FILESYSTEM_PATH_TRAITS_HPP -#define BOOST_FILESYSTEM_PATH_TRAITS_HPP - -#include <boost/filesystem/config.hpp> -#include <boost/system/error_category.hpp> -#include <boost/type_traits/is_array.hpp> -#include <boost/type_traits/decay.hpp> -#include <boost/core/enable_if.hpp> -#include <cstddef> -#include <cwchar> // for mbstate_t -#include <string> -#include <vector> -#include <list> -#include <iterator> -#include <locale> -#include <boost/assert.hpp> - -#include <boost/filesystem/detail/header.hpp> // must be the last #include - -namespace boost { -namespace filesystem { - -BOOST_FILESYSTEM_DECL system::error_category const& codecvt_error_category() BOOST_NOEXCEPT; -// uses std::codecvt_base::result used for error codes: -// -// ok: Conversion successful. -// partial: Not all source characters converted; one or more additional source -// characters are needed to produce the final target character, or the -// size of the target intermediate buffer was too small to hold the result. -// error: A character in the source could not be converted to the target encoding. -// noconv: The source and target characters have the same type and encoding, so no -// conversion was necessary. - -class directory_entry; - -namespace path_traits { - -typedef std::codecvt< wchar_t, char, std::mbstate_t > codecvt_type; - -// is_pathable type trait; allows disabling over-agressive class path member templates - -template< class T > -struct is_pathable -{ - static const bool value = false; -}; - -template<> -struct is_pathable< char* > -{ - static const bool value = true; -}; - -template<> -struct is_pathable< const char* > -{ - static const bool value = true; -}; - -template<> -struct is_pathable< wchar_t* > -{ - static const bool value = true; -}; - -template<> -struct is_pathable< const wchar_t* > -{ - static const bool value = true; -}; - -template<> -struct is_pathable< std::string > -{ - static const bool value = true; -}; - -template<> -struct is_pathable< std::wstring > -{ - static const bool value = true; -}; - -template<> -struct is_pathable< std::vector< char > > -{ - static const bool value = true; -}; - -template<> -struct is_pathable< std::vector< wchar_t > > -{ - static const bool value = true; -}; - -template<> -struct is_pathable< std::list< char > > -{ - static const bool value = true; -}; - -template<> -struct is_pathable< std::list< wchar_t > > -{ - static const bool value = true; -}; - -template<> -struct is_pathable< directory_entry > -{ - static const bool value = true; -}; - -// Pathable empty - -template< class Container > -inline - // disable_if aids broken compilers (IBM, old GCC, etc.) and is harmless for - // conforming compilers. Replace by plain "bool" at some future date (2012?) - typename boost::disable_if< boost::is_array< Container >, bool >::type - empty(Container const& c) -{ - return c.begin() == c.end(); -} - -template< class T > -inline bool empty(T* const& c_str) -{ - BOOST_ASSERT(c_str); - return !*c_str; -} - -template< typename T, std::size_t N > -inline bool empty(T (&x)[N]) -{ - return !x[0]; -} - -// value types differ ---------------------------------------------------------------// -// -// A from_end argument of NULL is less efficient than a known end, so use only if needed - -// with codecvt - -BOOST_FILESYSTEM_DECL -void convert(const char* from, - const char* from_end, // NULL for null terminated MBCS - std::wstring& to, codecvt_type const& cvt); - -BOOST_FILESYSTEM_DECL -void convert(const wchar_t* from, - const wchar_t* from_end, // NULL for null terminated MBCS - std::string& to, codecvt_type const& cvt); - -inline void convert(const char* from, std::wstring& to, codecvt_type const& cvt) -{ - BOOST_ASSERT(from); - convert(from, NULL, to, cvt); -} - -inline void convert(const wchar_t* from, std::string& to, codecvt_type const& cvt) -{ - BOOST_ASSERT(from); - convert(from, NULL, to, cvt); -} - -// without codecvt - -inline void convert(const char* from, - const char* from_end, // NULL for null terminated MBCS - std::wstring& to); - -inline void convert(const wchar_t* from, - const wchar_t* from_end, // NULL for null terminated MBCS - std::string& to); - -inline void convert(const char* from, std::wstring& to); - -inline void convert(const wchar_t* from, std::string& to); - -// value types same -----------------------------------------------------------------// - -// char with codecvt - -inline void convert(const char* from, const char* from_end, std::string& to, codecvt_type const&) -{ - BOOST_ASSERT(from); - BOOST_ASSERT(from_end); - to.append(from, from_end); -} - -inline void convert(const char* from, std::string& to, codecvt_type const&) -{ - BOOST_ASSERT(from); - to += from; -} - -// wchar_t with codecvt - -inline void convert(const wchar_t* from, const wchar_t* from_end, std::wstring& to, codecvt_type const&) -{ - BOOST_ASSERT(from); - BOOST_ASSERT(from_end); - to.append(from, from_end); -} - -inline void convert(const wchar_t* from, std::wstring& to, codecvt_type const&) -{ - BOOST_ASSERT(from); - to += from; -} - -// char without codecvt - -inline void convert(const char* from, const char* from_end, std::string& to) -{ - BOOST_ASSERT(from); - BOOST_ASSERT(from_end); - to.append(from, from_end); -} - -inline void convert(const char* from, std::string& to) -{ - BOOST_ASSERT(from); - to += from; -} - -// wchar_t without codecvt - -inline void convert(const wchar_t* from, const wchar_t* from_end, std::wstring& to) -{ - BOOST_ASSERT(from); - BOOST_ASSERT(from_end); - to.append(from, from_end); -} - -inline void convert(const wchar_t* from, std::wstring& to) -{ - BOOST_ASSERT(from); - to += from; -} - -// Source dispatch -----------------------------------------------------------------// - -// contiguous containers with codecvt -template< class U > -inline void dispatch(std::string const& c, U& to, codecvt_type const& cvt) -{ - if (!c.empty()) - convert(&*c.begin(), &*c.begin() + c.size(), to, cvt); -} -template< class U > -inline void dispatch(std::wstring const& c, U& to, codecvt_type const& cvt) -{ - if (!c.empty()) - convert(&*c.begin(), &*c.begin() + c.size(), to, cvt); -} -template< class U > -inline void dispatch(std::vector< char > const& c, U& to, codecvt_type const& cvt) -{ - if (!c.empty()) - convert(&*c.begin(), &*c.begin() + c.size(), to, cvt); -} -template< class U > -inline void dispatch(std::vector< wchar_t > const& c, U& to, codecvt_type const& cvt) -{ - if (!c.empty()) - convert(&*c.begin(), &*c.begin() + c.size(), to, cvt); -} - -// contiguous containers without codecvt -template< class U > -inline void dispatch(std::string const& c, U& to) -{ - if (!c.empty()) - convert(&*c.begin(), &*c.begin() + c.size(), to); -} -template< class U > -inline void dispatch(std::wstring const& c, U& to) -{ - if (!c.empty()) - convert(&*c.begin(), &*c.begin() + c.size(), to); -} -template< class U > -inline void dispatch(std::vector< char > const& c, U& to) -{ - if (!c.empty()) - convert(&*c.begin(), &*c.begin() + c.size(), to); -} -template< class U > -inline void dispatch(std::vector< wchar_t > const& c, U& to) -{ - if (!c.empty()) - convert(&*c.begin(), &*c.begin() + c.size(), to); -} - -// non-contiguous containers with codecvt -template< class Container, class U > -inline - // disable_if aids broken compilers (IBM, old GCC, etc.) and is harmless for - // conforming compilers. Replace by plain "void" at some future date (2012?) - typename boost::disable_if< boost::is_array< Container >, void >::type - dispatch(Container const& c, U& to, codecvt_type const& cvt) -{ - if (!c.empty()) - { - std::basic_string< typename Container::value_type > s(c.begin(), c.end()); - convert(s.c_str(), s.c_str() + s.size(), to, cvt); - } -} - -// c_str -template< class T, class U > -inline void dispatch(T* const& c_str, U& to, codecvt_type const& cvt) -{ - // std::cout << "dispatch() const T *\n"; - BOOST_ASSERT(c_str); - convert(c_str, to, cvt); -} - -// Note: there is no dispatch on C-style arrays because the array may -// contain a string smaller than the array size. - -BOOST_FILESYSTEM_DECL -void dispatch(directory_entry const& de, -#ifdef BOOST_WINDOWS_API - std::wstring& to, -#else - std::string& to, -#endif - codecvt_type const&); - -// non-contiguous containers without codecvt -template< class Container, class U > -inline - // disable_if aids broken compilers (IBM, old GCC, etc.) and is harmless for - // conforming compilers. Replace by plain "void" at some future date (2012?) - typename boost::disable_if< boost::is_array< Container >, void >::type - dispatch(Container const& c, U& to) -{ - if (!c.empty()) - { - std::basic_string< typename Container::value_type > seq(c.begin(), c.end()); - convert(seq.c_str(), seq.c_str() + seq.size(), to); - } -} - -// c_str -template< class T, class U > -inline void dispatch(T* const& c_str, U& to) -{ - // std::cout << "dispatch() const T *\n"; - BOOST_ASSERT(c_str); - convert(c_str, to); -} - -// Note: there is no dispatch on C-style arrays because the array may -// contain a string smaller than the array size. - -BOOST_FILESYSTEM_DECL -void dispatch(directory_entry const& de, -#ifdef BOOST_WINDOWS_API - std::wstring& to -#else - std::string& to -#endif -); - -} // namespace path_traits -} // namespace filesystem -} // namespace boost - -#include <boost/filesystem/detail/footer.hpp> - -#endif // BOOST_FILESYSTEM_PATH_TRAITS_HPP diff --git a/contrib/restricted/boost/filesystem/src/atomic_ref.hpp b/contrib/restricted/boost/filesystem/src/atomic_ref.hpp deleted file mode 100644 index 6e8208d39e..0000000000 --- a/contrib/restricted/boost/filesystem/src/atomic_ref.hpp +++ /dev/null @@ -1,32 +0,0 @@ -// atomic.hpp ------------------------------------------------------------------------// - -// Copyright 2021 Andrey Semashev - -// Distributed under the Boost Software License, Version 1.0. -// See http://www.boost.org/LICENSE_1_0.txt - -// See library home page at http://www.boost.org/libs/filesystem - -//--------------------------------------------------------------------------------------// - -#ifndef BOOST_FILESYSTEM_SRC_ATOMIC_REF_HPP_ -#define BOOST_FILESYSTEM_SRC_ATOMIC_REF_HPP_ - -#include <boost/filesystem/config.hpp> - -#if !defined(BOOST_FILESYSTEM_NO_CXX20_ATOMIC_REF) - -#include <atomic> - -namespace atomic_ns = std; - -#else // !defined(BOOST_FILESYSTEM_NO_CXX20_ATOMIC_REF) - -#include <boost/memory_order.hpp> -#include <boost/atomic/atomic_ref.hpp> - -namespace atomic_ns = boost; - -#endif // !defined(BOOST_FILESYSTEM_NO_CXX20_ATOMIC_REF) - -#endif // BOOST_FILESYSTEM_SRC_ATOMIC_REF_HPP_ diff --git a/contrib/restricted/boost/filesystem/src/atomic_tools.hpp b/contrib/restricted/boost/filesystem/src/atomic_tools.hpp deleted file mode 100644 index a60e5d325a..0000000000 --- a/contrib/restricted/boost/filesystem/src/atomic_tools.hpp +++ /dev/null @@ -1,69 +0,0 @@ -// atomic_tools.hpp ------------------------------------------------------------------// - -// Copyright 2021 Andrey Semashev - -// Distributed under the Boost Software License, Version 1.0. -// See http://www.boost.org/LICENSE_1_0.txt - -// See library home page at http://www.boost.org/libs/filesystem - -//--------------------------------------------------------------------------------------// - -#ifndef BOOST_FILESYSTEM_SRC_ATOMIC_TOOLS_HPP_ -#define BOOST_FILESYSTEM_SRC_ATOMIC_TOOLS_HPP_ - -#include <boost/filesystem/config.hpp> - -#if !defined(BOOST_FILESYSTEM_SINGLE_THREADED) - -#include "atomic_ref.hpp" - -namespace boost { -namespace filesystem { -namespace detail { - -//! Atomically loads the value -template< typename T > -BOOST_FORCEINLINE T atomic_load_relaxed(T& a) -{ - return atomic_ns::atomic_ref< T >(a).load(atomic_ns::memory_order_relaxed); -} - -//! Atomically stores the value -template< typename T > -BOOST_FORCEINLINE void atomic_store_relaxed(T& a, T val) -{ - atomic_ns::atomic_ref< T >(a).store(val, atomic_ns::memory_order_relaxed); -} - -} // namespace detail -} // namespace filesystem -} // namespace boost - -#else // !defined(BOOST_FILESYSTEM_SINGLE_THREADED) - -namespace boost { -namespace filesystem { -namespace detail { - -//! Atomically loads the value -template< typename T > -BOOST_FORCEINLINE T atomic_load_relaxed(T const& a) -{ - return a; -} - -//! Atomically stores the value -template< typename T > -BOOST_FORCEINLINE void atomic_store_relaxed(T& a, T val) -{ - a = val; -} - -} // namespace detail -} // namespace filesystem -} // namespace boost - -#endif // !defined(BOOST_FILESYSTEM_SINGLE_THREADED) - -#endif // BOOST_FILESYSTEM_SRC_ATOMIC_TOOLS_HPP_ diff --git a/contrib/restricted/boost/filesystem/src/codecvt_error_category.cpp b/contrib/restricted/boost/filesystem/src/codecvt_error_category.cpp deleted file mode 100644 index 72db677a09..0000000000 --- a/contrib/restricted/boost/filesystem/src/codecvt_error_category.cpp +++ /dev/null @@ -1,120 +0,0 @@ -// codecvt_error_category implementation file ----------------------------------------// - -// Copyright 2009 Beman Dawes -// Copyright 2022 Andrey Semashev - -// Distributed under the Boost Software License, Version 1.0. -// See http://www.boost.org/LICENSE_1_0.txt) - -// Library home page at http://www.boost.org/libs/filesystem - -//--------------------------------------------------------------------------------------// - -#include "platform_config.hpp" - -#include <boost/config/warning_disable.hpp> - -#include <boost/filesystem/config.hpp> -#include <boost/filesystem/path_traits.hpp> -#include <boost/system/error_category.hpp> -#include <locale> -#include <string> - -#include "private_config.hpp" - -#include <boost/filesystem/detail/header.hpp> // must be the last #include - -//--------------------------------------------------------------------------------------// - -namespace boost { -namespace filesystem { - -namespace { - -#if (defined(BOOST_GCC) && BOOST_GCC >= 40600) || defined(BOOST_CLANG) -#pragma GCC diagnostic push -// '(anonymous namespace)::codecvt_error_cat' has virtual functions but non-virtual destructor -// This is not a problem as instances of codecvt_error_cat are never destroyed through a pointer to base. -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#endif - -class codecvt_error_cat BOOST_FINAL : - public boost::system::error_category -{ -public: - // clang up to version 3.8 requires a user-defined default constructor in order to be able to declare a static constant of the error category. - BOOST_SYSTEM_CONSTEXPR codecvt_error_cat() BOOST_NOEXCEPT {} - const char* name() const BOOST_NOEXCEPT BOOST_OVERRIDE; - std::string message(int ev) const BOOST_OVERRIDE; -}; - -const char* codecvt_error_cat::name() const BOOST_NOEXCEPT -{ - return "codecvt"; -} - -std::string codecvt_error_cat::message(int ev) const -{ - std::string str; - switch (ev) - { - case std::codecvt_base::ok: - str = "ok"; - break; - case std::codecvt_base::partial: - str = "partial"; - break; - case std::codecvt_base::error: - str = "error"; - break; - case std::codecvt_base::noconv: - str = "noconv"; - break; - default: - str = "unknown error"; - break; - } - return str; -} - -#if (defined(BOOST_GCC) && BOOST_GCC >= 40600) || defined(BOOST_CLANG) -#pragma GCC diagnostic pop -#endif - -} // unnamed namespace - -BOOST_FILESYSTEM_DECL boost::system::error_category const& codecvt_error_category() BOOST_NOEXCEPT -{ - static -#if defined(BOOST_SYSTEM_HAS_CONSTEXPR) - constexpr -#else - const -#endif - codecvt_error_cat codecvt_error_cat_const; - return codecvt_error_cat_const; -} - -// Try to initialize the error category instance as early as possible to make sure it is -// available during global deinitialization stage. For MSVC, codecvt_error_category() will -// be called early by MSVC-specific initialization routine in path.cpp. -#if !defined(BOOST_SYSTEM_HAS_CONSTEXPR) && !defined(_MSC_VER) - -namespace { - -struct codecvt_error_category_initializer -{ - codecvt_error_category_initializer() { boost::filesystem::codecvt_error_category(); } -}; - -BOOST_FILESYSTEM_INIT_PRIORITY(BOOST_FILESYSTEM_PATH_GLOBALS_INIT_PRIORITY) BOOST_ATTRIBUTE_UNUSED BOOST_FILESYSTEM_ATTRIBUTE_RETAIN -const codecvt_error_category_initializer g_codecvt_error_category_initializer; - -} // namespace - -#endif // !defined(BOOST_SYSTEM_HAS_CONSTEXPR) && !defined(_MSC_VER) - -} // namespace filesystem -} // namespace boost - -#include <boost/filesystem/detail/footer.hpp> diff --git a/contrib/restricted/boost/filesystem/src/directory.cpp b/contrib/restricted/boost/filesystem/src/directory.cpp deleted file mode 100644 index 6a3e1dc731..0000000000 --- a/contrib/restricted/boost/filesystem/src/directory.cpp +++ /dev/null @@ -1,1495 +0,0 @@ -// directory.cpp --------------------------------------------------------------------// - -// Copyright 2002-2009, 2014 Beman Dawes -// Copyright 2001 Dietmar Kuehl -// Copyright 2019, 2022 Andrey Semashev - -// Distributed under the Boost Software License, Version 1.0. -// See http://www.boost.org/LICENSE_1_0.txt - -// See library home page at http://www.boost.org/libs/filesystem - -//--------------------------------------------------------------------------------------// - -#include "platform_config.hpp" - -#include <boost/throw_exception.hpp> -#include <boost/filesystem/config.hpp> -#include <boost/filesystem/directory.hpp> -#include <boost/filesystem/exception.hpp> -#include <boost/filesystem/operations.hpp> -#include <boost/filesystem/file_status.hpp> - -#include <cstddef> -#include <cerrno> -#include <cstring> -#include <cstdlib> // std::malloc, std::free -#include <new> // std::nothrow, std::bad_alloc -#include <limits> -#include <string> -#include <utility> // std::move -#include <boost/assert.hpp> -#include <boost/system/error_code.hpp> -#include <boost/smart_ptr/intrusive_ptr.hpp> - -#ifdef BOOST_POSIX_API - -#include <sys/types.h> -#include <sys/stat.h> -#include <dirent.h> -#include <unistd.h> -#include <fcntl.h> - -#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) && (_POSIX_THREAD_SAFE_FUNCTIONS >= 0) && defined(_SC_THREAD_SAFE_FUNCTIONS) && \ - !defined(__CYGWIN__) && \ - !(defined(linux) || defined(__linux) || defined(__linux__)) && \ - !defined(__ANDROID__) && \ - (!defined(__hpux) || defined(_REENTRANT)) && \ - (!defined(_AIX) || defined(__THREAD_SAFE)) && \ - !defined(__wasm) -#define BOOST_FILESYSTEM_USE_READDIR_R -#endif - -// At least Mac OS X 10.6 and older doesn't support O_CLOEXEC -#ifndef O_CLOEXEC -#define O_CLOEXEC 0 -#define BOOST_FILESYSTEM_NO_O_CLOEXEC -#endif - -#include "posix_tools.hpp" - -#else // BOOST_WINDOWS_API - -#include <cwchar> -#include <windows.h> -#include <boost/winapi/basic_types.hpp> // NTSTATUS_ - -#include "windows_tools.hpp" - -#endif // BOOST_WINDOWS_API - -#include "atomic_tools.hpp" -#include "error_handling.hpp" -#include "private_config.hpp" - -#include <boost/filesystem/detail/header.hpp> // must be the last #include - -// BOOST_FILESYSTEM_STATUS_CACHE enables file_status cache in -// dir_itr_increment. The config tests are placed here because some of the -// macros being tested come from dirent.h. -// -// TODO: find out what macros indicate dirent::d_type present in more libraries -#if defined(BOOST_WINDOWS_API) || defined(_DIRENT_HAVE_D_TYPE) // defined by GNU C library if d_type present -#define BOOST_FILESYSTEM_STATUS_CACHE -#endif - -namespace fs = boost::filesystem; -using boost::system::error_code; -using boost::system::system_category; - -namespace boost { -namespace filesystem { - -//--------------------------------------------------------------------------------------// -// // -// directory_entry // -// // -//--------------------------------------------------------------------------------------// - -BOOST_FILESYSTEM_DECL -file_status directory_entry::get_status(system::error_code* ec) const -{ - if (!status_known(m_status)) - { - // optimization: if the symlink status is known, and it isn't a symlink, - // then status and symlink_status are identical so just copy the - // symlink status to the regular status. - if (status_known(m_symlink_status) && !is_symlink(m_symlink_status)) - { - m_status = m_symlink_status; - if (ec) - ec->clear(); - } - else - { - m_status = detail::status(m_path, ec); - } - } - else if (ec) - { - ec->clear(); - } - - return m_status; -} - -BOOST_FILESYSTEM_DECL -file_status directory_entry::get_symlink_status(system::error_code* ec) const -{ - if (!status_known(m_symlink_status)) - m_symlink_status = detail::symlink_status(m_path, ec); - else if (ec) - ec->clear(); - - return m_symlink_status; -} - -// dispatch directory_entry supplied here rather than in -// <boost/filesystem/path_traits.hpp>, thus avoiding header circularity. -// test cases are in operations_unit_test.cpp - -namespace path_traits { - -BOOST_FILESYSTEM_DECL -void dispatch(directory_entry const& de, -#ifdef BOOST_WINDOWS_API - std::wstring& to, -#else - std::string& to, -#endif - codecvt_type const&) -{ - to = de.path().native(); -} - -BOOST_FILESYSTEM_DECL -void dispatch(directory_entry const& de, -#ifdef BOOST_WINDOWS_API - std::wstring& to -#else - std::string& to -#endif -) -{ - to = de.path().native(); -} - -} // namespace path_traits - -//--------------------------------------------------------------------------------------// -// // -// directory_iterator // -// // -//--------------------------------------------------------------------------------------// - -namespace detail { - -BOOST_CONSTEXPR_OR_CONST std::size_t dir_itr_imp_extra_data_alignment = 16u; - -BOOST_FILESYSTEM_DECL void* dir_itr_imp::operator new(std::size_t class_size, std::size_t extra_size) BOOST_NOEXCEPT -{ - if (extra_size > 0) - class_size = (class_size + dir_itr_imp_extra_data_alignment - 1u) & ~(dir_itr_imp_extra_data_alignment - 1u); - std::size_t total_size = class_size + extra_size; - - // Return NULL on OOM - void* p = std::malloc(total_size); - if (BOOST_LIKELY(p != NULL)) - std::memset(p, 0, total_size); - return p; -} - -BOOST_FILESYSTEM_DECL void dir_itr_imp::operator delete(void* p, std::size_t extra_size) BOOST_NOEXCEPT -{ - std::free(p); -} - -BOOST_FILESYSTEM_DECL void dir_itr_imp::operator delete(void* p) BOOST_NOEXCEPT -{ - std::free(p); -} - -namespace { - -inline void* get_dir_itr_imp_extra_data(dir_itr_imp* imp) BOOST_NOEXCEPT -{ - BOOST_CONSTEXPR_OR_CONST std::size_t extra_data_offset = (sizeof(dir_itr_imp) + dir_itr_imp_extra_data_alignment - 1u) & ~(dir_itr_imp_extra_data_alignment - 1u); - return reinterpret_cast< unsigned char* >(imp) + extra_data_offset; -} - -#ifdef BOOST_POSIX_API - -inline system::error_code dir_itr_close(dir_itr_imp& imp) BOOST_NOEXCEPT -{ - if (imp.handle != NULL) - { - DIR* h = static_cast< DIR* >(imp.handle); - imp.handle = NULL; - int err = 0; - if (BOOST_UNLIKELY(::closedir(h) != 0)) - { - err = errno; - return error_code(err, system_category()); - } - } - - return error_code(); -} - -#if defined(BOOST_FILESYSTEM_USE_READDIR_R) - -// Obtains maximum length of a path, not including the terminating zero -inline std::size_t get_path_max() -{ - // this code is based on Stevens and Rago, Advanced Programming in the - // UNIX envirnment, 2nd Ed., ISBN 0-201-43307-9, page 49 - std::size_t max = 0; - errno = 0; - long res = ::pathconf("/", _PC_PATH_MAX); - if (res < 0) - { -#if defined(PATH_MAX) - max = PATH_MAX; -#else - max = 4096; -#endif - } - else - { - max = static_cast< std::size_t >(res); // relative root -#if defined(PATH_MAX) - if (max < PATH_MAX) - max = PATH_MAX; -#endif - } - - if ((max + 1) < sizeof(dirent().d_name)) - max = sizeof(dirent().d_name) - 1; - - return max; -} - -// Returns maximum length of a path, not including the terminating zero -inline std::size_t path_max() -{ - static const std::size_t max = get_path_max(); - return max; -} - -#endif // BOOST_FILESYSTEM_USE_READDIR_R - -// *result set to NULL on end of directory -#if !defined(BOOST_FILESYSTEM_USE_READDIR_R) -inline -#endif -int readdir_impl(dir_itr_imp& imp, struct dirent** result) -{ - errno = 0; - - struct dirent* p = ::readdir(static_cast< DIR* >(imp.handle)); - *result = p; - if (!p) - return errno; - return 0; -} - -#if !defined(BOOST_FILESYSTEM_USE_READDIR_R) - -inline int invoke_readdir(dir_itr_imp& imp, struct dirent** result) -{ - return readdir_impl(imp, result); -} - -#else // !defined(BOOST_FILESYSTEM_USE_READDIR_R) - -int readdir_r_impl(dir_itr_imp& imp, struct dirent** result) -{ - return ::readdir_r - ( - static_cast< DIR* >(imp.handle), - static_cast< struct dirent* >(get_dir_itr_imp_extra_data(&imp)), - result - ); -} - -int readdir_select_impl(dir_itr_imp& imp, struct dirent** result); - -typedef int readdir_impl_t(dir_itr_imp& imp, struct dirent** result); - -//! Pointer to the actual implementation of the copy_file_data implementation -readdir_impl_t* readdir_impl_ptr = &readdir_select_impl; - -void init_readdir_impl() -{ - readdir_impl_t* impl = &readdir_impl; - if (::sysconf(_SC_THREAD_SAFE_FUNCTIONS) >= 0) - impl = &readdir_r_impl; - - filesystem::detail::atomic_store_relaxed(readdir_impl_ptr, impl); -} - -struct readdir_initializer -{ - readdir_initializer() - { - init_readdir_impl(); - } -}; - -BOOST_FILESYSTEM_INIT_PRIORITY(BOOST_FILESYSTEM_FUNC_PTR_INIT_PRIORITY) BOOST_ATTRIBUTE_UNUSED BOOST_FILESYSTEM_ATTRIBUTE_RETAIN -const readdir_initializer readdir_init; - -int readdir_select_impl(dir_itr_imp& imp, struct dirent** result) -{ - init_readdir_impl(); - return filesystem::detail::atomic_load_relaxed(readdir_impl_ptr)(imp, result); -} - -inline int invoke_readdir(dir_itr_imp& imp, struct dirent** result) -{ - return filesystem::detail::atomic_load_relaxed(readdir_impl_ptr)(imp, result); -} - -#endif // !defined(BOOST_FILESYSTEM_USE_READDIR_R) - -error_code dir_itr_increment(dir_itr_imp& imp, fs::path& filename, fs::file_status& sf, fs::file_status& symlink_sf) -{ - dirent* result = NULL; - int err = invoke_readdir(imp, &result); - if (BOOST_UNLIKELY(err != 0)) - return error_code(err, system_category()); - if (result == NULL) - return dir_itr_close(imp); - - filename = result->d_name; - -#ifdef BOOST_FILESYSTEM_STATUS_CACHE - if (result->d_type == DT_UNKNOWN) // filesystem does not supply d_type value - { - sf = symlink_sf = fs::file_status(fs::status_error); - } - else // filesystem supplies d_type value - { - if (result->d_type == DT_DIR) - sf = symlink_sf = fs::file_status(fs::directory_file); - else if (result->d_type == DT_REG) - sf = symlink_sf = fs::file_status(fs::regular_file); - else if (result->d_type == DT_LNK) - { - sf = fs::file_status(fs::status_error); - symlink_sf = fs::file_status(fs::symlink_file); - } - else - sf = symlink_sf = fs::file_status(fs::status_error); - } -#else - sf = symlink_sf = fs::file_status(fs::status_error); -#endif - return error_code(); -} - -error_code dir_itr_create(boost::intrusive_ptr< detail::dir_itr_imp >& imp, fs::path const& dir, unsigned int opts, directory_iterator_params* params, fs::path& first_filename, fs::file_status&, fs::file_status&) -{ - std::size_t extra_size = 0u; -#if defined(BOOST_FILESYSTEM_USE_READDIR_R) - { - readdir_impl_t* rdimpl = filesystem::detail::atomic_load_relaxed(readdir_impl_ptr); - if (BOOST_UNLIKELY(rdimpl == &readdir_select_impl)) - { - init_readdir_impl(); - rdimpl = filesystem::detail::atomic_load_relaxed(readdir_impl_ptr); - } - - if (rdimpl == &readdir_r_impl) - { - // According to readdir description, there's no reliable way to predict the length of the d_name string. - // It may exceed NAME_MAX and pathconf(_PC_NAME_MAX) limits. We are being conservative here and allocate - // buffer that is enough for PATH_MAX as the directory name. Still, this doesn't guarantee there won't be - // a buffer overrun. The readdir_r API is fundamentally flawed and we should avoid it as much as possible - // in favor of readdir. - extra_size = (sizeof(dirent) - sizeof(dirent().d_name)) + path_max() + 1u; // + 1 for "\0" - } - } -#endif // defined(BOOST_FILESYSTEM_USE_READDIR_R) - - boost::intrusive_ptr< detail::dir_itr_imp > pimpl(new (extra_size) detail::dir_itr_imp()); - if (BOOST_UNLIKELY(!pimpl)) - return make_error_code(system::errc::not_enough_memory); - -#if defined(BOOST_FILESYSTEM_HAS_FDOPENDIR_NOFOLLOW) - int flags = O_DIRECTORY | O_RDONLY | O_NONBLOCK | O_CLOEXEC; - if ((opts & static_cast< unsigned int >(directory_options::_detail_no_follow)) != 0u) - flags |= O_NOFOLLOW; - -#if defined(BOOST_FILESYSTEM_HAS_POSIX_AT_APIS) - int fd = ::openat(params ? params->basedir_fd : AT_FDCWD, dir.c_str(), flags); -#else - int fd = ::open(dir.c_str(), flags); -#endif - if (BOOST_UNLIKELY(fd < 0)) - { - const int err = errno; - return error_code(err, system_category()); - } - -#if defined(BOOST_FILESYSTEM_NO_O_CLOEXEC) && defined(FD_CLOEXEC) - int res = ::fcntl(fd, F_SETFD, FD_CLOEXEC); - if (BOOST_UNLIKELY(res < 0)) - { - const int err = errno; - close_fd(fd); - return error_code(err, system_category()); - } -#endif - - pimpl->handle = ::fdopendir(fd); - if (BOOST_UNLIKELY(!pimpl->handle)) - { - const int err = errno; - close_fd(fd); - return error_code(err, system_category()); - } -#else // defined(BOOST_FILESYSTEM_HAS_FDOPENDIR_NOFOLLOW) - pimpl->handle = ::opendir(dir.c_str()); - if (BOOST_UNLIKELY(!pimpl->handle)) - { - const int err = errno; - return error_code(err, system_category()); - } -#endif // defined(BOOST_FILESYSTEM_HAS_FDOPENDIR_NOFOLLOW) - - // Force initial readdir call by the caller. This will initialize the actual first filename and statuses. - first_filename.assign("."); - -#if defined(BOOST_FILESYSTEM_HAS_FDOPENDIR_NOFOLLOW) - if (params) - params->iterator_fd = fd; -#endif - - imp.swap(pimpl); - return error_code(); -} - -BOOST_CONSTEXPR_OR_CONST err_t not_found_error_code = ENOENT; - -#else // BOOST_WINDOWS_API - -inline void set_file_statuses(DWORD attrs, const ULONG* reparse_point_tag, fs::path const& filename, fs::file_status& sf, fs::file_status& symlink_sf) -{ - if ((attrs & FILE_ATTRIBUTE_REPARSE_POINT) != 0u) - { - // Reparse points are complex, so don't try to resolve them here; instead just mark - // them as status_error which causes directory_entry caching to call status() - // and symlink_status() which do handle reparse points fully - if (reparse_point_tag) - { - // If we have a reparse point tag we can at least populate the symlink status, - // consistent with symlink_status() behavior - symlink_sf.type(is_reparse_point_tag_a_symlink(*reparse_point_tag) ? fs::symlink_file : fs::reparse_file); - symlink_sf.permissions(make_permissions(filename, attrs)); - } - else - { - symlink_sf.type(fs::status_error); - } - - sf.type(fs::status_error); - } - else - { - if ((attrs & FILE_ATTRIBUTE_DIRECTORY) != 0u) - { - sf.type(fs::directory_file); - symlink_sf.type(fs::directory_file); - } - else - { - sf.type(fs::regular_file); - symlink_sf.type(fs::regular_file); - } - - sf.permissions(make_permissions(filename, attrs)); - symlink_sf.permissions(sf.permissions()); - } -} - -#if !defined(UNDER_CE) - -//! FILE_ID_128 definition from Windows SDK -struct file_id_128 -{ - BYTE Identifier[16]; -}; - -//! FILE_DIRECTORY_INFORMATION definition from Windows DDK. Used by NtQueryDirectoryFile, supported since Windows NT 4.0 (probably). -struct file_directory_information -{ - ULONG NextEntryOffset; - ULONG FileIndex; - LARGE_INTEGER CreationTime; - LARGE_INTEGER LastAccessTime; - LARGE_INTEGER LastWriteTime; - LARGE_INTEGER ChangeTime; - LARGE_INTEGER EndOfFile; - LARGE_INTEGER AllocationSize; - ULONG FileAttributes; - ULONG FileNameLength; - WCHAR FileName[1]; -}; - -//! FILE_ID_BOTH_DIR_INFO definition from Windows SDK. Basic support for directory iteration using GetFileInformationByHandleEx, supported since Windows Vista. -struct file_id_both_dir_info -{ - DWORD NextEntryOffset; - DWORD FileIndex; - LARGE_INTEGER CreationTime; - LARGE_INTEGER LastAccessTime; - LARGE_INTEGER LastWriteTime; - LARGE_INTEGER ChangeTime; - LARGE_INTEGER EndOfFile; - LARGE_INTEGER AllocationSize; - DWORD FileAttributes; - DWORD FileNameLength; - DWORD EaSize; - CCHAR ShortNameLength; - WCHAR ShortName[12]; - LARGE_INTEGER FileId; - WCHAR FileName[1]; -}; - -//! FILE_FULL_DIR_INFO definition from Windows SDK. More lightweight than FILE_ID_BOTH_DIR_INFO, supported since Windows 8. -struct file_full_dir_info -{ - ULONG NextEntryOffset; - ULONG FileIndex; - LARGE_INTEGER CreationTime; - LARGE_INTEGER LastAccessTime; - LARGE_INTEGER LastWriteTime; - LARGE_INTEGER ChangeTime; - LARGE_INTEGER EndOfFile; - LARGE_INTEGER AllocationSize; - ULONG FileAttributes; - ULONG FileNameLength; - ULONG EaSize; - WCHAR FileName[1]; -}; - -//! FILE_ID_EXTD_DIR_INFO definition from Windows SDK. Provides reparse point tag, which saves us querying it with a few separate syscalls. Supported since Windows 8. -struct file_id_extd_dir_info -{ - ULONG NextEntryOffset; - ULONG FileIndex; - LARGE_INTEGER CreationTime; - LARGE_INTEGER LastAccessTime; - LARGE_INTEGER LastWriteTime; - LARGE_INTEGER ChangeTime; - LARGE_INTEGER EndOfFile; - LARGE_INTEGER AllocationSize; - ULONG FileAttributes; - ULONG FileNameLength; - ULONG EaSize; - ULONG ReparsePointTag; - file_id_128 FileId; - WCHAR FileName[1]; -}; - -//! Indicates format of the extra data in the directory iterator -enum extra_data_format -{ - file_directory_information_format, - file_id_both_dir_info_format, - file_full_dir_info_format, - file_id_extd_dir_info_format -}; - -//! Indicates extra data format that should be used by directory iterator by default -extra_data_format g_extra_data_format = file_directory_information_format; - -/*! - * \brief Extra buffer size for GetFileInformationByHandleEx-based or NtQueryDirectoryFile-based directory iterator. - * - * Must be large enough to accommodate at least one FILE_DIRECTORY_INFORMATION or *_DIR_INFO struct and one filename. - * NTFS, VFAT, exFAT support filenames up to 255 UTF-16/UCS-2 characters. ReFS supports filenames up to 32768 UTF-16 characters. - */ -BOOST_CONSTEXPR_OR_CONST std::size_t dir_itr_extra_size = sizeof(file_id_extd_dir_info) + 65536u; - -inline system::error_code dir_itr_close(dir_itr_imp& imp) BOOST_NOEXCEPT -{ - imp.extra_data_format = 0u; - imp.current_offset = 0u; - - if (imp.handle != NULL) - { - if (BOOST_LIKELY(imp.close_handle)) - ::CloseHandle(imp.handle); - imp.handle = NULL; - } - - return error_code(); -} - -error_code dir_itr_increment(dir_itr_imp& imp, fs::path& filename, fs::file_status& sf, fs::file_status& symlink_sf) -{ - void* extra_data = get_dir_itr_imp_extra_data(&imp); - const void* current_data = static_cast< const unsigned char* >(extra_data) + imp.current_offset; - switch (imp.extra_data_format) - { - case file_id_extd_dir_info_format: - { - const file_id_extd_dir_info* data = static_cast< const file_id_extd_dir_info* >(current_data); - if (data->NextEntryOffset == 0u) - { - if (!filesystem::detail::atomic_load_relaxed(get_file_information_by_handle_ex_api)(imp.handle, file_id_extd_directory_info_class, extra_data, dir_itr_extra_size)) - { - DWORD error = ::GetLastError(); - - dir_itr_close(imp); - if (error == ERROR_NO_MORE_FILES) - goto done; - - return error_code(error, system_category()); - } - - imp.current_offset = 0u; - data = static_cast< const file_id_extd_dir_info* >(extra_data); - } - else - { - imp.current_offset += data->NextEntryOffset; - data = reinterpret_cast< const file_id_extd_dir_info* >(static_cast< const unsigned char* >(current_data) + data->NextEntryOffset); - } - - filename.assign(data->FileName, data->FileName + data->FileNameLength / sizeof(WCHAR)); - set_file_statuses(data->FileAttributes, &data->ReparsePointTag, filename, sf, symlink_sf); - } - break; - - case file_full_dir_info_format: - { - const file_full_dir_info* data = static_cast< const file_full_dir_info* >(current_data); - if (data->NextEntryOffset == 0u) - { - if (!filesystem::detail::atomic_load_relaxed(get_file_information_by_handle_ex_api)(imp.handle, file_full_directory_info_class, extra_data, dir_itr_extra_size)) - { - DWORD error = ::GetLastError(); - - dir_itr_close(imp); - if (error == ERROR_NO_MORE_FILES) - goto done; - - return error_code(error, system_category()); - } - - imp.current_offset = 0u; - data = static_cast< const file_full_dir_info* >(extra_data); - } - else - { - imp.current_offset += data->NextEntryOffset; - data = reinterpret_cast< const file_full_dir_info* >(static_cast< const unsigned char* >(current_data) + data->NextEntryOffset); - } - - filename.assign(data->FileName, data->FileName + data->FileNameLength / sizeof(WCHAR)); - set_file_statuses(data->FileAttributes, NULL, filename, sf, symlink_sf); - } - break; - - case file_id_both_dir_info_format: - { - const file_id_both_dir_info* data = static_cast< const file_id_both_dir_info* >(current_data); - if (data->NextEntryOffset == 0u) - { - if (!filesystem::detail::atomic_load_relaxed(get_file_information_by_handle_ex_api)(imp.handle, file_id_both_directory_info_class, extra_data, dir_itr_extra_size)) - { - DWORD error = ::GetLastError(); - - dir_itr_close(imp); - if (error == ERROR_NO_MORE_FILES) - goto done; - - return error_code(error, system_category()); - } - - imp.current_offset = 0u; - data = static_cast< const file_id_both_dir_info* >(extra_data); - } - else - { - imp.current_offset += data->NextEntryOffset; - data = reinterpret_cast< const file_id_both_dir_info* >(static_cast< const unsigned char* >(current_data) + data->NextEntryOffset); - } - - filename.assign(data->FileName, data->FileName + data->FileNameLength / sizeof(WCHAR)); - set_file_statuses(data->FileAttributes, NULL, filename, sf, symlink_sf); - } - break; - - default: - { - const file_directory_information* data = static_cast< const file_directory_information* >(current_data); - if (data->NextEntryOffset == 0u) - { - io_status_block iosb; - boost::winapi::NTSTATUS_ status = filesystem::detail::atomic_load_relaxed(nt_query_directory_file_api) - ( - imp.handle, - NULL, // Event - NULL, // ApcRoutine - NULL, // ApcContext - &iosb, - extra_data, - dir_itr_extra_size, - file_directory_information_class, - FALSE, // ReturnSingleEntry - NULL, // FileName - FALSE // RestartScan - ); - - if (!NT_SUCCESS(status)) - { - dir_itr_close(imp); - if (status == STATUS_NO_MORE_FILES) - goto done; - - return error_code(translate_ntstatus(status), system_category()); - } - - imp.current_offset = 0u; - data = static_cast< const file_directory_information* >(extra_data); - } - else - { - imp.current_offset += data->NextEntryOffset; - data = reinterpret_cast< const file_directory_information* >(static_cast< const unsigned char* >(current_data) + data->NextEntryOffset); - } - - filename.assign(data->FileName, data->FileName + data->FileNameLength / sizeof(WCHAR)); - set_file_statuses(data->FileAttributes, NULL, filename, sf, symlink_sf); - } - break; - } - -done: - return error_code(); -} - -error_code dir_itr_create(boost::intrusive_ptr< detail::dir_itr_imp >& imp, fs::path const& dir, unsigned int opts, directory_iterator_params* params, fs::path& first_filename, fs::file_status& sf, fs::file_status& symlink_sf) -{ - boost::intrusive_ptr< detail::dir_itr_imp > pimpl(new (dir_itr_extra_size) detail::dir_itr_imp()); - if (BOOST_UNLIKELY(!pimpl)) - return make_error_code(system::errc::not_enough_memory); - - GetFileInformationByHandleEx_t* get_file_information_by_handle_ex = filesystem::detail::atomic_load_relaxed(get_file_information_by_handle_ex_api); - - handle_wrapper h; - HANDLE iterator_handle; - bool close_handle = true; - if (params != NULL && params->use_handle != INVALID_HANDLE_VALUE) - { - // Operate on externally provided handle, which must be a directory handle - iterator_handle = params->use_handle; - close_handle = params->close_handle; - } - else - { - DWORD flags = FILE_FLAG_BACKUP_SEMANTICS; - if ((opts & static_cast< unsigned int >(directory_options::_detail_no_follow)) != 0u) - flags |= FILE_FLAG_OPEN_REPARSE_POINT; - - iterator_handle = h.handle = create_file_handle(dir, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, flags); - if (BOOST_UNLIKELY(iterator_handle == INVALID_HANDLE_VALUE)) - { - return_last_error: - DWORD error = ::GetLastError(); - return error_code(error, system_category()); - } - - if (BOOST_LIKELY(get_file_information_by_handle_ex != NULL)) - { - file_attribute_tag_info info; - BOOL res = get_file_information_by_handle_ex(iterator_handle, file_attribute_tag_info_class, &info, sizeof(info)); - if (BOOST_UNLIKELY(!res)) - { - // On FAT/exFAT filesystems requesting FILE_ATTRIBUTE_TAG_INFO returns ERROR_INVALID_PARAMETER. See the comment in symlink_status. - DWORD error = ::GetLastError(); - if (error == ERROR_INVALID_PARAMETER || error == ERROR_NOT_SUPPORTED) - goto use_get_file_information_by_handle; - - return error_code(error, system_category()); - } - - if (BOOST_UNLIKELY((info.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0u)) - return make_error_code(system::errc::not_a_directory); - - if ((opts & static_cast< unsigned int >(directory_options::_detail_no_follow)) != 0u) - { - if ((info.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0u && is_reparse_point_tag_a_symlink(info.ReparseTag)) - return make_error_code(system::errc::too_many_symbolic_link_levels); - } - } - else - { - use_get_file_information_by_handle: - BY_HANDLE_FILE_INFORMATION info; - BOOL res = ::GetFileInformationByHandle(iterator_handle, &info); - if (BOOST_UNLIKELY(!res)) - goto return_last_error; - - if (BOOST_UNLIKELY((info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0u)) - return make_error_code(system::errc::not_a_directory); - - if ((opts & static_cast< unsigned int >(directory_options::_detail_no_follow)) != 0u) - { - if ((info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0u && is_reparse_point_a_symlink_ioctl(h.handle)) - return make_error_code(system::errc::too_many_symbolic_link_levels); - } - } - } - - void* extra_data = get_dir_itr_imp_extra_data(pimpl.get()); - switch (filesystem::detail::atomic_load_relaxed(g_extra_data_format)) - { - case file_id_extd_dir_info_format: - { - if (!get_file_information_by_handle_ex(iterator_handle, file_id_extd_directory_restart_info_class, extra_data, dir_itr_extra_size)) - { - DWORD error = ::GetLastError(); - - if (error == ERROR_NOT_SUPPORTED || error == ERROR_INVALID_PARAMETER) - { - // Fall back to file_full_dir_info_format. - // Note that some mounted filesystems may not support FILE_ID_128 identifiers, which will cause - // GetFileInformationByHandleEx(FileIdExtdDirectoryRestartInfo) return ERROR_INVALID_PARAMETER, - // even though in general the operation is supported by the kernel. So don't downgrade to - // FileFullDirectoryRestartInfo permanently in this case - only for this particular iterator. - if (error == ERROR_NOT_SUPPORTED) - filesystem::detail::atomic_store_relaxed(g_extra_data_format, file_full_dir_info_format); - goto fallback_to_file_full_dir_info_format; - } - - if (error == ERROR_NO_MORE_FILES || error == ERROR_FILE_NOT_FOUND) - goto done; - - return error_code(error, system_category()); - } - - pimpl->extra_data_format = file_id_extd_dir_info_format; - - const file_id_extd_dir_info* data = static_cast< const file_id_extd_dir_info* >(extra_data); - first_filename.assign(data->FileName, data->FileName + data->FileNameLength / sizeof(WCHAR)); - - set_file_statuses(data->FileAttributes, &data->ReparsePointTag, first_filename, sf, symlink_sf); - } - break; - - case file_full_dir_info_format: - fallback_to_file_full_dir_info_format: - { - if (!get_file_information_by_handle_ex(iterator_handle, file_full_directory_restart_info_class, extra_data, dir_itr_extra_size)) - { - DWORD error = ::GetLastError(); - - if (error == ERROR_NOT_SUPPORTED || error == ERROR_INVALID_PARAMETER) - { - // Fall back to file_id_both_dir_info - filesystem::detail::atomic_store_relaxed(g_extra_data_format, file_id_both_dir_info_format); - goto fallback_to_file_id_both_dir_info; - } - - if (error == ERROR_NO_MORE_FILES || error == ERROR_FILE_NOT_FOUND) - goto done; - - return error_code(error, system_category()); - } - - pimpl->extra_data_format = file_full_dir_info_format; - - const file_full_dir_info* data = static_cast< const file_full_dir_info* >(extra_data); - first_filename.assign(data->FileName, data->FileName + data->FileNameLength / sizeof(WCHAR)); - - set_file_statuses(data->FileAttributes, NULL, first_filename, sf, symlink_sf); - } - break; - - case file_id_both_dir_info_format: - fallback_to_file_id_both_dir_info: - { - if (!get_file_information_by_handle_ex(iterator_handle, file_id_both_directory_restart_info_class, extra_data, dir_itr_extra_size)) - { - DWORD error = ::GetLastError(); - - if (error == ERROR_NO_MORE_FILES || error == ERROR_FILE_NOT_FOUND) - goto done; - - return error_code(error, system_category()); - } - - pimpl->extra_data_format = file_id_both_dir_info_format; - - const file_id_both_dir_info* data = static_cast< const file_id_both_dir_info* >(extra_data); - first_filename.assign(data->FileName, data->FileName + data->FileNameLength / sizeof(WCHAR)); - - set_file_statuses(data->FileAttributes, NULL, first_filename, sf, symlink_sf); - } - break; - - default: - { - NtQueryDirectoryFile_t* nt_query_directory_file = filesystem::detail::atomic_load_relaxed(boost::filesystem::detail::nt_query_directory_file_api); - if (BOOST_UNLIKELY(!nt_query_directory_file)) - return error_code(ERROR_NOT_SUPPORTED, system_category()); - - io_status_block iosb; - boost::winapi::NTSTATUS_ status = nt_query_directory_file - ( - iterator_handle, - NULL, // Event - NULL, // ApcRoutine - NULL, // ApcContext - &iosb, - extra_data, - dir_itr_extra_size, - file_directory_information_class, - FALSE, // ReturnSingleEntry - NULL, // FileName - TRUE // RestartScan - ); - - if (!NT_SUCCESS(status)) - { - // Note: an empty root directory has no "." or ".." entries, so this - // causes a ERROR_FILE_NOT_FOUND error returned from FindFirstFileW - // (which is presumably equivalent to STATUS_NO_SUCH_FILE) which we - // do not consider an error. It is treated as eof instead. - if (status == STATUS_NO_MORE_FILES || status == STATUS_NO_SUCH_FILE) - goto done; - - return error_code(translate_ntstatus(status), system_category()); - } - - pimpl->extra_data_format = file_directory_information_format; - - const file_directory_information* data = static_cast< const file_directory_information* >(extra_data); - first_filename.assign(data->FileName, data->FileName + data->FileNameLength / sizeof(WCHAR)); - - set_file_statuses(data->FileAttributes, NULL, first_filename, sf, symlink_sf); - } - break; - } - - - pimpl->handle = iterator_handle; - h.handle = INVALID_HANDLE_VALUE; - pimpl->close_handle = close_handle; - -done: - imp.swap(pimpl); - return error_code(); -} - -#else // !defined(UNDER_CE) - -inline system::error_code dir_itr_close(dir_itr_imp& imp) BOOST_NOEXCEPT -{ - if (imp.handle != NULL) - { - if (BOOST_LIKELY(imp.close_handle)) - ::FindClose(imp.handle); - imp.handle = NULL; - } - - return error_code(); -} - -error_code dir_itr_increment(dir_itr_imp& imp, fs::path& filename, fs::file_status& sf, fs::file_status& symlink_sf) -{ - WIN32_FIND_DATAW data; - if (::FindNextFileW(imp.handle, &data) == 0) // fails - { - DWORD error = ::GetLastError(); - dir_itr_close(imp); - if (error == ERROR_NO_MORE_FILES) - goto done; - return error_code(error, system_category()); - } - - filename = data.cFileName; - set_file_statuses(data.dwFileAttributes, NULL, filename, sf, symlink_sf); - -done: - return error_code(); -} - -error_code dir_itr_create(boost::intrusive_ptr< detail::dir_itr_imp >& imp, fs::path const& dir, unsigned int opts, directory_iterator_params*, fs::path& first_filename, fs::file_status& sf, fs::file_status& symlink_sf) -{ - boost::intrusive_ptr< detail::dir_itr_imp > pimpl(new (static_cast< std::size_t >(0u)) detail::dir_itr_imp()); - if (BOOST_UNLIKELY(!pimpl)) - return make_error_code(system::errc::not_enough_memory); - - // use a form of search Sebastian Martel reports will work with Win98 - fs::path dirpath(dir); - dirpath.make_preferred(); - dirpath /= L"*"; - - WIN32_FIND_DATAW data; - pimpl->handle = ::FindFirstFileW(dirpath.c_str(), &data); - if (BOOST_UNLIKELY(pimpl->handle == INVALID_HANDLE_VALUE)) - { - pimpl->handle = NULL; // signal eof - - // Note: an empty root directory has no "." or ".." entries, so this - // causes a ERROR_FILE_NOT_FOUND error which we do not consider an - // error. It is treated as eof instead. - // Windows Mobile returns ERROR_NO_MORE_FILES; see ticket #3551 - DWORD error = ::GetLastError(); - if (error == ERROR_FILE_NOT_FOUND || error == ERROR_NO_MORE_FILES) - goto done; - - return error_code(error, system_category()); - } - - pimpl->close_handle = true; - - first_filename = data.cFileName; - set_file_statuses(data.dwFileAttributes, NULL, first_filename, sf, symlink_sf); - -done: - imp.swap(pimpl); - return error_code(); -} - -#endif // !defined(UNDER_CE) - -BOOST_CONSTEXPR_OR_CONST err_t not_found_error_code = ERROR_PATH_NOT_FOUND; - -#endif // BOOST_WINDOWS_API - -} // namespace - -#if defined(BOOST_WINDOWS_API) && !defined(UNDER_CE) - -//! Initializes directory iterator implementation -void init_directory_iterator_impl() BOOST_NOEXCEPT -{ - if (filesystem::detail::atomic_load_relaxed(get_file_information_by_handle_ex_api) != NULL) - { - // Enable the latest format we support. It will get downgraded, if needed, as we attempt - // to create the directory iterator the first time. - filesystem::detail::atomic_store_relaxed(g_extra_data_format, file_id_extd_dir_info_format); - } -} - -#endif // defined(BOOST_WINDOWS_API) && !defined(UNDER_CE) - -BOOST_FILESYSTEM_DECL -dir_itr_imp::~dir_itr_imp() BOOST_NOEXCEPT -{ - dir_itr_close(*this); -} - -BOOST_FILESYSTEM_DECL -void directory_iterator_construct(directory_iterator& it, path const& p, unsigned int opts, directory_iterator_params* params, system::error_code* ec) -{ - if (BOOST_UNLIKELY(p.empty())) - { - emit_error(not_found_error_code, p, ec, "boost::filesystem::directory_iterator::construct"); - return; - } - - if (ec) - ec->clear(); - - try - { - boost::intrusive_ptr< detail::dir_itr_imp > imp; - path filename; - file_status file_stat, symlink_file_stat; - system::error_code result = dir_itr_create(imp, p, opts, params, filename, file_stat, symlink_file_stat); - - while (true) - { - if (result) - { - if (result != make_error_condition(system::errc::permission_denied) || - (opts & static_cast< unsigned int >(directory_options::skip_permission_denied)) == 0u) - { - if (!ec) - BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::directory_iterator::construct", p, result)); - *ec = result; - } - - return; - } - - if (imp->handle == NULL) // eof, make end - return; - - // Not eof - const path::string_type::value_type* filename_str = filename.c_str(); - if (!(filename_str[0] == path::dot // dot or dot-dot - && (filename_str[1] == static_cast< path::string_type::value_type >('\0') || - (filename_str[1] == path::dot && filename_str[2] == static_cast< path::string_type::value_type >('\0'))))) - { - imp->dir_entry.assign(p / filename, file_stat, symlink_file_stat); - it.m_imp.swap(imp); - return; - } - - // If dot or dot-dot name produced by the underlying API, skip it until the first actual file - result = dir_itr_increment(*imp, filename, file_stat, symlink_file_stat); - } - } - catch (std::bad_alloc&) - { - if (!ec) - throw; - - *ec = make_error_code(system::errc::not_enough_memory); - it.m_imp.reset(); - } -} - -BOOST_FILESYSTEM_DECL -void directory_iterator_increment(directory_iterator& it, system::error_code* ec) -{ - BOOST_ASSERT_MSG(!it.is_end(), "attempt to increment end iterator"); - - if (ec) - ec->clear(); - - try - { - path filename; - file_status file_stat, symlink_file_stat; - system::error_code increment_ec; - - while (true) - { - increment_ec = dir_itr_increment(*it.m_imp, filename, file_stat, symlink_file_stat); - - if (BOOST_UNLIKELY(!!increment_ec)) // happens if filesystem is corrupt, such as on a damaged optical disc - { - boost::intrusive_ptr< detail::dir_itr_imp > imp; - imp.swap(it.m_imp); - path error_path(imp->dir_entry.path().parent_path()); // fix ticket #5900 - if (!ec) - BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::directory_iterator::operator++", error_path, increment_ec)); - - *ec = increment_ec; - return; - } - - if (it.m_imp->handle == NULL) // eof, make end - { - it.m_imp.reset(); - return; - } - - const path::string_type::value_type* filename_str = filename.c_str(); - if (!(filename_str[0] == path::dot // !(dot or dot-dot) - && (filename_str[1] == static_cast< path::string_type::value_type >('\0') || - (filename_str[1] == path::dot && filename_str[2] == static_cast< path::string_type::value_type >('\0'))))) - { - it.m_imp->dir_entry.replace_filename(filename, file_stat, symlink_file_stat); - return; - } - } - } - catch (std::bad_alloc&) - { - if (!ec) - throw; - - it.m_imp.reset(); - *ec = make_error_code(system::errc::not_enough_memory); - } -} - -//--------------------------------------------------------------------------------------// -// // -// recursive_directory_iterator // -// // -//--------------------------------------------------------------------------------------// - -BOOST_FILESYSTEM_DECL -void recursive_directory_iterator_construct(recursive_directory_iterator& it, path const& dir_path, unsigned int opts, system::error_code* ec) -{ - if (ec) - ec->clear(); - - directory_iterator dir_it; - detail::directory_iterator_construct(dir_it, dir_path, opts, NULL, ec); - if ((ec && *ec) || dir_it == directory_iterator()) - return; - - boost::intrusive_ptr< detail::recur_dir_itr_imp > imp; - if (!ec) - { - imp = new detail::recur_dir_itr_imp(opts); - } - else - { - imp = new (std::nothrow) detail::recur_dir_itr_imp(opts); - if (BOOST_UNLIKELY(!imp)) - { - *ec = make_error_code(system::errc::not_enough_memory); - return; - } - } - - try - { -#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) - imp->m_stack.push_back(std::move(dir_it)); -#else - imp->m_stack.push_back(dir_it); -#endif - - it.m_imp.swap(imp); - } - catch (std::bad_alloc&) - { - if (ec) - { - *ec = make_error_code(system::errc::not_enough_memory); - return; - } - - throw; - } -} - -namespace { - -void recursive_directory_iterator_pop_on_error(detail::recur_dir_itr_imp* imp) -{ - imp->m_stack.pop_back(); - - while (!imp->m_stack.empty()) - { - directory_iterator& dir_it = imp->m_stack.back(); - system::error_code increment_ec; - detail::directory_iterator_increment(dir_it, &increment_ec); - if (!increment_ec && dir_it != directory_iterator()) - break; - - imp->m_stack.pop_back(); - } -} - -} // namespace - -BOOST_FILESYSTEM_DECL -void recursive_directory_iterator_pop(recursive_directory_iterator& it, system::error_code* ec) -{ - BOOST_ASSERT_MSG(!it.is_end(), "pop() on end recursive_directory_iterator"); - detail::recur_dir_itr_imp* const imp = it.m_imp.get(); - - if (ec) - ec->clear(); - - imp->m_stack.pop_back(); - - while (true) - { - if (imp->m_stack.empty()) - { - it.m_imp.reset(); // done, so make end iterator - break; - } - - directory_iterator& dir_it = imp->m_stack.back(); - system::error_code increment_ec; - detail::directory_iterator_increment(dir_it, &increment_ec); - if (BOOST_UNLIKELY(!!increment_ec)) - { - if ((imp->m_options & static_cast< unsigned int >(directory_options::pop_on_error)) == 0u) - { - // Make an end iterator on errors - it.m_imp.reset(); - } - else - { - recursive_directory_iterator_pop_on_error(imp); - - if (imp->m_stack.empty()) - it.m_imp.reset(); // done, so make end iterator - } - - if (!ec) - BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::recursive_directory_iterator::pop", increment_ec)); - - *ec = increment_ec; - return; - } - - if (dir_it != directory_iterator()) - break; - - imp->m_stack.pop_back(); - } -} - -namespace { - -enum push_directory_result -{ - directory_not_pushed = 0u, - directory_pushed = 1u, - keep_depth = 1u << 1 -}; - -// Returns: true if push occurs, otherwise false. Always returns false on error. -inline push_directory_result recursive_directory_iterator_push_directory(detail::recur_dir_itr_imp* imp, system::error_code& ec) BOOST_NOEXCEPT -{ - push_directory_result result = directory_not_pushed; - try - { - // Discover if the iterator is for a directory that needs to be recursed into, - // taking symlinks and options into account. - - if ((imp->m_options & static_cast< unsigned int >(directory_options::_detail_no_push)) != 0u) - { - imp->m_options &= ~static_cast< unsigned int >(directory_options::_detail_no_push); - return result; - } - - file_status symlink_stat; - - // If we are not recursing into symlinks, we are going to have to know if the - // stack top is a symlink, so get symlink_status and verify no error occurred. - if ((imp->m_options & static_cast< unsigned int >(directory_options::follow_directory_symlink)) == 0u || - (imp->m_options & static_cast< unsigned int >(directory_options::skip_dangling_symlinks)) != 0u) - { - symlink_stat = imp->m_stack.back()->symlink_status(ec); - if (ec) - return result; - } - - // Logic for following predicate was contributed by Daniel Aarno to handle cyclic - // symlinks correctly and efficiently, fixing ticket #5652. - // if (((m_options & directory_options::follow_directory_symlink) == directory_options::follow_directory_symlink - // || !is_symlink(m_stack.back()->symlink_status())) - // && is_directory(m_stack.back()->status())) ... - // The predicate code has since been rewritten to pass error_code arguments, - // per ticket #5653. - - if ((imp->m_options & static_cast< unsigned int >(directory_options::follow_directory_symlink)) != 0u || !fs::is_symlink(symlink_stat)) - { - file_status stat = imp->m_stack.back()->status(ec); - if (BOOST_UNLIKELY(!!ec)) - { - if (ec == make_error_condition(system::errc::no_such_file_or_directory) && fs::is_symlink(symlink_stat) && - (imp->m_options & static_cast< unsigned int >(directory_options::follow_directory_symlink | directory_options::skip_dangling_symlinks)) == static_cast< unsigned int >(directory_options::follow_directory_symlink | directory_options::skip_dangling_symlinks)) - { - // Skip dangling symlink and continue iteration on the current depth level - ec = error_code(); - } - - return result; - } - - if (!fs::is_directory(stat)) - return result; - - if (BOOST_UNLIKELY((imp->m_stack.size() - 1u) >= static_cast< std::size_t >((std::numeric_limits< int >::max)()))) - { - // We cannot let depth to overflow - ec = make_error_code(system::errc::value_too_large); - // When depth overflow happens, avoid popping the current directory iterator - // and attempt to continue iteration on the current depth. - result = keep_depth; - return result; - } - - directory_iterator next(imp->m_stack.back()->path(), static_cast< BOOST_SCOPED_ENUM_NATIVE(directory_options) >(imp->m_options), ec); - if (!ec && next != directory_iterator()) - { -#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) - imp->m_stack.push_back(std::move(next)); // may throw -#else - imp->m_stack.push_back(next); // may throw -#endif - return directory_pushed; - } - } - } - catch (std::bad_alloc&) - { - ec = make_error_code(system::errc::not_enough_memory); - } - - return result; -} - -} // namespace - -BOOST_FILESYSTEM_DECL -void recursive_directory_iterator_increment(recursive_directory_iterator& it, system::error_code* ec) -{ - BOOST_ASSERT_MSG(!it.is_end(), "increment() on end recursive_directory_iterator"); - detail::recur_dir_itr_imp* const imp = it.m_imp.get(); - - if (ec) - ec->clear(); - - system::error_code local_ec; - - // if various conditions are met, push a directory_iterator into the iterator stack - push_directory_result push_result = recursive_directory_iterator_push_directory(imp, local_ec); - if (push_result == directory_pushed) - return; - - // report errors if any - if (BOOST_UNLIKELY(!!local_ec)) - { - on_error: - if ((imp->m_options & static_cast< unsigned int >(directory_options::pop_on_error)) == 0u) - { - // Make an end iterator on errors - it.m_imp.reset(); - } - else - { - if ((push_result & keep_depth) != 0u) - { - system::error_code increment_ec; - directory_iterator& dir_it = imp->m_stack.back(); - detail::directory_iterator_increment(dir_it, &increment_ec); - if (!increment_ec && dir_it != directory_iterator()) - goto on_error_return; - } - - recursive_directory_iterator_pop_on_error(imp); - - if (imp->m_stack.empty()) - it.m_imp.reset(); // done, so make end iterator - } - - on_error_return: - if (!ec) - BOOST_FILESYSTEM_THROW(filesystem_error("filesystem::recursive_directory_iterator increment error", local_ec)); - - *ec = local_ec; - return; - } - - // Do the actual increment operation on the top iterator in the iterator - // stack, popping the stack if necessary, until either the stack is empty or a - // non-end iterator is reached. - while (true) - { - if (imp->m_stack.empty()) - { - it.m_imp.reset(); // done, so make end iterator - break; - } - - directory_iterator& dir_it = imp->m_stack.back(); - detail::directory_iterator_increment(dir_it, &local_ec); - if (BOOST_UNLIKELY(!!local_ec)) - goto on_error; - - if (dir_it != directory_iterator()) - break; - - imp->m_stack.pop_back(); - } -} - -} // namespace detail - -} // namespace filesystem -} // namespace boost - -#include <boost/filesystem/detail/footer.hpp> diff --git a/contrib/restricted/boost/filesystem/src/error_handling.hpp b/contrib/restricted/boost/filesystem/src/error_handling.hpp deleted file mode 100644 index 97590a8712..0000000000 --- a/contrib/restricted/boost/filesystem/src/error_handling.hpp +++ /dev/null @@ -1,220 +0,0 @@ -// error_handling.hpp --------------------------------------------------------------------// - -// Copyright 2002-2009, 2014 Beman Dawes -// Copyright 2019 Andrey Semashev - -// Distributed under the Boost Software License, Version 1.0. -// See http://www.boost.org/LICENSE_1_0.txt - -// See library home page at http://www.boost.org/libs/filesystem - -//--------------------------------------------------------------------------------------// - -#ifndef BOOST_FILESYSTEM_SRC_ERROR_HANDLING_HPP_ -#define BOOST_FILESYSTEM_SRC_ERROR_HANDLING_HPP_ - -#include <cerrno> -#include <boost/system/error_code.hpp> -#include <boost/filesystem/config.hpp> -#include <boost/filesystem/exception.hpp> - -#if defined(BOOST_WINDOWS_API) -#include <boost/winapi/basic_types.hpp> -#include <boost/winapi/get_last_error.hpp> -#include <boost/winapi/error_codes.hpp> -#endif - -#include <boost/filesystem/detail/header.hpp> // must be the last #include - -namespace boost { -namespace filesystem { - -#if defined(BOOST_POSIX_API) - -typedef int err_t; - -// POSIX uses a 0 return to indicate success -#define BOOST_ERRNO errno - -#define BOOST_ERROR_FILE_NOT_FOUND ENOENT -#define BOOST_ERROR_ALREADY_EXISTS EEXIST -#define BOOST_ERROR_NOT_SUPPORTED ENOSYS - -#else - -typedef boost::winapi::DWORD_ err_t; - -// Windows uses a non-0 return to indicate success -#define BOOST_ERRNO boost::winapi::GetLastError() - -#define BOOST_ERROR_FILE_NOT_FOUND boost::winapi::ERROR_FILE_NOT_FOUND_ -#define BOOST_ERROR_ALREADY_EXISTS boost::winapi::ERROR_ALREADY_EXISTS_ -#define BOOST_ERROR_NOT_SUPPORTED boost::winapi::ERROR_NOT_SUPPORTED_ - -// Note: Legacy MinGW doesn't have ntstatus.h and doesn't define NTSTATUS error codes other than STATUS_SUCCESS. -#if !defined(NT_SUCCESS) -#define NT_SUCCESS(Status) (((boost::winapi::NTSTATUS_)(Status)) >= 0) -#endif -#if !defined(STATUS_SUCCESS) -#define STATUS_SUCCESS ((boost::winapi::NTSTATUS_)0x00000000l) -#endif -#if !defined(STATUS_NOT_IMPLEMENTED) -#define STATUS_NOT_IMPLEMENTED ((boost::winapi::NTSTATUS_)0xC0000002l) -#endif -#if !defined(STATUS_INVALID_INFO_CLASS) -#define STATUS_INVALID_INFO_CLASS ((boost::winapi::NTSTATUS_)0xC0000003l) -#endif -#if !defined(STATUS_INVALID_HANDLE) -#define STATUS_INVALID_HANDLE ((boost::winapi::NTSTATUS_)0xC0000008l) -#endif -#if !defined(STATUS_INVALID_PARAMETER) -#define STATUS_INVALID_PARAMETER ((boost::winapi::NTSTATUS_)0xC000000Dl) -#endif -#if !defined(STATUS_NO_SUCH_DEVICE) -#define STATUS_NO_SUCH_DEVICE ((boost::winapi::NTSTATUS_)0xC000000El) -#endif -#if !defined(STATUS_NO_SUCH_FILE) -#define STATUS_NO_SUCH_FILE ((boost::winapi::NTSTATUS_)0xC000000Fl) -#endif -#if !defined(STATUS_NO_MORE_FILES) -#define STATUS_NO_MORE_FILES ((boost::winapi::NTSTATUS_)0x80000006l) -#endif -#if !defined(STATUS_BUFFER_OVERFLOW) -#define STATUS_BUFFER_OVERFLOW ((boost::winapi::NTSTATUS_)0x80000005l) -#endif -#if !defined(STATUS_NO_MEMORY) -#define STATUS_NO_MEMORY ((boost::winapi::NTSTATUS_)0xC0000017l) -#endif -#if !defined(STATUS_ACCESS_DENIED) -#define STATUS_ACCESS_DENIED ((boost::winapi::NTSTATUS_)0xC0000022l) -#endif -#if !defined(STATUS_OBJECT_NAME_NOT_FOUND) -#define STATUS_OBJECT_NAME_NOT_FOUND ((boost::winapi::NTSTATUS_)0xC0000034l) -#endif -#if !defined(STATUS_OBJECT_PATH_NOT_FOUND) -#define STATUS_OBJECT_PATH_NOT_FOUND ((boost::winapi::NTSTATUS_)0xC000003Al) -#endif -#if !defined(STATUS_NOT_SUPPORTED) -#define STATUS_NOT_SUPPORTED ((boost::winapi::NTSTATUS_)0xC00000BBl) -#endif -#if !defined(STATUS_BAD_NETWORK_PATH) -#define STATUS_BAD_NETWORK_PATH ((boost::winapi::NTSTATUS_)0xC00000BEl) -#endif -#if !defined(STATUS_DEVICE_DOES_NOT_EXIST) -#define STATUS_DEVICE_DOES_NOT_EXIST ((boost::winapi::NTSTATUS_)0xC00000C0l) -#endif -#if !defined(STATUS_BAD_NETWORK_NAME) -#define STATUS_BAD_NETWORK_NAME ((boost::winapi::NTSTATUS_)0xC00000CCl) -#endif -#if !defined(STATUS_DIRECTORY_NOT_EMPTY) -#define STATUS_DIRECTORY_NOT_EMPTY ((boost::winapi::NTSTATUS_)0xC0000101l) -#endif -#if !defined(STATUS_NOT_A_DIRECTORY) -#define STATUS_NOT_A_DIRECTORY ((boost::winapi::NTSTATUS_)0xC0000103l) -#endif -#if !defined(STATUS_NOT_FOUND) -#define STATUS_NOT_FOUND ((boost::winapi::NTSTATUS_)0xC0000225l) -#endif - -//! Converts NTSTATUS error codes to Win32 error codes for reporting -inline boost::winapi::DWORD_ translate_ntstatus(boost::winapi::NTSTATUS_ status) -{ - // We have to cast to unsigned integral type to avoid signed overflow and narrowing conversion in the constants. - switch (static_cast< boost::winapi::ULONG_ >(status)) - { - case static_cast< boost::winapi::ULONG_ >(STATUS_NO_MEMORY): - return boost::winapi::ERROR_OUTOFMEMORY_; - case static_cast< boost::winapi::ULONG_ >(STATUS_BUFFER_OVERFLOW): - return boost::winapi::ERROR_BUFFER_OVERFLOW_; - case static_cast< boost::winapi::ULONG_ >(STATUS_INVALID_HANDLE): - return boost::winapi::ERROR_INVALID_HANDLE_; - case static_cast< boost::winapi::ULONG_ >(STATUS_INVALID_PARAMETER): - return boost::winapi::ERROR_INVALID_PARAMETER_; - case static_cast< boost::winapi::ULONG_ >(STATUS_NO_MORE_FILES): - return boost::winapi::ERROR_NO_MORE_FILES_; - case static_cast< boost::winapi::ULONG_ >(STATUS_NO_SUCH_DEVICE): - case static_cast< boost::winapi::ULONG_ >(STATUS_DEVICE_DOES_NOT_EXIST): - return boost::winapi::ERROR_DEV_NOT_EXIST_; - case static_cast< boost::winapi::ULONG_ >(STATUS_NO_SUCH_FILE): - case static_cast< boost::winapi::ULONG_ >(STATUS_OBJECT_NAME_NOT_FOUND): - case static_cast< boost::winapi::ULONG_ >(STATUS_OBJECT_PATH_NOT_FOUND): - return boost::winapi::ERROR_FILE_NOT_FOUND_; - case static_cast< boost::winapi::ULONG_ >(STATUS_ACCESS_DENIED): - return boost::winapi::ERROR_ACCESS_DENIED_; - case static_cast< boost::winapi::ULONG_ >(STATUS_BAD_NETWORK_PATH): - return boost::winapi::ERROR_BAD_NETPATH_; - case static_cast< boost::winapi::ULONG_ >(STATUS_BAD_NETWORK_NAME): - return boost::winapi::ERROR_BAD_NET_NAME_; - case static_cast< boost::winapi::ULONG_ >(STATUS_DIRECTORY_NOT_EMPTY): - return boost::winapi::ERROR_DIR_NOT_EMPTY_; - case static_cast< boost::winapi::ULONG_ >(STATUS_NOT_A_DIRECTORY): - return boost::winapi::ERROR_DIRECTORY_; // The directory name is invalid - case static_cast< boost::winapi::ULONG_ >(STATUS_NOT_FOUND): - return boost::winapi::ERROR_NOT_FOUND_; - // map "invalid info class" to "not supported" as this error likely indicates that the kernel does not support what we request - case static_cast< boost::winapi::ULONG_ >(STATUS_INVALID_INFO_CLASS): - default: - return boost::winapi::ERROR_NOT_SUPPORTED_; - } -} - -#endif - -// error handling helpers ----------------------------------------------------------// - -// Implemented in exception.cpp -void emit_error(err_t error_num, system::error_code* ec, const char* message); -void emit_error(err_t error_num, path const& p, system::error_code* ec, const char* message); -void emit_error(err_t error_num, path const& p1, path const& p2, system::error_code* ec, const char* message); - -inline bool error(err_t error_num, system::error_code* ec, const char* message) -{ - if (BOOST_LIKELY(!error_num)) - { - if (ec) - ec->clear(); - return false; - } - else - { // error - filesystem::emit_error(error_num, ec, message); - return true; - } -} - -inline bool error(err_t error_num, path const& p, system::error_code* ec, const char* message) -{ - if (BOOST_LIKELY(!error_num)) - { - if (ec) - ec->clear(); - return false; - } - else - { // error - filesystem::emit_error(error_num, p, ec, message); - return true; - } -} - -inline bool error(err_t error_num, path const& p1, path const& p2, system::error_code* ec, const char* message) -{ - if (BOOST_LIKELY(!error_num)) - { - if (ec) - ec->clear(); - return false; - } - else - { // error - filesystem::emit_error(error_num, p1, p2, ec, message); - return true; - } -} - -} // namespace filesystem -} // namespace boost - -#include <boost/filesystem/detail/footer.hpp> - -#endif // BOOST_FILESYSTEM_SRC_ERROR_HANDLING_HPP_ diff --git a/contrib/restricted/boost/filesystem/src/exception.cpp b/contrib/restricted/boost/filesystem/src/exception.cpp deleted file mode 100644 index 91ee1c90a9..0000000000 --- a/contrib/restricted/boost/filesystem/src/exception.cpp +++ /dev/null @@ -1,188 +0,0 @@ -// boost/filesystem/exception.hpp -----------------------------------------------------// - -// Copyright Beman Dawes 2003 -// Copyright Andrey Semashev 2019 - -// Distributed under the Boost Software License, Version 1.0. -// See http://www.boost.org/LICENSE_1_0.txt - -// Library home page: http://www.boost.org/libs/filesystem - -#include "platform_config.hpp" - -#include <string> -#include <boost/system/error_code.hpp> -#include <boost/system/system_category.hpp> -#include <boost/filesystem/config.hpp> -#include <boost/filesystem/path.hpp> -#include <boost/filesystem/exception.hpp> - -#include "error_handling.hpp" - -#include <boost/filesystem/detail/header.hpp> // must be the last #include - -namespace boost { -namespace filesystem { - -BOOST_FILESYSTEM_DECL filesystem_error::filesystem_error(const char* what_arg, system::error_code ec) : - system::system_error(ec, what_arg) -{ - try - { - m_imp_ptr.reset(new impl()); - } - catch (...) - { - m_imp_ptr.reset(); - } -} - -BOOST_FILESYSTEM_DECL filesystem_error::filesystem_error(std::string const& what_arg, system::error_code ec) : - system::system_error(ec, what_arg) -{ - try - { - m_imp_ptr.reset(new impl()); - } - catch (...) - { - m_imp_ptr.reset(); - } -} - -BOOST_FILESYSTEM_DECL filesystem_error::filesystem_error(const char* what_arg, path const& path1_arg, system::error_code ec) : - system::system_error(ec, what_arg) -{ - try - { - m_imp_ptr.reset(new impl(path1_arg)); - } - catch (...) - { - m_imp_ptr.reset(); - } -} - -BOOST_FILESYSTEM_DECL filesystem_error::filesystem_error(std::string const& what_arg, path const& path1_arg, system::error_code ec) : - system::system_error(ec, what_arg) -{ - try - { - m_imp_ptr.reset(new impl(path1_arg)); - } - catch (...) - { - m_imp_ptr.reset(); - } -} - -BOOST_FILESYSTEM_DECL filesystem_error::filesystem_error(const char* what_arg, path const& path1_arg, path const& path2_arg, system::error_code ec) : - system::system_error(ec, what_arg) -{ - try - { - m_imp_ptr.reset(new impl(path1_arg, path2_arg)); - } - catch (...) - { - m_imp_ptr.reset(); - } -} - -BOOST_FILESYSTEM_DECL filesystem_error::filesystem_error(std::string const& what_arg, path const& path1_arg, path const& path2_arg, system::error_code ec) : - system::system_error(ec, what_arg) -{ - try - { - m_imp_ptr.reset(new impl(path1_arg, path2_arg)); - } - catch (...) - { - m_imp_ptr.reset(); - } -} - -BOOST_FILESYSTEM_DECL filesystem_error::filesystem_error(filesystem_error const& that) : - system::system_error(static_cast< system::system_error const& >(that)), - m_imp_ptr(that.m_imp_ptr) -{ -} - -BOOST_FILESYSTEM_DECL filesystem_error& filesystem_error::operator=(filesystem_error const& that) -{ - static_cast< system::system_error& >(*this) = static_cast< system::system_error const& >(that); - m_imp_ptr = that.m_imp_ptr; - return *this; -} - -BOOST_FILESYSTEM_DECL filesystem_error::~filesystem_error() BOOST_NOEXCEPT_OR_NOTHROW -{ -} - -BOOST_FILESYSTEM_DECL const char* filesystem_error::what() const BOOST_NOEXCEPT_OR_NOTHROW -{ - if (m_imp_ptr.get()) try - { - if (m_imp_ptr->m_what.empty()) - { - m_imp_ptr->m_what = system::system_error::what(); - if (!m_imp_ptr->m_path1.empty()) - { - m_imp_ptr->m_what += ": \""; - m_imp_ptr->m_what += m_imp_ptr->m_path1.string(); - m_imp_ptr->m_what += "\""; - } - if (!m_imp_ptr->m_path2.empty()) - { - m_imp_ptr->m_what += ", \""; - m_imp_ptr->m_what += m_imp_ptr->m_path2.string(); - m_imp_ptr->m_what += "\""; - } - } - - return m_imp_ptr->m_what.c_str(); - } - catch (...) - { - m_imp_ptr->m_what.clear(); - } - - return system::system_error::what(); -} - -BOOST_FILESYSTEM_DECL path const& filesystem_error::get_empty_path() BOOST_NOEXCEPT -{ - static const path empty_path; - return empty_path; -} - -// error handling helpers declared in error_handling.hpp -----------------------------------------------------// - -void emit_error(err_t error_num, system::error_code* ec, const char* message) -{ - if (!ec) - BOOST_FILESYSTEM_THROW(filesystem_error(message, system::error_code(error_num, system::system_category()))); - else - ec->assign(error_num, system::system_category()); -} - -void emit_error(err_t error_num, path const& p, system::error_code* ec, const char* message) -{ - if (!ec) - BOOST_FILESYSTEM_THROW(filesystem_error(message, p, system::error_code(error_num, system::system_category()))); - else - ec->assign(error_num, system::system_category()); -} - -void emit_error(err_t error_num, path const& p1, path const& p2, system::error_code* ec, const char* message) -{ - if (!ec) - BOOST_FILESYSTEM_THROW(filesystem_error(message, p1, p2, system::error_code(error_num, system::system_category()))); - else - ec->assign(error_num, system::system_category()); -} - -} // namespace filesystem -} // namespace boost - -#include <boost/filesystem/detail/footer.hpp> diff --git a/contrib/restricted/boost/filesystem/src/operations.cpp b/contrib/restricted/boost/filesystem/src/operations.cpp deleted file mode 100644 index dd636e9063..0000000000 --- a/contrib/restricted/boost/filesystem/src/operations.cpp +++ /dev/null @@ -1,4548 +0,0 @@ -// operations.cpp --------------------------------------------------------------------// - -// Copyright 2002-2009, 2014 Beman Dawes -// Copyright 2001 Dietmar Kuehl -// Copyright 2018-2022 Andrey Semashev - -// Distributed under the Boost Software License, Version 1.0. -// See http://www.boost.org/LICENSE_1_0.txt - -// See library home page at http://www.boost.org/libs/filesystem - -//--------------------------------------------------------------------------------------// - -#include "platform_config.hpp" - -#include <boost/predef/os/bsd/open.h> -#include <boost/filesystem/config.hpp> -#include <boost/filesystem/operations.hpp> -#include <boost/filesystem/file_status.hpp> -#include <boost/filesystem/exception.hpp> -#include <boost/filesystem/directory.hpp> -#include <boost/system/error_code.hpp> -#include <boost/smart_ptr/scoped_ptr.hpp> -#include <boost/smart_ptr/scoped_array.hpp> -#include <boost/detail/workaround.hpp> -#include <boost/core/bit.hpp> -#include <boost/cstdint.hpp> -#include <boost/assert.hpp> -#include <new> // std::bad_alloc, std::nothrow -#include <limits> -#include <string> -#include <cstddef> -#include <cstdlib> // for malloc, free -#include <cstring> -#include <cerrno> -#include <stdio.h> // for rename - -// Default to POSIX under Emscripten -// If BOOST_FILESYSTEM_EMSCRIPTEN_USE_WASI is set, use WASI instead -#if defined(__wasm) && (!defined(__EMSCRIPTEN__) || defined(BOOST_FILESYSTEM_EMSCRIPTEN_USE_WASI)) -#define BOOST_FILESYSTEM_USE_WASI -#endif - -#ifdef BOOST_POSIX_API - -#include <sys/types.h> -#include <sys/stat.h> - -#if defined(BOOST_FILESYSTEM_USE_WASI) -// WASI does not have statfs or statvfs. -#elif !defined(__APPLE__) && \ - (!defined(__OpenBSD__) || BOOST_OS_BSD_OPEN >= BOOST_VERSION_NUMBER(4, 4, 0)) && \ - !defined(__ANDROID__) && \ - !defined(__VXWORKS__) -#include <sys/statvfs.h> -#define BOOST_STATVFS statvfs -#define BOOST_STATVFS_F_FRSIZE vfs.f_frsize -#else -#ifdef __OpenBSD__ -#include <sys/param.h> -#elif defined(__ANDROID__) -#include <sys/vfs.h> -#endif -#if !defined(__VXWORKS__) -#include <sys/mount.h> -#endif -#define BOOST_STATVFS statfs -#define BOOST_STATVFS_F_FRSIZE static_cast< uintmax_t >(vfs.f_bsize) -#endif // BOOST_STATVFS definition - -#include <unistd.h> -#include <fcntl.h> -#if _POSIX_C_SOURCE < 200809L -#include <utime.h> -#endif -#include <limits.h> - -#if defined(linux) || defined(__linux) || defined(__linux__) - -#include <sys/vfs.h> -#include <sys/utsname.h> -#include <sys/syscall.h> -#include <sys/sysmacros.h> -#if !defined(BOOST_FILESYSTEM_DISABLE_SENDFILE) -#include <sys/sendfile.h> -#define BOOST_FILESYSTEM_USE_SENDFILE -#endif // !defined(BOOST_FILESYSTEM_DISABLE_SENDFILE) -#if !defined(BOOST_FILESYSTEM_DISABLE_COPY_FILE_RANGE) && defined(__NR_copy_file_range) -#define BOOST_FILESYSTEM_USE_COPY_FILE_RANGE -#endif // !defined(BOOST_FILESYSTEM_DISABLE_COPY_FILE_RANGE) && defined(__NR_copy_file_range) -#if !defined(BOOST_FILESYSTEM_DISABLE_STATX) && (defined(BOOST_FILESYSTEM_HAS_STATX) || defined(BOOST_FILESYSTEM_HAS_STATX_SYSCALL)) -#if !defined(BOOST_FILESYSTEM_HAS_STATX) && defined(BOOST_FILESYSTEM_HAS_STATX_SYSCALL) -#include <linux/stat.h> -#endif -#define BOOST_FILESYSTEM_USE_STATX -#endif // !defined(BOOST_FILESYSTEM_DISABLE_STATX) && (defined(BOOST_FILESYSTEM_HAS_STATX) || defined(BOOST_FILESYSTEM_HAS_STATX_SYSCALL)) - -#if defined(__has_include) -#if __has_include(<linux/magic.h>) -// This header was introduced in Linux kernel 2.6.19 -#include <linux/magic.h> -#endif -#endif - -// Some filesystem type magic constants are not defined in older kernel headers -#ifndef PROC_SUPER_MAGIC -#define PROC_SUPER_MAGIC 0x9fa0 -#endif -#ifndef SYSFS_MAGIC -#define SYSFS_MAGIC 0x62656572 -#endif -#ifndef TRACEFS_MAGIC -#define TRACEFS_MAGIC 0x74726163 -#endif -#ifndef DEBUGFS_MAGIC -#define DEBUGFS_MAGIC 0x64626720 -#endif - -#endif // defined(linux) || defined(__linux) || defined(__linux__) - -#if defined(POSIX_FADV_SEQUENTIAL) && (!defined(__ANDROID__) || __ANDROID_API__ >= 21) -#define BOOST_FILESYSTEM_HAS_POSIX_FADVISE -#endif - -#if defined(BOOST_FILESYSTEM_HAS_STAT_ST_MTIM) -#define BOOST_FILESYSTEM_STAT_ST_MTIMENSEC st_mtim.tv_nsec -#elif defined(BOOST_FILESYSTEM_HAS_STAT_ST_MTIMESPEC) -#define BOOST_FILESYSTEM_STAT_ST_MTIMENSEC st_mtimespec.tv_nsec -#elif defined(BOOST_FILESYSTEM_HAS_STAT_ST_MTIMENSEC) -#define BOOST_FILESYSTEM_STAT_ST_MTIMENSEC st_mtimensec -#endif - -#if defined(BOOST_FILESYSTEM_HAS_STAT_ST_BIRTHTIM) -#define BOOST_FILESYSTEM_STAT_ST_BIRTHTIME st_birthtim.tv_sec -#define BOOST_FILESYSTEM_STAT_ST_BIRTHTIMENSEC st_birthtim.tv_nsec -#elif defined(BOOST_FILESYSTEM_HAS_STAT_ST_BIRTHTIMESPEC) -#define BOOST_FILESYSTEM_STAT_ST_BIRTHTIME st_birthtimespec.tv_sec -#define BOOST_FILESYSTEM_STAT_ST_BIRTHTIMENSEC st_birthtimespec.tv_nsec -#elif defined(BOOST_FILESYSTEM_HAS_STAT_ST_BIRTHTIMENSEC) -#define BOOST_FILESYSTEM_STAT_ST_BIRTHTIME st_birthtime -#define BOOST_FILESYSTEM_STAT_ST_BIRTHTIMENSEC st_birthtimensec -#endif - -#include "posix_tools.hpp" - -#else // BOOST_WINDOWS_API - -#include <boost/winapi/dll.hpp> // get_proc_address, GetModuleHandleW -#include <cwchar> -#include <io.h> -#include <windows.h> -#include <winnt.h> -#if defined(__BORLANDC__) || defined(__MWERKS__) -#if defined(BOOST_BORLANDC) -using std::time_t; -#endif -#include <utime.h> -#else -#include <sys/utime.h> -#endif - -#include "windows_tools.hpp" - -#endif // BOOST_WINDOWS_API - -#include "atomic_tools.hpp" -#include "error_handling.hpp" -#include "private_config.hpp" - -#include <boost/filesystem/detail/header.hpp> // must be the last #include - -namespace fs = boost::filesystem; -using boost::filesystem::path; -using boost::filesystem::filesystem_error; -using boost::filesystem::perms; -using boost::system::error_code; -using boost::system::system_category; - -#if defined(BOOST_POSIX_API) - -// At least Mac OS X 10.6 and older doesn't support O_CLOEXEC -#ifndef O_CLOEXEC -#define O_CLOEXEC 0 -#endif - -#if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0 -#define BOOST_FILESYSTEM_HAS_FDATASYNC -#endif - -#else // defined(BOOST_POSIX_API) - -#ifndef MAXIMUM_REPARSE_DATA_BUFFER_SIZE -#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE (16 * 1024) -#endif - -#ifndef FSCTL_GET_REPARSE_POINT -#define FSCTL_GET_REPARSE_POINT 0x900a8 -#endif - -#ifndef SYMLINK_FLAG_RELATIVE -#define SYMLINK_FLAG_RELATIVE 1 -#endif - -// Fallback for MinGW/Cygwin -#ifndef SYMBOLIC_LINK_FLAG_DIRECTORY -#define SYMBOLIC_LINK_FLAG_DIRECTORY 0x1 -#endif - -#ifndef SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE -#define SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE 0x2 -#endif - -#endif // defined(BOOST_POSIX_API) - -// POSIX/Windows macros ----------------------------------------------------// - -// Portions of the POSIX and Windows API's are very similar, except for name, -// order of arguments, and meaning of zero/non-zero returns. The macros below -// abstract away those differences. They follow Windows naming and order of -// arguments, and return true to indicate no error occurred. [POSIX naming, -// order of arguments, and meaning of return were followed initially, but -// found to be less clear and cause more coding errors.] - -#if defined(BOOST_POSIX_API) - -#define BOOST_SET_CURRENT_DIRECTORY(P) (::chdir(P) == 0) -#define BOOST_MOVE_FILE(OLD, NEW) (::rename(OLD, NEW) == 0) -#define BOOST_RESIZE_FILE(P, SZ) (::truncate(P, SZ) == 0) - -#else // BOOST_WINDOWS_API - -#define BOOST_SET_CURRENT_DIRECTORY(P) (::SetCurrentDirectoryW(P) != 0) -#define BOOST_MOVE_FILE(OLD, NEW) (::MoveFileExW(OLD, NEW, MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED) != 0) -#define BOOST_RESIZE_FILE(P, SZ) (resize_file_impl(P, SZ) != 0) - -#endif - -namespace boost { -namespace filesystem { -namespace detail { - -#if defined(linux) || defined(__linux) || defined(__linux__) -//! Initializes fill_random implementation pointer. Implemented in unique_path.cpp. -void init_fill_random_impl(unsigned int major_ver, unsigned int minor_ver, unsigned int patch_ver); -#endif // defined(linux) || defined(__linux) || defined(__linux__) - -#if defined(BOOST_WINDOWS_API) && !defined(UNDER_CE) -//! Initializes directory iterator implementation. Implemented in directory.cpp. -void init_directory_iterator_impl() BOOST_NOEXCEPT; -#endif // defined(BOOST_WINDOWS_API) && !defined(UNDER_CE) - -//--------------------------------------------------------------------------------------// -// // -// helpers (all operating systems) // -// // -//--------------------------------------------------------------------------------------// - -namespace { - -// The number of retries remove_all should make if it detects that the directory it is about to enter has been replaced with a symlink or a regular file -BOOST_CONSTEXPR_OR_CONST unsigned int remove_all_directory_replaced_retry_count = 5u; - -#if defined(BOOST_POSIX_API) - -// Size of a small buffer for a path that can be placed on stack, in character code units -BOOST_CONSTEXPR_OR_CONST std::size_t small_path_size = 1024u; - -// Absolute maximum path length, in character code units, that we're willing to accept from various system calls. -// This value is arbitrary, it is supposed to be a hard limit to avoid memory exhaustion -// in some of the algorithms below in case of some corrupted or maliciously broken filesystem. -// A few examples of path size limits: -// - Windows: 32767 UTF-16 code units or 260 bytes for legacy multibyte APIs. -// - Linux: 4096 bytes -// - IRIX, HP-UX, Mac OS, QNX, FreeBSD, OpenBSD: 1024 bytes -// - GNU/Hurd: no hard limit -BOOST_CONSTEXPR_OR_CONST std::size_t absolute_path_max = 32u * 1024u; - -#endif // defined(BOOST_POSIX_API) - -// Maximum number of resolved symlinks before we register a loop -BOOST_CONSTEXPR_OR_CONST unsigned int symloop_max = -#if defined(SYMLOOP_MAX) - SYMLOOP_MAX < 40 ? 40 : SYMLOOP_MAX -#else - 40 -#endif -; - -// general helpers -----------------------------------------------------------------// - -bool is_empty_directory(path const& p, error_code* ec) -{ - fs::directory_iterator itr; - detail::directory_iterator_construct(itr, p, static_cast< unsigned int >(directory_options::none), NULL, ec); - return itr == fs::directory_iterator(); -} - -bool not_found_error(int errval) BOOST_NOEXCEPT; // forward declaration - -#ifdef BOOST_POSIX_API - -//--------------------------------------------------------------------------------------// -// // -// POSIX-specific helpers // -// // -//--------------------------------------------------------------------------------------// - -struct fd_wrapper -{ - int fd; - - fd_wrapper() BOOST_NOEXCEPT : fd(-1) {} - explicit fd_wrapper(int fd) BOOST_NOEXCEPT : fd(fd) {} - ~fd_wrapper() BOOST_NOEXCEPT - { - if (fd >= 0) - close_fd(fd); - } - BOOST_DELETED_FUNCTION(fd_wrapper(fd_wrapper const&)) - BOOST_DELETED_FUNCTION(fd_wrapper& operator=(fd_wrapper const&)) -}; - -inline bool not_found_error(int errval) BOOST_NOEXCEPT -{ - return errval == ENOENT || errval == ENOTDIR; -} - -#if defined(BOOST_FILESYSTEM_HAS_STATX) - -//! A wrapper for statx libc function. Disable MSAN since at least on clang 10 it doesn't -//! know which fields of struct statx are initialized by the syscall and misdetects errors. -BOOST_FILESYSTEM_NO_SANITIZE_MEMORY -BOOST_FORCEINLINE int invoke_statx(int dirfd, const char* path, int flags, unsigned int mask, struct ::statx* stx) -{ - return ::statx(dirfd, path, flags, mask, stx); -} - -#elif defined(BOOST_FILESYSTEM_HAS_STATX_SYSCALL) - -//! statx emulation through fstatat -int statx_fstatat(int dirfd, const char* path, int flags, unsigned int mask, struct ::statx* stx) -{ - struct ::stat st; - flags &= AT_EMPTY_PATH | AT_NO_AUTOMOUNT | AT_SYMLINK_NOFOLLOW; - int res = ::fstatat(dirfd, path, &st, flags); - if (BOOST_LIKELY(res == 0)) - { - std::memset(stx, 0, sizeof(*stx)); - stx->stx_mask = STATX_BASIC_STATS; - stx->stx_blksize = st.st_blksize; - stx->stx_nlink = st.st_nlink; - stx->stx_uid = st.st_uid; - stx->stx_gid = st.st_gid; - stx->stx_mode = st.st_mode; - stx->stx_ino = st.st_ino; - stx->stx_size = st.st_size; - stx->stx_blocks = st.st_blocks; - stx->stx_atime.tv_sec = st.st_atim.tv_sec; - stx->stx_atime.tv_nsec = st.st_atim.tv_nsec; - stx->stx_ctime.tv_sec = st.st_ctim.tv_sec; - stx->stx_ctime.tv_nsec = st.st_ctim.tv_nsec; - stx->stx_mtime.tv_sec = st.st_mtim.tv_sec; - stx->stx_mtime.tv_nsec = st.st_mtim.tv_nsec; - stx->stx_rdev_major = major(st.st_rdev); - stx->stx_rdev_minor = minor(st.st_rdev); - stx->stx_dev_major = major(st.st_dev); - stx->stx_dev_minor = minor(st.st_dev); - } - - return res; -} - -typedef int statx_t(int dirfd, const char* path, int flags, unsigned int mask, struct ::statx* stx); - -//! Pointer to the actual implementation of the statx implementation -statx_t* statx_ptr = &statx_fstatat; - -inline int invoke_statx(int dirfd, const char* path, int flags, unsigned int mask, struct ::statx* stx) BOOST_NOEXCEPT -{ - return filesystem::detail::atomic_load_relaxed(statx_ptr)(dirfd, path, flags, mask, stx); -} - -//! A wrapper for the statx syscall. Disable MSAN since at least on clang 10 it doesn't -//! know which fields of struct statx are initialized by the syscall and misdetects errors. -BOOST_FILESYSTEM_NO_SANITIZE_MEMORY -int statx_syscall(int dirfd, const char* path, int flags, unsigned int mask, struct ::statx* stx) -{ - int res = ::syscall(__NR_statx, dirfd, path, flags, mask, stx); - if (res < 0) - { - const int err = errno; - if (BOOST_UNLIKELY(err == ENOSYS)) - { - filesystem::detail::atomic_store_relaxed(statx_ptr, &statx_fstatat); - return statx_fstatat(dirfd, path, flags, mask, stx); - } - } - - return res; -} - -#endif // defined(BOOST_FILESYSTEM_HAS_STATX) - -#if defined(linux) || defined(__linux) || defined(__linux__) - -//! Initializes statx implementation pointer -inline void init_statx_impl(unsigned int major_ver, unsigned int minor_ver, unsigned int patch_ver) -{ -#if !defined(BOOST_FILESYSTEM_HAS_STATX) && defined(BOOST_FILESYSTEM_HAS_STATX_SYSCALL) - statx_t* stx = &statx_fstatat; - if (major_ver > 4u || (major_ver == 4u && minor_ver >= 11u)) - stx = &statx_syscall; - - filesystem::detail::atomic_store_relaxed(statx_ptr, stx); -#endif // !defined(BOOST_FILESYSTEM_HAS_STATX) && defined(BOOST_FILESYSTEM_HAS_STATX_SYSCALL) -} - -#endif // defined(linux) || defined(__linux) || defined(__linux__) - -#if defined(BOOST_FILESYSTEM_USE_STATX) - -//! Returns \c true if the two \c statx structures refer to the same file -inline bool equivalent_stat(struct ::statx const& s1, struct ::statx const& s2) BOOST_NOEXCEPT -{ - return s1.stx_dev_major == s2.stx_dev_major && s1.stx_dev_minor == s2.stx_dev_minor && s1.stx_ino == s2.stx_ino; -} - -//! Returns file type/access mode from \c statx structure -inline mode_t get_mode(struct ::statx const& st) BOOST_NOEXCEPT -{ - return st.stx_mode; -} - -//! Returns file size from \c statx structure -inline uintmax_t get_size(struct ::statx const& st) BOOST_NOEXCEPT -{ - return st.stx_size; -} - -//! Returns optimal block size from \c statx structure -inline std::size_t get_blksize(struct ::statx const& st) BOOST_NOEXCEPT -{ - return st.stx_blksize; -} - -#else // defined(BOOST_FILESYSTEM_USE_STATX) - -//! Returns \c true if the two \c stat structures refer to the same file -inline bool equivalent_stat(struct ::stat const& s1, struct ::stat const& s2) BOOST_NOEXCEPT -{ - // According to the POSIX stat specs, "The st_ino and st_dev fields - // taken together uniquely identify the file within the system." - return s1.st_dev == s2.st_dev && s1.st_ino == s2.st_ino; -} - -//! Returns file type/access mode from \c stat structure -inline mode_t get_mode(struct ::stat const& st) BOOST_NOEXCEPT -{ - return st.st_mode; -} - -//! Returns file size from \c stat structure -inline uintmax_t get_size(struct ::stat const& st) BOOST_NOEXCEPT -{ - return st.st_size; -} - -//! Returns optimal block size from \c stat structure -inline std::size_t get_blksize(struct ::stat const& st) BOOST_NOEXCEPT -{ -#if defined(BOOST_FILESYSTEM_HAS_STAT_ST_BLKSIZE) - return st.st_blksize; -#else - return 4096u; // a suitable default used on most modern SSDs/HDDs -#endif -} - -#endif // defined(BOOST_FILESYSTEM_USE_STATX) - -//! status() implementation -file_status status_impl -( - path const& p, - error_code* ec -#if defined(BOOST_FILESYSTEM_HAS_POSIX_AT_APIS) || defined(BOOST_FILESYSTEM_USE_STATX) - , int basedir_fd = AT_FDCWD -#endif -) -{ -#if defined(BOOST_FILESYSTEM_USE_STATX) - struct ::statx path_stat; - int err = invoke_statx(basedir_fd, p.c_str(), AT_NO_AUTOMOUNT, STATX_TYPE | STATX_MODE, &path_stat); -#elif defined(BOOST_FILESYSTEM_HAS_POSIX_AT_APIS) - struct ::stat path_stat; - int err = ::fstatat(basedir_fd, p.c_str(), &path_stat, AT_NO_AUTOMOUNT); -#else - struct ::stat path_stat; - int err = ::stat(p.c_str(), &path_stat); -#endif - - if (err != 0) - { - err = errno; - if (ec) // always report errno, even though some - ec->assign(err, system_category()); // errno values are not status_errors - - if (not_found_error(err)) - return fs::file_status(fs::file_not_found, fs::no_perms); - - if (!ec) - BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::status", p, error_code(err, system_category()))); - - return fs::file_status(fs::status_error); - } - -#if defined(BOOST_FILESYSTEM_USE_STATX) - if (BOOST_UNLIKELY((path_stat.stx_mask & (STATX_TYPE | STATX_MODE)) != (STATX_TYPE | STATX_MODE))) - { - emit_error(BOOST_ERROR_NOT_SUPPORTED, p, ec, "boost::filesystem::status"); - return fs::file_status(fs::status_error); - } -#endif - - const mode_t mode = get_mode(path_stat); - if (S_ISDIR(mode)) - return fs::file_status(fs::directory_file, static_cast< perms >(mode) & fs::perms_mask); - if (S_ISREG(mode)) - return fs::file_status(fs::regular_file, static_cast< perms >(mode) & fs::perms_mask); - if (S_ISBLK(mode)) - return fs::file_status(fs::block_file, static_cast< perms >(mode) & fs::perms_mask); - if (S_ISCHR(mode)) - return fs::file_status(fs::character_file, static_cast< perms >(mode) & fs::perms_mask); - if (S_ISFIFO(mode)) - return fs::file_status(fs::fifo_file, static_cast< perms >(mode) & fs::perms_mask); - if (S_ISSOCK(mode)) - return fs::file_status(fs::socket_file, static_cast< perms >(mode) & fs::perms_mask); - - return fs::file_status(fs::type_unknown); -} - -//! symlink_status() implementation -file_status symlink_status_impl -( - path const& p, - error_code* ec -#if defined(BOOST_FILESYSTEM_HAS_POSIX_AT_APIS) || defined(BOOST_FILESYSTEM_USE_STATX) - , int basedir_fd = AT_FDCWD -#endif -) -{ -#if defined(BOOST_FILESYSTEM_USE_STATX) - struct ::statx path_stat; - int err = invoke_statx(basedir_fd, p.c_str(), AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT, STATX_TYPE | STATX_MODE, &path_stat); -#elif defined(BOOST_FILESYSTEM_HAS_POSIX_AT_APIS) - struct ::stat path_stat; - int err = ::fstatat(basedir_fd, p.c_str(), &path_stat, AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT); -#else - struct ::stat path_stat; - int err = ::lstat(p.c_str(), &path_stat); -#endif - - if (err != 0) - { - err = errno; - if (ec) // always report errno, even though some - ec->assign(err, system_category()); // errno values are not status_errors - - if (not_found_error(err)) // these are not errors - return fs::file_status(fs::file_not_found, fs::no_perms); - - if (!ec) - BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::symlink_status", p, error_code(err, system_category()))); - - return fs::file_status(fs::status_error); - } - -#if defined(BOOST_FILESYSTEM_USE_STATX) - if (BOOST_UNLIKELY((path_stat.stx_mask & (STATX_TYPE | STATX_MODE)) != (STATX_TYPE | STATX_MODE))) - { - emit_error(BOOST_ERROR_NOT_SUPPORTED, p, ec, "boost::filesystem::symlink_status"); - return fs::file_status(fs::status_error); - } -#endif - - const mode_t mode = get_mode(path_stat); - if (S_ISREG(mode)) - return fs::file_status(fs::regular_file, static_cast< perms >(mode) & fs::perms_mask); - if (S_ISDIR(mode)) - return fs::file_status(fs::directory_file, static_cast< perms >(mode) & fs::perms_mask); - if (S_ISLNK(mode)) - return fs::file_status(fs::symlink_file, static_cast< perms >(mode) & fs::perms_mask); - if (S_ISBLK(mode)) - return fs::file_status(fs::block_file, static_cast< perms >(mode) & fs::perms_mask); - if (S_ISCHR(mode)) - return fs::file_status(fs::character_file, static_cast< perms >(mode) & fs::perms_mask); - if (S_ISFIFO(mode)) - return fs::file_status(fs::fifo_file, static_cast< perms >(mode) & fs::perms_mask); - if (S_ISSOCK(mode)) - return fs::file_status(fs::socket_file, static_cast< perms >(mode) & fs::perms_mask); - - return fs::file_status(fs::type_unknown); -} - -//! Flushes buffered data and attributes written to the file to permanent storage -inline int full_sync(int fd) -{ - while (true) - { -#if defined(__APPLE__) && defined(__MACH__) && defined(F_FULLFSYNC) - // Mac OS does not flush data to physical storage with fsync() - int err = ::fcntl(fd, F_FULLFSYNC); -#else - int err = ::fsync(fd); -#endif - if (BOOST_UNLIKELY(err < 0)) - { - err = errno; - // POSIX says fsync can return EINTR (https://pubs.opengroup.org/onlinepubs/9699919799/functions/fsync.html). - // fcntl(F_FULLFSYNC) isn't documented to return EINTR, but it doesn't hurt to check. - if (err == EINTR) - continue; - - return err; - } - - break; - } - - return 0; -} - -//! Flushes buffered data written to the file to permanent storage -inline int data_sync(int fd) -{ -#if defined(BOOST_FILESYSTEM_HAS_FDATASYNC) && !(defined(__APPLE__) && defined(__MACH__) && defined(F_FULLFSYNC)) - while (true) - { - int err = ::fdatasync(fd); - if (BOOST_UNLIKELY(err != 0)) - { - err = errno; - // POSIX says fsync can return EINTR (https://pubs.opengroup.org/onlinepubs/9699919799/functions/fsync.html). - // It doesn't say so for fdatasync, but it is reasonable to expect it as well. - if (err == EINTR) - continue; - - return err; - } - - break; - } - - return 0; -#else - return full_sync(fd); -#endif -} - -// Min and max buffer sizes are selected to minimize the overhead from system calls. -// The values are picked based on coreutils cp(1) benchmarking data described here: -// https://github.com/coreutils/coreutils/blob/d1b0257077c0b0f0ee25087efd46270345d1dd1f/src/ioblksize.h#L23-L72 -BOOST_CONSTEXPR_OR_CONST uint_least32_t min_read_write_buf_size = 8u * 1024u; -BOOST_CONSTEXPR_OR_CONST uint_least32_t max_read_write_buf_size = 256u * 1024u; - -//! copy_file read/write loop implementation -int copy_file_data_read_write_impl(int infile, int outfile, char* buf, std::size_t buf_size) -{ -#if defined(BOOST_FILESYSTEM_HAS_POSIX_FADVISE) - ::posix_fadvise(infile, 0, 0, POSIX_FADV_SEQUENTIAL); -#endif - - // Don't use file size to limit the amount of data to copy since some filesystems, like procfs or sysfs, - // provide files with generated content and indicate that their size is zero or 4096. Just copy as much data - // as we can read from the input file. - while (true) - { - ssize_t sz_read = ::read(infile, buf, buf_size); - if (sz_read == 0) - break; - if (BOOST_UNLIKELY(sz_read < 0)) - { - int err = errno; - if (err == EINTR) - continue; - return err; - } - - // Allow for partial writes - see Advanced Unix Programming (2nd Ed.), - // Marc Rochkind, Addison-Wesley, 2004, page 94 - for (ssize_t sz_wrote = 0; sz_wrote < sz_read;) - { - ssize_t sz = ::write(outfile, buf + sz_wrote, static_cast< std::size_t >(sz_read - sz_wrote)); - if (BOOST_UNLIKELY(sz < 0)) - { - int err = errno; - if (err == EINTR) - continue; - return err; - } - - sz_wrote += sz; - } - } - - return 0; -} - -//! copy_file implementation that uses read/write loop (fallback using a stack buffer) -int copy_file_data_read_write_stack_buf(int infile, int outfile) -{ - char stack_buf[min_read_write_buf_size]; - return copy_file_data_read_write_impl(infile, outfile, stack_buf, sizeof(stack_buf)); -} - -//! copy_file implementation that uses read/write loop -int copy_file_data_read_write(int infile, int outfile, uintmax_t size, std::size_t blksize) -{ - { - uintmax_t buf_sz = size; - // Prefer the buffer to be larger than the file size so that we don't have - // to perform an extra read if the file fits in the buffer exactly. - buf_sz += (buf_sz < ~static_cast< uintmax_t >(0u)); - if (buf_sz < blksize) - buf_sz = blksize; - if (buf_sz < min_read_write_buf_size) - buf_sz = min_read_write_buf_size; - if (buf_sz > max_read_write_buf_size) - buf_sz = max_read_write_buf_size; - const std::size_t buf_size = static_cast< std::size_t >(boost::core::bit_ceil(static_cast< uint_least32_t >(buf_sz))); - boost::scoped_array< char > buf(new (std::nothrow) char[buf_size]); - if (BOOST_LIKELY(!!buf.get())) - return copy_file_data_read_write_impl(infile, outfile, buf.get(), buf_size); - } - - return copy_file_data_read_write_stack_buf(infile, outfile); -} - -typedef int copy_file_data_t(int infile, int outfile, uintmax_t size, std::size_t blksize); - -//! Pointer to the actual implementation of the copy_file_data implementation -copy_file_data_t* copy_file_data = ©_file_data_read_write; - -#if defined(BOOST_FILESYSTEM_USE_SENDFILE) || defined(BOOST_FILESYSTEM_USE_COPY_FILE_RANGE) - -//! copy_file_data wrapper that tests if a read/write loop must be used for a given filesystem -template< typename CopyFileData > -int check_fs_type(int infile, int outfile, uintmax_t size, std::size_t blksize); - -#endif // defined(BOOST_FILESYSTEM_USE_SENDFILE) || defined(BOOST_FILESYSTEM_USE_COPY_FILE_RANGE) - -#if defined(BOOST_FILESYSTEM_USE_SENDFILE) - -struct copy_file_data_sendfile -{ - //! copy_file implementation that uses sendfile loop. Requires sendfile to support file descriptors. - static int impl(int infile, int outfile, uintmax_t size, std::size_t blksize) - { - // sendfile will not send more than this amount of data in one call - BOOST_CONSTEXPR_OR_CONST std::size_t max_batch_size = 0x7ffff000u; - uintmax_t offset = 0u; - while (offset < size) - { - uintmax_t size_left = size - offset; - std::size_t size_to_copy = max_batch_size; - if (size_left < static_cast< uintmax_t >(max_batch_size)) - size_to_copy = static_cast< std::size_t >(size_left); - ssize_t sz = ::sendfile(outfile, infile, NULL, size_to_copy); - if (BOOST_UNLIKELY(sz < 0)) - { - int err = errno; - if (err == EINTR) - continue; - - if (offset == 0u) - { - // sendfile may fail with EINVAL if the underlying filesystem does not support it - if (err == EINVAL) - { - fallback_to_read_write: - return copy_file_data_read_write(infile, outfile, size, blksize); - } - - if (err == ENOSYS) - { - filesystem::detail::atomic_store_relaxed(copy_file_data, ©_file_data_read_write); - goto fallback_to_read_write; - } - } - - return err; - } - - offset += sz; - } - - return 0; - } -}; - -#endif // defined(BOOST_FILESYSTEM_USE_SENDFILE) - -#if defined(BOOST_FILESYSTEM_USE_COPY_FILE_RANGE) - -struct copy_file_data_copy_file_range -{ - //! copy_file implementation that uses copy_file_range loop. Requires copy_file_range to support cross-filesystem copying. - static int impl(int infile, int outfile, uintmax_t size, std::size_t blksize) - { - // Although copy_file_range does not document any particular upper limit of one transfer, still use some upper bound to guarantee - // that size_t is not overflown in case if off_t is larger and the file size does not fit in size_t. - BOOST_CONSTEXPR_OR_CONST std::size_t max_batch_size = 0x7ffff000u; - uintmax_t offset = 0u; - while (offset < size) - { - uintmax_t size_left = size - offset; - std::size_t size_to_copy = max_batch_size; - if (size_left < static_cast< uintmax_t >(max_batch_size)) - size_to_copy = static_cast< std::size_t >(size_left); - // Note: Use syscall directly to avoid depending on libc version. copy_file_range is added in glibc 2.27. - // uClibc-ng does not have copy_file_range as of the time of this writing (the latest uClibc-ng release is 1.0.33). - loff_t sz = ::syscall(__NR_copy_file_range, infile, (loff_t*)NULL, outfile, (loff_t*)NULL, size_to_copy, (unsigned int)0u); - if (BOOST_UNLIKELY(sz < 0)) - { - int err = errno; - if (err == EINTR) - continue; - - if (offset == 0u) - { - // copy_file_range may fail with EINVAL if the underlying filesystem does not support it. - // In some RHEL/CentOS 7.7-7.8 kernel versions, copy_file_range on NFSv4 is also known to return EOPNOTSUPP - // if the remote server does not support COPY, despite that it is not a documented error code. - // See https://patchwork.kernel.org/project/linux-nfs/patch/20190411183418.4510-1-olga.kornievskaia@gmail.com/ - // and https://bugzilla.redhat.com/show_bug.cgi?id=1783554. - if (err == EINVAL || err == EOPNOTSUPP) - { -#if !defined(BOOST_FILESYSTEM_USE_SENDFILE) - fallback_to_read_write: -#endif - return copy_file_data_read_write(infile, outfile, size, blksize); - } - - if (err == EXDEV) - { -#if defined(BOOST_FILESYSTEM_USE_SENDFILE) - fallback_to_sendfile: - return copy_file_data_sendfile::impl(infile, outfile, size, blksize); -#else - goto fallback_to_read_write; -#endif - } - - if (err == ENOSYS) - { -#if defined(BOOST_FILESYSTEM_USE_SENDFILE) - filesystem::detail::atomic_store_relaxed(copy_file_data, &check_fs_type< copy_file_data_sendfile >); - goto fallback_to_sendfile; -#else - filesystem::detail::atomic_store_relaxed(copy_file_data, ©_file_data_read_write); - goto fallback_to_read_write; -#endif - } - } - - return err; - } - - offset += sz; - } - - return 0; - } -}; - -#endif // defined(BOOST_FILESYSTEM_USE_COPY_FILE_RANGE) - -#if defined(BOOST_FILESYSTEM_USE_SENDFILE) || defined(BOOST_FILESYSTEM_USE_COPY_FILE_RANGE) - -//! copy_file_data wrapper that tests if a read/write loop must be used for a given filesystem -template< typename CopyFileData > -int check_fs_type(int infile, int outfile, uintmax_t size, std::size_t blksize) -{ - { - // 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. - // https://lore.kernel.org/linux-fsdevel/20210212044405.4120619-1-drinkcat@chromium.org/T/ - struct statfs sfs; - while (true) - { - int err = ::fstatfs(infile, &sfs); - if (BOOST_UNLIKELY(err < 0)) - { - err = errno; - if (err == EINTR) - continue; - - goto fallback_to_read_write; - } - - break; - } - - if (BOOST_UNLIKELY(sfs.f_type == PROC_SUPER_MAGIC || - sfs.f_type == SYSFS_MAGIC || - sfs.f_type == TRACEFS_MAGIC || - sfs.f_type == DEBUGFS_MAGIC)) - { - fallback_to_read_write: - return copy_file_data_read_write(infile, outfile, size, blksize); - } - } - - return CopyFileData::impl(infile, outfile, size, blksize); -} - -#endif // defined(BOOST_FILESYSTEM_USE_SENDFILE) || defined(BOOST_FILESYSTEM_USE_COPY_FILE_RANGE) - -#if defined(linux) || defined(__linux) || defined(__linux__) - -//! Initializes copy_file_data implementation pointer -inline void init_copy_file_data_impl(unsigned int major_ver, unsigned int minor_ver, unsigned int patch_ver) -{ -#if defined(BOOST_FILESYSTEM_USE_SENDFILE) || defined(BOOST_FILESYSTEM_USE_COPY_FILE_RANGE) - copy_file_data_t* cfd = ©_file_data_read_write; - -#if defined(BOOST_FILESYSTEM_USE_SENDFILE) - // sendfile started accepting file descriptors as the target in Linux 2.6.33 - if (major_ver > 2u || (major_ver == 2u && (minor_ver > 6u || (minor_ver == 6u && patch_ver >= 33u)))) - cfd = &check_fs_type< copy_file_data_sendfile >; -#endif - -#if defined(BOOST_FILESYSTEM_USE_COPY_FILE_RANGE) - // Although copy_file_range appeared in Linux 4.5, it did not support cross-filesystem copying until 5.3. - // copy_file_data_copy_file_range will fallback to copy_file_data_sendfile if copy_file_range returns EXDEV. - if (major_ver > 4u || (major_ver == 4u && minor_ver >= 5u)) - cfd = &check_fs_type< copy_file_data_copy_file_range >; -#endif - - filesystem::detail::atomic_store_relaxed(copy_file_data, cfd); -#endif // defined(BOOST_FILESYSTEM_USE_SENDFILE) || defined(BOOST_FILESYSTEM_USE_COPY_FILE_RANGE) -} - -#endif // defined(linux) || defined(__linux) || defined(__linux__) - -#if defined(linux) || defined(__linux) || defined(__linux__) - -struct syscall_initializer -{ - syscall_initializer() - { - struct ::utsname system_info; - if (BOOST_UNLIKELY(::uname(&system_info) < 0)) - return; - - unsigned int major_ver = 0u, minor_ver = 0u, patch_ver = 0u; - int count = std::sscanf(system_info.release, "%u.%u.%u", &major_ver, &minor_ver, &patch_ver); - if (BOOST_UNLIKELY(count < 3)) - return; - - init_statx_impl(major_ver, minor_ver, patch_ver); - init_copy_file_data_impl(major_ver, minor_ver, patch_ver); - init_fill_random_impl(major_ver, minor_ver, patch_ver); - } -}; - -BOOST_FILESYSTEM_INIT_PRIORITY(BOOST_FILESYSTEM_FUNC_PTR_INIT_PRIORITY) BOOST_ATTRIBUTE_UNUSED BOOST_FILESYSTEM_ATTRIBUTE_RETAIN -const syscall_initializer syscall_init; - -#endif // defined(linux) || defined(__linux) || defined(__linux__) - -//! remove() implementation -inline bool remove_impl -( - path const& p, - fs::file_type type, - error_code* ec -#if defined(BOOST_FILESYSTEM_HAS_POSIX_AT_APIS) - , int basedir_fd = AT_FDCWD -#endif -) -{ - if (type == fs::file_not_found) - return false; - - int res; -#if defined(BOOST_FILESYSTEM_HAS_POSIX_AT_APIS) - res = ::unlinkat(basedir_fd, p.c_str(), type == fs::directory_file ? AT_REMOVEDIR : 0); -#else - if (type == fs::directory_file) - res = ::rmdir(p.c_str()); - else - res = ::unlink(p.c_str()); -#endif - - if (res != 0) - { - int err = errno; - if (BOOST_UNLIKELY(!not_found_error(err))) - emit_error(err, p, ec, "boost::filesystem::remove"); - - return false; - } - - return true; -} - -//! remove() implementation -inline bool remove_impl(path const& p, error_code* ec) -{ - // Since POSIX remove() is specified to work with either files or directories, in a - // perfect world it could just be called. But some important real-world operating - // systems (Windows, Mac OS, for example) don't implement the POSIX spec. So - // we have to distinguish between files and directories and call corresponding APIs - // to remove them. - - error_code local_ec; - fs::file_type type = fs::detail::symlink_status_impl(p, &local_ec).type(); - if (BOOST_UNLIKELY(type == fs::status_error)) - { - if (!ec) - BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::remove", p, local_ec)); - - *ec = local_ec; - return false; - } - - return fs::detail::remove_impl(p, type, ec); -} - -//! remove_all() implementation -uintmax_t remove_all_impl -( - path const& p, - error_code* ec -#if defined(BOOST_FILESYSTEM_HAS_FDOPENDIR_NOFOLLOW) && defined(BOOST_FILESYSTEM_HAS_POSIX_AT_APIS) - , int basedir_fd = AT_FDCWD -#endif -) -{ -#if defined(BOOST_FILESYSTEM_HAS_FDOPENDIR_NOFOLLOW) && defined(BOOST_FILESYSTEM_HAS_POSIX_AT_APIS) - fs::detail::directory_iterator_params params; - params.basedir_fd = basedir_fd; - params.iterator_fd = -1; -#endif - - error_code dit_create_ec; - for (unsigned int attempt = 0u; attempt < remove_all_directory_replaced_retry_count; ++attempt) - { - fs::file_type type; - { - error_code local_ec; - type = fs::detail::symlink_status_impl - ( - p, - &local_ec -#if defined(BOOST_FILESYSTEM_HAS_FDOPENDIR_NOFOLLOW) && defined(BOOST_FILESYSTEM_HAS_POSIX_AT_APIS) - , basedir_fd -#endif - ).type(); - - if (type == fs::file_not_found) - return 0u; - - if (BOOST_UNLIKELY(type == fs::status_error)) - { - if (!ec) - BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::remove_all", p, local_ec)); - - *ec = local_ec; - return static_cast< uintmax_t >(-1); - } - } - - uintmax_t count = 0u; - if (type == fs::directory_file) // but not a directory symlink - { - fs::directory_iterator itr; - fs::detail::directory_iterator_construct - ( - itr, - p, - static_cast< unsigned int >(directory_options::_detail_no_follow), -#if defined(BOOST_FILESYSTEM_HAS_FDOPENDIR_NOFOLLOW) && defined(BOOST_FILESYSTEM_HAS_POSIX_AT_APIS) - ¶ms, -#else - NULL, -#endif - &dit_create_ec - ); - - if (BOOST_UNLIKELY(!!dit_create_ec)) - { - if (dit_create_ec == error_code(ENOTDIR, system_category())) - continue; - -#if defined(BOOST_FILESYSTEM_HAS_FDOPENDIR_NOFOLLOW) - // If open(2) with O_NOFOLLOW fails with ELOOP, this means that either the path contains a loop - // of symbolic links, or the last element of the path is a symbolic link. Given that lstat(2) above - // did not fail, most likely it is the latter case. I.e. between the lstat above and this open call - // the filesystem was modified so that the path no longer refers to a directory file (as opposed to a symlink). - if (dit_create_ec == error_code(ELOOP, system_category())) - continue; -#endif // defined(BOOST_FILESYSTEM_HAS_FDOPENDIR_NOFOLLOW) - - if (!ec) - BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::remove_all", p, dit_create_ec)); - - *ec = dit_create_ec; - return static_cast< uintmax_t >(-1); - } - - const fs::directory_iterator end_dit; - while (itr != end_dit) - { - count += fs::detail::remove_all_impl - ( -#if defined(BOOST_FILESYSTEM_HAS_FDOPENDIR_NOFOLLOW) && defined(BOOST_FILESYSTEM_HAS_POSIX_AT_APIS) - itr->path().filename(), -#else - itr->path(), -#endif - ec -#if defined(BOOST_FILESYSTEM_HAS_FDOPENDIR_NOFOLLOW) && defined(BOOST_FILESYSTEM_HAS_POSIX_AT_APIS) - , params.iterator_fd -#endif - ); - if (ec && *ec) - return static_cast< uintmax_t >(-1); - - fs::detail::directory_iterator_increment(itr, ec); - if (ec && *ec) - return static_cast< uintmax_t >(-1); - } - } - - count += fs::detail::remove_impl - ( - p, - type, - ec -#if defined(BOOST_FILESYSTEM_HAS_FDOPENDIR_NOFOLLOW) && defined(BOOST_FILESYSTEM_HAS_POSIX_AT_APIS) - , basedir_fd -#endif - ); - if (ec && *ec) - return static_cast< uintmax_t >(-1); - - return count; - } - - if (!ec) - BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::remove_all: path cannot be opened as a directory", p, dit_create_ec)); - - *ec = dit_create_ec; - return static_cast< uintmax_t >(-1); -} - -#else // defined(BOOST_POSIX_API) - -//--------------------------------------------------------------------------------------// -// // -// Windows-specific helpers // -// // -//--------------------------------------------------------------------------------------// - -//! FILE_BASIC_INFO definition from Windows SDK -struct file_basic_info -{ - LARGE_INTEGER CreationTime; - LARGE_INTEGER LastAccessTime; - LARGE_INTEGER LastWriteTime; - LARGE_INTEGER ChangeTime; - DWORD FileAttributes; -}; - -//! FILE_DISPOSITION_INFO definition from Windows SDK -struct file_disposition_info -{ - BOOLEAN DeleteFile; -}; - -//! FILE_DISPOSITION_INFO_EX definition from Windows SDK -struct file_disposition_info_ex -{ - DWORD Flags; -}; - -#ifndef FILE_DISPOSITION_FLAG_DELETE -#define FILE_DISPOSITION_FLAG_DELETE 0x00000001 -#endif -// Available since Windows 10 1709 -#ifndef FILE_DISPOSITION_FLAG_POSIX_SEMANTICS -#define FILE_DISPOSITION_FLAG_POSIX_SEMANTICS 0x00000002 -#endif -// Available since Windows 10 1809 -#ifndef FILE_DISPOSITION_FLAG_IGNORE_READONLY_ATTRIBUTE -#define FILE_DISPOSITION_FLAG_IGNORE_READONLY_ATTRIBUTE 0x00000010 -#endif - -// REPARSE_DATA_BUFFER related definitions are found in ntifs.h, which is part of the -// Windows Device Driver Kit. Since that's inconvenient, the definitions are provided -// here. See http://msdn.microsoft.com/en-us/library/ms791514.aspx -struct reparse_data_buffer -{ - ULONG ReparseTag; - USHORT ReparseDataLength; - USHORT Reserved; - union - { - /* - * In SymbolicLink and MountPoint reparse points, there are two names. - * SubstituteName is the effective replacement path for the reparse point. - * This is what should be used for path traversal. - * PrintName is intended for presentation to the user and may omit some - * elements of the path or be absent entirely. - * - * Examples of substitute and print names: - * mklink /D ldrive c:\ - * SubstituteName: "\??\c:\" - * PrintName: "c:\" - * - * mklink /J ldrive c:\ - * SubstituteName: "\??\C:\" - * PrintName: "c:\" - * - * junction ldrive c:\ - * SubstituteName: "\??\C:\" - * PrintName: "" - * - * box.com mounted cloud storage - * SubstituteName: "\??\Volume{<UUID>}\" - * PrintName: "" - */ - struct - { - USHORT SubstituteNameOffset; - USHORT SubstituteNameLength; - USHORT PrintNameOffset; - USHORT PrintNameLength; - ULONG Flags; - WCHAR PathBuffer[1]; - } SymbolicLinkReparseBuffer; - struct - { - USHORT SubstituteNameOffset; - USHORT SubstituteNameLength; - USHORT PrintNameOffset; - USHORT PrintNameLength; - WCHAR PathBuffer[1]; - } MountPointReparseBuffer; - struct - { - UCHAR DataBuffer[1]; - } GenericReparseBuffer; - }; -}; - -// Our convenience type for allocating REPARSE_DATA_BUFFER along with sufficient space after it -union reparse_data_buffer_with_storage -{ - reparse_data_buffer rdb; - unsigned char storage[MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; -}; - -// Windows kernel32.dll functions that may or may not be present -// must be accessed through pointers - -typedef BOOL (WINAPI CreateHardLinkW_t)( - /*__in*/ LPCWSTR lpFileName, - /*__in*/ LPCWSTR lpExistingFileName, - /*__reserved*/ LPSECURITY_ATTRIBUTES lpSecurityAttributes); - -CreateHardLinkW_t* create_hard_link_api = NULL; - -typedef BOOLEAN (WINAPI CreateSymbolicLinkW_t)( - /*__in*/ LPCWSTR lpSymlinkFileName, - /*__in*/ LPCWSTR lpTargetFileName, - /*__in*/ DWORD dwFlags); - -CreateSymbolicLinkW_t* create_symbolic_link_api = NULL; - -//! SetFileInformationByHandle signature. Available since Windows Vista. -typedef BOOL (WINAPI SetFileInformationByHandle_t)( - /*_In_*/ HANDLE hFile, - /*_In_*/ file_info_by_handle_class FileInformationClass, // the actual type is FILE_INFO_BY_HANDLE_CLASS enum - /*_In_reads_bytes_(dwBufferSize)*/ LPVOID lpFileInformation, - /*_In_*/ DWORD dwBufferSize); - -SetFileInformationByHandle_t* set_file_information_by_handle_api = NULL; - -} // unnamed namespace - -GetFileInformationByHandleEx_t* get_file_information_by_handle_ex_api = NULL; - -#if !defined(UNDER_CE) -NtCreateFile_t* nt_create_file_api = NULL; -NtQueryDirectoryFile_t* nt_query_directory_file_api = NULL; -#endif // !defined(UNDER_CE) - -namespace { - -//! remove() implementation type -enum remove_impl_type -{ - remove_nt5, //!< Use Windows XP API - remove_disp, //!< Use FILE_DISPOSITION_INFO (Windows Vista and later) - remove_disp_ex_flag_posix_semantics, //!< Use FILE_DISPOSITION_INFO_EX with FILE_DISPOSITION_FLAG_POSIX_SEMANTICS - remove_disp_ex_flag_ignore_readonly //!< Use FILE_DISPOSITION_INFO_EX with FILE_DISPOSITION_FLAG_POSIX_SEMANTICS | FILE_DISPOSITION_FLAG_IGNORE_READONLY_ATTRIBUTE -}; - -remove_impl_type g_remove_impl_type = remove_nt5; - -//! Initializes WinAPI function pointers -BOOST_FILESYSTEM_INIT_FUNC init_winapi_func_ptrs() -{ - boost::winapi::HMODULE_ h = boost::winapi::GetModuleHandleW(L"kernel32.dll"); - if (BOOST_LIKELY(!!h)) - { - GetFileInformationByHandleEx_t* get_file_information_by_handle_ex = (GetFileInformationByHandleEx_t*)boost::winapi::get_proc_address(h, "GetFileInformationByHandleEx"); - filesystem::detail::atomic_store_relaxed(get_file_information_by_handle_ex_api, get_file_information_by_handle_ex); - SetFileInformationByHandle_t* set_file_information_by_handle = (SetFileInformationByHandle_t*)boost::winapi::get_proc_address(h, "SetFileInformationByHandle"); - filesystem::detail::atomic_store_relaxed(set_file_information_by_handle_api, set_file_information_by_handle); - filesystem::detail::atomic_store_relaxed(create_hard_link_api, (CreateHardLinkW_t*)boost::winapi::get_proc_address(h, "CreateHardLinkW")); - filesystem::detail::atomic_store_relaxed(create_symbolic_link_api, (CreateSymbolicLinkW_t*)boost::winapi::get_proc_address(h, "CreateSymbolicLinkW")); - - if (get_file_information_by_handle_ex && set_file_information_by_handle) - { - // Enable the most advanced implementation based on GetFileInformationByHandleEx/SetFileInformationByHandle. - // If certain flags are not supported by the OS, the remove() implementation will downgrade accordingly. - filesystem::detail::atomic_store_relaxed(g_remove_impl_type, remove_disp_ex_flag_ignore_readonly); - } - } - -#if !defined(UNDER_CE) - h = boost::winapi::GetModuleHandleW(L"ntdll.dll"); - if (BOOST_LIKELY(!!h)) - { - filesystem::detail::atomic_store_relaxed(nt_create_file_api, (NtCreateFile_t*)boost::winapi::get_proc_address(h, "NtCreateFile")); - filesystem::detail::atomic_store_relaxed(nt_query_directory_file_api, (NtQueryDirectoryFile_t*)boost::winapi::get_proc_address(h, "NtQueryDirectoryFile")); - } - - init_directory_iterator_impl(); -#endif // !defined(UNDER_CE) - - return BOOST_FILESYSTEM_INITRETSUCCESS_V; -} - -#if defined(_MSC_VER) - -#if _MSC_VER >= 1400 - -#pragma section(".CRT$XCL", long, read) -__declspec(allocate(".CRT$XCL")) BOOST_ATTRIBUTE_UNUSED BOOST_FILESYSTEM_ATTRIBUTE_RETAIN -extern const init_func_ptr_t p_init_winapi_func_ptrs = &init_winapi_func_ptrs; - -#else // _MSC_VER >= 1400 - -#if (_MSC_VER >= 1300) // 1300 == VC++ 7.0 -#pragma data_seg(push, old_seg) -#endif -#pragma data_seg(".CRT$XCL") -BOOST_ATTRIBUTE_UNUSED BOOST_FILESYSTEM_ATTRIBUTE_RETAIN -extern const init_func_ptr_t p_init_winapi_func_ptrs = &init_winapi_func_ptrs; -#pragma data_seg() -#if (_MSC_VER >= 1300) // 1300 == VC++ 7.0 -#pragma data_seg(pop, old_seg) -#endif - -#endif // _MSC_VER >= 1400 - -#if defined(BOOST_FILESYSTEM_NO_ATTRIBUTE_RETAIN) -//! Makes sure the global initializer pointers are referenced and not removed by linker -struct globals_retainer -{ - const init_func_ptr_t* volatile m_p_init_winapi_func_ptrs; - - globals_retainer() { m_p_init_winapi_func_ptrs = &p_init_winapi_func_ptrs; } -}; -BOOST_ATTRIBUTE_UNUSED -const globals_retainer g_globals_retainer; -#endif // defined(BOOST_FILESYSTEM_NO_ATTRIBUTE_RETAIN) - -#else // defined(_MSC_VER) - -//! Invokes WinAPI function pointers initialization -struct winapi_func_ptrs_initializer -{ - winapi_func_ptrs_initializer() { init_winapi_func_ptrs(); } -}; - -BOOST_FILESYSTEM_INIT_PRIORITY(BOOST_FILESYSTEM_FUNC_PTR_INIT_PRIORITY) BOOST_ATTRIBUTE_UNUSED BOOST_FILESYSTEM_ATTRIBUTE_RETAIN -const winapi_func_ptrs_initializer winapi_func_ptrs_init; - -#endif // defined(_MSC_VER) - - -// Windows CE has no environment variables -#if !defined(UNDER_CE) -inline std::wstring wgetenv(const wchar_t* name) -{ - // use a separate buffer since C++03 basic_string is not required to be contiguous - const DWORD size = ::GetEnvironmentVariableW(name, NULL, 0); - if (size > 0) - { - boost::scoped_array< wchar_t > buf(new wchar_t[size]); - if (BOOST_LIKELY(::GetEnvironmentVariableW(name, buf.get(), size) > 0)) - return std::wstring(buf.get()); - } - - return std::wstring(); -} -#endif // !defined(UNDER_CE) - -inline bool not_found_error(int errval) BOOST_NOEXCEPT -{ - return errval == ERROR_FILE_NOT_FOUND || errval == ERROR_PATH_NOT_FOUND || errval == ERROR_INVALID_NAME // "tools/jam/src/:sys:stat.h", "//foo" - || errval == ERROR_INVALID_DRIVE // USB card reader with no card inserted - || errval == ERROR_NOT_READY // CD/DVD drive with no disc inserted - || errval == ERROR_INVALID_PARAMETER // ":sys:stat.h" - || errval == ERROR_BAD_PATHNAME // "//no-host" on Win64 - || errval == ERROR_BAD_NETPATH // "//no-host" on Win32 - || errval == ERROR_BAD_NET_NAME; // "//no-host/no-share" on Win10 x64 -} - -// these constants come from inspecting some Microsoft sample code -inline std::time_t to_time_t(FILETIME const& ft) BOOST_NOEXCEPT -{ - uint64_t t = (static_cast< uint64_t >(ft.dwHighDateTime) << 32) | ft.dwLowDateTime; - t -= 116444736000000000ull; - t /= 10000000u; - return static_cast< std::time_t >(t); -} - -inline void to_FILETIME(std::time_t t, FILETIME& ft) BOOST_NOEXCEPT -{ - uint64_t temp = t; - temp *= 10000000u; - temp += 116444736000000000ull; - ft.dwLowDateTime = static_cast< DWORD >(temp); - ft.dwHighDateTime = static_cast< DWORD >(temp >> 32); -} - -} // unnamed namespace - -#if !defined(UNDER_CE) - -//! The flag indicates whether OBJ_DONT_REPARSE flag is not supported by the kernel -static bool g_no_obj_dont_reparse = false; - -//! Creates a file handle for a file relative to a previously opened base directory. The file path must be relative and in preferred format. -boost::winapi::NTSTATUS_ nt_create_file_handle_at(HANDLE& out, HANDLE basedir_handle, boost::filesystem::path const& p, ULONG FileAttributes, ACCESS_MASK DesiredAccess, ULONG ShareMode, ULONG CreateDisposition, ULONG CreateOptions) -{ - NtCreateFile_t* nt_create_file = filesystem::detail::atomic_load_relaxed(nt_create_file_api); - if (BOOST_UNLIKELY(!nt_create_file)) - return STATUS_NOT_IMPLEMENTED; - - unicode_string obj_name = {}; - obj_name.Buffer = const_cast< wchar_t* >(p.c_str()); - obj_name.Length = obj_name.MaximumLength = static_cast< USHORT >(p.size() * sizeof(wchar_t)); - - object_attributes obj_attrs = {}; - obj_attrs.Length = sizeof(obj_attrs); - obj_attrs.RootDirectory = basedir_handle; - obj_attrs.ObjectName = &obj_name; - - obj_attrs.Attributes = OBJ_CASE_INSENSITIVE; - if ((CreateOptions & FILE_OPEN_REPARSE_POINT) != 0u && !filesystem::detail::atomic_load_relaxed(g_no_obj_dont_reparse)) - obj_attrs.Attributes |= OBJ_DONT_REPARSE; - - io_status_block iosb; - boost::winapi::NTSTATUS_ status = nt_create_file - ( - &out, - DesiredAccess, - &obj_attrs, - &iosb, - NULL, // AllocationSize - FileAttributes, - ShareMode, - CreateDisposition, - CreateOptions, - NULL, // EaBuffer - 0u // EaLength - ); - - if (BOOST_UNLIKELY(status == STATUS_INVALID_PARAMETER && (obj_attrs.Attributes & OBJ_DONT_REPARSE) != 0u)) - { - // OBJ_DONT_REPARSE is supported since Windows 10, retry without it - filesystem::detail::atomic_store_relaxed(g_no_obj_dont_reparse, true); - obj_attrs.Attributes &= ~static_cast< ULONG >(OBJ_DONT_REPARSE); - - status = nt_create_file - ( - &out, - DesiredAccess, - &obj_attrs, - &iosb, - NULL, // AllocationSize - FileAttributes, - ShareMode, - CreateDisposition, - CreateOptions, - NULL, // EaBuffer - 0u // EaLength - ); - } - - return status; -} - -#endif // !defined(UNDER_CE) - -bool is_reparse_point_a_symlink_ioctl(HANDLE h) -{ - boost::scoped_ptr< reparse_data_buffer_with_storage > buf(new reparse_data_buffer_with_storage); - - // Query the reparse data - DWORD dwRetLen = 0u; - BOOL result = ::DeviceIoControl(h, FSCTL_GET_REPARSE_POINT, NULL, 0, buf.get(), sizeof(*buf), &dwRetLen, NULL); - if (BOOST_UNLIKELY(!result)) - return false; - - return is_reparse_point_tag_a_symlink(buf->rdb.ReparseTag); -} - -namespace { - -inline bool is_reparse_point_a_symlink(path const& p) -{ - handle_wrapper h(create_file_handle( - p, - FILE_READ_ATTRIBUTES, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - NULL, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT)); - if (BOOST_UNLIKELY(h.handle == INVALID_HANDLE_VALUE)) - return false; - - GetFileInformationByHandleEx_t* get_file_information_by_handle_ex = filesystem::detail::atomic_load_relaxed(get_file_information_by_handle_ex_api); - if (BOOST_LIKELY(get_file_information_by_handle_ex != NULL)) - { - file_attribute_tag_info info; - BOOL result = get_file_information_by_handle_ex(h.handle, file_attribute_tag_info_class, &info, sizeof(info)); - if (BOOST_UNLIKELY(!result)) - return false; - - if ((info.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) == 0u) - return false; - - return is_reparse_point_tag_a_symlink(info.ReparseTag); - } - - return is_reparse_point_a_symlink_ioctl(h.handle); -} - -inline std::size_t get_full_path_name(path const& src, std::size_t len, wchar_t* buf, wchar_t** p) -{ - return static_cast< std::size_t >(::GetFullPathNameW(src.c_str(), static_cast< DWORD >(len), buf, p)); -} - -inline fs::file_status process_status_failure(DWORD errval, path const& p, error_code* ec) -{ - if (ec) // always report errval, even though some - ec->assign(errval, system_category()); // errval values are not status_errors - - if (not_found_error(errval)) - { - return fs::file_status(fs::file_not_found, fs::no_perms); - } - else if (errval == ERROR_SHARING_VIOLATION) - { - return fs::file_status(fs::type_unknown); - } - - if (!ec) - BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::status", p, error_code(errval, system_category()))); - - return fs::file_status(fs::status_error); -} - -inline fs::file_status process_status_failure(path const& p, error_code* ec) -{ - return process_status_failure(::GetLastError(), p, ec); -} - -//! (symlink_)status() by handle implementation -fs::file_status status_by_handle(HANDLE h, path const& p, error_code* ec) -{ - fs::file_type ftype; - DWORD attrs; - GetFileInformationByHandleEx_t* get_file_information_by_handle_ex = filesystem::detail::atomic_load_relaxed(get_file_information_by_handle_ex_api); - if (BOOST_LIKELY(get_file_information_by_handle_ex != NULL)) - { - file_attribute_tag_info info; - BOOL res = get_file_information_by_handle_ex(h, file_attribute_tag_info_class, &info, sizeof(info)); - if (BOOST_UNLIKELY(!res)) - { - // On FAT/exFAT filesystems requesting FILE_ATTRIBUTE_TAG_INFO returns ERROR_INVALID_PARAMETER. - // Presumably, this is because these filesystems don't support reparse points, so ReparseTag - // cannot be returned. Also check ERROR_NOT_SUPPORTED for good measure. Fall back to the legacy - // code path in this case. - DWORD err = ::GetLastError(); - if (err == ERROR_INVALID_PARAMETER || err == ERROR_NOT_SUPPORTED) - goto use_get_file_information_by_handle; - - return process_status_failure(err, p, ec); - } - - attrs = info.FileAttributes; - - if (attrs & FILE_ATTRIBUTE_REPARSE_POINT) - { - ftype = is_reparse_point_tag_a_symlink(info.ReparseTag) ? fs::symlink_file : fs::reparse_file; - goto done; - } - } - else - { - use_get_file_information_by_handle: - BY_HANDLE_FILE_INFORMATION info; - BOOL res = ::GetFileInformationByHandle(h, &info); - if (BOOST_UNLIKELY(!res)) - return process_status_failure(p, ec); - - attrs = info.dwFileAttributes; - - if (attrs & FILE_ATTRIBUTE_REPARSE_POINT) - { - ftype = is_reparse_point_a_symlink_ioctl(h) ? fs::symlink_file : fs::reparse_file; - goto done; - } - } - - ftype = (attrs & FILE_ATTRIBUTE_DIRECTORY) ? fs::directory_file : fs::regular_file; - -done: - return fs::file_status(ftype, make_permissions(p, attrs)); -} - -//! symlink_status() implementation -fs::file_status symlink_status_impl(path const& p, error_code* ec) -{ - handle_wrapper h(create_file_handle( - p.c_str(), - FILE_READ_ATTRIBUTES, // dwDesiredAccess; attributes only - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - NULL, // lpSecurityAttributes - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT)); - - if (h.handle == INVALID_HANDLE_VALUE) - { - // For some system files and folders like "System Volume Information" CreateFileW fails - // with ERROR_ACCESS_DENIED. GetFileAttributesW succeeds for such files, so try that. - // Though this will only help if the file is not a reparse point (symlink or not). - DWORD err = ::GetLastError(); - if (err == ERROR_ACCESS_DENIED) - { - DWORD attrs = ::GetFileAttributesW(p.c_str()); - if (attrs != INVALID_FILE_ATTRIBUTES) - { - if ((attrs & FILE_ATTRIBUTE_REPARSE_POINT) == 0u) - return fs::file_status((attrs & FILE_ATTRIBUTE_DIRECTORY) ? fs::directory_file : fs::regular_file, make_permissions(p, attrs)); - } - else - { - err = ::GetLastError(); - } - } - - return process_status_failure(err, p, ec); - } - - return detail::status_by_handle(h.handle, p, ec); -} - -//! status() implementation -fs::file_status status_impl(path const& p, error_code* ec) -{ - // We should first test if the file is a symlink or a reparse point. Resolving some reparse - // points by opening the file may fail, and status() should return file_status(reparse_file) in this case. - // Which is what symlink_status() returns. - fs::file_status st(detail::symlink_status_impl(p, ec)); - if (st.type() == symlink_file) - { - // Resolve the symlink - handle_wrapper h(create_file_handle( - p.c_str(), - FILE_READ_ATTRIBUTES, // dwDesiredAccess; attributes only - FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, // lpSecurityAttributes - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS)); - - if (h.handle == INVALID_HANDLE_VALUE) - return process_status_failure(p, ec); - - st = detail::status_by_handle(h.handle, p, ec); - } - - return st; -} - -//! remove() implementation for Windows XP and older -bool remove_nt5_impl(path const& p, DWORD attrs, error_code* ec) -{ - const bool is_directory = (attrs & FILE_ATTRIBUTE_DIRECTORY) != 0; - const bool is_read_only = (attrs & FILE_ATTRIBUTE_READONLY) != 0; - if (is_read_only) - { - // RemoveDirectoryW and DeleteFileW do not allow to remove a read-only file, so we have to drop the attribute - DWORD new_attrs = attrs & ~FILE_ATTRIBUTE_READONLY; - BOOL res = ::SetFileAttributesW(p.c_str(), new_attrs); - if (BOOST_UNLIKELY(!res)) - { - DWORD err = ::GetLastError(); - if (!not_found_error(err)) - emit_error(err, p, ec, "boost::filesystem::remove"); - - return false; - } - } - - BOOL res; - if (!is_directory) - { - // DeleteFileW works for file symlinks by removing the symlink, not the target. - res = ::DeleteFileW(p.c_str()); - } - else - { - // RemoveDirectoryW works for symlinks and junctions by removing the symlink, not the target, - // even if the target directory is not empty. - // Note that unlike opening the directory with FILE_FLAG_DELETE_ON_CLOSE flag, RemoveDirectoryW - // will fail if the directory is not empty. - res = ::RemoveDirectoryW(p.c_str()); - } - - if (BOOST_UNLIKELY(!res)) - { - DWORD err = ::GetLastError(); - if (!not_found_error(err)) - { - if (is_read_only) - { - // Try to restore the read-only attribute - ::SetFileAttributesW(p.c_str(), attrs); - } - - emit_error(err, p, ec, "boost::filesystem::remove"); - } - - return false; - } - - return true; -} - -//! remove() by handle implementation for Windows Vista and newer -DWORD remove_nt6_by_handle(HANDLE handle, remove_impl_type impl) -{ - GetFileInformationByHandleEx_t* get_file_information_by_handle_ex = filesystem::detail::atomic_load_relaxed(get_file_information_by_handle_ex_api); - SetFileInformationByHandle_t* set_file_information_by_handle = filesystem::detail::atomic_load_relaxed(set_file_information_by_handle_api); - DWORD err = 0u; - switch (impl) - { - case remove_disp_ex_flag_ignore_readonly: - { - file_disposition_info_ex info; - info.Flags = FILE_DISPOSITION_FLAG_DELETE | FILE_DISPOSITION_FLAG_POSIX_SEMANTICS | FILE_DISPOSITION_FLAG_IGNORE_READONLY_ATTRIBUTE; - BOOL res = set_file_information_by_handle(handle, file_disposition_info_ex_class, &info, sizeof(info)); - if (BOOST_LIKELY(!!res)) - break; - - err = ::GetLastError(); - if (BOOST_UNLIKELY(err == ERROR_INVALID_PARAMETER || err == ERROR_INVALID_FUNCTION || err == ERROR_NOT_SUPPORTED)) - { - // Downgrade to the older implementation - impl = remove_disp_ex_flag_posix_semantics; - filesystem::detail::atomic_store_relaxed(g_remove_impl_type, impl); - } - else - { - break; - } - } - BOOST_FALLTHROUGH; - - case remove_disp_ex_flag_posix_semantics: - { - file_disposition_info_ex info; - info.Flags = FILE_DISPOSITION_FLAG_DELETE | FILE_DISPOSITION_FLAG_POSIX_SEMANTICS; - BOOL res = set_file_information_by_handle(handle, file_disposition_info_ex_class, &info, sizeof(info)); - if (BOOST_LIKELY(!!res)) - { - err = 0u; - break; - } - - err = ::GetLastError(); - if (err == ERROR_ACCESS_DENIED) - { - // Check if the file is read-only and reset the attribute - file_basic_info basic_info; - res = get_file_information_by_handle_ex(handle, file_basic_info_class, &basic_info, sizeof(basic_info)); - if (BOOST_UNLIKELY(!res || (basic_info.FileAttributes & FILE_ATTRIBUTE_READONLY) == 0)) - break; // return ERROR_ACCESS_DENIED - - basic_info.FileAttributes &= ~FILE_ATTRIBUTE_READONLY; - - res = set_file_information_by_handle(handle, file_basic_info_class, &basic_info, sizeof(basic_info)); - if (BOOST_UNLIKELY(!res)) - { - err = ::GetLastError(); - break; - } - - // Try to set the flag again - res = set_file_information_by_handle(handle, file_disposition_info_ex_class, &info, sizeof(info)); - if (BOOST_LIKELY(!!res)) - { - err = 0u; - break; - } - - err = ::GetLastError(); - - // Try to restore the read-only flag - basic_info.FileAttributes |= FILE_ATTRIBUTE_READONLY; - set_file_information_by_handle(handle, file_basic_info_class, &basic_info, sizeof(basic_info)); - - break; - } - else if (BOOST_UNLIKELY(err == ERROR_INVALID_PARAMETER || err == ERROR_INVALID_FUNCTION || err == ERROR_NOT_SUPPORTED)) - { - // Downgrade to the older implementation - impl = remove_disp; - filesystem::detail::atomic_store_relaxed(g_remove_impl_type, impl); - } - else - { - break; - } - } - BOOST_FALLTHROUGH; - - default: - { - file_disposition_info info; - info.DeleteFile = true; - BOOL res = set_file_information_by_handle(handle, file_disposition_info_class, &info, sizeof(info)); - if (BOOST_LIKELY(!!res)) - { - err = 0u; - break; - } - - err = ::GetLastError(); - if (err == ERROR_ACCESS_DENIED) - { - // Check if the file is read-only and reset the attribute - file_basic_info basic_info; - res = get_file_information_by_handle_ex(handle, file_basic_info_class, &basic_info, sizeof(basic_info)); - if (BOOST_UNLIKELY(!res || (basic_info.FileAttributes & FILE_ATTRIBUTE_READONLY) == 0)) - break; // return ERROR_ACCESS_DENIED - - basic_info.FileAttributes &= ~FILE_ATTRIBUTE_READONLY; - - res = set_file_information_by_handle(handle, file_basic_info_class, &basic_info, sizeof(basic_info)); - if (BOOST_UNLIKELY(!res)) - { - err = ::GetLastError(); - break; - } - - // Try to set the flag again - res = set_file_information_by_handle(handle, file_disposition_info_class, &info, sizeof(info)); - if (BOOST_LIKELY(!!res)) - { - err = 0u; - break; - } - - err = ::GetLastError(); - - // Try to restore the read-only flag - basic_info.FileAttributes |= FILE_ATTRIBUTE_READONLY; - set_file_information_by_handle(handle, file_basic_info_class, &basic_info, sizeof(basic_info)); - } - - break; - } - } - - return err; -} - -//! remove() implementation for Windows Vista and newer -inline bool remove_nt6_impl(path const& p, remove_impl_type impl, error_code* ec) -{ - handle_wrapper h(create_file_handle( - p, - DELETE | FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - NULL, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT)); - DWORD err = 0u; - if (BOOST_UNLIKELY(h.handle == INVALID_HANDLE_VALUE)) - { - err = ::GetLastError(); - - return_error: - if (!not_found_error(err)) - emit_error(err, p, ec, "boost::filesystem::remove"); - - return false; - } - - err = fs::detail::remove_nt6_by_handle(h.handle, impl); - if (BOOST_UNLIKELY(err != 0u)) - goto return_error; - - return true; -} - -//! remove() implementation -inline bool remove_impl(path const& p, error_code* ec) -{ - remove_impl_type impl = fs::detail::atomic_load_relaxed(g_remove_impl_type); - if (BOOST_LIKELY(impl != remove_nt5)) - { - return fs::detail::remove_nt6_impl(p, impl, ec); - } - else - { - const DWORD attrs = ::GetFileAttributesW(p.c_str()); - if (BOOST_UNLIKELY(attrs == INVALID_FILE_ATTRIBUTES)) - { - DWORD err = ::GetLastError(); - if (!not_found_error(err)) - emit_error(err, p, ec, "boost::filesystem::remove"); - - return false; - } - - return fs::detail::remove_nt5_impl(p, attrs, ec); - } -} - -#if !defined(UNDER_CE) - -//! remove_all() by handle implementation for Windows Vista and newer -uintmax_t remove_all_nt6_by_handle(HANDLE h, path const& p, error_code* ec) -{ - error_code local_ec; - fs::file_status st(fs::detail::status_by_handle(h, p, &local_ec)); - if (BOOST_UNLIKELY(st.type() == fs::status_error)) - { - if (!ec) - BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::remove_all", p, local_ec)); - - *ec = local_ec; - return static_cast< uintmax_t >(-1); - } - - uintmax_t count = 0u; - if (st.type() == fs::directory_file) - { - local_ec.clear(); - - fs::directory_iterator itr; - directory_iterator_params params; - params.use_handle = h; - params.close_handle = false; // the caller will close the handle - fs::detail::directory_iterator_construct(itr, p, static_cast< unsigned int >(directory_options::_detail_no_follow), ¶ms, &local_ec); - if (BOOST_UNLIKELY(!!local_ec)) - { - if (!ec) - BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::remove_all", p, local_ec)); - - *ec = local_ec; - return static_cast< uintmax_t >(-1); - } - - NtCreateFile_t* nt_create_file = filesystem::detail::atomic_load_relaxed(nt_create_file_api); - const fs::directory_iterator end_dit; - while (itr != end_dit) - { - fs::path nested_path(itr->path()); - handle_wrapper hh; - if (BOOST_LIKELY(nt_create_file != NULL)) - { - // Note: WinAPI methods like CreateFileW implicitly request SYNCHRONIZE access but NtCreateFile doesn't. - // Without SYNCHRONIZE access querying file attributes via GetFileInformationByHandleEx fails with ERROR_ACCESS_DENIED. - boost::winapi::NTSTATUS_ status = nt_create_file_handle_at - ( - hh.handle, - h, - nested_path.filename(), - 0u, // FileAttributes - FILE_LIST_DIRECTORY | DELETE | FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES | SYNCHRONIZE, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - FILE_OPEN, - FILE_OPEN_FOR_BACKUP_INTENT | FILE_OPEN_REPARSE_POINT - ); - - if (!NT_SUCCESS(status)) - { - if (status == STATUS_NO_SUCH_FILE || - status == STATUS_OBJECT_NAME_NOT_FOUND || - status == STATUS_OBJECT_PATH_NOT_FOUND || - status == STATUS_BAD_NETWORK_PATH || - status == STATUS_BAD_NETWORK_NAME) - { - goto next_entry; - } - - DWORD err = translate_ntstatus(status); - emit_error(err, nested_path, ec, "boost::filesystem::remove_all"); - return static_cast< uintmax_t >(-1); - } - } - else - { - hh.handle = create_file_handle( - nested_path, - FILE_LIST_DIRECTORY | DELETE | FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES | SYNCHRONIZE, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - NULL, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT); - - if (BOOST_UNLIKELY(hh.handle == INVALID_HANDLE_VALUE)) - { - DWORD err = ::GetLastError(); - if (not_found_error(err)) - goto next_entry; - - emit_error(err, nested_path, ec, "boost::filesystem::remove_all"); - return static_cast< uintmax_t >(-1); - } - } - - count += fs::detail::remove_all_nt6_by_handle(hh.handle, nested_path, ec); - if (ec && *ec) - return static_cast< uintmax_t >(-1); - - next_entry: - fs::detail::directory_iterator_increment(itr, ec); - if (ec && *ec) - return static_cast< uintmax_t >(-1); - } - } - - DWORD err = fs::detail::remove_nt6_by_handle(h, fs::detail::atomic_load_relaxed(g_remove_impl_type)); - if (BOOST_UNLIKELY(err != 0u)) - { - emit_error(err, p, ec, "boost::filesystem::remove_all"); - return static_cast< uintmax_t >(-1); - } - - ++count; - return count; -} - -#endif // !defined(UNDER_CE) - -//! remove_all() implementation for Windows XP and older -uintmax_t remove_all_nt5_impl(path const& p, error_code* ec) -{ - error_code dit_create_ec; - for (unsigned int attempt = 0u; attempt < remove_all_directory_replaced_retry_count; ++attempt) - { - const DWORD attrs = ::GetFileAttributesW(p.c_str()); - if (BOOST_UNLIKELY(attrs == INVALID_FILE_ATTRIBUTES)) - { - DWORD err = ::GetLastError(); - if (not_found_error(err)) - return 0u; - - emit_error(err, p, ec, "boost::filesystem::remove_all"); - return static_cast< uintmax_t >(-1); - } - - // Recurse into directories, but not into junctions or directory symlinks - const bool recurse = (attrs & FILE_ATTRIBUTE_DIRECTORY) != 0 && (attrs & FILE_ATTRIBUTE_REPARSE_POINT) == 0; - uintmax_t count = 0u; - if (recurse) - { - fs::directory_iterator itr; - fs::detail::directory_iterator_construct(itr, p, static_cast< unsigned int >(directory_options::_detail_no_follow), NULL, &dit_create_ec); - if (BOOST_UNLIKELY(!!dit_create_ec)) - { - if (dit_create_ec == make_error_condition(system::errc::not_a_directory) || - dit_create_ec == make_error_condition(system::errc::too_many_symbolic_link_levels)) - { - continue; - } - - if (!ec) - BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::remove_all", p, dit_create_ec)); - - *ec = dit_create_ec; - return static_cast< uintmax_t >(-1); - } - - const fs::directory_iterator end_dit; - while (itr != end_dit) - { - count += fs::detail::remove_all_nt5_impl(itr->path(), ec); - if (ec && *ec) - return static_cast< uintmax_t >(-1); - - fs::detail::directory_iterator_increment(itr, ec); - if (ec && *ec) - return static_cast< uintmax_t >(-1); - } - } - - bool removed = fs::detail::remove_nt5_impl(p, attrs, ec); - if (ec && *ec) - return static_cast< uintmax_t >(-1); - - count += removed; - return count; - } - - if (!ec) - BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::remove_all: path cannot be opened as a directory", p, dit_create_ec)); - - *ec = dit_create_ec; - return static_cast< uintmax_t >(-1); -} - -//! remove_all() implementation -inline uintmax_t remove_all_impl(path const& p, error_code* ec) -{ -#if !defined(UNDER_CE) - remove_impl_type impl = fs::detail::atomic_load_relaxed(g_remove_impl_type); - if (BOOST_LIKELY(impl != remove_nt5)) - { - handle_wrapper h(create_file_handle( - p, - FILE_LIST_DIRECTORY | DELETE | FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES | SYNCHRONIZE, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - NULL, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT)); - - if (BOOST_UNLIKELY(h.handle == INVALID_HANDLE_VALUE)) - { - DWORD err = ::GetLastError(); - if (not_found_error(err)) - return 0u; - - emit_error(err, p, ec, "boost::filesystem::remove_all"); - return static_cast< uintmax_t >(-1); - } - - return fs::detail::remove_all_nt6_by_handle(h.handle, p, ec); - } -#endif // !defined(UNDER_CE) - - return fs::detail::remove_all_nt5_impl(p, ec); -} - -inline BOOL resize_file_impl(const wchar_t* p, uintmax_t size) -{ - handle_wrapper h(CreateFileW(p, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)); - LARGE_INTEGER sz; - sz.QuadPart = size; - return h.handle != INVALID_HANDLE_VALUE && ::SetFilePointerEx(h.handle, sz, 0, FILE_BEGIN) && ::SetEndOfFile(h.handle); -} - -//! Converts NT path to a Win32 path -inline path convert_nt_path_to_win32_path(const wchar_t* nt_path, std::size_t size) -{ - // https://googleprojectzero.blogspot.com/2016/02/the-definitive-guide-on-win32-to-nt.html - // https://stackoverflow.com/questions/23041983/path-prefixes-and - // - // NT paths can be used to identify practically any named objects, devices, files, local and remote shares, etc. - // The path starts with a leading backslash and consists of one or more path elements separated with backslashes. - // The set of characters allowed in NT path elements is significantly larger than that of Win32 paths - basically, - // any character except the backslash is allowed. Path elements are case-insensitive. - // - // NT paths that start with the "\??\" prefix are used to indicate the current user's session namespace. The prefix - // indicates to the NT object manager to lookup the object relative to "\Sessions\0\DosDevices\[Logon Authentication ID]". - // - // There is also a special "\Global??\" prefix that refers to the system logon. User's session directory shadows - // the system logon directory, so that when the referenced object is not found in the user's namespace, - // system logon is looked up instead. - // - // There is a symlink "Global" in the user's session namespace that refers to the global namespace, so "\??\Global" - // effectively resolves to "\Global??". This allows Win32 applications to directly refer to the system objects, - // even if shadowed by the current user's logon object. - // - // NT paths can be used to reference not only local filesystems, but also devices and remote shares identifiable via - // UNC paths. For this, there is a special "UNC" device (which is a symlink to "\Device\Mup") in the system logon - // namespace, so "\??\UNC\host\share" (or "\??\Global\UNC\host\share", or "\Global??\UNC\host\share") is equivalent - // to "\\host\share". - // - // NT paths are not universally accepted by Win32 applications and APIs. For example, Far supports paths starting - // with "\??\" and "\??\Global\" but not with "\Global??\". As of Win10 21H1, File Explorer, cmd.exe and PowerShell - // don't support any of these. Given this, and that NT paths have a different set of allowed characters from Win32 paths, - // we should normally avoid exposing NT paths to users that expect Win32 paths. - // - // In Boost.Filesystem we only deal with NT paths that come from reparse points, such as symlinks and mount points, - // including directory junctions. It was observed that reparse points created by junction.exe and mklink use the "\??\" - // prefix for directory junctions and absolute symlink and unqualified relative path for relative symlinks. - // Absolute paths are using drive letters for mounted drives (e.g. "\??\C:\directory"), although it is possible - // to create a junction to an directory using a different way of identifying the filesystem (e.g. - // "\??\Volume{00000000-0000-0000-0000-000000000000}\directory"). - // mklink does not support creating junctions pointing to a UNC path. junction.exe does create a junction that - // uses a seemingly invalid syntax like "\??\\\host\share", i.e. it basically does not expect an UNC path. It is not known - // if reparse points that refer to a UNC path are considered valid. - // There are reparse points created as mount points for local and remote filsystems (for example, a cloud storage mounted - // in the local filesystem). Such mount points have the form of "\??\Volume{00000000-0000-0000-0000-000000000000}\", - // "\??\Harddisk0Partition1\" or "\??\HarddiskVolume1\". - // Reparse points that refer directly to a global namespace (through "\??\Global\" or "\Global??\" prefixes) or - // devices (e.g. "\Device\HarddiskVolume1") have not been observed so far. - - path win32_path; - std::size_t pos = 0u; - bool global_namespace = false; - - // Check for the "\??\" prefix - if (size >= 4u && - nt_path[0] == path::preferred_separator && - nt_path[1] == questionmark && - nt_path[2] == questionmark && - nt_path[3] == path::preferred_separator) - { - pos = 4u; - - // Check "Global" - if ((size - pos) >= 6u && - (nt_path[pos] == L'G' || nt_path[pos] == L'g') && - (nt_path[pos + 1] == L'l' || nt_path[pos + 1] == L'L') && - (nt_path[pos + 2] == L'o' || nt_path[pos + 2] == L'O') && - (nt_path[pos + 3] == L'b' || nt_path[pos + 3] == L'B') && - (nt_path[pos + 4] == L'a' || nt_path[pos + 4] == L'A') && - (nt_path[pos + 5] == L'l' || nt_path[pos + 5] == L'L')) - { - if ((size - pos) == 6u) - { - pos += 6u; - global_namespace = true; - } - else if (detail::is_directory_separator(nt_path[pos + 6u])) - { - pos += 7u; - global_namespace = true; - } - } - } - // Check for the "\Global??\" prefix - else if (size >= 10u && - nt_path[0] == path::preferred_separator && - (nt_path[1] == L'G' || nt_path[1] == L'g') && - (nt_path[2] == L'l' || nt_path[2] == L'L') && - (nt_path[3] == L'o' || nt_path[3] == L'O') && - (nt_path[4] == L'b' || nt_path[4] == L'B') && - (nt_path[5] == L'a' || nt_path[5] == L'A') && - (nt_path[6] == L'l' || nt_path[6] == L'L') && - nt_path[7] == questionmark && - nt_path[8] == questionmark && - nt_path[9] == path::preferred_separator) - { - pos = 10u; - global_namespace = true; - } - - if (pos > 0u) - { - if ((size - pos) >= 2u && - ( - // Check if the following is a drive letter - ( - detail::is_letter(nt_path[pos]) && nt_path[pos + 1u] == colon && - ((size - pos) == 2u || detail::is_directory_separator(nt_path[pos + 2u])) - ) || - // Check for an "incorrect" syntax for UNC path junction points - ( - detail::is_directory_separator(nt_path[pos]) && detail::is_directory_separator(nt_path[pos + 1u]) && - ((size - pos) == 2u || !detail::is_directory_separator(nt_path[pos + 2u])) - ) - )) - { - // Strip the NT path prefix - goto done; - } - - static const wchar_t win32_path_prefix[4u] = { path::preferred_separator, path::preferred_separator, questionmark, path::preferred_separator }; - - // Check for a UNC path - if ((size - pos) >= 4u && - (nt_path[pos] == L'U' || nt_path[pos] == L'u') && - (nt_path[pos + 1] == L'N' || nt_path[pos + 1] == L'n') && - (nt_path[pos + 2] == L'C' || nt_path[pos + 2] == L'c') && - nt_path[pos + 3] == path::preferred_separator) - { - win32_path.assign(win32_path_prefix, win32_path_prefix + 2); - pos += 4u; - goto done; - } - - // This is some other NT path, possibly a volume mount point. Replace the NT prefix with a Win32 filesystem prefix "\\?\". - win32_path.assign(win32_path_prefix, win32_path_prefix + 4); - if (global_namespace) - { - static const wchar_t win32_path_global_prefix[7u] = { L'G', L'l', L'o', L'b', L'a', L'l', path::preferred_separator }; - win32_path.concat(win32_path_global_prefix, win32_path_global_prefix + 7); - } - } - -done: - win32_path.concat(nt_path + pos, nt_path + size); - return win32_path; -} - -#endif // defined(BOOST_POSIX_API) - -} // unnamed namespace -} // namespace detail - -//--------------------------------------------------------------------------------------// -// // -// operations functions declared in operations.hpp // -// // -//--------------------------------------------------------------------------------------// - -namespace detail { - -BOOST_FILESYSTEM_DECL bool possible_large_file_size_support() -{ -#ifdef BOOST_POSIX_API - typedef struct stat struct_stat; - return sizeof(struct_stat().st_size) > 4; -#else - return true; -#endif -} - -BOOST_FILESYSTEM_DECL -path absolute(path const& p, path const& base, system::error_code* ec) -{ - if (ec) - ec->clear(); - - if (p.is_absolute()) - return p; - - // recursively calling absolute is sub-optimal, but is sure and simple - path abs_base = base; - if (!base.is_absolute()) - { - if (ec) - { - abs_base = absolute(base, *ec); - if (*ec) - return path(); - } - else - { - abs_base = absolute(base); - } - } - - if (p.empty()) - return abs_base; - - path res; - if (p.has_root_name()) - res = p.root_name(); - else - res = abs_base.root_name(); - - if (p.has_root_directory()) - { - res.concat(p.root_directory()); - } - else - { - res.concat(abs_base.root_directory()); - res /= abs_base.relative_path(); - } - - path p_relative_path(p.relative_path()); - if (!p_relative_path.empty()) - res /= p_relative_path; - - return res; -} - -BOOST_FILESYSTEM_DECL -path canonical(path const& p, path const& base, system::error_code* ec) -{ - if (ec) - ec->clear(); - - path source(p); - if (!p.is_absolute()) - { - source = detail::absolute(p, base, ec); - if (ec && *ec) - { - return_empty_path: - return path(); - } - } - - system::error_code local_ec; - file_status st(detail::status_impl(source, &local_ec)); - - if (st.type() == fs::file_not_found) - { - local_ec = system::errc::make_error_code(system::errc::no_such_file_or_directory); - goto fail_local_ec; - } - else if (local_ec) - { - fail_local_ec: - if (!ec) - BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::canonical", source, local_ec)); - - *ec = local_ec; - goto return_empty_path; - } - - path root(source.root_path()); - path const& dot_p = dot_path(); - path const& dot_dot_p = dot_dot_path(); - unsigned int symlinks_allowed = symloop_max; - path result; - while (true) - { - for (path::iterator itr(source.begin()), end(source.end()); itr != end; ++itr) - { - if (*itr == dot_p) - continue; - if (*itr == dot_dot_p) - { - if (result != root) - result.remove_filename(); - continue; - } - - if (itr->size() == 1u && detail::is_directory_separator(itr->native()[0])) - { - // Convert generic separator returned by the iterator for the root directory to - // the preferred separator. This is important on Windows, as in some cases, - // like paths for network shares and cloud storage mount points GetFileAttributesW - // will return "file not found" if the path contains forward slashes. - result += path::preferred_separator; - // We don't need to check for a symlink after adding a separator. - continue; - } - - result /= *itr; - - // If we don't have an absolute path yet then don't check symlink status. - // This avoids checking "C:" which is "the current directory on drive C" - // and hence not what we want to check/resolve here. - if (!result.is_absolute()) - continue; - - st = detail::symlink_status_impl(result, ec); - if (ec && *ec) - goto return_empty_path; - - if (is_symlink(st)) - { - if (symlinks_allowed == 0) - { - local_ec = system::errc::make_error_code(system::errc::too_many_symbolic_link_levels); - goto fail_local_ec; - } - - --symlinks_allowed; - - path link(detail::read_symlink(result, ec)); - if (ec && *ec) - goto return_empty_path; - result.remove_filename(); - - if (link.is_absolute()) - { - for (++itr; itr != end; ++itr) - { - if (*itr != dot_p) - link /= *itr; - } - source = link; - root = source.root_path(); - } - else // link is relative - { - link.remove_trailing_separator(); - if (link == dot_p) - continue; - - path new_source(result); - new_source /= link; - for (++itr; itr != end; ++itr) - { - if (*itr != dot_p) - new_source /= *itr; - } - source = new_source; - } - - // symlink causes scan to be restarted - goto restart_scan; - } - } - - break; - - restart_scan: - result.clear(); - } - - BOOST_ASSERT_MSG(result.is_absolute(), "canonical() implementation error; please report"); - return result; -} - -BOOST_FILESYSTEM_DECL -void copy(path const& from, path const& to, unsigned int options, system::error_code* ec) -{ - BOOST_ASSERT((((options & static_cast< unsigned int >(copy_options::overwrite_existing)) != 0u) + - ((options & static_cast< unsigned int >(copy_options::skip_existing)) != 0u) + - ((options & static_cast< unsigned int >(copy_options::update_existing)) != 0u)) <= 1); - - BOOST_ASSERT((((options & static_cast< unsigned int >(copy_options::copy_symlinks)) != 0u) + - ((options & static_cast< unsigned int >(copy_options::skip_symlinks)) != 0u)) <= 1); - - BOOST_ASSERT((((options & static_cast< unsigned int >(copy_options::directories_only)) != 0u) + - ((options & static_cast< unsigned int >(copy_options::create_symlinks)) != 0u) + - ((options & static_cast< unsigned int >(copy_options::create_hard_links)) != 0u)) <= 1); - - if (ec) - ec->clear(); - - file_status from_stat; - if ((options & (static_cast< unsigned int >(copy_options::copy_symlinks) | - static_cast< unsigned int >(copy_options::skip_symlinks) | - static_cast< unsigned int >(copy_options::create_symlinks))) != 0u) - { - from_stat = detail::symlink_status_impl(from, ec); - } - else - { - from_stat = detail::status_impl(from, ec); - } - - if (ec && *ec) - return; - - if (!exists(from_stat)) - { - emit_error(BOOST_ERROR_FILE_NOT_FOUND, from, to, ec, "boost::filesystem::copy"); - return; - } - - if (is_symlink(from_stat)) - { - if ((options & static_cast< unsigned int >(copy_options::skip_symlinks)) != 0u) - return; - - if ((options & static_cast< unsigned int >(copy_options::copy_symlinks)) == 0u) - goto fail; - - detail::copy_symlink(from, to, ec); - } - else if (is_regular_file(from_stat)) - { - if ((options & static_cast< unsigned int >(copy_options::directories_only)) != 0u) - return; - - if ((options & static_cast< unsigned int >(copy_options::create_symlinks)) != 0u) - { - const path* pfrom = &from; - path relative_from; - if (!from.is_absolute()) - { - // Try to generate a relative path from the target location to the original file - path cur_dir = detail::current_path(ec); - if (ec && *ec) - return; - path abs_from = detail::absolute(from.parent_path(), cur_dir, ec); - if (ec && *ec) - return; - path abs_to = to.parent_path(); - if (!abs_to.is_absolute()) - { - abs_to = detail::absolute(abs_to, cur_dir, ec); - if (ec && *ec) - return; - } - relative_from = detail::relative(abs_from, abs_to, ec); - if (ec && *ec) - return; - if (relative_from != dot_path()) - relative_from /= from.filename(); - else - relative_from = from.filename(); - pfrom = &relative_from; - } - detail::create_symlink(*pfrom, to, ec); - return; - } - - if ((options & static_cast< unsigned int >(copy_options::create_hard_links)) != 0u) - { - detail::create_hard_link(from, to, ec); - return; - } - - error_code local_ec; - file_status to_stat; - if ((options & (static_cast< unsigned int >(copy_options::skip_symlinks) | - static_cast< unsigned int >(copy_options::create_symlinks))) != 0u) - { - to_stat = detail::symlink_status_impl(to, &local_ec); - } - else - { - to_stat = detail::status_impl(to, &local_ec); - } - - // Note: local_ec may be set by (symlink_)status() even in some non-fatal situations, e.g. when the file does not exist. - // OTOH, when it returns status_error, then a real error have happened and it must have set local_ec. - if (to_stat.type() == fs::status_error) - { - if (!ec) - BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::copy", from, to, local_ec)); - *ec = local_ec; - return; - } - - if (is_directory(to_stat)) - detail::copy_file(from, to / from.filename(), options, ec); - else - detail::copy_file(from, to, options, ec); - } - else if (is_directory(from_stat)) - { - error_code local_ec; - if ((options & static_cast< unsigned int >(copy_options::create_symlinks)) != 0u) - { - local_ec = make_error_code(system::errc::is_a_directory); - if (!ec) - BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::copy", from, to, local_ec)); - *ec = local_ec; - return; - } - - file_status to_stat; - if ((options & (static_cast< unsigned int >(copy_options::skip_symlinks) | - static_cast< unsigned int >(copy_options::create_symlinks))) != 0u) - { - to_stat = detail::symlink_status_impl(to, &local_ec); - } - else - { - to_stat = detail::status_impl(to, &local_ec); - } - - // Note: ec may be set by (symlink_)status() even in some non-fatal situations, e.g. when the file does not exist. - // OTOH, when it returns status_error, then a real error have happened and it must have set local_ec. - if (to_stat.type() == fs::status_error) - { - if (!ec) - BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::copy", from, to, local_ec)); - *ec = local_ec; - return; - } - - if (!exists(to_stat)) - { - detail::create_directory(to, &from, ec); - if (ec && *ec) - return; - } - - if ((options & static_cast< unsigned int >(copy_options::recursive)) != 0u || options == 0u) - { - fs::directory_iterator itr; - detail::directory_iterator_construct(itr, from, static_cast< unsigned int >(directory_options::none), NULL, ec); - if (ec && *ec) - return; - - const fs::directory_iterator end_dit; - while (itr != end_dit) - { - path const& p = itr->path(); - // Set _detail_recursing flag so that we don't recurse more than for one level deeper into the directory if options are copy_options::none - detail::copy(p, to / p.filename(), options | static_cast< unsigned int >(copy_options::_detail_recursing), ec); - if (ec && *ec) - return; - - detail::directory_iterator_increment(itr, ec); - if (ec && *ec) - return; - } - } - } - else - { - fail: - emit_error(BOOST_ERROR_NOT_SUPPORTED, from, to, ec, "boost::filesystem::copy"); - } -} - -BOOST_FILESYSTEM_DECL -bool copy_file(path const& from, path const& to, unsigned int options, error_code* ec) -{ - BOOST_ASSERT((((options & static_cast< unsigned int >(copy_options::overwrite_existing)) != 0u) + - ((options & static_cast< unsigned int >(copy_options::skip_existing)) != 0u) + - ((options & static_cast< unsigned int >(copy_options::update_existing)) != 0u)) <= 1); - - if (ec) - ec->clear(); - -#if defined(BOOST_POSIX_API) - - int err = 0; - - // Note: Declare fd_wrappers here so that errno is not clobbered by close() that may be called in fd_wrapper destructors - fd_wrapper infile, outfile; - - while (true) - { - infile.fd = ::open(from.c_str(), O_RDONLY | O_CLOEXEC); - if (BOOST_UNLIKELY(infile.fd < 0)) - { - err = errno; - if (err == EINTR) - continue; - - fail: - emit_error(err, from, to, ec, "boost::filesystem::copy_file"); - return false; - } - - break; - } - -#if defined(BOOST_FILESYSTEM_USE_STATX) - unsigned int statx_data_mask = STATX_TYPE | STATX_MODE | STATX_INO | STATX_SIZE; - if ((options & static_cast< unsigned int >(copy_options::update_existing)) != 0u) - statx_data_mask |= STATX_MTIME; - - struct ::statx from_stat; - if (BOOST_UNLIKELY(invoke_statx(infile.fd, "", AT_EMPTY_PATH | AT_NO_AUTOMOUNT, statx_data_mask, &from_stat) < 0)) - { - fail_errno: - err = errno; - goto fail; - } - - if (BOOST_UNLIKELY((from_stat.stx_mask & statx_data_mask) != statx_data_mask)) - { - err = ENOSYS; - goto fail; - } -#else - struct ::stat from_stat; - if (BOOST_UNLIKELY(::fstat(infile.fd, &from_stat) != 0)) - { - fail_errno: - err = errno; - goto fail; - } -#endif - - const mode_t from_mode = get_mode(from_stat); - if (BOOST_UNLIKELY(!S_ISREG(from_mode))) - { - err = ENOSYS; - goto fail; - } - - mode_t to_mode = from_mode; -#if !defined(BOOST_FILESYSTEM_USE_WASI) - // Enable writing for the newly created files. Having write permission set is important e.g. for NFS, - // which checks the file permission on the server, even if the client's file descriptor supports writing. - to_mode |= S_IWUSR; -#endif - int oflag = O_WRONLY | O_CLOEXEC; - - if ((options & static_cast< unsigned int >(copy_options::update_existing)) != 0u) - { - // Try opening the existing file without truncation to test the modification time later - while (true) - { - outfile.fd = ::open(to.c_str(), oflag, to_mode); - if (outfile.fd < 0) - { - err = errno; - if (err == EINTR) - continue; - - if (err == ENOENT) - goto create_outfile; - - goto fail; - } - - break; - } - } - else - { - create_outfile: - oflag |= O_CREAT | O_TRUNC; - if (((options & static_cast< unsigned int >(copy_options::overwrite_existing)) == 0u || - (options & static_cast< unsigned int >(copy_options::skip_existing)) != 0u) && - (options & static_cast< unsigned int >(copy_options::update_existing)) == 0u) - { - oflag |= O_EXCL; - } - - while (true) - { - outfile.fd = ::open(to.c_str(), oflag, to_mode); - if (outfile.fd < 0) - { - err = errno; - if (err == EINTR) - continue; - - if (err == EEXIST && (options & static_cast< unsigned int >(copy_options::skip_existing)) != 0u) - return false; - - goto fail; - } - - break; - } - } - -#if defined(BOOST_FILESYSTEM_USE_STATX) - statx_data_mask = STATX_TYPE | STATX_MODE | STATX_INO; - if ((oflag & O_TRUNC) == 0) - { - // O_TRUNC is not set if copy_options::update_existing is set and an existing file was opened. - statx_data_mask |= STATX_MTIME; - } - - struct ::statx to_stat; - if (BOOST_UNLIKELY(invoke_statx(outfile.fd, "", AT_EMPTY_PATH | AT_NO_AUTOMOUNT, statx_data_mask, &to_stat) < 0)) - goto fail_errno; - - if (BOOST_UNLIKELY((to_stat.stx_mask & statx_data_mask) != statx_data_mask)) - { - err = ENOSYS; - goto fail; - } -#else - struct ::stat to_stat; - if (BOOST_UNLIKELY(::fstat(outfile.fd, &to_stat) != 0)) - goto fail_errno; -#endif - - to_mode = get_mode(to_stat); - if (BOOST_UNLIKELY(!S_ISREG(to_mode))) - { - err = ENOSYS; - goto fail; - } - - if (BOOST_UNLIKELY(detail::equivalent_stat(from_stat, to_stat))) - { - err = EEXIST; - goto fail; - } - - if ((oflag & O_TRUNC) == 0) - { - // O_TRUNC is not set if copy_options::update_existing is set and an existing file was opened. - // We need to check the last write times. -#if defined(BOOST_FILESYSTEM_USE_STATX) - if (from_stat.stx_mtime.tv_sec < to_stat.stx_mtime.tv_sec || (from_stat.stx_mtime.tv_sec == to_stat.stx_mtime.tv_sec && from_stat.stx_mtime.tv_nsec <= to_stat.stx_mtime.tv_nsec)) - return false; -#elif defined(BOOST_FILESYSTEM_STAT_ST_MTIMENSEC) - // Modify time is available with nanosecond precision. - if (from_stat.st_mtime < to_stat.st_mtime || (from_stat.st_mtime == to_stat.st_mtime && from_stat.BOOST_FILESYSTEM_STAT_ST_MTIMENSEC <= to_stat.BOOST_FILESYSTEM_STAT_ST_MTIMENSEC)) - return false; -#else - if (from_stat.st_mtime <= to_stat.st_mtime) - return false; -#endif - - if (BOOST_UNLIKELY(::ftruncate(outfile.fd, 0) != 0)) - goto fail_errno; - } - - // Note: Use block size of the target file since it is most important for writing performance. - err = filesystem::detail::atomic_load_relaxed(filesystem::detail::copy_file_data)(infile.fd, outfile.fd, get_size(from_stat), get_blksize(to_stat)); - if (BOOST_UNLIKELY(err != 0)) - goto fail; // err already contains the error code - -#if !defined(BOOST_FILESYSTEM_USE_WASI) - // If we created a new file with an explicitly added S_IWUSR permission, - // we may need to update its mode bits to match the source file. - if (to_mode != from_mode) - { - if (BOOST_UNLIKELY(::fchmod(outfile.fd, from_mode) != 0)) - goto fail_errno; - } -#endif - - if ((options & (static_cast< unsigned int >(copy_options::synchronize_data) | static_cast< unsigned int >(copy_options::synchronize))) != 0u) - { - if ((options & static_cast< unsigned int >(copy_options::synchronize)) != 0u) - err = full_sync(outfile.fd); - else - err = data_sync(outfile.fd); - - if (BOOST_UNLIKELY(err != 0)) - goto fail; - } - - // We have to explicitly close the output file descriptor in order to handle a possible error returned from it. The error may indicate - // a failure of a prior write operation. - err = close_fd(outfile.fd); - outfile.fd = -1; - if (BOOST_UNLIKELY(err < 0)) - { - err = errno; - // EINPROGRESS is an allowed error code in future POSIX revisions, according to https://www.austingroupbugs.net/view.php?id=529#c1200. - if (err != EINTR && err != EINPROGRESS) - goto fail; - } - - return true; - -#else // defined(BOOST_POSIX_API) - - DWORD copy_flags = 0u; - if ((options & static_cast< unsigned int >(copy_options::overwrite_existing)) == 0u || - (options & static_cast< unsigned int >(copy_options::skip_existing)) != 0u) - { - copy_flags |= COPY_FILE_FAIL_IF_EXISTS; - } - - if ((options & static_cast< unsigned int >(copy_options::update_existing)) != 0u) - { - // Create handle_wrappers here so that CloseHandle calls don't clobber error code returned by GetLastError - handle_wrapper hw_from, hw_to; - - hw_from.handle = create_file_handle(from.c_str(), FILE_READ_ATTRIBUTES, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS); - - FILETIME lwt_from; - if (hw_from.handle == INVALID_HANDLE_VALUE) - { - fail_last_error: - DWORD err = ::GetLastError(); - emit_error(err, from, to, ec, "boost::filesystem::copy_file"); - return false; - } - - if (!::GetFileTime(hw_from.handle, NULL, NULL, &lwt_from)) - goto fail_last_error; - - hw_to.handle = create_file_handle(to.c_str(), FILE_READ_ATTRIBUTES, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS); - - if (hw_to.handle != INVALID_HANDLE_VALUE) - { - FILETIME lwt_to; - if (!::GetFileTime(hw_to.handle, NULL, NULL, &lwt_to)) - goto fail_last_error; - - ULONGLONG tfrom = (static_cast< ULONGLONG >(lwt_from.dwHighDateTime) << 32) | static_cast< ULONGLONG >(lwt_from.dwLowDateTime); - ULONGLONG tto = (static_cast< ULONGLONG >(lwt_to.dwHighDateTime) << 32) | static_cast< ULONGLONG >(lwt_to.dwLowDateTime); - if (tfrom <= tto) - return false; - } - - copy_flags &= ~static_cast< DWORD >(COPY_FILE_FAIL_IF_EXISTS); - } - - struct callback_context - { - DWORD flush_error; - }; - - struct local - { - //! Callback that is called to report progress of \c CopyFileExW - static DWORD WINAPI on_copy_file_progress( - LARGE_INTEGER total_file_size, - LARGE_INTEGER total_bytes_transferred, - LARGE_INTEGER stream_size, - LARGE_INTEGER stream_bytes_transferred, - DWORD stream_number, - DWORD callback_reason, - HANDLE from_handle, - HANDLE to_handle, - LPVOID ctx) - { - // For each stream, CopyFileExW will open a separate pair of file handles, so we need to flush each stream separately. - if (stream_bytes_transferred.QuadPart == stream_size.QuadPart) - { - BOOL res = ::FlushFileBuffers(to_handle); - if (BOOST_UNLIKELY(!res)) - { - callback_context* context = static_cast< callback_context* >(ctx); - if (BOOST_LIKELY(context->flush_error == 0u)) - context->flush_error = ::GetLastError(); - } - } - - return PROGRESS_CONTINUE; - } - }; - - callback_context cb_context = {}; - LPPROGRESS_ROUTINE cb = NULL; - LPVOID cb_ctx = NULL; - - if ((options & (static_cast< unsigned int >(copy_options::synchronize_data) | static_cast< unsigned int >(copy_options::synchronize))) != 0u) - { - cb = &local::on_copy_file_progress; - cb_ctx = &cb_context; - } - - BOOL cancelled = FALSE; - BOOL res = ::CopyFileExW(from.c_str(), to.c_str(), cb, cb_ctx, &cancelled, copy_flags); - DWORD err; - if (BOOST_UNLIKELY(!res)) - { - err = ::GetLastError(); - if ((err == ERROR_FILE_EXISTS || err == ERROR_ALREADY_EXISTS) && (options & static_cast< unsigned int >(copy_options::skip_existing)) != 0u) - return false; - - copy_failed: - emit_error(err, from, to, ec, "boost::filesystem::copy_file"); - return false; - } - - if (BOOST_UNLIKELY(cb_context.flush_error != 0u)) - { - err = cb_context.flush_error; - goto copy_failed; - } - - return true; - -#endif // defined(BOOST_POSIX_API) -} - -BOOST_FILESYSTEM_DECL -void copy_symlink(path const& existing_symlink, path const& new_symlink, system::error_code* ec) -{ - path p(read_symlink(existing_symlink, ec)); - if (ec && *ec) - return; - create_symlink(p, new_symlink, ec); -} - -BOOST_FILESYSTEM_DECL -bool create_directories(path const& p, system::error_code* ec) -{ - if (p.empty()) - { - if (!ec) - { - BOOST_FILESYSTEM_THROW(filesystem_error( - "boost::filesystem::create_directories", p, - system::errc::make_error_code(system::errc::invalid_argument))); - } - ec->assign(system::errc::invalid_argument, system::generic_category()); - return false; - } - - if (ec) - ec->clear(); - - path::const_iterator e(p.end()), it(e); - path parent(p); - path const& dot_p = dot_path(); - path const& dot_dot_p = dot_dot_path(); - error_code local_ec; - - // Find the initial part of the path that exists - for (path fname = parent.filename(); parent.has_relative_path(); fname = parent.filename()) - { - if (!fname.empty() && fname != dot_p && fname != dot_dot_p) - { - file_status existing_status = detail::status_impl(parent, &local_ec); - - if (existing_status.type() == directory_file) - { - break; - } - else if (BOOST_UNLIKELY(existing_status.type() == status_error)) - { - if (!ec) - BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::create_directories", p, parent, local_ec)); - *ec = local_ec; - return false; - } - } - - --it; - parent.remove_filename(); - } - - // Create missing directories - bool created = false; - for (; it != e; ++it) - { - path const& fname = *it; - parent /= fname; - if (!fname.empty() && fname != dot_p && fname != dot_dot_p) - { - created = create_directory(parent, NULL, &local_ec); - if (BOOST_UNLIKELY(!!local_ec)) - { - if (!ec) - BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::create_directories", p, parent, local_ec)); - *ec = local_ec; - return false; - } - } - } - - return created; -} - -BOOST_FILESYSTEM_DECL -bool create_directory(path const& p, const path* existing, error_code* ec) -{ - if (ec) - ec->clear(); - -#if defined(BOOST_POSIX_API) - - mode_t mode = S_IRWXU | S_IRWXG | S_IRWXO; - if (existing) - { -#if defined(BOOST_FILESYSTEM_USE_STATX) - struct ::statx existing_stat; - if (BOOST_UNLIKELY(invoke_statx(AT_FDCWD, existing->c_str(), AT_NO_AUTOMOUNT, STATX_TYPE | STATX_MODE, &existing_stat) < 0)) - { - emit_error(errno, p, *existing, ec, "boost::filesystem::create_directory"); - return false; - } - - if (BOOST_UNLIKELY((existing_stat.stx_mask & (STATX_TYPE | STATX_MODE)) != (STATX_TYPE | STATX_MODE))) - { - emit_error(BOOST_ERROR_NOT_SUPPORTED, p, *existing, ec, "boost::filesystem::create_directory"); - return false; - } -#else - struct ::stat existing_stat; - if (::stat(existing->c_str(), &existing_stat) < 0) - { - emit_error(errno, p, *existing, ec, "boost::filesystem::create_directory"); - return false; - } -#endif - - const mode_t existing_mode = get_mode(existing_stat); - if (!S_ISDIR(existing_mode)) - { - emit_error(ENOTDIR, p, *existing, ec, "boost::filesystem::create_directory"); - return false; - } - - mode = existing_mode; - } - - if (::mkdir(p.c_str(), mode) == 0) - return true; - -#else // defined(BOOST_POSIX_API) - - BOOL res; - if (existing) - res = ::CreateDirectoryExW(existing->c_str(), p.c_str(), NULL); - else - res = ::CreateDirectoryW(p.c_str(), NULL); - - if (res) - return true; - -#endif // defined(BOOST_POSIX_API) - - // attempt to create directory failed - err_t errval = BOOST_ERRNO; // save reason for failure - error_code dummy; - - if (is_directory(p, dummy)) - return false; - - // attempt to create directory failed && it doesn't already exist - emit_error(errval, p, ec, "boost::filesystem::create_directory"); - return false; -} - -// Deprecated, to be removed in a future release -BOOST_FILESYSTEM_DECL -void copy_directory(path const& from, path const& to, system::error_code* ec) -{ - if (ec) - ec->clear(); - -#if defined(BOOST_POSIX_API) - -#if defined(BOOST_FILESYSTEM_USE_STATX) - int err; - struct ::statx from_stat; - if (BOOST_UNLIKELY(invoke_statx(AT_FDCWD, from.c_str(), AT_NO_AUTOMOUNT, STATX_TYPE | STATX_MODE, &from_stat) < 0)) - { - fail_errno: - err = errno; - fail: - emit_error(err, from, to, ec, "boost::filesystem::copy_directory"); - return; - } - - if (BOOST_UNLIKELY((from_stat.stx_mask & (STATX_TYPE | STATX_MODE)) != (STATX_TYPE | STATX_MODE))) - { - err = BOOST_ERROR_NOT_SUPPORTED; - goto fail; - } -#else - struct ::stat from_stat; - if (BOOST_UNLIKELY(::stat(from.c_str(), &from_stat) < 0)) - { - fail_errno: - emit_error(errno, from, to, ec, "boost::filesystem::copy_directory"); - return; - } -#endif - - if (BOOST_UNLIKELY(::mkdir(to.c_str(), get_mode(from_stat)) < 0)) - goto fail_errno; - -#else // defined(BOOST_POSIX_API) - - if (BOOST_UNLIKELY(!::CreateDirectoryExW(from.c_str(), to.c_str(), 0))) - emit_error(BOOST_ERRNO, from, to, ec, "boost::filesystem::copy_directory"); - -#endif // defined(BOOST_POSIX_API) -} - -BOOST_FILESYSTEM_DECL -void create_directory_symlink(path const& to, path const& from, system::error_code* ec) -{ - if (ec) - ec->clear(); - -#if defined(BOOST_POSIX_API) - int err = ::symlink(to.c_str(), from.c_str()); - if (BOOST_UNLIKELY(err < 0)) - { - err = errno; - emit_error(err, to, from, ec, "boost::filesystem::create_directory_symlink"); - } -#else - // see if actually supported by Windows runtime dll - if (!create_symbolic_link_api) - { - emit_error(BOOST_ERROR_NOT_SUPPORTED, to, from, ec, "boost::filesystem::create_directory_symlink"); - return; - } - - if (!create_symbolic_link_api(from.c_str(), to.c_str(), SYMBOLIC_LINK_FLAG_DIRECTORY | SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE)) - { - emit_error(BOOST_ERRNO, to, from, ec, "boost::filesystem::create_directory_symlink"); - } -#endif -} - -BOOST_FILESYSTEM_DECL -void create_hard_link(path const& to, path const& from, error_code* ec) -{ - if (ec) - ec->clear(); - -#if defined(BOOST_POSIX_API) - int err = ::link(to.c_str(), from.c_str()); - if (BOOST_UNLIKELY(err < 0)) - { - err = errno; - emit_error(err, to, from, ec, "boost::filesystem::create_hard_link"); - } -#else - // see if actually supported by Windows runtime dll - CreateHardLinkW_t* chl_api = filesystem::detail::atomic_load_relaxed(create_hard_link_api); - if (BOOST_UNLIKELY(!chl_api)) - { - emit_error(BOOST_ERROR_NOT_SUPPORTED, to, from, ec, "boost::filesystem::create_hard_link"); - return; - } - - if (BOOST_UNLIKELY(!chl_api(from.c_str(), to.c_str(), NULL))) - { - emit_error(BOOST_ERRNO, to, from, ec, "boost::filesystem::create_hard_link"); - } -#endif -} - -BOOST_FILESYSTEM_DECL -void create_symlink(path const& to, path const& from, error_code* ec) -{ - if (ec) - ec->clear(); - -#if defined(BOOST_POSIX_API) - int err = ::symlink(to.c_str(), from.c_str()); - if (BOOST_UNLIKELY(err < 0)) - { - err = errno; - emit_error(err, to, from, ec, "boost::filesystem::create_symlink"); - } -#else - // see if actually supported by Windows runtime dll - CreateSymbolicLinkW_t* csl_api = filesystem::detail::atomic_load_relaxed(create_symbolic_link_api); - if (BOOST_UNLIKELY(!csl_api)) - { - emit_error(BOOST_ERROR_NOT_SUPPORTED, to, from, ec, "boost::filesystem::create_symlink"); - return; - } - - if (BOOST_UNLIKELY(!csl_api(from.c_str(), to.c_str(), SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE))) - { - emit_error(BOOST_ERRNO, to, from, ec, "boost::filesystem::create_symlink"); - } -#endif -} - -BOOST_FILESYSTEM_DECL -path current_path(error_code* ec) -{ -#if defined(UNDER_CE) || defined(BOOST_FILESYSTEM_USE_WASI) - // Windows CE has no current directory, so everything's relative to the root of the directory tree. - // WASI also does not support current path. - emit_error(BOOST_ERROR_NOT_SUPPORTED, ec, "boost::filesystem::current_path"); - return path(); -#elif defined(BOOST_POSIX_API) - struct local - { - static bool getcwd_error(error_code* ec) - { - const int err = errno; - return error((err != ERANGE -#if defined(__MSL__) && (defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)) - // bug in some versions of the Metrowerks C lib on the Mac: wrong errno set - && err != 0 -#endif - ) ? err : 0, - ec, "boost::filesystem::current_path"); - } - }; - - path cur; - char small_buf[small_path_size]; - const char* p = ::getcwd(small_buf, sizeof(small_buf)); - if (BOOST_LIKELY(!!p)) - { - cur = p; - if (ec) - ec->clear(); - } - else if (BOOST_LIKELY(!local::getcwd_error(ec))) - { - for (std::size_t path_max = sizeof(small_buf) * 2u;; path_max *= 2u) // loop 'til buffer large enough - { - if (BOOST_UNLIKELY(path_max > absolute_path_max)) - { - emit_error(ENAMETOOLONG, ec, "boost::filesystem::current_path"); - break; - } - - boost::scoped_array< char > buf(new char[path_max]); - p = ::getcwd(buf.get(), path_max); - if (BOOST_LIKELY(!!p)) - { - cur = buf.get(); - if (ec) - ec->clear(); - break; - } - else if (BOOST_UNLIKELY(local::getcwd_error(ec))) - { - break; - } - } - } - - return cur; -#else - DWORD sz; - if ((sz = ::GetCurrentDirectoryW(0, NULL)) == 0) - sz = 1; - boost::scoped_array< path::value_type > buf(new path::value_type[sz]); - error(::GetCurrentDirectoryW(sz, buf.get()) == 0 ? BOOST_ERRNO : 0, ec, "boost::filesystem::current_path"); - return path(buf.get()); -#endif -} - -BOOST_FILESYSTEM_DECL -void current_path(path const& p, system::error_code* ec) -{ -#if defined(UNDER_CE) || defined(BOOST_FILESYSTEM_USE_WASI) - emit_error(BOOST_ERROR_NOT_SUPPORTED, p, ec, "boost::filesystem::current_path"); -#else - error(!BOOST_SET_CURRENT_DIRECTORY(p.c_str()) ? BOOST_ERRNO : 0, p, ec, "boost::filesystem::current_path"); -#endif -} - -BOOST_FILESYSTEM_DECL -bool equivalent(path const& p1, path const& p2, system::error_code* ec) -{ -#if defined(BOOST_POSIX_API) - - // p2 is done first, so any error reported is for p1 -#if defined(BOOST_FILESYSTEM_USE_STATX) - struct ::statx s2; - int e2 = invoke_statx(AT_FDCWD, p2.c_str(), AT_NO_AUTOMOUNT, STATX_INO, &s2); - if (BOOST_LIKELY(e2 == 0)) - { - if (BOOST_UNLIKELY((s2.stx_mask & STATX_INO) != STATX_INO)) - { - fail_unsupported: - emit_error(BOOST_ERROR_NOT_SUPPORTED, p1, p2, ec, "boost::filesystem::equivalent"); - return false; - } - } - - struct ::statx s1; - int e1 = invoke_statx(AT_FDCWD, p1.c_str(), AT_NO_AUTOMOUNT, STATX_INO, &s1); - if (BOOST_LIKELY(e1 == 0)) - { - if (BOOST_UNLIKELY((s1.stx_mask & STATX_INO) != STATX_INO)) - goto fail_unsupported; - } -#else - struct ::stat s2; - int e2 = ::stat(p2.c_str(), &s2); - struct ::stat s1; - int e1 = ::stat(p1.c_str(), &s1); -#endif - - if (BOOST_UNLIKELY(e1 != 0 || e2 != 0)) - { - // if one is invalid and the other isn't then they aren't equivalent, - // but if both are invalid then it is an error - if (e1 != 0 && e2 != 0) - emit_error(errno, p1, p2, ec, "boost::filesystem::equivalent"); - return false; - } - - return equivalent_stat(s1, s2); - -#else // Windows - - // Thanks to Jeremy Maitin-Shepard for much help and for permission to - // base the equivalent() implementation on portions of his - // file-equivalence-win32.cpp experimental code. - - // Note well: Physical location on external media is part of the - // equivalence criteria. If there are no open handles, physical location - // can change due to defragmentation or other relocations. Thus handles - // must be held open until location information for both paths has - // been retrieved. - - // p2 is done first, so any error reported is for p1 - handle_wrapper h2(create_file_handle( - p2.c_str(), - FILE_READ_ATTRIBUTES, - FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS)); - - handle_wrapper h1(create_file_handle( - p1.c_str(), - FILE_READ_ATTRIBUTES, - FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS)); - - if (BOOST_UNLIKELY(h1.handle == INVALID_HANDLE_VALUE || h2.handle == INVALID_HANDLE_VALUE)) - { - // if one is invalid and the other isn't, then they aren't equivalent, - // but if both are invalid then it is an error - if (h1.handle == INVALID_HANDLE_VALUE && h2.handle == INVALID_HANDLE_VALUE) - error(BOOST_ERRNO, p1, p2, ec, "boost::filesystem::equivalent"); - return false; - } - - // at this point, both handles are known to be valid - - BY_HANDLE_FILE_INFORMATION info1, info2; - - if (error(!::GetFileInformationByHandle(h1.handle, &info1) ? BOOST_ERRNO : 0, p1, p2, ec, "boost::filesystem::equivalent")) - return false; - - if (error(!::GetFileInformationByHandle(h2.handle, &info2) ? BOOST_ERRNO : 0, p1, p2, ec, "boost::filesystem::equivalent")) - return false; - - // In theory, volume serial numbers are sufficient to distinguish between - // devices, but in practice VSN's are sometimes duplicated, so last write - // time and file size are also checked. - return info1.dwVolumeSerialNumber == info2.dwVolumeSerialNumber && - info1.nFileIndexHigh == info2.nFileIndexHigh && - info1.nFileIndexLow == info2.nFileIndexLow && - info1.nFileSizeHigh == info2.nFileSizeHigh && - info1.nFileSizeLow == info2.nFileSizeLow && - info1.ftLastWriteTime.dwLowDateTime == info2.ftLastWriteTime.dwLowDateTime && - info1.ftLastWriteTime.dwHighDateTime == info2.ftLastWriteTime.dwHighDateTime; - -#endif -} - -BOOST_FILESYSTEM_DECL -uintmax_t file_size(path const& p, error_code* ec) -{ - if (ec) - ec->clear(); - -#if defined(BOOST_POSIX_API) - -#if defined(BOOST_FILESYSTEM_USE_STATX) - struct ::statx path_stat; - if (BOOST_UNLIKELY(invoke_statx(AT_FDCWD, p.c_str(), AT_NO_AUTOMOUNT, STATX_TYPE | STATX_SIZE, &path_stat) < 0)) - { - emit_error(errno, p, ec, "boost::filesystem::file_size"); - return static_cast< uintmax_t >(-1); - } - - if (BOOST_UNLIKELY((path_stat.stx_mask & (STATX_TYPE | STATX_SIZE)) != (STATX_TYPE | STATX_SIZE) || !S_ISREG(path_stat.stx_mode))) - { - emit_error(BOOST_ERROR_NOT_SUPPORTED, p, ec, "boost::filesystem::file_size"); - return static_cast< uintmax_t >(-1); - } -#else - struct ::stat path_stat; - if (BOOST_UNLIKELY(::stat(p.c_str(), &path_stat) < 0)) - { - emit_error(errno, p, ec, "boost::filesystem::file_size"); - return static_cast< uintmax_t >(-1); - } - - if (BOOST_UNLIKELY(!S_ISREG(path_stat.st_mode))) - { - emit_error(BOOST_ERROR_NOT_SUPPORTED, p, ec, "boost::filesystem::file_size"); - return static_cast< uintmax_t >(-1); - } -#endif - - return get_size(path_stat); - -#else // defined(BOOST_POSIX_API) - - // assume uintmax_t is 64-bits on all Windows compilers - - WIN32_FILE_ATTRIBUTE_DATA fad; - - if (BOOST_UNLIKELY(!::GetFileAttributesExW(p.c_str(), ::GetFileExInfoStandard, &fad))) - { - emit_error(BOOST_ERRNO, p, ec, "boost::filesystem::file_size"); - return static_cast< uintmax_t >(-1); - } - - if (BOOST_UNLIKELY((fad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)) - { - emit_error(ERROR_NOT_SUPPORTED, p, ec, "boost::filesystem::file_size"); - return static_cast< uintmax_t >(-1); - } - - return (static_cast< uintmax_t >(fad.nFileSizeHigh) - << (sizeof(fad.nFileSizeLow) * 8u)) | - fad.nFileSizeLow; - -#endif // defined(BOOST_POSIX_API) -} - -BOOST_FILESYSTEM_DECL -uintmax_t hard_link_count(path const& p, system::error_code* ec) -{ - if (ec) - ec->clear(); - -#if defined(BOOST_POSIX_API) - -#if defined(BOOST_FILESYSTEM_USE_STATX) - struct ::statx path_stat; - if (BOOST_UNLIKELY(invoke_statx(AT_FDCWD, p.c_str(), AT_NO_AUTOMOUNT, STATX_NLINK, &path_stat) < 0)) - { - emit_error(errno, p, ec, "boost::filesystem::hard_link_count"); - return static_cast< uintmax_t >(-1); - } - - if (BOOST_UNLIKELY((path_stat.stx_mask & STATX_NLINK) != STATX_NLINK)) - { - emit_error(BOOST_ERROR_NOT_SUPPORTED, p, ec, "boost::filesystem::hard_link_count"); - return static_cast< uintmax_t >(-1); - } - - return static_cast< uintmax_t >(path_stat.stx_nlink); -#else - struct ::stat path_stat; - if (BOOST_UNLIKELY(::stat(p.c_str(), &path_stat) < 0)) - { - emit_error(errno, p, ec, "boost::filesystem::hard_link_count"); - return static_cast< uintmax_t >(-1); - } - - return static_cast< uintmax_t >(path_stat.st_nlink); -#endif - -#else // defined(BOOST_POSIX_API) - - handle_wrapper h(create_file_handle( - p.c_str(), - FILE_READ_ATTRIBUTES, - FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS)); - - if (BOOST_UNLIKELY(h.handle == INVALID_HANDLE_VALUE)) - { - fail_errno: - emit_error(BOOST_ERRNO, p, ec, "boost::filesystem::hard_link_count"); - return static_cast< uintmax_t >(-1); - } - - // Link count info is only available through GetFileInformationByHandle - BY_HANDLE_FILE_INFORMATION info; - if (BOOST_UNLIKELY(!::GetFileInformationByHandle(h.handle, &info))) - goto fail_errno; - - return static_cast< uintmax_t >(info.nNumberOfLinks); - -#endif // defined(BOOST_POSIX_API) -} - -BOOST_FILESYSTEM_DECL -path initial_path(error_code* ec) -{ - static path init_path; - if (init_path.empty()) - init_path = current_path(ec); - else if (ec) - ec->clear(); - return init_path; -} - -BOOST_FILESYSTEM_DECL -bool is_empty(path const& p, system::error_code* ec) -{ - if (ec) - ec->clear(); - -#if defined(BOOST_POSIX_API) - -#if defined(BOOST_FILESYSTEM_USE_STATX) - struct ::statx path_stat; - if (BOOST_UNLIKELY(invoke_statx(AT_FDCWD, p.c_str(), AT_NO_AUTOMOUNT, STATX_TYPE | STATX_SIZE, &path_stat) < 0)) - { - emit_error(errno, p, ec, "boost::filesystem::is_empty"); - return false; - } - - if (BOOST_UNLIKELY((path_stat.stx_mask & STATX_TYPE) != STATX_TYPE)) - { - fail_unsupported: - emit_error(BOOST_ERROR_NOT_SUPPORTED, p, ec, "boost::filesystem::is_empty"); - return false; - } - - if (S_ISDIR(get_mode(path_stat))) - return is_empty_directory(p, ec); - - if (BOOST_UNLIKELY((path_stat.stx_mask & STATX_SIZE) != STATX_SIZE)) - goto fail_unsupported; - - return get_size(path_stat) == 0u; -#else - struct ::stat path_stat; - if (BOOST_UNLIKELY(::stat(p.c_str(), &path_stat) < 0)) - { - emit_error(errno, p, ec, "boost::filesystem::is_empty"); - return false; - } - - return S_ISDIR(get_mode(path_stat)) ? is_empty_directory(p, ec) : get_size(path_stat) == 0u; -#endif - -#else // defined(BOOST_POSIX_API) - - WIN32_FILE_ATTRIBUTE_DATA fad; - if (BOOST_UNLIKELY(!::GetFileAttributesExW(p.c_str(), ::GetFileExInfoStandard, &fad))) - { - emit_error(BOOST_ERRNO, p, ec, "boost::filesystem::is_empty"); - return false; - } - - return (fad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? is_empty_directory(p, ec) : (!fad.nFileSizeHigh && !fad.nFileSizeLow); - -#endif // defined(BOOST_POSIX_API) -} - -BOOST_FILESYSTEM_DECL -std::time_t creation_time(path const& p, system::error_code* ec) -{ - if (ec) - ec->clear(); - -#if defined(BOOST_POSIX_API) - -#if defined(BOOST_FILESYSTEM_USE_STATX) - struct ::statx stx; - if (BOOST_UNLIKELY(invoke_statx(AT_FDCWD, p.c_str(), AT_NO_AUTOMOUNT, STATX_BTIME, &stx) < 0)) - { - emit_error(BOOST_ERRNO, p, ec, "boost::filesystem::creation_time"); - return (std::numeric_limits< std::time_t >::min)(); - } - if (BOOST_UNLIKELY((stx.stx_mask & STATX_BTIME) != STATX_BTIME)) - { - emit_error(BOOST_ERROR_NOT_SUPPORTED, p, ec, "boost::filesystem::creation_time"); - return (std::numeric_limits< std::time_t >::min)(); - } - return stx.stx_btime.tv_sec; -#elif defined(BOOST_FILESYSTEM_STAT_ST_BIRTHTIME) && defined(BOOST_FILESYSTEM_STAT_ST_BIRTHTIMENSEC) - struct ::stat st; - if (BOOST_UNLIKELY(::stat(p.c_str(), &st) < 0)) - { - emit_error(BOOST_ERRNO, p, ec, "boost::filesystem::creation_time"); - return (std::numeric_limits< std::time_t >::min)(); - } - return st.BOOST_FILESYSTEM_STAT_ST_BIRTHTIME; -#else - emit_error(BOOST_ERROR_NOT_SUPPORTED, p, ec, "boost::filesystem::creation_time"); - return (std::numeric_limits< std::time_t >::min)(); -#endif - -#else // defined(BOOST_POSIX_API) - - handle_wrapper hw(create_file_handle( - p.c_str(), - FILE_READ_ATTRIBUTES, - FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS)); - - if (BOOST_UNLIKELY(hw.handle == INVALID_HANDLE_VALUE)) - { - fail: - emit_error(BOOST_ERRNO, p, ec, "boost::filesystem::creation_time"); - return (std::numeric_limits< std::time_t >::min)(); - } - - FILETIME ct; - - if (BOOST_UNLIKELY(!::GetFileTime(hw.handle, &ct, NULL, NULL))) - goto fail; - - return to_time_t(ct); - -#endif // defined(BOOST_POSIX_API) -} - -BOOST_FILESYSTEM_DECL -std::time_t last_write_time(path const& p, system::error_code* ec) -{ - if (ec) - ec->clear(); - -#if defined(BOOST_POSIX_API) - -#if defined(BOOST_FILESYSTEM_USE_STATX) - struct ::statx stx; - if (BOOST_UNLIKELY(invoke_statx(AT_FDCWD, p.c_str(), AT_NO_AUTOMOUNT, STATX_MTIME, &stx) < 0)) - { - emit_error(BOOST_ERRNO, p, ec, "boost::filesystem::last_write_time"); - return (std::numeric_limits< std::time_t >::min)(); - } - if (BOOST_UNLIKELY((stx.stx_mask & STATX_MTIME) != STATX_MTIME)) - { - emit_error(BOOST_ERROR_NOT_SUPPORTED, p, ec, "boost::filesystem::last_write_time"); - return (std::numeric_limits< std::time_t >::min)(); - } - return stx.stx_mtime.tv_sec; -#else - struct ::stat st; - if (BOOST_UNLIKELY(::stat(p.c_str(), &st) < 0)) - { - emit_error(BOOST_ERRNO, p, ec, "boost::filesystem::last_write_time"); - return (std::numeric_limits< std::time_t >::min)(); - } - return st.st_mtime; -#endif - -#else // defined(BOOST_POSIX_API) - - handle_wrapper hw(create_file_handle( - p.c_str(), - FILE_READ_ATTRIBUTES, - FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS)); - - if (BOOST_UNLIKELY(hw.handle == INVALID_HANDLE_VALUE)) - { - fail: - emit_error(BOOST_ERRNO, p, ec, "boost::filesystem::last_write_time"); - return (std::numeric_limits< std::time_t >::min)(); - } - - FILETIME lwt; - - if (BOOST_UNLIKELY(!::GetFileTime(hw.handle, NULL, NULL, &lwt))) - goto fail; - - return to_time_t(lwt); - -#endif // defined(BOOST_POSIX_API) -} - -BOOST_FILESYSTEM_DECL -void last_write_time(path const& p, const std::time_t new_time, system::error_code* ec) -{ - if (ec) - ec->clear(); - -#if defined(BOOST_POSIX_API) - -#if defined(BOOST_FILESYSTEM_HAS_POSIX_AT_APIS) - - struct timespec times[2] = {}; - - // Keep the last access time unchanged - times[0].tv_nsec = UTIME_OMIT; - - times[1].tv_sec = new_time; - - if (BOOST_UNLIKELY(::utimensat(AT_FDCWD, p.c_str(), times, 0) != 0)) - { - emit_error(BOOST_ERRNO, p, ec, "boost::filesystem::last_write_time"); - return; - } - -#else // defined(BOOST_FILESYSTEM_HAS_POSIX_AT_APIS) - - struct ::stat st; - if (BOOST_UNLIKELY(::stat(p.c_str(), &st) < 0)) - { - emit_error(BOOST_ERRNO, p, ec, "boost::filesystem::last_write_time"); - return; - } - - ::utimbuf buf; - buf.actime = st.st_atime; // utime() updates access time too :-( - buf.modtime = new_time; - if (BOOST_UNLIKELY(::utime(p.c_str(), &buf) < 0)) - emit_error(BOOST_ERRNO, p, ec, "boost::filesystem::last_write_time"); - -#endif // defined(BOOST_FILESYSTEM_HAS_POSIX_AT_APIS) - -#else // defined(BOOST_POSIX_API) - - handle_wrapper hw(create_file_handle( - p.c_str(), - FILE_WRITE_ATTRIBUTES, - FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS)); - - if (BOOST_UNLIKELY(hw.handle == INVALID_HANDLE_VALUE)) - { - fail: - emit_error(BOOST_ERRNO, p, ec, "boost::filesystem::last_write_time"); - return; - } - - FILETIME lwt; - to_FILETIME(new_time, lwt); - - if (BOOST_UNLIKELY(!::SetFileTime(hw.handle, NULL, NULL, &lwt))) - goto fail; - -#endif // defined(BOOST_POSIX_API) -} - -#ifdef BOOST_POSIX_API -const perms active_bits(all_all | set_uid_on_exe | set_gid_on_exe | sticky_bit); -inline mode_t mode_cast(perms prms) -{ - return prms & active_bits; -} -#endif - -BOOST_FILESYSTEM_DECL -void permissions(path const& p, perms prms, system::error_code* ec) -{ - BOOST_ASSERT_MSG(!((prms & add_perms) && (prms & remove_perms)), "add_perms and remove_perms are mutually exclusive"); - - if ((prms & add_perms) && (prms & remove_perms)) // precondition failed - return; - -#if defined(BOOST_FILESYSTEM_USE_WASI) - emit_error(BOOST_ERROR_NOT_SUPPORTED, p, ec, "boost::filesystem::permissions"); -#elif defined(BOOST_POSIX_API) - error_code local_ec; - file_status current_status((prms & symlink_perms) ? detail::symlink_status_impl(p, &local_ec) : detail::status_impl(p, &local_ec)); - if (local_ec) - { - if (!ec) - BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::permissions", p, local_ec)); - - *ec = local_ec; - return; - } - - if (prms & add_perms) - prms |= current_status.permissions(); - else if (prms & remove_perms) - prms = current_status.permissions() & ~prms; - - // OS X <10.10, iOS <8.0 and some other platforms don't support fchmodat(). - // Solaris (SunPro and gcc) only support fchmodat() on Solaris 11 and higher, - // and a runtime check is too much trouble. - // Linux does not support permissions on symbolic links and has no plans to - // support them in the future. The chmod() code is thus more practical, - // rather than always hitting ENOTSUP when sending in AT_SYMLINK_NO_FOLLOW. - // - See the 3rd paragraph of - // "Symbolic link ownership, permissions, and timestamps" at: - // "http://man7.org/linux/man-pages/man7/symlink.7.html" - // - See the fchmodat() Linux man page: - // "http://man7.org/linux/man-pages/man2/fchmodat.2.html" -#if defined(BOOST_FILESYSTEM_HAS_POSIX_AT_APIS) && \ - !(defined(__SUNPRO_CC) || defined(__sun) || defined(sun)) && \ - !(defined(linux) || defined(__linux) || defined(__linux__)) && \ - !(defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101000) && \ - !(defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 80000) && \ - !(defined(__rtems__)) && \ - !(defined(__QNX__) && (_NTO_VERSION <= 700)) - if (::fchmodat(AT_FDCWD, p.c_str(), mode_cast(prms), !(prms & symlink_perms) ? 0 : AT_SYMLINK_NOFOLLOW)) -#else // fallback if fchmodat() not supported - if (::chmod(p.c_str(), mode_cast(prms))) -#endif - { - const int err = errno; - if (!ec) - { - BOOST_FILESYSTEM_THROW(filesystem_error( - "boost::filesystem::permissions", p, error_code(err, system::generic_category()))); - } - - ec->assign(err, system::generic_category()); - } - -#else // Windows - - // if not going to alter FILE_ATTRIBUTE_READONLY, just return - if (!(!((prms & (add_perms | remove_perms))) || (prms & (owner_write | group_write | others_write)))) - return; - - DWORD attr = ::GetFileAttributesW(p.c_str()); - - if (error(attr == 0 ? BOOST_ERRNO : 0, p, ec, "boost::filesystem::permissions")) - return; - - if (prms & add_perms) - attr &= ~FILE_ATTRIBUTE_READONLY; - else if (prms & remove_perms) - attr |= FILE_ATTRIBUTE_READONLY; - else if (prms & (owner_write | group_write | others_write)) - attr &= ~FILE_ATTRIBUTE_READONLY; - else - attr |= FILE_ATTRIBUTE_READONLY; - - error(::SetFileAttributesW(p.c_str(), attr) == 0 ? BOOST_ERRNO : 0, p, ec, "boost::filesystem::permissions"); -#endif -} - -BOOST_FILESYSTEM_DECL -path read_symlink(path const& p, system::error_code* ec) -{ - if (ec) - ec->clear(); - - path symlink_path; - -#ifdef BOOST_POSIX_API - const char* const path_str = p.c_str(); - char small_buf[small_path_size]; - ssize_t result = ::readlink(path_str, small_buf, sizeof(small_buf)); - if (BOOST_UNLIKELY(result < 0)) - { - fail: - const int err = errno; - if (!ec) - BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::read_symlink", p, error_code(err, system_category()))); - - ec->assign(err, system_category()); - } - else if (BOOST_LIKELY(static_cast< std::size_t >(result) < sizeof(small_buf))) - { - symlink_path.assign(small_buf, small_buf + result); - } - else - { - for (std::size_t path_max = sizeof(small_buf) * 2u;; path_max *= 2u) // loop 'til buffer large enough - { - if (BOOST_UNLIKELY(path_max > absolute_path_max)) - { - if (!ec) - BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::read_symlink", p, error_code(ENAMETOOLONG, system_category()))); - - ec->assign(ENAMETOOLONG, system_category()); - break; - } - - boost::scoped_array< char > buf(new char[path_max]); - result = ::readlink(path_str, buf.get(), path_max); - if (BOOST_UNLIKELY(result < 0)) - { - goto fail; - } - else if (BOOST_LIKELY(static_cast< std::size_t >(result) < path_max)) - { - symlink_path.assign(buf.get(), buf.get() + result); - break; - } - } - } - -#else - - handle_wrapper h(create_file_handle( - p.c_str(), - FILE_READ_ATTRIBUTES, - FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT)); - - DWORD error; - if (BOOST_UNLIKELY(h.handle == INVALID_HANDLE_VALUE)) - { - error = ::GetLastError(); - - return_error: - emit_error(error, p, ec, "boost::filesystem::read_symlink"); - return symlink_path; - } - - boost::scoped_ptr< reparse_data_buffer_with_storage > buf(new reparse_data_buffer_with_storage); - DWORD sz = 0u; - if (BOOST_UNLIKELY(!::DeviceIoControl(h.handle, FSCTL_GET_REPARSE_POINT, NULL, 0, buf.get(), sizeof(*buf), &sz, NULL))) - { - error = ::GetLastError(); - goto return_error; - } - - const wchar_t* buffer; - std::size_t offset, len; - switch (buf->rdb.ReparseTag) - { - case IO_REPARSE_TAG_MOUNT_POINT: - buffer = buf->rdb.MountPointReparseBuffer.PathBuffer; - offset = buf->rdb.MountPointReparseBuffer.SubstituteNameOffset; - len = buf->rdb.MountPointReparseBuffer.SubstituteNameLength; - break; - - case IO_REPARSE_TAG_SYMLINK: - buffer = buf->rdb.SymbolicLinkReparseBuffer.PathBuffer; - offset = buf->rdb.SymbolicLinkReparseBuffer.SubstituteNameOffset; - len = buf->rdb.SymbolicLinkReparseBuffer.SubstituteNameLength; - // Note: iff info.rdb.SymbolicLinkReparseBuffer.Flags & SYMLINK_FLAG_RELATIVE - // -> resulting path is relative to the source - break; - - default: - emit_error(BOOST_ERROR_NOT_SUPPORTED, p, ec, "Unknown ReparseTag in boost::filesystem::read_symlink"); - return symlink_path; - } - - symlink_path = convert_nt_path_to_win32_path(buffer + offset / sizeof(wchar_t), len / sizeof(wchar_t)); -#endif - - return symlink_path; -} - -BOOST_FILESYSTEM_DECL -path relative(path const& p, path const& base, error_code* ec) -{ - if (ec) - ec->clear(); - - error_code local_ec; - path cur_path; - if (!p.is_absolute() || !base.is_absolute()) - { - cur_path = detail::current_path(&local_ec); - if (BOOST_UNLIKELY(!!local_ec)) - { - fail_local_ec: - if (!ec) - BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::relative", p, base, local_ec)); - - *ec = local_ec; - return path(); - } - } - - path wc_base(detail::weakly_canonical(base, cur_path, &local_ec)); - if (BOOST_UNLIKELY(!!local_ec)) - goto fail_local_ec; - path wc_p(detail::weakly_canonical(p, cur_path, &local_ec)); - if (BOOST_UNLIKELY(!!local_ec)) - goto fail_local_ec; - return wc_p.lexically_relative(wc_base); -} - -BOOST_FILESYSTEM_DECL -bool remove(path const& p, error_code* ec) -{ - if (ec) - ec->clear(); - - return detail::remove_impl(p, ec); -} - -BOOST_FILESYSTEM_DECL -uintmax_t remove_all(path const& p, error_code* ec) -{ - if (ec) - ec->clear(); - - return detail::remove_all_impl(p, ec); -} - -BOOST_FILESYSTEM_DECL -void rename(path const& old_p, path const& new_p, error_code* ec) -{ - error(!BOOST_MOVE_FILE(old_p.c_str(), new_p.c_str()) ? BOOST_ERRNO : 0, old_p, new_p, ec, "boost::filesystem::rename"); -} - -BOOST_FILESYSTEM_DECL -void resize_file(path const& p, uintmax_t size, system::error_code* ec) -{ -#if defined(BOOST_POSIX_API) - if (BOOST_UNLIKELY(size > static_cast< uintmax_t >((std::numeric_limits< off_t >::max)()))) - { - emit_error(system::errc::file_too_large, p, ec, "boost::filesystem::resize_file"); - return; - } -#endif - error(!BOOST_RESIZE_FILE(p.c_str(), size) ? BOOST_ERRNO : 0, p, ec, "boost::filesystem::resize_file"); -} - -BOOST_FILESYSTEM_DECL -space_info space(path const& p, error_code* ec) -{ - space_info info; - // Initialize members to -1, as required by C++20 [fs.op.space]/1 in case of error - info.capacity = static_cast< uintmax_t >(-1); - info.free = static_cast< uintmax_t >(-1); - info.available = static_cast< uintmax_t >(-1); - - if (ec) - ec->clear(); - -#if defined(BOOST_FILESYSTEM_USE_WASI) - - emit_error(BOOST_ERROR_NOT_SUPPORTED, p, ec, "boost::filesystem::space"); - -#elif defined(BOOST_POSIX_API) - - struct BOOST_STATVFS vfs; - if (!error(::BOOST_STATVFS(p.c_str(), &vfs) ? BOOST_ERRNO : 0, p, ec, "boost::filesystem::space")) - { - info.capacity = static_cast< uintmax_t >(vfs.f_blocks) * BOOST_STATVFS_F_FRSIZE; - info.free = static_cast< uintmax_t >(vfs.f_bfree) * BOOST_STATVFS_F_FRSIZE; - info.available = static_cast< uintmax_t >(vfs.f_bavail) * BOOST_STATVFS_F_FRSIZE; - } - -#else - - // GetDiskFreeSpaceExW requires a directory path, which is unlike statvfs, which accepts any file. - // To work around this, test if the path refers to a directory and use the parent directory if not. - error_code local_ec; - file_status status = detail::status_impl(p, &local_ec); - if (status.type() == fs::status_error || status.type() == fs::file_not_found) - { - fail_local_ec: - if (!ec) - BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::space", p, local_ec)); - *ec = local_ec; - return info; - } - - path dir_path = p; - if (!is_directory(status)) - { - path cur_path = detail::current_path(ec); - if (ec && *ec) - return info; - - status = detail::symlink_status_impl(p, &local_ec); - if (status.type() == fs::status_error) - goto fail_local_ec; - if (is_symlink(status)) - { - // We need to resolve the symlink so that we report the space for the symlink target - dir_path = detail::canonical(p, cur_path, ec); - if (ec && *ec) - return info; - } - - dir_path = dir_path.parent_path(); - if (dir_path.empty()) - { - // The original path was just a filename, which is a relative path wrt. current directory - dir_path = cur_path; - } - } - - // For UNC names, the path must also include a trailing slash. - path::string_type str = dir_path.native(); - if (str.size() >= 2u && detail::is_directory_separator(str[0]) && detail::is_directory_separator(str[1]) && !detail::is_directory_separator(*(str.end() - 1))) - str.push_back(path::preferred_separator); - - ULARGE_INTEGER avail, total, free; - if (!error(::GetDiskFreeSpaceExW(str.c_str(), &avail, &total, &free) == 0, p, ec, "boost::filesystem::space")) - { - info.capacity = static_cast< uintmax_t >(total.QuadPart); - info.free = static_cast< uintmax_t >(free.QuadPart); - info.available = static_cast< uintmax_t >(avail.QuadPart); - } - -#endif - - return info; -} - -BOOST_FILESYSTEM_DECL -file_status status(path const& p, error_code* ec) -{ - if (ec) - ec->clear(); - - return detail::status_impl(p, ec); -} - -BOOST_FILESYSTEM_DECL -file_status symlink_status(path const& p, error_code* ec) -{ - if (ec) - ec->clear(); - - return detail::symlink_status_impl(p, ec); -} - -// contributed by Jeff Flinn -BOOST_FILESYSTEM_DECL -path temp_directory_path(system::error_code* ec) -{ - if (ec) - ec->clear(); - -#ifdef BOOST_POSIX_API - const char* val = NULL; - - (val = std::getenv("TMPDIR")) || - (val = std::getenv("TMP")) || - (val = std::getenv("TEMP")) || - (val = std::getenv("TEMPDIR")); - -#ifdef __ANDROID__ - const char* default_tmp = "/data/local/tmp"; -#else - const char* default_tmp = "/tmp"; -#endif - path p((val != NULL) ? val : default_tmp); - - if (BOOST_UNLIKELY(p.empty())) - { - fail_not_dir: - error(ENOTDIR, p, ec, "boost::filesystem::temp_directory_path"); - return p; - } - - file_status status = detail::status_impl(p, ec); - if (BOOST_UNLIKELY(ec && *ec)) - return path(); - if (BOOST_UNLIKELY(!is_directory(status))) - goto fail_not_dir; - - return p; - -#else // Windows -#if !defined(UNDER_CE) - - const wchar_t* tmp_env = L"TMP"; - const wchar_t* temp_env = L"TEMP"; - const wchar_t* localappdata_env = L"LOCALAPPDATA"; - const wchar_t* userprofile_env = L"USERPROFILE"; - const wchar_t* env_list[] = { tmp_env, temp_env, localappdata_env, userprofile_env }; - - path p; - for (unsigned int i = 0; i < sizeof(env_list) / sizeof(*env_list); ++i) - { - std::wstring env = wgetenv(env_list[i]); - if (!env.empty()) - { - p = env; - if (i >= 2) - p /= L"Temp"; - error_code lcl_ec; - if (exists(p, lcl_ec) && !lcl_ec && is_directory(p, lcl_ec) && !lcl_ec) - break; - p.clear(); - } - } - - if (p.empty()) - { - // use a separate buffer since in C++03 a string is not required to be contiguous - const UINT size = ::GetWindowsDirectoryW(NULL, 0); - if (BOOST_UNLIKELY(size == 0)) - { - getwindir_error: - int errval = ::GetLastError(); - error(errval, ec, "boost::filesystem::temp_directory_path"); - return path(); - } - - boost::scoped_array< wchar_t > buf(new wchar_t[size]); - if (BOOST_UNLIKELY(::GetWindowsDirectoryW(buf.get(), size) == 0)) - goto getwindir_error; - - p = buf.get(); // do not depend on initial buf size, see ticket #10388 - p /= L"Temp"; - } - - return p; - -#else // Windows CE - - // Windows CE has no environment variables, so the same code as used for - // regular Windows, above, doesn't work. - - DWORD size = ::GetTempPathW(0, NULL); - if (size == 0u) - { - fail: - int errval = ::GetLastError(); - error(errval, ec, "boost::filesystem::temp_directory_path"); - return path(); - } - - boost::scoped_array< wchar_t > buf(new wchar_t[size]); - if (::GetTempPathW(size, buf.get()) == 0) - goto fail; - - path p(buf.get()); - p.remove_trailing_separator(); - - file_status status = detail::status_impl(p, ec); - if (ec && *ec) - return path(); - if (!is_directory(status)) - { - error(ERROR_PATH_NOT_FOUND, p, ec, "boost::filesystem::temp_directory_path"); - return path(); - } - - return p; - -#endif // !defined(UNDER_CE) -#endif -} - -BOOST_FILESYSTEM_DECL -path system_complete(path const& p, system::error_code* ec) -{ -#ifdef BOOST_POSIX_API - - return (p.empty() || p.is_absolute()) ? p : current_path() / p; - -#else - if (p.empty()) - { - if (ec) - ec->clear(); - return p; - } - - BOOST_CONSTEXPR_OR_CONST std::size_t buf_size = 128u; - wchar_t buf[buf_size]; - wchar_t* pfn; - std::size_t len = get_full_path_name(p, buf_size, buf, &pfn); - - if (error(len == 0 ? BOOST_ERRNO : 0, p, ec, "boost::filesystem::system_complete")) - return path(); - - if (len < buf_size) // len does not include null termination character - return path(&buf[0]); - - boost::scoped_array< wchar_t > big_buf(new wchar_t[len]); - - return error(get_full_path_name(p, len, big_buf.get(), &pfn) == 0 ? BOOST_ERRNO : 0, p, ec, "boost::filesystem::system_complete") ? path() : path(big_buf.get()); -#endif -} - -BOOST_FILESYSTEM_DECL -path weakly_canonical(path const& p, path const& base, system::error_code* ec) -{ - system::error_code local_ec; - const path::iterator p_end(p.end()); - -#if defined(BOOST_POSIX_API) - - path::iterator itr(p_end); - path head(p); - for (; !head.empty(); --itr) - { - file_status head_status = detail::status_impl(head, &local_ec); - if (BOOST_UNLIKELY(head_status.type() == fs::status_error)) - { - if (!ec) - BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::weakly_canonical", head, local_ec)); - - *ec = local_ec; - return path(); - } - - if (head_status.type() != fs::file_not_found) - break; - - head.remove_filename(); - } - -#else - - // On Windows, filesystem APIs such as GetFileAttributesW perform lexical path normalization internally. - // As a result, a path like "c:\a\.." can be reported as present even if "c:\a" is not. This would break - // canonical, as symlink_status that it calls internally would report an error that the file at the intermediate - // path does not exist. To avoid this, scan the initial path in the forward direction. - // Also, operate on paths with preferred separators. This can be important on Windows since GetFileAttributesW, - // which is called in status() may return "file not found" for paths to network shares and mounted cloud - // storages that have forward slashes as separators. - path::iterator itr(p.begin()); - path head; - for (; itr != p_end; ++itr) - { - path const& p_elem = *itr; - if (p_elem.size() == 1u && detail::is_directory_separator(p_elem.native()[0])) - { - // Convert generic separator returned by the iterator for the root directory to - // the preferred separator. - head += path::preferred_separator; - } - else - { - head /= p_elem; - } - - file_status head_status = detail::status_impl(head, &local_ec); - if (BOOST_UNLIKELY(head_status.type() == fs::status_error)) - { - if (!ec) - BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::weakly_canonical", head, local_ec)); - - *ec = local_ec; - return path(); - } - - if (head_status.type() == fs::file_not_found) - { - head.remove_filename(); - break; - } - } - -#endif - - path const& dot_p = dot_path(); - path const& dot_dot_p = dot_dot_path(); - path tail; - bool tail_has_dots = false; - for (; itr != p_end; ++itr) - { - path const& tail_elem = *itr; -#if defined(BOOST_WINDOWS_API) - if (tail_elem.size() == 1u && detail::is_directory_separator(tail_elem.native()[0])) - { - // Convert generic separator returned by the iterator for the root directory to - // the preferred separator. - tail += path::preferred_separator; - continue; - } -#endif - tail /= tail_elem; - // for a later optimization, track if any dot or dot-dot elements are present - if (!tail_has_dots && (tail_elem == dot_p || tail_elem == dot_dot_p)) - tail_has_dots = true; - } - - if (head.empty()) - return p.lexically_normal(); - - head = detail::canonical(head, base, &local_ec); - if (BOOST_UNLIKELY(!!local_ec)) - { - if (!ec) - BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::weakly_canonical", head, local_ec)); - - *ec = local_ec; - return path(); - } - - if (BOOST_LIKELY(!tail.empty())) - { - head /= tail; - - // optimization: only normalize if tail had dot or dot-dot element - if (tail_has_dots) - return head.lexically_normal(); - } - - return head; -} - -} // namespace detail -} // namespace filesystem -} // namespace boost - -#include <boost/filesystem/detail/footer.hpp> diff --git a/contrib/restricted/boost/filesystem/src/path.cpp b/contrib/restricted/boost/filesystem/src/path.cpp deleted file mode 100644 index 27b32e57c5..0000000000 --- a/contrib/restricted/boost/filesystem/src/path.cpp +++ /dev/null @@ -1,1684 +0,0 @@ -// filesystem path.cpp ------------------------------------------------------------- // - -// Copyright Beman Dawes 2008 -// Copyright Andrey Semashev 2021 - -// Distributed under the Boost Software License, Version 1.0. -// See http://www.boost.org/LICENSE_1_0.txt - -// Library home page: http://www.boost.org/libs/filesystem - -#include "platform_config.hpp" - -#include <boost/filesystem/config.hpp> -#include <boost/filesystem/path.hpp> -#include <boost/filesystem/path_traits.hpp> // codecvt_error_category() -#include <boost/scoped_array.hpp> -#include <boost/system/error_category.hpp> // for BOOST_SYSTEM_HAS_CONSTEXPR -#include <boost/assert.hpp> -#include <algorithm> -#include <iterator> -#include <utility> -#include <string> -#include <cstddef> -#include <cstring> -#include <cstdlib> // std::atexit - -#ifdef BOOST_WINDOWS_API -#include "windows_file_codecvt.hpp" -#include "windows_tools.hpp" -#include <windows.h> -#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__HAIKU__) -#include <boost/filesystem/detail/utf8_codecvt_facet.hpp> -#endif - -#ifdef BOOST_FILESYSTEM_DEBUG -#include <iostream> -#include <iomanip> -#endif - -#include "atomic_tools.hpp" -#include "private_config.hpp" - -#include <boost/filesystem/detail/header.hpp> // must be the last #include - -namespace fs = boost::filesystem; - -using boost::filesystem::path; - -//--------------------------------------------------------------------------------------// -// // -// class path helpers // -// // -//--------------------------------------------------------------------------------------// - -namespace { -//------------------------------------------------------------------------------------// -// miscellaneous class path helpers // -//------------------------------------------------------------------------------------// - -typedef path::value_type value_type; -typedef path::string_type string_type; -typedef string_type::size_type size_type; -using boost::filesystem::path_detail::substring; - -#ifdef BOOST_WINDOWS_API - -const wchar_t dot_path_literal[] = L"."; -const wchar_t dot_dot_path_literal[] = L".."; -const wchar_t separators[] = L"/\\"; -using boost::filesystem::detail::colon; -using boost::filesystem::detail::questionmark; - -inline bool is_alnum(wchar_t c) -{ - return boost::filesystem::detail::is_letter(c) || (c >= L'0' && c <= L'9'); -} - -inline bool is_device_name_char(wchar_t c) -{ - // https://googleprojectzero.blogspot.com/2016/02/the-definitive-guide-on-win32-to-nt.html - // Device names are: - // - // - PRN - // - AUX - // - NUL - // - CON - // - LPT[1-9] - // - COM[1-9] - // - CONIN$ - // - CONOUT$ - return is_alnum(c) || c == L'$'; -} - -//! Returns position of the first directory separator in the \a size initial characters of \a p, or \a size if not found -inline size_type find_separator(const wchar_t* p, size_type size) BOOST_NOEXCEPT -{ - size_type pos = 0u; - for (; pos < size; ++pos) - { - const wchar_t c = p[pos]; - if (boost::filesystem::detail::is_directory_separator(c)) - break; - } - return pos; -} - -#else // BOOST_WINDOWS_API - -const char dot_path_literal[] = "."; -const char dot_dot_path_literal[] = ".."; -const char separators[] = "/"; - -//! Returns position of the first directory separator in the \a size initial characters of \a p, or \a size if not found -inline size_type find_separator(const char* p, size_type size) BOOST_NOEXCEPT -{ - const char* sep = static_cast< const char* >(std::memchr(p, '/', size)); - size_type pos = size; - if (BOOST_LIKELY(!!sep)) - pos = sep - p; - return pos; -} - -#endif // BOOST_WINDOWS_API - -// pos is position of the separator -bool is_root_separator(string_type const& str, size_type root_dir_pos, size_type pos); - -// Returns: Size of the filename element that ends at end_pos (which is past-the-end position). 0 if no filename found. -size_type find_filename_size(string_type const& str, size_type root_name_size, size_type end_pos); - -// Returns: starting position of root directory or size if not found. Sets root_name_size to length -// of the root name if the characters before the returned position (if any) are considered a root name. -size_type find_root_directory_start(const value_type* path, size_type size, size_type& root_name_size); - -// Finds position and size of the first element of the path -void first_element(string_type const& src, size_type& element_pos, size_type& element_size, size_type size); - -// Finds position and size of the first element of the path -inline void first_element(string_type const& src, size_type& element_pos, size_type& element_size) -{ - first_element(src, element_pos, element_size, src.size()); -} - -} // unnamed namespace - -//--------------------------------------------------------------------------------------// -// // -// class path implementation // -// // -//--------------------------------------------------------------------------------------// - -namespace boost { -namespace filesystem { - -BOOST_FILESYSTEM_DECL void path::append_v3(path const& p) -{ - if (!p.empty()) - { - if (BOOST_LIKELY(this != &p)) - { - if (!detail::is_directory_separator(*p.m_pathname.begin())) - append_separator_if_needed(); - m_pathname += p.m_pathname; - } - else - { - // self-append - path rhs(p); - append_v3(rhs); - } - } -} - -BOOST_FILESYSTEM_DECL void path::append_v3(const value_type* begin, const value_type* end) -{ - if (begin != end) - { - if (BOOST_LIKELY(begin < m_pathname.data() || begin >= (m_pathname.data() + m_pathname.size()))) - { - if (!detail::is_directory_separator(*begin)) - append_separator_if_needed(); - m_pathname.append(begin, end); - } - else - { - // overlapping source - path rhs(begin, end); - append_v3(rhs); - } - } -} - -BOOST_FILESYSTEM_DECL void path::append_v4(path const& p) -{ - if (!p.empty()) - { - if (BOOST_LIKELY(this != &p)) - { - const size_type that_size = p.m_pathname.size(); - size_type that_root_name_size = 0; - size_type that_root_dir_pos = find_root_directory_start(p.m_pathname.c_str(), that_size, that_root_name_size); - - // if (p.is_absolute()) - if - ( -#if defined(BOOST_WINDOWS_API) && !defined(UNDER_CE) - that_root_name_size > 0 && -#endif - that_root_dir_pos < that_size - ) - { - return_assign: - assign(p); - return; - } - - size_type this_root_name_size = 0; - find_root_directory_start(m_pathname.c_str(), m_pathname.size(), this_root_name_size); - - if - ( - that_root_name_size > 0 && - (that_root_name_size != this_root_name_size || std::memcmp(m_pathname.c_str(), p.m_pathname.c_str(), this_root_name_size * sizeof(value_type)) != 0) - ) - { - goto return_assign; - } - - if (that_root_dir_pos < that_size) - { - // Remove root directory (if any) and relative path to replace with those from p - m_pathname.erase(m_pathname.begin() + this_root_name_size, m_pathname.end()); - } - - const value_type* const that_path = p.m_pathname.c_str() + that_root_name_size; - if (!detail::is_directory_separator(*that_path)) - append_separator_if_needed(); - m_pathname.append(that_path, that_size - that_root_name_size); - } - else - { - // self-append - path rhs(p); - append_v4(rhs); - } - } - else if (has_filename_v4()) - { - m_pathname.push_back(preferred_separator); - } -} - -BOOST_FILESYSTEM_DECL void path::append_v4(const value_type* begin, const value_type* end) -{ - if (begin != end) - { - if (BOOST_LIKELY(begin < m_pathname.data() || begin >= (m_pathname.data() + m_pathname.size()))) - { - const size_type that_size = end - begin; - size_type that_root_name_size = 0; - size_type that_root_dir_pos = find_root_directory_start(begin, that_size, that_root_name_size); - - // if (p.is_absolute()) - if - ( -#if defined(BOOST_WINDOWS_API) && !defined(UNDER_CE) - that_root_name_size > 0 && -#endif - that_root_dir_pos < that_size - ) - { - return_assign: - assign(begin, end); - return; - } - - size_type this_root_name_size = 0; - find_root_directory_start(m_pathname.c_str(), m_pathname.size(), this_root_name_size); - - if - ( - that_root_name_size > 0 && - (that_root_name_size != this_root_name_size || std::memcmp(m_pathname.c_str(), begin, this_root_name_size * sizeof(value_type)) != 0) - ) - { - goto return_assign; - } - - if (that_root_dir_pos < that_size) - { - // Remove root directory (if any) and relative path to replace with those from p - m_pathname.erase(m_pathname.begin() + this_root_name_size, m_pathname.end()); - } - - const value_type* const that_path = begin + that_root_name_size; - if (!detail::is_directory_separator(*that_path)) - append_separator_if_needed(); - m_pathname.append(that_path, end); - } - else - { - // overlapping source - path rhs(begin, end); - append_v4(rhs); - } - } - else if (has_filename_v4()) - { - m_pathname.push_back(preferred_separator); - } -} - -#ifdef BOOST_WINDOWS_API - -BOOST_FILESYSTEM_DECL path path::generic_path() const -{ - path tmp(*this); - std::replace(tmp.m_pathname.begin(), tmp.m_pathname.end(), L'\\', L'/'); - return tmp; -} - -#endif // BOOST_WINDOWS_API - -BOOST_FILESYSTEM_DECL int path::compare_v3(path const& p) const BOOST_NOEXCEPT -{ - return detail::lex_compare_v3(begin(), end(), p.begin(), p.end()); -} - -BOOST_FILESYSTEM_DECL int path::compare_v4(path const& p) const BOOST_NOEXCEPT -{ - return detail::lex_compare_v4(begin(), end(), p.begin(), p.end()); -} - -// append_separator_if_needed ----------------------------------------------------// - -BOOST_FILESYSTEM_DECL path::string_type::size_type path::append_separator_if_needed() -{ - if (!m_pathname.empty() && -#ifdef BOOST_WINDOWS_API - *(m_pathname.end() - 1) != colon && -#endif - !detail::is_directory_separator(*(m_pathname.end() - 1))) - { - string_type::size_type tmp(m_pathname.size()); - m_pathname += preferred_separator; - return tmp; - } - return 0; -} - -// erase_redundant_separator -----------------------------------------------------// - -BOOST_FILESYSTEM_DECL void path::erase_redundant_separator(string_type::size_type sep_pos) -{ - if (sep_pos // a separator was added - && sep_pos < m_pathname.size() // and something was appended - && (m_pathname[sep_pos + 1] == separator // and it was also separator -#ifdef BOOST_WINDOWS_API - || m_pathname[sep_pos + 1] == preferred_separator // or preferred_separator -#endif - )) - { - m_pathname.erase(m_pathname.begin() + sep_pos); // erase the added separator - } -} - -// modifiers -----------------------------------------------------------------------// - -#ifdef BOOST_WINDOWS_API -BOOST_FILESYSTEM_DECL path& path::make_preferred() -{ - std::replace(m_pathname.begin(), m_pathname.end(), L'/', L'\\'); - return *this; -} -#endif - -BOOST_FILESYSTEM_DECL path& path::remove_filename() -{ - size_type end_pos = find_parent_path_size(); - m_pathname.erase(m_pathname.begin() + end_pos, m_pathname.end()); - return *this; -} - -BOOST_FILESYSTEM_DECL path& path::remove_trailing_separator() -{ - if (!m_pathname.empty() && detail::is_directory_separator(m_pathname[m_pathname.size() - 1])) - m_pathname.erase(m_pathname.end() - 1); - return *this; -} - -BOOST_FILESYSTEM_DECL void path::replace_extension_v3(path const& new_extension) -{ - // erase existing extension, including the dot, if any - size_type ext_pos = m_pathname.size() - extension_v3().m_pathname.size(); - m_pathname.erase(m_pathname.begin() + ext_pos, m_pathname.end()); - - if (!new_extension.empty()) - { - // append new_extension, adding the dot if necessary - if (new_extension.m_pathname[0] != dot) - m_pathname.push_back(dot); - m_pathname.append(new_extension.m_pathname); - } -} - -BOOST_FILESYSTEM_DECL void path::replace_extension_v4(path const& new_extension) -{ - // erase existing extension, including the dot, if any - size_type ext_pos = m_pathname.size() - find_extension_v4_size(); - m_pathname.erase(m_pathname.begin() + ext_pos, m_pathname.end()); - - if (!new_extension.empty()) - { - // append new_extension, adding the dot if necessary - if (new_extension.m_pathname[0] != dot) - m_pathname.push_back(dot); - m_pathname.append(new_extension.m_pathname); - } -} - -// decomposition -------------------------------------------------------------------// - -BOOST_FILESYSTEM_DECL size_type path::find_root_name_size() const -{ - size_type root_name_size = 0; - find_root_directory_start(m_pathname.c_str(), m_pathname.size(), root_name_size); - return root_name_size; -} - -BOOST_FILESYSTEM_DECL size_type path::find_root_path_size() const -{ - size_type root_name_size = 0; - size_type root_dir_pos = find_root_directory_start(m_pathname.c_str(), m_pathname.size(), root_name_size); - - size_type size = root_name_size; - if (root_dir_pos < m_pathname.size()) - size = root_dir_pos + 1; - - return size; -} - -BOOST_FILESYSTEM_DECL substring path::find_root_directory() const -{ - substring root_dir; - size_type root_name_size = 0; - root_dir.pos = find_root_directory_start(m_pathname.c_str(), m_pathname.size(), root_name_size); - root_dir.size = static_cast< std::size_t >(root_dir.pos < m_pathname.size()); - return root_dir; -} - -BOOST_FILESYSTEM_DECL substring path::find_relative_path() const -{ - size_type root_name_size = 0; - size_type root_dir_pos = find_root_directory_start(m_pathname.c_str(), m_pathname.size(), root_name_size); - - // Skip root name, root directory and any duplicate separators - size_type size = root_name_size; - if (root_dir_pos < m_pathname.size()) - { - size = root_dir_pos + 1; - - for (size_type n = m_pathname.size(); size < n; ++size) - { - if (!detail::is_directory_separator(m_pathname[size])) - break; - } - } - - substring rel_path; - rel_path.pos = size; - rel_path.size = m_pathname.size() - size; - - return rel_path; -} - -BOOST_FILESYSTEM_DECL string_type::size_type path::find_parent_path_size() const -{ - const size_type size = m_pathname.size(); - size_type root_name_size = 0; - size_type root_dir_pos = find_root_directory_start(m_pathname.c_str(), size, root_name_size); - - size_type filename_size = find_filename_size(m_pathname, root_name_size, size); - size_type end_pos = size - filename_size; - while (true) - { - if (end_pos <= root_name_size) - { - // Keep the root name as the parent path if there was a filename - if (filename_size == 0) - end_pos = 0u; - break; - } - - --end_pos; - - if (!detail::is_directory_separator(m_pathname[end_pos])) - { - ++end_pos; - break; - } - - if (end_pos == root_dir_pos) - { - // Keep the trailing root directory if there was a filename - end_pos += filename_size > 0; - break; - } - } - - return end_pos; -} - -BOOST_FILESYSTEM_DECL path path::filename_v3() const -{ - const size_type size = m_pathname.size(); - size_type root_name_size = 0; - size_type root_dir_pos = find_root_directory_start(m_pathname.c_str(), size, root_name_size); - size_type filename_size, pos; - if (root_dir_pos < size && detail::is_directory_separator(m_pathname[size - 1]) && is_root_separator(m_pathname, root_dir_pos, size - 1)) - { - // Return root directory - pos = root_dir_pos; - filename_size = 1u; - } - else if (root_name_size == size) - { - // Return root name - pos = 0u; - filename_size = root_name_size; - } - else - { - filename_size = find_filename_size(m_pathname, root_name_size, size); - pos = size - filename_size; - if (filename_size == 0u && pos > root_name_size && detail::is_directory_separator(m_pathname[pos - 1]) && !is_root_separator(m_pathname, root_dir_pos, pos - 1)) - return detail::dot_path(); - } - - const value_type* p = m_pathname.c_str() + pos; - return path(p, p + filename_size); -} - -BOOST_FILESYSTEM_DECL string_type::size_type path::find_filename_v4_size() const -{ - const size_type size = m_pathname.size(); - size_type root_name_size = 0; - find_root_directory_start(m_pathname.c_str(), size, root_name_size); - return find_filename_size(m_pathname, root_name_size, size); -} - -BOOST_FILESYSTEM_DECL path path::stem_v3() const -{ - path name(filename_v3()); - if (name != detail::dot_path() && name != detail::dot_dot_path()) - { - size_type pos = name.m_pathname.rfind(dot); - if (pos != string_type::npos) - name.m_pathname.erase(name.m_pathname.begin() + pos, name.m_pathname.end()); - } - return name; -} - -BOOST_FILESYSTEM_DECL path path::stem_v4() const -{ - path name(filename_v4()); - if (name != detail::dot_path() && name != detail::dot_dot_path()) - { - size_type pos = name.m_pathname.rfind(dot); - if (pos != 0 && pos != string_type::npos) - name.m_pathname.erase(name.m_pathname.begin() + pos, name.m_pathname.end()); - } - return name; -} - -BOOST_FILESYSTEM_DECL path path::extension_v3() const -{ - path name(filename_v3()); - if (name == detail::dot_path() || name == detail::dot_dot_path()) - return path(); - size_type pos(name.m_pathname.rfind(dot)); - return pos == string_type::npos ? path() : path(name.m_pathname.c_str() + pos); -} - -BOOST_FILESYSTEM_DECL string_type::size_type path::find_extension_v4_size() const -{ - const size_type size = m_pathname.size(); - size_type root_name_size = 0; - find_root_directory_start(m_pathname.c_str(), size, root_name_size); - size_type filename_size = find_filename_size(m_pathname, root_name_size, size); - size_type filename_pos = size - filename_size; - if - ( - filename_size > 0u && - // Check for "." and ".." filenames - !(m_pathname[filename_pos] == dot && - (filename_size == 1u || (filename_size == 2u && m_pathname[filename_pos + 1u] == dot))) - ) - { - size_type ext_pos = size; - while (ext_pos > filename_pos) - { - --ext_pos; - if (m_pathname[ext_pos] == dot) - break; - } - - if (ext_pos > filename_pos) - return size - ext_pos; - } - - return 0u; -} - -// lexical operations --------------------------------------------------------------// - -namespace detail { -// C++14 provides a mismatch algorithm with four iterator arguments(), but earlier -// standard libraries didn't, so provide this needed functionality. -inline std::pair< path::iterator, path::iterator > mismatch(path::iterator it1, path::iterator it1end, path::iterator it2, path::iterator it2end) -{ - for (; it1 != it1end && it2 != it2end && *it1 == *it2;) - { - ++it1; - ++it2; - } - return std::make_pair(it1, it2); -} -} // namespace detail - -BOOST_FILESYSTEM_DECL path path::lexically_relative(path const& base) const -{ - path::iterator b = begin(), e = end(), base_b = base.begin(), base_e = base.end(); - std::pair< path::iterator, path::iterator > mm = detail::mismatch(b, e, base_b, base_e); - if (mm.first == b && mm.second == base_b) - return path(); - if (mm.first == e && mm.second == base_e) - return detail::dot_path(); - - std::ptrdiff_t n = 0; - for (; mm.second != base_e; ++mm.second) - { - path const& p = *mm.second; - if (p == detail::dot_dot_path()) - --n; - else if (!p.empty() && p != detail::dot_path()) - ++n; - } - if (n < 0) - return path(); - if (n == 0 && (mm.first == e || mm.first->empty())) - return detail::dot_path(); - - path tmp; - for (; n > 0; --n) - tmp /= detail::dot_dot_path(); - for (; mm.first != e; ++mm.first) - tmp /= *mm.first; - return tmp; -} - -// normal --------------------------------------------------------------------------// - -BOOST_FILESYSTEM_DECL path path::lexically_normal_v3() const -{ - const value_type* const pathname = m_pathname.c_str(); - const size_type pathname_size = m_pathname.size(); - size_type root_name_size = 0; - size_type root_dir_pos = find_root_directory_start(pathname, pathname_size, root_name_size); - path normal(pathname, pathname + root_name_size); - -#if defined(BOOST_WINDOWS_API) - for (size_type i = 0; i < root_name_size; ++i) - { - if (normal.m_pathname[i] == path::separator) - normal.m_pathname[i] = path::preferred_separator; - } -#endif - - size_type root_path_size = root_name_size; - if (root_dir_pos < pathname_size) - { - root_path_size = root_dir_pos + 1; - normal.m_pathname.push_back(preferred_separator); - } - - size_type i = root_path_size; - - // Skip redundant directory separators after the root directory - while (i < pathname_size && detail::is_directory_separator(pathname[i])) - ++i; - - if (i < pathname_size) - { - bool last_element_was_dot = false; - while (true) - { - { - const size_type start_pos = i; - - // Find next separator - i += find_separator(pathname + i, pathname_size - i); - - const size_type size = i - start_pos; - - // Skip dot elements - if (size == 1u && pathname[start_pos] == dot) - { - last_element_was_dot = true; - goto skip_append; - } - - last_element_was_dot = false; - - // Process dot dot elements - if (size == 2u && pathname[start_pos] == dot && pathname[start_pos + 1] == dot && normal.m_pathname.size() > root_path_size) - { - // Don't remove previous dot dot elements - const size_type normal_size = normal.m_pathname.size(); - size_type filename_size = find_filename_size(normal.m_pathname, root_path_size, normal_size); - size_type pos = normal_size - filename_size; - if (filename_size != 2u || normal.m_pathname[pos] != dot || normal.m_pathname[pos + 1] != dot) - { - if (pos > root_path_size && detail::is_directory_separator(normal.m_pathname[pos - 1])) - --pos; - normal.m_pathname.erase(normal.m_pathname.begin() + pos , normal.m_pathname.end()); - goto skip_append; - } - } - - // Append the element - normal.append_separator_if_needed(); - normal.m_pathname.append(pathname + start_pos, size); - } - - skip_append: - if (i == pathname_size) - break; - - // Skip directory separators, including duplicates - while (i < pathname_size && detail::is_directory_separator(pathname[i])) - ++i; - - if (i == pathname_size) - { - // If a path ends with a separator, add a trailing dot element - goto append_trailing_dot; - } - } - - if (normal.empty() || last_element_was_dot) - { - append_trailing_dot: - normal.append_separator_if_needed(); - normal.m_pathname.push_back(dot); - } - } - - return normal; -} - -BOOST_FILESYSTEM_DECL path path::lexically_normal_v4() const -{ - const value_type* const pathname = m_pathname.c_str(); - const size_type pathname_size = m_pathname.size(); - size_type root_name_size = 0; - size_type root_dir_pos = find_root_directory_start(pathname, pathname_size, root_name_size); - path normal(pathname, pathname + root_name_size); - -#if defined(BOOST_WINDOWS_API) - for (size_type i = 0; i < root_name_size; ++i) - { - if (normal.m_pathname[i] == path::separator) - normal.m_pathname[i] = path::preferred_separator; - } -#endif - - size_type root_path_size = root_name_size; - if (root_dir_pos < pathname_size) - { - root_path_size = root_dir_pos + 1; - normal.m_pathname.push_back(preferred_separator); - } - - size_type i = root_path_size; - - // Skip redundant directory separators after the root directory - while (i < pathname_size && detail::is_directory_separator(pathname[i])) - ++i; - - if (i < pathname_size) - { - while (true) - { - bool last_element_was_dot = false; - { - const size_type start_pos = i; - - // Find next separator - i += find_separator(pathname + i, pathname_size - i); - - const size_type size = i - start_pos; - - // Skip dot elements - if (size == 1u && pathname[start_pos] == dot) - { - last_element_was_dot = true; - goto skip_append; - } - - // Process dot dot elements - if (size == 2u && pathname[start_pos] == dot && pathname[start_pos + 1] == dot && normal.m_pathname.size() > root_path_size) - { - // Don't remove previous dot dot elements - const size_type normal_size = normal.m_pathname.size(); - size_type filename_size = find_filename_size(normal.m_pathname, root_path_size, normal_size); - size_type pos = normal_size - filename_size; - if (filename_size != 2u || normal.m_pathname[pos] != dot || normal.m_pathname[pos + 1] != dot) - { - if (pos > root_path_size && detail::is_directory_separator(normal.m_pathname[pos - 1])) - --pos; - normal.m_pathname.erase(normal.m_pathname.begin() + pos, normal.m_pathname.end()); - goto skip_append; - } - } - - // Append the element - normal.append_separator_if_needed(); - normal.m_pathname.append(pathname + start_pos, size); - } - - skip_append: - if (i == pathname_size) - { - // If a path ends with a trailing dot after a directory element, add a trailing separator - if (last_element_was_dot && !normal.empty() && !normal.filename_is_dot_dot()) - normal.append_separator_if_needed(); - - break; - } - - // Skip directory separators, including duplicates - while (i < pathname_size && detail::is_directory_separator(pathname[i])) - ++i; - - if (i == pathname_size) - { - // If a path ends with a separator, add a trailing separator - if (!normal.empty() && !normal.filename_is_dot_dot()) - normal.append_separator_if_needed(); - break; - } - } - - // If the original path was not empty and normalized ended up being empty, make it a dot - if (normal.empty()) - normal.m_pathname.push_back(dot); - } - - return normal; -} - -} // namespace filesystem -} // namespace boost - -//--------------------------------------------------------------------------------------// -// // -// class path helpers implementation // -// // -//--------------------------------------------------------------------------------------// - -namespace { - -// is_root_separator ---------------------------------------------------------------// - -// pos is position of the separator -inline bool is_root_separator(string_type const& str, size_type root_dir_pos, size_type pos) -{ - BOOST_ASSERT_MSG(pos < str.size() && fs::detail::is_directory_separator(str[pos]), "precondition violation"); - - // root_dir_pos points at the leftmost separator, we need to skip any duplicate separators right of root dir - while (pos > root_dir_pos && fs::detail::is_directory_separator(str[pos - 1])) - --pos; - - return pos == root_dir_pos; -} - -// find_filename_size --------------------------------------------------------------// - -// Returns: Size of the filename element that ends at end_pos (which is past-the-end position). 0 if no filename found. -inline size_type find_filename_size(string_type const& str, size_type root_name_size, size_type end_pos) -{ - size_type pos = end_pos; - while (pos > root_name_size) - { - --pos; - - if (fs::detail::is_directory_separator(str[pos])) - { - ++pos; // filename starts past the separator - break; - } - } - - return end_pos - pos; -} - -// find_root_directory_start -------------------------------------------------------// - -// Returns: starting position of root directory or size if not found -size_type find_root_directory_start(const value_type* path, size_type size, size_type& root_name_size) -{ - root_name_size = 0; - if (size == 0) - return 0; - - bool parsing_root_name = false; - size_type pos = 0; - - // case "//", possibly followed by more characters - if (fs::detail::is_directory_separator(path[0])) - { - if (size >= 2 && fs::detail::is_directory_separator(path[1])) - { - if (size == 2) - { - // The whole path is just a pair of separators - root_name_size = 2; - return 2; - } -#ifdef BOOST_WINDOWS_API - // https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file - // cases "\\?\" and "\\.\" - else if (size >= 4 && (path[2] == questionmark || path[2] == fs::path::dot) && fs::detail::is_directory_separator(path[3])) - { - parsing_root_name = true; - pos += 4; - } -#endif - else if (fs::detail::is_directory_separator(path[2])) - { - // The path starts with three directory separators, which is interpreted as a root directory followed by redundant separators - return 0; - } - else - { - // case "//net {/}" - parsing_root_name = true; - pos += 2; - goto find_next_separator; - } - } -#ifdef BOOST_WINDOWS_API - // https://stackoverflow.com/questions/23041983/path-prefixes-and - // case "\??\" (NT path prefix) - else if (size >= 4 && path[1] == questionmark && path[2] == questionmark && fs::detail::is_directory_separator(path[3])) - { - parsing_root_name = true; - pos += 4; - } -#endif - else - { - // The path starts with a separator, possibly followed by a non-separator character - return 0; - } - } - -#ifdef BOOST_WINDOWS_API - // case "c:" or "prn:" - // Note: There is ambiguity in a "c:x" path interpretation. It could either mean a file "x" located at the current directory for drive C:, - // or an alternative stream "x" of a file "c". Windows API resolve this as the former, and so do we. - if ((size - pos) >= 2 && fs::detail::is_letter(path[pos])) - { - size_type i = pos + 1; - for (; i < size; ++i) - { - if (!is_device_name_char(path[i])) - break; - } - - if (i < size && path[i] == colon) - { - pos = i + 1; - root_name_size = pos; - parsing_root_name = false; - - if (pos < size && fs::detail::is_directory_separator(path[pos])) - return pos; - } - } -#endif - - if (!parsing_root_name) - return size; - -find_next_separator: - pos += find_separator(path + pos, size - pos); - if (parsing_root_name) - root_name_size = pos; - - return pos; -} - -// first_element --------------------------------------------------------------------// - -// sets pos and len of first element, excluding extra separators -// if src.empty(), sets pos,len, to 0,0. -void first_element(string_type const& src, size_type& element_pos, size_type& element_size, size_type size) -{ - element_pos = 0; - element_size = 0; - if (src.empty()) - return; - - size_type root_name_size = 0; - size_type root_dir_pos = find_root_directory_start(src.c_str(), size, root_name_size); - - // First element is the root name, if there is one - if (root_name_size > 0) - { - element_size = root_name_size; - return; - } - - // Otherwise, the root directory - if (root_dir_pos < size) - { - element_pos = root_dir_pos; - element_size = 1u; - return; - } - - // Otherwise, the first filename or directory name in a relative path - size_type end_pos = src.find_first_of(separators); - if (end_pos == string_type::npos) - end_pos = src.size(); - element_size = end_pos; -} - -} // unnamed namespace - -namespace boost { -namespace filesystem { -namespace detail { - -BOOST_FILESYSTEM_DECL -int lex_compare_v3(path::iterator first1, path::iterator last1, path::iterator first2, path::iterator last2) -{ - for (; first1 != last1 && first2 != last2;) - { - if (first1->native() < first2->native()) - return -1; - if (first2->native() < first1->native()) - return 1; - BOOST_ASSERT(first2->native() == first1->native()); - first1.increment_v3(); - first2.increment_v3(); - } - if (first1 == last1 && first2 == last2) - return 0; - return first1 == last1 ? -1 : 1; -} - -BOOST_FILESYSTEM_DECL -int lex_compare_v4(path::iterator first1, path::iterator last1, path::iterator first2, path::iterator last2) -{ - for (; first1 != last1 && first2 != last2;) - { - if (first1->native() < first2->native()) - return -1; - if (first2->native() < first1->native()) - return 1; - BOOST_ASSERT(first2->native() == first1->native()); - ++first1; - ++first2; - } - if (first1 == last1 && first2 == last2) - return 0; - return first1 == last1 ? -1 : 1; -} - -} // namespace detail - -//--------------------------------------------------------------------------------------// -// // -// class path::iterator implementation // -// // -//--------------------------------------------------------------------------------------// - -BOOST_FILESYSTEM_DECL path::iterator path::begin() const -{ - iterator itr; - itr.m_path_ptr = this; - - size_type element_size; - first_element(m_pathname, itr.m_pos, element_size); - - if (element_size > 0) - { - itr.m_element = m_pathname.substr(itr.m_pos, element_size); -#ifdef BOOST_WINDOWS_API - if (itr.m_element.m_pathname.size() == 1u && itr.m_element.m_pathname[0] == preferred_separator) - itr.m_element.m_pathname[0] = separator; -#endif - } - - return itr; -} - -BOOST_FILESYSTEM_DECL path::iterator path::end() const -{ - iterator itr; - itr.m_path_ptr = this; - itr.m_pos = m_pathname.size(); - return itr; -} - -BOOST_FILESYSTEM_DECL void path::iterator::increment_v3() -{ - const size_type size = m_path_ptr->m_pathname.size(); - BOOST_ASSERT_MSG(m_pos < size, "path::iterator increment past end()"); - - // increment to position past current element; if current element is implicit dot, - // this will cause m_pos to represent the end iterator - m_pos += m_element.m_pathname.size(); - - // if the end is reached, we are done - if (m_pos >= size) - { - BOOST_ASSERT_MSG(m_pos == size, "path::iterator increment after the referenced path was modified"); - m_element.clear(); // aids debugging - return; - } - - // process separator (Windows drive spec is only case not a separator) - if (detail::is_directory_separator(m_path_ptr->m_pathname[m_pos])) - { - size_type root_name_size = 0; - size_type root_dir_pos = find_root_directory_start(m_path_ptr->m_pathname.c_str(), size, root_name_size); - - // detect root directory and set iterator value to the separator if it is - if (m_pos == root_dir_pos && m_element.m_pathname.size() == root_name_size) - { - m_element.m_pathname = separator; // generic format; see docs - return; - } - - // skip separators until m_pos points to the start of the next element - while (m_pos != size && detail::is_directory_separator(m_path_ptr->m_pathname[m_pos])) - { - ++m_pos; - } - - // detect trailing separator, and treat it as ".", per POSIX spec - if (m_pos == size && - !is_root_separator(m_path_ptr->m_pathname, root_dir_pos, m_pos - 1)) - { - --m_pos; - m_element = detail::dot_path(); - return; - } - } - - // get m_element - size_type end_pos = m_path_ptr->m_pathname.find_first_of(separators, m_pos); - if (end_pos == string_type::npos) - end_pos = size; - const path::value_type* p = m_path_ptr->m_pathname.c_str(); - m_element.m_pathname.assign(p + m_pos, p + end_pos); -} - -BOOST_FILESYSTEM_DECL void path::iterator::increment_v4() -{ - const size_type size = m_path_ptr->m_pathname.size(); - BOOST_ASSERT_MSG(m_pos <= size, "path::iterator increment past end()"); - - if (m_element.m_pathname.empty() && (m_pos + 1) == size && detail::is_directory_separator(m_path_ptr->m_pathname[m_pos])) - { - // The iterator was pointing to the last empty element of the path; set to end. - m_pos = size; - return; - } - - // increment to position past current element; if current element is implicit dot, - // this will cause m_pos to represent the end iterator - m_pos += m_element.m_pathname.size(); - - // if the end is reached, we are done - if (m_pos >= size) - { - BOOST_ASSERT_MSG(m_pos == size, "path::iterator increment after the referenced path was modified"); - m_element.clear(); // aids debugging - return; - } - - // process separator (Windows drive spec is only case not a separator) - if (detail::is_directory_separator(m_path_ptr->m_pathname[m_pos])) - { - size_type root_name_size = 0; - size_type root_dir_pos = find_root_directory_start(m_path_ptr->m_pathname.c_str(), size, root_name_size); - - // detect root directory and set iterator value to the separator if it is - if (m_pos == root_dir_pos && m_element.m_pathname.size() == root_name_size) - { - m_element.m_pathname = separator; // generic format; see docs - return; - } - - // skip separators until m_pos points to the start of the next element - while (m_pos != size && detail::is_directory_separator(m_path_ptr->m_pathname[m_pos])) - { - ++m_pos; - } - - // detect trailing separator - if (m_pos == size && - !is_root_separator(m_path_ptr->m_pathname, root_dir_pos, m_pos - 1)) - { - --m_pos; - m_element.m_pathname.clear(); - return; - } - } - - // get m_element - size_type end_pos = m_path_ptr->m_pathname.find_first_of(separators, m_pos); - if (end_pos == string_type::npos) - end_pos = size; - const path::value_type* p = m_path_ptr->m_pathname.c_str(); - m_element.m_pathname.assign(p + m_pos, p + end_pos); -} - -BOOST_FILESYSTEM_DECL void path::iterator::decrement_v3() -{ - const size_type size = m_path_ptr->m_pathname.size(); - BOOST_ASSERT_MSG(m_pos > 0, "path::iterator decrement past begin()"); - BOOST_ASSERT_MSG(m_pos <= size, "path::iterator decrement after the referenced path was modified"); - - size_type root_name_size = 0; - size_type root_dir_pos = find_root_directory_start(m_path_ptr->m_pathname.c_str(), size, root_name_size); - - if (root_dir_pos < size && m_pos == root_dir_pos) - { - // Was pointing at root directory, decrement to root name - set_to_root_name: - m_pos = 0u; - const path::value_type* p = m_path_ptr->m_pathname.c_str(); - m_element.m_pathname.assign(p, p + root_name_size); - return; - } - - // if at end and there was a trailing non-root '/', return "." - if (m_pos == size && - size > 1 && - detail::is_directory_separator(m_path_ptr->m_pathname[m_pos - 1]) && - !is_root_separator(m_path_ptr->m_pathname, root_dir_pos, m_pos - 1)) - { - --m_pos; - m_element = detail::dot_path(); - return; - } - - // skip separators unless root directory - size_type end_pos = m_pos; - while (end_pos > root_name_size) - { - --end_pos; - - if (end_pos == root_dir_pos) - { - // Decremented to the root directory - m_pos = end_pos; - m_element.m_pathname = separator; // generic format; see docs - return; - } - - if (!detail::is_directory_separator(m_path_ptr->m_pathname[end_pos])) - { - ++end_pos; - break; - } - } - - if (end_pos <= root_name_size) - goto set_to_root_name; - - size_type filename_size = find_filename_size(m_path_ptr->m_pathname, root_name_size, end_pos); - m_pos = end_pos - filename_size; - const path::value_type* p = m_path_ptr->m_pathname.c_str(); - m_element.m_pathname.assign(p + m_pos, p + end_pos); -} - -BOOST_FILESYSTEM_DECL void path::iterator::decrement_v4() -{ - const size_type size = m_path_ptr->m_pathname.size(); - BOOST_ASSERT_MSG(m_pos > 0, "path::iterator decrement past begin()"); - BOOST_ASSERT_MSG(m_pos <= size, "path::iterator decrement after the referenced path was modified"); - - size_type root_name_size = 0; - size_type root_dir_pos = find_root_directory_start(m_path_ptr->m_pathname.c_str(), size, root_name_size); - - if (root_dir_pos < size && m_pos == root_dir_pos) - { - // Was pointing at root directory, decrement to root name - set_to_root_name: - m_pos = 0u; - const path::value_type* p = m_path_ptr->m_pathname.c_str(); - m_element.m_pathname.assign(p, p + root_name_size); - return; - } - - // if at end and there was a trailing '/', return "" - if (m_pos == size && - size > 1 && - detail::is_directory_separator(m_path_ptr->m_pathname[m_pos - 1]) && - !is_root_separator(m_path_ptr->m_pathname, root_dir_pos, m_pos - 1)) - { - --m_pos; - m_element.m_pathname.clear(); - return; - } - - // skip separators unless root directory - size_type end_pos = m_pos; - while (end_pos > root_name_size) - { - --end_pos; - - if (end_pos == root_dir_pos) - { - // Decremented to the root directory - m_pos = end_pos; - m_element.m_pathname = separator; // generic format; see docs - return; - } - - if (!detail::is_directory_separator(m_path_ptr->m_pathname[end_pos])) - { - ++end_pos; - break; - } - } - - if (end_pos <= root_name_size) - goto set_to_root_name; - - size_type filename_size = find_filename_size(m_path_ptr->m_pathname, root_name_size, end_pos); - m_pos = end_pos - filename_size; - const path::value_type* p = m_path_ptr->m_pathname.c_str(); - m_element.m_pathname.assign(p + m_pos, p + end_pos); -} - -} // namespace filesystem -} // namespace boost - -namespace { - -//------------------------------------------------------------------------------------// -// locale helpers // -//------------------------------------------------------------------------------------// - -// Prior versions of these locale and codecvt implementations tried to take advantage -// of static initialization where possible, kept a local copy of the current codecvt -// facet (to avoid codecvt() having to call use_facet()), and was not multi-threading -// safe (again for efficiency). -// -// This was error prone, and required different implementation techniques depending -// on the compiler and also whether static or dynamic linking was used. Furthermore, -// users could not easily provide their multi-threading safe wrappers because the -// path interface requires the implementation itself to call codecvt() to obtain the -// default facet, and the initialization of the static within path_locale() could race. -// -// The code below is portable to all platforms, is much simpler, and hopefully will be -// much more robust. Timing tests (on Windows, using a Visual C++ release build) -// indicated the current code is roughly 9% slower than the previous code, and that -// seems a small price to pay for better code that is easier to use. - -std::locale default_locale() -{ -#if defined(BOOST_WINDOWS_API) - std::locale global_loc = std::locale(); - return std::locale(global_loc, new boost::filesystem::detail::windows_file_codecvt()); -#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__HAIKU__) - // "All BSD system functions expect their string parameters to be in UTF-8 encoding - // and nothing else." See - // http://developer.apple.com/mac/library/documentation/MacOSX/Conceptual/BPInternational/Articles/FileEncodings.html - // - // "The kernel will reject any filename that is not a valid UTF-8 string, and it will - // even be normalized (to Unicode NFD) before stored on disk, at least when using HFS. - // The right way to deal with it would be to always convert the filename to UTF-8 - // before trying to open/create a file." See - // http://lists.apple.com/archives/unix-porting/2007/Sep/msg00023.html - // - // "How a file name looks at the API level depends on the API. Current Carbon APIs - // handle file names as an array of UTF-16 characters; POSIX ones handle them as an - // array of UTF-8, which is why UTF-8 works well in Terminal. How it's stored on disk - // depends on the disk format; HFS+ uses UTF-16, but that's not important in most - // cases." See - // http://lists.apple.com/archives/applescript-users/2002/Sep/msg00319.html - // - // Many thanks to Peter Dimov for digging out the above references! - - std::locale global_loc = std::locale(); - return std::locale(global_loc, new boost::filesystem::detail::utf8_codecvt_facet()); -#else // Other POSIX - // ISO C calls std::locale("") "the locale-specific native environment", and this - // locale is the default for many POSIX-based operating systems such as Linux. - return std::locale(""); -#endif -} - -std::locale* g_path_locale = NULL; - -void schedule_path_locale_cleanup() BOOST_NOEXCEPT; - -// std::locale("") construction, needed on non-Apple POSIX systems, can throw -// (if environmental variables LC_MESSAGES or LANG are wrong, for example), so -// get_path_locale() provides lazy initialization to ensure that any -// exceptions occur after main() starts and so can be caught. Furthermore, -// g_path_locale is only initialized if path::codecvt() or path::imbue() are themselves -// actually called, ensuring that an exception will only be thrown if std::locale("") -// is really needed. -inline std::locale& get_path_locale() -{ -#if !defined(BOOST_FILESYSTEM_SINGLE_THREADED) - atomic_ns::atomic_ref< std::locale* > a(g_path_locale); - std::locale* p = a.load(atomic_ns::memory_order_acquire); - if (BOOST_UNLIKELY(!p)) - { - std::locale* new_p = new std::locale(default_locale()); - if (a.compare_exchange_strong(p, new_p, atomic_ns::memory_order_acq_rel, atomic_ns::memory_order_acquire)) - { - p = new_p; - schedule_path_locale_cleanup(); - } - else - { - delete new_p; - } - } - return *p; -#else // !defined(BOOST_FILESYSTEM_SINGLE_THREADED) - std::locale* p = g_path_locale; - if (BOOST_UNLIKELY(!p)) - { - g_path_locale = p = new std::locale(default_locale()); - schedule_path_locale_cleanup(); - } - return *p; -#endif // !defined(BOOST_FILESYSTEM_SINGLE_THREADED) -} - -inline std::locale* replace_path_locale(std::locale const& loc) -{ - std::locale* new_p = new std::locale(loc); -#if !defined(BOOST_FILESYSTEM_SINGLE_THREADED) - std::locale* p = atomic_ns::atomic_ref< std::locale* >(g_path_locale).exchange(new_p, atomic_ns::memory_order_acq_rel); -#else - std::locale* p = g_path_locale; - g_path_locale = new_p; -#endif - if (!p) - schedule_path_locale_cleanup(); - return p; -} - -#if defined(_MSC_VER) - -const boost::filesystem::path* g_dot_path = NULL; -const boost::filesystem::path* g_dot_dot_path = NULL; - -inline void schedule_path_locale_cleanup() BOOST_NOEXCEPT -{ -} - -inline boost::filesystem::path const& get_dot_path() -{ -#if !defined(BOOST_FILESYSTEM_SINGLE_THREADED) - atomic_ns::atomic_ref< const boost::filesystem::path* > a(g_dot_path); - const boost::filesystem::path* p = a.load(atomic_ns::memory_order_acquire); - if (BOOST_UNLIKELY(!p)) - { - const boost::filesystem::path* new_p = new boost::filesystem::path(dot_path_literal); - if (a.compare_exchange_strong(p, new_p, atomic_ns::memory_order_acq_rel, atomic_ns::memory_order_acquire)) - p = new_p; - else - delete new_p; - } - return *p; -#else // !defined(BOOST_FILESYSTEM_SINGLE_THREADED) - const boost::filesystem::path* p = g_dot_path; - if (BOOST_UNLIKELY(!p)) - g_dot_path = p = new boost::filesystem::path(dot_path_literal); - return *p; -#endif // !defined(BOOST_FILESYSTEM_SINGLE_THREADED) -} - -inline boost::filesystem::path const& get_dot_dot_path() -{ -#if !defined(BOOST_FILESYSTEM_SINGLE_THREADED) - atomic_ns::atomic_ref< const boost::filesystem::path* > a(g_dot_dot_path); - const boost::filesystem::path* p = a.load(atomic_ns::memory_order_acquire); - if (BOOST_UNLIKELY(!p)) - { - const boost::filesystem::path* new_p = new boost::filesystem::path(dot_dot_path_literal); - if (a.compare_exchange_strong(p, new_p, atomic_ns::memory_order_acq_rel, atomic_ns::memory_order_acquire)) - p = new_p; - else - delete new_p; - } - return *p; -#else // !defined(BOOST_FILESYSTEM_SINGLE_THREADED) - const boost::filesystem::path* p = g_dot_dot_path; - if (BOOST_UNLIKELY(!p)) - g_dot_dot_path = p = new boost::filesystem::path(dot_dot_path_literal); - return *p; -#endif // !defined(BOOST_FILESYSTEM_SINGLE_THREADED) -} - -void __cdecl destroy_path_globals() -{ - delete g_dot_dot_path; - g_dot_dot_path = NULL; - delete g_dot_path; - g_dot_path = NULL; - delete g_path_locale; - g_path_locale = NULL; -} - -BOOST_FILESYSTEM_INIT_FUNC init_path_globals() -{ -#if !defined(BOOST_SYSTEM_HAS_CONSTEXPR) - // codecvt_error_category needs to be called early to dynamic-initialize the error category instance - boost::filesystem::codecvt_error_category(); -#endif - std::atexit(&destroy_path_globals); - return BOOST_FILESYSTEM_INITRETSUCCESS_V; -} - -#if _MSC_VER >= 1400 - -#pragma section(".CRT$XCM", long, read) -__declspec(allocate(".CRT$XCM")) BOOST_ATTRIBUTE_UNUSED BOOST_FILESYSTEM_ATTRIBUTE_RETAIN -extern const init_func_ptr_t p_init_path_globals = &init_path_globals; - -#else // _MSC_VER >= 1400 - -#if (_MSC_VER >= 1300) // 1300 == VC++ 7.0 -#pragma data_seg(push, old_seg) -#endif -#pragma data_seg(".CRT$XCM") -BOOST_ATTRIBUTE_UNUSED BOOST_FILESYSTEM_ATTRIBUTE_RETAIN -extern const init_func_ptr_t p_init_path_globals = &init_path_globals; -#pragma data_seg() -#if (_MSC_VER >= 1300) // 1300 == VC++ 7.0 -#pragma data_seg(pop, old_seg) -#endif - -#endif // _MSC_VER >= 1400 - -#if defined(BOOST_FILESYSTEM_NO_ATTRIBUTE_RETAIN) -//! Makes sure the global initializer pointers are referenced and not removed by linker -struct globals_retainer -{ - const init_func_ptr_t* volatile m_p_init_path_globals; - - globals_retainer() { m_p_init_path_globals = &p_init_path_globals; } -}; -BOOST_ATTRIBUTE_UNUSED -static const globals_retainer g_globals_retainer; -#endif // defined(BOOST_FILESYSTEM_NO_ATTRIBUTE_RETAIN) - -#else // defined(_MSC_VER) - -struct path_locale_deleter -{ - ~path_locale_deleter() - { - delete g_path_locale; - g_path_locale = NULL; - } -}; - -#if defined(BOOST_FILESYSTEM_HAS_INIT_PRIORITY) - -BOOST_FILESYSTEM_INIT_PRIORITY(BOOST_FILESYSTEM_PATH_GLOBALS_INIT_PRIORITY) BOOST_ATTRIBUTE_UNUSED -const path_locale_deleter g_path_locale_deleter = {}; -BOOST_FILESYSTEM_INIT_PRIORITY(BOOST_FILESYSTEM_PATH_GLOBALS_INIT_PRIORITY) -const boost::filesystem::path g_dot_path(dot_path_literal); -BOOST_FILESYSTEM_INIT_PRIORITY(BOOST_FILESYSTEM_PATH_GLOBALS_INIT_PRIORITY) -const boost::filesystem::path g_dot_dot_path(dot_dot_path_literal); - -inline void schedule_path_locale_cleanup() BOOST_NOEXCEPT -{ -} - -inline boost::filesystem::path const& get_dot_path() -{ - return g_dot_path; -} - -inline boost::filesystem::path const& get_dot_dot_path() -{ - return g_dot_dot_path; -} - -#else // defined(BOOST_FILESYSTEM_HAS_INIT_PRIORITY) - -inline void schedule_path_locale_cleanup() BOOST_NOEXCEPT -{ - BOOST_ATTRIBUTE_UNUSED static const path_locale_deleter g_path_locale_deleter; -} - -inline boost::filesystem::path const& get_dot_path() -{ - static const boost::filesystem::path g_dot_path(dot_path_literal); - return g_dot_path; -} - -inline boost::filesystem::path const& get_dot_dot_path() -{ - static const boost::filesystem::path g_dot_dot_path(dot_dot_path_literal); - return g_dot_dot_path; -} - -#endif // defined(BOOST_FILESYSTEM_HAS_INIT_PRIORITY) - -#endif // defined(_MSC_VER) - -} // unnamed namespace - -//--------------------------------------------------------------------------------------// -// path::codecvt() and path::imbue() implementation // -//--------------------------------------------------------------------------------------// - -namespace boost { -namespace filesystem { - -BOOST_FILESYSTEM_DECL path::codecvt_type const& path::codecvt() -{ -#ifdef BOOST_FILESYSTEM_DEBUG - std::cout << "***** path::codecvt() called" << std::endl; -#endif - return std::use_facet< std::codecvt< wchar_t, char, std::mbstate_t > >(get_path_locale()); -} - -BOOST_FILESYSTEM_DECL std::locale path::imbue(std::locale const& loc) -{ -#ifdef BOOST_FILESYSTEM_DEBUG - std::cout << "***** path::imbue() called" << std::endl; -#endif - std::locale* p = replace_path_locale(loc); - if (BOOST_LIKELY(p != NULL)) - { - // Note: copying/moving std::locale does not throw -#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) - std::locale temp(std::move(*p)); -#else - std::locale temp(*p); -#endif - delete p; - return temp; - } - - return default_locale(); -} - -namespace detail { - -BOOST_FILESYSTEM_DECL path const& dot_path() -{ - return get_dot_path(); -} - -BOOST_FILESYSTEM_DECL path const& dot_dot_path() -{ - return get_dot_dot_path(); -} - -} // namespace detail -} // namespace filesystem -} // namespace boost - -#include <boost/filesystem/detail/footer.hpp> diff --git a/contrib/restricted/boost/filesystem/src/path_traits.cpp b/contrib/restricted/boost/filesystem/src/path_traits.cpp deleted file mode 100644 index aa4b8815f7..0000000000 --- a/contrib/restricted/boost/filesystem/src/path_traits.cpp +++ /dev/null @@ -1,201 +0,0 @@ -// filesystem path_traits.cpp --------------------------------------------------------// - -// Copyright Beman Dawes 2008, 2009 - -// Distributed under the Boost Software License, Version 1.0. -// See http://www.boost.org/LICENSE_1_0.txt - -// Library home page: http://www.boost.org/libs/filesystem - -//--------------------------------------------------------------------------------------// - -#include "platform_config.hpp" - -#include <boost/filesystem/config.hpp> -#include <boost/filesystem/path_traits.hpp> -#include <boost/system/system_error.hpp> -#include <boost/smart_ptr/scoped_array.hpp> -#include <boost/assert.hpp> -#include <string> -#include <locale> // for codecvt_base::result -#include <cstring> // for strlen -#include <cwchar> // for wcslen -#include <cstddef> - -#include <boost/filesystem/detail/header.hpp> // must be the last #include - -namespace pt = boost::filesystem::path_traits; -namespace fs = boost::filesystem; -namespace bs = boost::system; - -//--------------------------------------------------------------------------------------// -// configuration // -//--------------------------------------------------------------------------------------// - -#ifndef BOOST_FILESYSTEM_CODECVT_BUF_SIZE -#define BOOST_FILESYSTEM_CODECVT_BUF_SIZE 256 -#endif - -namespace { - -BOOST_CONSTEXPR_OR_CONST std::size_t default_codecvt_buf_size = BOOST_FILESYSTEM_CODECVT_BUF_SIZE; - -//--------------------------------------------------------------------------------------// -// // -// The public convert() functions do buffer management, and then forward to the // -// convert_aux() functions for the actual call to the codecvt facet. // -// // -//--------------------------------------------------------------------------------------// - -//--------------------------------------------------------------------------------------// -// convert_aux const char* to wstring // -//--------------------------------------------------------------------------------------// - -void convert_aux( - const char* from, - const char* from_end, - wchar_t* to, wchar_t* to_end, - std::wstring& target, - pt::codecvt_type const& cvt) -{ - //std::cout << std::hex - // << " from=" << std::size_t(from) - // << " from_end=" << std::size_t(from_end) - // << " to=" << std::size_t(to) - // << " to_end=" << std::size_t(to_end) - // << std::endl; - - std::mbstate_t state = std::mbstate_t(); // perhaps unneeded, but cuts bug reports - const char* from_next; - wchar_t* to_next; - - std::codecvt_base::result res; - - if ((res = cvt.in(state, from, from_end, from_next, to, to_end, to_next)) != std::codecvt_base::ok) - { - //std::cout << " result is " << static_cast<int>(res) << std::endl; - BOOST_FILESYSTEM_THROW(bs::system_error(res, fs::codecvt_error_category(), "boost::filesystem::path codecvt to wstring")); - } - target.append(to, to_next); -} - -//--------------------------------------------------------------------------------------// -// convert_aux const wchar_t* to string // -//--------------------------------------------------------------------------------------// - -void convert_aux( - const wchar_t* from, - const wchar_t* from_end, - char* to, char* to_end, - std::string& target, - pt::codecvt_type const& cvt) -{ - //std::cout << std::hex - // << " from=" << std::size_t(from) - // << " from_end=" << std::size_t(from_end) - // << " to=" << std::size_t(to) - // << " to_end=" << std::size_t(to_end) - // << std::endl; - - std::mbstate_t state = std::mbstate_t(); // perhaps unneeded, but cuts bug reports - const wchar_t* from_next; - char* to_next; - - std::codecvt_base::result res; - - if ((res = cvt.out(state, from, from_end, from_next, to, to_end, to_next)) != std::codecvt_base::ok) - { - //std::cout << " result is " << static_cast<int>(res) << std::endl; - BOOST_FILESYSTEM_THROW(bs::system_error(res, fs::codecvt_error_category(), "boost::filesystem::path codecvt to string")); - } - target.append(to, to_next); -} - -} // unnamed namespace - -//--------------------------------------------------------------------------------------// -// path_traits // -//--------------------------------------------------------------------------------------// - -namespace boost { -namespace filesystem { -namespace path_traits { - -//--------------------------------------------------------------------------------------// -// convert const char* to wstring // -//--------------------------------------------------------------------------------------// - -BOOST_FILESYSTEM_DECL -void convert(const char* from, - const char* from_end, // 0 for null terminated MBCS - std::wstring& to, codecvt_type const& cvt) -{ - BOOST_ASSERT(from); - - if (!from_end) // null terminated - { - from_end = from + std::strlen(from); - } - - if (from == from_end) - return; - - std::size_t buf_size = (from_end - from) * 3; // perhaps too large, but that's OK - - // dynamically allocate a buffer only if source is unusually large - if (buf_size > default_codecvt_buf_size) - { - boost::scoped_array< wchar_t > buf(new wchar_t[buf_size]); - convert_aux(from, from_end, buf.get(), buf.get() + buf_size, to, cvt); - } - else - { - wchar_t buf[default_codecvt_buf_size]; - convert_aux(from, from_end, buf, buf + default_codecvt_buf_size, to, cvt); - } -} - -//--------------------------------------------------------------------------------------// -// convert const wchar_t* to string // -//--------------------------------------------------------------------------------------// - -BOOST_FILESYSTEM_DECL -void convert(const wchar_t* from, - const wchar_t* from_end, // 0 for null terminated MBCS - std::string& to, codecvt_type const& cvt) -{ - BOOST_ASSERT(from); - - if (!from_end) // null terminated - { - from_end = from + std::wcslen(from); - } - - if (from == from_end) - return; - - // The codecvt length functions may not be implemented, and I don't really - // understand them either. Thus this code is just a guess; if it turns - // out the buffer is too small then an error will be reported and the code - // will have to be fixed. - std::size_t buf_size = (from_end - from) * 4; // perhaps too large, but that's OK - buf_size += 4; // encodings like shift-JIS need some prefix space - - // dynamically allocate a buffer only if source is unusually large - if (buf_size > default_codecvt_buf_size) - { - boost::scoped_array< char > buf(new char[buf_size]); - convert_aux(from, from_end, buf.get(), buf.get() + buf_size, to, cvt); - } - else - { - char buf[default_codecvt_buf_size]; - convert_aux(from, from_end, buf, buf + default_codecvt_buf_size, to, cvt); - } -} - -} // namespace path_traits -} // namespace filesystem -} // namespace boost - -#include <boost/filesystem/detail/footer.hpp> diff --git a/contrib/restricted/boost/filesystem/src/platform_config.hpp b/contrib/restricted/boost/filesystem/src/platform_config.hpp deleted file mode 100644 index 941338b0a7..0000000000 --- a/contrib/restricted/boost/filesystem/src/platform_config.hpp +++ /dev/null @@ -1,83 +0,0 @@ -// platform_config.hpp --------------------------------------------------------------------// - -// Copyright 2020 Andrey Semashev - -// Distributed under the Boost Software License, Version 1.0. -// See http://www.boost.org/LICENSE_1_0.txt - -// See library home page at http://www.boost.org/libs/filesystem - -#ifndef BOOST_FILESYSTEM_PLATFORM_CONFIG_HPP_ -#define BOOST_FILESYSTEM_PLATFORM_CONFIG_HPP_ - -// define 64-bit offset macros BEFORE including boost/config.hpp (see ticket #5355) -#if defined(__ANDROID__) && defined(__ANDROID_API__) && __ANDROID_API__ < 24 -// Android fully supports 64-bit file offsets only for API 24 and above. -// -// Trying to define _FILE_OFFSET_BITS=64 for APIs below 24 -// leads to compilation failure for one or another reason, -// depending on target Android API level, Android NDK version, -// used STL, order of include paths and more. -// For more information, please see: -// - https://github.com/boostorg/filesystem/issues/65 -// - https://github.com/boostorg/filesystem/pull/69 -// -// Android NDK developers consider it the expected behavior. -// See their official position here: -// - https://github.com/android-ndk/ndk/issues/501#issuecomment-326447479 -// - https://android.googlesource.com/platform/bionic/+/a34817457feee026e8702a1d2dffe9e92b51d7d1/docs/32-bit-abi.md#32_bit-abi-bugs -// -// Thus we do not define _FILE_OFFSET_BITS in such case. -#else -// Defining _FILE_OFFSET_BITS=64 should kick in 64-bit off_t's -// (and thus st_size) on 32-bit systems that provide the Large File -// Support (LFS) interface, such as Linux, Solaris, and IRIX. -// -// At the time of this comment writing (March 2018), on most systems -// _FILE_OFFSET_BITS=64 definition is harmless: -// either the definition is supported and enables 64-bit off_t, -// or the definition is not supported and is ignored, in which case -// off_t does not change its default size for the target system -// (which may be 32-bit or 64-bit already). -// Thus it makes sense to have _FILE_OFFSET_BITS=64 defined by default, -// instead of listing every system that supports the definition. -// Those few systems, on which _FILE_OFFSET_BITS=64 is harmful, -// for example this definition causes compilation failure on those systems, -// should be exempt from defining _FILE_OFFSET_BITS by adding -// an appropriate #elif block above with the appropriate comment. -// -// _FILE_OFFSET_BITS must be defined before any headers are included -// to ensure that the definition is available to all included headers. -// That is required at least on Solaris, and possibly on other -// systems as well. -#define _FILE_OFFSET_BITS 64 -#endif - -#if defined(__APPLE__) || defined(__MACH__) -// Enable newer ABI on Mac OS 10.5 and later, which is needed for struct stat to have birthtime members -#define _DARWIN_USE_64_BIT_INODE 1 -#endif - -#ifndef _POSIX_PTHREAD_SEMANTICS -#define _POSIX_PTHREAD_SEMANTICS // Sun readdir_r() needs this -#endif - -#if !defined(_INCLUDE_STDCSOURCE_199901) && (defined(hpux) || defined(_hpux) || defined(__hpux)) -// For HP-UX, request that WCHAR_MAX and WCHAR_MIN be defined as macros, -// not casts. See ticket 5048 -#define _INCLUDE_STDCSOURCE_199901 -#endif - -#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(__TOS_WIN__) || defined(__WINDOWS__) || \ - defined(__CYGWIN__) -// Define target Windows version macros before including any other headers -#include <boost/winapi/config.hpp> -#endif - -#ifndef BOOST_SYSTEM_NO_DEPRECATED -#define BOOST_SYSTEM_NO_DEPRECATED -#endif - -#include <boost/filesystem/config.hpp> - -#endif // BOOST_FILESYSTEM_PLATFORM_CONFIG_HPP_ diff --git a/contrib/restricted/boost/filesystem/src/portability.cpp b/contrib/restricted/boost/filesystem/src/portability.cpp deleted file mode 100644 index 8e0e2e5d98..0000000000 --- a/contrib/restricted/boost/filesystem/src/portability.cpp +++ /dev/null @@ -1,83 +0,0 @@ -// portability.cpp -------------------------------------------------------------------// - -// Copyright 2002-2005 Beman Dawes -// Use, modification, and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy -// at http://www.boost.org/LICENSE_1_0.txt) - -// See library home page at http://www.boost.org/libs/filesystem - -//--------------------------------------------------------------------------------------// - -#include "platform_config.hpp" - -#include <boost/filesystem/config.hpp> -#include <boost/filesystem/path.hpp> - -#include <cstring> // SGI MIPSpro compilers need this -#include <string> - -#include <boost/filesystem/detail/header.hpp> // must be the last #include - -namespace boost { -namespace filesystem { - -namespace { - -BOOST_CONSTEXPR_OR_CONST char windows_invalid_chars[] = - "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" - "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F" - "<>:\"/\\|"; - -BOOST_CONSTEXPR_OR_CONST char posix_valid_chars[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._-"; - -} // unnamed namespace - -// name_check functions ----------------------------------------------// - -#ifdef BOOST_WINDOWS -BOOST_FILESYSTEM_DECL bool native(std::string const& name) -{ - return windows_name(name); -} -#else -BOOST_FILESYSTEM_DECL bool native(std::string const& name) -{ - return !name.empty() && name[0] != ' ' && name.find('/') == std::string::npos; -} -#endif - -BOOST_FILESYSTEM_DECL bool portable_posix_name(std::string const& name) -{ - return !name.empty() && name.find_first_not_of(posix_valid_chars, 0, sizeof(posix_valid_chars) - 1) == std::string::npos; -} - -BOOST_FILESYSTEM_DECL bool windows_name(std::string const& name) -{ - // note that the terminating '\0' is part of the string - thus the size below - // is sizeof(windows_invalid_chars) rather than sizeof(windows_invalid_chars)-1. - return !name.empty() && name[0] != ' ' && name.find_first_of(windows_invalid_chars, 0, sizeof(windows_invalid_chars)) == std::string::npos - && *(name.end() - 1) != ' ' && (*(name.end() - 1) != '.' || name.size() == 1 || name == ".."); -} - -BOOST_FILESYSTEM_DECL bool portable_name(std::string const& name) -{ - return !name.empty() && (name == "." || name == ".." || (windows_name(name) && portable_posix_name(name) && name[0] != '.' && name[0] != '-')); -} - -BOOST_FILESYSTEM_DECL bool portable_directory_name(std::string const& name) -{ - return name == "." || name == ".." || (portable_name(name) && name.find('.') == std::string::npos); -} - -BOOST_FILESYSTEM_DECL bool portable_file_name(std::string const& name) -{ - std::string::size_type pos; - return portable_name(name) && name != "." && name != ".." && ((pos = name.find('.')) == std::string::npos || (name.find('.', pos + 1) == std::string::npos && (pos + 5) > name.size())); -} - -} // namespace filesystem -} // namespace boost - -#include <boost/filesystem/detail/footer.hpp> diff --git a/contrib/restricted/boost/filesystem/src/posix_tools.hpp b/contrib/restricted/boost/filesystem/src/posix_tools.hpp deleted file mode 100644 index 52cd87b0a0..0000000000 --- a/contrib/restricted/boost/filesystem/src/posix_tools.hpp +++ /dev/null @@ -1,81 +0,0 @@ -// posix_tools.hpp -------------------------------------------------------------------// - -// Copyright 2021 Andrey Semashev - -// Distributed under the Boost Software License, Version 1.0. -// See http://www.boost.org/LICENSE_1_0.txt - -// See library home page at http://www.boost.org/libs/filesystem - -//--------------------------------------------------------------------------------------// - -#ifndef BOOST_FILESYSTEM_SRC_POSIX_TOOLS_HPP_ -#define BOOST_FILESYSTEM_SRC_POSIX_TOOLS_HPP_ - -#include "platform_config.hpp" -#include <cerrno> -#include <boost/filesystem/config.hpp> -#ifdef BOOST_HAS_UNISTD_H -#include <unistd.h> -#endif - -#include <boost/filesystem/detail/header.hpp> // must be the last #include - -namespace boost { -namespace filesystem { -namespace detail { - -//! Platform-specific parameters for directory iterator construction -struct directory_iterator_params -{ -#if defined(BOOST_FILESYSTEM_HAS_POSIX_AT_APIS) - //! File descriptor of the base directory relative to which to interpret relative paths - int basedir_fd; -#endif -#if defined(BOOST_FILESYSTEM_HAS_FDOPENDIR_NOFOLLOW) - //! File descriptor of the directory over which the iterator iterates - int iterator_fd; -#endif -}; - -/*! - * Closes a file descriptor and returns the result, similar to close(2). Unlike close(2), guarantees that the file descriptor is closed even if EINTR error happens. - * - * Some systems don't close the file descriptor in case if the thread is interrupted by a signal and close(2) returns EINTR. - * Other (most) systems do close the file descriptor even when when close(2) returns EINTR, and attempting to close it - * again could close a different file descriptor that was opened by a different thread. This function hides this difference in behavior. - * - * Future POSIX standards will likely fix this by introducing posix_close (see https://www.austingroupbugs.net/view.php?id=529) - * and prohibiting returning EINTR from close(2), but we still have to support older systems where this new behavior is not available and close(2) - * behaves differently between systems. - */ -inline int close_fd(int fd) -{ -#if defined(hpux) || defined(_hpux) || defined(__hpux) - int res; - while (true) - { - res = ::close(fd); - if (BOOST_UNLIKELY(res < 0)) - { - int err = errno; - if (err == EINTR) - continue; - } - - break; - } - - return res; -#else - return ::close(fd); -#endif -} - -} // namespace detail -} // namespace filesystem -} // namespace boost - -#include <boost/filesystem/detail/footer.hpp> - -#endif // BOOST_FILESYSTEM_SRC_POSIX_TOOLS_HPP_ diff --git a/contrib/restricted/boost/filesystem/src/private_config.hpp b/contrib/restricted/boost/filesystem/src/private_config.hpp deleted file mode 100644 index c58d245ee1..0000000000 --- a/contrib/restricted/boost/filesystem/src/private_config.hpp +++ /dev/null @@ -1,74 +0,0 @@ -// private_config.hpp ----------------------------------------------------------------// - -// Copyright 2021 Andrey Semashev - -// Distributed under the Boost Software License, Version 1.0. -// See http://www.boost.org/LICENSE_1_0.txt - -// See library home page at http://www.boost.org/libs/filesystem - -//--------------------------------------------------------------------------------------// - -#ifndef BOOST_FILESYSTEM_SRC_PRIVATE_CONFIG_HPP_ -#define BOOST_FILESYSTEM_SRC_PRIVATE_CONFIG_HPP_ - -#include <boost/filesystem/config.hpp> - -#if defined(BOOST_FILESYSTEM_HAS_INIT_PRIORITY) -#define BOOST_FILESYSTEM_INIT_PRIORITY(n) __attribute__ ((init_priority(n))) -#else -#define BOOST_FILESYSTEM_INIT_PRIORITY(n) -#endif - -// According to https://gcc.gnu.org/bugzilla//show_bug.cgi?id=65115, -// the default C++ object initializers priority is 65535. We would like to -// initialize function pointers earlier than that (with lower priority values), -// before the other global objects initializers are run. Other than this, -// these priority values are arbitrary. -#define BOOST_FILESYSTEM_FUNC_PTR_INIT_PRIORITY 32767 - -// Path globals initialization priority -#define BOOST_FILESYSTEM_PATH_GLOBALS_INIT_PRIORITY 32768 - -#if defined(__has_feature) && defined(__has_attribute) -#if __has_feature(memory_sanitizer) && __has_attribute(no_sanitize) -#define BOOST_FILESYSTEM_NO_SANITIZE_MEMORY __attribute__ ((no_sanitize("memory"))) -#endif -#endif // defined(__has_feature) && defined(__has_attribute) - -#ifndef BOOST_FILESYSTEM_NO_SANITIZE_MEMORY -#define BOOST_FILESYSTEM_NO_SANITIZE_MEMORY -#endif - -#if defined(_MSC_VER) -#if _MSC_VER < 1300 || _MSC_VER > 1900 // 1300 == VC++ 7.0, 1900 == VC++ 14.0 -typedef void (__cdecl* init_func_ptr_t)(); -#define BOOST_FILESYSTEM_INITRETSUCCESS_V -#define BOOST_FILESYSTEM_INIT_FUNC void __cdecl -#else -typedef int (__cdecl* init_func_ptr_t)(); -#define BOOST_FILESYSTEM_INITRETSUCCESS_V 0 -#define BOOST_FILESYSTEM_INIT_FUNC int __cdecl -#endif -#else // defined(_MSC_VER) -typedef void (*init_func_ptr_t)(); -#define BOOST_FILESYSTEM_INITRETSUCCESS_V -#define BOOST_FILESYSTEM_INIT_FUNC void -#endif // defined(_MSC_VER) - -#if defined(__has_attribute) -#if __has_attribute(__used__) -#define BOOST_FILESYSTEM_ATTRIBUTE_RETAIN __attribute__ ((__used__)) -#endif -#endif - -#if !defined(BOOST_FILESYSTEM_ATTRIBUTE_RETAIN) && defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 402 -#define BOOST_FILESYSTEM_ATTRIBUTE_RETAIN __attribute__ ((__used__)) -#endif - -#if !defined(BOOST_FILESYSTEM_ATTRIBUTE_RETAIN) -#define BOOST_FILESYSTEM_NO_ATTRIBUTE_RETAIN -#define BOOST_FILESYSTEM_ATTRIBUTE_RETAIN -#endif - -#endif // BOOST_FILESYSTEM_SRC_PRIVATE_CONFIG_HPP_ diff --git a/contrib/restricted/boost/filesystem/src/unique_path.cpp b/contrib/restricted/boost/filesystem/src/unique_path.cpp deleted file mode 100644 index f0bc6058cb..0000000000 --- a/contrib/restricted/boost/filesystem/src/unique_path.cpp +++ /dev/null @@ -1,331 +0,0 @@ -// filesystem unique_path.cpp --------------------------------------------------------// - -// Copyright Beman Dawes 2010 -// Copyright Andrey Semashev 2020 - -// Distributed under the Boost Software License, Version 1.0. -// See http://www.boost.org/LICENSE_1_0.txt - -// Library home page: http://www.boost.org/libs/filesystem - -//--------------------------------------------------------------------------------------// - -#include "platform_config.hpp" - -#include <boost/predef/library/c/cloudabi.h> -#include <boost/predef/os/bsd/open.h> -#include <boost/predef/os/bsd/free.h> - -#ifdef BOOST_POSIX_API - -#include <cerrno> -#include <stddef.h> -#include <fcntl.h> -#ifdef BOOST_HAS_UNISTD_H -#include <unistd.h> -#endif - -#if !defined(BOOST_FILESYSTEM_DISABLE_ARC4RANDOM) -#if BOOST_OS_BSD_OPEN >= BOOST_VERSION_NUMBER(2, 1, 0) || \ - BOOST_OS_BSD_FREE >= BOOST_VERSION_NUMBER(8, 0, 0) || \ - BOOST_LIB_C_CLOUDABI -#include <stdlib.h> -#define BOOST_FILESYSTEM_HAS_ARC4RANDOM -#endif -#endif // !defined(BOOST_FILESYSTEM_DISABLE_ARC4RANDOM) - -#if !defined(BOOST_FILESYSTEM_DISABLE_GETRANDOM) -#if (defined(__linux__) || defined(__linux) || defined(linux)) && \ - (!defined(__ANDROID__) || __ANDROID_API__ >= 28) -#include <sys/syscall.h> -#if defined(SYS_getrandom) -#define BOOST_FILESYSTEM_HAS_GETRANDOM_SYSCALL -#endif // defined(SYS_getrandom) -#if defined(__has_include) -#if __has_include(<sys/random.h>) -#define BOOST_FILESYSTEM_HAS_GETRANDOM -#endif -#elif defined(__GLIBC__) -#if __GLIBC_PREREQ(2, 25) -#define BOOST_FILESYSTEM_HAS_GETRANDOM -#endif -#endif // BOOST_FILESYSTEM_HAS_GETRANDOM definition -#if defined(BOOST_FILESYSTEM_HAS_GETRANDOM) -#include <sys/random.h> -#endif -#endif // (defined(__linux__) || defined(__linux) || defined(linux)) && (!defined(__ANDROID__) || __ANDROID_API__ >= 28) -#endif // !defined(BOOST_FILESYSTEM_DISABLE_GETRANDOM) - -#include "posix_tools.hpp" - -#else // BOOST_WINDOWS_API - -// We use auto-linking below to help users of static builds of Boost.Filesystem to link to whatever Windows SDK library we selected. -// The dependency information is currently not exposed in CMake config files generated by Boost.Build (https://github.com/boostorg/boost_install/issues/18), -// which makes it non-trivial for users to discover the libraries they need. This feature is deprecated and may be removed in the future, -// when the situation with CMake config files improves. -// Note that the library build system is the principal source of linking the library, which must work regardless of auto-linking. -#include <boost/predef/platform.h> -#include <boost/winapi/basic_types.hpp> - -#if defined(BOOST_FILESYSTEM_HAS_BCRYPT) // defined on the command line by the project -#include <boost/winapi/error_codes.hpp> -#include <boost/winapi/bcrypt.hpp> -#if !defined(BOOST_FILESYSTEM_NO_DEPRECATED) && defined(_MSC_VER) -#pragma comment(lib, "bcrypt.lib") -#endif // !defined(BOOST_FILESYSTEM_NO_DEPRECATED) && defined(_MSC_VER) -#else // defined(BOOST_FILESYSTEM_HAS_BCRYPT) -#include <boost/winapi/crypt.hpp> -#include <boost/winapi/get_last_error.hpp> -#if !defined(BOOST_FILESYSTEM_NO_DEPRECATED) && defined(_MSC_VER) -#if !defined(_WIN32_WCE) -#pragma comment(lib, "advapi32.lib") -#else -#pragma comment(lib, "coredll.lib") -#endif -#endif // !defined(BOOST_FILESYSTEM_NO_DEPRECATED) && defined(_MSC_VER) -#endif // defined(BOOST_FILESYSTEM_HAS_BCRYPT) - -#endif // BOOST_POSIX_API - -#include <cstddef> -#include <boost/filesystem/config.hpp> -#include <boost/filesystem/operations.hpp> -#include "private_config.hpp" -#include "atomic_tools.hpp" -#include "error_handling.hpp" - -#include <boost/filesystem/detail/header.hpp> // must be the last #include - -#if defined(BOOST_POSIX_API) -// At least Mac OS X 10.6 and older doesn't support O_CLOEXEC -#ifndef O_CLOEXEC -#define O_CLOEXEC 0 -#endif -#endif // defined(BOOST_POSIX_API) - -namespace boost { -namespace filesystem { -namespace detail { - -namespace { - -#if defined(BOOST_POSIX_API) && !defined(BOOST_FILESYSTEM_HAS_ARC4RANDOM) - -//! Fills buffer with cryptographically random data obtained from /dev/(u)random -int fill_random_dev_random(void* buf, std::size_t len) -{ - int file = ::open("/dev/urandom", O_RDONLY | O_CLOEXEC); - if (file == -1) - { - file = ::open("/dev/random", O_RDONLY | O_CLOEXEC); - if (file == -1) - return errno; - } - - std::size_t bytes_read = 0u; - while (bytes_read < len) - { - ssize_t n = ::read(file, buf, len - bytes_read); - if (BOOST_UNLIKELY(n == -1)) - { - int err = errno; - if (err == EINTR) - continue; - close_fd(file); - return err; - } - bytes_read += n; - buf = static_cast< char* >(buf) + n; - } - - close_fd(file); - return 0; -} - -#if defined(BOOST_FILESYSTEM_HAS_GETRANDOM) || defined(BOOST_FILESYSTEM_HAS_GETRANDOM_SYSCALL) - -typedef int fill_random_t(void* buf, std::size_t len); - -//! Pointer to the implementation of fill_random. -fill_random_t* fill_random = &fill_random_dev_random; - -//! Fills buffer with cryptographically random data obtained from getrandom() -int fill_random_getrandom(void* buf, std::size_t len) -{ - std::size_t bytes_read = 0u; - while (bytes_read < len) - { -#if defined(BOOST_FILESYSTEM_HAS_GETRANDOM) - ssize_t n = ::getrandom(buf, len - bytes_read, 0u); -#else - ssize_t n = ::syscall(SYS_getrandom, buf, len - bytes_read, 0u); -#endif - if (BOOST_UNLIKELY(n < 0)) - { - const int err = errno; - if (err == EINTR) - continue; - - if (err == ENOSYS && bytes_read == 0u) - { - filesystem::detail::atomic_store_relaxed(fill_random, &fill_random_dev_random); - return fill_random_dev_random(buf, len); - } - - return err; - } - - bytes_read += n; - buf = static_cast< char* >(buf) + n; - } - - return 0; -} - -#endif // defined(BOOST_FILESYSTEM_HAS_GETRANDOM) || defined(BOOST_FILESYSTEM_HAS_GETRANDOM_SYSCALL) - -#endif // defined(BOOST_POSIX_API) && !defined(BOOST_FILESYSTEM_HAS_ARC4RANDOM) - -void system_crypt_random(void* buf, std::size_t len, boost::system::error_code* ec) -{ -#if defined(BOOST_POSIX_API) - -#if defined(BOOST_FILESYSTEM_HAS_GETRANDOM) || defined(BOOST_FILESYSTEM_HAS_GETRANDOM_SYSCALL) - - int err = filesystem::detail::atomic_load_relaxed(fill_random)(buf, len); - if (BOOST_UNLIKELY(err != 0)) - emit_error(err, ec, "boost::filesystem::unique_path"); - -#elif defined(BOOST_FILESYSTEM_HAS_ARC4RANDOM) - - arc4random_buf(buf, len); - -#else - - int err = fill_random_dev_random(buf, len); - if (BOOST_UNLIKELY(err != 0)) - emit_error(err, ec, "boost::filesystem::unique_path"); - -#endif - -#else // defined(BOOST_POSIX_API) - -#if defined(BOOST_FILESYSTEM_HAS_BCRYPT) - - boost::winapi::BCRYPT_ALG_HANDLE_ handle; - boost::winapi::NTSTATUS_ status = boost::winapi::BCryptOpenAlgorithmProvider(&handle, boost::winapi::BCRYPT_RNG_ALGORITHM_, NULL, 0); - if (BOOST_UNLIKELY(status != 0)) - { - fail: - emit_error(translate_ntstatus(status), ec, "boost::filesystem::unique_path"); - return; - } - - status = boost::winapi::BCryptGenRandom(handle, static_cast< boost::winapi::PUCHAR_ >(buf), static_cast< boost::winapi::ULONG_ >(len), 0); - - boost::winapi::BCryptCloseAlgorithmProvider(handle, 0); - - if (BOOST_UNLIKELY(status != 0)) - goto fail; - -#else // defined(BOOST_FILESYSTEM_HAS_BCRYPT) - - boost::winapi::HCRYPTPROV_ handle; - boost::winapi::DWORD_ err = 0u; - if (BOOST_UNLIKELY(!boost::winapi::CryptAcquireContextW(&handle, NULL, NULL, boost::winapi::PROV_RSA_FULL_, boost::winapi::CRYPT_VERIFYCONTEXT_ | boost::winapi::CRYPT_SILENT_))) - { - err = boost::winapi::GetLastError(); - - fail: - emit_error(err, ec, "boost::filesystem::unique_path"); - return; - } - - boost::winapi::BOOL_ gen_ok = boost::winapi::CryptGenRandom(handle, static_cast< boost::winapi::DWORD_ >(len), static_cast< boost::winapi::BYTE_* >(buf)); - - if (BOOST_UNLIKELY(!gen_ok)) - err = boost::winapi::GetLastError(); - - boost::winapi::CryptReleaseContext(handle, 0); - - if (BOOST_UNLIKELY(!gen_ok)) - goto fail; - -#endif // defined(BOOST_FILESYSTEM_HAS_BCRYPT) - -#endif // defined(BOOST_POSIX_API) -} - -#ifdef BOOST_WINDOWS_API -BOOST_CONSTEXPR_OR_CONST wchar_t hex[] = L"0123456789abcdef"; -BOOST_CONSTEXPR_OR_CONST wchar_t percent = L'%'; -#else -BOOST_CONSTEXPR_OR_CONST char hex[] = "0123456789abcdef"; -BOOST_CONSTEXPR_OR_CONST char percent = '%'; -#endif - -} // unnamed namespace - -#if defined(linux) || defined(__linux) || defined(__linux__) - -//! Initializes fill_random implementation pointer -void init_fill_random_impl(unsigned int major_ver, unsigned int minor_ver, unsigned int patch_ver) -{ -#if defined(BOOST_FILESYSTEM_HAS_INIT_PRIORITY) && \ - (defined(BOOST_FILESYSTEM_HAS_GETRANDOM) || defined(BOOST_FILESYSTEM_HAS_GETRANDOM_SYSCALL)) - fill_random_t* fr = &fill_random_dev_random; - - if (major_ver > 3u || (major_ver == 3u && minor_ver >= 17u)) - fr = &fill_random_getrandom; - - filesystem::detail::atomic_store_relaxed(fill_random, fr); -#endif -} - -#endif // defined(linux) || defined(__linux) || defined(__linux__) - -BOOST_FILESYSTEM_DECL -path unique_path(path const& model, system::error_code* ec) -{ - // This function used wstring for fear of misidentifying - // a part of a multibyte character as a percent sign. - // However, double byte encodings only have 80-FF as lead - // bytes and 40-7F as trailing bytes, whereas % is 25. - // So, use string on POSIX and avoid conversions. - - path::string_type s(model.native()); - - char ran[16] = {}; // init to avoid clang static analyzer message - // see ticket #8954 - BOOST_CONSTEXPR_OR_CONST unsigned int max_nibbles = 2u * sizeof(ran); // 4-bits per nibble - - unsigned int nibbles_used = max_nibbles; - for (path::string_type::size_type i = 0, n = s.size(); i < n; ++i) - { - if (s[i] == percent) // digit request - { - if (nibbles_used == max_nibbles) - { - system_crypt_random(ran, sizeof(ran), ec); - if (ec && *ec) - return path(); - nibbles_used = 0; - } - unsigned int c = ran[nibbles_used / 2u]; - c >>= 4u * (nibbles_used++ & 1u); // if odd, shift right 1 nibble - s[i] = hex[c & 0xf]; // convert to hex digit and replace - } - } - - if (ec) - ec->clear(); - - return s; -} - -} // namespace detail -} // namespace filesystem -} // namespace boost - -#include <boost/filesystem/detail/footer.hpp> diff --git a/contrib/restricted/boost/filesystem/src/utf8_codecvt_facet.cpp b/contrib/restricted/boost/filesystem/src/utf8_codecvt_facet.cpp deleted file mode 100644 index 7e5939bb71..0000000000 --- a/contrib/restricted/boost/filesystem/src/utf8_codecvt_facet.cpp +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright Vladimir Prus 2004. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt -// or copy at http://www.boost.org/LICENSE_1_0.txt) - -#include "platform_config.hpp" - -#include <boost/filesystem/config.hpp> - -#include <boost/filesystem/detail/header.hpp> - -#define BOOST_UTF8_BEGIN_NAMESPACE \ - namespace boost { \ - namespace filesystem { \ - namespace detail { - -#define BOOST_UTF8_END_NAMESPACE \ - } \ - } \ - } -#define BOOST_UTF8_DECL BOOST_FILESYSTEM_DECL - -#include <boost/detail/utf8_codecvt_facet.ipp> - -#undef BOOST_UTF8_BEGIN_NAMESPACE -#undef BOOST_UTF8_END_NAMESPACE -#undef BOOST_UTF8_DECL - -#include <boost/filesystem/detail/footer.hpp> diff --git a/contrib/restricted/boost/filesystem/src/windows_file_codecvt.cpp b/contrib/restricted/boost/filesystem/src/windows_file_codecvt.cpp deleted file mode 100644 index f86ba5111b..0000000000 --- a/contrib/restricted/boost/filesystem/src/windows_file_codecvt.cpp +++ /dev/null @@ -1,72 +0,0 @@ -// filesystem windows_file_codecvt.cpp -----------------------------------------// - -// Copyright Beman Dawes 2009 - -// Distributed under the Boost Software License, Version 1.0. -// See http://www.boost.org/LICENSE_1_0.txt - -// Library home page: http://www.boost.org/libs/filesystem - -//--------------------------------------------------------------------------------------// - -#include "platform_config.hpp" - -#include <cwchar> // for mbstate_t - -#ifdef BOOST_WINDOWS_API - -#include "windows_file_codecvt.hpp" - -#include <windows.h> - -#include <boost/filesystem/detail/header.hpp> // must be the last #include - -namespace boost { -namespace filesystem { -namespace detail { - -std::codecvt_base::result windows_file_codecvt::do_in( - std::mbstate_t&, - const char* from, const char* from_end, const char*& from_next, - wchar_t* to, wchar_t* to_end, wchar_t*& to_next) const -{ - UINT codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP; - - int count; - if ((count = ::MultiByteToWideChar(codepage, MB_PRECOMPOSED, from, static_cast< int >(from_end - from), to, static_cast< int >(to_end - to))) == 0) - { - return error; // conversion failed - } - - from_next = from_end; - to_next = to + count; - *to_next = L'\0'; - return ok; -} - -std::codecvt_base::result windows_file_codecvt::do_out( - std::mbstate_t&, - const wchar_t* from, const wchar_t* from_end, const wchar_t*& from_next, - char* to, char* to_end, char*& to_next) const -{ - UINT codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP; - - int count; - if ((count = ::WideCharToMultiByte(codepage, WC_NO_BEST_FIT_CHARS, from, static_cast< int >(from_end - from), to, static_cast< int >(to_end - to), 0, 0)) == 0) - { - return error; // conversion failed - } - - from_next = from_end; - to_next = to + count; - *to_next = '\0'; - return ok; -} - -} // namespace detail -} // namespace filesystem -} // namespace boost - -#include <boost/filesystem/detail/footer.hpp> - -#endif // BOOST_WINDOWS_API diff --git a/contrib/restricted/boost/filesystem/src/windows_file_codecvt.hpp b/contrib/restricted/boost/filesystem/src/windows_file_codecvt.hpp deleted file mode 100644 index 917dc2182f..0000000000 --- a/contrib/restricted/boost/filesystem/src/windows_file_codecvt.hpp +++ /dev/null @@ -1,72 +0,0 @@ -// filesystem windows_file_codecvt.hpp -----------------------------------------------// - -// Copyright Beman Dawes 2009 - -// Distributed under the Boost Software License, Version 1.0. -// See http://www.boost.org/LICENSE_1_0.txt - -// Library home page: http://www.boost.org/libs/filesystem - -#ifndef BOOST_FILESYSTEM_WINDOWS_FILE_CODECVT_HPP -#define BOOST_FILESYSTEM_WINDOWS_FILE_CODECVT_HPP - -#include <boost/filesystem/config.hpp> - -#ifdef BOOST_WINDOWS_API - -#include <boost/config/workaround.hpp> -#include <cstddef> -#include <cwchar> // std::mbstate_t -#include <locale> - -#include <boost/filesystem/detail/header.hpp> // must be the last #include - -namespace boost { -namespace filesystem { -namespace detail { - -//------------------------------------------------------------------------------------// -// // -// class windows_file_codecvt // -// // -// Warning: partial implementation; even do_in and do_out only partially meet the // -// standard library specifications as the "to" buffer must hold the entire result. // -// // -//------------------------------------------------------------------------------------// - -class BOOST_SYMBOL_VISIBLE windows_file_codecvt BOOST_FINAL : - public std::codecvt< wchar_t, char, std::mbstate_t > -{ -public: - explicit windows_file_codecvt(std::size_t refs = 0) : - std::codecvt< wchar_t, char, std::mbstate_t >(refs) - { - } - -protected: - bool do_always_noconv() const BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE { return false; } - - // seems safest to assume variable number of characters since we don't - // actually know what codepage is active - int do_encoding() const BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE { return 0; } - std::codecvt_base::result do_in(std::mbstate_t& state, const char* from, const char* from_end, const char*& from_next, wchar_t* to, wchar_t* to_end, wchar_t*& to_next) const BOOST_OVERRIDE; - std::codecvt_base::result do_out(std::mbstate_t& state, const wchar_t* from, const wchar_t* from_end, const wchar_t*& from_next, char* to, char* to_end, char*& to_next) const BOOST_OVERRIDE; - std::codecvt_base::result do_unshift(std::mbstate_t&, char* /*from*/, char* /*to*/, char*& /*next*/) const BOOST_OVERRIDE { return ok; } - int do_length(std::mbstate_t&, const char* /*from*/, const char* /*from_end*/, std::size_t /*max*/) const -#if BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600)) - throw() -#endif - BOOST_OVERRIDE - { return 0; } - int do_max_length() const BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE { return 0; } -}; - -} // namespace detail -} // namespace filesystem -} // namespace boost - -#include <boost/filesystem/detail/footer.hpp> - -#endif // BOOST_WINDOWS_API - -#endif // BOOST_FILESYSTEM_WINDOWS_FILE_CODECVT_HPP diff --git a/contrib/restricted/boost/filesystem/src/windows_tools.hpp b/contrib/restricted/boost/filesystem/src/windows_tools.hpp deleted file mode 100644 index 8a2de7f0c9..0000000000 --- a/contrib/restricted/boost/filesystem/src/windows_tools.hpp +++ /dev/null @@ -1,273 +0,0 @@ -// windows_tools.hpp -----------------------------------------------------------------// - -// Copyright 2002-2009, 2014 Beman Dawes -// Copyright 2001 Dietmar Kuehl - -// Distributed under the Boost Software License, Version 1.0. -// See http://www.boost.org/LICENSE_1_0.txt - -// See library home page at http://www.boost.org/libs/filesystem - -//--------------------------------------------------------------------------------------// - -#ifndef BOOST_FILESYSTEM_SRC_WINDOWS_TOOLS_HPP_ -#define BOOST_FILESYSTEM_SRC_WINDOWS_TOOLS_HPP_ - -#include <cstddef> -#include <boost/filesystem/config.hpp> -#include <boost/filesystem/path.hpp> -#include <boost/filesystem/file_status.hpp> -#include <boost/winapi/basic_types.hpp> // NTSTATUS_ - -#include <windows.h> - -#include <boost/filesystem/detail/header.hpp> // must be the last #include - -#ifndef IO_REPARSE_TAG_MOUNT_POINT -#define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L) -#endif - -#ifndef IO_REPARSE_TAG_SYMLINK -#define IO_REPARSE_TAG_SYMLINK (0xA000000CL) -#endif - -namespace boost { -namespace filesystem { -namespace detail { - -BOOST_INLINE_VARIABLE BOOST_CONSTEXPR_OR_CONST wchar_t colon = L':'; -BOOST_INLINE_VARIABLE BOOST_CONSTEXPR_OR_CONST wchar_t questionmark = L'?'; - -inline bool is_letter(wchar_t c) -{ - return (c >= L'A' && c <= L'Z') || (c >= L'a' && c <= L'z'); -} - -inline bool equal_extension(wchar_t const* p, wchar_t const (&x1)[5], wchar_t const (&x2)[5]) -{ - return (p[0] == x1[0] || p[0] == x2[0]) && - (p[1] == x1[1] || p[1] == x2[1]) && - (p[2] == x1[2] || p[2] == x2[2]) && - (p[3] == x1[3] || p[3] == x2[3]) && - p[4] == 0; -} - -inline boost::filesystem::perms make_permissions(boost::filesystem::path const& p, DWORD attr) -{ - boost::filesystem::perms prms = boost::filesystem::owner_read | boost::filesystem::group_read | boost::filesystem::others_read; - if ((attr & FILE_ATTRIBUTE_READONLY) == 0u) - prms |= boost::filesystem::owner_write | boost::filesystem::group_write | boost::filesystem::others_write; - boost::filesystem::path ext = p.extension(); - wchar_t const* q = ext.c_str(); - if (equal_extension(q, L".exe", L".EXE") || equal_extension(q, L".com", L".COM") || equal_extension(q, L".bat", L".BAT") || equal_extension(q, L".cmd", L".CMD")) - prms |= boost::filesystem::owner_exe | boost::filesystem::group_exe | boost::filesystem::others_exe; - return prms; -} - -bool is_reparse_point_a_symlink_ioctl(HANDLE h); - -inline bool is_reparse_point_tag_a_symlink(ULONG reparse_point_tag) -{ - return reparse_point_tag == IO_REPARSE_TAG_SYMLINK - // Issue 9016 asked that NTFS directory junctions be recognized as directories. - // That is equivalent to recognizing them as symlinks, and then the normal symlink - // mechanism will take care of recognizing them as directories. - // - // Directory junctions are very similar to symlinks, but have some performance - // and other advantages over symlinks. They can be created from the command line - // with "mklink /J junction-name target-path". - // - // Note that mounted filesystems also have the same repartse point tag, which makes - // them look like directory symlinks in terms of Boost.Filesystem. read_symlink() - // may return a volume path or NT path for such symlinks. - || reparse_point_tag == IO_REPARSE_TAG_MOUNT_POINT; // aka "directory junction" or "junction" -} - -#if !defined(UNDER_CE) - -//! Platform-specific parameters for directory iterator construction -struct directory_iterator_params -{ - //! Handle of the directory to iterate over. If not \c INVALID_HANDLE_VALUE, the directory path is ignored. - HANDLE use_handle; - /*! - * If \c use_handle is not \c INVALID_HANDLE_VALUE, specifies whether the directory iterator should close the handle upon destruction. - * If \c false, the handle must remain valid for the lifetime of the iterator. - */ - bool close_handle; -}; - -//! IO_STATUS_BLOCK definition from Windows SDK. -struct io_status_block -{ - union - { - boost::winapi::NTSTATUS_ Status; - PVOID Pointer; - }; - ULONG_PTR Information; -}; - -//! UNICODE_STRING definition from Windows SDK -struct unicode_string -{ - USHORT Length; - USHORT MaximumLength; - PWSTR Buffer; -}; - -//! OBJECT_ATTRIBUTES definition from Windows SDK -struct object_attributes -{ - ULONG Length; - HANDLE RootDirectory; - unicode_string* ObjectName; - ULONG Attributes; - PVOID SecurityDescriptor; - PVOID SecurityQualityOfService; -}; - -#ifndef OBJ_CASE_INSENSITIVE -#define OBJ_CASE_INSENSITIVE 0x00000040 -#endif -#ifndef OBJ_DONT_REPARSE -#define OBJ_DONT_REPARSE 0x00001000 -#endif - -#ifndef FILE_SUPERSEDE -#define FILE_SUPERSEDE 0x00000000 -#endif -#ifndef FILE_OPEN -#define FILE_OPEN 0x00000001 -#endif -#ifndef FILE_CREATE -#define FILE_CREATE 0x00000002 -#endif -#ifndef FILE_OPEN_IF -#define FILE_OPEN_IF 0x00000003 -#endif -#ifndef FILE_OVERWRITE -#define FILE_OVERWRITE 0x00000004 -#endif -#ifndef FILE_OVERWRITE_IF -#define FILE_OVERWRITE_IF 0x00000005 -#endif - -#ifndef FILE_DIRECTORY_FILE -#define FILE_DIRECTORY_FILE 0x00000001 -#endif -#ifndef FILE_OPEN_FOR_BACKUP_INTENT -#define FILE_OPEN_FOR_BACKUP_INTENT 0x00004000 -#endif -#ifndef FILE_OPEN_REPARSE_POINT -#define FILE_OPEN_REPARSE_POINT 0x00200000 -#endif - -//! NtCreateFile signature. Available since Windows 2000 (probably). -typedef boost::winapi::NTSTATUS_ (NTAPI NtCreateFile_t)( - /*out*/ PHANDLE FileHandle, - /*in*/ ACCESS_MASK DesiredAccess, - /*in*/ object_attributes* ObjectAttributes, - /*out*/ io_status_block* IoStatusBlock, - /*in, optional*/ PLARGE_INTEGER AllocationSize, - /*in*/ ULONG FileAttributes, - /*in*/ ULONG ShareAccess, - /*in*/ ULONG CreateDisposition, - /*in*/ ULONG CreateOptions, - /*in, optional*/ PVOID EaBuffer, - /*in*/ ULONG EaLength); - -extern NtCreateFile_t* nt_create_file_api; - -//! PIO_APC_ROUTINE definition from Windows SDK -typedef VOID (NTAPI* pio_apc_routine) (PVOID ApcContext, io_status_block* IoStatusBlock, ULONG Reserved); - -//! FILE_INFORMATION_CLASS enum entries -enum file_information_class -{ - file_directory_information_class = 1 -}; - -//! NtQueryDirectoryFile signature. Available since Windows NT 4.0 (probably). -typedef boost::winapi::NTSTATUS_ (NTAPI NtQueryDirectoryFile_t)( - /*in*/ HANDLE FileHandle, - /*in, optional*/ HANDLE Event, - /*in, optional*/ pio_apc_routine ApcRoutine, - /*in, optional*/ PVOID ApcContext, - /*out*/ io_status_block* IoStatusBlock, - /*out*/ PVOID FileInformation, - /*in*/ ULONG Length, - /*in*/ file_information_class FileInformationClass, - /*in*/ BOOLEAN ReturnSingleEntry, - /*in, optional*/ unicode_string* FileName, - /*in*/ BOOLEAN RestartScan); - -extern NtQueryDirectoryFile_t* nt_query_directory_file_api; - -#endif // !defined(UNDER_CE) - -//! FILE_INFO_BY_HANDLE_CLASS enum entries -enum file_info_by_handle_class -{ - file_basic_info_class = 0, - file_disposition_info_class = 4, - file_attribute_tag_info_class = 9, - file_id_both_directory_info_class = 10, - file_id_both_directory_restart_info_class = 11, - file_full_directory_info_class = 14, - file_full_directory_restart_info_class = 15, - file_id_extd_directory_info_class = 19, - file_id_extd_directory_restart_info_class = 20, - file_disposition_info_ex_class = 21 -}; - -//! FILE_ATTRIBUTE_TAG_INFO definition from Windows SDK -struct file_attribute_tag_info -{ - DWORD FileAttributes; - DWORD ReparseTag; -}; - -//! GetFileInformationByHandleEx signature. Available since Windows Vista. -typedef BOOL (WINAPI GetFileInformationByHandleEx_t)( - /*__in*/ HANDLE hFile, - /*__in*/ file_info_by_handle_class FileInformationClass, // the actual type is FILE_INFO_BY_HANDLE_CLASS enum - /*__out_bcount(dwBufferSize)*/ LPVOID lpFileInformation, - /*__in*/ DWORD dwBufferSize); - -extern GetFileInformationByHandleEx_t* get_file_information_by_handle_ex_api; - -//! HANDLE wrapper that automatically closes the handle -struct handle_wrapper -{ - HANDLE handle; - - handle_wrapper() BOOST_NOEXCEPT : handle(INVALID_HANDLE_VALUE) {} - explicit handle_wrapper(HANDLE h) BOOST_NOEXCEPT : handle(h) {} - ~handle_wrapper() BOOST_NOEXCEPT - { - if (handle != INVALID_HANDLE_VALUE) - ::CloseHandle(handle); - } - BOOST_DELETED_FUNCTION(handle_wrapper(handle_wrapper const&)) - BOOST_DELETED_FUNCTION(handle_wrapper& operator=(handle_wrapper const&)) -}; - -//! Creates a file handle -inline HANDLE create_file_handle(boost::filesystem::path const& p, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile = NULL) -{ - return ::CreateFileW(p.c_str(), dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); -} - -#if !defined(UNDER_CE) -//! Creates a file handle for a file relative to a previously opened base directory. The file path must be relative and in preferred format. -boost::winapi::NTSTATUS_ nt_create_file_handle_at(HANDLE& out, HANDLE basedir_handle, boost::filesystem::path const& p, ULONG FileAttributes, ACCESS_MASK DesiredAccess, ULONG ShareMode, ULONG CreateDisposition, ULONG CreateOptions); -#endif // !defined(UNDER_CE) - -} // namespace detail -} // namespace filesystem -} // namespace boost - -#include <boost/filesystem/detail/footer.hpp> - -#endif // BOOST_FILESYSTEM_SRC_WINDOWS_TOOLS_HPP_ diff --git a/contrib/restricted/boost/io/include/boost/io/detail/buffer_fill.hpp b/contrib/restricted/boost/io/include/boost/io/detail/buffer_fill.hpp deleted file mode 100644 index b25a884473..0000000000 --- a/contrib/restricted/boost/io/include/boost/io/detail/buffer_fill.hpp +++ /dev/null @@ -1,39 +0,0 @@ -/* -Copyright 2019-2020 Glen Joseph Fernandes -(glenjofe@gmail.com) - -Distributed under the Boost Software License, Version 1.0. -(http://www.boost.org/LICENSE_1_0.txt) -*/ -#ifndef BOOST_IO_DETAIL_BUFFER_FILL_HPP -#define BOOST_IO_DETAIL_BUFFER_FILL_HPP - -#include <iosfwd> -#include <cstddef> - -namespace boost { -namespace io { -namespace detail { - -template<class charT, class traits> -inline bool -buffer_fill(std::basic_streambuf<charT, traits>& buf, charT ch, - std::size_t size) -{ - charT fill[] = { ch, ch, ch, ch, ch, ch, ch, ch }; - enum { - chunk = sizeof fill / sizeof(charT) - }; - for (; size > chunk; size -= chunk) { - if (static_cast<std::size_t>(buf.sputn(fill, chunk)) != chunk) { - return false; - } - } - return static_cast<std::size_t>(buf.sputn(fill, size)) == size; -} - -} /* detail */ -} /* io */ -} /* boost */ - -#endif diff --git a/contrib/restricted/boost/io/include/boost/io/detail/ostream_guard.hpp b/contrib/restricted/boost/io/include/boost/io/detail/ostream_guard.hpp deleted file mode 100644 index 6999d81344..0000000000 --- a/contrib/restricted/boost/io/include/boost/io/detail/ostream_guard.hpp +++ /dev/null @@ -1,45 +0,0 @@ -/* -Copyright 2019-2020 Glen Joseph Fernandes -(glenjofe@gmail.com) - -Distributed under the Boost Software License, Version 1.0. -(http://www.boost.org/LICENSE_1_0.txt) -*/ -#ifndef BOOST_IO_DETAIL_OSTREAM_GUARD_HPP -#define BOOST_IO_DETAIL_OSTREAM_GUARD_HPP - -#include <boost/config.hpp> -#include <iosfwd> - -namespace boost { -namespace io { -namespace detail { - -template<class Char, class Traits> -class ostream_guard { -public: - explicit ostream_guard(std::basic_ostream<Char, Traits>& os) BOOST_NOEXCEPT - : os_(&os) { } - - ~ostream_guard() BOOST_NOEXCEPT_IF(false) { - if (os_) { - os_->setstate(std::basic_ostream<Char, Traits>::badbit); - } - } - - void release() BOOST_NOEXCEPT { - os_ = 0; - } - -private: - ostream_guard(const ostream_guard&); - ostream_guard& operator=(const ostream_guard&); - - std::basic_ostream<Char, Traits>* os_; -}; - -} /* detail */ -} /* io */ -} /* boost */ - -#endif diff --git a/contrib/restricted/boost/io/include/boost/io/quoted.hpp b/contrib/restricted/boost/io/include/boost/io/quoted.hpp deleted file mode 100644 index fc7d205e82..0000000000 --- a/contrib/restricted/boost/io/include/boost/io/quoted.hpp +++ /dev/null @@ -1,217 +0,0 @@ -/* -Copyright 2010 Beman Dawes - -Copyright 2019-2020 Glen Joseph Fernandes -(glenjofe@gmail.com) - -Distributed under the Boost Software License, Version 1.0. -(http://www.boost.org/LICENSE_1_0.txt) -*/ -#ifndef BOOST_IO_QUOTED_HPP -#define BOOST_IO_QUOTED_HPP - -#include <boost/io/detail/buffer_fill.hpp> -#include <boost/io/detail/ostream_guard.hpp> -#include <boost/io/ios_state.hpp> - -namespace boost { -namespace io { -namespace detail { - -template<class String, class Char> -struct quoted_proxy { - String string; - Char escape; - Char delim; -}; - -template<class Char> -struct quoted_state { - const Char* string; - std::size_t size; - std::size_t count; -}; - -template<class Char> -inline quoted_state<Char> -quoted_start(const Char* string, Char escape, Char delim) -{ - const Char* end = string; - std::size_t count = 2; - for (Char ch; (ch = *end) != 0; ++end) { - count += 1 + (ch == escape || ch == delim); - } - quoted_state<Char> state = { string, - static_cast<std::size_t>(end - string), count }; - return state; -} - -template<class Char, class String> -inline quoted_state<Char> -quoted_start(const String* string, Char escape, Char delim) -{ - const Char* begin = string->data(); - std::size_t size = string->size(); - std::size_t count = 2; - for (const Char *it = begin, *end = begin + size; it != end; ++it) { - Char ch = *it; - count += 1 + (ch == escape || ch == delim); - } - quoted_state<Char> state = { begin, size, count }; - return state; -} - -template<class Char, class Traits> -inline bool -quoted_put(std::basic_streambuf<Char, Traits>& buf, const Char* string, - std::size_t size, std::size_t count, Char escape, Char delim) -{ - if (buf.sputc(delim) == Traits::eof()) { - return false; - } - if (size == count) { - if (static_cast<std::size_t>(buf.sputn(string, size)) != size) { - return false; - } - } else { - for (const Char* end = string + size; string != end; ++string) { - Char ch = *string; - if ((ch == escape || ch == delim) && - buf.sputc(escape) == Traits::eof()) { - return false; - } - if (buf.sputc(ch) == Traits::eof()) { - return false; - } - } - } - return buf.sputc(delim) != Traits::eof(); -} - -template<class Char, class Traits, class String> -inline std::basic_ostream<Char, Traits>& -quoted_out(std::basic_ostream<Char, Traits>& os, String* string, Char escape, - Char delim) -{ - typedef std::basic_ostream<Char, Traits> stream; - ostream_guard<Char, Traits> guard(os); - typename stream::sentry entry(os); - if (entry) { - quoted_state<Char> state = boost::io::detail::quoted_start(string, - escape, delim); - std::basic_streambuf<Char, Traits>& buf = *os.rdbuf(); - std::size_t width = static_cast<std::size_t>(os.width()); - if (width <= state.count) { - if (!boost::io::detail::quoted_put(buf, state.string, state.size, - state.count, escape, delim)) { - return os; - } - } else if ((os.flags() & stream::adjustfield) == stream::left) { - if (!boost::io::detail::quoted_put(buf, state.string, state.size, - state.count, escape, delim) || - !boost::io::detail::buffer_fill(buf, os.fill(), - width - state.count)) { - return os; - } - } else if (!boost::io::detail::buffer_fill(buf, os.fill(), - width - state.count) || - !boost::io::detail::quoted_put(buf, state.string, state.size, - state.count, escape, delim)) { - return os; - } - os.width(0); - } - guard.release(); - return os; -} - -template<class Char, class Traits> -inline std::basic_ostream<Char, Traits>& -operator<<(std::basic_ostream<Char, Traits>& os, - const quoted_proxy<const Char*, Char>& proxy) -{ - return boost::io::detail::quoted_out(os, proxy.string, proxy.escape, - proxy.delim); -} - -template <class Char, class Traits, class Alloc> -inline std::basic_ostream<Char, Traits>& -operator<<(std::basic_ostream<Char, Traits>& os, - const quoted_proxy<const std::basic_string<Char, Traits, Alloc>*, - Char>& proxy) -{ - return boost::io::detail::quoted_out(os, proxy.string, proxy.escape, - proxy.delim); -} - -template<class Char, class Traits, class Alloc> -inline std::basic_ostream<Char, Traits>& -operator<<(std::basic_ostream<Char, Traits>& os, - const quoted_proxy<std::basic_string<Char, Traits, Alloc>*, Char>& proxy) -{ - return boost::io::detail::quoted_out(os, proxy.string, proxy.escape, - proxy.delim); -} - -template<class Char, class Traits, class Alloc> -inline std::basic_istream<Char, Traits>& -operator>>(std::basic_istream<Char, Traits>& is, - const quoted_proxy<std::basic_string<Char, Traits, Alloc>*, Char>& proxy) -{ - Char ch; - if (!(is >> ch)) { - return is; - } - if (ch != proxy.delim) { - is.unget(); - return is >> *proxy.string; - } - { - boost::io::ios_flags_saver ifs(is); - std::noskipws(is); - proxy.string->clear(); - while ((is >> ch) && ch != proxy.delim) { - if (ch == proxy.escape && !(is >> ch)) { - break; - } - proxy.string->push_back(ch); - } - } - return is; -} - -} /* detail */ - -template<class Char, class Traits, class Alloc> -inline detail::quoted_proxy<const std::basic_string<Char, Traits, Alloc>*, - Char> -quoted(const std::basic_string<Char, Traits, Alloc>& s, Char escape='\\', - Char delim='\"') -{ - detail::quoted_proxy<const std::basic_string<Char, Traits, Alloc>*, - Char> proxy = { &s, escape, delim }; - return proxy; -} - -template<class Char, class Traits, class Alloc> -inline detail::quoted_proxy<std::basic_string<Char, Traits, Alloc>*, Char> -quoted(std::basic_string<Char, Traits, Alloc>& s, Char escape='\\', - Char delim='\"') -{ - detail::quoted_proxy<std::basic_string<Char, Traits, Alloc>*, - Char> proxy = { &s, escape, delim }; - return proxy; -} - -template<class Char> -inline detail::quoted_proxy<const Char*, Char> -quoted(const Char* s, Char escape='\\', Char delim='\"') -{ - detail::quoted_proxy<const Char*, Char> proxy = { s, escape, delim }; - return proxy; -} - -} /* io */ -} /* boost */ - -#endif diff --git a/contrib/restricted/boost/spirit/CMakeLists.darwin.txt b/contrib/restricted/boost/spirit/CMakeLists.darwin.txt index 70770f16ae..d44747f796 100644 --- a/contrib/restricted/boost/spirit/CMakeLists.darwin.txt +++ b/contrib/restricted/boost/spirit/CMakeLists.darwin.txt @@ -13,32 +13,22 @@ target_include_directories(restricted-boost-spirit INTERFACE ) target_link_libraries(restricted-boost-spirit INTERFACE contrib-libs-cxxsupp - yutil - restricted-boost-algorithm restricted-boost-array restricted-boost-assert - restricted-boost-concept_check restricted-boost-config restricted-boost-core restricted-boost-endian - restricted-boost-filesystem - restricted-boost-foreach restricted-boost-function restricted-boost-function_types restricted-boost-fusion restricted-boost-integer restricted-boost-io - restricted-boost-iostreams restricted-boost-iterator - restricted-boost-lexical_cast - restricted-boost-locale - restricted-boost-math restricted-boost-move restricted-boost-mpl restricted-boost-optional restricted-boost-phoenix restricted-boost-pool - restricted-boost-predef restricted-boost-preprocessor restricted-boost-proto restricted-boost-range @@ -47,7 +37,6 @@ target_link_libraries(restricted-boost-spirit INTERFACE restricted-boost-static_assert restricted-boost-thread restricted-boost-throw_exception - restricted-boost-tti restricted-boost-type_traits restricted-boost-typeof restricted-boost-unordered diff --git a/contrib/restricted/boost/spirit/CMakeLists.linux-aarch64.txt b/contrib/restricted/boost/spirit/CMakeLists.linux-aarch64.txt index 08125299b6..05b0380527 100644 --- a/contrib/restricted/boost/spirit/CMakeLists.linux-aarch64.txt +++ b/contrib/restricted/boost/spirit/CMakeLists.linux-aarch64.txt @@ -14,32 +14,22 @@ target_include_directories(restricted-boost-spirit INTERFACE target_link_libraries(restricted-boost-spirit INTERFACE contrib-libs-linux-headers contrib-libs-cxxsupp - yutil - restricted-boost-algorithm restricted-boost-array restricted-boost-assert - restricted-boost-concept_check restricted-boost-config restricted-boost-core restricted-boost-endian - restricted-boost-filesystem - restricted-boost-foreach restricted-boost-function restricted-boost-function_types restricted-boost-fusion restricted-boost-integer restricted-boost-io - restricted-boost-iostreams restricted-boost-iterator - restricted-boost-lexical_cast - restricted-boost-locale - restricted-boost-math restricted-boost-move restricted-boost-mpl restricted-boost-optional restricted-boost-phoenix restricted-boost-pool - restricted-boost-predef restricted-boost-preprocessor restricted-boost-proto restricted-boost-range @@ -48,7 +38,6 @@ target_link_libraries(restricted-boost-spirit INTERFACE restricted-boost-static_assert restricted-boost-thread restricted-boost-throw_exception - restricted-boost-tti restricted-boost-type_traits restricted-boost-typeof restricted-boost-unordered diff --git a/contrib/restricted/boost/spirit/CMakeLists.linux.txt b/contrib/restricted/boost/spirit/CMakeLists.linux.txt index 08125299b6..05b0380527 100644 --- a/contrib/restricted/boost/spirit/CMakeLists.linux.txt +++ b/contrib/restricted/boost/spirit/CMakeLists.linux.txt @@ -14,32 +14,22 @@ target_include_directories(restricted-boost-spirit INTERFACE target_link_libraries(restricted-boost-spirit INTERFACE contrib-libs-linux-headers contrib-libs-cxxsupp - yutil - restricted-boost-algorithm restricted-boost-array restricted-boost-assert - restricted-boost-concept_check restricted-boost-config restricted-boost-core restricted-boost-endian - restricted-boost-filesystem - restricted-boost-foreach restricted-boost-function restricted-boost-function_types restricted-boost-fusion restricted-boost-integer restricted-boost-io - restricted-boost-iostreams restricted-boost-iterator - restricted-boost-lexical_cast - restricted-boost-locale - restricted-boost-math restricted-boost-move restricted-boost-mpl restricted-boost-optional restricted-boost-phoenix restricted-boost-pool - restricted-boost-predef restricted-boost-preprocessor restricted-boost-proto restricted-boost-range @@ -48,7 +38,6 @@ target_link_libraries(restricted-boost-spirit INTERFACE restricted-boost-static_assert restricted-boost-thread restricted-boost-throw_exception - restricted-boost-tti restricted-boost-type_traits restricted-boost-typeof restricted-boost-unordered diff --git a/contrib/restricted/boost/tti/CMakeLists.linux-aarch64.txt b/contrib/restricted/boost/tti/CMakeLists.linux-aarch64.txt deleted file mode 100644 index 2c50d54bbc..0000000000 --- a/contrib/restricted/boost/tti/CMakeLists.linux-aarch64.txt +++ /dev/null @@ -1,22 +0,0 @@ - -# This file was gererated by the build system used internally in the Yandex monorepo. -# Only simple modifications are allowed (adding source-files to targets, adding simple properties -# like target_include_directories). These modifications will be ported to original -# ya.make files by maintainers. Any complex modifications which can't be ported back to the -# original buildsystem will not be accepted. - - - -add_library(restricted-boost-tti INTERFACE) -target_include_directories(restricted-boost-tti INTERFACE - ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/tti/include -) -target_link_libraries(restricted-boost-tti INTERFACE - contrib-libs-linux-headers - contrib-libs-cxxsupp - restricted-boost-config - restricted-boost-function_types - restricted-boost-mpl - restricted-boost-preprocessor - restricted-boost-type_traits -) diff --git a/contrib/restricted/boost/tti/CMakeLists.txt b/contrib/restricted/boost/tti/CMakeLists.txt index 3e0811fb22..79468a5d8d 100644 --- a/contrib/restricted/boost/tti/CMakeLists.txt +++ b/contrib/restricted/boost/tti/CMakeLists.txt @@ -6,9 +6,7 @@ # original buildsystem will not be accepted. -if (CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" AND UNIX AND NOT APPLE AND NOT ANDROID) - include(CMakeLists.linux-aarch64.txt) -elseif (APPLE) +if (APPLE) include(CMakeLists.darwin.txt) elseif (CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND UNIX AND NOT APPLE AND NOT ANDROID) include(CMakeLists.linux.txt) diff --git a/contrib/restricted/boost/winapi/include/boost/winapi/bcrypt.hpp b/contrib/restricted/boost/winapi/include/boost/winapi/bcrypt.hpp deleted file mode 100644 index d476b76d31..0000000000 --- a/contrib/restricted/boost/winapi/include/boost/winapi/bcrypt.hpp +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2017 James E. King, III - * - * Distributed under the Boost Software License, Version 1.0. - * See http://www.boost.org/LICENSE_1_0.txt - */ - -#ifndef BOOST_WINAPI_BCRYPT_HPP_INCLUDED_ -#define BOOST_WINAPI_BCRYPT_HPP_INCLUDED_ - -#include <boost/winapi/basic_types.hpp> - -#ifdef BOOST_HAS_PRAGMA_ONCE -#pragma once -#endif - -#if BOOST_USE_WINAPI_VERSION >= BOOST_WINAPI_VERSION_WIN6 - -#if BOOST_WINAPI_PARTITION_APP_SYSTEM - -#if defined(BOOST_USE_WINDOWS_H) -#include <bcrypt.h> -#endif - -#include <boost/winapi/detail/header.hpp> - -#if defined(BOOST_USE_WINDOWS_H) - -namespace boost { namespace winapi { -typedef ::BCRYPT_ALG_HANDLE BCRYPT_ALG_HANDLE_; -}} - -#else // defined(BOOST_USE_WINDOWS_H) - -namespace boost { namespace winapi { -typedef PVOID_ BCRYPT_ALG_HANDLE_; -}} - -extern "C" { - -boost::winapi::NTSTATUS_ BOOST_WINAPI_WINAPI_CC -BCryptCloseAlgorithmProvider( - boost::winapi::BCRYPT_ALG_HANDLE_ hAlgorithm, - boost::winapi::ULONG_ dwFlags -); - -boost::winapi::NTSTATUS_ BOOST_WINAPI_WINAPI_CC -BCryptGenRandom( - boost::winapi::BCRYPT_ALG_HANDLE_ hAlgorithm, - boost::winapi::PUCHAR_ pbBuffer, - boost::winapi::ULONG_ cbBuffer, - boost::winapi::ULONG_ dwFlags -); - -boost::winapi::NTSTATUS_ BOOST_WINAPI_WINAPI_CC -BCryptOpenAlgorithmProvider( - boost::winapi::BCRYPT_ALG_HANDLE_ *phAlgorithm, - boost::winapi::LPCWSTR_ pszAlgId, - boost::winapi::LPCWSTR_ pszImplementation, - boost::winapi::DWORD_ dwFlags -); - -} // extern "C" - -#endif // defined(BOOST_USE_WINDOWS_H) - -namespace boost { -namespace winapi { - -#if defined(BOOST_USE_WINDOWS_H) -const WCHAR_ BCRYPT_RNG_ALGORITHM_[] = BCRYPT_RNG_ALGORITHM; -#else -const WCHAR_ BCRYPT_RNG_ALGORITHM_[] = L"RNG"; -#endif - -using ::BCryptCloseAlgorithmProvider; -using ::BCryptGenRandom; -using ::BCryptOpenAlgorithmProvider; - -} // winapi -} // boost - -#include <boost/winapi/detail/footer.hpp> - -#endif // BOOST_WINAPI_PARTITION_APP_SYSTEM - -#endif // BOOST_USE_WINAPI_VERSION >= BOOST_WINAPI_VERSION_WIN6 - -#endif // BOOST_WINAPI_BCRYPT_HPP_INCLUDED_ diff --git a/contrib/restricted/boost/winapi/include/boost/winapi/crypt.hpp b/contrib/restricted/boost/winapi/include/boost/winapi/crypt.hpp deleted file mode 100644 index 12b74999dd..0000000000 --- a/contrib/restricted/boost/winapi/include/boost/winapi/crypt.hpp +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright 2014 Antony Polukhin - * Copyright 2015 Andrey Semashev - * - * Distributed under the Boost Software License, Version 1.0. - * See http://www.boost.org/LICENSE_1_0.txt - */ - -#ifndef BOOST_WINAPI_CRYPT_HPP_INCLUDED_ -#define BOOST_WINAPI_CRYPT_HPP_INCLUDED_ - -#include <boost/winapi/basic_types.hpp> -#if defined( BOOST_USE_WINDOWS_H ) -// This header is not always included as part of windows.h -#include <wincrypt.h> -#endif -#include <boost/winapi/detail/header.hpp> - -#ifdef BOOST_HAS_PRAGMA_ONCE -#pragma once -#endif - -#if !defined( BOOST_USE_WINDOWS_H ) -namespace boost { namespace winapi { -typedef ULONG_PTR_ HCRYPTPROV_; -}} - -extern "C" { -#if BOOST_WINAPI_PARTITION_DESKTOP || BOOST_WINAPI_PARTITION_SYSTEM -#if !defined( BOOST_NO_ANSI_APIS ) -BOOST_WINAPI_IMPORT boost::winapi::BOOL_ BOOST_WINAPI_WINAPI_CC -CryptEnumProvidersA( - boost::winapi::DWORD_ dwIndex, - boost::winapi::DWORD_ *pdwReserved, - boost::winapi::DWORD_ dwFlags, - boost::winapi::DWORD_ *pdwProvType, - boost::winapi::LPSTR_ szProvName, - boost::winapi::DWORD_ *pcbProvName); - -BOOST_WINAPI_IMPORT boost::winapi::BOOL_ BOOST_WINAPI_WINAPI_CC -CryptAcquireContextA( - boost::winapi::HCRYPTPROV_ *phProv, - boost::winapi::LPCSTR_ pszContainer, - boost::winapi::LPCSTR_ pszProvider, - boost::winapi::DWORD_ dwProvType, - boost::winapi::DWORD_ dwFlags); -#endif // !defined( BOOST_NO_ANSI_APIS ) - -BOOST_WINAPI_IMPORT boost::winapi::BOOL_ BOOST_WINAPI_WINAPI_CC -CryptEnumProvidersW( - boost::winapi::DWORD_ dwIndex, - boost::winapi::DWORD_ *pdwReserved, - boost::winapi::DWORD_ dwFlags, - boost::winapi::DWORD_ *pdwProvType, - boost::winapi::LPWSTR_ szProvName, - boost::winapi::DWORD_ *pcbProvName); - -BOOST_WINAPI_IMPORT boost::winapi::BOOL_ BOOST_WINAPI_WINAPI_CC -CryptAcquireContextW( - boost::winapi::HCRYPTPROV_ *phProv, - boost::winapi::LPCWSTR_ szContainer, - boost::winapi::LPCWSTR_ szProvider, - boost::winapi::DWORD_ dwProvType, - boost::winapi::DWORD_ dwFlags); - -BOOST_WINAPI_IMPORT boost::winapi::BOOL_ BOOST_WINAPI_WINAPI_CC -CryptGenRandom( - boost::winapi::HCRYPTPROV_ hProv, - boost::winapi::DWORD_ dwLen, - boost::winapi::BYTE_ *pbBuffer); -#endif // BOOST_WINAPI_PARTITION_DESKTOP || BOOST_WINAPI_PARTITION_SYSTEM - -#if BOOST_WINAPI_PARTITION_APP_SYSTEM -#if defined(_MSC_VER) && (_MSC_VER+0) >= 1500 && (_MSC_VER+0) < 1900 && BOOST_USE_NTDDI_VERSION < BOOST_WINAPI_NTDDI_WINXP -// Standalone MS Windows SDK 6.0A and later until 10.0 provide a different declaration of CryptReleaseContext for Windows 2000 and older. -// This is not the case for (a) MinGW and MinGW-w64, (b) MSVC 7.1 and 8, which are shipped with their own Windows SDK, -// and (c) MSVC 14.0 and later, which are used with Windows SDK 10. -BOOST_WINAPI_IMPORT boost::winapi::BOOL_ BOOST_WINAPI_WINAPI_CC -CryptReleaseContext( - boost::winapi::HCRYPTPROV_ hProv, - boost::winapi::ULONG_PTR_ dwFlags); -#else -BOOST_WINAPI_IMPORT boost::winapi::BOOL_ BOOST_WINAPI_WINAPI_CC -CryptReleaseContext( - boost::winapi::HCRYPTPROV_ hProv, - boost::winapi::DWORD_ dwFlags); -#endif -#endif // BOOST_WINAPI_PARTITION_APP_SYSTEM -} -#endif // !defined( BOOST_USE_WINDOWS_H ) - -namespace boost { -namespace winapi { - -#if defined( BOOST_USE_WINDOWS_H ) - -typedef ::HCRYPTPROV HCRYPTPROV_; - -#if BOOST_WINAPI_PARTITION_APP_SYSTEM -BOOST_CONSTEXPR_OR_CONST DWORD_ PROV_RSA_FULL_ = PROV_RSA_FULL; - -BOOST_CONSTEXPR_OR_CONST DWORD_ CRYPT_VERIFYCONTEXT_ = CRYPT_VERIFYCONTEXT; -BOOST_CONSTEXPR_OR_CONST DWORD_ CRYPT_NEWKEYSET_ = CRYPT_NEWKEYSET; -BOOST_CONSTEXPR_OR_CONST DWORD_ CRYPT_DELETEKEYSET_ = CRYPT_DELETEKEYSET; -BOOST_CONSTEXPR_OR_CONST DWORD_ CRYPT_MACHINE_KEYSET_ = CRYPT_MACHINE_KEYSET; -BOOST_CONSTEXPR_OR_CONST DWORD_ CRYPT_SILENT_ = CRYPT_SILENT; -#endif - -#else - -#if BOOST_WINAPI_PARTITION_APP_SYSTEM -BOOST_CONSTEXPR_OR_CONST DWORD_ PROV_RSA_FULL_ = 1; - -BOOST_CONSTEXPR_OR_CONST DWORD_ CRYPT_VERIFYCONTEXT_ = 0xF0000000; -BOOST_CONSTEXPR_OR_CONST DWORD_ CRYPT_NEWKEYSET_ = 8; -BOOST_CONSTEXPR_OR_CONST DWORD_ CRYPT_DELETEKEYSET_ = 16; -BOOST_CONSTEXPR_OR_CONST DWORD_ CRYPT_MACHINE_KEYSET_ = 32; -BOOST_CONSTEXPR_OR_CONST DWORD_ CRYPT_SILENT_ = 64; -#endif - -#endif - -#if BOOST_WINAPI_PARTITION_DESKTOP || BOOST_WINAPI_PARTITION_SYSTEM - -#if !defined( BOOST_NO_ANSI_APIS ) -using ::CryptEnumProvidersA; -using ::CryptAcquireContextA; -#endif -using ::CryptEnumProvidersW; -using ::CryptAcquireContextW; -using ::CryptGenRandom; - -#if !defined( BOOST_NO_ANSI_APIS ) -BOOST_FORCEINLINE BOOL_ crypt_enum_providers( - DWORD_ dwIndex, - DWORD_ *pdwReserved, - DWORD_ dwFlags, - DWORD_ *pdwProvType, - LPSTR_ szProvName, - DWORD_ *pcbProvName) -{ - return ::CryptEnumProvidersA(dwIndex, pdwReserved, dwFlags, pdwProvType, szProvName, pcbProvName); -} - -BOOST_FORCEINLINE BOOL_ crypt_acquire_context( - HCRYPTPROV_ *phProv, - LPCSTR_ pszContainer, - LPCSTR_ pszProvider, - DWORD_ dwProvType, - DWORD_ dwFlags) -{ - return ::CryptAcquireContextA(phProv, pszContainer, pszProvider, dwProvType, dwFlags); -} -#endif - -BOOST_FORCEINLINE BOOL_ crypt_enum_providers( - DWORD_ dwIndex, - DWORD_ *pdwReserved, - DWORD_ dwFlags, - DWORD_ *pdwProvType, - LPWSTR_ szProvName, - DWORD_ *pcbProvName) -{ - return ::CryptEnumProvidersW(dwIndex, pdwReserved, dwFlags, pdwProvType, szProvName, pcbProvName); -} - -BOOST_FORCEINLINE BOOL_ crypt_acquire_context( - HCRYPTPROV_ *phProv, - LPCWSTR_ szContainer, - LPCWSTR_ szProvider, - DWORD_ dwProvType, - DWORD_ dwFlags) -{ - return ::CryptAcquireContextW(phProv, szContainer, szProvider, dwProvType, dwFlags); -} - -#endif // BOOST_WINAPI_PARTITION_DESKTOP || BOOST_WINAPI_PARTITION_SYSTEM - -#if BOOST_WINAPI_PARTITION_APP_SYSTEM -BOOST_FORCEINLINE BOOL_ CryptReleaseContext(HCRYPTPROV_ hProv, DWORD_ dwFlags) -{ - return ::CryptReleaseContext(hProv, dwFlags); -} -#endif - -} -} - -#include <boost/winapi/detail/footer.hpp> - -#endif // BOOST_WINAPI_CRYPT_HPP_INCLUDED_ |