diff options
Diffstat (limited to 'externals/fmt/src/os.cc')
-rw-r--r-- | externals/fmt/src/os.cc | 161 |
1 files changed, 99 insertions, 62 deletions
diff --git a/externals/fmt/src/os.cc b/externals/fmt/src/os.cc index f388ead0..bca410e9 100644 --- a/externals/fmt/src/os.cc +++ b/externals/fmt/src/os.cc @@ -18,6 +18,10 @@ # include <sys/stat.h> # include <sys/types.h> +# ifdef _WRS_KERNEL // VxWorks7 kernel +# include <ioLib.h> // getpagesize +# endif + # ifndef _WIN32 # include <unistd.h> # else @@ -72,34 +76,6 @@ inline std::size_t convert_rwcount(std::size_t count) { return count; } FMT_BEGIN_NAMESPACE #ifdef _WIN32 -detail::utf16_to_utf8::utf16_to_utf8(basic_string_view<wchar_t> s) { - if (int error_code = convert(s)) { - FMT_THROW(windows_error(error_code, - "cannot convert string from UTF-16 to UTF-8")); - } -} - -int detail::utf16_to_utf8::convert(basic_string_view<wchar_t> s) { - if (s.size() > INT_MAX) return ERROR_INVALID_PARAMETER; - int s_size = static_cast<int>(s.size()); - if (s_size == 0) { - // WideCharToMultiByte does not support zero length, handle separately. - buffer_.resize(1); - buffer_[0] = 0; - return 0; - } - - int length = WideCharToMultiByte(CP_UTF8, 0, s.data(), s_size, nullptr, 0, - nullptr, nullptr); - if (length == 0) return GetLastError(); - buffer_.resize(length + 1); - length = WideCharToMultiByte(CP_UTF8, 0, s.data(), s_size, &buffer_[0], - length, nullptr, nullptr); - if (length == 0) return GetLastError(); - buffer_[length] = 0; - return 0; -} - namespace detail { class system_message { @@ -138,10 +114,10 @@ class utf8_system_category final : public std::error_category { public: const char* name() const noexcept override { return "system"; } std::string message(int error_code) const override { - system_message msg(error_code); + auto&& msg = system_message(error_code); if (msg) { - utf16_to_utf8 utf8_message; - if (utf8_message.convert(msg) == ERROR_SUCCESS) { + auto utf8_message = to_utf8<wchar_t>(); + if (utf8_message.convert(msg)) { return utf8_message.str(); } } @@ -165,11 +141,12 @@ std::system_error vwindows_error(int err_code, string_view format_str, void detail::format_windows_error(detail::buffer<char>& out, int error_code, const char* message) noexcept { FMT_TRY { - system_message msg(error_code); + auto&& msg = system_message(error_code); if (msg) { - utf16_to_utf8 utf8_message; - if (utf8_message.convert(msg) == ERROR_SUCCESS) { - fmt::format_to(buffer_appender<char>(out), "{}: {}", message, utf8_message); + auto utf8_message = to_utf8<wchar_t>(); + if (utf8_message.convert(msg)) { + fmt::format_to(appender(out), FMT_STRING("{}: {}"), message, + string_view(utf8_message)); return; } } @@ -192,37 +169,47 @@ buffered_file::buffered_file(cstring_view filename, cstring_view mode) { FMT_RETRY_VAL(file_, FMT_SYSTEM(fopen(filename.c_str(), mode.c_str())), nullptr); if (!file_) - FMT_THROW(system_error(errno, "cannot open file {}", filename.c_str())); + FMT_THROW(system_error(errno, FMT_STRING("cannot open file {}"), + filename.c_str())); } void buffered_file::close() { if (!file_) return; int result = FMT_SYSTEM(fclose(file_)); file_ = nullptr; - if (result != 0) FMT_THROW(system_error(errno, "cannot close file")); + if (result != 0) + FMT_THROW(system_error(errno, FMT_STRING("cannot close file"))); } int buffered_file::descriptor() const { +#ifdef fileno // fileno is a macro on OpenBSD so we cannot use FMT_POSIX_CALL. + int fd = fileno(file_); +#else int fd = FMT_POSIX_CALL(fileno(file_)); - if (fd == -1) FMT_THROW(system_error(errno, "cannot get file descriptor")); +#endif + if (fd == -1) + FMT_THROW(system_error(errno, FMT_STRING("cannot get file descriptor"))); return fd; } #if FMT_USE_FCNTL -file::file(cstring_view path, int oflag) { # ifdef _WIN32 - using mode_t = int; +using mode_t = int; # endif - constexpr mode_t mode = - S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; +constexpr mode_t default_open_mode = + S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; + +file::file(cstring_view path, int oflag) { # if defined(_WIN32) && !defined(__MINGW32__) fd_ = -1; - FMT_POSIX_CALL(sopen_s(&fd_, path.c_str(), oflag, _SH_DENYNO, mode)); + auto converted = detail::utf8_to_utf16(string_view(path.c_str())); + *this = file::open_windows_file(converted.c_str(), oflag); # else - FMT_RETRY(fd_, FMT_POSIX_CALL(open(path.c_str(), oflag, mode))); -# endif + FMT_RETRY(fd_, FMT_POSIX_CALL(open(path.c_str(), oflag, default_open_mode))); if (fd_ == -1) - FMT_THROW(system_error(errno, "cannot open file {}", path.c_str())); + FMT_THROW( + system_error(errno, FMT_STRING("cannot open file {}"), path.c_str())); +# endif } file::~file() noexcept { @@ -238,7 +225,8 @@ void file::close() { // See http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html int result = FMT_POSIX_CALL(close(fd_)); fd_ = -1; - if (result != 0) FMT_THROW(system_error(errno, "cannot close file")); + if (result != 0) + FMT_THROW(system_error(errno, FMT_STRING("cannot close file"))); } long long file::size() const { @@ -260,7 +248,7 @@ long long file::size() const { using Stat = struct stat; Stat file_stat = Stat(); if (FMT_POSIX_CALL(fstat(fd_, &file_stat)) == -1) - FMT_THROW(system_error(errno, "cannot get file attributes")); + FMT_THROW(system_error(errno, FMT_STRING("cannot get file attributes"))); static_assert(sizeof(long long) >= sizeof(file_stat.st_size), "return type of file::size is not large enough"); return file_stat.st_size; @@ -270,14 +258,16 @@ long long file::size() const { std::size_t file::read(void* buffer, std::size_t count) { rwresult result = 0; FMT_RETRY(result, FMT_POSIX_CALL(read(fd_, buffer, convert_rwcount(count)))); - if (result < 0) FMT_THROW(system_error(errno, "cannot read from file")); + if (result < 0) + FMT_THROW(system_error(errno, FMT_STRING("cannot read from file"))); return detail::to_unsigned(result); } std::size_t file::write(const void* buffer, std::size_t count) { rwresult result = 0; FMT_RETRY(result, FMT_POSIX_CALL(write(fd_, buffer, convert_rwcount(count)))); - if (result < 0) FMT_THROW(system_error(errno, "cannot write to file")); + if (result < 0) + FMT_THROW(system_error(errno, FMT_STRING("cannot write to file"))); return detail::to_unsigned(result); } @@ -286,7 +276,8 @@ file file::dup(int fd) { // http://pubs.opengroup.org/onlinepubs/009695399/functions/dup.html int new_fd = FMT_POSIX_CALL(dup(fd)); if (new_fd == -1) - FMT_THROW(system_error(errno, "cannot duplicate file descriptor {}", fd)); + FMT_THROW(system_error( + errno, FMT_STRING("cannot duplicate file descriptor {}"), fd)); return file(new_fd); } @@ -294,8 +285,9 @@ void file::dup2(int fd) { int result = 0; FMT_RETRY(result, FMT_POSIX_CALL(dup2(fd_, fd))); if (result == -1) { - FMT_THROW(system_error(errno, "cannot duplicate file descriptor {} to {}", - fd_, fd)); + FMT_THROW(system_error( + errno, FMT_STRING("cannot duplicate file descriptor {} to {}"), fd_, + fd)); } } @@ -320,7 +312,8 @@ void file::pipe(file& read_end, file& write_end) { // http://pubs.opengroup.org/onlinepubs/009696799/functions/pipe.html int result = FMT_POSIX_CALL(pipe(fds)); # endif - if (result != 0) FMT_THROW(system_error(errno, "cannot create pipe")); + if (result != 0) + FMT_THROW(system_error(errno, FMT_STRING("cannot create pipe"))); // The following assignments don't throw because read_fd and write_fd // are closed. read_end = file(fds[0]); @@ -334,28 +327,72 @@ buffered_file file::fdopen(const char* mode) { # else FILE* f = FMT_POSIX_CALL(fdopen(fd_, mode)); # endif - if (!f) - FMT_THROW( - system_error(errno, "cannot associate stream with file descriptor")); + if (!f) { + FMT_THROW(system_error( + errno, FMT_STRING("cannot associate stream with file descriptor"))); + } buffered_file bf(f); fd_ = -1; return bf; } +# if defined(_WIN32) && !defined(__MINGW32__) +file file::open_windows_file(wcstring_view path, int oflag) { + int fd = -1; + auto err = _wsopen_s(&fd, path.c_str(), oflag, _SH_DENYNO, default_open_mode); + if (fd == -1) { + FMT_THROW(system_error(err, FMT_STRING("cannot open file {}"), + detail::to_utf8<wchar_t>(path.c_str()).c_str())); + } + return file(fd); +} +# endif + +# if !defined(__MSDOS__) long getpagesize() { -# ifdef _WIN32 +# ifdef _WIN32 SYSTEM_INFO si; GetSystemInfo(&si); return si.dwPageSize; -# else +# else +# ifdef _WRS_KERNEL + long size = FMT_POSIX_CALL(getpagesize()); +# else long size = FMT_POSIX_CALL(sysconf(_SC_PAGESIZE)); - if (size < 0) FMT_THROW(system_error(errno, "cannot get memory page size")); +# endif + + if (size < 0) + FMT_THROW(system_error(errno, FMT_STRING("cannot get memory page size"))); return size; -# endif +# endif } +# endif -FMT_API void ostream::grow(size_t) { +namespace detail { + +void file_buffer::grow(size_t) { if (this->size() == this->capacity()) flush(); } + +file_buffer::file_buffer(cstring_view path, + const detail::ostream_params& params) + : file_(path, params.oflag) { + set(new char[params.buffer_size], params.buffer_size); +} + +file_buffer::file_buffer(file_buffer&& other) + : detail::buffer<char>(other.data(), other.size(), other.capacity()), + file_(std::move(other.file_)) { + other.clear(); + other.set(nullptr, 0); +} + +file_buffer::~file_buffer() { + flush(); + delete[] data(); +} +} // namespace detail + +ostream::~ostream() = default; #endif // FMT_USE_FCNTL FMT_END_NAMESPACE |