Added UTF-8 locale test to u8arguments, some cleanup.

This commit is contained in:
Steffen Schümann 2018-10-22 20:01:52 +02:00
parent 22da1c7698
commit 0cb8a42f83
5 changed files with 59 additions and 29 deletions

View File

@ -1,7 +1,9 @@
cmake_minimum_required(VERSION 3.2)
cmake_minimum_required(VERSION 3.10)
project(ghcfilesystem)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
add_compile_options("$<$<C_COMPILER_ID:MSVC>:/utf-8>")
add_compile_options("$<$<CXX_COMPILER_ID:MSVC>:/utf-8>")

View File

@ -152,7 +152,7 @@ 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
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
@ -170,6 +170,10 @@ 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
// ...

View File

@ -1,17 +1,21 @@
add_executable(fs_dir dir.cpp ../filesystem.h)
target_compile_definitions(fs_dir PRIVATE _CRT_SECURE_NO_WARNINGS)
if(CMAKE_CXX_COMPILER_ID MATCHES MSVC)
target_compile_definitions(fs_dir PRIVATE _CRT_SECURE_NO_WARNINGS)
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))
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)

View File

@ -31,6 +31,10 @@ 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;

View File

@ -62,21 +62,22 @@
#error "Operating system currently not supported!"
#endif
#ifndef GHC_OS_WINDOWS
#ifdef GHC_OS_WINDOWS
#include <sys/stat.h>
#include <sys/types.h>
#include <wchar.h>
#include <windows.h>
#include <winioctl.h>
#else
#include <dirent.h>
#include <fcntl.h>
#include <langinfo.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/statvfs.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#else
#include <sys/stat.h>
#include <sys/types.h>
#include <wchar.h>
#include <windows.h>
#include <winioctl.h>
#endif
#ifdef GHC_OS_MACOS
#include <Availability.h>
@ -917,11 +918,17 @@ public:
_refargv = _argv;
}
bool valid() const
{
return _isvalid;
}
private:
int _argc;
char** _argv;
int& _refargc;
char**& _refargv;
bool _isvalid;
#ifdef GHC_OS_WINDOWS
std::vector<std::string> _args;
std::vector<char*> _argp;
@ -1203,25 +1210,6 @@ inline void postprocess_path_with_format(path::string_type& p, path::format fmt)
} // 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>
inline path::path(const Source& source, format fmt)
@ -1667,6 +1655,34 @@ inline file_status status_ex(const path& p, std::error_code& ec, file_status* sl
} // namespace detail
inline u8arguments::u8arguments(int& argc, char**& argv)
: _argc(argc)
, _argv(argv)
, _refargc(argc)
, _refargv(argv)
, _isvalid(false)
{
#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);
_isvalid = true;
#else
std::setlocale(LC_ALL, "");
if(!detail::compare_no_case(::nl_langinfo(CODESET), "UTF-8")) {
_isvalid = true;
}
#endif
}
//-----------------------------------------------------------------------------
// 30.10.8.4.1 constructors and destructor