40 #if defined(_WIN32) && defined(__MINGW32__)
45 # if defined(NOMINMAX) || defined(FMT_WIN_MINMAX)
58 # define FMT_CATCH(x) catch (x)
60 # define FMT_TRY if (true)
61 # define FMT_CATCH(x) if (false)
65 # pragma warning(push)
66 # pragma warning(disable: 4127) // conditional expression is constant
67 # pragma warning(disable: 4702) // unreachable code
70 # pragma warning(disable: 4996)
91 # define FMT_SNPRINTF snprintf
93 inline int fmt_snprintf(
char *buffer,
size_t size,
const char *
format, ...) {
96 int result = vsnprintf_s(buffer, size, _TRUNCATE,
format, args);
100 # define FMT_SNPRINTF fmt_snprintf
103 #if defined(_WIN32) && defined(__MINGW32__) && !defined(__NO_ISOCEXT)
104 # define FMT_SWPRINTF snwprintf
106 # define FMT_SWPRINTF swprintf
107 #endif // defined(_WIN32) && defined(__MINGW32__) && !defined(__NO_ISOCEXT)
109 const char RESET_COLOR[] =
"\x1b[0m";
123 int error_code,
char *&buffer, std::size_t buffer_size)
FMT_NOEXCEPT {
124 FMT_ASSERT(buffer != 0 && buffer_size != 0,
"invalid buffer");
130 std::size_t buffer_size_;
133 void operator=(
const StrError &) {}
136 int handle(
int result) {
138 return result == -1 ? errno : result;
142 int handle(
char *message) {
144 if (message == buffer_ && strlen(buffer_) == buffer_size_ - 1)
151 int handle(internal::Null<>) {
152 return fallback(
strerror_s(buffer_, buffer_size_, error_code_));
156 int fallback(
int result) {
158 return result == 0 && strlen(buffer_) == buffer_size_ - 1 ?
163 int fallback(internal::Null<>) {
165 buffer_ = strerror(error_code_);
170 StrError(
int err_code,
char *&buf, std::size_t buf_size)
171 : error_code_(err_code), buffer_(buf), buffer_size_(buf_size) {}
175 return handle(
strerror_r(error_code_, buffer_, buffer_size_));
178 return StrError(error_code, buffer, buffer_size).run();
181 void format_error_code(
Writer &out,
int error_code,
187 static const char SEP[] =
": ";
188 static const char ERROR_STR[] =
"error ";
190 std::size_t error_code_size =
sizeof(SEP) +
sizeof(ERROR_STR) - 2;
191 typedef internal::IntTraits<int>::MainType MainType;
192 MainType abs_value =
static_cast<MainType
>(error_code);
194 abs_value = 0 - abs_value;
199 out << message << SEP;
200 out << ERROR_STR << error_code;
204 void report_error(FormatFunc func,
int error_code,
207 func(full_message, error_code, message);
210 std::fwrite(full_message.data(), full_message.size(), 1, stderr);
211 std::fputc(
'\n', stderr);
228 error_code_ = err_code;
231 std::runtime_error &base = *
this;
232 base = std::runtime_error(w.
str());
235 template <
typename T>
237 char *buffer, std::size_t size,
const char *
format,
238 unsigned width,
int precision, T
value) {
240 return precision < 0 ?
244 return precision < 0 ?
249 template <
typename T>
251 wchar_t *buffer, std::size_t size,
const wchar_t *
format,
252 unsigned width,
int precision, T
value) {
254 return precision < 0 ?
258 return precision < 0 ?
263 template <
typename T>
265 "0001020304050607080910111213141516171819"
266 "2021222324252627282930313233343536373839"
267 "4041424344454647484950515253545556575859"
268 "6061626364656667686970717273747576777879"
269 "8081828384858687888990919293949596979899";
271 #define FMT_POWERS_OF_10(factor) \
279 factor * 100000000, \
282 template <
typename T>
287 template <
typename T>
299 if (std::isprint(
static_cast<unsigned char>(code))) {
301 fmt::format(
"unknown format code '{}' for {}", code, type)));
304 fmt::format(
"unknown format code '\\x{:02x}' for {}",
305 static_cast<unsigned>(code), type)));
308 #if FMT_USE_WINDOWS_H
311 static const char ERROR_MSG[] =
"cannot convert string from UTF-8 to UTF-16";
312 if (s.
size() > INT_MAX)
313 FMT_THROW(WindowsError(ERROR_INVALID_PARAMETER, ERROR_MSG));
314 int s_size =
static_cast<int>(s.
size());
315 int length = MultiByteToWideChar(
316 CP_UTF8, MB_ERR_INVALID_CHARS, s.
data(), s_size, 0, 0);
318 FMT_THROW(WindowsError(GetLastError(), ERROR_MSG));
319 buffer_.resize(length + 1);
320 length = MultiByteToWideChar(
321 CP_UTF8, MB_ERR_INVALID_CHARS, s.
data(), s_size, &buffer_[0], length);
323 FMT_THROW(WindowsError(GetLastError(), ERROR_MSG));
328 if (
int error_code =
convert(s)) {
330 "cannot convert string from UTF-16 to UTF-8"));
335 if (s.
size() > INT_MAX)
336 return ERROR_INVALID_PARAMETER;
337 int s_size =
static_cast<int>(s.
size());
338 int length = WideCharToMultiByte(CP_UTF8, 0, s.
data(), s_size, 0, 0, 0, 0);
340 return GetLastError();
341 buffer_.resize(length + 1);
342 length = WideCharToMultiByte(
343 CP_UTF8, 0, s.
data(), s_size, &buffer_[0], length, 0, 0);
345 return GetLastError();
350 FMT_FUNC void fmt::WindowsError::init(
351 int err_code,
CStringRef format_str, ArgList args) {
352 error_code_ = err_code;
354 internal::format_windows_error(w, err_code,
format(format_str, args));
355 std::runtime_error &base = *
this;
356 base = std::runtime_error(w.str());
359 FMT_FUNC void fmt::internal::format_windows_error(
363 MemoryBuffer<wchar_t, INLINE_BUFFER_SIZE> buffer;
366 wchar_t *system_message = &buffer[0];
367 int result = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
368 0, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
369 system_message,
static_cast<uint32_t
>(buffer.size()), 0);
371 UTF16ToUTF8 utf8_message;
372 if (utf8_message.convert(system_message) == ERROR_SUCCESS) {
373 out << message <<
": " << utf8_message;
378 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
380 buffer.resize(buffer.size() * 2);
383 fmt::format_error_code(out, error_code, message);
386 #endif // FMT_USE_WINDOWS_H
395 char *system_message = &buffer[0];
396 int result = safe_strerror(error_code, system_message, buffer.
size());
398 out << message <<
": " << system_message;
401 if (result != ERANGE)
406 fmt::format_error_code(out, error_code, message);
409 template <
typename Char>
418 for (
unsigned i = 0;; ++i) {
425 map_.push_back(
Pair(named_arg->
name, *named_arg));
437 map_.push_back(
Pair(named_arg->
name, *named_arg));
446 map_.push_back(
Pair(named_arg->
name, *named_arg));
454 template <
typename Char>
456 FMT_THROW(std::runtime_error(
"buffer overflow"));
460 unsigned arg_index,
const char *&error) {
461 Arg arg = args_[arg_index];
464 error =
"argument index out of range";
481 #if FMT_USE_WINDOWS_H
482 FMT_FUNC void fmt::report_windows_error(
485 fmt::report_error(internal::format_windows_error, error_code, message);
491 w.
write(format_str, args);
492 std::fwrite(w.
data(), 1, w.
size(), f);
496 print(stdout, format_str, args);
500 char escape[] =
"\x1b[30m";
501 escape[3] =
static_cast<char>(
'0' + c);
502 std::fputs(escape, stdout);
504 std::fputs(RESET_COLOR, stdout);
510 std::size_t size = w.
size();
511 return std::fwrite(w.
data(), 1, size, f) < size ? -1 :
static_cast<int>(size);
514 #ifndef FMT_HEADER_ONLY
528 char *buffer, std::size_t size,
const char *
format,
529 unsigned width,
int precision,
double value);
532 char *buffer, std::size_t size,
const char *
format,
533 unsigned width,
int precision,
long double value);
545 wchar_t *buffer, std::size_t size,
const wchar_t *
format,
546 unsigned width,
int precision,
double value);
549 wchar_t *buffer, std::size_t size,
const wchar_t *
format,
550 unsigned width,
int precision,
long double value);
552 #endif // FMT_HEADER_ONLY
555 # pragma warning(pop)