diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2018-05-31 20:20:24 +0100 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2018-05-31 20:20:24 +0100 |
commit | 9534a5e62dc2b81d001f98f1ed582bc3f1d39c80 (patch) | |
tree | e449a700dd80cd385dae290e507849c96069af53 /libstdc++-v3/src/filesystem/dir-common.h | |
parent | c9315097046c86e654871722e65f6da209e0c62a (diff) | |
download | gcc-9534a5e62dc2b81d001f98f1ed582bc3f1d39c80.zip gcc-9534a5e62dc2b81d001f98f1ed582bc3f1d39c80.tar.gz gcc-9534a5e62dc2b81d001f98f1ed582bc3f1d39c80.tar.bz2 |
PR libstdc++/78870 support std::filesystem on Windows
PR libstdc++/78870 support std::filesystem on Windows
* config.h.in: Regenerate.
* configure: Regenerate.
* configure.ac: Check for link, readlink and symlink.
* include/bits/fs_path.h (path::operator/=(const path&)): Move
definition out of class body.
(path::is_absolute(), path::_M_append(path)): Likewise.
(operator<<(basic_ostream, const path&)): Use std::quoted directly.
(operator>>(basic_istream, path&)): Likewise.
(u8path): Reorder definitions and fix Windows implementation.
(path::is_absolute()): Define inline and fix for Windows.
[!_GLIBCXX_FILESYSTEM_IS_WINDOWS] (path::operator/=(const path&)):
Define POSIX version inline.
(path::_M_append(path)): Define inline.
* include/experimental/bits/fs_path.h (path::is_absolute()): Move
definition out of class body.
(operator<<(basic_ostream, const path&)): Fix type of delimiter and
escape characters.
(operator>>(basic_istream, path&)): Likewise.
(path::is_absolute()): Define inline and fix for Windows.
* src/filesystem/dir-common.h (__gnu_posix): New namespace.
(__gnu_posix::char_type, __gnu_posix::DIR, __gnu_posix::dirent)
(__gnu_posix::opendir, __gnu_posix::readdir, __gnu_posix::closedir):
Define as adaptors for Windows functions/types or as
using-declarations for POSIX functions/types.
(_Dir_base, get_file_type): Qualify names to use declarations from
__gnu_posix namespace.
(_Dir_base::is_dor_or_dotdot): New helper functions.
* src/filesystem/dir.cc (_Dir, recursive_directory_iterator): Qualify
names to use declarations from __gnu_posix namespace.
* src/filesystem/ops-common.h (__gnu_posix): New nested namespace.
(__gnu_posix::open, __gnu_posix::close, __gnu_posix::stat_type)
(__gnu_posix::stat, __gnu_posix::lstat, __gnu_posix::mode_t)
(__gnu_posix::chmod, __gnu_posix::mkdir, __gnu_posix::getcwd)
(__gnu_posix::chdir, __gnu_posix::utimbuf, __gnu_posix::utime)
(__gnu_posix::rename, __gnu_posix::truncate, __gnu_posix::char_type):
Define as adaptors for Windows functions/types or as
using-declarations for POSIX functions/types.
(stat_type, do_copy_file): Qualify names to use declarations from
__gnu_posix namespace.
(do_space): Declare new function.
(make_file_type): Only use S_ISLNK if defined.
* src/filesystem/ops.cc (char_ptr, filesystem::canonical): Use
path::value_type not char.
(filesystem::copy, create_dir, filesystem::create_directory): Qualify
names to use declarations from __gnu_posix namespace.
(filesystem::create_hard_link): Check HAVE_LINK autoconf macro and
add implementation for Windows.
(filesystem::create_symlink): Check HAVE_SYMLINK autoconf macro.
(filesystem::current_path(error_code&)): Use __gnu_posix::getcwd.
[!_PC_PATH_MAX]: Don't use pathconf.
[PATH_MAX]: Use if defined.
(filesystem::current_path(const path&, error_code&))
(filesystem::equivalent, do_stat, filesystem::hard_link_count)
(filesystem::last_write_time, filesystem::permissions): Use names
from __gnu_posix.
(filesystem::read_symlink): Check HAVE_READLINK autoconf macro.
(filesystem::remove) [_GLIBCXX_FILESYSTEM_IS_WINDOWS]: Add
implementation for Windows.
(filesystem::rename, filesystem::resize_file): Use names from
__gnu_posix.
(filesystem::space): Use do_space.
[_GLIBCXX_FILESYSTEM_IS_WINDOWS]: Get absolute path to directory.
(filesystem::status, filesystem::symlink_status): Use names from
__gnu_posix.
(filesystem::temp_directory_path): Add implementation for Windows.
* src/filesystem/path.cc (dot): Define constant.
(path::replace_extension): Use dot.
(path::_M_find_extension): Likewise. Use path::string_type not
std::string.
(path::_M_split_cmpts): Use dot.
(filesystem_error::_M_get_what): Use u8string() not native().
* src/filesystem/std-dir.cc (_Dir, recursive_directory_iterator):
Qualify names to use declarations from __gnu_posix namespace.
* src/filesystem/std-ops.cc (filesystem::absolute(const path&)): Use
correct error_code.
(filesystem::absolute(const path&, error_code&)): Add implementation
for Windows.
(char_ptr, filesystem::canonical): Use path::value_type not char.
(do_copy_file): Use names from __gnu_posix.
[_GLIBCXX_FILESYSTEM_IS_WINDOWS]: Do not use fchmod, fchmodat or
sendfile.
(filesystem::copy, create_dir, filesystem::create_directory): Qualify
names to use declarations from __gnu_posix namespace.
(filesystem::create_hard_link): Check HAVE_LINK autoconf macro and
add implementation for Windows.
(filesystem::create_symlink): Check HAVE_SYMLINK autoconf macro.
(filesystem::current_path(error_code&)): Use __gnu_posix::getcwd.
[!_PC_PATH_MAX]: Don't use pathconf.
[PATH_MAX]: Use if defined.
(filesystem::current_path(const path&, error_code&))
(filesystem::equivalent, do_stat, filesystem::hard_link_count)
(filesystem::last_write_time, filesystem::permissions): Use names
from __gnu_posix.
(filesystem::read_symlink): Check HAVE_READLINK autoconf macro.
(filesystem::remove) [_GLIBCXX_FILESYSTEM_IS_WINDOWS]: Add
implementation for Windows.
(filesystem::rename, filesystem::resize_file): Use names from
__gnu_posix.
(do_space): Define.
(filesystem::space): Use do_space.
(filesystem::status, filesystem::symlink_status): Use names from
__gnu_posix.
(filesystem::temp_directory_path): Add implementation for Windows.
* src/filesystem/std-path.cc
[_GLIBCXX_FILESYSTEM_IS_WINDOWS] (path::operator/=(const path&)):
Define for Windows.
(dot): Define constant.
(path::replace_extension, is_dot): Use dot.
(path::lexically_normal): Check _M_type instead of calling
non-existent function.
(path::_M_find_extension): Use dot. Use path::string_type not
std::string.
(path::_M_split_cmpts): Use dot.
(filesystem_error::_M_get_what): Use u8string() not native().
* testsuite/27_io/filesystem/iterators/directory_iterator.cc: Do not
use symlinks.
* testsuite/27_io/filesystem/iterators/recursive_directory_iterator.cc:
Likewise.
* testsuite/27_io/filesystem/operations/absolute.cc: Use
__gnu_test::root_path() instead of "/" and add Windows-specific tests.
* testsuite/27_io/filesystem/operations/canonical.cc: Use
path::string() to get narrow string, not path::native().
* testsuite/27_io/filesystem/operations/copy.cc: Construct fstreams
with std::filesystem::path not std::basic_string.
* testsuite/27_io/filesystem/operations/copy_file.cc: Likewise.
* testsuite/27_io/filesystem/operations/exists.cc: Use
__gnu_test::root_path() instead of "/".
* testsuite/27_io/filesystem/operations/is_empty.cc: Construct
fstreams with std::filesystem::path not std::basic_string.
* testsuite/27_io/filesystem/operations/last_write_time.cc: Use
path::string() to get narrow string.
* testsuite/27_io/filesystem/operations/space.cc: Check results for
errors, expect sensible values otherwise.
* testsuite/27_io/filesystem/operations/temp_directory_path.cc: Add
helpers for adjusting the environment on Windows.
* testsuite/27_io/filesystem/path/append/path.cc: Test
Windows-specific behaviour.
* testsuite/27_io/filesystem/path/construct/format.cc: Fix creation
of path::string_type objects.
* testsuite/27_io/filesystem/path/construct/locale.cc: Compare native
string to wide string on Windows.
* testsuite/27_io/filesystem/path/decompose/root_directory.cc: Allow
for backslash as root-directory.
* testsuite/27_io/filesystem/path/decompose/stem.cc: Use
path::string() to get narrow string.
* testsuite/27_io/filesystem/path/itr/traversal.cc: Test Windows-style
paths.
* testsuite/27_io/filesystem/path/native/string.cc: Use string_type
not std::string.
* testsuite/27_io/filesystem/path/query/is_absolute.cc: Adjust for
different definintion of absolute paths on Windows.
* testsuite/experimental/filesystem/iterators/directory_iterator.cc:
Do not use symlinks.
* testsuite/experimental/filesystem/operations/absolute.cc: Test
Windows behaviour.
* testsuite/experimental/filesystem/operations/copy.cc: Construct
fstreams with NTCTS not std::basic_string.
* testsuite/experimental/filesystem/operations/copy_file.cc: Likewise.
* testsuite/experimental/filesystem/operations/exists.cc: Use
__gnu_test::root_path() instead of "/".
* testsuite/experimental/filesystem/operations/is_empty.cc: Construct
fstreams with NTCTS not std::basic_string.
* testsuite/experimental/filesystem/operations/last_write_time.cc:
Use path::string() to get narrow string.
* testsuite/experimental/filesystem/operations/space.cc: Use
__gnu_test::root_path() instead of "/".
* testsuite/experimental/filesystem/operations/temp_directory_path.cc:
Add helpers for adjusting the environment on Windows.
* testsuite/experimental/filesystem/path/append/path.cc: Use
path::string() to get narrow strings for comparisons.
* testsuite/experimental/filesystem/path/concat/path.cc: Likewise.
* testsuite/experimental/filesystem/path/decompose/root_directory.cc:
Likewise.
* testsuite/experimental/filesystem/path/decompose/stem.cc: Likewise.
* testsuite/experimental/filesystem/path/native/string.cc: Use
string_type not std::string.
* testsuite/experimental/filesystem/path/query/is_absolute.cc:
Adjust for different definintion of absolute paths on Windows.
* testsuite/util/testsuite_fs.h (__gnu_test::root_path()): New
function.
(__gnu_test::scoped_file): Construct fstreams with NTCTS not
std::basic_string.
From-SVN: r261034
Diffstat (limited to 'libstdc++-v3/src/filesystem/dir-common.h')
-rw-r--r-- | libstdc++-v3/src/filesystem/dir-common.h | 56 |
1 files changed, 42 insertions, 14 deletions
diff --git a/libstdc++-v3/src/filesystem/dir-common.h b/libstdc++-v3/src/filesystem/dir-common.h index 21ba01c..0387581 100644 --- a/libstdc++-v3/src/filesystem/dir-common.h +++ b/libstdc++-v3/src/filesystem/dir-common.h @@ -26,6 +26,9 @@ #define _GLIBCXX_DIR_COMMON_H 1 #include <string.h> // strcmp +#if _GLIBCXX_FILESYSTEM_IS_WINDOWS +#include <wchar.h> // wcscmp +#endif #ifdef _GLIBCXX_HAVE_DIRENT_H # ifdef _GLIBCXX_HAVE_SYS_TYPES_H # include <sys/types.h> @@ -35,26 +38,42 @@ # error "the <dirent.h> header is needed to build the Filesystem TS" #endif -#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS -# undef opendir -# define opendir _wopendir -#endif - namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace filesystem { +namespace __gnu_posix +{ +#if _GLIBCXX_FILESYSTEM_IS_WINDOWS +// Adapt the Windows _wxxx functions to look like POSIX xxx, but for wchar_t*. +using char_type = wchar_t; +using DIR = ::_WDIR; +using dirent = _wdirent; +inline DIR* opendir(const wchar_t* path) { return ::_wopendir(path); } +inline dirent* readdir(DIR* dir) { return ::_wreaddir(dir); } +inline int closedir(DIR* dir) { return ::_wclosedir(dir); } +#else +using char_type = char; +using DIR = ::DIR; +typedef struct ::dirent dirent; +using ::opendir; +using ::readdir; +using ::closedir; +#endif +} // namespace __gnu_posix + +namespace posix = __gnu_posix; struct _Dir_base { - _Dir_base(DIR* dirp = nullptr) : dirp(dirp) { } + _Dir_base(posix::DIR* dirp = nullptr) : dirp(dirp) { } // If no error occurs then dirp is non-null, // otherwise null (whether error ignored or not). - _Dir_base(const char* p, bool skip_permission_denied, + _Dir_base(const posix::char_type* pathname, bool skip_permission_denied, error_code& ec) noexcept - : dirp(::opendir(p)) + : dirp(posix::opendir(pathname)) { if (dirp) ec.clear(); @@ -72,22 +91,22 @@ struct _Dir_base _Dir_base& operator=(_Dir_base&&) = delete; - ~_Dir_base() { if (dirp) ::closedir(dirp); } + ~_Dir_base() { if (dirp) posix::closedir(dirp); } - const struct ::dirent* + const posix::dirent* advance(bool skip_permission_denied, error_code& ec) noexcept { ec.clear(); int err = std::exchange(errno, 0); - const struct ::dirent* entp = readdir(dirp); + const posix::dirent* entp = posix::readdir(dirp); // std::swap cannot be used with Bionic's errno err = std::exchange(errno, err); if (entp) { // skip past dot and dot-dot - if (!strcmp(entp->d_name, ".") || !strcmp(entp->d_name, "..")) + if (is_dot_or_dotdot(entp->d_name)) return advance(skip_permission_denied, ec); return entp; } @@ -105,15 +124,24 @@ struct _Dir_base } } - DIR* dirp; + static bool is_dot_or_dotdot(const char* s) noexcept + { return !strcmp(s, ".") || !strcmp(s, ".."); } + +#if _GLIBCXX_FILESYSTEM_IS_WINDOWS + static bool is_dot_or_dotdot(const wchar_t* s) noexcept + { return !wcscmp(s, L".") || !wcscmp(s, L".."); } +#endif + + posix::DIR* dirp; }; } // namespace filesystem // BEGIN/END macros must be defined before including this file. _GLIBCXX_BEGIN_NAMESPACE_FILESYSTEM + inline file_type -get_file_type(const ::dirent& d __attribute__((__unused__))) +get_file_type(const std::filesystem::__gnu_posix::dirent& d [[gnu::unused]]) { #ifdef _GLIBCXX_HAVE_STRUCT_DIRENT_D_TYPE switch (d.d_type) |