mirror of
https://git.mirrors.martin98.com/https://github.com/gulrak/filesystem
synced 2025-06-04 11:13:58 +08:00
Restructured CMakeLists, added fs::u8arguments helper, added first example
This commit is contained in:
parent
3e6a1e1771
commit
1da3ae7864
@ -6,29 +6,5 @@ set(CMAKE_CXX_STANDARD 11)
|
|||||||
add_compile_options("$<$<C_COMPILER_ID:MSVC>:/utf-8>")
|
add_compile_options("$<$<C_COMPILER_ID:MSVC>:/utf-8>")
|
||||||
add_compile_options("$<$<CXX_COMPILER_ID:MSVC>:/utf-8>")
|
add_compile_options("$<$<CXX_COMPILER_ID:MSVC>:/utf-8>")
|
||||||
|
|
||||||
add_executable(filesystem_test test/filesystem_test.cpp filesystem.h test/catch.hpp)
|
add_subdirectory(test)
|
||||||
if(CMAKE_GENERATOR STREQUAL Xcode)
|
add_subdirectory(examples)
|
||||||
add_executable(filesystem_test_cov test/filesystem_test.cpp filesystem.h test/catch.hpp)
|
|
||||||
target_compile_options(filesystem_test_cov PRIVATE "$<$<CONFIG:DEBUG>:--coverage>")
|
|
||||||
target_link_libraries(filesystem_test_cov PRIVATE --coverage)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
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))
|
|
||||||
include_directories(/usr/local/opt/llvm/include)
|
|
||||||
link_directories(/usr/local/opt/llvm/lib)
|
|
||||||
add_executable(std_filesystem_test test/filesystem_test.cpp filesystem.h test/catch.hpp)
|
|
||||||
set_property(TARGET std_filesystem_test PROPERTY CXX_STANDARD 17)
|
|
||||||
target_compile_definitions(std_filesystem_test PRIVATE USE_STD_FS)
|
|
||||||
target_link_libraries(std_filesystem_test -lc++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(std_filesystem_test test/filesystem_test.cpp filesystem.h test/catch.hpp)
|
|
||||||
set_property(TARGET std_filesystem_test PROPERTY CXX_STANDARD 17)
|
|
||||||
target_compile_definitions(std_filesystem_test PRIVATE USE_STD_FS)
|
|
||||||
target_link_libraries(std_filesystem_test -lstdc++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(std_filesystem_test test/filesystem_test.cpp filesystem.h test/catch.hpp)
|
|
||||||
set_property(TARGET std_filesystem_test PROPERTY CXX_STANDARD 17)
|
|
||||||
target_compile_definitions(std_filesystem_test PRIVATE USE_STD_FS)
|
|
||||||
endif()
|
|
||||||
|
48
README.md
48
README.md
@ -132,11 +132,50 @@ It's the version as decimal number `(major * 10000 + minor * 100 + patch)`.
|
|||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
There is no documentation in this release, as any `std::filesystem` 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
|
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
|
head over to https://en.cppreference.com/w/cpp/filesystem for a description of
|
||||||
the components of this library.
|
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 acts neutral 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);
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
|
||||||
## Differences
|
## Differences
|
||||||
|
|
||||||
@ -292,6 +331,13 @@ to the expected behavior.
|
|||||||
* Updated catch2 to v2.4.0.
|
* Updated catch2 to v2.4.0.
|
||||||
* Refactored `fs.op.permissions` test to work with all tested `std::filesystem`
|
* Refactored `fs.op.permissions` test to work with all tested `std::filesystem`
|
||||||
implementations (gcc, clang, msvc++).
|
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.
|
||||||
|
|
||||||
### [v1.0.1](https://github.com/gulrak/filesystem/tree/v1.0.1)
|
### [v1.0.1](https://github.com/gulrak/filesystem/tree/v1.0.1)
|
||||||
|
|
||||||
|
17
examples/CMakeLists.txt
Normal file
17
examples/CMakeLists.txt
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
|
||||||
|
add_executable(fs_dir dir.cpp ../filesystem.h)
|
||||||
|
|
||||||
|
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))
|
||||||
|
add_executable(std_fs_dir dir.cpp)
|
||||||
|
set_property(TARGET std_fs_dir PROPERTY CXX_STANDARD 17)
|
||||||
|
target_link_libraries(std_fs_dir -lc++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(std_fs_dir dir.cpp)
|
||||||
|
set_property(TARGET std_fs_dir PROPERTY CXX_STANDARD 17)
|
||||||
|
target_link_libraries(std_fs_dir -lstdc++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(std_fs_dir dir.cpp)
|
||||||
|
set_property(TARGET std_fs_dir PROPERTY CXX_STANDARD 17)
|
||||||
|
endif()
|
53
examples/dir.cpp
Normal file
53
examples/dir.cpp
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
|
#if defined(__cplusplus) && __cplusplus >= 201703L && defined(__has_include) && __has_include(<filesystem>)
|
||||||
|
#include <filesystem>
|
||||||
|
namespace fs = std::filesystem;
|
||||||
|
#else
|
||||||
|
#include "../filesystem.h"
|
||||||
|
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
|
||||||
|
return std::chrono::system_clock::to_time_t(std::chrono::system_clock::now() + (tp - TP::clock::now()));
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string perm_to_str(fs::perms prms)
|
||||||
|
{
|
||||||
|
std::string result;
|
||||||
|
result.reserve(6);
|
||||||
|
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);
|
||||||
|
#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;
|
||||||
|
}
|
40
filesystem.h
40
filesystem.h
@ -901,6 +901,26 @@ typedef basic_ofstream<wchar_t> wofstream;
|
|||||||
typedef basic_fstream<char> fstream;
|
typedef basic_fstream<char> fstream;
|
||||||
typedef basic_fstream<wchar_t> wfstream;
|
typedef basic_fstream<wchar_t> wfstream;
|
||||||
|
|
||||||
|
class u8arguments {
|
||||||
|
public:
|
||||||
|
u8arguments(int& argc, char**& argv);
|
||||||
|
~u8arguments()
|
||||||
|
{
|
||||||
|
_refargc = _argc;
|
||||||
|
_refargv = _argv;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
int _argc;
|
||||||
|
char** _argv;
|
||||||
|
int& _refargc;
|
||||||
|
char**& _refargv;
|
||||||
|
#ifdef GHC_OS_WINDOWS
|
||||||
|
std::vector<std::string> _args;
|
||||||
|
std::vector<char*> _argp;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------------------
|
||||||
// Implementation
|
// Implementation
|
||||||
//-------------------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------------------
|
||||||
@ -1181,6 +1201,26 @@ inline void postprocess_path_with_format(path::string_type& p, path::format fmt)
|
|||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
|
inline u8arguments::u8arguments(int& argc, char**& argv)
|
||||||
|
: _argc(argc)
|
||||||
|
, _argv(argv)
|
||||||
|
, _refargc(argc)
|
||||||
|
, _refargv(argv)
|
||||||
|
{
|
||||||
|
#ifdef GHC_OS_WINDOWS
|
||||||
|
LPWSTR* p;
|
||||||
|
p = ::CommandLineToArgvW(::GetCommandLineW(), &argc);
|
||||||
|
_args.reserve(argc);
|
||||||
|
_argp.reserve(argc);
|
||||||
|
for (size_t i = 0; i < argc; ++i) {
|
||||||
|
_args.push_back(detail::toUtf8(std::wstring(p[i])));
|
||||||
|
_argp.push_back((char*)_args[i].data());
|
||||||
|
}
|
||||||
|
argv = _argp.data();
|
||||||
|
::LocalFree(p);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
template <class Source, typename>
|
template <class Source, typename>
|
||||||
inline path::path(const Source& source, format fmt)
|
inline path::path(const Source& source, format fmt)
|
||||||
: _path(source)
|
: _path(source)
|
||||||
|
27
test/CMakeLists.txt
Normal file
27
test/CMakeLists.txt
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
|
||||||
|
add_executable(filesystem_test filesystem_test.cpp ../filesystem.h catch.hpp)
|
||||||
|
if(CMAKE_GENERATOR STREQUAL Xcode)
|
||||||
|
add_executable(filesystem_test_cov filesystem_test.cpp ../filesystem.h catch.hpp)
|
||||||
|
target_compile_options(filesystem_test_cov PRIVATE "$<$<CONFIG:DEBUG>:--coverage>")
|
||||||
|
target_link_libraries(filesystem_test_cov PRIVATE --coverage)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
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))
|
||||||
|
include_directories(/usr/local/opt/llvm/include)
|
||||||
|
link_directories(/usr/local/opt/llvm/lib)
|
||||||
|
add_executable(std_filesystem_test filesystem_test.cpp ../filesystem.h catch.hpp)
|
||||||
|
set_property(TARGET std_filesystem_test PROPERTY CXX_STANDARD 17)
|
||||||
|
target_compile_definitions(std_filesystem_test PRIVATE USE_STD_FS)
|
||||||
|
target_link_libraries(std_filesystem_test -lc++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(std_filesystem_test filesystem_test.cpp ../filesystem.h catch.hpp)
|
||||||
|
set_property(TARGET std_filesystem_test PROPERTY CXX_STANDARD 17)
|
||||||
|
target_compile_definitions(std_filesystem_test PRIVATE USE_STD_FS)
|
||||||
|
target_link_libraries(std_filesystem_test -lstdc++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(std_filesystem_test filesystem_test.cpp ../filesystem.h catch.hpp)
|
||||||
|
set_property(TARGET std_filesystem_test PROPERTY CXX_STANDARD 17)
|
||||||
|
target_compile_definitions(std_filesystem_test PRIVATE USE_STD_FS)
|
||||||
|
endif()
|
Loading…
x
Reference in New Issue
Block a user