mirror of https://github.com/oxen-io/lokinet
Replace cppbackport with ghc-filesystem
From https://github.com/gulrak/filesystem which is more up-to-date and looks better maintained than cppbackport.pull/952/head
parent
9c7355ff9c
commit
8d2c22fc72
@ -1,21 +0,0 @@
|
||||
set(CXX_COMPAT_SRC
|
||||
cppbackport-master/lib/fs/rename.cpp
|
||||
cppbackport-master/lib/fs/filestatus.cpp
|
||||
cppbackport-master/lib/fs/filetype.cpp
|
||||
cppbackport-master/lib/fs/cleanpath.cpp
|
||||
cppbackport-master/lib/fs/perms.cpp
|
||||
cppbackport-master/lib/fs/equivalent.cpp
|
||||
cppbackport-master/lib/fs/current_path.cpp
|
||||
cppbackport-master/lib/fs/basename.cpp
|
||||
cppbackport-master/lib/fs/tempdir.cpp
|
||||
cppbackport-master/lib/fs/create_directory.cpp
|
||||
cppbackport-master/lib/fs/path.cpp
|
||||
cppbackport-master/lib/fs/remove.cpp
|
||||
cppbackport-master/lib/fs/diriter.cpp
|
||||
cppbackport-master/lib/fs/copyfile.cpp
|
||||
cppbackport-master/lib/fs/absolute.cpp
|
||||
cppbackport-master/lib/fs/direntry.cpp
|
||||
)
|
||||
|
||||
add_library(cppbackport STATIC ${CXX_COMPAT_SRC})
|
||||
target_include_directories(cppbackport PUBLIC cppbackport-master/lib)
|
@ -1 +0,0 @@
|
||||
*.user
|
@ -1,27 +0,0 @@
|
||||
Copyright (c) 2016, Pollard Banknote Limited
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of cppbackport nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
@ -1,60 +0,0 @@
|
||||
This is a backport of the current C++ standard library to C++03/11/14. Obviously not everything
|
||||
can be backported, but quite a bit can.
|
||||
|
||||
Quick Start
|
||||
===========
|
||||
|
||||
There are a couple of small examples to give you an idea of usage. If you have make and g++
|
||||
you can build things quickly enough:
|
||||
- clone the repo to /some/place/cppbackport
|
||||
- make a temp dir /wherever/you/wanna/build
|
||||
- cd /wherever/you/wanna/build
|
||||
- make -f /some/place/cppbackport/examples/Makefile
|
||||
|
||||
The examples are all setup to compile the cppbackport files as a static library (libcppbackport.a),
|
||||
and then link it with one of the main example files (ex., gibberish.cpp).
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
I recommend copying the lib directory into your project, and calling the included Makefile
|
||||
to create libcppbackport.a. Link that into your project, and add the appropriate include
|
||||
flags (ex., -iquotecppbackport).
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
Basically, #include "filesystem.h" or similar. Then use cpp namespace in place of std namespace.
|
||||
The headers are all named after their official counterparts, with the addition of the .h
|
||||
extension.
|
||||
|
||||
FAQ
|
||||
===
|
||||
**Who is this library suitable for?**
|
||||
Anyone, really. There are a few use cases:
|
||||
- The primary use case is to provide some newer features to people who are stuck with/choose to use an older compiler
|
||||
- Another use would be to soften the requirements of your own project (i.e., so your users can use an older compiler)
|
||||
- In some cases, this project may provide usable code before compilers support a standard. For example, C++17 at the moment isn't even standardized, *but* we basically know what's in it so we can start supporting it.
|
||||
|
||||
**What's the license?**
|
||||
BSD 3-clause. Use it. Contribute if you like. Don't blame us for things.
|
||||
|
||||
**What compiler(s)/platforms are supported**
|
||||
The development environment is Fedora 24 with GCC 6.1.1. I've used it with earlier versions
|
||||
of GCC (4.7.4, I think), and a semi-recent version of Clang. I've not tested under Windows, yet.
|
||||
|
||||
**Will this use C++11/14/17 if available?**
|
||||
Yes. Based on the value of the __cplusplus define, the files will simply #include the
|
||||
system header (as appropriate).
|
||||
|
||||
**Why not header-only?**
|
||||
I actually like the interface/implementation distinction. Header-only implementations (IMO)
|
||||
get way too large and the files are difficult to navigate. Also, save the compiler some work.
|
||||
Also, installing a lib isn't really that hard.
|
||||
|
||||
**Does it work on Windows?**
|
||||
Sorry, POSIX mostly. Would love for some Windows devs to help.
|
||||
|
||||
**Why not use Boost?**
|
||||
There's some overlap, but there are differences, too. And none of these things, *individually*
|
||||
are that big.
|
@ -1,2 +0,0 @@
|
||||
// Add predefined macros for your project here. For example:
|
||||
// #define THE_ANSWER 42
|
@ -1 +0,0 @@
|
||||
[General]
|
@ -1,144 +0,0 @@
|
||||
examples/any.cpp
|
||||
examples/clock.cpp
|
||||
examples/directory_listing.cpp
|
||||
examples/fbind.cpp
|
||||
examples/gibberish.cpp
|
||||
examples/hash.cpp
|
||||
examples/histogram.cpp
|
||||
examples/lshere.cpp
|
||||
examples/mathfns.cpp
|
||||
examples/maxalign.cpp
|
||||
examples/multithreading.cpp
|
||||
examples/multitype.cpp
|
||||
examples/now.cpp
|
||||
examples/optional.cpp
|
||||
examples/pathiter.cpp
|
||||
examples/singlell.cpp
|
||||
examples/smartptr.cpp
|
||||
examples/tempdir.cpp
|
||||
examples/testtraits.cpp
|
||||
examples/two_threads.cpp
|
||||
lib/algorithm.h
|
||||
lib/any.h
|
||||
lib/array.h
|
||||
lib/atomic.h
|
||||
lib/chrono.cpp
|
||||
lib/chrono.h
|
||||
lib/cmath.cpp
|
||||
lib/cmath.h
|
||||
lib/condition_variable.cpp
|
||||
lib/condition_variable.h
|
||||
lib/config/arch.h
|
||||
lib/config/os.h
|
||||
lib/cstdarg.h
|
||||
lib/cstddef.h
|
||||
lib/cstdint.h
|
||||
lib/cstdlib.h
|
||||
lib/filesystem.h
|
||||
lib/forward_list.h
|
||||
lib/fs/absolute.cpp
|
||||
lib/fs/absolute.h
|
||||
lib/fs/basename.cpp
|
||||
lib/fs/basename.h
|
||||
lib/fs/cleanpath.cpp
|
||||
lib/fs/cleanpath.h
|
||||
lib/fs/copyfile.cpp
|
||||
lib/fs/copyfile.h
|
||||
lib/fs/create_directory.cpp
|
||||
lib/fs/create_directory.h
|
||||
lib/fs/current_path.cpp
|
||||
lib/fs/current_path.h
|
||||
lib/fs/direntry.cpp
|
||||
lib/fs/direntry.h
|
||||
lib/fs/diriter.cpp
|
||||
lib/fs/diriter.h
|
||||
lib/fs/equivalent.cpp
|
||||
lib/fs/equivalent.h
|
||||
lib/fs/filestatus.cpp
|
||||
lib/fs/filestatus.h
|
||||
lib/fs/filetype.cpp
|
||||
lib/fs/filetype.h
|
||||
lib/fs/path.cpp
|
||||
lib/fs/path.h
|
||||
lib/fs/perms.cpp
|
||||
lib/fs/perms.h
|
||||
lib/fs/remove.cpp
|
||||
lib/fs/remove.h
|
||||
lib/fs/rename.cpp
|
||||
lib/fs/rename.h
|
||||
lib/fs/tempdir.cpp
|
||||
lib/fs/tempdir.h
|
||||
lib/functional.h
|
||||
lib/future.h
|
||||
lib/iterator.h
|
||||
lib/locale.h
|
||||
lib/memory.h
|
||||
lib/mutex.cpp
|
||||
lib/mutex.h
|
||||
lib/numeric.h
|
||||
lib/optional.h
|
||||
lib/random.cpp
|
||||
lib/random.h
|
||||
lib/ratio.h
|
||||
lib/rvalueref.h
|
||||
lib/shared_mutex.cpp
|
||||
lib/shared_mutex.h
|
||||
lib/string.h
|
||||
lib/string_view.h
|
||||
lib/system_error.h
|
||||
lib/thread.cpp
|
||||
lib/thread.h
|
||||
lib/traits/add_cv.h
|
||||
lib/traits/add_pointer.h
|
||||
lib/traits/add_reference.h
|
||||
lib/traits/alignment.h
|
||||
lib/traits/common_type.h
|
||||
lib/traits/conditional.h
|
||||
lib/traits/decay.h
|
||||
lib/traits/declval.h
|
||||
lib/traits/enable_if.h
|
||||
lib/traits/extent.h
|
||||
lib/traits/integral_constant.h
|
||||
lib/traits/is_arithmetic.h
|
||||
lib/traits/is_array.h
|
||||
lib/traits/is_base_of.h
|
||||
lib/traits/is_class_or_union.h
|
||||
lib/traits/is_compound.h
|
||||
lib/traits/is_const.h
|
||||
lib/traits/is_convertible.h
|
||||
lib/traits/is_enum.h
|
||||
lib/traits/is_floating_point.h
|
||||
lib/traits/is_function.h
|
||||
lib/traits/is_fundamental.h
|
||||
lib/traits/is_integral.h
|
||||
lib/traits/is_member_pointer.h
|
||||
lib/traits/is_null_pointer.h
|
||||
lib/traits/is_object.h
|
||||
lib/traits/is_pointer.h
|
||||
lib/traits/is_reference.h
|
||||
lib/traits/is_same.h
|
||||
lib/traits/is_scalar.h
|
||||
lib/traits/is_signed.h
|
||||
lib/traits/is_unsigned.h
|
||||
lib/traits/is_void.h
|
||||
lib/traits/is_volatile.h
|
||||
lib/traits/make_signed.h
|
||||
lib/traits/make_unsigned.h
|
||||
lib/traits/rank.h
|
||||
lib/traits/remove_cv.h
|
||||
lib/traits/remove_extent.h
|
||||
lib/traits/remove_pointer.h
|
||||
lib/traits/remove_reference.h
|
||||
lib/traits/result_of.h
|
||||
lib/traits/underlying_type.h
|
||||
lib/traits/void_t.h
|
||||
lib/traits/yesno.h
|
||||
lib/tuple.h
|
||||
lib/type_traits.h
|
||||
lib/unordered_map.h
|
||||
lib/unordered_set.h
|
||||
lib/utility.h
|
||||
lib/variant.h
|
||||
lib/version.h
|
||||
LICENSE
|
||||
README.md
|
@ -1,2 +0,0 @@
|
||||
lib
|
||||
.
|
@ -1,56 +0,0 @@
|
||||
/* Copyright (c) 2016, Pollard Banknote Limited
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef PBL_CONFIG_ARCH_H
|
||||
#define PBL_CONFIG_ARCH_H
|
||||
|
||||
#include <climits>
|
||||
|
||||
/* Whether or not the compiler supports long long and unsigned long long
|
||||
*/
|
||||
#ifndef HAS_LONG_LONG
|
||||
#if __cplusplus >= 201103L
|
||||
#define HAS_LONG_LONG
|
||||
#else
|
||||
#ifdef __GNUG__
|
||||
#ifdef __SIZEOF_LONG_LONG__
|
||||
#define HAS_LONG_LONG
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* The character type that char matches (i.e., signed or unsigned)
|
||||
*/
|
||||
#if CHAR_MIN < 0
|
||||
typedef signed char underlying_char_type;
|
||||
#else
|
||||
typedef unsigned char underlying_char_type;
|
||||
#endif
|
||||
|
||||
#endif // PBL_CONFIG_ARCH_H
|
@ -1,131 +0,0 @@
|
||||
/* Copyright (c) 2016, Pollard Banknote Limited
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/** Provide types, macros, and functions for the operating system
|
||||
*
|
||||
* This file provides a stable way to work with the OS. It provides
|
||||
* - namespaces and typedefs that can be used portably between OS's
|
||||
* - feature macros for enabling specific operating system capabilities
|
||||
*
|
||||
* @todo May want to rethink OS_POSIX as feature test macros since posix can
|
||||
* sorta be in Windows (ex., Cygwin)
|
||||
*/
|
||||
#ifndef PBL_CONFIG_OS_H
|
||||
#define PBL_CONFIG_OS_H
|
||||
|
||||
// =============================================================================
|
||||
// Determine the platform. Ex., Windows or POSIX. Define feature macros
|
||||
|
||||
#if ( defined( __unix__ ) || defined( __unix ) || ( defined( __APPLE__ ) && defined( __MACH__ ) ) )
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef _POSIX_VERSION
|
||||
// ISO POSIX.1 aka IEEE 1003.1
|
||||
|
||||
/// OS_POSIX - unistd.h is included and _POSIX_VERSION is defined
|
||||
#define OS_POSIX
|
||||
|
||||
#if _POSIX_VERSION >= 199506L
|
||||
// ISO POSIX.1-1996 aka IEEE 1003.1-1996
|
||||
#define POSIX_THREADS
|
||||
|
||||
#if ( _POSIX_VERSION >= 200112L )
|
||||
// ISO POSIX.1-2001 aka IEEE 1003.1-2001, aka Issue 6, aka SUSv3
|
||||
#define POSIX_ISSUE_6
|
||||
|
||||
#if ( _POSIX_VERSION >= 200809L )
|
||||
// ISO POSIX.1-2008, aka IEEE 1003.1-2008, aka Issue 7, aka SUSv4
|
||||
#define POSIX_ISSUE_7
|
||||
#endif // 2008
|
||||
#endif // 2001
|
||||
#endif // 1996
|
||||
#endif // ifdef _POSIX_VERSION
|
||||
#endif // if ( defined( __unix__ ) || defined( __unix ) || ( defined( __APPLE__ ) && defined( __MACH__ )))
|
||||
|
||||
#if defined( _WIN64 ) || defined( _WIN32 )
|
||||
#include <windows.h> /* MS Windows operating systems */
|
||||
#define OS_WINDOWS
|
||||
#endif
|
||||
|
||||
// =============================================================================
|
||||
// Determine basic types
|
||||
|
||||
#ifdef OS_POSIX
|
||||
#include <sys/types.h>
|
||||
namespace pbl
|
||||
{
|
||||
namespace os
|
||||
{
|
||||
// Identifies a user
|
||||
typedef uid_t user_id_type;
|
||||
|
||||
// Identifies a process
|
||||
typedef pid_t pid_type;
|
||||
}
|
||||
}
|
||||
#else
|
||||
#ifdef OS_WINDOWS
|
||||
namespace pbl
|
||||
{
|
||||
namespace os
|
||||
{
|
||||
typedef DWORD pid_type;
|
||||
}
|
||||
}
|
||||
#endif // Windows
|
||||
#endif // ifdef OS_POSIX
|
||||
|
||||
// =============================================================================
|
||||
// Determine multithreading types
|
||||
|
||||
#ifdef POSIX_THREADS
|
||||
#include <pthread.h>
|
||||
namespace pbl
|
||||
{
|
||||
namespace os
|
||||
{
|
||||
typedef pthread_t thread_type;
|
||||
typedef pthread_mutex_t mutex_type;
|
||||
typedef pthread_rwlock_t shared_mutex_type;
|
||||
typedef pthread_cond_t condition_variable_type;
|
||||
}
|
||||
}
|
||||
#else
|
||||
#ifdef OS_WINDOWS
|
||||
namespace pbl
|
||||
{
|
||||
namespace os
|
||||
{
|
||||
typedef HANDLE thread_type;
|
||||
typedef CRITICAL_SECTION mutex_type;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif // ifdef POSIX_THREADS
|
||||
|
||||
#endif // PBL_CONFIG_OS_H
|
@ -1,116 +0,0 @@
|
||||
/* Copyright (c) 2016, Pollard Banknote Limited
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/** @file version.h
|
||||
* @brief namespaces for C++11 and C++14
|
||||
*/
|
||||
#ifndef PBL_CPP_VERSION_H
|
||||
#define PBL_CPP_VERSION_H
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
/// @todo Value may not be correct, because as of writing C++17 isn't official
|
||||
#if __cplusplus >= 201703L
|
||||
#define CPP17
|
||||
#endif
|
||||
#if __cplusplus >= 201402L
|
||||
#define CPP14
|
||||
#endif
|
||||
#if __cplusplus >= 201103L
|
||||
#define CPP11
|
||||
#endif
|
||||
|
||||
/* Namespace macros. It's sometimes necessary to put something into the "std"
|
||||
* namespace. For example, a specialization of std::hash. These macros can be
|
||||
* used to put the code in the correct namespace.
|
||||
*/
|
||||
#ifdef CPP17
|
||||
#define CPP17_NAMESPACE std
|
||||
#else
|
||||
#define CPP17_NAMESPACE cpp17
|
||||
#endif
|
||||
#ifdef CPP14
|
||||
#define CPP14_NAMESPACE std
|
||||
#else
|
||||
#define CPP14_NAMESPACE cpp14
|
||||
#endif
|
||||
#ifdef CPP11
|
||||
#define CPP11_NAMESPACE std
|
||||
#else
|
||||
#define CPP11_NAMESPACE cpp11
|
||||
#endif
|
||||
|
||||
namespace cpp11
|
||||
{
|
||||
}
|
||||
|
||||
#ifndef CPP11
|
||||
namespace cpp11
|
||||
{
|
||||
class nullptr_t
|
||||
{
|
||||
public:
|
||||
template< class T >
|
||||
operator T*() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
template< class C, class T >
|
||||
operator T C::*( ) const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
private:
|
||||
void operator&() const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
const cpp11::nullptr_t nullptr = {};
|
||||
#endif // ifndef CPP11
|
||||
|
||||
namespace cpp14
|
||||
{
|
||||
}
|
||||
|
||||
namespace cpp17
|
||||
{
|
||||
}
|
||||
|
||||
/* cpp points to either std or cpp11/14/17 as appropriate
|
||||
*/
|
||||
namespace cpp
|
||||
{
|
||||
using namespace ::std;
|
||||
using namespace ::cpp11;
|
||||
using namespace ::cpp14;
|
||||
using namespace ::cpp17;
|
||||
}
|
||||
|
||||
#endif // PBL_CPP_VERSION_H
|
@ -1,58 +0,0 @@
|
||||
/* Copyright (c) 2016, Pollard Banknote Limited
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef PBL_CPP_FILESYSTEM_H
|
||||
#define PBL_CPP_FILESYSTEM_H
|
||||
|
||||
#include "cppbackport_version.h"
|
||||
|
||||
#if defined(CPP17) && defined(USE_CXX17_FILESYSTEM)
|
||||
#include <experimental/filesystem>
|
||||
#else
|
||||
// OpenBSD needs this
|
||||
// MacOS llvm 3.8 needs this
|
||||
#include "fs/absolute.h"
|
||||
#include "fs/basename.h"
|
||||
#include "fs/cleanpath.h"
|
||||
#include "fs/copyfile.h"
|
||||
#include "fs/create_directory.h"
|
||||
#include "fs/current_path.h"
|
||||
#include "fs/direntry.h"
|
||||
#include "fs/diriter.h"
|
||||
#include "fs/equivalent.h"
|
||||
#include "fs/filestatus.h"
|
||||
#include "fs/filetype.h"
|
||||
#include "fs/path.h"
|
||||
#include "fs/perms.h"
|
||||
#include "fs/remove.h"
|
||||
#include "fs/rename.h"
|
||||
#include "fs/tempdir.h"
|
||||
#endif // if not cpp17 and not openbsd
|
||||
|
||||
#endif // PBL_CPP_FILESYSTEM_H
|
@ -1,96 +0,0 @@
|
||||
/* Copyright (c) 2014, Pollard Banknote Limited
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "absolute.h"
|
||||
|
||||
#include <climits>
|
||||
#include <cstdlib>
|
||||
|
||||
#include "../config/os.h"
|
||||
|
||||
namespace cpp17
|
||||
{
|
||||
namespace filesystem
|
||||
{
|
||||
path
|
||||
absolute(const path& filename)
|
||||
{
|
||||
if(!filename.empty())
|
||||
{
|
||||
#if((defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809l) \
|
||||
|| defined(__GLIBC__)) \
|
||||
|| defined(ANDROID)
|
||||
// Preferred - POSIX-2008 and glibc will allocate the path buffer
|
||||
char* res = ::realpath(filename.c_str(), NULL);
|
||||
|
||||
if(res)
|
||||
{
|
||||
path s = res;
|
||||
::free(res);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
#else
|
||||
#ifdef _GNU_SOURCE
|
||||
// Maybe we can rely on the GNU extension
|
||||
char* res = ::canonicalize_file_name(filename.c_str());
|
||||
|
||||
if(res)
|
||||
{
|
||||
std::string s = res;
|
||||
::free(res);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
#elif(((defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L) \
|
||||
|| (defined(_XOPEN_VERSION) && _XOPEN_VERSION >= 500)) \
|
||||
&& defined(PATH_MAX))
|
||||
/// @todo PATH_MAX may be huge or -1, according to man pages for
|
||||
/// realpath
|
||||
char resolved[PATH_MAX + 1];
|
||||
char* res = ::realpath(filename.c_str(), resolved);
|
||||
|
||||
if(res)
|
||||
{
|
||||
return resolved;
|
||||
}
|
||||
|
||||
#else
|
||||
#error "No way to get absolute file path!"
|
||||
#endif // if 1
|
||||
#endif // if ( defined( _POSIX_VERSION ) && _POSIX_VERSION >= 200809l )
|
||||
}
|
||||
|
||||
return path();
|
||||
}
|
||||
|
||||
} // namespace filesystem
|
||||
} // namespace cpp17
|
@ -1,50 +0,0 @@
|
||||
/* Copyright (c) 2015, Pollard Banknote Limited
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef PBL_CPP_FS_ABSOLUTE_H
|
||||
#define PBL_CPP_FS_ABSOLUTE_H
|
||||
|
||||
#include "path.h"
|
||||
|
||||
namespace cpp17
|
||||
{
|
||||
namespace filesystem
|
||||
{
|
||||
|
||||
/** Get an absolute path of a file
|
||||
*
|
||||
* @param filepath The path of an (existing) file
|
||||
* @returns An absolute path that corresponds to the same file as filepath, or
|
||||
* an empty string if there is an error.
|
||||
*/
|
||||
path absolute(const path& filepath);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif // PBL_CPP_FS_ABSOLUTE_H
|
@ -1,207 +0,0 @@
|
||||
/* Copyright (c) 2014, Pollard Banknote Limited
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "basename.h"
|
||||
|
||||
#include "../config/os.h"
|
||||
#include "cleanpath.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
// the position following the previous occurrence of c (relative to position
|
||||
// j), or 0 if not. In this file, the first letter of a path component.
|
||||
std::size_t
|
||||
after_last(const std::string& s, char c, std::size_t j)
|
||||
{
|
||||
std::size_t i = s.find_last_of(c, j);
|
||||
|
||||
return i == std::string::npos ? 0 : i + 1;
|
||||
}
|
||||
|
||||
// (first character, length) of last path component in s or (0,0) for "."
|
||||
// or (npos, 0) if error
|
||||
std::pair< std::size_t, std::size_t >
|
||||
locate_last_path_component(const std::string& s)
|
||||
{
|
||||
if(s.empty())
|
||||
{
|
||||
// error
|
||||
return std::pair< std::size_t, std::size_t >(std::string::npos, 0);
|
||||
}
|
||||
|
||||
// j points to the last character in a component
|
||||
std::size_t j = s.find_last_not_of('/');
|
||||
unsigned depth = 0;
|
||||
|
||||
while(j != std::string::npos)
|
||||
{
|
||||
// i points to first character of a component
|
||||
// i <= j, because j never points to a '/'
|
||||
const std::size_t i = after_last(s, '/', j);
|
||||
|
||||
if(j - i + 1 == 1 && s[i] == '.')
|
||||
{
|
||||
// component is ".", basically ignore this component
|
||||
}
|
||||
else if(j - i + 1 == 2 && s[i] == '.' && s[i + 1] == '.')
|
||||
{
|
||||
// component is "..", ignore the next component
|
||||
++depth;
|
||||
}
|
||||
else
|
||||
{
|
||||
// found a "normal" path component
|
||||
if(depth == 0)
|
||||
{
|
||||
return std::pair< std::size_t, std::size_t >(i, j - i + 1);
|
||||
}
|
||||
|
||||
// ..but we're ignoring it
|
||||
--depth;
|
||||
}
|
||||
|
||||
if(i == 0)
|
||||
{
|
||||
if(depth == 0)
|
||||
{
|
||||
// "."
|
||||
return std::pair< std::size_t, std::size_t >(0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// error, path is malformed
|
||||
return std::pair< std::size_t, std::size_t >(std::string::npos, 0);
|
||||
}
|
||||
}
|
||||
|
||||
j = s.find_last_not_of('/', i - 1);
|
||||
}
|
||||
|
||||
// all slashes
|
||||
return std::pair< std::size_t, std::size_t >(0, 1);
|
||||
}
|
||||
|
||||
std::string
|
||||
basename_posix(const std::string& s)
|
||||
{
|
||||
const std::pair< std::size_t, std::size_t > range =
|
||||
locate_last_path_component(s);
|
||||
|
||||
if(range.first == std::string::npos)
|
||||
{
|
||||
return std::string();
|
||||
}
|
||||
|
||||
if(range.first == 0 && range.second == 0)
|
||||
{
|
||||
return ".";
|
||||
}
|
||||
|
||||
return s.substr(range.first, range.second);
|
||||
}
|
||||
std::string
|
||||
dirname_posix(const std::string& s)
|
||||
{
|
||||
const std::pair< std::size_t, std::size_t > range =
|
||||
locate_last_path_component(s);
|
||||
|
||||
// path was malformed
|
||||
if(range.first == std::string::npos)
|
||||
{
|
||||
return std::string();
|
||||
}
|
||||
|
||||
if(range.first == 0)
|
||||
{
|
||||
if(range.second == 0)
|
||||
{
|
||||
return "..";
|
||||
}
|
||||
|
||||
// could be '/', or could be a unpathed filename
|
||||
if(s[0] == '/')
|
||||
{
|
||||
return "/";
|
||||
}
|
||||
|
||||
return ".";
|
||||
}
|
||||
else
|
||||
{
|
||||
// leading directory
|
||||
return s.substr(0, range.first);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace cpp17
|
||||
{
|
||||
namespace filesystem
|
||||
{
|
||||
// Calls the basename_xxx appropriate for this platform
|
||||
std::string
|
||||
basename(const std::string& s)
|
||||
{
|
||||
#ifdef OS_POSIX
|
||||
return basename_posix(s);
|
||||
#else
|
||||
std::string t;
|
||||
char fname[_MAX_FNAME], ext[_MAX_EXT];
|
||||
_splitpath(s.c_str(), nullptr, nullptr, fname, ext);
|
||||
t = fname;
|
||||
t += ext;
|
||||
return t;
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string
|
||||
dirname(const std::string& s)
|
||||
{
|
||||
#ifdef OS_POSIX
|
||||
const std::string& t = dirname_posix(s);
|
||||
|
||||
if(t == ".")
|
||||
{
|
||||
return t;
|
||||
}
|
||||
|
||||
return cleanpath(t);
|
||||
|
||||
#else
|
||||
std::string t;
|
||||
char _dirname[_MAX_DIR];
|
||||
_splitpath(s.c_str(), nullptr, _dirname, nullptr, nullptr);
|
||||
t = _dirname;
|
||||
return t;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace filesystem
|
||||
} // namespace cpp17
|
@ -1,85 +0,0 @@
|
||||
/* Copyright (c) 2015, Pollard Banknote Limited
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef PBL_CPP_FS_BASENAME_H
|
||||
#define PBL_CPP_FS_BASENAME_H
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace cpp17
|
||||
{
|
||||
namespace filesystem
|
||||
{
|
||||
|
||||
/** Return the name of the file system component indicated by path
|
||||
*
|
||||
* @param path A file path
|
||||
* @returns The name of the directory or file that the path points to, or the
|
||||
* empty string if there's an error
|
||||
*
|
||||
* The exact behavior of this function is platform dependent, because paths are.
|
||||
* However, whatever the platform, it should return the name of the file or
|
||||
* directory pathed. Ex., on POSIX platforms it should return "readme.txt" for
|
||||
* "/home/user/documents/readme.txt"; similarly it should return "readme.txt"
|
||||
* for "C:\Windows\readme.txt" on Windows platforms.
|
||||
*
|
||||
* This function does not access the file system. It merely parses the string.
|
||||
* In particular, it does not check if the path is valid and/or accessible. It
|
||||
* also does not check that the component before "." or ".." is, in fact, a
|
||||
* directory.
|
||||
*
|
||||
* If the last component cannot be determined for whatever reason, the string is
|
||||
* considered malformed and the empty string is returned.
|
||||
*
|
||||
* @note Although the empty string is considered a malformed path, "." (and
|
||||
* anything equivalent) will return ".".
|
||||
*/
|
||||
std::string basename(const std::string& path);
|
||||
|
||||
/** Return the directory which has the last path component
|
||||
*
|
||||
* @param path A file path
|
||||
*
|
||||
* Determines the last path component as in basename, then returns directory
|
||||
* which contains that file system object. Ex., the dirname of
|
||||
* "/home/user/documents/readme.txt" is "/home/user/documents".
|
||||
*
|
||||
* As special cases, the dirname of a bare filename is "."; the dirname of
|
||||
* "." (or equivalent) is ".."; the dirname of the root directory is still the
|
||||
* root.
|
||||
*
|
||||
* If the path is malformed, the empty string is returned.
|
||||
*
|
||||
* @sa basename
|
||||
*/
|
||||
std::string dirname(const std::string& path);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif // PBL_FS_BASENAME_H
|
@ -1,144 +0,0 @@
|
||||
/* Copyright (c) 2014, Pollard Banknote Limited
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "cleanpath.h"
|
||||
#include <algorithm>
|
||||
|
||||
#if defined(_WIN32) && !defined(NOMINMAX)
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
|
||||
namespace cpp17
|
||||
{
|
||||
namespace filesystem
|
||||
{
|
||||
/// @todo Probably belongs in path.cpp
|
||||
std::string
|
||||
cleanpath(const std::string& s)
|
||||
{
|
||||
std::string t;
|
||||
|
||||
if(s.empty())
|
||||
{
|
||||
// error
|
||||
return t;
|
||||
}
|
||||
|
||||
const std::size_t n = s.length();
|
||||
|
||||
for(std::size_t i = 0; i < n;)
|
||||
{
|
||||
if(s[i] == '/')
|
||||
{
|
||||
// directory separator
|
||||
t.push_back('/');
|
||||
i = s.find_first_not_of('/', i);
|
||||
}
|
||||
else
|
||||
{
|
||||
// path component
|
||||
const std::size_t j = std::min(s.find('/', i), n);
|
||||
|
||||
if(s.compare(i, j - i, ".", 1) == 0)
|
||||
{
|
||||
// handle dot
|
||||
if(j < n)
|
||||
{
|
||||
i = s.find_first_not_of('/', j);
|
||||
}
|
||||
else
|
||||
{
|
||||
i = n;
|
||||
}
|
||||
}
|
||||
else if(s.compare(i, j - i, "..", 2) == 0)
|
||||
{
|
||||
// handle dot-dot
|
||||
const std::size_t l = t.length();
|
||||
|
||||
if(l == 0)
|
||||
{
|
||||
// no previous component (ex., "../src")
|
||||
t.assign("..", 2);
|
||||
i = j;
|
||||
}
|
||||
else
|
||||
{
|
||||
// remove previously copied component (unless root)
|
||||
if(l >= 2)
|
||||
{
|
||||
const std::size_t k = t.find_last_of('/', l - 2);
|
||||
|
||||
if(k == std::string::npos)
|
||||
{
|
||||
t.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
t.resize(k + 1);
|
||||
}
|
||||
}
|
||||
|
||||
if(j < n)
|
||||
{
|
||||
i = s.find_first_not_of('/', j);
|
||||
}
|
||||
else
|
||||
{
|
||||
i = n;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// append path component
|
||||
t.append(s, i, j - i);
|
||||
i = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(t.empty())
|
||||
{
|
||||
return ".";
|
||||
}
|
||||
|
||||
// drop trailing slashes
|
||||
const std::size_t i = t.find_last_not_of('/');
|
||||
|
||||
if(i != std::string::npos)
|
||||
{
|
||||
t.resize(i + 1);
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
} // namespace filesystem
|
||||
} // namespace cpp17
|
@ -1,64 +0,0 @@
|
||||
/* Copyright (c) 2015, Pollard Banknote Limited
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef PBL_CPP_FS_CLEANPATH_H
|
||||
#define PBL_CPP_FS_CLEANPATH_H
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace cpp17
|
||||
{
|
||||
namespace filesystem
|
||||
{
|
||||
/** Return a simplified version of path
|
||||
*
|
||||
* @param path A file system path
|
||||
*
|
||||
* Collapses multiple path separators (ex., as in "/home//user"); replaces
|
||||
* "name/." with "name" and "parent/child/.." with "parent"; removes
|
||||
* trailing slashes.
|
||||
*
|
||||
* The returned path is equivalent to the original path in the sense that it
|
||||
* identifies the same file system object. Specifically, relative paths are
|
||||
* preserved (ex., no simplification is done to the dot-dot in "../here").
|
||||
*
|
||||
* If the path is malformed, the empty string is returned. For this
|
||||
* function, really only the empty string itself is "malformed".
|
||||
*
|
||||
* @note This is a textual operation. It does not validate the string
|
||||
* against the file system or otherwise touch the file system.
|
||||
* @bug foo/bar/../baz may not point to /foo/baz if bar symlinks to
|
||||
* flip/flop
|
||||
*/
|
||||
std::string
|
||||
cleanpath(const std::string& path);
|
||||
} // namespace filesystem
|
||||
} // namespace cpp17
|
||||
|
||||
#endif // PBL_FS_CLEANPATH_H
|
@ -1,174 +0,0 @@
|
||||
/* Copyright (c) 2014, Pollard Banknote Limited
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "copyfile.h"
|
||||
|
||||
#include <cerrno>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
namespace cpp17
|
||||
{
|
||||
namespace filesystem
|
||||
{
|
||||
|
||||
/** Try to do copy the file as safely as possible (esp., gracefully handle
|
||||
* errors, avoid race conditions).
|
||||
*
|
||||
* @bug If there's an error while overwriting a file, the original is lost
|
||||
*/
|
||||
bool copy_file(
|
||||
const path& source,
|
||||
const path& dest,
|
||||
copy_options opt
|
||||
)
|
||||
{
|
||||
const int in = ::open(source.c_str(), O_RDONLY | O_CLOEXEC);
|
||||
|
||||
if ( in != -1 )
|
||||
{
|
||||
struct stat instat;
|
||||
|
||||
if ( ::fstat(in, &instat) == 0 && ( S_ISREG(instat.st_mode) || S_ISLNK(instat.st_mode) ) )
|
||||
{
|
||||
// Get the destination file
|
||||
int out = ::open(dest.c_str(), O_CREAT | O_EXCL | O_WRONLY | O_CLOEXEC, S_IWUSR);
|
||||
|
||||
if ( out == -1 && errno == EEXIST )
|
||||
{
|
||||
// File already exists -- maybe we will overwrite it
|
||||
out = ::open(dest.c_str(), O_WRONLY | O_CLOEXEC);
|
||||
|
||||
if ( out != -1 )
|
||||
{
|
||||
bool err = false;
|
||||
|
||||
struct stat outstat;
|
||||
|
||||
if ( ( ::fstat(out, &outstat) != 0 ) || ( instat.st_dev == outstat.st_dev && instat.st_ino == outstat.st_ino ) || ( ( opt & 7 ) == 0 ) )
|
||||
{
|
||||
// Couldn't stat, Same file, or bad copy_options
|
||||
err = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Replace file or not, depending on flags
|
||||
if ( (opt& copy_options::overwrite_existing) || ( (opt& copy_options::update_existing) && ( instat.st_mtime > outstat.st_mtime ) ) )
|
||||
{
|
||||
// replace the existing file
|
||||
if ( ::ftruncate(out, 0) != 0 )
|
||||
{
|
||||
err = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// do nothing
|
||||
::close(out);
|
||||
::close(in);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ( err )
|
||||
{
|
||||
::close(out);
|
||||
out = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Do we have a destination file?
|
||||
if ( out != -1 )
|
||||
{
|
||||
bool err = false;
|
||||
|
||||
while ( !err )
|
||||
{
|
||||
char buf[4096];
|
||||
|
||||
const ssize_t n = ::read( in, buf, sizeof( buf ) );
|
||||
|
||||
if ( n == -1 )
|
||||
{
|
||||
err = true;
|
||||
}
|
||||
else if ( n == 0 )
|
||||
{
|
||||
// EOF - copy has been successful
|
||||
::fchmod(out, instat.st_mode & 0777);
|
||||
::close(out);
|
||||
::close(in);
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
const char* p = buf;
|
||||
|
||||
while ( p - buf < n )
|
||||
{
|
||||
const ssize_t m = ::write( out, p, static_cast< std::size_t >( n - ( p - buf ) ) );
|
||||
|
||||
if ( m == -1 )
|
||||
{
|
||||
err = true;
|
||||
break;
|
||||
}
|
||||
|
||||
p += m;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove the incomplete file
|
||||
::unlink( dest.c_str() );
|
||||
::close(out);
|
||||
}
|
||||
}
|
||||
|
||||
::close(in);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool copy_file(
|
||||
const path& source,
|
||||
const path& dest
|
||||
)
|
||||
{
|
||||
return copy_file(source, dest, ::copy_options::none);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,81 +0,0 @@
|
||||
/* Copyright (c) 2015, Pollard Banknote Limited
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef PBL_CPP_FS_COPYFILE_H
|
||||
#define PBL_CPP_FS_COPYFILE_H
|
||||
|
||||
#include "path.h"
|
||||
|
||||
namespace copy_options
|
||||
{
|
||||
enum copy_options
|
||||
{
|
||||
none = 0,
|
||||
skip_existing = 1,
|
||||
overwrite_existing = 2,
|
||||
update_existing = 4,
|
||||
recursive = 8,
|
||||
copy_symlinks = 16,
|
||||
skip_symlinks = 32,
|
||||
directories_only = 64,
|
||||
create_symlinks = 128,
|
||||
create_hard_links = 256
|
||||
};
|
||||
}
|
||||
|
||||
namespace cpp17
|
||||
{
|
||||
namespace filesystem
|
||||
{
|
||||
typedef ::copy_options::copy_options copy_options;
|
||||
|
||||
/** Copy the file at source to dest
|
||||
*
|
||||
* @param source A file to copy
|
||||
* @param dest A file (including name) of the file to create
|
||||
* @returns true iff dest exists and is a copy of source
|
||||
*
|
||||
* If source does not exist or is not a file, the copy will fail.
|
||||
*
|
||||
* If dest exists, it will be overwritten. Dest will have the same file
|
||||
* permissions of source, if possible (subject to umask).
|
||||
*
|
||||
* This function copies the source file "safely". That is, in the event of an
|
||||
* error, dest is unaltered (or, if it didn't exist, continues to not exist).
|
||||
*
|
||||
* @todo The std::experimental::fs namespace defines copy and copy_file. This
|
||||
* function should be renamed accordingly.
|
||||
*/
|
||||
bool copy_file(const path &source, const path &dest, copy_options);
|
||||
|
||||
bool copy_file(const path& source, const path& dest);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif // PBL_CPP_FS_COPYFILE_H
|
@ -1,77 +0,0 @@
|
||||
/* Copyright (c) 2016, Pollard Banknote Limited
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "create_directory.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "perms.h"
|
||||
#include "filestatus.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <direct.h>
|
||||
#define mkdir(x, y) mkdir(x)
|
||||
#endif
|
||||
|
||||
namespace cpp17
|
||||
{
|
||||
namespace filesystem
|
||||
{
|
||||
bool
|
||||
create_directory(const path& s, __attribute__((unused)) std::error_code& ec)
|
||||
{
|
||||
if(s.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return ::mkdir(s.c_str(), static_cast< int >(perms::all)) == 0;
|
||||
}
|
||||
|
||||
bool
|
||||
create_directories(const path& s,
|
||||
__attribute__((unused)) std::error_code& ec)
|
||||
{
|
||||
path p = s.parent_path();
|
||||
|
||||
if(!p.empty())
|
||||
{
|
||||
std::error_code ec, ec2;
|
||||
if(!exists(p, ec) && !create_directories(p, ec2))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
std::error_code ec3;
|
||||
return create_directory(s, ec3);
|
||||
}
|
||||
|
||||
} // namespace filesystem
|
||||
} // namespace cpp17
|
@ -1,45 +0,0 @@
|
||||
/* Copyright (c) 2016, Pollard Banknote Limited
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef PBL_CPP_FS_CREATE_DIRECTORY_H
|
||||
#define PBL_CPP_FS_CREATE_DIRECTORY_H
|
||||
|
||||
#include "path.h"
|
||||
#include <system_error>
|
||||
|
||||
namespace cpp17
|
||||
{
|
||||
namespace filesystem
|
||||
{
|
||||
bool create_directory(const path&, std::error_code&);
|
||||
|
||||
bool create_directories(const path&, std::error_code&);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // PBL_CPP_FS_CREATE_DIRECTORY_H
|
@ -1,83 +0,0 @@
|
||||
/* Copyright (c) 2016, Pollard Banknote Limited
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "current_path.h"
|
||||
|
||||
#include <cerrno>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
namespace cpp17
|
||||
{
|
||||
namespace filesystem
|
||||
{
|
||||
path
|
||||
current_path()
|
||||
{
|
||||
char buf[4096];
|
||||
|
||||
if(::getcwd(buf, sizeof(buf)))
|
||||
{
|
||||
return buf;
|
||||
}
|
||||
|
||||
// Dynamically allocate larger buffers until cwd fits
|
||||
std::size_t size = 2 * sizeof(buf);
|
||||
|
||||
while(true)
|
||||
{
|
||||
char* q = new char[size];
|
||||
|
||||
if(::getcwd(q, size))
|
||||
{
|
||||
path p = q;
|
||||
delete[] q;
|
||||
|
||||
return p;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(errno == ERANGE)
|
||||
{
|
||||
delete[] q;
|
||||
size *= 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
delete[] q;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return path();
|
||||
}
|
||||
|
||||
} // namespace filesystem
|
||||
} // namespace cpp17
|
@ -1,42 +0,0 @@
|
||||
/* Copyright (c) 2016, Pollard Banknote Limited
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef PBL_CPP_FS_CURRENT_PATH_H
|
||||
#define PBL_CPP_FS_CURRENT_PATH_H
|
||||
|
||||
#include "path.h"
|
||||
|
||||
namespace cpp17
|
||||
{
|
||||
namespace filesystem
|
||||
{
|
||||
path current_path();
|
||||
}
|
||||
}
|
||||
|
||||
#endif // PBL_CPP_FS_CURRENT_PATH_H
|
@ -1,137 +0,0 @@
|
||||
/* Copyright (c) 2015, Pollard Banknote Limited
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "direntry.h"
|
||||
|
||||
namespace cpp17
|
||||
{
|
||||
namespace filesystem
|
||||
{
|
||||
directory_entry::directory_entry()
|
||||
{
|
||||
}
|
||||
|
||||
directory_entry::directory_entry(const directory_entry& e)
|
||||
: path_(e.path_)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
directory_entry::directory_entry(const ::cpp17::filesystem::path& p)
|
||||
: path_(p)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
directory_entry& directory_entry::operator=(const directory_entry& e)
|
||||
{
|
||||
path_ = e.path_;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void directory_entry::assign(const ::cpp17::filesystem::path& p)
|
||||
{
|
||||
path_ = p;
|
||||
}
|
||||
|
||||
void directory_entry::replace_filename(const ::cpp17::filesystem::path& p)
|
||||
{
|
||||
path_ = path_.parent_path() / p;
|
||||
}
|
||||
|
||||
const path& directory_entry::path() const
|
||||
{
|
||||
return path_;
|
||||
}
|
||||
|
||||
directory_entry::operator const ::cpp17::filesystem::path&() const
|
||||
{
|
||||
return path_;
|
||||
}
|
||||
|
||||
file_status directory_entry::status() const
|
||||
{
|
||||
return ::cpp17::filesystem::status(path_);
|
||||
}
|
||||
|
||||
file_status directory_entry::symlink_status() const
|
||||
{
|
||||
return ::cpp17::filesystem::symlink_status(path_);
|
||||
}
|
||||
|
||||
bool operator==(
|
||||
const directory_entry& a,
|
||||
const directory_entry& b
|
||||
)
|
||||
{
|
||||
return a.path() == b.path();
|
||||
}
|
||||
|
||||
bool operator!=(
|
||||
const directory_entry& a,
|
||||
const directory_entry& b
|
||||
)
|
||||
{
|
||||
return a.path() != b.path();
|
||||
}
|
||||
|
||||
bool operator<(
|
||||
const directory_entry& a,
|
||||
const directory_entry& b
|
||||
)
|
||||
{
|
||||
return a.path() < b.path();
|
||||
}
|
||||
|
||||
bool operator<=(
|
||||
const directory_entry& a,
|
||||
const directory_entry& b
|
||||
)
|
||||
{
|
||||
return a.path() <= b.path();
|
||||
}
|
||||
|
||||
bool operator>(
|
||||
const directory_entry& a,
|
||||
const directory_entry& b
|
||||
)
|
||||
{
|
||||
return a.path() > b.path();
|
||||
}
|
||||
|
||||
bool operator>=(
|
||||
const directory_entry& a,
|
||||
const directory_entry& b
|
||||
)
|
||||
{
|
||||
return a.path() >= b.path();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,71 +0,0 @@
|
||||
/* Copyright (c) 2015, Pollard Banknote Limited
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef PBL_CPP_FS_DIRENTRY_H
|
||||
#define PBL_CPP_FS_DIRENTRY_H
|
||||
|
||||
#include <iosfwd>
|
||||
#include "path.h"
|
||||
#include "filestatus.h"
|
||||
|
||||
namespace cpp17
|
||||
{
|
||||
namespace filesystem
|
||||
{
|
||||
/** Reperesents a file system object
|
||||
*/
|
||||
class directory_entry
|
||||
{
|
||||
public:
|
||||
directory_entry();
|
||||
directory_entry(const directory_entry&);
|
||||
explicit directory_entry(const path&);
|
||||
|
||||
directory_entry& operator=(const directory_entry&);
|
||||
void assign(const path&);
|
||||
void replace_filename(const path&);
|
||||
|
||||
const ::cpp17::filesystem::path& path() const;
|
||||
operator const ::cpp17::filesystem::path&() const;
|
||||
|
||||
file_status status() const;
|
||||
|
||||
file_status symlink_status() const;
|
||||
private:
|
||||
::cpp17::filesystem::path path_;
|
||||
};
|
||||
|
||||
bool operator==(const directory_entry&, const directory_entry&);
|
||||
bool operator!=(const directory_entry&, const directory_entry&);
|
||||
bool operator<(const directory_entry&, const directory_entry&);
|
||||
bool operator<=(const directory_entry&, const directory_entry&);
|
||||
bool operator>(const directory_entry&, const directory_entry&);
|
||||
bool operator>=(const directory_entry&, const directory_entry&);
|
||||
}
|
||||
}
|
||||
#endif // PBL_FS_DIRENTRY_H
|
@ -1,502 +0,0 @@
|
||||
/* Copyright (c) 2014, Pollard Banknote Limited
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "diriter.h"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <climits>
|
||||
|
||||
#include <dirent.h>
|
||||
#ifdef _WIN32
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
#include "direntry.h"
|
||||
#include "path.h"
|
||||
|
||||
namespace cpp17
|
||||
{
|
||||
namespace filesystem
|
||||
{
|
||||
/// @todo Could save the malloc/free (of e) if we mark end-of-directory
|
||||
class directory_iterator::impl
|
||||
{
|
||||
public:
|
||||
impl() : p(), d(0), e(0), info(), valid_info(false)
|
||||
{
|
||||
// printf("directory_iterator::impl::cstr\n");
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
explicit impl(const path& path_)
|
||||
: p(path_), d(0), e(0), info(), valid_info(false)
|
||||
{
|
||||
// printf("directory_iterator::impl::cstr path[%s]\n", path_.c_str());
|
||||
this->cPath = path_;
|
||||
d = ::opendir(path_.c_str());
|
||||
|
||||
if(d)
|
||||
{
|
||||
e = acquire();
|
||||
next();
|
||||
}
|
||||
}
|
||||
|
||||
~impl()
|
||||
{
|
||||
// printf("directory_iterator::impl::dstr [%s]\n", this->cPath.c_str());
|
||||
if(d)
|
||||
{
|
||||
release(); // free e
|
||||
::closedir(d);
|
||||
d = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
rewind()
|
||||
{
|
||||
// printf("directory_iterator::impl::rewind\n");
|
||||
if(d)
|
||||
{
|
||||
release();
|
||||
::closedir(d);
|
||||
}
|
||||
d = ::opendir(this->cPath.c_str());
|
||||
pos = 0;
|
||||
if(d)
|
||||
{
|
||||
e = acquire();
|
||||
next();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
seek(size_t seekPos)
|
||||
{
|
||||
// printf("directory_iterator::impl::seek\n");
|
||||
this->rewind();
|
||||
for(size_t i = 0; i < seekPos; i++)
|
||||
{
|
||||
this->next();
|
||||
}
|
||||
}
|
||||
|
||||
/** Test if this is an end iterator
|
||||
*/
|
||||
bool
|
||||
is_end() const
|
||||
{
|
||||
// printf("directory_iterator::impl::is_end\n");
|
||||
return !e;
|
||||
}
|
||||
|
||||
bool
|
||||
next()
|
||||
{
|
||||
// printf("directory_iterator::impl::next\n");
|
||||
if(d)
|
||||
{
|
||||
valid_info = false;
|
||||
|
||||
do
|
||||
{
|
||||
dirent* ptr = 0;
|
||||
|
||||
const int res = ::readdir_r(d, e, &ptr);
|
||||
|
||||
if(res != 0 || ptr == 0)
|
||||
{
|
||||
// error, or end of directory
|
||||
pos = 0;
|
||||
release();
|
||||
|
||||
return false;
|
||||
}
|
||||
} while(std::strcmp(e->d_name, ".") == 0
|
||||
|| std::strcmp(e->d_name, "..") == 0);
|
||||
|
||||
pos++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
path
|
||||
get_path() const
|
||||
{
|
||||
// printf("directory_iterator::impl::get_path\n");
|
||||
return e ? (p / e->d_name) : path();
|
||||
}
|
||||
|
||||
file_type
|
||||
type() const
|
||||
{
|
||||
// printf("directory_iterator::impl::type\n");
|
||||
if(e)
|
||||
{
|
||||
#ifdef DT_BLK
|
||||
switch(e->d_type)
|
||||
{
|
||||
case DT_FIFO:
|
||||
|
||||
return file_type::fifo;
|
||||
|
||||
case DT_CHR:
|
||||
|
||||
return file_type::character;
|
||||
|
||||
case DT_DIR:
|
||||
|
||||
return file_type::directory;
|
||||
|
||||
case DT_BLK:
|
||||
|
||||
return file_type::block;
|
||||
|
||||
case DT_REG:
|
||||
|
||||
return file_type::regular;
|
||||
|
||||
case DT_LNK:
|
||||
|
||||
return file_type::symlink;
|
||||
|
||||
case DT_SOCK:
|
||||
|
||||
return file_type::socket;
|
||||
|
||||
default:
|
||||
break;
|
||||
} // switch
|
||||
#endif
|
||||
}
|
||||
|
||||
return file_type::unknown;
|
||||
}
|
||||
|
||||
const directory_entry&
|
||||
get_reference()
|
||||
{
|
||||
// printf("directory_iterator::impl::get_reference\n");
|
||||
update();
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
const directory_entry*
|
||||
get_pointer()
|
||||
{
|
||||
// printf("directory_iterator::impl::get_pointer\n");
|
||||
update();
|
||||
|
||||
return &info;
|
||||
}
|
||||
|
||||
/// Position
|
||||
size_t pos;
|
||||
|
||||
// Path to directory
|
||||
path p;
|
||||
|
||||
private:
|
||||
void
|
||||
update()
|
||||
{
|
||||
// printf("directory_iterator::impl::update\n");
|
||||
if(!valid_info && e)
|
||||
{
|
||||
const path q = p / e->d_name;
|
||||
|
||||
info.assign(q);
|
||||
valid_info = true;
|
||||
}
|
||||
}
|
||||
|
||||
static dirent*
|
||||
acquire()
|
||||
{
|
||||
// printf("directory_iterator::impl::acquire\n");
|
||||
/* dirent::d_name is required to be at least NAME_MAX + 1 bytes.
|
||||
* However, some implementations use the struct hack and make d_name
|
||||
* 1 byte. Watch for this scenario and adjust accordingly.
|
||||
*/
|
||||
if(sizeof(static_cast< dirent* >(0)->d_name) < NAME_MAX + 1)
|
||||
{
|
||||
return static_cast< dirent* >(
|
||||
::malloc(sizeof(dirent) + NAME_MAX + 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
return static_cast< dirent* >(::malloc(sizeof(dirent)));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
release()
|
||||
{
|
||||
// printf("directory_iterator::impl::release\n");
|
||||
::free(e);
|
||||
e = 0;
|
||||
}
|
||||
|
||||
// constructor path
|
||||
path cPath;
|
||||
|
||||
/// Platform information
|
||||
DIR* d;
|
||||
|
||||
/// Platform information
|
||||
dirent* e;
|
||||
|
||||
directory_entry info;
|
||||
|
||||
bool valid_info; // info has been populated
|
||||
};
|
||||
|
||||
directory_iterator::directory_iterator() : pimpl(new impl)
|
||||
{
|
||||
}
|
||||
|
||||
directory_iterator::directory_iterator(const path& path_)
|
||||
: pimpl(new impl(path_))
|
||||
{
|
||||
}
|
||||
|
||||
// is this right
|
||||
directory_iterator::directory_iterator(directory_iterator const& src)
|
||||
: pimpl(new impl(src.pimpl->p.c_str()))
|
||||
{
|
||||
pimpl->seek(src.pimpl->pos);
|
||||
}
|
||||
|
||||
directory_iterator::~directory_iterator()
|
||||
{
|
||||
delete pimpl;
|
||||
}
|
||||
|
||||
directory_iterator::directory_iterator(directory_iterator const& src,
|
||||
int pos)
|
||||
{
|
||||
// printf("directory_iterator::directory_iterator copy at pos - pimpl[%x]
|
||||
// from[%s]\n", pimpl, src->path().c_str());
|
||||
pimpl = new impl(src.pimpl->p.c_str());
|
||||
pimpl->seek(pos);
|
||||
}
|
||||
|
||||
bool
|
||||
directory_iterator::operator==(const directory_iterator& i) const
|
||||
{
|
||||
// only equal if both are end iterators
|
||||
return pimpl->is_end() && i.pimpl->is_end();
|
||||
}
|
||||
|
||||
bool
|
||||
directory_iterator::operator!=(const directory_iterator& i) const
|
||||
{
|
||||
return !(pimpl->is_end() && i.pimpl->is_end());
|
||||
}
|
||||
|
||||
directory_iterator&
|
||||
directory_iterator::operator++()
|
||||
{
|
||||
pimpl->next();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
const directory_entry& directory_iterator::operator*() const
|
||||
{
|
||||
return pimpl->get_reference();
|
||||
}
|
||||
|
||||
const directory_entry* directory_iterator::operator->() const
|
||||
{
|
||||
return pimpl->get_pointer();
|
||||
}
|
||||
|
||||
file_type
|
||||
directory_iterator::type() const
|
||||
{
|
||||
return pimpl->type();
|
||||
}
|
||||
|
||||
void
|
||||
directory_iterator::swap(directory_iterator& d)
|
||||
{
|
||||
std::swap(pimpl, d.pimpl);
|
||||
}
|
||||
|
||||
// FIXME: this isn't right
|
||||
directory_iterator
|
||||
directory_iterator::begin()
|
||||
{
|
||||
return directory_iterator(*this, 0);
|
||||
/*
|
||||
printf("directory_iterator::directory_iterator::begin - start\n");
|
||||
size_t cur = pimpl->pos; // backup state
|
||||
printf("directory_iterator::directory_iterator::begin - was at
|
||||
[%zu][%s]\n", cur, this->pimpl->get_path().c_str()); pimpl->rewind();
|
||||
directory_iterator *ret = new directory_iterator(*this); // copy ourself
|
||||
pimpl->seek(cur); // restore state
|
||||
printf("directory_iterator::directory_iterator::begin - end\n");
|
||||
return *ret;
|
||||
*/
|
||||
}
|
||||
directory_iterator
|
||||
directory_iterator::end()
|
||||
{
|
||||
// return *(directory_iterator *)endPtr;
|
||||
// printf("directory_iterator::directory_iterator::end - start\n");
|
||||
size_t cur = pimpl->pos; // backup state
|
||||
// printf("directory_iterator::directory_iterator::end - was at
|
||||
// [%zu][%s]\n", cur, this->pimpl->get_path().c_str());
|
||||
// spool to the end
|
||||
size_t finalPos = pimpl->pos;
|
||||
while(!pimpl->is_end())
|
||||
{
|
||||
if(pimpl->next())
|
||||
{
|
||||
finalPos = pimpl->pos;
|
||||
}
|
||||
}
|
||||
// directory_iterator *ret = new directory_iterator(*this); // copy
|
||||
// ourself printf("directory_iterator::directory_iterator::end - now at
|
||||
// [%zu][%s]\n", pimpl->pos, this->pimpl->get_path().c_str());
|
||||
pimpl->seek(cur); // restore state
|
||||
return directory_iterator(*this, finalPos);
|
||||
// printf("directory_iterator::directory_iterator::end - end\n");
|
||||
// return *ret;
|
||||
}
|
||||
|
||||
//
|
||||
// recursive_directory_iterator
|
||||
//
|
||||
|
||||
recursive_directory_iterator::recursive_directory_iterator()
|
||||
{
|
||||
}
|
||||
|
||||
recursive_directory_iterator::recursive_directory_iterator(const path& p)
|
||||
{
|
||||
descend(p);
|
||||
}
|
||||
|
||||
recursive_directory_iterator::~recursive_directory_iterator()
|
||||
{
|
||||
while(!stack.empty())
|
||||
{
|
||||
ascend();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
recursive_directory_iterator::descend(const path& p)
|
||||
{
|
||||
directory_iterator it(p), end;
|
||||
|
||||
if(it != end)
|
||||
{
|
||||
directory_iterator* jt = new directory_iterator();
|
||||
jt->swap(it);
|
||||
stack.push(jt);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
recursive_directory_iterator::ascend()
|
||||
{
|
||||
delete stack.top();
|
||||
stack.pop();
|
||||
}
|
||||
|
||||
const directory_entry& recursive_directory_iterator::operator*() const
|
||||
{
|
||||
return *(*stack.top());
|
||||
}
|
||||
|
||||
const directory_entry* recursive_directory_iterator::operator->() const
|
||||
{
|
||||
return stack.top()->operator->();
|
||||
}
|
||||
|
||||
recursive_directory_iterator&
|
||||
recursive_directory_iterator::operator++()
|
||||
{
|
||||
if(stack.top()->type() == file_type::directory)
|
||||
{
|
||||
// go to directory's first child (if any)
|
||||
if(descend((*stack.top())->path()))
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
// move to sibling
|
||||
stack.top()->operator++();
|
||||
|
||||
directory_iterator end;
|
||||
|
||||
if(*(stack.top()) != end)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
// move to parent
|
||||
ascend();
|
||||
} while(!stack.empty());
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool
|
||||
recursive_directory_iterator::operator==(
|
||||
const recursive_directory_iterator& i) const
|
||||
{
|
||||
return stack.empty() && i.stack.empty();
|
||||
}
|
||||
|
||||
bool
|
||||
recursive_directory_iterator::operator!=(
|
||||
const recursive_directory_iterator& i) const
|
||||
{
|
||||
return !(stack.empty() && i.stack.empty());
|
||||
}
|
||||
|
||||
} // namespace filesystem
|
||||
} // namespace cpp17
|
@ -1,151 +0,0 @@
|
||||
/* Copyright (c) 2014, Pollard Banknote Limited
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef PBL_CPP_FS_DIRITER_H
|
||||
#define PBL_CPP_FS_DIRITER_H
|
||||
|
||||
#include <stack>
|
||||
#include "direntry.h"
|
||||
|
||||
namespace cpp17
|
||||
{
|
||||
namespace filesystem
|
||||
{
|
||||
|
||||
/** An iterator for traversing directory contents
|
||||
*
|
||||
* This class can be used for iterating over the contents of a directory. The
|
||||
* parameterized constructor will make a "begin" iterator, and the default
|
||||
* constructor will make an "end" iterator. One can dereference an iterator
|
||||
* to get a directory_entry describing the file/subdirectory.
|
||||
*
|
||||
* @note The "." and ".." 'files' are ignored by this iterator, since they are
|
||||
* not 'in' the directory.
|
||||
*
|
||||
* @note These objects are not copyable
|
||||
*
|
||||
* @note Only end iterators are ever considered equal. In particular, two
|
||||
* directory_iterator-s constructed with the same argument may not point to the
|
||||
* same file.
|
||||
*/
|
||||
class directory_iterator
|
||||
{
|
||||
public:
|
||||
/** Construct an iterator for a directory
|
||||
*
|
||||
* After construction, the iterator will point to the first file in the
|
||||
* directory.
|
||||
*/
|
||||
explicit directory_iterator(const path& path_);
|
||||
|
||||
/** Construct an end iterator
|
||||
*/
|
||||
directory_iterator();
|
||||
|
||||
/** Destructor
|
||||
*/
|
||||
~directory_iterator();
|
||||
|
||||
directory_iterator begin();
|
||||
directory_iterator end();
|
||||
|
||||
/** Test if two iterators are equal
|
||||
*
|
||||
* Only two end iterators are equal
|
||||
*/
|
||||
bool operator==(const directory_iterator& i) const;
|
||||
|
||||
/** Test if two iterators are not equal
|
||||
*
|
||||
* Only two end iterators are equal
|
||||
*/
|
||||
bool operator!=(const directory_iterator& i) const;
|
||||
|
||||
/** Move to the next file/subdirectory
|
||||
*/
|
||||
directory_iterator& operator++();
|
||||
|
||||
/** Get information for the file system object
|
||||
*
|
||||
* @note Causes a stat. If all you need is the type of the file system object,
|
||||
* use the cheaper type() member
|
||||
*/
|
||||
const directory_entry& operator*() const;
|
||||
|
||||
/** Get information for the file system object
|
||||
*
|
||||
* @note Causes a stat. If all you need is the type of the file system object,
|
||||
* use the cheaper type() member
|
||||
*/
|
||||
const directory_entry* operator->() const;
|
||||
|
||||
file_type type() const;
|
||||
|
||||
void swap(directory_iterator&);
|
||||
|
||||
// non-copyable
|
||||
// now it is
|
||||
directory_iterator(const directory_iterator&);
|
||||
directory_iterator& operator=(const directory_iterator&);
|
||||
|
||||
directory_iterator(const directory_iterator&, int pos);
|
||||
|
||||
//void *endPtr;
|
||||
private:
|
||||
class impl;
|
||||
|
||||
|
||||
impl* pimpl;
|
||||
};
|
||||
|
||||
class recursive_directory_iterator
|
||||
{
|
||||
public:
|
||||
recursive_directory_iterator();
|
||||
explicit recursive_directory_iterator(const path& p);
|
||||
~recursive_directory_iterator();
|
||||
|
||||
recursive_directory_iterator& operator++();
|
||||
const directory_entry& operator*() const;
|
||||
const directory_entry* operator->() const;
|
||||
bool operator==(const recursive_directory_iterator& i) const;
|
||||
bool operator!=(const recursive_directory_iterator& i) const;
|
||||
private:
|
||||
// non-copyable
|
||||
recursive_directory_iterator(const recursive_directory_iterator&);
|
||||
recursive_directory_iterator& operator=(const recursive_directory_iterator&);
|
||||
|
||||
bool descend(const path& p);
|
||||
void ascend();
|
||||
|
||||
std::stack< directory_iterator* > stack;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
#endif // PBL_FS_DIRITER_H
|
@ -1,60 +0,0 @@
|
||||
/* Copyright (c) 2018, Pollard Banknote Limited
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "equivalent.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace cpp17
|
||||
{
|
||||
namespace filesystem
|
||||
{
|
||||
bool equivalent(
|
||||
const path& p1,
|
||||
const path& p2
|
||||
)
|
||||
{
|
||||
struct stat s1;
|
||||
|
||||
if ( ::stat(p1.c_str(), &s1) == 0 )
|
||||
{
|
||||
struct stat s2;
|
||||
|
||||
if ( ::stat(p2.c_str(), &s2) == 0 )
|
||||
{
|
||||
return s1.st_ino == s2.st_ino && s1.st_dev == s2.st_dev;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
/* Copyright (c) 2018, Pollard Banknote Limited
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef PBL_CPP_FS_EQUIVALENT_H
|
||||
#define PBL_CPP_FS_EQUIVALENT_H
|
||||
|
||||
#include "path.h"
|
||||
|
||||
namespace cpp17
|
||||
{
|
||||
namespace filesystem
|
||||
{
|
||||
bool equivalent(const path&, const path&);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // PBL_CPP_FS_EQUIVALENT_H
|
@ -1,303 +0,0 @@
|
||||
/* Copyright (c) 2015, Pollard Banknote Limited
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "filestatus.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "path.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
::cpp17::filesystem::file_status
|
||||
from_mode_t(mode_t m)
|
||||
{
|
||||
::cpp17::filesystem::perms p =
|
||||
static_cast< cpp17::filesystem::perms >(m & 0xFFF);
|
||||
|
||||
::cpp17::filesystem::file_type t = file_type::unknown;
|
||||
|
||||
if(S_ISREG(m))
|
||||
{
|
||||
t = file_type::regular;
|
||||
}
|
||||
else if(S_ISDIR(m))
|
||||
{
|
||||
t = file_type::directory;
|
||||
}
|
||||
else if(S_ISCHR(m))
|
||||
{
|
||||
t = file_type::character;
|
||||
}
|
||||
else if(S_ISBLK(m))
|
||||
{
|
||||
t = file_type::block;
|
||||
}
|
||||
else if(S_ISFIFO(m))
|
||||
{
|
||||
t = file_type::fifo;
|
||||
}
|
||||
#ifndef _WIN32 // these only work on cygnus or msys2!
|
||||
else if(S_ISLNK(m))
|
||||
{
|
||||
t = file_type::symlink;
|
||||
}
|
||||
else if(S_ISSOCK(m))
|
||||
{
|
||||
t = file_type::socket;
|
||||
}
|
||||
#endif
|
||||
return ::cpp17::filesystem::file_status(t, p);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace cpp17
|
||||
{
|
||||
namespace filesystem
|
||||
{
|
||||
file_status::file_status(const file_status& s) : t(s.t), p(s.p)
|
||||
{
|
||||
}
|
||||
|
||||
file_status::file_status(file_type t_, perms p_) : t(t_), p(p_)
|
||||
{
|
||||
}
|
||||
|
||||
file_status&
|
||||
file_status::operator=(const file_status& s)
|
||||
{
|
||||
t = s.t;
|
||||
p = s.p;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
file_type
|
||||
file_status::type() const
|
||||
{
|
||||
return t;
|
||||
}
|
||||
|
||||
void
|
||||
file_status::type(file_type t_)
|
||||
{
|
||||
t = t_;
|
||||
}
|
||||
|
||||
perms
|
||||
file_status::permissions() const
|
||||
{
|
||||
return p;
|
||||
}
|
||||
|
||||
void
|
||||
file_status::permissions(perms p_)
|
||||
{
|
||||
p = p_;
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const file_status& fs)
|
||||
{
|
||||
os << fs.type() << "; " << fs.permissions();
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
file_status
|
||||
status(const path& path_)
|
||||
{
|
||||
if(!path_.empty())
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
if(::stat(path_.c_str(), &st) == 0)
|
||||
{
|
||||
return from_mode_t(st.st_mode);
|
||||
}
|
||||
}
|
||||
|
||||
return file_status();
|
||||
}
|
||||
|
||||
file_status
|
||||
symlink_status(const path& path_)
|
||||
{
|
||||
if(!path_.empty())
|
||||
{
|
||||
struct stat st;
|
||||
#ifndef _WIN32
|
||||
if(::lstat(path_.c_str(), &st) == 0)
|
||||
#else
|
||||
if(::stat(path_.c_str(), &st) == 0)
|
||||
#endif
|
||||
{
|
||||
return from_mode_t(st.st_mode);
|
||||
}
|
||||
}
|
||||
return file_status();
|
||||
}
|
||||
|
||||
bool
|
||||
status_known(file_status s)
|
||||
{
|
||||
return s.type() != file_type::none;
|
||||
}
|
||||
|
||||
bool
|
||||
exists(file_status s)
|
||||
{
|
||||
return status_known(s) && s.type() != file_type::not_found;
|
||||
}
|
||||
|
||||
bool
|
||||
exists(const path& p, __attribute__((unused)) std::error_code& ec)
|
||||
{
|
||||
return exists(status(p));
|
||||
}
|
||||
|
||||
bool
|
||||
is_block_file(file_status s)
|
||||
{
|
||||
return s.type() == file_type::block;
|
||||
}
|
||||
|
||||
bool
|
||||
is_block_file(const path& p)
|
||||
{
|
||||
return is_block_file(status(p));
|
||||
}
|
||||
|
||||
bool
|
||||
is_character_file(file_status s)
|
||||
{
|
||||
return s.type() == file_type::character;
|
||||
}
|
||||
|
||||
bool
|
||||
is_character_file(const path& p)
|
||||
{
|
||||
return is_character_file(status(p));
|
||||
}
|
||||
|
||||
bool
|
||||
is_fifo(file_status s)
|
||||
{
|
||||
return s.type() == file_type::fifo;
|
||||
}
|
||||
|
||||
bool
|
||||
is_fifo(const path& p)
|
||||
{
|
||||
return is_fifo(status(p));
|
||||
}
|
||||
|
||||
bool
|
||||
is_other(file_status s)
|
||||
{
|
||||
return exists(s) && !is_regular_file(s) && !is_directory(s)
|
||||
&& !is_symlink(s);
|
||||
}
|
||||
|
||||
bool
|
||||
is_other(const path& p)
|
||||
{
|
||||
return is_other(status(p));
|
||||
}
|
||||
|
||||
bool
|
||||
is_regular_file(file_status s)
|
||||
{
|
||||
return s.type() == file_type::regular;
|
||||
}
|
||||
|
||||
bool
|
||||
is_regular_file(const path& p)
|
||||
{
|
||||
return is_regular_file(status(p));
|
||||
}
|
||||
|
||||
bool
|
||||
is_socket(file_status s)
|
||||
{
|
||||
return s.type() == file_type::socket;
|
||||
}
|
||||
|
||||
bool
|
||||
is_socket(const path& p)
|
||||
{
|
||||
return is_socket(status(p));
|
||||
}
|
||||
|
||||
bool
|
||||
is_symlink(file_status s)
|
||||
{
|
||||
return s.type() == file_type::symlink;
|
||||
}
|
||||
|
||||
bool
|
||||
is_symlink(const path& p)
|
||||
{
|
||||
return is_symlink(status(p));
|
||||
}
|
||||
|
||||
bool
|
||||
is_directory(file_status s)
|
||||
{
|
||||
return s.type() == file_type::directory;
|
||||
}
|
||||
|
||||
bool
|
||||
is_directory(const path& p)
|
||||
{
|
||||
return is_directory(status(p));
|
||||
}
|
||||
|
||||
std::size_t
|
||||
file_size(const path& p)
|
||||
{
|
||||
if(!p.empty())
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
if(::stat(p.c_str(), &st) == 0)
|
||||
{
|
||||
return st.st_size;
|
||||
}
|
||||
}
|
||||
|
||||
return std::size_t(-1);
|
||||
}
|
||||
} // namespace filesystem
|
||||
} // namespace cpp17
|
@ -1,92 +0,0 @@
|
||||
/* Copyright (c) 2015, Pollard Banknote Limited
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef PBL_CPP_FS_FILESTATUS_H
|
||||
#define PBL_CPP_FS_FILESTATUS_H
|
||||
|
||||
#include <iosfwd>
|
||||
#include <system_error>
|
||||
#include "filetype.h"
|
||||
#include "perms.h"
|
||||
|
||||
namespace cpp17
|
||||
{
|
||||
namespace filesystem
|
||||
{
|
||||
class path;
|
||||
|
||||
/** Information about a file's type and permissions
|
||||
*
|
||||
* Due to the nature of the file system, the information may not be exactly
|
||||
* current.
|
||||
*/
|
||||
class file_status
|
||||
{
|
||||
public:
|
||||
file_status(const file_status&);
|
||||
explicit file_status(file_type = file_type::none, perms = perms::unknown);
|
||||
|
||||
file_status& operator=(const file_status&);
|
||||
file_type type() const;
|
||||
void type(file_type);
|
||||
perms permissions() const;
|
||||
void permissions(perms);
|
||||
private:
|
||||
file_type t;
|
||||
perms p;
|
||||
};
|
||||
|
||||
file_status status(const path&);
|
||||
file_status symlink_status(const path&);
|
||||
bool status_known(file_status);
|
||||
|
||||
bool exists(file_status);
|
||||
bool exists(const path&, std::error_code&);
|
||||
bool is_block_file(file_status);
|
||||
bool is_block_file(const path&);
|
||||
bool is_character_file(file_status);
|
||||
bool is_character_file(const path&);
|
||||
bool is_fifo(file_status);
|
||||
bool is_fifo(const path&);
|
||||
bool is_other(file_status);
|
||||
bool is_other(const path&);
|
||||
bool is_regular_file(file_status);
|
||||
bool is_regular_file(const path&);
|
||||
bool is_socket(file_status);
|
||||
bool is_socket(const path&);
|
||||
bool is_symlink(file_status);
|
||||
bool is_symlink(const path&);
|
||||
bool is_directory(file_status);
|
||||
bool is_directory(const path&);
|
||||
std::size_t file_size(const path&);
|
||||
|
||||
std::ostream& operator<<(std::ostream&, const file_status&);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // PBL_CPP_FS_FILESTATUS_H
|
@ -1,59 +0,0 @@
|
||||
/* Copyright (c) 2015, Pollard Banknote Limited
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "filetype.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
static const char* const friendly[] =
|
||||
{
|
||||
"Not found", "None", "Regular File", "Directory", "Symbolic Link",
|
||||
"Block Device", "Character Device", "FIFO", "Socket"
|
||||
};
|
||||
|
||||
namespace file_type
|
||||
{
|
||||
|
||||
std::ostream& operator<<(
|
||||
std::ostream& os,
|
||||
file_type t
|
||||
)
|
||||
{
|
||||
if ( -1 <= t && t < 8 )
|
||||
{
|
||||
os << friendly[t + 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
os << "Unknown";
|
||||
}
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
/* Copyright (c) 2015, Pollard Banknote Limited
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef PBL_CPP_FS_FILETYPE_H
|
||||
#define PBL_CPP_FS_FILETYPE_H
|
||||
#include <iosfwd>
|
||||
|
||||
namespace file_type
|
||||
{
|
||||
enum file_type
|
||||
{
|
||||
not_found = -1, none = 0, regular, directory, symlink, block, character, fifo,
|
||||
socket, unknown
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream&, file_type);
|
||||
}
|
||||
|
||||
namespace cpp17
|
||||
{
|
||||
namespace filesystem
|
||||
{
|
||||
/** Types of file system objects
|
||||
*/
|
||||
typedef ::file_type::file_type file_type;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // PBL_CPP_FS_FILETYPE_H
|
@ -1,698 +0,0 @@
|
||||
/* Copyright (c) 2015, Pollard Banknote Limited
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "path.h"
|
||||
#include <algorithm>
|
||||
namespace cpp17
|
||||
{
|
||||
namespace filesystem
|
||||
{
|
||||
path::path()
|
||||
{
|
||||
}
|
||||
|
||||
path::path(const string_type& s_) : s(s_)
|
||||
{
|
||||
}
|
||||
|
||||
path::path(const char* s_) : s(s_)
|
||||
{
|
||||
}
|
||||
|
||||
path::path(const path& p) : s(p.s)
|
||||
{
|
||||
}
|
||||
|
||||
path&
|
||||
path::operator=(const path& p)
|
||||
{
|
||||
s = p.s;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void
|
||||
path::clear()
|
||||
{
|
||||
s.clear();
|
||||
}
|
||||
|
||||
void
|
||||
path::swap(path& p)
|
||||
{
|
||||
std::swap(p.s, s);
|
||||
}
|
||||
|
||||
std::string
|
||||
path::string() const
|
||||
{
|
||||
return s;
|
||||
}
|
||||
|
||||
const char*
|
||||
path::c_str() const
|
||||
{
|
||||
return s.c_str();
|
||||
}
|
||||
|
||||
bool
|
||||
path::empty() const
|
||||
{
|
||||
return s.empty();
|
||||
}
|
||||
|
||||
path
|
||||
path::extension() const
|
||||
{
|
||||
const std::size_t i = s.find_last_of(preferred_separator);
|
||||
|
||||
const std::size_t j = (i == std::string::npos ? 0 : i + 1);
|
||||
|
||||
if(j < s.length())
|
||||
{
|
||||
if(s.compare(j, std::string::npos, ".", 1) != 0
|
||||
&& s.compare(j, std::string::npos, "..", 2) != 0)
|
||||
{
|
||||
const std::size_t k = s.find_last_of('.');
|
||||
|
||||
if(k != std::string::npos && j <= k)
|
||||
{
|
||||
return s.substr(k);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return path();
|
||||
}
|
||||
|
||||
path
|
||||
path::filename() const
|
||||
{
|
||||
const std::size_t i = s.find_last_of(preferred_separator);
|
||||
|
||||
if(i == std::string::npos)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
if(i + 1 < s.length())
|
||||
{
|
||||
return path(s.substr(i + 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
return ".";
|
||||
}
|
||||
}
|
||||
|
||||
path
|
||||
path::parent_path() const
|
||||
{
|
||||
const std::size_t i = s.find_last_of(preferred_separator);
|
||||
|
||||
if(i == std::string::npos)
|
||||
{
|
||||
return path();
|
||||
}
|
||||
|
||||
return path(s.substr(0, i));
|
||||
}
|
||||
|
||||
path&
|
||||
path::remove_filename()
|
||||
{
|
||||
const std::size_t i = s.find_last_of(preferred_separator);
|
||||
|
||||
if(i != std::string::npos)
|
||||
{
|
||||
s.resize(i);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
path&
|
||||
path::replace_filename(const path& p)
|
||||
{
|
||||
const std::size_t i = s.find_last_of(preferred_separator);
|
||||
|
||||
if(i != std::string::npos)
|
||||
{
|
||||
s.resize(i);
|
||||
append(p);
|
||||
}
|
||||
else
|
||||
{
|
||||
assign(p);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
path::operator string_type() const
|
||||
{
|
||||
return s;
|
||||
}
|
||||
|
||||
path&
|
||||
path::append(const path& p)
|
||||
{
|
||||
bool sep = true;
|
||||
|
||||
if(!s.empty() && s[s.length() - 1] == preferred_separator)
|
||||
{
|
||||
sep = false;
|
||||
}
|
||||
else if(s.empty())
|
||||
{
|
||||
sep = false;
|
||||
}
|
||||
else if(p.empty() || p.s[0] == preferred_separator)
|
||||
{
|
||||
sep = false;
|
||||
}
|
||||
|
||||
if(sep)
|
||||
{
|
||||
s += preferred_separator;
|
||||
}
|
||||
|
||||
s.append(p.native());
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
path&
|
||||
path::operator/=(const path& p)
|
||||
{
|
||||
return append(p);
|
||||
}
|
||||
|
||||
const std::string&
|
||||
path::native() const
|
||||
{
|
||||
return s;
|
||||
}
|
||||
|
||||
path
|
||||
path::lexically_relative(const path& p) const
|
||||
{
|
||||
const_iterator first1 = begin(), last1 = end();
|
||||
const_iterator first2 = p.begin(), last2 = p.end();
|
||||
|
||||
const_iterator it = first1;
|
||||
const_iterator jt = first2;
|
||||
|
||||
while(it != last1 && jt != last2 && *it == *jt)
|
||||
{
|
||||
++it, ++jt;
|
||||
}
|
||||
|
||||
if(it == first1 || jt == first2)
|
||||
{
|
||||
return path();
|
||||
}
|
||||
|
||||
if(it == last1 && jt == last2)
|
||||
{
|
||||
return path(".");
|
||||
}
|
||||
|
||||
path r;
|
||||
|
||||
for(; jt != last2; ++jt)
|
||||
{
|
||||
r /= "..";
|
||||
}
|
||||
|
||||
for(; it != last1; ++it)
|
||||
{
|
||||
r /= *it;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
bool
|
||||
path::is_absolute() const
|
||||
{
|
||||
return !s.empty() && s[0] == preferred_separator;
|
||||
}
|
||||
|
||||
path
|
||||
path::lexically_normal() const
|
||||
{
|
||||
std::string t;
|
||||
|
||||
if(s.empty())
|
||||
{
|
||||
// error
|
||||
return t;
|
||||
}
|
||||
|
||||
const std::size_t n = s.length();
|
||||
|
||||
for(std::size_t i = 0; i < n;)
|
||||
{
|
||||
if(s[i] == '/')
|
||||
{
|
||||
// directory separator
|
||||
t.push_back('/');
|
||||
i = s.find_first_not_of('/', i);
|
||||
}
|
||||
else
|
||||
{
|
||||
// path component
|
||||
const std::size_t j = std::min(s.find('/', i), n);
|
||||
|
||||
if(s.compare(i, j - i, ".", 1) == 0)
|
||||
{
|
||||
// handle dot
|
||||
if(j < n)
|
||||
{
|
||||
i = s.find_first_not_of('/', j);
|
||||
}
|
||||
else
|
||||
{
|
||||
i = n;
|
||||
}
|
||||
}
|
||||
else if(s.compare(i, j - i, "..", 2) == 0)
|
||||
{
|
||||
// handle dot-dot
|
||||
const std::size_t l = t.length();
|
||||
|
||||
if(l == 0)
|
||||
{
|
||||
// no previous component (ex., "../src")
|
||||
t.assign("..", 2);
|
||||
i = j;
|
||||
}
|
||||
else
|
||||
{
|
||||
// remove previously copied component (unless root)
|
||||
if(l >= 2)
|
||||
{
|
||||
const std::size_t k = t.find_last_of('/', l - 2);
|
||||
|
||||
if(k == std::string::npos)
|
||||
{
|
||||
t.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
t.resize(k + 1);
|
||||
}
|
||||
}
|
||||
|
||||
if(j < n)
|
||||
{
|
||||
i = s.find_first_not_of('/', j);
|
||||
}
|
||||
else
|
||||
{
|
||||
i = n;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// append path component
|
||||
t.append(s, i, j - i);
|
||||
i = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(t.empty())
|
||||
{
|
||||
return ".";
|
||||
}
|
||||
|
||||
// drop trailing slashes
|
||||
const std::size_t i = t.find_last_not_of('/');
|
||||
|
||||
if(i != std::string::npos)
|
||||
{
|
||||
t.resize(i + 1);
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
int
|
||||
path::compare(const path& p) const
|
||||
{
|
||||
const_iterator first1 = begin(), last1 = end();
|
||||
const_iterator first2 = p.begin(), last2 = p.end();
|
||||
|
||||
while(first1 != last1 && first2 != last2)
|
||||
{
|
||||
if(first1->native() < first2->native())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(first2->native() < first1->native())
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
++first1;
|
||||
++first2;
|
||||
}
|
||||
|
||||
if(first1 != last1)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(first2 != last2)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
path::const_iterator
|
||||
path::begin() const
|
||||
{
|
||||
begin_iterator_tag tag;
|
||||
|
||||
return const_iterator(this, tag);
|
||||
}
|
||||
|
||||
path::const_iterator
|
||||
path::end() const
|
||||
{
|
||||
end_iterator_tag tag;
|
||||
|
||||
return const_iterator(this, tag);
|
||||
}
|
||||
|
||||
path::const_iterator::const_iterator()
|
||||
: parent(0), first(std::string::npos), last(std::string::npos), value()
|
||||
{
|
||||
}
|
||||
|
||||
path::const_iterator::const_iterator(const path* parent_,
|
||||
begin_iterator_tag)
|
||||
: parent(parent_), first(0)
|
||||
{
|
||||
if(parent->s.empty())
|
||||
{
|
||||
first = std::string::npos;
|
||||
last = std::string::npos;
|
||||
}
|
||||
else
|
||||
{
|
||||
const std::size_t k = parent->s.find_first_of(preferred_separator);
|
||||
|
||||
if(k == std::string::npos)
|
||||
{
|
||||
last = parent->s.length();
|
||||
}
|
||||
else if(k == 0)
|
||||
{
|
||||
last = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
last = k;
|
||||
}
|
||||
|
||||
value = parent->s.substr(0, last);
|
||||
}
|
||||
}
|
||||
|
||||
path::const_iterator::const_iterator(const path* p, end_iterator_tag)
|
||||
: parent(p), first(std::string::npos), last(std::string::npos), value()
|
||||
{
|
||||
}
|
||||
|
||||
path::const_iterator&
|
||||
path::const_iterator::operator++()
|
||||
{
|
||||
if(parent)
|
||||
{
|
||||
if(last < parent->s.length())
|
||||
{
|
||||
// find next component
|
||||
const std::size_t j =
|
||||
parent->s.find_first_not_of(preferred_separator, last);
|
||||
|
||||
if(j == std::string::npos)
|
||||
{
|
||||
if(parent->s[first] == preferred_separator)
|
||||
{
|
||||
// path to root
|
||||
first = std::string::npos;
|
||||
last = std::string::npos;
|
||||
value.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
// ends with directory
|
||||
first = parent->s.length();
|
||||
last = std::string::npos;
|
||||
value = ".";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
first = j;
|
||||
|
||||
// next path component
|
||||
const std::size_t k =
|
||||
parent->s.find_first_of(preferred_separator, j);
|
||||
|
||||
if(k == std::string::npos)
|
||||
{
|
||||
last = parent->s.length();
|
||||
}
|
||||
else
|
||||
{
|
||||
last = k;
|
||||
}
|
||||
|
||||
value = parent->s.substr(first, last - first);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// go to end iterator
|
||||
first = std::string::npos;
|
||||
last = std::string::npos;
|
||||
value.clear();
|
||||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
path::const_iterator
|
||||
path::const_iterator::operator++(int)
|
||||
{
|
||||
const_iterator t = *this;
|
||||
|
||||
operator++();
|
||||
return t;
|
||||
}
|
||||
|
||||
path::const_iterator&
|
||||
path::const_iterator::operator--()
|
||||
{
|
||||
if(parent && first != 0)
|
||||
{
|
||||
if(first == std::string::npos)
|
||||
{
|
||||
// end iterator
|
||||
if(!parent->s.empty())
|
||||
{
|
||||
const std::size_t j = parent->s.find_last_of(preferred_separator);
|
||||
|
||||
if(j == std::string::npos)
|
||||
{
|
||||
// single path component
|
||||
first = 0;
|
||||
last = parent->s.length();
|
||||
value = parent->s;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(j + 1 < parent->s.length())
|
||||
{
|
||||
// trailing filename
|
||||
first = j + 1;
|
||||
last = parent->s.length();
|
||||
value = parent->s.substr(first, last - first);
|
||||
}
|
||||
else
|
||||
{
|
||||
// trailing directory, or root
|
||||
const std::size_t k =
|
||||
parent->s.find_last_not_of(preferred_separator, j);
|
||||
|
||||
if(k == std::string::npos)
|
||||
{
|
||||
first = 0;
|
||||
last = 1;
|
||||
value = parent->s.substr(first, last - first);
|
||||
}
|
||||
else
|
||||
{
|
||||
first = parent->s.length();
|
||||
last = std::string::npos;
|
||||
value = ".";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// on an actual path component, or the fake "."
|
||||
const std::size_t j =
|
||||
parent->s.find_last_not_of(preferred_separator, first - 1);
|
||||
|
||||
if(j == std::string::npos)
|
||||
{
|
||||
// beginning of absolute path
|
||||
first = 0;
|
||||
last = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
last = j + 1;
|
||||
const std::size_t k =
|
||||
parent->s.find_last_of(preferred_separator, j);
|
||||
|
||||
if(k == std::string::npos)
|
||||
{
|
||||
first = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
first = k + 1;
|
||||
}
|
||||
}
|
||||
|
||||
value = parent->s.substr(first, last - first);
|
||||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
path::const_iterator
|
||||
path::const_iterator::operator--(int)
|
||||
{
|
||||
const_iterator t = *this;
|
||||
|
||||
operator--();
|
||||
return t;
|
||||
}
|
||||
|
||||
bool
|
||||
path::const_iterator::operator==(const const_iterator& o) const
|
||||
{
|
||||
return parent == o.parent && first == o.first;
|
||||
}
|
||||
|
||||
bool
|
||||
path::const_iterator::operator!=(const const_iterator& o) const
|
||||
{
|
||||
return parent != o.parent || first != o.first;
|
||||
}
|
||||
|
||||
const path& path::const_iterator::operator*() const
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
const path* path::const_iterator::operator->() const
|
||||
{
|
||||
return &value;
|
||||
}
|
||||
|
||||
path
|
||||
operator/(const path& lhs, const path& rhs)
|
||||
{
|
||||
path res = lhs;
|
||||
|
||||
res.append(rhs);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const path& p)
|
||||
{
|
||||
return os << p.string();
|
||||
}
|
||||
|
||||
bool
|
||||
operator==(const path& l, const path& r)
|
||||
{
|
||||
return l.compare(r) == 0;
|
||||
}
|
||||
|
||||
bool
|
||||
operator!=(const path& l, const path& r)
|
||||
{
|
||||
return l.compare(r) != 0;
|
||||
}
|
||||
|
||||
bool
|
||||
operator<(const path& l, const path& r)
|
||||
{
|
||||
return l.compare(r) < 0;
|
||||
}
|
||||
|
||||
bool
|
||||
operator<=(const path& l, const path& r)
|
||||
{
|
||||
return l.compare(r) <= 0;
|
||||
}
|
||||
|
||||
bool
|
||||
operator>(const path& l, const path& r)
|
||||
{
|
||||
return l.compare(r) > 0;
|
||||
}
|
||||
|
||||
bool
|
||||
operator>=(const path& l, const path& r)
|
||||
{
|
||||
return l.compare(r) >= 0;
|
||||
}
|
||||
|
||||
} // namespace filesystem
|
||||
} // namespace cpp17
|
@ -1,192 +0,0 @@
|
||||
/* Copyright (c) 2015, Pollard Banknote Limited
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef PBL_CPP_FS_PATH_H
|
||||
#define PBL_CPP_FS_PATH_H
|
||||
#include <string>
|
||||
#include <iosfwd>
|
||||
#include <iterator>
|
||||
#include <iostream>
|
||||
|
||||
namespace cpp17
|
||||
{
|
||||
namespace filesystem
|
||||
{
|
||||
/** A file path
|
||||
*
|
||||
* A partial implementation of std::experimental::filesystem::path
|
||||
* @todo Construct from the other basic_string types and pointer-to-char16_t, etc.
|
||||
* @bug Throughout, preferred_separator is used incorrectly
|
||||
*/
|
||||
class path
|
||||
{
|
||||
public:
|
||||
typedef char value_type;
|
||||
typedef std::basic_string< value_type > string_type;
|
||||
|
||||
static const value_type preferred_separator = '/';
|
||||
|
||||
class const_iterator;
|
||||
|
||||
typedef const_iterator iterator;
|
||||
|
||||
/// An empty path
|
||||
path();
|
||||
|
||||
/// Construct a path form the given string
|
||||
path(const string_type&);
|
||||
|
||||
path(const char*);
|
||||
|
||||
template< typename Iterator >
|
||||
path(Iterator first, Iterator last) : s(first, last)
|
||||
{
|
||||
}
|
||||
|
||||
/// Copy constructor
|
||||
path(const path&);
|
||||
|
||||
/// Copy assignment
|
||||
path& operator=(const path&);
|
||||
|
||||
template< typename Source >
|
||||
path& operator=(const Source& source)
|
||||
{
|
||||
return assign(source);
|
||||
}
|
||||
|
||||
template< typename Source >
|
||||
path& assign(const Source& source)
|
||||
{
|
||||
s = string_type(source);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template< typename Iterator >
|
||||
path& assign(
|
||||
Iterator first,
|
||||
Iterator last
|
||||
)
|
||||
{
|
||||
s = string_type(first, last);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Clear the path
|
||||
void clear();
|
||||
|
||||
/// Swap the two paths
|
||||
void swap(path&);
|
||||
|
||||
std::string string() const;
|
||||
const char* c_str() const;
|
||||
path& operator/=(const path&);
|
||||
path& append(const path&);
|
||||
|
||||
/// Is the path empty (i.e., "")
|
||||
bool empty() const;
|
||||
const std::string& native() const;
|
||||
|
||||
path extension() const;
|
||||
path filename() const;
|
||||
path parent_path() const;
|
||||
path& remove_filename();
|
||||
path& replace_filename(const path&);
|
||||
|
||||
operator string_type() const;
|
||||
|
||||
bool is_absolute() const;
|
||||
|
||||
path lexically_normal() const;
|
||||
path lexically_relative(const path&) const;
|
||||
|
||||
int compare(const path&) const;
|
||||
|
||||
const_iterator begin() const;
|
||||
const_iterator end() const;
|
||||
private:
|
||||
struct begin_iterator_tag {};
|
||||
struct end_iterator_tag {};
|
||||
|
||||
std::string s;
|
||||
};
|
||||
|
||||
class path::const_iterator
|
||||
{
|
||||
public:
|
||||
typedef const path value_type;
|
||||
typedef const path& reference;
|
||||
typedef const path* pointer;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
|
||||
const_iterator();
|
||||
const_iterator(const path*, begin_iterator_tag);
|
||||
const_iterator(const path*, end_iterator_tag);
|
||||
|
||||
const_iterator& operator++();
|
||||
const_iterator operator++(int);
|
||||
const_iterator& operator--();
|
||||
const_iterator operator--(int);
|
||||
bool operator==(const const_iterator&) const;
|
||||
bool operator!=(const const_iterator&) const;
|
||||
const path& operator*() const;
|
||||
const path* operator->() const;
|
||||
private:
|
||||
const path* parent;
|
||||
std::size_t first;
|
||||
std::size_t last;
|
||||
path value;
|
||||
};
|
||||
|
||||
|
||||
path operator/(const path& lhs, const path& rhs);
|
||||
|
||||
std::ostream& operator<<(std::ostream&, const path&);
|
||||
|
||||
bool operator==(const path&, const path&);
|
||||
bool operator!=(const path&, const path&);
|
||||
bool operator<(const path&, const path&);
|
||||
bool operator<=(const path&, const path&);
|
||||
bool operator>(const path&, const path&);
|
||||
bool operator>=(const path&, const path&);
|
||||
}
|
||||
}
|
||||
|
||||
namespace std
|
||||
{
|
||||
template< >
|
||||
struct iterator_traits< ::cpp17::filesystem::path::const_iterator >
|
||||
{
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef const ::cpp17::filesystem::path value_type;
|
||||
typedef const ::cpp17::filesystem::path* pointer;
|
||||
typedef const ::cpp17::filesystem::path& reference;
|
||||
typedef std::bidirectional_iterator_tag iterator_category;
|
||||
};
|
||||
}
|
||||
#endif // PBL_FS_PATH_H
|
@ -1,48 +0,0 @@
|
||||
/* Copyright (c) 2015, Pollard Banknote Limited
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "perms.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
namespace perms
|
||||
{
|
||||
std::ostream& operator<<(
|
||||
std::ostream& os,
|
||||
perms p
|
||||
)
|
||||
{
|
||||
std::ostream t( os.rdbuf() );
|
||||
|
||||
t << "mode: " << std::oct << static_cast< int >( p );
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
}
|
@ -1,101 +0,0 @@
|
||||
/* Copyright (c) 2015, Pollard Banknote Limited
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef PBL_CPP_FS_PERMS_H
|
||||
#define PBL_CPP_FS_PERMS_H
|
||||
|
||||
#include <iosfwd>
|
||||
|
||||
namespace perms
|
||||
{
|
||||
/** File permissions
|
||||
*
|
||||
* See: std::experimental::filesystem::perms
|
||||
*/
|
||||
enum perms
|
||||
{
|
||||
none = 0,
|
||||
owner_read = 0400, // S_IRUSR
|
||||
owner_write = 0200, // S_IWUSR
|
||||
owner_exec = 0100, // S_IXUSR
|
||||
owner_all = 0700, // S_IRWXU
|
||||
group_read = 040, // S_IRGRP
|
||||
group_write = 020, // S_IWGRP
|
||||
group_exec = 010, // S_IXGRP
|
||||
group_all = 070, // S_IRWXG
|
||||
others_read = 04, // S_IROTH
|
||||
others_write = 02, // S_IWOTH
|
||||
others_exec = 01, // S_IXOTH
|
||||
others_all = 07, // S_IRWXO
|
||||
all = 0777,
|
||||
set_uid = 04000,
|
||||
set_gid = 02000,
|
||||
sticky_bit = 01000,
|
||||
mask = 07777,
|
||||
unknown = 0xffff,
|
||||
add_perms = 0x10000,
|
||||
remove_perms = 0x20000,
|
||||
resolve_symlinks = 0x40000
|
||||
};
|
||||
|
||||
inline perms operator|(
|
||||
perms a,
|
||||
perms b
|
||||
)
|
||||
{
|
||||
return static_cast< perms >( static_cast< int >( a ) | static_cast< int >( b ) );
|
||||
}
|
||||
|
||||
inline perms operator&(
|
||||
perms a,
|
||||
perms b
|
||||
)
|
||||
{
|
||||
return static_cast< perms >( static_cast< int >( a ) & static_cast< int >( b ) );
|
||||
}
|
||||
|
||||
inline perms operator^(
|
||||
perms a,
|
||||
perms b
|
||||
)
|
||||
{
|
||||
return static_cast< perms >( static_cast< int >( a ) ^ static_cast< int >( b ) );
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream&, perms);
|
||||
|
||||
}
|
||||
|
||||
namespace cpp17
|
||||
{
|
||||
namespace filesystem
|
||||
{
|
||||
typedef ::perms::perms perms;
|
||||
}
|
||||
}
|
||||
#endif // PBL_CPP_FS_PERMS_H
|
@ -1,62 +0,0 @@
|
||||
/* Copyright (c) 2016, Pollard Banknote Limited
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "remove.h"
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
#include "diriter.h"
|
||||
|
||||
namespace cpp17
|
||||
{
|
||||
namespace filesystem
|
||||
{
|
||||
bool remove(const path& p)
|
||||
{
|
||||
return ::remove( p.c_str() ) == 0;
|
||||
}
|
||||
|
||||
unsigned long remove_all(const path& p)
|
||||
{
|
||||
unsigned long total = 0;
|
||||
|
||||
for ( directory_iterator it(p), last; it != last; ++it )
|
||||
{
|
||||
total += remove_all( it->path() );
|
||||
}
|
||||
|
||||
if ( remove(p) )
|
||||
{
|
||||
++total;
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
/* Copyright (c) 2016, Pollard Banknote Limited
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef PBL_CPP_FS_REMOVE_H
|
||||
#define PBL_CPP_FS_REMOVE_H
|
||||
|
||||
#include "path.h"
|
||||
|
||||
namespace cpp17
|
||||
{
|
||||
namespace filesystem
|
||||
{
|
||||
bool remove(const path&);
|
||||
unsigned long remove_all(const path&);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // PBL_CPP_FS_REMOVE_H
|
@ -1,51 +0,0 @@
|
||||
/* Copyright (c) 2018, Pollard Banknote Limited
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "rename.h"
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
#include "copyfile.h"
|
||||
#include "remove.h"
|
||||
|
||||
namespace cpp17
|
||||
{
|
||||
namespace filesystem
|
||||
{
|
||||
/// @bug This is just a quick and dirty implementation
|
||||
void rename(const path& from, const path& to)
|
||||
{
|
||||
if (std::rename(from.c_str(), to.c_str()) != 0)
|
||||
{
|
||||
if (copy_file(from, to))
|
||||
cpp17::filesystem::remove(from);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,42 +0,0 @@
|
||||
/* Copyright (c) 2018, Pollard Banknote Limited
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef PBL_CPP_FS_RENAME_H
|
||||
#define PBL_CPP_FS_RENAME_H
|
||||
|
||||
#include "path.h"
|
||||
|
||||
namespace cpp17
|
||||
{
|
||||
namespace filesystem
|
||||
{
|
||||
void rename(const path& from, const path& to);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // PBL_CPP_FS_RENAME_H
|
@ -1,70 +0,0 @@
|
||||
/* Copyright (c) 2016, Pollard Banknote Limited
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "tempdir.h"
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
namespace cpp17
|
||||
{
|
||||
namespace filesystem
|
||||
{
|
||||
|
||||
/* TMPDIR is the POSIX variable for the temporary directory. Other variables
|
||||
* are sometimes used, however, in non-conforming environments. Those are
|
||||
* checked as fallback (following Boost's implementation)
|
||||
*/
|
||||
path temp_directory_path()
|
||||
{
|
||||
const char* p = std::getenv("TMPDIR");
|
||||
|
||||
if ( !p )
|
||||
{
|
||||
p = std::getenv("TMP");
|
||||
|
||||
if ( !p )
|
||||
{
|
||||
p = std::getenv("TEMP");
|
||||
|
||||
if ( !p )
|
||||
{
|
||||
p = std::getenv("TEMPDIR");
|
||||
|
||||
if ( !p )
|
||||
{
|
||||
p = "/tmp";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return path(p);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
/* Copyright (c) 2016, Pollard Banknote Limited
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef PBL_CPP_FS_TEMPDIR_H
|
||||
#define PBL_CPP_FS_TEMPDIR_H
|
||||
|
||||
#include "path.h"
|
||||
|
||||
namespace cpp17
|
||||
{
|
||||
namespace filesystem
|
||||
{
|
||||
path temp_directory_path();
|
||||
}
|
||||
}
|
||||
|
||||
#endif // PBL_CPP_FS_TEMPDIR_H
|
@ -1,422 +0,0 @@
|
||||
# This Makefile is intended to be included by another Makefile. It contains a
|
||||
# number of common functions, variables, recipes. Ideally the calling Makefile
|
||||
# will only need to define targets for that project.
|
||||
#
|
||||
# Features:
|
||||
# - Shadow building
|
||||
# - Auto dependency generation
|
||||
# - debug target uses address sanitizer when available (GCC >= 4.8.0),
|
||||
# and undefined behavior sanitizer (GCC >=4.9.0)
|
||||
# - coloured error messages when available (GCC >=4.9.0)
|
||||
# - pre-configured targets for cleaning .o files, insure leftovers
|
||||
# - targets for callgrind, memcheck, insure, profiling and code coverage
|
||||
#
|
||||
# Organization
|
||||
# - Supporting functions
|
||||
# - Definitions of the variables used by this makefile (ex., CXX, WARNINGS)
|
||||
# - Predefined configurations of variables (ex., DEBUG)
|
||||
# - File type targets (ex., .o)
|
||||
# - Named targets (ex., profile)
|
||||
# - Inclusion of auto-dependencies
|
||||
#
|
||||
# TODO Profile guided optimization
|
||||
# TODO Precompiled headers
|
||||
# TODO Static analysis
|
||||
# TODO Clang support
|
||||
# TODO -fsanitize=integer for clang
|
||||
# TODO -fsanitize=thread
|
||||
# TODO ubsan prints messages to the stderr; does not terminate
|
||||
# TODO dynamic/static libs
|
||||
# TODO _GLIBCXX_DEBUG and _GLIBCXX_DEBUG_PEDANTIC
|
||||
# TODO split up makefile into common functions, variables, configurations, recipes
|
||||
# TODO -B option for TOOLCHAIN
|
||||
# TODO CONFIG=RELEASE (strip, for example)
|
||||
# TODO Different debug levels
|
||||
# TODO CONFIG=HARDENED including some of the following options
|
||||
# TODO -fstack-protector-strong?
|
||||
# TODO -Wformat-security
|
||||
# TODO -pie -fPIE
|
||||
# TODO full relro -Wl,-z,relro,-z,now
|
||||
# TODO -pipe
|
||||
# TODO -flto
|
||||
|
||||
# Shadow building ==============================================================
|
||||
# This gets the directory of the calling Makefile (and, presumably, where the
|
||||
# source code resides
|
||||
|
||||
# Functions ====================================================================
|
||||
gccversion = $(shell $(CXX) -dumpversion | sed -e 's/\.\([0-9][0-9]\)/\1/g' -e 's/\.\([0-9]\)/0\1/g' -e 's/^[0-9]\{3,4\}$$/&00/')
|
||||
gcc48 = $(shell expr $(gccversion) \>= 40800)
|
||||
gcc49 = $(shell expr $(gccversion) \>= 40900)
|
||||
gcc51 = $(shell expr $(gccversion) \>= 50100)
|
||||
|
||||
# Convert a word to lowercase
|
||||
lower = $(shell echo $(1) | tr '[:upper:]' '[:lower:]')
|
||||
|
||||
# Convert a word to uppercase
|
||||
upper = $(shell echo $(1) | tr '[:lower:]' '[:upper:]')
|
||||
|
||||
# Variables ====================================================================
|
||||
#
|
||||
# The basic variables that this makefile uses
|
||||
|
||||
# Toolchain --------------------------------------------------------------------
|
||||
# Which programs to use during compilation
|
||||
|
||||
# Path to a different toolchain (ex., ~/bin/gcc-4.9.0)
|
||||
TOOLCHAIN =
|
||||
|
||||
ifndef TOOLCHAIN
|
||||
# C++ compiler
|
||||
CXX = g++
|
||||
|
||||
# Archive (.a) program
|
||||
AR = ar
|
||||
|
||||
# Linker
|
||||
LD = $(CXX)
|
||||
|
||||
PROFILER = gprof
|
||||
else
|
||||
# Use a particular set of tools
|
||||
CXX = $(TOOLCHAIN)/bin/g++ -B$(TOOLCHAIN)/bin/
|
||||
AR = $(TOOLCHAIN)/bin/ar
|
||||
LD = $(CXX)
|
||||
PROFILER = $(TOOLCHAIN)/bin/gprof
|
||||
endif
|
||||
|
||||
# Misc
|
||||
VALGRIND = valgrind
|
||||
|
||||
# Compiler flags ---------------------------------------------------------------
|
||||
# Arguments to the toolchain programs
|
||||
|
||||
# Which version of C++ to compile for
|
||||
STANDARD = -ansi -pedantic
|
||||
|
||||
# Optimization flags
|
||||
OPTIMIZATION = -O2
|
||||
|
||||
# Architecture flags
|
||||
TARGET_ARCH =
|
||||
|
||||
# Warnings
|
||||
WARNINGS = -Wall -Wsign-compare -Wconversion -Wpointer-arith \
|
||||
-Winit-self -Wcast-qual -Wredundant-decls -Wcast-align -Wwrite-strings \
|
||||
-Wno-long-long -Woverloaded-virtual -Wformat -Wno-unknown-pragmas \
|
||||
-Wnon-virtual-dtor -Wno-c++0x-compat
|
||||
# -Wold-style-cast
|
||||
|
||||
ifeq "$(gcc51)" "1"
|
||||
#WARNINGS += -Wsuggest-attribute=const -Wsuggest-attribute=pure
|
||||
endif
|
||||
|
||||
# Level of debugging information to provide
|
||||
DEBUGGING = -g
|
||||
|
||||
# Machine independent options
|
||||
#-fno-nonansi-builtins
|
||||
OPTIONS = -fuse-cxa-atexit -ffor-scope
|
||||
|
||||
ifeq "$(gcc49)" "1"
|
||||
OPTIONS += -fdiagnostics-color
|
||||
endif
|
||||
|
||||
# Flags to use when compiling C++ source into object files
|
||||
CXXFLAGS = $(STANDARD) $(DEBUGGING) $(OPTIMIZATION) $(WARNINGS) $(OPTIONS) $(TARGET_ARCH)
|
||||
|
||||
# Directories to search for includes
|
||||
INCLUDE =
|
||||
|
||||
# Any macros that can be defined on the command line
|
||||
DEFINES = -D_FORTIFY_SOURCE=1
|
||||
|
||||
# Preprocessor flags
|
||||
CPPFLAGS = $(INCLUDE) $(DEFINES)
|
||||
|
||||
# How to build an archive
|
||||
ARFLAGS = crs
|
||||
|
||||
# Linker flags
|
||||
LDFLAGS =
|
||||
LDLIBS =
|
||||
|
||||
ifdef TOOLCHAIN
|
||||
# Statically link the GCC and
|
||||
LDFLAGS += -static-libgcc -static-libstdc++
|
||||
|
||||
# Dynamic linking
|
||||
#LDFLAGS += -Wl,-rpath -Wl,$(TOOLCHAIN)/lib
|
||||
#LDLIBS = -L$(TOOLCHAIN)/lib
|
||||
endif
|
||||
|
||||
# Printing =====================================================================
|
||||
# If this is not empty, print messages
|
||||
VERBOSE =
|
||||
|
||||
# Predefined configurations ====================================================
|
||||
# Combinations of the OPTIMIZATION, etc.
|
||||
ifdef CONFIG
|
||||
UCONFIG := $(call upper,$(CONFIG))
|
||||
|
||||
# Fast -------------------------------------------------------------------------
|
||||
# A faster build, primarily for testing
|
||||
ifeq "$(UCONFIG)" "FAST"
|
||||
OPTIMIZATION = -O0
|
||||
endif
|
||||
|
||||
# Tune -------------------------------------------------------------------------
|
||||
# Heavily optimized for a fast application
|
||||
ifeq "$(UCONFIG)" "TUNE"
|
||||
ifeq "$(gcc48)" "1"
|
||||
TARGET_ARCH = -march=native
|
||||
endif
|
||||
OPTIMIZATION = -O3 -mtune=native
|
||||
endif
|
||||
|
||||
# Debug ------------------------------------------------------------------------
|
||||
# Programmer is tracking a bug
|
||||
ifeq "$(UCONFIG)" "DEBUG"
|
||||
|
||||
# Set additional warnings and flags
|
||||
WARNINGS += -Wshadow -Wfloat-equal
|
||||
ifeq "$(gcc51)" "1"
|
||||
WARNINGS += -Wstrict-overflow=5
|
||||
endif
|
||||
|
||||
DEBUGGING = -ggdb3 -fno-omit-frame-pointer -fno-default-inline -fno-inline -fno-merge-constants -ffloat-store
|
||||
# -fno-elide-constructors
|
||||
|
||||
# Set the optimization level
|
||||
ifeq "$(gcc48)" "1"
|
||||
OPTIMIZATION = -Og
|
||||
else
|
||||
OPTIMIZATION = -O0
|
||||
endif
|
||||
|
||||
# Turn on address sanitizer
|
||||
ifeq "$(gcc48)" "1"
|
||||
DEBUGGING += -fsanitize=address
|
||||
LDFLAGS += -fsanitize=address -static-libasan
|
||||
endif
|
||||
|
||||
# Turn on undefined behavior sanitizer and leak sanitizer
|
||||
ifeq "$(gcc49)" "1"
|
||||
DEBUGGING += -fsanitize=undefined -fsanitize=leak
|
||||
LDFLAGS += -fsanitize=undefined -fsanitize=leak -static-libubsan -static-liblsan
|
||||
endif
|
||||
endif
|
||||
|
||||
# Profile ----------------------------------------------------------------------
|
||||
# Programmer wants profile information
|
||||
ifeq "$(UCONFIG)" "PROFILE"
|
||||
OPTIMIZATION = -O2 -pg
|
||||
LDFLAGS += -pg
|
||||
endif
|
||||
|
||||
# Coverage ---------------------------------------------------------------------
|
||||
# Programmer wants code coverage information
|
||||
ifeq "$(UCONFIG)" "COVERAGE"
|
||||
DEBUGGING += --coverage -fno-elide-constructors
|
||||
LDFLAGS += --coverage
|
||||
OPTIMIZATION = -O0
|
||||
endif
|
||||
|
||||
# Insure -----------------------------------------------------------------------
|
||||
# Programmer wants to run insure
|
||||
ifeq "$(UCONFIG)" "INSURE"
|
||||
CXX = insure
|
||||
LDLIBS += -lstdc++
|
||||
OPTIMIZATION = -O0
|
||||
endif
|
||||
endif
|
||||
|
||||
# Targets ======================================================================
|
||||
.PHONY: no_default_goal depend clean_insure clean_objects clean_profile clean_depend distclean coverage profile memcheck callgrind cachegrind help help_common examples
|
||||
|
||||
no_default_goal:
|
||||
$(error "The including Makefile hasn't specified a default goal. It should.")
|
||||
|
||||
# Dependency generation --------------------------------------------------------
|
||||
DEPDIR := .deps
|
||||
|
||||
# Build object files with automatic dependency generation
|
||||
# TODO maybe use LINK.cpp from 'make -p'
|
||||
%.o: %.cpp
|
||||
@mkdir -p $(@D)/$(DEPDIR)
|
||||
ifeq ($(VERBOSE),)
|
||||
@echo [CXX] $@
|
||||
@$(CXX) -c $(CXXFLAGS) $(CPPFLAGS) -MMD -MP -MF $(@D)/$(DEPDIR)/$(*F).d -o $@ $<
|
||||
else
|
||||
$(CXX) -c $(CXXFLAGS) $(CPPFLAGS) -MMD -MP -MF $(@D)/$(DEPDIR)/$(*F).d -o $@ $<
|
||||
endif
|
||||
|
||||
%.a:
|
||||
ifeq ($(VERBOSE),)
|
||||
@echo [AR] $@
|
||||
@$(AR) $(ARFLAGS) $@ $^ > /dev/null
|
||||
else
|
||||
$(AR) $(ARFLAGS) $@ $^ > /dev/null
|
||||
endif
|
||||
|
||||
# A script for combining .a's. Dependency list for the mri should be
|
||||
# subdirectories containing static libs. Name of the output library
|
||||
# is inferred from the mri name (abc.mri produces libabc.a)
|
||||
%.mri:
|
||||
@echo 'CREATE $(patsubst %.mri,lib%.a,$@)' > $@
|
||||
@for dir in $^; do echo ADDLIB $$dir >> $@; done
|
||||
@echo 'SAVE' >> $@
|
||||
|
||||
|
||||
# TODO dynamic libs
|
||||
# %.so: CXXFLAGS += -fPIC
|
||||
# %.so: LDFLAGS := -shared
|
||||
# %.so:
|
||||
# $(CXX) $(LDFLAGS) $^ $(LDLIBS) -o $@
|
||||
# optionally add -Wl,-soname,$(SONAME)
|
||||
|
||||
# TODO java classes
|
||||
# %.class: %.java
|
||||
# $(JC) -cp . $<
|
||||
|
||||
# Code coverage ----------------------------------------------------------------
|
||||
coverage:
|
||||
ifdef COVERAGE_OUT
|
||||
@TMPFILE=`mktemp`; lcov --capture --directory . --output-file $$TMPFILE; genhtml $$TMPFILE --output-directory $(COVERAGE_OUT); $(RM) $$TMPFILE
|
||||
else
|
||||
$(error You have not set COVERAGE_OUT)
|
||||
endif
|
||||
|
||||
# Profiling --------------------------------------------------------------------
|
||||
profile:
|
||||
ifdef PROFILE_TARGET
|
||||
$(PROFILE_TARGET) $(PROFILE_TARGET_ARGS)
|
||||
ifdef PROFILE_OUT
|
||||
@$(PROFILER) -c $(PROFILE_TARGET) > $(PROFILE_OUT)
|
||||
else
|
||||
$(error You have not specified PROFILE_OUT)
|
||||
endif
|
||||
else
|
||||
$(error You have not specified PROFILE_TARGET)
|
||||
endif
|
||||
|
||||
# Memcheck ---------------------------------------------------------------------
|
||||
# User should set MEMCHECK_TARGET, MEMCHECK_TARGET_ARGS, and a recipe like:
|
||||
# memcheck: $(MEMCHECK_TARGET)
|
||||
memcheck:
|
||||
$(VALGRIND) --tool=memcheck -v --read-var-info=yes --track-origins=yes --show-reachable=yes --leak-check=full --read-inline-info=yes --keep-stacktraces=alloc-and-free $(VALGRIND_TARGET) $(VALGRIND_TARGET_ARGS) 2> $(MEMCHECK_OUT)
|
||||
|
||||
# Callgrind --------------------------------------------------------------------
|
||||
# User should set CALLGRIND_TARGET, CALLGRIND_TARGET_ARGS, and a recipe like:
|
||||
# callgrind: $(CALLGRIND_TARGET)
|
||||
callgrind:
|
||||
$(VALGRIND) --tool=callgrind $(VALGRIND_TARGET) $(VALGRIND_TARGET_ARGS)
|
||||
|
||||
cachegrind:
|
||||
$(VALGRIND) --tool=cachegrind --branch-sim=yes $(VALGRIND_TARGET) $(VALGRIND_TARGET_ARGS)
|
||||
|
||||
# Clean targets ----------------------------------------------------------------
|
||||
# remove all .o files
|
||||
clean_objects:
|
||||
ifeq ($(VERBOSE),)
|
||||
@find -name '*.o' -exec $(RM) '{}' \;
|
||||
else
|
||||
find -name '*.o' -exec $(RM) '{}' \;
|
||||
endif
|
||||
|
||||
# remove all files left by insure
|
||||
clean_insure:
|
||||
ifeq ($(VERBOSE),)
|
||||
@find -name '*.tcl' -exec $(RM) '{}' \;
|
||||
@$(RM) tca.map tca.log
|
||||
else
|
||||
find -name '*.tcl' -exec $(RM) '{}' \;
|
||||
$(RM) tca.map tca.log
|
||||
endif
|
||||
|
||||
# remove all files left by gprof
|
||||
clean_profile:
|
||||
ifeq ($(VERBOSE),)
|
||||
@$(RM) profile
|
||||
@find \( -name '*.gcda' -o -name '*.gcno' \) -exec $(RM) '{}' \;
|
||||
else
|
||||
$(RM) profile
|
||||
find \( -name '*.gcda' -o -name '*.gcno' \) -exec $(RM) '{}' \;
|
||||
endif
|
||||
|
||||
clean_depend:
|
||||
ifeq ($(VERBOSE),)
|
||||
@find -depth -name $(DEPDIR) -type d -exec $(RM) -r '{}' \;
|
||||
else
|
||||
find -depth -name $(DEPDIR) -type d -exec $(RM) -r '{}' \;
|
||||
endif
|
||||
|
||||
depend: clean clean_depend
|
||||
|
||||
distclean: depend
|
||||
|
||||
# Documentation ----------------------------------------------------------------
|
||||
help_common:
|
||||
@echo "==================================================================="
|
||||
@echo "Here are some standard Makefile variables and their defaults:"
|
||||
@echo " CXX ($(CXX))"
|
||||
@echo " CPPFLAGS ($(CPPFLAGS))"
|
||||
@echo " LDFLAGS ($(LDFLAGS))"
|
||||
@echo " LDLIBS ($(LDLIBS))"
|
||||
@echo " AR ($(AR))"
|
||||
@echo " ARFLAGS ($(ARFLAGS))"
|
||||
@echo
|
||||
@echo "You can set the TOOLCHAIN variable to use a different compiler,"
|
||||
@echo "linker, profiler. Ex., (~/bin/gcc-4.9.0)"
|
||||
@echo
|
||||
@echo "The CXXFLAGS variable is comprised of a number of other variables:"
|
||||
@echo " STANDARD ($(STANDARD))"
|
||||
@echo " DEBUGGING ($(DEBUGGING))"
|
||||
@echo " OPTIMIZATION ($(OPTIMIZATION))"
|
||||
@echo " WARNINGS ($(WARNINGS))"
|
||||
@echo " TARGET_ARCH ($(TARGET_ARCH))"
|
||||
@echo
|
||||
@echo "For convenience, several preconfigured options are available by"
|
||||
@echo "setting the CONFIG variale:"
|
||||
@echo " DEBUG - Turns on debugging info; turns down optimization; enables"
|
||||
@echo " address sanitizer, etc. if available"
|
||||
@echo " PROFILE - Keeps optimization for release build; adds debugging"
|
||||
@echo " and gprof flags"
|
||||
@echo " COVERAGE - Don't inline functions"
|
||||
@echo " INSURE - Build the target with the insure compiler"
|
||||
@echo " TUNE - High optimization level; CPU-specific instructions"
|
||||
@echo " FAST - A fast compilation with low optimization level"
|
||||
@echo
|
||||
@echo "==================================================================="
|
||||
@echo "Here are some special targets and variables that affect them"
|
||||
@echo
|
||||
@echo " profile - First build a target with CONFIG=PROFILE and run it."
|
||||
@echo " PROFILE_TARGET the name of the program to profile"
|
||||
@echo " (default: $(PROFILE_TARGET))"
|
||||
@echo " PROFILE_TARGET_ARGS arguments to the program to profile"
|
||||
@echo " (default: $(PROFILE_TARGET_ARGS))"
|
||||
@echo " PROFILE_OUT the file to place the profile data in"
|
||||
@echo " (default: $(PROFILE_OUT))"
|
||||
@echo " PROFILER Path to profiler"
|
||||
@echo " (default: $(PROFILER))"
|
||||
@echo " coverage - First build a target with CONFIG=COVERAGE and run it."
|
||||
@echo " COVERAGE_OUT specifies where to put the resulting web pages"
|
||||
@echo " (default: $(COVERAGE_OUT))"
|
||||
@echo
|
||||
@echo " memcheck - Run memcheck for VALGRIND_TARGET, testing memory access"
|
||||
@echo " callgrind - Run callgrind for VALGRIND_TARGET, testing performance"
|
||||
@echo " cachegrind - Run cachegrind for VALGRIND_TARGET, testing cache"
|
||||
@echo " VALGRIND_TARGET The program to check"
|
||||
@echo " (default: $(VALGRIND_TARGET))"
|
||||
@echo " VALGRIND_TARGET_ARGS The arguments to VALGRIND_TARGET"
|
||||
@echo " (default: $(VALGRIND_TARGET_ARGS))"
|
||||
@echo " MEMCHECK_OUT Where to put the memcheck results"
|
||||
@echo " (default: $(MEMCHECK_OUT))"
|
||||
@echo "==================================================================="
|
||||
|
||||
help: help_common
|
||||
|
||||
# ==============================================================================
|
||||
# Include dependencies which are stored as .d files in the $(DEPDIR) directories
|
||||
# TODO prefer -wholename to -path, but old version of find doesn't have wholename
|
||||
-include $(shell find -path '*/$(DEPDIR)/*.d')
|
@ -0,0 +1,85 @@
|
||||
environment:
|
||||
matrix:
|
||||
- platform: x86
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
generator: "Visual Studio 14 2015"
|
||||
compiler: msvc
|
||||
configuration: Release
|
||||
|
||||
- platform: x64
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
generator: "Visual Studio 14 2015 Win64"
|
||||
compiler: msvc
|
||||
configuration: Release
|
||||
|
||||
- platform: x86
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
generator: "Visual Studio 15 2017"
|
||||
compiler: msvc
|
||||
configuration: Release
|
||||
|
||||
- platform: x64
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
generator: "Visual Studio 15 2017 Win64"
|
||||
compiler: msvc
|
||||
configuration: Release
|
||||
|
||||
- platform: x86
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||
generator: "Visual Studio 16 2019"
|
||||
compiler: msvc19
|
||||
configuration: Release
|
||||
arch: Win32
|
||||
|
||||
- platform: x64
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||
generator: "Visual Studio 16 2019"
|
||||
compiler: msvc19
|
||||
configuration: Release
|
||||
arch: x64
|
||||
|
||||
- platform: x86
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
generator: "MinGW Makefiles"
|
||||
compiler: mingw
|
||||
TOOLCHAIN_PATH: C:\mingw-w64\i686-6.3.0-posix-dwarf-rt_v5-rev1/mingw32\bin
|
||||
CC: C:/mingw-w64/i686-6.3.0-posix-dwarf-rt_v5-rev1/mingw32/bin/gcc.exe
|
||||
CXX: C:/mingw-w64/i686-6.3.0-posix-dwarf-rt_v5-rev1/mingw32/bin/g++.exe
|
||||
configuration: Release
|
||||
|
||||
- platform: x64
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
generator: "MinGW Makefiles"
|
||||
compiler: mingw
|
||||
TOOLCHAIN_PATH: C:\mingw-w64\x86_64-7.2.0-posix-seh-rt_v5-rev1\mingw64\bin
|
||||
CC: C:/mingw-w64/x86_64-7.2.0-posix-seh-rt_v5-rev1/mingw64/bin/gcc.exe
|
||||
CXX: C:/mingw-w64/x86_64-7.2.0-posix-seh-rt_v5-rev1/mingw64/bin/g++.exe
|
||||
configuration: Release
|
||||
|
||||
matrix:
|
||||
fast_finish: false
|
||||
|
||||
init:
|
||||
- cmd: cmake --version
|
||||
- cmd: msbuild /version
|
||||
|
||||
install:
|
||||
- cmd: reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock" /t REG_DWORD /f /v "AllowDevelopmentWithoutDevLicense" /d "1"
|
||||
- cmd: ren "C:\Program Files\Git\usr\bin\sh.exe" _sh.exe
|
||||
|
||||
build_script:
|
||||
- mkdir build
|
||||
- cd build
|
||||
- if [%compiler%]==[msvc] cmake -G"%generator%" ..
|
||||
- if [%compiler%]==[msvc19] cmake -G"%generator%" -A "%arch%" ..
|
||||
- if [%compiler%]==[mingw] set PATH=%TOOLCHAIN_PATH%;%PATH%
|
||||
- if [%compiler%]==[mingw] cmake -G"%generator%" -DCMAKE_C_COMPILER=%CC% -DCMAKE_CXX_COMPILER=%CXX% -DCMAKE_SH=CMAKE_SH-NOTFOUND -DCMAKE_BUILD_TYPE=%configuration% ..
|
||||
- cmake --build . --config %configuration%
|
||||
|
||||
test_script:
|
||||
- cd %APPVEYOR_BUILD_FOLDER%\build
|
||||
- set CTEST_OUTPUT_ON_FAILURE=1
|
||||
- ctest -C %configuration%
|
||||
- if exist "test\Release\std_filesystem_test.exe" test\Release\std_filesystem_test.exe & exit 0
|
||||
- cd ..
|
||||
|
@ -0,0 +1,25 @@
|
||||
---
|
||||
Language: Cpp
|
||||
BasedOnStyle: Chromium
|
||||
AccessModifierOffset: '-4'
|
||||
IndentWidth: '4'
|
||||
ColumnLimit: 256
|
||||
BreakBeforeBraces: Custom
|
||||
BraceWrapping:
|
||||
AfterClass: true
|
||||
AfterControlStatement: false
|
||||
AfterFunction: true
|
||||
AfterNamespace: false
|
||||
AfterObjCDeclaration: true
|
||||
AfterStruct: true
|
||||
AfterUnion: true
|
||||
BeforeCatch: true
|
||||
BeforeElse: true
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: true
|
||||
SplitEmptyRecord: true
|
||||
SplitEmptyNamespace: true
|
||||
BreakConstructorInitializers: BeforeComma
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||
IndentPPDirectives: None
|
||||
...
|
@ -0,0 +1,17 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Detailed steps to reproduce the behavior.
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
@ -0,0 +1,17 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
@ -0,0 +1,2 @@
|
||||
/build*/
|
||||
.vscode/
|
@ -0,0 +1,104 @@
|
||||
language: cpp
|
||||
|
||||
dist: xenial # default distribution
|
||||
os: linux # default os
|
||||
sudo: false
|
||||
|
||||
|
||||
matrix:
|
||||
fast_finish: true
|
||||
include:
|
||||
- env: MATRIX_EVAL="CC=gcc-5 && CXX=g++-5 && GENERATOR='Unix Makefiles' && CONFIG=Release"
|
||||
addons: { apt: { packages: ["g++-5"], sources: ["ubuntu-toolchain-r-test"] } }
|
||||
|
||||
- env: MATRIX_EVAL="CC=gcc-6 && CXX=g++-6 && GENERATOR='Unix Makefiles' && CONFIG=Release"
|
||||
addons: { apt: { packages: ["g++-6"], sources: ["ubuntu-toolchain-r-test"] } }
|
||||
|
||||
- env: MATRIX_EVAL="CC=gcc-7 && CXX=g++-7 && GENERATOR='Unix Makefiles' && CONFIG=Release"
|
||||
addons: { apt: { packages: ["g++-7"], sources: ["ubuntu-toolchain-r-test"] } }
|
||||
|
||||
- env: MATRIX_EVAL="CC=gcc-7 && CXX=g++-7 && GENERATOR='Unix Makefiles' && CONFIG=Debug && GHC_COVERAGE=1"
|
||||
addons: { apt: { packages: ["g++-7", "lcov"], sources: ["ubuntu-toolchain-r-test"] } }
|
||||
|
||||
- env: MATRIX_EVAL="CC=gcc-8 && CXX=g++-8 && GENERATOR='Unix Makefiles' && CONFIG=Release"
|
||||
addons: { apt: { packages: ["g++-8"], sources: ["ubuntu-toolchain-r-test"] } }
|
||||
|
||||
- env: MATRIX_EVAL="CC=gcc-9 && CXX=g++-9 && GENERATOR='Unix Makefiles' && CONFIG=Release"
|
||||
addons: { apt: { packages: ["g++-9"], sources: ["ubuntu-toolchain-r-test"] } }
|
||||
|
||||
- env: MATRIX_EVAL="CC=clang-5.0 && CXX=clang++-5.0 && GENERATOR='Unix Makefiles' && CONFIG=Release"
|
||||
addons: { apt: { packages: ["clang-5.0"] } }
|
||||
|
||||
- env: MATRIX_EVAL="CC=clang-6.0 && CXX=clang++-6.0 && GENERATOR='Unix Makefiles' && CONFIG=Release"
|
||||
addons: { apt: { packages: ["clang-6.0"] } }
|
||||
|
||||
- env: MATRIX_EVAL="CC=clang-7 && CXX=clang++-7 && GENERATOR='Unix Makefiles' && CONFIG=Release"
|
||||
addons: { apt: { packages: ["clang-7", "libc++-7-dev", "libc++abi-7-dev"], sources: ["llvm-toolchain-xenial-7"] } }
|
||||
|
||||
- env: MATRIX_EVAL="CC=clang-8 && CXX=clang++-8 && GENERATOR='Unix Makefiles' && CONFIG=Release"
|
||||
addons: { apt: { packages: ["clang-8", "libc++-8-dev", "libc++abi-8-dev"], sources: ["llvm-toolchain-xenial-8"] } }
|
||||
|
||||
- env: MATRIX_EVAL="CC=clang-9 && CXX=clang++-9 && GENERATOR='Unix Makefiles' && CONFIG=Release"
|
||||
addons: { apt: { packages: ["clang-9", "libc++-9-dev", "libc++abi-9-dev"], sources: [{sourceline: 'deb https://apt.llvm.org/xenial/ llvm-toolchain-xenial-9 main', key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'}] } }
|
||||
|
||||
- os: osx
|
||||
env: MATRIX_EVAL="CC=clang && CXX=clang++ && GENERATOR=Xcode && CONFIG=Release"
|
||||
osx_image: xcode9.2
|
||||
|
||||
- os: osx
|
||||
env: MATRIX_EVAL="CC=clang && CXX=clang++ && GENERATOR=Xcode && CONFIG=Release"
|
||||
osx_image: xcode10.1
|
||||
|
||||
- os: osx
|
||||
env: MATRIX_EVAL="CC=clang && CXX=clang++ && GENERATOR=Xcode && CONFIG=Release"
|
||||
osx_image: xcode11.2
|
||||
|
||||
install:
|
||||
- eval "${MATRIX_EVAL}"
|
||||
- |
|
||||
if [ "${TRAVIS_OS_NAME}" = "osx" ]; then
|
||||
brew update
|
||||
fi
|
||||
- |
|
||||
if [ "${GHC_COVERAGE}" = "1" ]; then
|
||||
gem install coveralls-lcov
|
||||
fi
|
||||
- $CC --version
|
||||
- $CXX --version
|
||||
- cmake --version
|
||||
|
||||
before_script:
|
||||
- eval "${MATRIX_EVAL}"
|
||||
- mkdir build
|
||||
- cd build
|
||||
- export VERBOSE=1
|
||||
- |
|
||||
if [ "${CONFIG}" = "Debug" ]; then
|
||||
cmake -G"${GENERATOR}" -DCMAKE_CXX_COMPILER=${CXX} -DCMAKE_C_COMPILER=${CC} -DCMAKE_BUILD_TYPE=${CONFIG} -DGHC_COVERAGE=ON ..
|
||||
else
|
||||
cmake -G"${GENERATOR}" -DCMAKE_CXX_COMPILER=${CXX} -DCMAKE_C_COMPILER=${CC} -DCMAKE_BUILD_TYPE=${CONFIG} ..
|
||||
fi
|
||||
|
||||
script:
|
||||
- export VERBOSE=1
|
||||
- cmake --build . --config ${CONFIG} --target filesystem_test
|
||||
- |
|
||||
if [ "${GHC_COVERAGE}" = "1" ]; then
|
||||
cmake --build . --config ${CONFIG} --target filesystem_test
|
||||
test/filesystem_test
|
||||
else
|
||||
cmake --build . --config ${CONFIG}
|
||||
ctest -C ${CONFIG} -E Windows
|
||||
if [ -f "test/std_filesystem_test" ]; then
|
||||
test/std_filesystem_test || true
|
||||
fi
|
||||
fi
|
||||
|
||||
after_success:
|
||||
- |
|
||||
if [ "${GHC_COVERAGE}" = "1" ]; then
|
||||
lcov --compat-libtool --directory . --capture --output-file coverage_output.info
|
||||
lcov --remove coverage_output.info '/usr/*' '*/c++/*' '*.h' '*/catch.hpp' -o coverage.info
|
||||
sed -i 's|SF:/.*/filesystem/|SF:../|g' coverage.info
|
||||
coveralls-lcov coverage.info
|
||||
fi
|
@ -0,0 +1,56 @@
|
||||
cmake_minimum_required(VERSION 3.7.2)
|
||||
project(ghcfilesystem)
|
||||
|
||||
include(CMakeDependentOption)
|
||||
|
||||
cmake_dependent_option(GHC_FILESYSTEM_BUILD_TESTING
|
||||
"Enable tests" ON
|
||||
"CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR" OFF)
|
||||
cmake_dependent_option(GHC_FILESYSTEM_BUILD_EXAMPLES
|
||||
"Build examples" ON
|
||||
"CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR" OFF)
|
||||
cmake_dependent_option(GHC_FILESYSTEM_WITH_INSTALL
|
||||
"With install target" ON
|
||||
"CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR" OFF)
|
||||
|
||||
if(NOT DEFINED CMAKE_CXX_STANDARD)
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
endif()
|
||||
if(CMAKE_CXX_STANDARD LESS 11)
|
||||
message(FATAL_ERROR "CMAKE_CXX_STANDARD is less than 11, ghc::filesystem only works with C++11 and above.")
|
||||
endif()
|
||||
|
||||
add_library(ghc_filesystem INTERFACE)
|
||||
target_include_directories(ghc_filesystem INTERFACE
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||
$<INSTALL_INTERFACE:include>)
|
||||
target_compile_options(ghc_filesystem INTERFACE "$<$<C_COMPILER_ID:MSVC>:/utf-8>")
|
||||
target_compile_options(ghc_filesystem INTERFACE "$<$<CXX_COMPILER_ID:MSVC>:/utf-8>")
|
||||
|
||||
get_directory_property(hasParent PARENT_DIRECTORY)
|
||||
if(NOT hasParent)
|
||||
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/")
|
||||
include(GhcHelper)
|
||||
|
||||
if(GHC_FILESYSTEM_BUILD_TESTING)
|
||||
enable_testing()
|
||||
add_subdirectory(test)
|
||||
endif()
|
||||
|
||||
if(GHC_FILESYSTEM_BUILD_EXAMPLES)
|
||||
add_subdirectory(examples)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(GHC_FILESYSTEM_WITH_INSTALL)
|
||||
include(CMakePackageConfigHelpers)
|
||||
include(GNUInstallDirs)
|
||||
|
||||
install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||
install(TARGETS ghc_filesystem EXPORT ghcFilesystemConfig)
|
||||
install(EXPORT ghcFilesystemConfig NAMESPACE ghcFilesystem:: DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/ghcFilesystem)
|
||||
endif()
|
||||
|
@ -0,0 +1,27 @@
|
||||
Copyright (c) 2018, Steffen Schümann <s.schuemann@pobox.com>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
@ -0,0 +1,710 @@
|
||||
![Supported Platforms](https://img.shields.io/badge/platform-macOS%20%7C%20Linux%20%7C%20Windows-blue.svg)
|
||||
[![Build Status](https://travis-ci.org/gulrak/filesystem.svg?branch=master)](https://travis-ci.org/gulrak/filesystem)
|
||||
[![Build status](https://ci.appveyor.com/api/projects/status/t07wp3k2cddo0hpo/branch/master?svg=true)](https://ci.appveyor.com/project/gulrak/filesystem)
|
||||
[![Coverage Status](https://coveralls.io/repos/github/gulrak/filesystem/badge.svg?branch=master)](https://coveralls.io/github/gulrak/filesystem?branch=master)
|
||||
[![Latest Release Tag](https://img.shields.io/github/tag/gulrak/filesystem.svg)](https://github.com/gulrak/filesystem/tree/v1.2.10)
|
||||
|
||||
# Filesystem
|
||||
|
||||
This is a header-only single-file std::filesystem compatible helper library,
|
||||
based on the C++17 specs, but implemented for C++11, C++14 or C++17 (tightly following
|
||||
the C++17 with very few documented exceptions). It is currently tested on
|
||||
macOS 10.12/10.14, Windows 10, and Ubuntu 18.04 but should work on other versions too, as long as you have a
|
||||
C++11 compatible compiler. It is of course in its own namespace `ghc::filesystem`
|
||||
to not interfere with a regular `std::filesystem` should you use it in a mixed C++17
|
||||
environment.
|
||||
|
||||
*It could still use some polishing, test coverage is above 90%, I didn't benchmark
|
||||
much yet, but I'll try to optimize some parts and refactor others, so I'm striving
|
||||
to improve it as long as it doesn't introduce additional C++17 compatibility
|
||||
issues. Feedback is always welcome. Simply open an issue if you see something missing
|
||||
or wrong or not behaving as expected and I'll comment.*
|
||||
|
||||
|
||||
## Motivation
|
||||
|
||||
I'm often in need of filesystem functionality, mostly `fs::path`, but directory
|
||||
access too, and when beginning to use C++11, I used that language update
|
||||
to try to reduce my third-party dependencies. I could drop most of what
|
||||
I used, but still missed some stuff that I started implementing for the
|
||||
fun of it. Originally I based these helpers on my own coding- and naming
|
||||
conventions. When C++17 was finalized, I wanted to use that interface,
|
||||
but it took a while, to push myself to convert my classes.
|
||||
|
||||
The implementation is closely based on chapter 30.10 from the C++17 standard
|
||||
and a draft close to that version is
|
||||
[Working Draft N4687](https://github.com/cplusplus/draft/raw/master/papers/n4687.pdf).
|
||||
It is from after the standardization of C++17 but it contains the latest filesystem
|
||||
interface changes compared to the
|
||||
[Working Draft N4659](https://github.com/cplusplus/draft/raw/master/papers/n4659.pdf).
|
||||
|
||||
I want to thank the people working on improving C++, I really liked how the language
|
||||
evolved with C++11 and the following standards. Keep on the good work!
|
||||
|
||||
Oh, and if you ask yourself, what `ghc` is standing for, it is simply
|
||||
`gulraks helper classes`, yeah, I know, not very imaginative, but I wanted a
|
||||
short namespace and I use it in some of my private classes (so it has nothing
|
||||
to do with Haskell).
|
||||
|
||||
## Platforms
|
||||
|
||||
`ghc::filesystem` is developed on macOS but tested on Windows and Linux.
|
||||
It should work on any of these with a C++11-capable compiler. I currently
|
||||
don't have a BSD derivate besides macOS, so the preprocessor checks will
|
||||
cry out if you try to use it there, but if there is demand, I can try to
|
||||
help. Also there are some checks to hopefully better work on Android, but
|
||||
as I currently don't test with the Android NDK, I wouldn't call it a
|
||||
supported platform yet. All in all, I don't see it replacing `std::filesystem`
|
||||
where full C++17 is available, it doesn't try to be a "better"
|
||||
`std::filesystem`, just a drop-in if you can't use it (with the exception
|
||||
of the UTF-8 preference on Windows).
|
||||
|
||||
|
||||
Unit tests are currently run with:
|
||||
|
||||
* macOS 10.12: Xcode 9.2 (clang-900.0.39.2), GCC 9.2, Clang 9.0, macOS 10.13: Xcode 10.1, macOS 10.14: Xcode 11.2
|
||||
* Windows: Visual Studio 2017, Visual Studio 2015, Visual Studio 2019, MinGW GCC 6.3 (Win32), GCC 7.2 (Win64)
|
||||
* Linux (Ubuntu): GCC (5.5, 6.5, 7.4, 8.3, 9.2), Clang (5.0, 6.0, 7.1, 8.0, 9.0)
|
||||
|
||||
|
||||
## Tests
|
||||
|
||||
The header comes with a set of unit-tests and uses [CMake](https://cmake.org/)
|
||||
as a build tool and [Catch2](https://github.com/catchorg/Catch2) as test framework.
|
||||
|
||||
All tests agains this implementation should succeed, depending on your environment
|
||||
it might be that there are some warnings, e.g. if you have no rights to create
|
||||
Symlinks on Windows or at least the test thinks so, but these are just informative.
|
||||
|
||||
To build the tests from inside the project directory under macOS or Linux just:
|
||||
|
||||
```cpp
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DCMAKE_BUILD_TYPE=Debug ..
|
||||
make
|
||||
```
|
||||
|
||||
This generates `filesystem_test`, the binary that runs all tests.
|
||||
|
||||
If the default compiler is a GCC 8 or newer, or Clang 7 or newer, it
|
||||
additionally tries to build a version of the test binary compiled against GCCs/Clangs
|
||||
`std::filesystem` implementation, named `std_filesystem_test`
|
||||
as an additional test of conformance. Ideally all tests should compile and
|
||||
succeed with all filesystem implementations, but in reality, there are
|
||||
some differences in behavior, sometimes due to room for interpretation in
|
||||
in the standard, and there might be issues in these implementations too.
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
### Downloads
|
||||
|
||||
The latest release version is [v1.2.10](https://github.com/gulrak/filesystem/tree/v1.2.10) and
|
||||
source archives can be found [here](https://github.com/gulrak/filesystem/releases/tag/v1.2.10).
|
||||
|
||||
### Using it as Single-File-Header
|
||||
|
||||
As `ghc::filesystem` is at first a header-only library, it should be enough to copy the header
|
||||
or the `include/ghc` directory into your project folder oder point your include path to this place and
|
||||
simply include the `filesystem.hpp` header (or `ghc/filesystem.hpp` if you use the subdirectory).
|
||||
|
||||
Everything is in the namespace `ghc::filesystem`, so one way to use it only as
|
||||
a fallback could be:
|
||||
|
||||
```cpp
|
||||
#if defined(__cplusplus) && __cplusplus >= 201703L && defined(__has_include)
|
||||
#if __has_include(<filesystem>)
|
||||
#define GHC_USE_STD_FS
|
||||
#include <filesystem>
|
||||
namespace fs = std::filesystem;
|
||||
#endif
|
||||
#endif
|
||||
#ifndef GHC_USE_STD_FS
|
||||
#include <ghc/filesystem.hpp>
|
||||
namespace fs = ghc::filesystem;
|
||||
#endif
|
||||
```
|
||||
|
||||
**Note that this code uses a two-stage preprocessor condition because Visual Studio 2015
|
||||
doesn't like the `(<...>)` syntax, even if it could cut evaluation early before.**
|
||||
|
||||
**Note also, that on MSVC this detection only works starting from version 15.7 on and when setting
|
||||
the `/Zc:__cplusplus` compile switch, as the compiler allways reports `199711L`
|
||||
without that switch ([see](https://blogs.msdn.microsoft.com/vcblog/2018/04/09/msvc-now-correctly-reports-__cplusplus/)).**
|
||||
|
||||
If you want to also use the `fstream` wrapper with `path` support as fallback,
|
||||
you might use:
|
||||
|
||||
```cpp
|
||||
#if defined(__cplusplus) && __cplusplus >= 201703L && defined(__has_include)
|
||||
#if __has_include(<filesystem>)
|
||||
#define GHC_USE_STD_FS
|
||||
#include <filesystem>
|
||||
namespace fs {
|
||||
using namespace std::filesystem;
|
||||
using ifstream = std::ifstream;
|
||||
using ofstream = std::ofstream;
|
||||
using fstream = std::fstream;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#ifndef GHC_USE_STD_FS
|
||||
#include <ghc/filesystem.hpp>
|
||||
namespace fs {
|
||||
using namespace ghc::filesystem;
|
||||
using ifstream = ghc::filesystem::ifstream;
|
||||
using ofstream = ghc::filesystem::ofstream;
|
||||
using fstream = ghc::filesystem::fstream;
|
||||
}
|
||||
#endif
|
||||
```
|
||||
|
||||
Now you have e.g. `fs::ofstream out(somePath);` and it is either the wrapper or
|
||||
the C++17 `std::ofstream`.
|
||||
|
||||
**Be aware, as a header-only library, it is not hiding the fact, that it
|
||||
uses system includes, so they "pollute" your global namespace.**
|
||||
|
||||
:information_source: **Hint:** There is an additional header named `ghc/fs_std.hpp` that implements this
|
||||
dynamic selection of a filesystem implementation, that you can include
|
||||
instead of `ghc/filesystem.hpp` when you want std::filesystem where
|
||||
available and ghc::filesystem where not. It also enables the `wchar_t`
|
||||
support on `ghc::filesystem` on Windows, so the resulting implementation
|
||||
in the `fs` namespace will be compatible.
|
||||
|
||||
|
||||
### Using it as Forwarding-/Implementation-Header
|
||||
|
||||
Alternatively, starting from v1.1.0 `ghc::filesystem` can also be used by
|
||||
including one of two additional wrapper headers. These allow to include
|
||||
a forwarded version in most places (`ghc/fs_fwd.hpp`) while hiding the
|
||||
implementation details in a single cpp that includes `ghc/fs_impl.hpp` to
|
||||
implement the needed code. That way system includes are only visible from
|
||||
inside the cpp, all other places are clean.
|
||||
|
||||
Be aware, that it is currently not supported to hide the implementation
|
||||
into a Windows-DLL, as a DLL interface with C++ standard templates in interfaces
|
||||
is a different beast. If someone is willing to give it a try, I might integrate
|
||||
a PR but currently working on that myself is not a priority.
|
||||
|
||||
If you use the forwarding/implementation approach, you can still use the dynamic
|
||||
switching like this:
|
||||
|
||||
```cpp
|
||||
#if defined(__cplusplus) && __cplusplus >= 201703L && defined(__has_include)
|
||||
#if __has_include(<filesystem>)
|
||||
#define GHC_USE_STD_FS
|
||||
#include <filesystem>
|
||||
namespace fs {
|
||||
using namespace std::filesystem;
|
||||
using ifstream = std::ifstream;
|
||||
using ofstream = std::ofstream;
|
||||
using fstream = std::fstream;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#ifndef GHC_USE_STD_FS
|
||||
#include <ghc/fs-fwd.hpp>
|
||||
namespace fs {
|
||||
using namespace ghc::filesystem;
|
||||
using ifstream = ghc::filesystem::ifstream;
|
||||
using ofstream = ghc::filesystem::ofstream;
|
||||
using fstream = ghc::filesystem::fstream;
|
||||
}
|
||||
#endif
|
||||
```
|
||||
|
||||
and in the implementation hiding cpp, you might use (before any include that includes `ghc/fs_fwd.hpp`
|
||||
to take precedence:
|
||||
|
||||
```cpp
|
||||
#if !(defined(__cplusplus) && __cplusplus >= 201703L && defined(__has_include)
|
||||
#if __has_include(<filesystem>))
|
||||
#include <ghc/fs_impl.hpp>
|
||||
#endif
|
||||
#endif
|
||||
```
|
||||
|
||||
:information_source: **Hint:** There are additional helper headers, named `ghc/fs_std_fwd.hpp` and
|
||||
`ghc/fs_std_impl.hpp` that use this technique, so you can simply include them
|
||||
if you want to dynamically select the filesystem implementation. they also
|
||||
enable the `wchar_t` support on `ghc::filesystem` on Windows, so the resulting
|
||||
implementation in the `fs` namespace will be compatible.
|
||||
|
||||
|
||||
|
||||
### Git Submodule and CMake
|
||||
|
||||
Starting from v1.1.0, it is possible to add `ghc::filesystem`
|
||||
as a git submodule, add the directory to your `CMakeLists.txt` with
|
||||
`add_subdirectory()` and then simply use `target_link_libraries(your-target ghc_filesystem)`
|
||||
to ensure correct include path that allow `#include <ghc/filesystem.hpp>`
|
||||
to work.
|
||||
|
||||
The `CMakeLists.txt` offers a few options to customize its behaviour:
|
||||
|
||||
* `GHC_FILESYSTEM_BUILD_TESTING` - Compile tests, default is `OFF` when used as
|
||||
a submodule, else `ON`.
|
||||
* `GHC_FILESYSTEM_BUILD_EXAMPLES` - Compile the examples, default is `OFF` when used as
|
||||
a submodule, else `ON`.
|
||||
* `GHC_FILESYSTEM_WITH_INSTALL` - Add install target to build, default is `OFF` when used as
|
||||
a submodule, else `ON`.
|
||||
|
||||
### Versioning
|
||||
|
||||
There is a version macro `GHC_FILESYSTEM_VERSION` defined in case future changes
|
||||
might make it needed to react on the version, but I don't plan to break anything.
|
||||
It's the version as decimal number `(major * 10000 + minor * 100 + patch)`.
|
||||
|
||||
**Note:** Starting from v1.0.2 only even patch versions will be used for releases
|
||||
and odd patch version will only be used for in between commits while working on
|
||||
the next version.
|
||||
|
||||
|
||||
## Documentation
|
||||
|
||||
There is almost no documentation in this release, as any `std::filesystem`
|
||||
documentation would work, besides the few differences explained in the next
|
||||
section. So you might head over to https://en.cppreference.com/w/cpp/filesystem
|
||||
for a description of the components of this library.
|
||||
|
||||
The only additions to the standard are documented here:
|
||||
|
||||
|
||||
### `ghc::filesystem::ifstream`, `ghc::filesystem::ofstream`, `ghc::filesystem::fstream`
|
||||
|
||||
These are simple wrappers around `std::ifstream`, `std::ofstream` and `std::fstream`.
|
||||
They simply add an `open()` method and a constuctor with an `ghc::filesystem::path`
|
||||
argument as the `fstream` variants in C++17 have them.
|
||||
|
||||
### `ghc::filesystem::u8arguments`
|
||||
|
||||
This is a helper class that currently checks for UTF-8 encoding on non-Windows platforms but on Windows it
|
||||
fetches the command line arguments als Unicode strings from the OS with
|
||||
|
||||
```cpp
|
||||
::CommandLineToArgvW(::GetCommandLineW(), &argc)
|
||||
```
|
||||
|
||||
and then converts them to UTF-8, and replaces `argc` and `argv`. It is a guard-like
|
||||
class that reverts its changes when going out of scope.
|
||||
|
||||
So basic usage is:
|
||||
|
||||
```cpp
|
||||
namespace fs = ghc::filesystem;
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
fs::u8arguments u8guard(argc, argv);
|
||||
if(!u8guard.valid()) {
|
||||
std::cerr << "Bad encoding, needs UTF-8." << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// now use argc/argv as usual, they have utf-8 enconding on windows
|
||||
// ...
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
That way `argv` is UTF-8 encoded as long as the scope from `main` is valid.
|
||||
|
||||
**Note:** On macOS, while debugging under Xcode the code currently will return
|
||||
`false` as Xcode starts the application with `US-ASCII` as encoding, no matter what
|
||||
encoding is actually used and even setting `LC_ALL` in the product scheme doesn't
|
||||
change anything. I still need to investigate this.
|
||||
|
||||
|
||||
## Differences
|
||||
|
||||
As this implementation is based on existing code from my private helper
|
||||
classes, it derived some constraints of it, leading to some differences
|
||||
between this and the standard C++17 API.
|
||||
|
||||
|
||||
### LWG Defects
|
||||
|
||||
This implementation has switchable behavior for the LWG defects
|
||||
[#2682](https://wg21.cmeerw.net/lwg/issue2682),
|
||||
[#2935](http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2935) and
|
||||
[#2937](http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2937).
|
||||
The currently selected behavior is following
|
||||
[#2682](https://wg21.cmeerw.net/lwg/issue2682),
|
||||
[#2937](http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2937) but
|
||||
not following [#2935](http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2935),
|
||||
as I feel it is a bug to report no error on a `create_directory()` or `create_directories()`
|
||||
where a regular file of the same name prohibits the creation of a directory and forces
|
||||
the user of those functions to double-check via `fs::is_directory` if it really worked.
|
||||
The more intuitive approach to directory creation of treating a file with that name as an
|
||||
error is also advocated by the newer paper
|
||||
[WG21 P1164R0](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1164r0.pdf), the revison
|
||||
P1161R1 was agreed upon on Kona 2019 meeting [see merge](https://github.com/cplusplus/draft/issues/2703)
|
||||
and GCC by now switched to following its proposal
|
||||
([GCC #86910](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86910)).
|
||||
|
||||
### Not Implemented on C++ before C++17
|
||||
|
||||
```cpp
|
||||
// methods in ghc::filesystem::path:
|
||||
path& operator+=(basic_string_view<value_type> x);
|
||||
int compare(basic_string_view<value_type> s) const;
|
||||
```
|
||||
|
||||
These are not implemented under C++11 and C++14, as there is no
|
||||
`std::basic_string_view` available and I did want to keep this
|
||||
implementation self-contained and not write a full C++17-upgrade for
|
||||
C++11/14. Starting with v1.1.0 these are supported when compiling
|
||||
ghc::filesystem under C++17.
|
||||
|
||||
|
||||
### Differences in API
|
||||
|
||||
```cpp
|
||||
filesystem::path::string_type
|
||||
filesystem::path::value_type
|
||||
```
|
||||
|
||||
In Windows, an implementation should use `std::wstring` and `wchar_t` as types used
|
||||
for the native representation, but as I'm a big fan of the
|
||||
["UTF-8 Everywhere" philosophy](https://utf8everywhere.org/), I decided
|
||||
agains it for now. If you need to call some Windows API, use the W-variant
|
||||
with the `path::wstring()` member
|
||||
(e.g. `GetFileAttributesW(p.wstring().c_str())`). This gives you the
|
||||
Unicode variant independant of the `UNICODE` macro and makes sharing code
|
||||
between Windows, Linux and macOS easier.
|
||||
|
||||
Starting with v1.2.0 `ghc::filesystem` has the option to select the more
|
||||
standard conforming APi with `wchar_t` and `std::wstring` on Windows by
|
||||
defining `GHC_WIN_WSTRING_STRING_TYPE`. This define has no effect on other
|
||||
platforms and will be set by the helping headers `ghc/fs_std.hpp` and
|
||||
the pair `ghc/fs_std_fwd.hpp`/`ghc/fs_std_impl.hpp` to enhance compatibility.
|
||||
|
||||
|
||||
```cpp
|
||||
const path::string_type& path::native() const /*noexcept*/;
|
||||
const path::value_type *path::c_str() const /*noexcept*/;
|
||||
```
|
||||
|
||||
These two can not be `noexcept` with the current implementation. This due
|
||||
to the fact, that internally path is working on the generic path version
|
||||
only, and the getters need to do a conversion to native path format.
|
||||
|
||||
```cpp
|
||||
const path::string_type& path::generic_string() const;
|
||||
```
|
||||
|
||||
This returns a const reference, instead of a value, because it can. This
|
||||
implementation uses the generic representation for internal workings, so
|
||||
it's "free" to return that.
|
||||
|
||||
|
||||
### Differences in Behavior
|
||||
|
||||
#### fs.path ([ref](https://en.cppreference.com/w/cpp/filesystem/path))
|
||||
|
||||
As the complete inner mechanics of this implementation `fs::path` are working
|
||||
on the generic format, it is the internal representation. So creating any mixed
|
||||
slash `fs::path` object under Windows (e.g. with `"C:\foo/bar"`) will lead to a
|
||||
unified path with `"C:\foo\bar"` via `native()` and `"C:/foo/bar"` via
|
||||
`generic_string()` API.
|
||||
|
||||
Additionally this implementation follows the standards suggestion to handle
|
||||
posix paths of the form `"//host/path"` and USC path on windows also as having
|
||||
a root-name (e.g. `"//host"`). The GCC implementation didn't choose to do that
|
||||
while testing on Ubuntu 18.04 and macOS with GCC 8.1.0 or Clang 7.0.0. This difference
|
||||
will show as warnings under std::filesystem. This leads to a change in the
|
||||
algorithm described in the standard for `operator/=(path& p)` where any path
|
||||
`p` with `p.is_absolute()` will degrade to an assignment, while this implementation
|
||||
has the exception where `*this == *this.root_name()` and `p == preferred_seperator`
|
||||
a normal append will be done, to allow:
|
||||
|
||||
```cpp
|
||||
fs::path p1 = "//host/foo/bar/file.txt";
|
||||
fs::path p2;
|
||||
for (auto p : p1) p2 /= p;
|
||||
ASSERT(p1 == p2);
|
||||
```
|
||||
|
||||
For all non-host-leading paths the behaviour will match the one described by
|
||||
the standard.
|
||||
|
||||
#### fs.op.copy ([ref](https://en.cppreference.com/w/cpp/filesystem/copy))
|
||||
|
||||
Then there is `fs::copy`. The tests in the suite fail partially with C++17 `std::filesystem`
|
||||
on GCC/Clang. They complain about a copy call with `fs::copy_options::recursive` combined
|
||||
with `fs::copy_options::create_symlinks` or `fs::copy_options::create_hard_links` if the
|
||||
source is a directory. There is nothing in the standard that forbids this combination
|
||||
and it is the only way to deep-copy a tree while only create links for the files.
|
||||
There is [LWG #2682](https://wg21.cmeerw.net/lwg/issue2682) that supports this
|
||||
interpretation, but the issue ignores the usefulness of the combination with recursive
|
||||
and part of the justification for the proposed solution is "we did it so for almost two years".
|
||||
But this makes `fs::copy` with `fs::copy_options::create_symlinks` or `fs::copy_options::create_hard_links`
|
||||
just a more complicated syntax for the `fs::create_symlink` or `fs::create_hardlink` operation
|
||||
and I don't want to believe, that this was the intention of the original writing.
|
||||
As there is another issue related to copy, with a different take on the description.
|
||||
|
||||
**Note:** With v1.1.2 I decided to integrate a behavior switch for this and make the LWG #2682
|
||||
the default.
|
||||
|
||||
## Open Issues
|
||||
|
||||
### General Known Issues
|
||||
|
||||
There are still some methods that break the `noexcept` clause, some
|
||||
are related to LWG defects, some are due to my implementation. I
|
||||
work on fixing the later ones, and might in cases where there is no
|
||||
way of implementing the feature without risk of an exception, break
|
||||
conformance and remove the `noexcept`.
|
||||
|
||||
### Windows
|
||||
|
||||
#### Symbolic Links on Windows
|
||||
|
||||
As symbolic links on Windows, while being supported more or less since
|
||||
Windows Vista (with some strict security constraints) and fully since some earlier
|
||||
build of Windows 10, when "Developer Mode" is activated, are at time of writing
|
||||
(2018) rarely used, still they are supported with this implementation.
|
||||
|
||||
#### Permissions
|
||||
|
||||
The Windows ACL permission feature translates badly to the POSIX permission
|
||||
bit mask used in the interface of C++17 filesystem. The permissions returned
|
||||
in the `file_status` are therefore currently synthesized for the `user`-level
|
||||
and copied to the `group`- and `other`-level. There is still some potential
|
||||
for more interaction with the Windows permission system, but currently setting
|
||||
or reading permissions with this implementation will most certainly not lead
|
||||
to the expected behavior.
|
||||
|
||||
|
||||
## Release Notes
|
||||
|
||||
### [v1.2.10](https://github.com/gulrak/filesystem/releases/tag/v1.2.10)
|
||||
|
||||
* The Visual Studio 2019 compiler, GCC 9.2 and Clang 9.0 where added to the
|
||||
CI configuration.
|
||||
* Bugfix for [#39](https://github.com/gulrak/filesystem/issues/39), `fs::rename`
|
||||
on Windows didn't replace an axisting regular file as required by the standard,
|
||||
but gave an error. New tests and a fix as provided in the issue was implemented.
|
||||
* Bugfix for [#39](https://github.com/gulrak/filesystem/issues/39), for the
|
||||
forwarding use via `fs_fwd.hpp` or `fs_std_fwd.hpp` der was a use of
|
||||
`DWORD` in the forwarding part leading to an error if `Windows.h` was not
|
||||
included before the header. The tests were changed to give an error in that
|
||||
case too and the useage of `DWORD` was removed.
|
||||
* Bugfix for [#38](https://github.com/gulrak/filesystem/issues/38), casting the
|
||||
return value of `GetProcAddress` gave a warning with `-Wcast-function-type`
|
||||
on MSYS2 and MinGW GCC 9 builds.
|
||||
|
||||
### [v1.2.8](https://github.com/gulrak/filesystem/releases/tag/v1.2.8)
|
||||
|
||||
* Pull request [#30](https://github.com/gulrak/filesystem/pull/30), the
|
||||
`CMakeLists.txt` will automatically exclude building examples and tests when
|
||||
used as submodule, the configuration options now use a prefixed name to
|
||||
reduce risk of conflicts.
|
||||
* Pull request [#24](https://github.com/gulrak/filesystem/pull/24), install
|
||||
target now creates a `ghcFilesystemConfig.cmake` in
|
||||
`${CMAKE_INSTALL_LIBDIR}/cmake/ghcFilesystem` for `find_package` that
|
||||
exports a target as `ghcFilesystem::ghc_filesystem`.
|
||||
* Pull request [#31](https://github.com/gulrak/filesystem/pull/31), fixes
|
||||
`error: redundant redeclaration of 'constexpr' static data member` deprecation
|
||||
warning in C++17 mode.
|
||||
* Pull request [#32](https://github.com/gulrak/filesystem/pull/32), fixes
|
||||
old-style-cast warnings.
|
||||
* Pull request [#34](https://github.com/gulrak/filesystem/pull/34), fixes
|
||||
[TOCTOU](https://en.wikipedia.org/wiki/Time-of-check_to_time-of-use) situation
|
||||
on `fs::create_directories`, thanks for the PR!
|
||||
* Feature [#35](https://github.com/gulrak/filesystem/issues/35), new CMake
|
||||
option to add an install target `GHC_FILESYSTEM_WITH_INSTALL` that is
|
||||
defaulted to OFF if `ghc::filesystem` is used via `add_subdirectory`.
|
||||
* Bugfix for [#33](https://github.com/gulrak/filesystem/issues/33), fixes
|
||||
an issue with `fs::path::lexically_normal()` that leaves a trailing separator
|
||||
in case of a resulting path ending with `..` as last element.
|
||||
* Bugfix for [#36](https://github.com/gulrak/filesystem/issues/36), warings
|
||||
on Xcode 11.2 due to unhelpfull references in path element iteration.
|
||||
|
||||
### [v1.2.6](https://github.com/gulrak/filesystem/releases/tag/v1.2.6)
|
||||
|
||||
* Pull request [#23](https://github.com/gulrak/filesystem/pull/23), tests and
|
||||
examples can now be disabled in CMake via seting `BUILD_TESTING` and
|
||||
`BUILD_EXAMPLES` to `NO`, `OFF` or `FALSE`.
|
||||
* Pull request [#25](https://github.com/gulrak/filesystem/pull/25),
|
||||
missing specialization for construction from `std::string_view` when
|
||||
available was added.
|
||||
* Additional test case when `std::string_view` is available.
|
||||
* Bugfix for [#27](https://github.com/gulrak/filesystem/issues/27), the
|
||||
`fs::path::preferred_seperator` declaration was not compiling on pre
|
||||
C++17 compilers and no test accessed it, to show the problem. Fixed
|
||||
it to an construction C++11 compiler should accept and added a test that
|
||||
is successful on all combinations tested.
|
||||
* Bugfix for [#29](https://github.com/gulrak/filesystem/issues/29), stricter
|
||||
warning settings where chosen and resulting warnings where fixed.
|
||||
|
||||
### [v1.2.4](https://github.com/gulrak/filesystem/releases/tag/v1.2.4)
|
||||
|
||||
* Enabled stronger warning switches and resulting fixed issues on GCC and MinGW
|
||||
* Bugfix for #22, the `fs::copy_options` where not forwarded from `fs::copy` to
|
||||
`fs::copy_file` in one of the cases.
|
||||
|
||||
### [v1.2.2](https://github.com/gulrak/filesystem/releases/tag/v1.2.2)
|
||||
|
||||
* Fix for ([#21](https://github.com/gulrak/filesystem/pull/21)), when compiling
|
||||
on Alpine Linux with musl instead of glibc, the wrong `strerror_r` signature
|
||||
was expected. The complex preprocessor define mix was dropped in favor of
|
||||
the usual dispatch by overloading a unifying wrapper.
|
||||
|
||||
### [v1.2.0](https://github.com/gulrak/filesystem/releases/tag/v1.2.0)
|
||||
|
||||
* Added MinGW 32/64 and Visual Studio 2015 builds to the CI configuration.
|
||||
* Fixed additional compilation issues on MinGW.
|
||||
* Pull request ([#13](https://github.com/gulrak/filesystem/pull/13)), set
|
||||
minimum required CMake version to 3.7.2 (as in Debian 8).
|
||||
* Pull request ([#14](https://github.com/gulrak/filesystem/pull/14)), added
|
||||
support for a make install target.
|
||||
* Bugfix for ([#15](https://github.com/gulrak/filesystem/issues/15)), the
|
||||
forward/impl way of using `ghc::filesystem` missed a `<vector>` include
|
||||
in the windows case.
|
||||
* Bugfix for ([#16](https://github.com/gulrak/filesystem/issues/16)),
|
||||
VS2019 didn't like the old size dispatching in the utf8 decoder, so it
|
||||
was changed to a sfinae based approach.
|
||||
* New feature ([#17](https://github.com/gulrak/filesystem/issues/17)), optional
|
||||
support for standard conforming `wchar_t/std::wstring` interface when
|
||||
compiling on Windows with defined `GHC_WIN_WSTRING_STRING_TYPE`, this is
|
||||
default when using the `ghc/fs_std*.hpp` header, to enhance compatibility.
|
||||
* New feature ([#18](https://github.com/gulrak/filesystem/issues/18)), optional
|
||||
filesystem exceptions/errors on unicode errors with defined
|
||||
`GHC_RAISE_UNICODE_ERRORS` (instead of replacing invalid code points or
|
||||
UTF-8 encoding errors with the replacement character `U+FFFD`).
|
||||
* Pull request ([#20](https://github.com/gulrak/filesystem/pull/20)), fix for
|
||||
file handle leak in `fs::copy_file`.
|
||||
* Coverage now checked in CI (~95% line coverage).
|
||||
|
||||
### [v1.1.4](https://github.com/gulrak/filesystem/releases/tag/v1.1.4)
|
||||
|
||||
* Additional Bugfix for ([#12](https://github.com/gulrak/filesystem/issues/12)),
|
||||
error in old unified `readdir/readdir_r` code of `fs::directory_iterator`;
|
||||
as `readdir_r` is now depricated, I decided to drop it and the resulting
|
||||
code is much easier, shorter and due to more refactoring faster
|
||||
* Fix for crashing unit tests against MSVC C++17 std::filesystem
|
||||
* Travis-CI now additionally test with Xcode 10.2 on macOS
|
||||
* Some minor refactorings
|
||||
|
||||
### [v1.1.2](https://github.com/gulrak/filesystem/releases/tag/v1.1.2)
|
||||
|
||||
* Bugfix for ([#11](https://github.com/gulrak/filesystem/issues/11)),
|
||||
`fs::path::lexically_normal()` had some issues with `".."`-sequences.
|
||||
* Bugfix for ([#12](https://github.com/gulrak/filesystem/issues/12)),
|
||||
`fs::recursive_directory_iterator` could run into endless loops,
|
||||
the methods depth() and pop() had issues and the copy behaviour and
|
||||
`input_iterator_tag` conformance was broken, added tests
|
||||
* Restructured some CMake code into a macro to ease the support for
|
||||
C++17 std::filesystem builds of tests and examples for interoperability
|
||||
checks.
|
||||
* Some fixes on Windows tests to ease interoperability test runs.
|
||||
* Reduced noise on `fs::weakly_canonical()` tests against `std::fs`
|
||||
* Added simple `du` example showing the `recursive_directory_iterator`
|
||||
used to add the sizes of files in a directory tree.
|
||||
* Added error checking in `fs::file_time_type` test helpers
|
||||
* `fs::copy()` now conforms LWG #2682, disallowing the use of
|
||||
`copy_option::create_symlinks' to be used on directories
|
||||
|
||||
### [v1.1.0](https://github.com/gulrak/filesystem/releases/tag/v1.1.0)
|
||||
|
||||
* Restructuring of the project directory. The header files are now using
|
||||
`hpp` as extension to be marked as c++ and they where moved to
|
||||
`include/ghc/` to be able to include by `<ghc/filesystem.hpp>` as the
|
||||
former include name might have been to generic and conflict with other
|
||||
files.
|
||||
* Better CMake support: `ghc::filesystem` now can be used as a submodul
|
||||
and added with `add_subdirectory` and will export itself as `ghc_filesystem`
|
||||
target. To use it, only `target_link_libraries(your-target ghc_filesystem)`
|
||||
is needed and the include directories will be set so `#include <ghc/filesystem.hpp>`
|
||||
will be a valid directive.
|
||||
Still you can simply only add the header file to you project and include it
|
||||
from there.
|
||||
* Enhancement ([#10](https://github.com/gulrak/filesystem/issues/10)),
|
||||
support for separation of implementation and forwarded api: Two
|
||||
additional simple includes are added, that can be used to forward
|
||||
`ghc::filesystem` declarations (`fs_fwd.hpp`) and to wrap the
|
||||
implementation into a single cpp (`fs_impl.hpp`)
|
||||
* The `std::basic_string_view` variants of the `fs::path` api are
|
||||
now supported when compiling with C++17.
|
||||
* Added CI integration for Travis-CI and Appveyor.
|
||||
* Fixed MinGW compilation issues.
|
||||
* Added long filename support for Windows.
|
||||
|
||||
### [v1.0.10](https://github.com/gulrak/filesystem/releases/tag/v1.0.10)
|
||||
|
||||
* Bugfix for ([#9](https://github.com/gulrak/filesystem/issues/9)), added
|
||||
missing return statement to `ghc::filesystem::path::generic_string()`
|
||||
* Added checks to hopefully better compile against Android NDK. There where
|
||||
no tests run yet, so feedback is needed to actually call this supported.
|
||||
* `filesystem.h` was renamed `filesystem.hpp` to better reflect that it is
|
||||
a c++ language header.
|
||||
|
||||
### [v1.0.8](https://github.com/gulrak/filesystem/releases/tag/v1.0.8)
|
||||
|
||||
* Bugfix for ([#6](https://github.com/gulrak/filesystem/issues/6)), where
|
||||
`ghc::filesystem::remove()` and `ghc::filesystem::remove_all()` both are
|
||||
now able to remove a single file and both will not raise an error if the
|
||||
path doesn't exist.
|
||||
* Merged pull request ([#7](https://github.com/gulrak/filesystem/pull/7)),
|
||||
a typo leading to setting error code instead of comparing it in
|
||||
`ghc::filesystem::remove()` under Windows.
|
||||
* Bugfix for (([#8](https://github.com/gulrak/filesystem/issues/8)), the
|
||||
Windows version of `ghc::filesystem::directory_iterator` now releases
|
||||
resources when reaching `end()` like the POSIX one does.
|
||||
|
||||
|
||||
### [v1.0.6](https://github.com/gulrak/filesystem/releases/tag/v1.0.6)
|
||||
|
||||
* Bugfix for ([#4](https://github.com/gulrak/filesystem/issues/4)), missing error_code
|
||||
propagation in `ghc::filesystem::copy()` and `ghc::filesystem::remove_all` fixed.
|
||||
* Bugfix for ([#5](https://github.com/gulrak/filesystem/issues/5)), added missing std
|
||||
namespace in `ghc::filesystem::recursive_directory_iterator::difference_type`.
|
||||
|
||||
### [v1.0.4](https://github.com/gulrak/filesystem/releases/tag/v1.0.4)
|
||||
|
||||
* Bugfix for ([#3](https://github.com/gulrak/filesystem/issues/3)), fixed missing inlines
|
||||
and added test to ensure including into multiple implementation files works as expected.
|
||||
* Building tests with `-Wall -Wextra -Werror` and fixed resulting issues.
|
||||
|
||||
### [v1.0.2](https://github.com/gulrak/filesystem/releases/tag/v1.0.2)
|
||||
|
||||
* Updated catch2 to v2.4.0.
|
||||
* Refactored `fs.op.permissions` test to work with all tested `std::filesystem`
|
||||
implementations (gcc, clang, msvc++).
|
||||
* Added helper class `ghc::filesystem::u8arguments` as `argv` converter, to
|
||||
help follow the UTF-8 path on windows. Simply instantiate it with `argc` and
|
||||
`argv` and it will fetch the Unicode version of the command line and convert
|
||||
it to UTF-8. The destructor reverts the change.
|
||||
* Added `examples` folder with hopefully some usefull example usage. Examples are
|
||||
tested (and build) with `ghc::filesystem` and C++17 `std::filesystem` when
|
||||
available.
|
||||
* Starting with this version, only even patch level versions will be tagged and
|
||||
odd patch levels mark in-between non-stable wip states.
|
||||
* Tests can now also be run against MS version of std::filesystem for comparison.
|
||||
* Added missing `fstream` include.
|
||||
* Removed non-conforming C99 `timespec`/`timeval` usage.
|
||||
* Fixed some integer type mismatches that could lead to warnings.
|
||||
* Fixed `chrono` conversion issues in test and example on clang 7.0.0.
|
||||
|
||||
### [v1.0.1](https://github.com/gulrak/filesystem/releases/tag/v1.0.1)
|
||||
|
||||
* Bugfix: `ghc::filesystem::canonical` now sees empty path as non-existant and reports
|
||||
an error. Due to this `ghc::filesystem::weakly_canonical` now returns relative
|
||||
paths for non-existant argument paths. ([#1](https://github.com/gulrak/filesystem/issues/1))
|
||||
* Bugfix: `ghc::filesystem::remove_all` now also counts directories removed ([#2](https://github.com/gulrak/filesystem/issues/2))
|
||||
* Bugfix: `recursive_directory_iterator` tests didn't respect equality domain issues
|
||||
and dereferencable constraints, leading to fails on `std::filesystem` tests.
|
||||
* Bugfix: Some `noexcept` tagged methods and functions could indirectly throw exceptions
|
||||
due to UFT-8 decoding issues.
|
||||
* `std_filesystem_test` is now also generated if LLVM/clang 7.0.0 is found.
|
||||
|
||||
|
||||
### [v1.0.0](https://github.com/gulrak/filesystem/releases/tag/v1.0.0)
|
||||
|
||||
This was the first public release version. It implements the full range of
|
||||
C++17 std::filesystem, as far as possible without other C++17 dependencies.
|
||||
|
@ -0,0 +1,38 @@
|
||||
macro(AddExecutableWithStdFS targetName)
|
||||
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" AND (CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 7.0 OR CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 7.0))
|
||||
if(APPLE)
|
||||
include_directories(/usr/local/opt/llvm/include)
|
||||
link_directories(/usr/local/opt/llvm/lib)
|
||||
endif()
|
||||
add_executable(${targetName} ${ARGN})
|
||||
set_property(TARGET ${targetName} PROPERTY CXX_STANDARD 17)
|
||||
if(APPLE)
|
||||
target_link_libraries(${targetName} -lc++fs)
|
||||
else()
|
||||
target_compile_options(${targetName} PRIVATE "-stdlib=libc++")
|
||||
target_link_libraries(${targetName} -stdlib=libc++ -lc++fs)
|
||||
endif()
|
||||
|
||||
target_link_libraries(${targetName} -lc++fs)
|
||||
target_compile_definitions(${targetName} PRIVATE USE_STD_FS)
|
||||
endif()
|
||||
|
||||
if (CMAKE_COMPILER_IS_GNUCXX AND (CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 8.0 OR CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 8.0))
|
||||
add_executable(${targetName} ${ARGN})
|
||||
set_property(TARGET ${targetName} PROPERTY CXX_STANDARD 17)
|
||||
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.0)
|
||||
target_link_libraries(${targetName} -lstdc++fs)
|
||||
endif()
|
||||
target_compile_definitions(${targetName} PRIVATE USE_STD_FS)
|
||||
endif()
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES MSVC AND (CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 19.15 OR CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 19.15))
|
||||
add_executable(${targetName} ${ARGN})
|
||||
set_property(TARGET ${targetName} PROPERTY CXX_STANDARD 17)
|
||||
set_property(TARGET ${targetName} PROPERTY CXX_STANDARD_REQUIRED ON)
|
||||
target_compile_options(${targetName} PRIVATE "/Zc:__cplusplus")
|
||||
target_compile_definitions(${targetName} PRIVATE USE_STD_FS _CRT_SECURE_NO_WARNINGS)
|
||||
endif()
|
||||
|
||||
endmacro()
|
@ -0,0 +1,5 @@
|
||||
@PACKAGE_INIT@
|
||||
|
||||
set_and_check(ghcfilesystem_INCLUDE_DIRS "@PACKAGE_INCLUDE_INSTALL_DIR@")
|
||||
|
||||
check_required_components(ghcfilesystem)
|
@ -0,0 +1,12 @@
|
||||
|
||||
add_executable(fs_dir dir.cpp)
|
||||
target_link_libraries(fs_dir ghc_filesystem)
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES MSVC)
|
||||
target_compile_definitions(fs_dir PRIVATE _CRT_SECURE_NO_WARNINGS)
|
||||
endif()
|
||||
AddExecutableWithStdFS(std_fs_dir dir.cpp)
|
||||
|
||||
add_executable(fs_du du.cpp)
|
||||
target_link_libraries(fs_du ghc_filesystem)
|
||||
AddExecutableWithStdFS(std_fs_du du.cpp)
|
||||
|
@ -0,0 +1,60 @@
|
||||
#include <chrono>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#if defined(__cplusplus) && __cplusplus >= 201703L && defined(__has_include)
|
||||
#if __has_include(<filesystem>)
|
||||
#define GHC_USE_STD_FS
|
||||
#include <filesystem>
|
||||
namespace fs = std::filesystem;
|
||||
#endif
|
||||
#endif
|
||||
#ifndef GHC_USE_STD_FS
|
||||
#include <ghc/filesystem.hpp>
|
||||
namespace fs = ghc::filesystem;
|
||||
#endif
|
||||
|
||||
template <typename TP>
|
||||
std::time_t to_time_t(TP tp)
|
||||
{
|
||||
// Based on trick from: Nico Josuttis, C++17 - The Complete Guide
|
||||
std::chrono::system_clock::duration dt = std::chrono::duration_cast<std::chrono::system_clock::duration>(tp - TP::clock::now());
|
||||
return std::chrono::system_clock::to_time_t(std::chrono::system_clock::now() + dt);
|
||||
}
|
||||
|
||||
static std::string perm_to_str(fs::perms prms)
|
||||
{
|
||||
std::string result;
|
||||
result.reserve(9);
|
||||
for (int i = 0; i < 9; ++i) {
|
||||
result = ((static_cast<int>(prms) & (1 << i)) ? "xwrxwrxwr"[i] : '-') + result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
#ifdef GHC_FILESYSTEM_VERSION
|
||||
fs::u8arguments u8guard(argc, argv);
|
||||
if (!u8guard.valid()) {
|
||||
std::cerr << "Invalid character encoding, UTF-8 based encoding needed." << std::endl;
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
#endif
|
||||
if (argc > 2) {
|
||||
std::cerr << "USAGE: dir <path>" << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
fs::path dir{"."};
|
||||
if (argc == 2) {
|
||||
dir = fs::u8path(argv[1]);
|
||||
}
|
||||
for (auto de : fs::directory_iterator(dir)) {
|
||||
auto ft = to_time_t(de.last_write_time());
|
||||
auto ftm = *std::localtime(&ft);
|
||||
std::cout << (de.is_directory() ? "d" : "-") << perm_to_str(de.symlink_status().permissions()) << " " << std::setw(8) << (de.is_directory() ? "-" : std::to_string(de.file_size())) << " " << std::put_time(&ftm, "%Y-%m-%d %H:%M:%S") << " "
|
||||
<< de.path().filename().string() << std::endl;
|
||||
}
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <chrono>
|
||||
|
||||
#if defined(__cplusplus) && __cplusplus >= 201703L && defined(__has_include)
|
||||
#if __has_include(<filesystem>)
|
||||
#define GHC_USE_STD_FS
|
||||
#include <filesystem>
|
||||
namespace fs = std::filesystem;
|
||||
#endif
|
||||
#endif
|
||||
#ifndef GHC_USE_STD_FS
|
||||
#include <ghc/filesystem.hpp>
|
||||
namespace fs = ghc::filesystem;
|
||||
#endif
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
#ifdef GHC_FILESYSTEM_VERSION
|
||||
fs::u8arguments u8guard(argc, argv);
|
||||
if(!u8guard.valid()) {
|
||||
std::cerr << "Invalid character encoding, UTF-8 based encoding needed." << std::endl;
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
#endif
|
||||
if(argc > 2) {
|
||||
std::cerr << "USAGE: du <path>" << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
fs::path dir{"."};
|
||||
if(argc == 2) {
|
||||
dir = fs::u8path(argv[1]);
|
||||
}
|
||||
|
||||
uint64_t totalSize = 0;
|
||||
int totalDirs = 0;
|
||||
int totalFiles = 0;
|
||||
int maxDepth = 0;
|
||||
|
||||
try {
|
||||
auto rdi = fs::recursive_directory_iterator(dir);
|
||||
for(auto de : rdi) {
|
||||
if(rdi.depth() > maxDepth) {
|
||||
maxDepth = rdi.depth();
|
||||
}
|
||||
if(de.is_regular_file()) {
|
||||
totalSize += de.file_size();
|
||||
++totalFiles;
|
||||
}
|
||||
else if(de.is_directory()) {
|
||||
++totalDirs;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(fs::filesystem_error fe) {
|
||||
std::cerr << "Error: " << fe.what() << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
std::cout << totalSize << " bytes in " << totalFiles << " files and " << totalDirs << " directories, maximum depth: " << maxDepth << std::endl;
|
||||
return 0;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,46 @@
|
||||
//---------------------------------------------------------------------------------------
|
||||
//
|
||||
// ghc::filesystem - A C++17-like filesystem implementation for C++11/C++14
|
||||
//
|
||||
//---------------------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2018, Steffen Schümann <s.schuemann@pobox.com>
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice, this
|
||||
// list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software without
|
||||
// specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//---------------------------------------------------------------------------------------
|
||||
// fs_fwd.hpp - The forwarding header for the header/implementation seperated usage of
|
||||
// ghc::filesystem.
|
||||
// This file can be include at any place, where ghc::filesystem api is needed while
|
||||
// not bleeding implementation details (e.g. system includes) into the global namespace,
|
||||
// as long as one cpp includes fs_impl.hpp to deliver the matching implementations.
|
||||
//---------------------------------------------------------------------------------------
|
||||
#ifndef GHC_FILESYSTEM_FWD_H
|
||||
#define GHC_FILESYSTEM_FWD_H
|
||||
#define GHC_FILESYSTEM_FWD
|
||||
#include <ghc/filesystem.hpp>
|
||||
#endif // GHC_FILESYSTEM_FWD_H
|
@ -0,0 +1,43 @@
|
||||
//---------------------------------------------------------------------------------------
|
||||
//
|
||||
// ghc::filesystem - A C++17-like filesystem implementation for C++11/C++14
|
||||
//
|
||||
//---------------------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2018, Steffen Schümann <s.schuemann@pobox.com>
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice, this
|
||||
// list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software without
|
||||
// specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//---------------------------------------------------------------------------------------
|
||||
// fs_impl.hpp - The implementation header for the header/implementation seperated usage of
|
||||
// ghc::filesystem.
|
||||
// This file can be used to hide the implementation of ghc::filesystem into a single cpp.
|
||||
// The cpp has to include this before including fs_fwd.hpp directly or via a different
|
||||
// header to work.
|
||||
//---------------------------------------------------------------------------------------
|
||||
#define GHC_FILESYSTEM_IMPLEMENTATION
|
||||
#include <ghc/filesystem.hpp>
|
@ -0,0 +1,64 @@
|
||||
//---------------------------------------------------------------------------------------
|
||||
//
|
||||
// ghc::filesystem - A C++17-like filesystem implementation for C++11/C++14
|
||||
//
|
||||
//---------------------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2018, Steffen Schümann <s.schuemann@pobox.com>
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice, this
|
||||
// list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software without
|
||||
// specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//---------------------------------------------------------------------------------------
|
||||
// fs_std.hpp - The dynamic switching header that includes std::filesystem if detected
|
||||
// or ghc::filesystem if not, and makes the resulting API available in the
|
||||
// namespace fs.
|
||||
//---------------------------------------------------------------------------------------
|
||||
#ifndef GHC_FILESYSTEM_STD_H
|
||||
#if defined(__cplusplus) && __cplusplus >= 201703L && defined(__has_include)
|
||||
#if __has_include(<filesystem>)
|
||||
#define GHC_USE_STD_FS
|
||||
#include <filesystem>
|
||||
namespace fs {
|
||||
using namespace std::filesystem;
|
||||
using ifstream = std::ifstream;
|
||||
using ofstream = std::ofstream;
|
||||
using fstream = std::fstream;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#ifndef GHC_USE_STD_FS
|
||||
#define GHC_WIN_WSTRING_STRING_TYPE
|
||||
#include <ghc/filesystem.hpp>
|
||||
namespace fs {
|
||||
using namespace ghc::filesystem;
|
||||
using ifstream = ghc::filesystem::ifstream;
|
||||
using ofstream = ghc::filesystem::ofstream;
|
||||
using fstream = ghc::filesystem::fstream;
|
||||
}
|
||||
#endif
|
||||
#endif // GHC_FILESYSTEM_STD_H
|
||||
|
@ -0,0 +1,68 @@
|
||||
//---------------------------------------------------------------------------------------
|
||||
//
|
||||
// ghc::filesystem - A C++17-like filesystem implementation for C++11/C++14
|
||||
//
|
||||
//---------------------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2018, Steffen Schümann <s.schuemann@pobox.com>
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice, this
|
||||
// list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software without
|
||||
// specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//---------------------------------------------------------------------------------------
|
||||
// fs_std_fwd.hpp - The forwarding header for the header/implementation seperated usage of
|
||||
// ghc::filesystem that uses std::filesystem if it detects it.
|
||||
// This file can be include at any place, where fs::filesystem api is needed while
|
||||
// not bleeding implementation details (e.g. system includes) into the global namespace,
|
||||
// as long as one cpp includes fs_std_impl.hpp to deliver the matching implementations.
|
||||
//---------------------------------------------------------------------------------------
|
||||
#ifndef GHC_FILESYSTEM_STD_FWD_H
|
||||
#define GHC_FILESYSTEM_STD_FWD_H
|
||||
#if defined(__cplusplus) && __cplusplus >= 201703L && defined(__has_include)
|
||||
#if __has_include(<filesystem>)
|
||||
#define GHC_USE_STD_FS
|
||||
#include <filesystem>
|
||||
namespace fs {
|
||||
using namespace std::filesystem;
|
||||
using ifstream = std::ifstream;
|
||||
using ofstream = std::ofstream;
|
||||
using fstream = std::fstream;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#ifndef GHC_USE_STD_FS
|
||||
#define GHC_WIN_WSTRING_STRING_TYPE
|
||||
#define GHC_FILESYSTEM_FWD
|
||||
#include <ghc/filesystem.hpp>
|
||||
namespace fs {
|
||||
using namespace ghc::filesystem;
|
||||
using ifstream = ghc::filesystem::ifstream;
|
||||
using ofstream = ghc::filesystem::ofstream;
|
||||
using fstream = ghc::filesystem::fstream;
|
||||
}
|
||||
#endif
|
||||
#endif // GHC_FILESYSTEM_STD_FWD_H
|
||||
|
@ -0,0 +1,51 @@
|
||||
//---------------------------------------------------------------------------------------
|
||||
//
|
||||
// ghc::filesystem - A C++17-like filesystem implementation for C++11/C++14
|
||||
//
|
||||
//---------------------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2018, Steffen Schümann <s.schuemann@pobox.com>
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice, this
|
||||
// list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software without
|
||||
// specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//---------------------------------------------------------------------------------------
|
||||
// fs_std_impl.hpp - The implementation header for the header/implementation seperated usage of
|
||||
// ghc::filesystem that does nothing if std::filesystem is detected.
|
||||
// This file can be used to hide the implementation of ghc::filesystem into a single cpp.
|
||||
// The cpp has to include this before including fs_std_fwd.hpp directly or via a different
|
||||
// header to work.
|
||||
//---------------------------------------------------------------------------------------
|
||||
#if defined(__cplusplus) && __cplusplus >= 201703L && defined(__has_include)
|
||||
#if __has_include(<filesystem>)
|
||||
#define GHC_USE_STD_FS
|
||||
#endif
|
||||
#endif
|
||||
#ifndef GHC_USE_STD_FS
|
||||
#define GHC_WIN_WSTRING_STRING_TYPE
|
||||
#define GHC_FILESYSTEM_IMPLEMENTATION
|
||||
#include <ghc/filesystem.hpp>
|
||||
#endif
|
@ -0,0 +1,54 @@
|
||||
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/")
|
||||
set(PARSE_CATCH_TESTS_ADD_TO_CONFIGURE_DEPENDS ON)
|
||||
include(ParseAndAddCatchTests)
|
||||
|
||||
if(GHC_COVERAGE)
|
||||
message("Generating test runner for coverage run...")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMCMAKE_EXE_LINKER_FLAGS} --coverage")
|
||||
add_executable(filesystem_test filesystem_test.cpp catch.hpp)
|
||||
if(MINGW)
|
||||
target_compile_options(filesystem_test PUBLIC --coverage "-Wa,-mbig-obj")
|
||||
else()
|
||||
target_compile_options(filesystem_test PUBLIC --coverage)
|
||||
endif()
|
||||
target_link_libraries(filesystem_test PUBLIC ghc_filesystem --coverage)
|
||||
else()
|
||||
message("Generating test runner for normal test...")
|
||||
add_executable(filesystem_test filesystem_test.cpp catch.hpp)
|
||||
target_link_libraries(filesystem_test ghc_filesystem)
|
||||
target_compile_options(filesystem_test PRIVATE
|
||||
$<$<CXX_COMPILER_ID:Clang>:-Wall -Wextra -Wshadow -Wconversion -Wsign-conversion -Wpedantic -Werror>
|
||||
$<$<CXX_COMPILER_ID:GNU>:-Wall -Wextra -Wshadow -Wconversion -Wsign-conversion -Wpedantic -Werror>
|
||||
$<$<CXX_COMPILER_ID:MSVC>:/WX>)
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES MSVC)
|
||||
target_compile_definitions(filesystem_test PRIVATE _CRT_SECURE_NO_WARNINGS)
|
||||
endif()
|
||||
ParseAndAddCatchTests(filesystem_test)
|
||||
AddExecutableWithStdFS(std_filesystem_test filesystem_test.cpp catch.hpp)
|
||||
if(WIN32)
|
||||
add_executable(filesystem_test_wchar filesystem_test.cpp catch.hpp)
|
||||
target_link_libraries(filesystem_test_wchar ghc_filesystem)
|
||||
target_compile_options(filesystem_test_wchar PRIVATE
|
||||
$<$<CXX_COMPILER_ID:Clang>:-Wall -Wextra -Werror>
|
||||
$<$<CXX_COMPILER_ID:GNU>:-Wall -Werror>
|
||||
$<$<CXX_COMPILER_ID:MSVC>:/WX>)
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES MSVC)
|
||||
target_compile_definitions(filesystem_test_wchar PRIVATE _CRT_SECURE_NO_WARNINGS GHC_WIN_WSTRING_STRING_TYPE)
|
||||
else()
|
||||
target_compile_definitions(filesystem_test_wchar PRIVATE GHC_WIN_WSTRING_STRING_TYPE)
|
||||
endif()
|
||||
ParseAndAddCatchTests(filesystem_test_wchar)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_executable(multifile_test multi1.cpp multi2.cpp catch.hpp)
|
||||
target_link_libraries(multifile_test ghc_filesystem)
|
||||
add_test(multifile_test multifile_test)
|
||||
|
||||
add_executable(fwd_impl_test fwd_test.cpp impl_test.cpp)
|
||||
target_link_libraries(fwd_impl_test ghc_filesystem)
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES MSVC)
|
||||
target_compile_definitions(fwd_impl_test PRIVATE _CRT_SECURE_NO_WARNINGS)
|
||||
endif()
|
||||
add_test(fwd_impl_test fwd_impl_test)
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,225 @@
|
||||
#==================================================================================================#
|
||||
# supported macros #
|
||||
# - TEST_CASE, #
|
||||
# - SCENARIO, #
|
||||
# - TEST_CASE_METHOD, #
|
||||
# - CATCH_TEST_CASE, #
|
||||
# - CATCH_SCENARIO, #
|
||||
# - CATCH_TEST_CASE_METHOD. #
|
||||
# #
|
||||
# Usage #
|
||||
# 1. make sure this module is in the path or add this otherwise: #
|
||||
# set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake.modules/") #
|
||||
# 2. make sure that you've enabled testing option for the project by the call: #
|
||||
# enable_testing() #
|
||||
# 3. add the lines to the script for testing target (sample CMakeLists.txt): #
|
||||
# project(testing_target) #
|
||||
# set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake.modules/") #
|
||||
# enable_testing() #
|
||||
# #
|
||||
# find_path(CATCH_INCLUDE_DIR "catch.hpp") #
|
||||
# include_directories(${INCLUDE_DIRECTORIES} ${CATCH_INCLUDE_DIR}) #
|
||||
# #
|
||||
# file(GLOB SOURCE_FILES "*.cpp") #
|
||||
# add_executable(${PROJECT_NAME} ${SOURCE_FILES}) #
|
||||
# #
|
||||
# include(ParseAndAddCatchTests) #
|
||||
# ParseAndAddCatchTests(${PROJECT_NAME}) #
|
||||
# #
|
||||
# The following variables affect the behavior of the script: #
|
||||
# #
|
||||
# PARSE_CATCH_TESTS_VERBOSE (Default OFF) #
|
||||
# -- enables debug messages #
|
||||
# PARSE_CATCH_TESTS_NO_HIDDEN_TESTS (Default OFF) #
|
||||
# -- excludes tests marked with [!hide], [.] or [.foo] tags #
|
||||
# PARSE_CATCH_TESTS_ADD_FIXTURE_IN_TEST_NAME (Default ON) #
|
||||
# -- adds fixture class name to the test name #
|
||||
# PARSE_CATCH_TESTS_ADD_TARGET_IN_TEST_NAME (Default ON) #
|
||||
# -- adds cmake target name to the test name #
|
||||
# PARSE_CATCH_TESTS_ADD_TO_CONFIGURE_DEPENDS (Default OFF) #
|
||||
# -- causes CMake to rerun when file with tests changes so that new tests will be discovered #
|
||||
# #
|
||||
# One can also set (locally) the optional variable OptionalCatchTestLauncher to precise the way #
|
||||
# a test should be run. For instance to use test MPI, one can write #
|
||||
# set(OptionalCatchTestLauncher ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} ${NUMPROC}) #
|
||||
# just before calling this ParseAndAddCatchTests function #
|
||||
# #
|
||||
# The AdditionalCatchParameters optional variable can be used to pass extra argument to the test #
|
||||
# command. For example, to include successful tests in the output, one can write #
|
||||
# set(AdditionalCatchParameters --success) #
|
||||
# #
|
||||
# After the script, the ParseAndAddCatchTests_TESTS property for the target, and for each source #
|
||||
# file in the target is set, and contains the list of the tests extracted from that target, or #
|
||||
# from that file. This is useful, for example to add further labels or properties to the tests. #
|
||||
# #
|
||||
#==================================================================================================#
|
||||
|
||||
if (CMAKE_MINIMUM_REQUIRED_VERSION VERSION_LESS 2.8.8)
|
||||
message(FATAL_ERROR "ParseAndAddCatchTests requires CMake 2.8.8 or newer")
|
||||
endif()
|
||||
|
||||
option(PARSE_CATCH_TESTS_VERBOSE "Print Catch to CTest parser debug messages" OFF)
|
||||
option(PARSE_CATCH_TESTS_NO_HIDDEN_TESTS "Exclude tests with [!hide], [.] or [.foo] tags" OFF)
|
||||
option(PARSE_CATCH_TESTS_ADD_FIXTURE_IN_TEST_NAME "Add fixture class name to the test name" ON)
|
||||
option(PARSE_CATCH_TESTS_ADD_TARGET_IN_TEST_NAME "Add target name to the test name" ON)
|
||||
option(PARSE_CATCH_TESTS_ADD_TO_CONFIGURE_DEPENDS "Add test file to CMAKE_CONFIGURE_DEPENDS property" OFF)
|
||||
|
||||
function(ParseAndAddCatchTests_PrintDebugMessage)
|
||||
if(PARSE_CATCH_TESTS_VERBOSE)
|
||||
message(STATUS "ParseAndAddCatchTests: ${ARGV}")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# This removes the contents between
|
||||
# - block comments (i.e. /* ... */)
|
||||
# - full line comments (i.e. // ... )
|
||||
# contents have been read into '${CppCode}'.
|
||||
# !keep partial line comments
|
||||
function(ParseAndAddCatchTests_RemoveComments CppCode)
|
||||
string(ASCII 2 CMakeBeginBlockComment)
|
||||
string(ASCII 3 CMakeEndBlockComment)
|
||||
string(REGEX REPLACE "/\\*" "${CMakeBeginBlockComment}" ${CppCode} "${${CppCode}}")
|
||||
string(REGEX REPLACE "\\*/" "${CMakeEndBlockComment}" ${CppCode} "${${CppCode}}")
|
||||
string(REGEX REPLACE "${CMakeBeginBlockComment}[^${CMakeEndBlockComment}]*${CMakeEndBlockComment}" "" ${CppCode} "${${CppCode}}")
|
||||
string(REGEX REPLACE "\n[ \t]*//+[^\n]+" "\n" ${CppCode} "${${CppCode}}")
|
||||
|
||||
set(${CppCode} "${${CppCode}}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Worker function
|
||||
function(ParseAndAddCatchTests_ParseFile SourceFile TestTarget)
|
||||
# If SourceFile is an object library, do not scan it (as it is not a file). Exit without giving a warning about a missing file.
|
||||
if(SourceFile MATCHES "\\\$<TARGET_OBJECTS:.+>")
|
||||
ParseAndAddCatchTests_PrintDebugMessage("Detected OBJECT library: ${SourceFile} this will not be scanned for tests.")
|
||||
return()
|
||||
endif()
|
||||
# According to CMake docs EXISTS behavior is well-defined only for full paths.
|
||||
get_filename_component(SourceFile ${SourceFile} ABSOLUTE)
|
||||
if(NOT EXISTS ${SourceFile})
|
||||
message(WARNING "Cannot find source file: ${SourceFile}")
|
||||
return()
|
||||
endif()
|
||||
ParseAndAddCatchTests_PrintDebugMessage("parsing ${SourceFile}")
|
||||
file(STRINGS ${SourceFile} Contents NEWLINE_CONSUME)
|
||||
|
||||
# Remove block and fullline comments
|
||||
ParseAndAddCatchTests_RemoveComments(Contents)
|
||||
|
||||
# Find definition of test names
|
||||
string(REGEX MATCHALL "[ \t]*(CATCH_)?(TEST_CASE_METHOD|SCENARIO|TEST_CASE)[ \t]*\\([^\)]+\\)+[ \t\n]*{+[ \t]*(//[^\n]*[Tt][Ii][Mm][Ee][Oo][Uu][Tt][ \t]*[0-9]+)*" Tests "${Contents}")
|
||||
|
||||
if(PARSE_CATCH_TESTS_ADD_TO_CONFIGURE_DEPENDS AND Tests)
|
||||
ParseAndAddCatchTests_PrintDebugMessage("Adding ${SourceFile} to CMAKE_CONFIGURE_DEPENDS property")
|
||||
set_property(
|
||||
DIRECTORY
|
||||
APPEND
|
||||
PROPERTY CMAKE_CONFIGURE_DEPENDS ${SourceFile}
|
||||
)
|
||||
endif()
|
||||
|
||||
foreach(TestName ${Tests})
|
||||
# Strip newlines
|
||||
string(REGEX REPLACE "\\\\\n|\n" "" TestName "${TestName}")
|
||||
|
||||
# Get test type and fixture if applicable
|
||||
string(REGEX MATCH "(CATCH_)?(TEST_CASE_METHOD|SCENARIO|TEST_CASE)[ \t]*\\([^,^\"]*" TestTypeAndFixture "${TestName}")
|
||||
string(REGEX MATCH "(CATCH_)?(TEST_CASE_METHOD|SCENARIO|TEST_CASE)" TestType "${TestTypeAndFixture}")
|
||||
string(REGEX REPLACE "${TestType}\\([ \t]*" "" TestFixture "${TestTypeAndFixture}")
|
||||
|
||||
# Get string parts of test definition
|
||||
string(REGEX MATCHALL "\"+([^\\^\"]|\\\\\")+\"+" TestStrings "${TestName}")
|
||||
|
||||
# Strip wrapping quotation marks
|
||||
string(REGEX REPLACE "^\"(.*)\"$" "\\1" TestStrings "${TestStrings}")
|
||||
string(REPLACE "\";\"" ";" TestStrings "${TestStrings}")
|
||||
|
||||
# Validate that a test name and tags have been provided
|
||||
list(LENGTH TestStrings TestStringsLength)
|
||||
if(TestStringsLength GREATER 2 OR TestStringsLength LESS 1)
|
||||
message(FATAL_ERROR "You must provide a valid test name and tags for all tests in ${SourceFile}")
|
||||
endif()
|
||||
|
||||
# Assign name and tags
|
||||
list(GET TestStrings 0 Name)
|
||||
if("${TestType}" STREQUAL "SCENARIO")
|
||||
set(Name "Scenario: ${Name}")
|
||||
endif()
|
||||
if(PARSE_CATCH_TESTS_ADD_FIXTURE_IN_TEST_NAME AND TestFixture)
|
||||
set(CTestName "${TestFixture}:${Name}")
|
||||
else()
|
||||
set(CTestName "${Name}")
|
||||
endif()
|
||||
if(PARSE_CATCH_TESTS_ADD_TARGET_IN_TEST_NAME)
|
||||
set(CTestName "${TestTarget}:${CTestName}")
|
||||
endif()
|
||||
# add target to labels to enable running all tests added from this target
|
||||
set(Labels ${TestTarget})
|
||||
if(TestStringsLength EQUAL 2)
|
||||
list(GET TestStrings 1 Tags)
|
||||
string(TOLOWER "${Tags}" Tags)
|
||||
# remove target from labels if the test is hidden
|
||||
if("${Tags}" MATCHES ".*\\[!?(hide|\\.)\\].*")
|
||||
list(REMOVE_ITEM Labels ${TestTarget})
|
||||
endif()
|
||||
string(REPLACE "]" ";" Tags "${Tags}")
|
||||
string(REPLACE "[" "" Tags "${Tags}")
|
||||
else()
|
||||
# unset tags variable from previous loop
|
||||
unset(Tags)
|
||||
endif()
|
||||
|
||||
list(APPEND Labels ${Tags})
|
||||
|
||||
set(HiddenTagFound OFF)
|
||||
foreach(label ${Labels})
|
||||
string(REGEX MATCH "^!hide|^\\." result ${label})
|
||||
if(result)
|
||||
set(HiddenTagFound ON)
|
||||
break()
|
||||
endif(result)
|
||||
endforeach(label)
|
||||
if(PARSE_CATCH_TESTS_NO_HIDDEN_TESTS AND ${HiddenTagFound} AND ${CMAKE_VERSION} VERSION_LESS "3.9")
|
||||
ParseAndAddCatchTests_PrintDebugMessage("Skipping test \"${CTestName}\" as it has [!hide], [.] or [.foo] label")
|
||||
else()
|
||||
ParseAndAddCatchTests_PrintDebugMessage("Adding test \"${CTestName}\"")
|
||||
if(Labels)
|
||||
ParseAndAddCatchTests_PrintDebugMessage("Setting labels to ${Labels}")
|
||||
endif()
|
||||
|
||||
# Escape commas in the test spec
|
||||
string(REPLACE "," "\\," Name ${Name})
|
||||
|
||||
# Add the test and set its properties
|
||||
add_test(NAME "\"${CTestName}\"" COMMAND ${OptionalCatchTestLauncher} $<TARGET_FILE:${TestTarget}> ${Name} ${AdditionalCatchParameters})
|
||||
# Old CMake versions do not document VERSION_GREATER_EQUAL, so we use VERSION_GREATER with 3.8 instead
|
||||
if(PARSE_CATCH_TESTS_NO_HIDDEN_TESTS AND ${HiddenTagFound} AND ${CMAKE_VERSION} VERSION_GREATER "3.8")
|
||||
ParseAndAddCatchTests_PrintDebugMessage("Setting DISABLED test property")
|
||||
set_tests_properties("\"${CTestName}\"" PROPERTIES DISABLED ON)
|
||||
else()
|
||||
set_tests_properties("\"${CTestName}\"" PROPERTIES FAIL_REGULAR_EXPRESSION "No tests ran"
|
||||
LABELS "${Labels}")
|
||||
endif()
|
||||
set_property(
|
||||
TARGET ${TestTarget}
|
||||
APPEND
|
||||
PROPERTY ParseAndAddCatchTests_TESTS "\"${CTestName}\"")
|
||||
set_property(
|
||||
SOURCE ${SourceFile}
|
||||
APPEND
|
||||
PROPERTY ParseAndAddCatchTests_TESTS "\"${CTestName}\"")
|
||||
endif()
|
||||
|
||||
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
# entry point
|
||||
function(ParseAndAddCatchTests TestTarget)
|
||||
ParseAndAddCatchTests_PrintDebugMessage("Started parsing ${TestTarget}")
|
||||
get_target_property(SourceFiles ${TestTarget} SOURCES)
|
||||
ParseAndAddCatchTests_PrintDebugMessage("Found the following sources: ${SourceFiles}")
|
||||
foreach(SourceFile ${SourceFiles})
|
||||
ParseAndAddCatchTests_ParseFile(${SourceFile} ${TestTarget})
|
||||
endforeach()
|
||||
ParseAndAddCatchTests_PrintDebugMessage("Finished parsing ${TestTarget}")
|
||||
endfunction()
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,7 @@
|
||||
// This test file is part of the fwd_test.cpp/impl_test.cpp pair
|
||||
// and used to test the new optional two-part usage of ghc::filesystem
|
||||
// where exactly one cpp includes fs_impl.hpp and all others use
|
||||
// fs_fwd.hpp (to test this with maximum functionality, the unit tests
|
||||
// are included here, signaling they should only include the fs_fwd.hpp)
|
||||
#define GHC_FILESYSTEM_FWD_TEST
|
||||
#include "filesystem_test.cpp"
|
@ -0,0 +1,9 @@
|
||||
// This test file is part of the fwd_test.cpp/impl_test.cpp pair
|
||||
// and used to test the new optional two-part usage of ghc::filesystem
|
||||
// where exactly one cpp includes fs_impl.hpp and all others use
|
||||
// fs_fwd.hpp (to test this with maximum functionality, the unit tests
|
||||
// are included here, signaling they should only include the fs_fwd.hpp)
|
||||
#define NOMINMAX
|
||||
#include <ghc/fs_impl.hpp>
|
||||
#define CATCH_CONFIG_MAIN
|
||||
#include "catch.hpp"
|
@ -0,0 +1,50 @@
|
||||
//---------------------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2018, Steffen Schümann <s.schuemann@pobox.com>
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice, this
|
||||
// list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software without
|
||||
// specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//---------------------------------------------------------------------------------------
|
||||
#define CATCH_CONFIG_MAIN
|
||||
#include "catch.hpp"
|
||||
|
||||
#include <ghc/filesystem.hpp>
|
||||
namespace fs = ghc::filesystem;
|
||||
|
||||
// This test and the one in multi2.cpp doesn't actualy test relevant functionality,
|
||||
// it is just used to check that it is possible to include filesystem.h in multiple
|
||||
// source files.
|
||||
TEST_CASE("Multifile-test 1", "[multi]")
|
||||
{
|
||||
CHECK("/usr/local/bin" == fs::path("/usr/local/bin").generic_string());
|
||||
std::string str = "/usr/local/bin";
|
||||
std::u16string u16str = u"/usr/local/bin";
|
||||
std::u32string u32str = U"/usr/local/bin";
|
||||
CHECK(str == fs::path(str.begin(), str.end()));
|
||||
CHECK(str == fs::path(u16str.begin(), u16str.end()));
|
||||
CHECK(str == fs::path(u32str.begin(), u32str.end()));
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
//---------------------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2018, Steffen Schümann <s.schuemann@pobox.com>
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice, this
|
||||
// list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software without
|
||||
// specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//---------------------------------------------------------------------------------------
|
||||
#include "catch.hpp"
|
||||
#include <ghc/filesystem.hpp>
|
||||
namespace fs = ghc::filesystem;
|
||||
|
||||
// This test and the one in multi1.cpp doesn't actualy test relevant functionality,
|
||||
// it is just used to check that it is possible to include filesystem.h in multiple
|
||||
// source files.
|
||||
TEST_CASE("Multifile-test 2", "[multi]")
|
||||
{
|
||||
CHECK("/usr/local/bin" == fs::path("/usr/local/bin").generic_string());
|
||||
std::string str = "/usr/local/bin";
|
||||
std::u16string u16str = u"/usr/local/bin";
|
||||
std::u32string u32str = U"/usr/local/bin";
|
||||
CHECK(str == fs::path(str.begin(), str.end()));
|
||||
CHECK(str == fs::path(u16str.begin(), u16str.end()));
|
||||
CHECK(str == fs::path(u32str.begin(), u32str.end()));
|
||||
}
|
Loading…
Reference in New Issue