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
18namespace fmt {
19namespace internal {
20
21// Checks if a value fits in int - used to avoid warnings about comparing
22// signed and unsigned integers.
23template <bool IsSigned>
24struct IntChecker {
25  template <typename T>
26  static bool fits_in_int(T value) {
27    unsigned max = std::numeric_limits<int>::max();
28    return value <= max;
29  }
30  static bool fits_in_int(bool) { return true; }
31};
32
33template <>
34struct 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
43class 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.
58class IsZeroInt : public ArgVisitor<IsZeroInt, bool> {
59 public:
60  template <typename T>
61  bool visit_any_int(T value) { return value == 0; }
62};
63
64template <typename T, typename U>
65struct is_same {
66  enum { value = 0 };
67};
68
69template <typename T>
70struct 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)
78template <typename T = void>
79class 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.
128class 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.
146class 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 */
192template <typename Impl, typename Char>
193class 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. */
273template <typename Char>
274class 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. */
283template <typename Char, typename ArgFormatter = PrintfArgFormatter<Char> >
284class 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
314template <typename Char, typename AF>
315void 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
340template <typename Char, typename AF>
341internal::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
352template <typename Char, typename AF>
353unsigned 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
386template <typename Char, typename AF>
387void 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
486template <typename Char>
487void 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*/
500inline std::string sprintf(CStringRef format, ArgList args) {
501  MemoryWriter w;
502  printf(w, format, args);
503  return w.str();
504}
505FMT_VARIADIC(std::string, sprintf, CStringRef)
506
507inline std::wstring sprintf(WCStringRef format, ArgList args) {
508  WMemoryWriter w;
509  printf(w, format, args);
510  return w.str();
511}
512FMT_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 */
523FMT_API int fprintf(std::FILE *f, CStringRef format, ArgList args);
524FMT_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 */
535inline int printf(CStringRef format, ArgList args) {
536  return fprintf(stdout, format, args);
537}
538FMT_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 */
549inline 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}
555FMT_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