aboutsummaryrefslogtreecommitdiffhomepage
path: root/externals/fmt/src/os.cc
diff options
context:
space:
mode:
Diffstat (limited to 'externals/fmt/src/os.cc')
-rw-r--r--externals/fmt/src/os.cc161
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