2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
39#if defined(_WIN32
) && defined(__MINGW32__)
44# if !defined(FMT_HEADER_ONLY) && !defined(WIN32_LEAN_AND_MEAN)
45# define WIN32_LEAN_AND_MEAN
47# 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)
66# pragma warning(disable: 4127
)
67# pragma warning(disable: 4702
)
70# pragma warning(disable: 4996
)
93# define FMT_SNPRINTF snprintf
95inline int fmt_snprintf(
char *buffer, size_t size,
const char *format, ...) {
97 va_start(args, format);
98 int result = vsnprintf_s(buffer, size, _TRUNCATE, format, args);
102# define FMT_SNPRINTF fmt_snprintf
105#if defined(_WIN32
) && defined(__MINGW32__) && !defined(__NO_ISOCEXT)
106# define FMT_SWPRINTF snwprintf
108# define FMT_SWPRINTF swprintf
132 std::size_t buffer_size_;
135 void operator=(
const StrError &) {}
138 int handle(
int result) {
140 return result == -1 ? errno : result;
144 int handle(
char *message) {
146 if (message == buffer_ && strlen(buffer_) == buffer_size_ - 1)
158 int fallback(
int result) {
160 return result == 0 && strlen(buffer_) == buffer_size_ - 1 ?
165# pragma clang diagnostic push
166# pragma clang diagnostic ignored "-Wdeprecated-declarations"
172 buffer_ = strerror(error_code_);
177# pragma clang diagnostic pop
181 StrError(
int err_code,
char *&buf,
std::size_t buf_size)
182 : error_code_(err_code), buffer_(buf), buffer_size_(buf_size) {}
188 return StrError(error_code, buffer, buffer_size).run();
197 static const char SEP[] =
": ";
198 static const char ERROR_STR[] =
"error ";
200 std::size_t error_code_size =
sizeof(SEP) +
sizeof(ERROR_STR) - 2;
201 typedef internal::IntTraits<
int>::MainType MainType;
202 MainType abs_value =
static_cast<MainType>(error_code);
203 if (
internal::is_negative(error_code)) {
204 abs_value = 0 - abs_value;
207 error_code_size +=
internal::count_digits(abs_value);
208 if (message.size() <=
internal::INLINE_BUFFER_SIZE - error_code_size)
209 out << message << SEP;
210 out << ERROR_STR << error_code;
211 assert(out.size() <=
internal::INLINE_BUFFER_SIZE);
216 MemoryWriter full_message;
217 func(full_message, error_code, message);
220 std::fwrite(full_message.data(), full_message.size(), 1, stderr);
221 std::fputc(
'\n', stderr);
226 int err_code, CStringRef format_str, ArgList args) {
229 format_system_error(w, err_code, format(format_str, args));
230 std::runtime_error &base = *
this;
231 base =
std::runtime_error(w.str());
236 char *buffer,
std::size_t size,
const char *format,
237 unsigned width,
int precision, T value) {
239 return precision < 0 ?
243 return precision < 0 ?
245 FMT_SNPRINTF(buffer, size, format, width, precision, value);
250 wchar_t *buffer,
std::size_t size,
const wchar_t *format,
251 unsigned width,
int precision, T value) {
253 return precision < 0 ?
257 return precision < 0 ?
259 FMT_SWPRINTF(buffer, size, format, width, precision, value);
263const char internal::BasicData<T>::DIGITS[] =
264 "0001020304050607080910111213141516171819"
265 "2021222324252627282930313233343536373839"
266 "4041424344454647484950515253545556575859"
267 "6061626364656667686970717273747576777879"
268 "8081828384858687888990919293949596979899";
270#define FMT_POWERS_OF_10(factor)
282const uint32_t
internal::BasicData<T>::POWERS_OF_10_32[] = {
287const uint64_t
internal::BasicData<T>::POWERS_OF_10_64[] = {
293 ULongLong(1000000000) * ULongLong(1000000000) * 10
298 if (
std::isprint(
static_cast<
unsigned char>(code))) {
300 format(
"unknown format code '{}' for {}", code, type)));
303 format(
"unknown format code '\\x{:02x}' for {}",
304 static_cast<
unsigned>(code), type)));
310 static const char ERROR_MSG[] =
"cannot convert string from UTF-8 to UTF-16";
311 if (s.size() > INT_MAX)
312 FMT_THROW(WindowsError(ERROR_INVALID_PARAMETER, ERROR_MSG));
313 int s_size =
static_cast<
int>(s.size());
314 int length = MultiByteToWideChar(
315 CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), s_size,
FMT_NULL, 0);
317 FMT_THROW(WindowsError(GetLastError(), ERROR_MSG));
318 buffer_.resize(length + 1);
319 length = MultiByteToWideChar(
320 CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), s_size, &buffer_[0], length);
322 FMT_THROW(WindowsError(GetLastError(), ERROR_MSG));
327 if (
int error_code = convert(s)) {
329 "cannot convert string from UTF-16 to UTF-8"));
334 if (s.size() > INT_MAX)
335 return ERROR_INVALID_PARAMETER;
336 int s_size =
static_cast<
int>(s.size());
337 int length = WideCharToMultiByte(
340 return GetLastError();
341 buffer_.resize(length + 1);
342 length = WideCharToMultiByte(
345 return GetLastError();
351 int err_code, CStringRef format_str, ArgList args) {
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());
360 Writer &out,
int error_code, StringRef message)
FMT_NOEXCEPT {
362 MemoryBuffer<
wchar_t, INLINE_BUFFER_SIZE> buffer;
363 buffer.resize(INLINE_BUFFER_SIZE);
365 wchar_t *system_message = &buffer[0];
366 int result = FormatMessageW(
367 FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
368 FMT_NULL, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
369 system_message,
static_cast<uint32_t>(buffer.size()),
FMT_NULL);
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);
389 Writer &out,
int error_code, StringRef message)
FMT_NOEXCEPT {
392 buffer.resize(
internal::INLINE_BUFFER_SIZE);
394 char *system_message = &buffer[0];
397 out << message <<
": " << system_message;
400 if (result != ERANGE)
402 buffer.resize(buffer.size() * 2);
408template <
typename Char>
414 unsigned arg_index,
const char *&error) {
418 error =
"argument index out of range";
421 arg = *
static_cast<
const internal::Arg*>(arg.pointer);
443FMT_FUNC void print(
std::FILE *f, CStringRef format_str, ArgList args) {
445 w.write(format_str, args);
446 std::fwrite(w.data(), 1, w.size(), f);
449FMT_FUNC void print(CStringRef format_str, ArgList args) {
450 print(stdout, format_str, args);
454 char escape[] =
"\x1b[30m";
455 escape[3] =
static_cast<
char>(
'0' + c);
456 std::fputs(escape, stdout);
461#ifndef FMT_HEADER_ONLY
463template struct internal::BasicData<
void>;
FMT_API ~SystemError() FMT_DTOR_NOEXCEPT FMT_OVERRIDE
int format_float(char *buffer, std::size_t size, const char *format, unsigned width, int precision, T value)
int format_float(wchar_t *buffer, std::size_t size, const wchar_t *format, unsigned width, int precision, T value)