Optional Win9x support
Adds optional support for Windows 9x/ME and the original Xbox (nxdk). Most of libfmt is available except functions that depend on `fileno`, such as file descriptor duplication. For now, support must be enabled explicitly by defining `FMT_WIN9X`.
This commit is contained in:
parent
f6276a2c2b
commit
fba8bc3975
@ -268,6 +268,11 @@ target_include_directories(fmt-header-only ${FMT_SYSTEM_HEADERS_ATTRIBUTE} INTER
|
|||||||
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
|
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
|
||||||
$<INSTALL_INTERFACE:${FMT_INC_DIR}>)
|
$<INSTALL_INTERFACE:${FMT_INC_DIR}>)
|
||||||
|
|
||||||
|
if (FMT_WIN98X)
|
||||||
|
target_compile_definitions(fmt PUBLIC FMT_WIN98X=1)
|
||||||
|
target_compile_definitions(fmt-header-only INTERFACE FMT_WIN98X=1)
|
||||||
|
endif()
|
||||||
|
|
||||||
# Install targets.
|
# Install targets.
|
||||||
if (FMT_INSTALL)
|
if (FMT_INSTALL)
|
||||||
include(CMakePackageConfigHelpers)
|
include(CMakePackageConfigHelpers)
|
||||||
|
|||||||
@ -46,8 +46,8 @@ FMT_BEGIN_NAMESPACE
|
|||||||
# if FMT_HAS_INCLUDE("winapifamily.h")
|
# if FMT_HAS_INCLUDE("winapifamily.h")
|
||||||
# include <winapifamily.h>
|
# include <winapifamily.h>
|
||||||
# endif
|
# endif
|
||||||
# if defined(_WIN32) && (!defined(WINAPI_FAMILY) || \
|
# if defined(_WIN32) && !FMT_WIN9X && \
|
||||||
(WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP))
|
(!defined(WINAPI_FAMILY) || (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP))
|
||||||
# define FMT_USE_TZSET 1
|
# define FMT_USE_TZSET 1
|
||||||
# else
|
# else
|
||||||
# define FMT_USE_TZSET 0
|
# define FMT_USE_TZSET 0
|
||||||
@ -488,7 +488,7 @@ inline std::tm localtime(std::time_t time) {
|
|||||||
|
|
||||||
bool fallback(int res) { return res == 0; }
|
bool fallback(int res) { return res == 0; }
|
||||||
|
|
||||||
#if !FMT_MSC_VERSION
|
#if !FMT_MSC_VERSION || FMT_WIN9X
|
||||||
bool fallback(detail::null<>) {
|
bool fallback(detail::null<>) {
|
||||||
using namespace fmt::detail;
|
using namespace fmt::detail;
|
||||||
std::tm* tm = std::localtime(&time_);
|
std::tm* tm = std::localtime(&time_);
|
||||||
@ -537,7 +537,7 @@ inline std::tm gmtime(std::time_t time) {
|
|||||||
|
|
||||||
bool fallback(int res) { return res == 0; }
|
bool fallback(int res) { return res == 0; }
|
||||||
|
|
||||||
#if !FMT_MSC_VERSION
|
#if !FMT_MSC_VERSION || FMT_WIN9X
|
||||||
bool fallback(detail::null<>) {
|
bool fallback(detail::null<>) {
|
||||||
std::tm* tm = std::gmtime(&time_);
|
std::tm* tm = std::gmtime(&time_);
|
||||||
if (tm) tm_ = *tm;
|
if (tm) tm_ = *tm;
|
||||||
|
|||||||
@ -257,6 +257,14 @@
|
|||||||
# define FMT_UNICODE !FMT_MSC_VERSION
|
# define FMT_UNICODE !FMT_MSC_VERSION
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef FMT_WIN9X
|
||||||
|
# if defined(NXDK)
|
||||||
|
# define FMT_WIN9X 1
|
||||||
|
# else
|
||||||
|
# define FMT_WIN9X 0
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef FMT_CONSTEVAL
|
#ifndef FMT_CONSTEVAL
|
||||||
# if ((FMT_GCC_VERSION >= 1000 || FMT_CLANG_VERSION >= 1101) && \
|
# if ((FMT_GCC_VERSION >= 1000 || FMT_CLANG_VERSION >= 1101) && \
|
||||||
(!defined(__apple_build_version__) || \
|
(!defined(__apple_build_version__) || \
|
||||||
|
|||||||
@ -22,7 +22,7 @@
|
|||||||
# include <locale>
|
# include <locale>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _WIN32
|
#if defined(_WIN32) && !FMT_WIN9X
|
||||||
# include <io.h> // _isatty
|
# include <io.h> // _isatty
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1453,7 +1453,7 @@ FMT_FUNC std::string vformat(string_view fmt, format_args args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
#ifdef _WIN32
|
#if defined(_WIN32) && !FMT_WIN9X
|
||||||
using dword = conditional_t<sizeof(long) == 4, unsigned long, unsigned>;
|
using dword = conditional_t<sizeof(long) == 4, unsigned long, unsigned>;
|
||||||
extern "C" __declspec(dllimport) int __stdcall WriteConsoleW( //
|
extern "C" __declspec(dllimport) int __stdcall WriteConsoleW( //
|
||||||
void*, const void*, dword, dword*, void*);
|
void*, const void*, dword, dword*, void*);
|
||||||
@ -1478,7 +1478,7 @@ FMT_FUNC bool write_console(std::FILE* f, string_view text) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
FMT_FUNC void print(std::FILE* f, string_view text) {
|
FMT_FUNC void print(std::FILE* f, string_view text) {
|
||||||
#ifdef _WIN32
|
#if defined(_WIN32) && !FMT_WIN9X
|
||||||
if (write_console(f, text)) return;
|
if (write_console(f, text)) return;
|
||||||
#endif
|
#endif
|
||||||
detail::fwrite_fully(text.data(), 1, text.size(), f);
|
detail::fwrite_fully(text.data(), 1, text.size(), f);
|
||||||
@ -1491,7 +1491,7 @@ FMT_FUNC void vprint(std::FILE* f, string_view format_str, format_args args) {
|
|||||||
detail::print(f, {buffer.data(), buffer.size()});
|
detail::print(f, {buffer.data(), buffer.size()});
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#if defined(_WIN32) && !FMT_WIN9X
|
||||||
// Print assuming legacy (non-Unicode) encoding.
|
// Print assuming legacy (non-Unicode) encoding.
|
||||||
FMT_FUNC void detail::vprint_mojibake(std::FILE* f, string_view format_str,
|
FMT_FUNC void detail::vprint_mojibake(std::FILE* f, string_view format_str,
|
||||||
format_args args) {
|
format_args args) {
|
||||||
|
|||||||
@ -49,7 +49,7 @@
|
|||||||
# define FMT_POSIX_CALL(call) FMT_SYSTEM(call)
|
# define FMT_POSIX_CALL(call) FMT_SYSTEM(call)
|
||||||
#else
|
#else
|
||||||
# define FMT_SYSTEM(call) ::call
|
# define FMT_SYSTEM(call) ::call
|
||||||
# ifdef _WIN32
|
# if defined(_WIN32) && !FMT_WIN9X
|
||||||
// Fix warnings about deprecated symbols.
|
// Fix warnings about deprecated symbols.
|
||||||
# define FMT_POSIX_CALL(call) ::_##call
|
# define FMT_POSIX_CALL(call) ::_##call
|
||||||
# else
|
# else
|
||||||
@ -242,7 +242,9 @@ class buffered_file {
|
|||||||
// Returns the pointer to a FILE object representing this file.
|
// Returns the pointer to a FILE object representing this file.
|
||||||
FILE* get() const noexcept { return file_; }
|
FILE* get() const noexcept { return file_; }
|
||||||
|
|
||||||
|
#if !FMT_WIN9X
|
||||||
FMT_API int descriptor() const;
|
FMT_API int descriptor() const;
|
||||||
|
#endif
|
||||||
|
|
||||||
void vprint(string_view format_str, format_args args) {
|
void vprint(string_view format_str, format_args args) {
|
||||||
fmt::vprint(file_, format_str, args);
|
fmt::vprint(file_, format_str, args);
|
||||||
@ -318,6 +320,7 @@ class FMT_API file {
|
|||||||
// Attempts to write count bytes from the specified buffer to the file.
|
// Attempts to write count bytes from the specified buffer to the file.
|
||||||
size_t write(const void* buffer, size_t count);
|
size_t write(const void* buffer, size_t count);
|
||||||
|
|
||||||
|
#if !FMT_WIN9X
|
||||||
// Duplicates a file descriptor with the dup function and returns
|
// Duplicates a file descriptor with the dup function and returns
|
||||||
// the duplicate as a file object.
|
// the duplicate as a file object.
|
||||||
static file dup(int fd);
|
static file dup(int fd);
|
||||||
@ -333,6 +336,7 @@ class FMT_API file {
|
|||||||
// Creates a pipe setting up read_end and write_end file objects for reading
|
// Creates a pipe setting up read_end and write_end file objects for reading
|
||||||
// and writing respectively.
|
// and writing respectively.
|
||||||
static void pipe(file& read_end, file& write_end);
|
static void pipe(file& read_end, file& write_end);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Creates a buffered_file object associated with this file and detaches
|
// Creates a buffered_file object associated with this file and detaches
|
||||||
// this file object from the file.
|
// this file object from the file.
|
||||||
|
|||||||
@ -71,7 +71,7 @@ inline std::size_t convert_rwcount(std::size_t count) { return count; }
|
|||||||
|
|
||||||
FMT_BEGIN_NAMESPACE
|
FMT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
#ifdef _WIN32
|
#if defined(_WIN32) && !FMT_WIN9X
|
||||||
detail::utf16_to_utf8::utf16_to_utf8(basic_string_view<wchar_t> s) {
|
detail::utf16_to_utf8::utf16_to_utf8(basic_string_view<wchar_t> s) {
|
||||||
if (int error_code = convert(s)) {
|
if (int error_code = convert(s)) {
|
||||||
FMT_THROW(windows_error(error_code,
|
FMT_THROW(windows_error(error_code,
|
||||||
@ -205,6 +205,7 @@ void buffered_file::close() {
|
|||||||
FMT_THROW(system_error(errno, FMT_STRING("cannot close file")));
|
FMT_THROW(system_error(errno, FMT_STRING("cannot close file")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !FMT_WIN9X
|
||||||
int buffered_file::descriptor() const {
|
int buffered_file::descriptor() const {
|
||||||
#ifdef fileno // fileno is a macro on OpenBSD so we cannot use FMT_POSIX_CALL.
|
#ifdef fileno // fileno is a macro on OpenBSD so we cannot use FMT_POSIX_CALL.
|
||||||
int fd = fileno(file_);
|
int fd = fileno(file_);
|
||||||
@ -215,6 +216,7 @@ int buffered_file::descriptor() const {
|
|||||||
FMT_THROW(system_error(errno, FMT_STRING("cannot get file descriptor")));
|
FMT_THROW(system_error(errno, FMT_STRING("cannot get file descriptor")));
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
#endif // !FMT_WIN9X
|
||||||
|
|
||||||
#if FMT_USE_FCNTL
|
#if FMT_USE_FCNTL
|
||||||
# ifdef _WIN32
|
# ifdef _WIN32
|
||||||
@ -295,6 +297,7 @@ std::size_t file::write(const void* buffer, std::size_t count) {
|
|||||||
return detail::to_unsigned(result);
|
return detail::to_unsigned(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !FMT_WIN9X
|
||||||
file file::dup(int fd) {
|
file file::dup(int fd) {
|
||||||
// Don't retry as dup doesn't return EINTR.
|
// Don't retry as dup doesn't return EINTR.
|
||||||
// http://pubs.opengroup.org/onlinepubs/009695399/functions/dup.html
|
// http://pubs.opengroup.org/onlinepubs/009695399/functions/dup.html
|
||||||
@ -343,6 +346,7 @@ void file::pipe(file& read_end, file& write_end) {
|
|||||||
read_end = file(fds[0]);
|
read_end = file(fds[0]);
|
||||||
write_end = file(fds[1]);
|
write_end = file(fds[1]);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
buffered_file file::fdopen(const char* mode) {
|
buffered_file file::fdopen(const char* mode) {
|
||||||
// Don't retry as fdopen doesn't return EINTR.
|
// Don't retry as fdopen doesn't return EINTR.
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user