1 /* 2 Formatting library for C++ 3 4 Copyright (c) 2012 - 2016, Victor Zverovich 5 All rights reserved. 6 7 For the license information refer to format.h. 8 */ 9 10 #ifndef FMT_PRINTF_H_ 11 #define FMT_PRINTF_H_ 12 13 #include <algorithm> // std::fill_n 14 #include <limits> // std::numeric_limits 15 16 #include "ostream.h" 17 18 namespace fmt { 19 namespace internal { 20 21 // Checks if a value fits in int - used to avoid warnings about comparing 22 // signed and unsigned integers. 23 template <bool IsSigned> 24 struct IntChecker { 25 template <typename T> fits_in_intIntChecker26 static bool fits_in_int(T value) { 27 unsigned max = std::numeric_limits<int>::max(); 28 return value <= max; 29 } fits_in_intIntChecker30 static bool fits_in_int(bool) { return true; } 31 }; 32 33 template <> 34 struct IntChecker<true> { 35 template <typename T> 36 static bool fits_in_int(T value) { 37 return value >= std::numeric_limits<int>::min() && 38 value <= std::numeric_limits<int>::max(); 39 } 40 static bool fits_in_int(int) { return true; } 41 }; 42 43 class PrecisionHandler : public ArgVisitor<PrecisionHandler, int> { 44 public: 45 void report_unhandled_arg() { 46 FMT_THROW(FormatError("precision is not integer")); 47 } 48 49 template <typename T> 50 int visit_any_int(T value) { 51 if (!IntChecker<std::numeric_limits<T>::is_signed>::fits_in_int(value)) 52 FMT_THROW(FormatError("number is too big")); 53 return static_cast<int>(value); 54 } 55 }; 56 57 // IsZeroInt::visit(arg) returns true iff arg is a zero integer. 58 class IsZeroInt : public ArgVisitor<IsZeroInt, bool> { 59 public: 60 template <typename T> 61 bool visit_any_int(T value) { return value == 0; } 62 }; 63 64 template <typename T, typename U> 65 struct is_same { 66 enum { value = 0 }; 67 }; 68 69 template <typename T> 70 struct is_same<T, T> { 71 enum { value = 1 }; 72 }; 73 74 // An argument visitor that converts an integer argument to T for printf, 75 // if T is an integral type. If T is void, the argument is converted to 76 // corresponding signed or unsigned type depending on the type specifier: 77 // 'd' and 'i' - signed, other - unsigned) 78 template <typename T = void> 79 class ArgConverter : public ArgVisitor<ArgConverter<T>, void> { 80 private: 81 internal::Arg &arg_; 82 wchar_t type_; 83 84 FMT_DISALLOW_COPY_AND_ASSIGN(ArgConverter); 85 86 public: 87 ArgConverter(internal::Arg &arg, wchar_t type) 88 : arg_(arg), type_(type) {} 89 90 void visit_bool(bool value) { 91 if (type_ != 's') 92 visit_any_int(value); 93 } 94 95 template <typename U> 96 void visit_any_int(U value) { 97 bool is_signed = type_ == 'd' || type_ == 'i'; 98 using internal::Arg; 99 typedef typename internal::Conditional< 100 is_same<T, void>::value, U, T>::type TargetType; 101 if (sizeof(TargetType) <= sizeof(int)) { 102 // Extra casts are used to silence warnings. 103 if (is_signed) { 104 arg_.type = Arg::INT; 105 arg_.int_value = static_cast<int>(static_cast<TargetType>(value)); 106 } else { 107 arg_.type = Arg::UINT; 108 typedef typename internal::MakeUnsigned<TargetType>::Type Unsigned; 109 arg_.uint_value = static_cast<unsigned>(static_cast<Unsigned>(value)); 110 } 111 } else { 112 if (is_signed) { 113 arg_.type = Arg::LONG_LONG; 114 // glibc's printf doesn't sign extend arguments of smaller types: 115 // std::printf("%lld", -42); // prints "4294967254" 116 // but we don't have to do the same because it's a UB. 117 arg_.long_long_value = static_cast<LongLong>(value); 118 } else { 119 arg_.type = Arg::ULONG_LONG; 120 arg_.ulong_long_value = 121 static_cast<typename internal::MakeUnsigned<U>::Type>(value); 122 } 123 } 124 } 125 }; 126 127 // Converts an integer argument to char for printf. 128 class CharConverter : public ArgVisitor<CharConverter, void> { 129 private: 130 internal::Arg &arg_; 131 132 FMT_DISALLOW_COPY_AND_ASSIGN(CharConverter); 133 134 public: 135 explicit CharConverter(internal::Arg &arg) : arg_(arg) {} 136 137 template <typename T> 138 void visit_any_int(T value) { 139 arg_.type = internal::Arg::CHAR; 140 arg_.int_value = static_cast<char>(value); 141 } 142 }; 143 144 // Checks if an argument is a valid printf width specifier and sets 145 // left alignment if it is negative. 146 class WidthHandler : public ArgVisitor<WidthHandler, unsigned> { 147 private: 148 FormatSpec &spec_; 149 150 FMT_DISALLOW_COPY_AND_ASSIGN(WidthHandler); 151 152 public: 153 explicit WidthHandler(FormatSpec &spec) : spec_(spec) {} 154 155 void report_unhandled_arg() { 156 FMT_THROW(FormatError("width is not integer")); 157 } 158 159 template <typename T> 160 unsigned visit_any_int(T value) { 161 typedef typename internal::IntTraits<T>::MainType UnsignedType; 162 UnsignedType width = static_cast<UnsignedType>(value); 163 if (internal::is_negative(value)) { 164 spec_.align_ = ALIGN_LEFT; 165 width = 0 - width; 166 } 167 unsigned int_max = std::numeric_limits<int>::max(); 168 if (width > int_max) 169 FMT_THROW(FormatError("number is too big")); 170 return static_cast<unsigned>(width); 171 } 172 }; 173 } // namespace internal 174 175 /** 176 \rst 177 A ``printf`` argument formatter based on the `curiously recurring template 178 pattern <http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern>`_. 179 180 To use `~fmt::BasicPrintfArgFormatter` define a subclass that implements some 181 or all of the visit methods with the same signatures as the methods in 182 `~fmt::ArgVisitor`, for example, `~fmt::ArgVisitor::visit_int()`. 183 Pass the subclass as the *Impl* template parameter. When a formatting 184 function processes an argument, it will dispatch to a visit method 185 specific to the argument type. For example, if the argument type is 186 ``double`` then the `~fmt::ArgVisitor::visit_double()` method of a subclass 187 will be called. If the subclass doesn't contain a method with this signature, 188 then a corresponding method of `~fmt::BasicPrintfArgFormatter` or its 189 superclass will be called. 190 \endrst 191 */ 192 template <typename Impl, typename Char> 193 class BasicPrintfArgFormatter : public internal::ArgFormatterBase<Impl, Char> { 194 private: 195 void write_null_pointer() { 196 this->spec().type_ = 0; 197 this->write("(nil)"); 198 } 199 200 typedef internal::ArgFormatterBase<Impl, Char> Base; 201 202 public: 203 /** 204 \rst 205 Constructs an argument formatter object. 206 *writer* is a reference to the output writer and *spec* contains format 207 specifier information for standard argument types. 208 \endrst 209 */ 210 BasicPrintfArgFormatter(BasicWriter<Char> &w, FormatSpec &s) 211 : internal::ArgFormatterBase<Impl, Char>(w, s) {} 212 213 /** Formats an argument of type ``bool``. */ 214 void visit_bool(bool value) { 215 FormatSpec &fmt_spec = this->spec(); 216 if (fmt_spec.type_ != 's') 217 return this->visit_any_int(value); 218 fmt_spec.type_ = 0; 219 this->write(value); 220 } 221 222 /** Formats a character. */ 223 void visit_char(int value) { 224 const FormatSpec &fmt_spec = this->spec(); 225 BasicWriter<Char> &w = this->writer(); 226 if (fmt_spec.type_ && fmt_spec.type_ != 'c') 227 w.write_int(value, fmt_spec); 228 typedef typename BasicWriter<Char>::CharPtr CharPtr; 229 CharPtr out = CharPtr(); 230 if (fmt_spec.width_ > 1) { 231 Char fill = ' '; 232 out = w.grow_buffer(fmt_spec.width_); 233 if (fmt_spec.align_ != ALIGN_LEFT) { 234 std::fill_n(out, fmt_spec.width_ - 1, fill); 235 out += fmt_spec.width_ - 1; 236 } else { 237 std::fill_n(out + 1, fmt_spec.width_ - 1, fill); 238 } 239 } else { 240 out = w.grow_buffer(1); 241 } 242 *out = static_cast<Char>(value); 243 } 244 245 /** Formats a null-terminated C string. */ 246 void visit_cstring(const char *value) { 247 if (value) 248 Base::visit_cstring(value); 249 else if (this->spec().type_ == 'p') 250 write_null_pointer(); 251 else 252 this->write("(null)"); 253 } 254 255 /** Formats a pointer. */ 256 void visit_pointer(const void *value) { 257 if (value) 258 return Base::visit_pointer(value); 259 this->spec().type_ = 0; 260 write_null_pointer(); 261 } 262 263 /** Formats an argument of a custom (user-defined) type. */ 264 void visit_custom(internal::Arg::CustomValue c) { 265 BasicFormatter<Char> formatter(ArgList(), this->writer()); 266 const Char format_str[] = {'}', 0}; 267 const Char *format = format_str; 268 c.format(&formatter, c.value, &format); 269 } 270 }; 271 272 /** The default printf argument formatter. */ 273 template <typename Char> 274 class PrintfArgFormatter 275 : public BasicPrintfArgFormatter<PrintfArgFormatter<Char>, Char> { 276 public: 277 /** Constructs an argument formatter object. */ 278 PrintfArgFormatter(BasicWriter<Char> &w, FormatSpec &s) 279 : BasicPrintfArgFormatter<PrintfArgFormatter<Char>, Char>(w, s) {} 280 }; 281 282 /** This template formats data and writes the output to a writer. */ 283 template <typename Char, typename ArgFormatter = PrintfArgFormatter<Char> > 284 class PrintfFormatter : private internal::FormatterBase { 285 private: 286 BasicWriter<Char> &writer_; 287 288 void parse_flags(FormatSpec &spec, const Char *&s); 289 290 // Returns the argument with specified index or, if arg_index is equal 291 // to the maximum unsigned value, the next argument. 292 internal::Arg get_arg( 293 const Char *s, 294 unsigned arg_index = (std::numeric_limits<unsigned>::max)()); 295 296 // Parses argument index, flags and width and returns the argument index. 297 unsigned parse_header(const Char *&s, FormatSpec &spec); 298 299 public: 300 /** 301 \rst 302 Constructs a ``PrintfFormatter`` object. References to the arguments and 303 the writer are stored in the formatter object so make sure they have 304 appropriate lifetimes. 305 \endrst 306 */ 307 explicit PrintfFormatter(const ArgList &al, BasicWriter<Char> &w) 308 : FormatterBase(al), writer_(w) {} 309 310 /** Formats stored arguments and writes the output to the writer. */ 311 FMT_API void format(BasicCStringRef<Char> format_str); 312 }; 313 314 template <typename Char, typename AF> 315 void PrintfFormatter<Char, AF>::parse_flags(FormatSpec &spec, const Char *&s) { 316 for (;;) { 317 switch (*s++) { 318 case '-': 319 spec.align_ = ALIGN_LEFT; 320 break; 321 case '+': 322 spec.flags_ |= SIGN_FLAG | PLUS_FLAG; 323 break; 324 case '0': 325 spec.fill_ = '0'; 326 break; 327 case ' ': 328 spec.flags_ |= SIGN_FLAG; 329 break; 330 case '#': 331 spec.flags_ |= HASH_FLAG; 332 break; 333 default: 334 --s; 335 return; 336 } 337 } 338 } 339 340 template <typename Char, typename AF> 341 internal::Arg PrintfFormatter<Char, AF>::get_arg(const Char *s, 342 unsigned arg_index) { 343 (void)s; 344 const char *error = FMT_NULL; 345 internal::Arg arg = arg_index == std::numeric_limits<unsigned>::max() ? 346 next_arg(error) : FormatterBase::get_arg(arg_index - 1, error); 347 if (error) 348 FMT_THROW(FormatError(!*s ? "invalid format string" : error)); 349 return arg; 350 } 351 352 template <typename Char, typename AF> 353 unsigned PrintfFormatter<Char, AF>::parse_header( 354 const Char *&s, FormatSpec &spec) { 355 unsigned arg_index = std::numeric_limits<unsigned>::max(); 356 Char c = *s; 357 if (c >= '0' && c <= '9') { 358 // Parse an argument index (if followed by '$') or a width possibly 359 // preceded with '0' flag(s). 360 unsigned value = internal::parse_nonnegative_int(s); 361 if (*s == '$') { // value is an argument index 362 ++s; 363 arg_index = value; 364 } else { 365 if (c == '0') 366 spec.fill_ = '0'; 367 if (value != 0) { 368 // Nonzero value means that we parsed width and don't need to 369 // parse it or flags again, so return now. 370 spec.width_ = value; 371 return arg_index; 372 } 373 } 374 } 375 parse_flags(spec, s); 376 // Parse width. 377 if (*s >= '0' && *s <= '9') { 378 spec.width_ = internal::parse_nonnegative_int(s); 379 } else if (*s == '*') { 380 ++s; 381 spec.width_ = internal::WidthHandler(spec).visit(get_arg(s)); 382 } 383 return arg_index; 384 } 385 386 template <typename Char, typename AF> 387 void PrintfFormatter<Char, AF>::format(BasicCStringRef<Char> format_str) { 388 const Char *start = format_str.c_str(); 389 const Char *s = start; 390 while (*s) { 391 Char c = *s++; 392 if (c != '%') continue; 393 if (*s == c) { 394 write(writer_, start, s); 395 start = ++s; 396 continue; 397 } 398 write(writer_, start, s - 1); 399 400 FormatSpec spec; 401 spec.align_ = ALIGN_RIGHT; 402 403 // Parse argument index, flags and width. 404 unsigned arg_index = parse_header(s, spec); 405 406 // Parse precision. 407 if (*s == '.') { 408 ++s; 409 if ('0' <= *s && *s <= '9') { 410 spec.precision_ = static_cast<int>(internal::parse_nonnegative_int(s)); 411 } else if (*s == '*') { 412 ++s; 413 spec.precision_ = internal::PrecisionHandler().visit(get_arg(s)); 414 } 415 } 416 417 using internal::Arg; 418 Arg arg = get_arg(s, arg_index); 419 if (spec.flag(HASH_FLAG) && internal::IsZeroInt().visit(arg)) 420 spec.flags_ &= ~internal::to_unsigned<int>(HASH_FLAG); 421 if (spec.fill_ == '0') { 422 if (arg.type <= Arg::LAST_NUMERIC_TYPE) 423 spec.align_ = ALIGN_NUMERIC; 424 else 425 spec.fill_ = ' '; // Ignore '0' flag for non-numeric types. 426 } 427 428 // Parse length and convert the argument to the required type. 429 using internal::ArgConverter; 430 switch (*s++) { 431 case 'h': 432 if (*s == 'h') 433 ArgConverter<signed char>(arg, *++s).visit(arg); 434 else 435 ArgConverter<short>(arg, *s).visit(arg); 436 break; 437 case 'l': 438 if (*s == 'l') 439 ArgConverter<fmt::LongLong>(arg, *++s).visit(arg); 440 else 441 ArgConverter<long>(arg, *s).visit(arg); 442 break; 443 case 'j': 444 ArgConverter<intmax_t>(arg, *s).visit(arg); 445 break; 446 case 'z': 447 ArgConverter<std::size_t>(arg, *s).visit(arg); 448 break; 449 case 't': 450 ArgConverter<std::ptrdiff_t>(arg, *s).visit(arg); 451 break; 452 case 'L': 453 // printf produces garbage when 'L' is omitted for long double, no 454 // need to do the same. 455 break; 456 default: 457 --s; 458 ArgConverter<void>(arg, *s).visit(arg); 459 } 460 461 // Parse type. 462 if (!*s) 463 FMT_THROW(FormatError("invalid format string")); 464 spec.type_ = static_cast<char>(*s++); 465 if (arg.type <= Arg::LAST_INTEGER_TYPE) { 466 // Normalize type. 467 switch (spec.type_) { 468 case 'i': case 'u': 469 spec.type_ = 'd'; 470 break; 471 case 'c': 472 // TODO: handle wchar_t 473 internal::CharConverter(arg).visit(arg); 474 break; 475 } 476 } 477 478 start = s; 479 480 // Format argument. 481 AF(writer_, spec).visit(arg); 482 } 483 write(writer_, start, s); 484 } 485 486 template <typename Char> 487 void printf(BasicWriter<Char> &w, BasicCStringRef<Char> format, ArgList args) { 488 PrintfFormatter<Char>(args, w).format(format); 489 } 490 491 /** 492 \rst 493 Formats arguments and returns the result as a string. 494 495 **Example**:: 496 497 std::string message = fmt::sprintf("The answer is %d", 42); 498 \endrst 499 */ 500 inline std::string sprintf(CStringRef format, ArgList args) { 501 MemoryWriter w; 502 printf(w, format, args); 503 return w.str(); 504 } 505 FMT_VARIADIC(std::string, sprintf, CStringRef) 506 507 inline std::wstring sprintf(WCStringRef format, ArgList args) { 508 WMemoryWriter w; 509 printf(w, format, args); 510 return w.str(); 511 } 512 FMT_VARIADIC_W(std::wstring, sprintf, WCStringRef) 513 514 /** 515 \rst 516 Prints formatted data to the file *f*. 517 518 **Example**:: 519 520 fmt::fprintf(stderr, "Don't %s!", "panic"); 521 \endrst 522 */ 523 FMT_API int fprintf(std::FILE *f, CStringRef format, ArgList args); 524 FMT_VARIADIC(int, fprintf, std::FILE *, CStringRef) 525 526 /** 527 \rst 528 Prints formatted data to ``stdout``. 529 530 **Example**:: 531 532 fmt::printf("Elapsed time: %.2f seconds", 1.23); 533 \endrst 534 */ 535 inline int printf(CStringRef format, ArgList args) { 536 return fprintf(stdout, format, args); 537 } 538 FMT_VARIADIC(int, printf, CStringRef) 539 540 /** 541 \rst 542 Prints formatted data to the stream *os*. 543 544 **Example**:: 545 546 fprintf(cerr, "Don't %s!", "panic"); 547 \endrst 548 */ 549 inline int fprintf(std::ostream &os, CStringRef format_str, ArgList args) { 550 MemoryWriter w; 551 printf(w, format_str, args); 552 internal::write(os, w); 553 return static_cast<int>(w.size()); 554 } 555 FMT_VARIADIC(int, fprintf, std::ostream &, CStringRef) 556 } // namespace fmt 557 558 #ifdef FMT_HEADER_ONLY 559 # include "printf.cc" 560 #endif 561 562 #endif // FMT_PRINTF_H_ 563