1    	/*
2    	 Formatting library for C++
3    	
4    	 Copyright (c) 2012 - 2016, Victor Zverovich
5    	 All rights reserved.
6    	
7    	 Redistribution and use in source and binary forms, with or without
8    	 modification, are permitted provided that the following conditions are met:
9    	
10   	 1. Redistributions of source code must retain the above copyright notice, this
11   	    list of conditions and the following disclaimer.
12   	 2. Redistributions in binary form must reproduce the above copyright notice,
13   	    this list of conditions and the following disclaimer in the documentation
14   	    and/or other materials provided with the distribution.
15   	
16   	 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17   	 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18   	 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19   	 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
20   	 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21   	 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22   	 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23   	 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24   	 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25   	 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26   	 */
27   	
28   	#include "mp/format.h"
29   	
30   	#include <string.h>
31   	
32   	#include <cctype>
33   	#include <cerrno>
34   	#include <climits>
35   	#include <cmath>
36   	#include <cstdarg>
37   	#include <cstddef>  // for std::ptrdiff_t
38   	
39   	#if defined(_WIN32) && defined(__MINGW32__)
40   	# include <cstring>
41   	#endif
42   	
43   	#if FMT_USE_WINDOWS_H
44   	# if defined(NOMINMAX) || defined(FMT_WIN_MINMAX)
45   	#  include <windows.h>
46   	# else
47   	#  define NOMINMAX
48   	#  include <windows.h>
49   	#  undef NOMINMAX
50   	# endif
51   	#endif
52   	
53   	using fmt::internal::Arg;
54   	
55   	#if FMT_EXCEPTIONS
56   	# define FMT_TRY try
57   	# define FMT_CATCH(x) catch (x)
58   	#else
59   	# define FMT_TRY if (true)
60   	# define FMT_CATCH(x) if (false)
61   	#endif
62   	
63   	#ifdef _MSC_VER
64   	# pragma warning(push)
65   	# pragma warning(disable: 4127)  // conditional expression is constant
66   	# pragma warning(disable: 4702)  // unreachable code
67   	// Disable deprecation warning for strerror. The latter is not called but
68   	// MSVC fails to detect it.
69   	# pragma warning(disable: 4996)
70   	#endif
71   	
72   	// Dummy implementations of strerror_r and strerror_s called if corresponding
73   	// system functions are not available.
74   	static inline fmt::internal::Null<> strerror_r(int, char *, ...) {
75   	  return fmt::internal::Null<>();
76   	}
77   	static inline fmt::internal::Null<> strerror_s(char *, std::size_t, ...) {
78   	  return fmt::internal::Null<>();
79   	}
80   	
81   	namespace fmt {
82   	
83   	FMT_FUNC internal::RuntimeError::~RuntimeError() throw() {}
84   	FMT_FUNC FormatError::~FormatError() throw() {}
85   	FMT_FUNC SystemError::~SystemError() throw() {}
86   	
87   	namespace {
88   	
89   	#ifndef _MSC_VER
90   	# define FMT_SNPRINTF snprintf
91   	#else  // _MSC_VER
92   	inline int fmt_snprintf(char *buffer, size_t size, const char *format, ...) {
93   	  va_list args;
94   	  va_start(args, format);
95   	  int result = vsnprintf_s(buffer, size, _TRUNCATE, format, args);
96   	  va_end(args);
97   	  return result;
98   	}
99   	# define FMT_SNPRINTF fmt_snprintf
100  	#endif  // _MSC_VER
101  	
102  	#if defined(_WIN32) && defined(__MINGW32__) && !defined(__NO_ISOCEXT)
103  	# define FMT_SWPRINTF snwprintf
104  	#else
105  	# define FMT_SWPRINTF swprintf
106  	#endif // defined(_WIN32) && defined(__MINGW32__) && !defined(__NO_ISOCEXT)
107  	
108  	// Checks if a value fits in int - used to avoid warnings about comparing
109  	// signed and unsigned integers.
110  	template <bool IsSigned>
111  	struct IntChecker {
112  	  template <typename T>
113  	  static bool fits_in_int(T value) {
114  	    unsigned max = INT_MAX;
115  	    return value <= max;
116  	  }
117  	  static bool fits_in_int(bool) { return true; }
118  	};
119  	
120  	template <>
121  	struct IntChecker<true> {
122  	  template <typename T>
123  	  static bool fits_in_int(T value) {
124  	    return value >= INT_MIN && value <= INT_MAX;
125  	  }
126  	  static bool fits_in_int(int) { return true; }
127  	};
128  	
129  	const char RESET_COLOR[] = "\x1b[0m";
130  	
131  	typedef void (*FormatFunc)(Writer &, int, StringRef);
132  	
133  	// Portable thread-safe version of strerror.
134  	// Sets buffer to point to a string describing the error code.
135  	// This can be either a pointer to a string stored in buffer,
136  	// or a pointer to some static immutable string.
137  	// Returns one of the following values:
138  	//   0      - success
139  	//   ERANGE - buffer is not large enough to store the error message
140  	//   other  - failure
141  	// Buffer should be at least of size 1.
142  	int safe_strerror(
143  	    int error_code, char *&buffer, std::size_t buffer_size) FMT_NOEXCEPT {
144  	  FMT_ASSERT(buffer != 0 && buffer_size != 0, "invalid buffer");
145  	
146  	  class StrError {
147  	   private:
148  	    int error_code_;
149  	    char *&buffer_;
150  	    std::size_t buffer_size_;
151  	
152  	    // A noop assignment operator to avoid bogus warnings.
153  	    void operator=(const StrError &) {}
154  	
155  	    // Handle the result of XSI-compliant version of strerror_r.
156  	    int handle(int result) {
157  	      // glibc versions before 2.13 return result in errno.
158  	      return result == -1 ? errno : result;
159  	    }
160  	
161  	    // Handle the result of GNU-specific version of strerror_r.
162  	    int handle(char *message) {
163  	      // If the buffer is full then the message is probably truncated.
164  	      if (message == buffer_ && strlen(buffer_) == buffer_size_ - 1)
165  	        return ERANGE;
166  	      buffer_ = message;
167  	      return 0;
168  	    }
169  	
170  	    // Handle the case when strerror_r is not available.
171  	    int handle(internal::Null<>) {
172  	      return fallback(strerror_s(buffer_, buffer_size_, error_code_));
173  	    }
174  	
175  	    // Fallback to strerror_s when strerror_r is not available.
176  	    int fallback(int result) {
177  	      // If the buffer is full then the message is probably truncated.
178  	      return result == 0 && strlen(buffer_) == buffer_size_ - 1 ?
179  	            ERANGE : result;
180  	    }
181  	
182  	    // Fallback to strerror if strerror_r and strerror_s are not available.
183  	    int fallback(internal::Null<>) {
184  	      errno = 0;
185  	      buffer_ = strerror(error_code_);
186  	      return errno;
187  	    }
188  	
189  	   public:
190  	    StrError(int err_code, char *&buf, std::size_t buf_size)
191  	      : error_code_(err_code), buffer_(buf), buffer_size_(buf_size) {}
192  	
193  	    int run() {
194  	      strerror_r(0, 0, "");  // Suppress a warning about unused strerror_r.
195  	      return handle(strerror_r(error_code_, buffer_, buffer_size_));
196  	    }
197  	  };
198  	  return StrError(error_code, buffer, buffer_size).run();
199  	}
200  	
201  	void format_error_code(Writer &out, int error_code,
202  	                       StringRef message) FMT_NOEXCEPT {
203  	  // Report error code making sure that the output fits into
204  	  // INLINE_BUFFER_SIZE to avoid dynamic memory allocation and potential
205  	  // bad_alloc.
206  	  out.clear();
207  	  static const char SEP[] = ": ";
208  	  static const char ERROR_STR[] = "error ";
209  	  // Subtract 2 to account for terminating null characters in SEP and ERROR_STR.
210  	  std::size_t error_code_size = sizeof(SEP) + sizeof(ERROR_STR) - 2;
211  	  typedef internal::IntTraits<int>::MainType MainType;
212  	  MainType abs_value = static_cast<MainType>(error_code);
213  	  if (internal::is_negative(error_code)) {
214  	    abs_value = 0 - abs_value;
215  	    ++error_code_size;
216  	  }
217  	  error_code_size += internal::count_digits(abs_value);
218  	  if (message.size() <= internal::INLINE_BUFFER_SIZE - error_code_size)
219  	    out << message << SEP;
220  	  out << ERROR_STR << error_code;
221  	  assert(out.size() <= internal::INLINE_BUFFER_SIZE);
222  	}
223  	
224  	void report_error(FormatFunc func, int error_code,
225  	                  StringRef message) FMT_NOEXCEPT {
226  	  MemoryWriter full_message;
227  	  func(full_message, error_code, message);
228  	  // Use Writer::data instead of Writer::c_str to avoid potential memory
229  	  // allocation.
230  	  std::fwrite(full_message.data(), full_message.size(), 1, stderr);
231  	  std::fputc('\n', stderr);
232  	}
233  	
234  	// IsZeroInt::visit(arg) returns true iff arg is a zero integer.
235  	class IsZeroInt : public ArgVisitor<IsZeroInt, bool> {
236  	 public:
237  	  template <typename T>
238  	  bool visit_any_int(T value) { return value == 0; }
239  	};
240  	
241  	// Checks if an argument is a valid printf width specifier and sets
242  	// left alignment if it is negative.
243  	class WidthHandler : public ArgVisitor<WidthHandler, unsigned> {
244  	 private:
245  	  FormatSpec &spec_;
246  	
247  	  FMT_DISALLOW_COPY_AND_ASSIGN(WidthHandler);
248  	
249  	 public:
250  	  explicit WidthHandler(FormatSpec &spec) : spec_(spec) {}
251  	
252  	  void report_unhandled_arg() {
253  	    FMT_THROW(FormatError("width is not integer"));
254  	  }
255  	
256  	  template <typename T>
257  	  unsigned visit_any_int(T value) {
258  	    typedef typename internal::IntTraits<T>::MainType UnsignedType;
259  	    UnsignedType width = static_cast<UnsignedType>(value);
260  	    if (internal::is_negative(value)) {
261  	      spec_.align_ = ALIGN_LEFT;
262  	      width = 0 - width;
263  	    }
264  	    if (width > INT_MAX)
265  	      FMT_THROW(FormatError("number is too big"));
266  	    return static_cast<unsigned>(width);
267  	  }
268  	};
269  	
270  	class PrecisionHandler : public ArgVisitor<PrecisionHandler, int> {
271  	 public:
272  	  void report_unhandled_arg() {
273  	    FMT_THROW(FormatError("precision is not integer"));
274  	  }
275  	
276  	  template <typename T>
277  	  int visit_any_int(T value) {
278  	    if (!IntChecker<std::numeric_limits<T>::is_signed>::fits_in_int(value))
279  	      FMT_THROW(FormatError("number is too big"));
280  	    return static_cast<int>(value);
281  	  }
282  	};
283  	
284  	template <typename T, typename U>
285  	struct is_same {
286  	  enum { value = 0 };
287  	};
288  	
289  	template <typename T>
290  	struct is_same<T, T> {
291  	  enum { value = 1 };
292  	};
293  	
294  	// An argument visitor that converts an integer argument to T for printf,
295  	// if T is an integral type. If T is void, the argument is converted to
296  	// corresponding signed or unsigned type depending on the type specifier:
297  	// 'd' and 'i' - signed, other - unsigned)
298  	template <typename T = void>
299  	class ArgConverter : public ArgVisitor<ArgConverter<T>, void> {
300  	 private:
301  	  internal::Arg &arg_;
302  	  wchar_t type_;
303  	
304  	  FMT_DISALLOW_COPY_AND_ASSIGN(ArgConverter);
305  	
306  	 public:
307  	  ArgConverter(internal::Arg &arg, wchar_t type)
308  	    : arg_(arg), type_(type) {}
309  	
310  	  void visit_bool(bool value) {
311  	    if (type_ != 's')
312  	      visit_any_int(value);
313  	  }
314  	
315  	  template <typename U>
316  	  void visit_any_int(U value) {
317  	    bool is_signed = type_ == 'd' || type_ == 'i';
318  	    using internal::Arg;
319  	    typedef typename internal::Conditional<
320  	        is_same<T, void>::value, U, T>::type TargetType;
321  	    if (sizeof(TargetType) <= sizeof(int)) {
322  	      // Extra casts are used to silence warnings.
323  	      if (is_signed) {
324  	        arg_.type = Arg::INT;
325  	        arg_.int_value = static_cast<int>(static_cast<TargetType>(value));
326  	      } else {
327  	        arg_.type = Arg::UINT;
328  	        typedef typename internal::MakeUnsigned<TargetType>::Type Unsigned;
329  	        arg_.uint_value = static_cast<unsigned>(static_cast<Unsigned>(value));
330  	      }
331  	    } else {
332  	      if (is_signed) {
333  	        arg_.type = Arg::LONG_LONG;
334  	        // glibc's printf doesn't sign extend arguments of smaller types:
335  	        //   std::printf("%lld", -42);  // prints "4294967254"
336  	        // but we don't have to do the same because it's a UB.
337  	        arg_.long_long_value = static_cast<LongLong>(value);
338  	      } else {
339  	        arg_.type = Arg::ULONG_LONG;
340  	        arg_.ulong_long_value =
341  	            static_cast<typename internal::MakeUnsigned<U>::Type>(value);
342  	      }
343  	    }
344  	  }
345  	};
346  	
347  	// Converts an integer argument to char for printf.
348  	class CharConverter : public ArgVisitor<CharConverter, void> {
349  	 private:
350  	  internal::Arg &arg_;
351  	
352  	  FMT_DISALLOW_COPY_AND_ASSIGN(CharConverter);
353  	
354  	 public:
355  	  explicit CharConverter(internal::Arg &arg) : arg_(arg) {}
356  	
357  	  template <typename T>
358  	  void visit_any_int(T value) {
359  	    arg_.type = internal::Arg::CHAR;
360  	    arg_.int_value = static_cast<char>(value);
361  	  }
362  	};
363  	}  // namespace
364  	
365  	namespace internal {
366  	
367  	template <typename Char>
368  	class PrintfArgFormatter :
369  	    public ArgFormatterBase<PrintfArgFormatter<Char>, Char> {
370  	
371  	  void write_null_pointer() {
372  	    this->spec().type_ = 0;
373  	    this->write("(nil)");
374  	  }
375  	
376  	  typedef ArgFormatterBase<PrintfArgFormatter<Char>, Char> Base;
377  	
378  	 public:
379  	  PrintfArgFormatter(BasicWriter<Char> &w, FormatSpec &s)
380  	  : ArgFormatterBase<PrintfArgFormatter<Char>, Char>(w, s) {}
381  	
382  	  void visit_bool(bool value) {
383  	    FormatSpec &fmt_spec = this->spec();
384  	    if (fmt_spec.type_ != 's')
385  	      return this->visit_any_int(value);
386  	    fmt_spec.type_ = 0;
387  	    this->write(value);
388  	  }
389  	
390  	  void visit_char(int value) {
391  	    const FormatSpec &fmt_spec = this->spec();
392  	    BasicWriter<Char> &w = this->writer();
393  	    if (fmt_spec.type_ && fmt_spec.type_ != 'c')
394  	      w.write_int(value, fmt_spec);
395  	    typedef typename BasicWriter<Char>::CharPtr CharPtr;
396  	    CharPtr out = CharPtr();
397  	    if (fmt_spec.width_ > 1) {
398  	      Char fill = ' ';
399  	      out = w.grow_buffer(fmt_spec.width_);
400  	      if (fmt_spec.align_ != ALIGN_LEFT) {
401  	        std::fill_n(out, fmt_spec.width_ - 1, fill);
402  	        out += fmt_spec.width_ - 1;
403  	      } else {
404  	        std::fill_n(out + 1, fmt_spec.width_ - 1, fill);
405  	      }
406  	    } else {
407  	      out = w.grow_buffer(1);
408  	    }
409  	    *out = static_cast<Char>(value);
410  	  }
411  	
412  	  void visit_cstring(const char *value) {
413  	    if (value)
414  	      Base::visit_cstring(value);
415  	    else if (this->spec().type_ == 'p')
416  	      write_null_pointer();
417  	    else
418  	      this->write("(null)");
419  	  }
420  	
421  	  void visit_pointer(const void *value) {
422  	    if (value)
423  	      return Base::visit_pointer(value);
424  	    this->spec().type_ = 0;
425  	    write_null_pointer();
426  	  }
427  	
428  	  void visit_custom(Arg::CustomValue c) {
429  	    BasicFormatter<Char> formatter(ArgList(), this->writer());
430  	    const Char format_str[] = {'}', 0};
431  	    const Char *format = format_str;
432  	    c.format(&formatter, c.value, &format);
433  	  }
434  	};
435  	}  // namespace internal
436  	}  // namespace fmt
437  	
438  	FMT_FUNC void fmt::SystemError::init(
439  	    int err_code, CStringRef format_str, ArgList args) {
440  	  error_code_ = err_code;
441  	  MemoryWriter w;
442  	  internal::format_system_error(w, err_code, format(format_str, args));
443  	  std::runtime_error &base = *this;
444  	  base = std::runtime_error(w.str());
445  	}
446  	
447  	template <typename T>
448  	int fmt::internal::CharTraits<char>::format_float(
449  	    char *buffer, std::size_t size, const char *format,
450  	    unsigned width, int precision, T value) {
451  	  if (width == 0) {
452  	    return precision < 0 ?
453  	        FMT_SNPRINTF(buffer, size, format, value) :
454  	        FMT_SNPRINTF(buffer, size, format, precision, value);
455  	  }
456  	  return precision < 0 ?
457  	      FMT_SNPRINTF(buffer, size, format, width, value) :
458  	      FMT_SNPRINTF(buffer, size, format, width, precision, value);
459  	}
460  	
461  	template <typename T>
462  	int fmt::internal::CharTraits<wchar_t>::format_float(
463  	    wchar_t *buffer, std::size_t size, const wchar_t *format,
464  	    unsigned width, int precision, T value) {
465  	  if (width == 0) {
466  	    return precision < 0 ?
467  	        FMT_SWPRINTF(buffer, size, format, value) :
468  	        FMT_SWPRINTF(buffer, size, format, precision, value);
469  	  }
470  	  return precision < 0 ?
471  	      FMT_SWPRINTF(buffer, size, format, width, value) :
472  	      FMT_SWPRINTF(buffer, size, format, width, precision, value);
473  	}
474  	
475  	template <typename T>
476  	const char fmt::internal::BasicData<T>::DIGITS[] =
477  	    "0001020304050607080910111213141516171819"
478  	    "2021222324252627282930313233343536373839"
479  	    "4041424344454647484950515253545556575859"
480  	    "6061626364656667686970717273747576777879"
481  	    "8081828384858687888990919293949596979899";
482  	
483  	#define FMT_POWERS_OF_10(factor) \
484  	  factor * 10, \
485  	  factor * 100, \
486  	  factor * 1000, \
487  	  factor * 10000, \
488  	  factor * 100000, \
489  	  factor * 1000000, \
490  	  factor * 10000000, \
491  	  factor * 100000000, \
492  	  factor * 1000000000
493  	
494  	template <typename T>
495  	const uint32_t fmt::internal::BasicData<T>::POWERS_OF_10_32[] = {
496  	  0, FMT_POWERS_OF_10(1)
497  	};
498  	
499  	template <typename T>
500  	const uint64_t fmt::internal::BasicData<T>::POWERS_OF_10_64[] = {
501  	  0,
502  	  FMT_POWERS_OF_10(1),
503  	  FMT_POWERS_OF_10(fmt::ULongLong(1000000000)),
504  	  // Multiply several constants instead of using a single long long constant
505  	  // to avoid warnings about C++98 not supporting long long.
506  	  fmt::ULongLong(1000000000) * fmt::ULongLong(1000000000) * 10
507  	};
508  	
509  	FMT_FUNC void fmt::internal::report_unknown_type(char code, const char *type) {
510  	  (void)type;
511  	  if (std::isprint(static_cast<unsigned char>(code))) {
512  	    FMT_THROW(fmt::FormatError(
513  	        fmt::format("unknown format code '{}' for {}", code, type)));
514  	  }
515  	  FMT_THROW(fmt::FormatError(
516  	      fmt::format("unknown format code '\\x{:02x}' for {}",
517  	        static_cast<unsigned>(code), type)));
518  	}
519  	
520  	#if FMT_USE_WINDOWS_H
521  	
522  	FMT_FUNC fmt::internal::UTF8ToUTF16::UTF8ToUTF16(fmt::StringRef s) {
523  	  static const char ERROR_MSG[] = "cannot convert string from UTF-8 to UTF-16";
524  	  if (s.size() > INT_MAX)
525  	    FMT_THROW(WindowsError(ERROR_INVALID_PARAMETER, ERROR_MSG));
526  	  int s_size = static_cast<int>(s.size());
527  	  int length = MultiByteToWideChar(
528  	      CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), s_size, 0, 0);
529  	  if (length == 0)
530  	    FMT_THROW(WindowsError(GetLastError(), ERROR_MSG));
531  	  buffer_.resize(length + 1);
532  	  length = MultiByteToWideChar(
533  	    CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), s_size, &buffer_[0], length);
534  	  if (length == 0)
535  	    FMT_THROW(WindowsError(GetLastError(), ERROR_MSG));
536  	  buffer_[length] = 0;
537  	}
538  	
539  	FMT_FUNC fmt::internal::UTF16ToUTF8::UTF16ToUTF8(fmt::WStringRef s) {
540  	  if (int error_code = convert(s)) {
541  	    FMT_THROW(WindowsError(error_code,
542  	        "cannot convert string from UTF-16 to UTF-8"));
543  	  }
544  	}
545  	
546  	FMT_FUNC int fmt::internal::UTF16ToUTF8::convert(fmt::WStringRef s) {
547  	  if (s.size() > INT_MAX)
548  	    return ERROR_INVALID_PARAMETER;
549  	  int s_size = static_cast<int>(s.size());
550  	  int length = WideCharToMultiByte(CP_UTF8, 0, s.data(), s_size, 0, 0, 0, 0);
551  	  if (length == 0)
552  	    return GetLastError();
553  	  buffer_.resize(length + 1);
554  	  length = WideCharToMultiByte(
555  	    CP_UTF8, 0, s.data(), s_size, &buffer_[0], length, 0, 0);
556  	  if (length == 0)
557  	    return GetLastError();
558  	  buffer_[length] = 0;
559  	  return 0;
560  	}
561  	
562  	FMT_FUNC void fmt::WindowsError::init(
563  	    int err_code, CStringRef format_str, ArgList args) {
564  	  error_code_ = err_code;
565  	  MemoryWriter w;
566  	  internal::format_windows_error(w, err_code, format(format_str, args));
567  	  std::runtime_error &base = *this;
568  	  base = std::runtime_error(w.str());
569  	}
570  	
571  	FMT_FUNC void fmt::internal::format_windows_error(
572  	    fmt::Writer &out, int error_code,
573  	    fmt::StringRef message) FMT_NOEXCEPT {
574  	  FMT_TRY {
575  	    MemoryBuffer<wchar_t, INLINE_BUFFER_SIZE> buffer;
576  	    buffer.resize(INLINE_BUFFER_SIZE);
577  	    for (;;) {
578  	      wchar_t *system_message = &buffer[0];
579  	      int result = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
580  	                                  0, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
581  	                                  system_message, static_cast<uint32_t>(buffer.size()), 0);
582  	      if (result != 0) {
583  	        UTF16ToUTF8 utf8_message;
584  	        if (utf8_message.convert(system_message) == ERROR_SUCCESS) {
585  	          out << message << ": " << utf8_message;
586  	          return;
587  	        }
588  	        break;
589  	      }
590  	      if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
591  	        break;  // Can't get error message, report error code instead.
592  	      buffer.resize(buffer.size() * 2);
593  	    }
594  	  } FMT_CATCH(...) {}
595  	  fmt::format_error_code(out, error_code, message);  // 'fmt::' is for bcc32.
596  	}
597  	
598  	#endif  // FMT_USE_WINDOWS_H
599  	
600  	FMT_FUNC void fmt::internal::format_system_error(
601  	    fmt::Writer &out, int error_code,
602  	    fmt::StringRef message) FMT_NOEXCEPT {
603  	  FMT_TRY {
604  	    MemoryBuffer<char, INLINE_BUFFER_SIZE> buffer;
605  	    buffer.resize(INLINE_BUFFER_SIZE);
606  	    for (;;) {
607  	      char *system_message = &buffer[0];
608  	      int result = safe_strerror(error_code, system_message, buffer.size());
609  	      if (result == 0) {
610  	        out << message << ": " << system_message;
611  	        return;
612  	      }
613  	      if (result != ERANGE)
614  	        break;  // Can't get error message, report error code instead.
615  	      buffer.resize(buffer.size() * 2);
616  	    }
617  	  } FMT_CATCH(...) {}
618  	  fmt::format_error_code(out, error_code, message);  // 'fmt::' is for bcc32.
619  	}
620  	
621  	template <typename Char>
622  	void fmt::internal::ArgMap<Char>::init(const ArgList &args) {
623  	  if (!map_.empty())
624  	    return;
625  	  typedef internal::NamedArg<Char> NamedArg;
626  	  const NamedArg *named_arg = 0;
627  	  bool use_values =
628  	      args.type(ArgList::MAX_PACKED_ARGS - 1) == internal::Arg::NONE;
629  	  if (use_values) {
630  	    for (unsigned i = 0;/*nothing*/; ++i) {
631  	      internal::Arg::Type arg_type = args.type(i);
632  	      switch (arg_type) {
633  	      case internal::Arg::NONE:
634  	        return;
635  	      case internal::Arg::NAMED_ARG:
636  	        named_arg = static_cast<const NamedArg*>(args.values_[i].pointer);
637  	        map_.push_back(Pair(named_arg->name, *named_arg));
638  	        break;
639  	      default:
640  	        /*nothing*/;
641  	      }
642  	    }
643  	    return;
644  	  }
645  	  for (unsigned i = 0; i != ArgList::MAX_PACKED_ARGS; ++i) {
646  	    internal::Arg::Type arg_type = args.type(i);
647  	    if (arg_type == internal::Arg::NAMED_ARG) {
648  	      named_arg = static_cast<const NamedArg*>(args.args_[i].pointer);
649  	      map_.push_back(Pair(named_arg->name, *named_arg));
650  	    }
651  	  }
652  	  for (unsigned i = ArgList::MAX_PACKED_ARGS;/*nothing*/; ++i) {
653  	    switch (args.args_[i].type) {
654  	    case internal::Arg::NONE:
655  	      return;
656  	    case internal::Arg::NAMED_ARG:
657  	      named_arg = static_cast<const NamedArg*>(args.args_[i].pointer);
658  	      map_.push_back(Pair(named_arg->name, *named_arg));
659  	      break;
660  	    default:
661  	      /*nothing*/;
662  	    }
663  	  }
664  	}
665  	
666  	template <typename Char>
667  	void fmt::internal::FixedBuffer<Char>::grow(std::size_t) {
668  	  FMT_THROW(std::runtime_error("buffer overflow"));
669  	}
670  	
671  	FMT_FUNC Arg fmt::internal::FormatterBase::do_get_arg(
672  	    unsigned arg_index, const char *&error) {
673  	  Arg arg = args_[arg_index];
674  	  switch (arg.type) {
675  	  case Arg::NONE:
676  	    error = "argument index out of range";
677  	    break;
678  	  case Arg::NAMED_ARG:
679  	    arg = *static_cast<const internal::Arg*>(arg.pointer);
680  	    break;
681  	  default:
682  	    /*nothing*/;
683  	  }
684  	  return arg;
685  	}
686  	
687  	template <typename Char>
688  	void fmt::internal::PrintfFormatter<Char>::parse_flags(
689  	    FormatSpec &spec, const Char *&s) {
690  	  for (;;) {
(1) Event switch_selector_expr_is_constant: selector expression is constant
(2) Event caretline: ^
Also see events: [template_instantiation_context][template_instantiation_context]
691  	    switch (*s++) {
692  	      case '-':
693  	        spec.align_ = ALIGN_LEFT;
694  	        break;
695  	      case '+':
696  	        spec.flags_ |= SIGN_FLAG | PLUS_FLAG;
697  	        break;
698  	      case '0':
699  	        spec.fill_ = '0';
700  	        break;
701  	      case ' ':
702  	        spec.flags_ |= SIGN_FLAG;
703  	        break;
704  	      case '#':
705  	        spec.flags_ |= HASH_FLAG;
706  	        break;
707  	      default:
708  	        --s;
709  	        return;
710  	    }
711  	  }
712  	}
713  	
714  	template <typename Char>
715  	Arg fmt::internal::PrintfFormatter<Char>::get_arg(
716  	    const Char *s, unsigned arg_index) {
717  	  (void)s;
718  	  const char *error = 0;
719  	  Arg arg = arg_index == UINT_MAX ?
720  	    next_arg(error) : FormatterBase::get_arg(arg_index - 1, error);
721  	  if (error)
722  	    FMT_THROW(FormatError(!*s ? "invalid format string" : error));
723  	  return arg;
724  	}
725  	
726  	template <typename Char>
727  	unsigned fmt::internal::PrintfFormatter<Char>::parse_header(
728  	  const Char *&s, FormatSpec &spec) {
729  	  unsigned arg_index = UINT_MAX;
730  	  Char c = *s;
731  	  if (c >= '0' && c <= '9') {
732  	    // Parse an argument index (if followed by '$') or a width possibly
733  	    // preceded with '0' flag(s).
734  	    unsigned value = parse_nonnegative_int(s);
735  	    if (*s == '$') {  // value is an argument index
736  	      ++s;
737  	      arg_index = value;
738  	    } else {
739  	      if (c == '0')
740  	        spec.fill_ = '0';
741  	      if (value != 0) {
742  	        // Nonzero value means that we parsed width and don't need to
743  	        // parse it or flags again, so return now.
744  	        spec.width_ = value;
745  	        return arg_index;
746  	      }
747  	    }
748  	  }
749  	  parse_flags(spec, s);
750  	  // Parse width.
751  	  if (*s >= '0' && *s <= '9') {
752  	    spec.width_ = parse_nonnegative_int(s);
753  	  } else if (*s == '*') {
754  	    ++s;
755  	    spec.width_ = WidthHandler(spec).visit(get_arg(s));
756  	  }
757  	  return arg_index;
758  	}
759  	
760  	template <typename Char>
761  	void fmt::internal::PrintfFormatter<Char>::format(
762  	    BasicWriter<Char> &writer, BasicCStringRef<Char> format_str) {
763  	  const Char *start = format_str.c_str();
764  	  const Char *s = start;
765  	  while (*s) {
766  	    Char c = *s++;
767  	    if (c != '%') continue;
768  	    if (*s == c) {
769  	      write(writer, start, s);
770  	      start = ++s;
771  	      continue;
772  	    }
773  	    write(writer, start, s - 1);
774  	
775  	    FormatSpec spec;
776  	    spec.align_ = ALIGN_RIGHT;
777  	
778  	    // Parse argument index, flags and width.
(3) Event template_instantiation_context: instantiation of "unsigned int fmt::internal::PrintfFormatter<Char>::parse_header(const Char *&, fmt::FormatSpec &) [with Char=char]" at line 779
Also see events: [switch_selector_expr_is_constant][caretline][template_instantiation_context]
779  	    unsigned arg_index = parse_header(s, spec);
780  	
781  	    // Parse precision.
782  	    if (*s == '.') {
783  	      ++s;
784  	      if ('0' <= *s && *s <= '9') {
785  	        spec.precision_ = static_cast<int>(parse_nonnegative_int(s));
786  	      } else if (*s == '*') {
787  	        ++s;
788  	        spec.precision_ = PrecisionHandler().visit(get_arg(s));
789  	      }
790  	    }
791  	
792  	    Arg arg = get_arg(s, arg_index);
793  	    if (spec.flag(HASH_FLAG) && IsZeroInt().visit(arg))
794  	      spec.flags_ &= ~to_unsigned<int>(HASH_FLAG);
795  	    if (spec.fill_ == '0') {
796  	      if (arg.type <= Arg::LAST_NUMERIC_TYPE)
797  	        spec.align_ = ALIGN_NUMERIC;
798  	      else
799  	        spec.fill_ = ' ';  // Ignore '0' flag for non-numeric types.
800  	    }
801  	
802  	    // Parse length and convert the argument to the required type.
803  	    switch (*s++) {
804  	    case 'h':
805  	      if (*s == 'h')
806  	        ArgConverter<signed char>(arg, *++s).visit(arg);
807  	      else
808  	        ArgConverter<short>(arg, *s).visit(arg);
809  	      break;
810  	    case 'l':
811  	      if (*s == 'l')
812  	        ArgConverter<fmt::LongLong>(arg, *++s).visit(arg);
813  	      else
814  	        ArgConverter<long>(arg, *s).visit(arg);
815  	      break;
816  	    case 'j':
817  	      ArgConverter<intmax_t>(arg, *s).visit(arg);
818  	      break;
819  	    case 'z':
820  	      ArgConverter<std::size_t>(arg, *s).visit(arg);
821  	      break;
822  	    case 't':
823  	      ArgConverter<std::ptrdiff_t>(arg, *s).visit(arg);
824  	      break;
825  	    case 'L':
826  	      // printf produces garbage when 'L' is omitted for long double, no
827  	      // need to do the same.
828  	      break;
829  	    default:
830  	      --s;
831  	      ArgConverter<void>(arg, *s).visit(arg);
832  	    }
833  	
834  	    // Parse type.
835  	    if (!*s)
836  	      FMT_THROW(FormatError("invalid format string"));
837  	    spec.type_ = static_cast<char>(*s++);
838  	    if (arg.type <= Arg::LAST_INTEGER_TYPE) {
839  	      // Normalize type.
840  	      switch (spec.type_) {
841  	      case 'i': case 'u':
842  	        spec.type_ = 'd';
843  	        break;
844  	      case 'c':
845  	        // TODO: handle wchar_t
846  	        CharConverter(arg).visit(arg);
847  	        break;
848  	      }
849  	    }
850  	
851  	    start = s;
852  	
853  	    // Format argument.
854  	    internal::PrintfArgFormatter<Char>(writer, spec).visit(arg);
855  	  }
856  	  write(writer, start, s);
857  	}
858  	
859  	FMT_FUNC void fmt::report_system_error(
860  	    int error_code, fmt::StringRef message) FMT_NOEXCEPT {
861  	  // 'fmt::' is for bcc32.
862  	  fmt::report_error(internal::format_system_error, error_code, message);
863  	}
864  	
865  	#if FMT_USE_WINDOWS_H
866  	FMT_FUNC void fmt::report_windows_error(
867  	    int error_code, fmt::StringRef message) FMT_NOEXCEPT {
868  	  // 'fmt::' is for bcc32.
869  	  fmt::report_error(internal::format_windows_error, error_code, message);
870  	}
871  	#endif
872  	
873  	FMT_FUNC void fmt::print(std::FILE *f, CStringRef format_str, ArgList args) {
874  	  MemoryWriter w;
875  	  w.write(format_str, args);
876  	  std::fwrite(w.data(), 1, w.size(), f);
877  	}
878  	
879  	FMT_FUNC void fmt::print(CStringRef format_str, ArgList args) {
880  	  print(stdout, format_str, args);
881  	}
882  	
883  	FMT_FUNC void fmt::print_colored(Color c, CStringRef format, ArgList args) {
884  	  char escape[] = "\x1b[30m";
885  	  escape[3] = static_cast<char>('0' + c);
886  	  std::fputs(escape, stdout);
887  	  print(format, args);
888  	  std::fputs(RESET_COLOR, stdout);
889  	}
890  	
891  	FMT_FUNC int fmt::fprintf(std::FILE *f, CStringRef format, ArgList args) {
892  	  MemoryWriter w;
893  	  printf(w, format, args);
894  	  std::size_t size = w.size();
895  	  return std::fwrite(w.data(), 1, size, f) < size ? -1 : static_cast<int>(size);
896  	}
897  	
898  	#ifndef FMT_HEADER_ONLY
899  	
900  	template struct fmt::internal::BasicData<void>;
901  	
902  	// Explicit instantiations for char.
903  	
904  	template void fmt::internal::FixedBuffer<char>::grow(std::size_t);
905  	
906  	template void fmt::internal::ArgMap<char>::init(const fmt::ArgList &args);
907  	
908  	template void fmt::internal::PrintfFormatter<char>::format(
909  	  BasicWriter<char> &writer, CStringRef format);
910  	
911  	template int fmt::internal::CharTraits<char>::format_float(
912  	    char *buffer, std::size_t size, const char *format,
913  	    unsigned width, int precision, double value);
914  	
915  	template int fmt::internal::CharTraits<char>::format_float(
916  	    char *buffer, std::size_t size, const char *format,
917  	    unsigned width, int precision, long double value);
918  	
919  	// Explicit instantiations for wchar_t.
920  	
921  	template void fmt::internal::FixedBuffer<wchar_t>::grow(std::size_t);
922  	
923  	template void fmt::internal::ArgMap<wchar_t>::init(const fmt::ArgList &args);
924  	
925  	template void fmt::internal::PrintfFormatter<wchar_t>::format(
926  	    BasicWriter<wchar_t> &writer, WCStringRef format);
927  	
928  	template int fmt::internal::CharTraits<wchar_t>::format_float(
929  	    wchar_t *buffer, std::size_t size, const wchar_t *format,
930  	    unsigned width, int precision, double value);
931  	
932  	template int fmt::internal::CharTraits<wchar_t>::format_float(
933  	    wchar_t *buffer, std::size_t size, const wchar_t *format,
934  	    unsigned width, int precision, long double value);
935  	
936  	#endif  // FMT_HEADER_ONLY
937  	
938  	#ifdef _MSC_VER
939  	# pragma warning(pop)
940  	#endif
941