1 // Formatting library for C++ - legacy printf implementation
2 //
3 // Copyright (c) 2012 - 2016, Victor Zverovich
4 // All rights reserved.
5 //
6 // For the license information refer to format.h.
7 
8 #ifndef FMT_PRINTF_H_
9 #define FMT_PRINTF_H_
10 
11 #include <algorithm>  // std::max
12 #include <limits>     // std::numeric_limits
13 
14 #include "ostream.h"
15 
16 FMT_BEGIN_NAMESPACE
17 namespace internal {
18 
19 // Checks if a value fits in int - used to avoid warnings about comparing
20 // signed and unsigned integers.
21 template <bool IsSigned> struct int_checker {
fits_in_intint_checker22   template <typename T> static bool fits_in_int(T value) {
23     unsigned max = max_value<int>();
24     return value <= max;
25   }
fits_in_intint_checker26   static bool fits_in_int(bool) { return true; }
27 };
28 
29 template <> struct int_checker<true> {
30   template <typename T> static bool fits_in_int(T value) {
31     return value >= std::numeric_limits<int>::min() &&
32            value <= max_value<int>();
33   }
34   static bool fits_in_int(int) { return true; }
35 };
36 
37 class printf_precision_handler {
38  public:
39   template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
40   int operator()(T value) {
41     if (!int_checker<std::numeric_limits<T>::is_signed>::fits_in_int(value))
42       FMT_THROW(format_error("number is too big"));
43     return (std::max)(static_cast<int>(value), 0);
44   }
45 
46   template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
47   int operator()(T) {
48     FMT_THROW(format_error("precision is not integer"));
49     return 0;
50   }
51 };
52 
53 // An argument visitor that returns true iff arg is a zero integer.
54 class is_zero_int {
55  public:
56   template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
57   bool operator()(T value) {
58     return value == 0;
59   }
60 
61   template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
62   bool operator()(T) {
63     return false;
64   }
65 };
66 
67 template <typename T> struct make_unsigned_or_bool : std::make_unsigned<T> {};
68 
69 template <> struct make_unsigned_or_bool<bool> { using type = bool; };
70 
71 template <typename T, typename Context> class arg_converter {
72  private:
73   using char_type = typename Context::char_type;
74 
75   basic_format_arg<Context>& arg_;
76   char_type type_;
77 
78  public:
79   arg_converter(basic_format_arg<Context>& arg, char_type type)
80       : arg_(arg), type_(type) {}
81 
82   void operator()(bool value) {
83     if (type_ != 's') operator()<bool>(value);
84   }
85 
86   template <typename U, FMT_ENABLE_IF(std::is_integral<U>::value)>
87   void operator()(U value) {
88     bool is_signed = type_ == 'd' || type_ == 'i';
89     using target_type = conditional_t<std::is_same<T, void>::value, U, T>;
90     if (const_check(sizeof(target_type) <= sizeof(int))) {
91       // Extra casts are used to silence warnings.
92       if (is_signed) {
93         arg_ = internal::make_arg<Context>(
94             static_cast<int>(static_cast<target_type>(value)));
95       } else {
96         using unsigned_type = typename make_unsigned_or_bool<target_type>::type;
97         arg_ = internal::make_arg<Context>(
98             static_cast<unsigned>(static_cast<unsigned_type>(value)));
99       }
100     } else {
101       if (is_signed) {
102         // glibc's printf doesn't sign extend arguments of smaller types:
103         //   std::printf("%lld", -42);  // prints "4294967254"
104         // but we don't have to do the same because it's a UB.
105         arg_ = internal::make_arg<Context>(static_cast<long long>(value));
106       } else {
107         arg_ = internal::make_arg<Context>(
108             static_cast<typename make_unsigned_or_bool<U>::type>(value));
109       }
110     }
111   }
112 
113   template <typename U, FMT_ENABLE_IF(!std::is_integral<U>::value)>
114   void operator()(U) {}  // No conversion needed for non-integral types.
115 };
116 
117 // Converts an integer argument to T for printf, if T is an integral type.
118 // If T is void, the argument is converted to corresponding signed or unsigned
119 // type depending on the type specifier: 'd' and 'i' - signed, other -
120 // unsigned).
121 template <typename T, typename Context, typename Char>
122 void convert_arg(basic_format_arg<Context>& arg, Char type) {
123   visit_format_arg(arg_converter<T, Context>(arg, type), arg);
124 }
125 
126 // Converts an integer argument to char for printf.
127 template <typename Context> class char_converter {
128  private:
129   basic_format_arg<Context>& arg_;
130 
131  public:
132   explicit char_converter(basic_format_arg<Context>& arg) : arg_(arg) {}
133 
134   template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
135   void operator()(T value) {
136     arg_ = internal::make_arg<Context>(
137         static_cast<typename Context::char_type>(value));
138   }
139 
140   template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
141   void operator()(T) {}  // No conversion needed for non-integral types.
142 };
143 
144 // Checks if an argument is a valid printf width specifier and sets
145 // left alignment if it is negative.
146 template <typename Char> class printf_width_handler {
147  private:
148   using format_specs = basic_format_specs<Char>;
149 
150   format_specs& specs_;
151 
152  public:
153   explicit printf_width_handler(format_specs& specs) : specs_(specs) {}
154 
155   template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
156   unsigned operator()(T value) {
157     auto width = static_cast<uint32_or_64_or_128_t<T>>(value);
158     if (internal::is_negative(value)) {
159       specs_.align = align::left;
160       width = 0 - width;
161     }
162     unsigned int_max = max_value<int>();
163     if (width > int_max) FMT_THROW(format_error("number is too big"));
164     return static_cast<unsigned>(width);
165   }
166 
167   template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
168   unsigned operator()(T) {
169     FMT_THROW(format_error("width is not integer"));
170     return 0;
171   }
172 };
173 
174 template <typename Char, typename Context>
175 void printf(buffer<Char>& buf, basic_string_view<Char> format,
176             basic_format_args<Context> args) {
177   Context(std::back_inserter(buf), format, args).format();
178 }
179 
180 template <typename OutputIt, typename Char, typename Context>
181 internal::truncating_iterator<OutputIt> printf(
182     internal::truncating_iterator<OutputIt> it, basic_string_view<Char> format,
183     basic_format_args<Context> args) {
184   return Context(it, format, args).format();
185 }
186 }  // namespace internal
187 
188 using internal::printf;  // For printing into memory_buffer.
189 
190 template <typename Range> class printf_arg_formatter;
191 
192 template <typename OutputIt, typename Char> class basic_printf_context;
193 
194 /**
195   \rst
196   The ``printf`` argument formatter.
197   \endrst
198  */
199 template <typename Range>
200 class printf_arg_formatter : public internal::arg_formatter_base<Range> {
201  public:
202   using iterator = typename Range::iterator;
203 
204  private:
205   using char_type = typename Range::value_type;
206   using base = internal::arg_formatter_base<Range>;
207   using context_type = basic_printf_context<iterator, char_type>;
208 
209   context_type& context_;
210 
211   void write_null_pointer(char) {
212     this->specs()->type = 0;
213     this->write("(nil)");
214   }
215 
216   void write_null_pointer(wchar_t) {
217     this->specs()->type = 0;
218     this->write(L"(nil)");
219   }
220 
221  public:
222   using format_specs = typename base::format_specs;
223 
224   /**
225     \rst
226     Constructs an argument formatter object.
227     *buffer* is a reference to the output buffer and *specs* contains format
228     specifier information for standard argument types.
229     \endrst
230    */
231   printf_arg_formatter(iterator iter, format_specs& specs, context_type& ctx)
232       : base(Range(iter), &specs, internal::locale_ref()), context_(ctx) {}
233 
234   template <typename T, FMT_ENABLE_IF(fmt::internal::is_integral<T>::value)>
235   iterator operator()(T value) {
236     // MSVC2013 fails to compile separate overloads for bool and char_type so
237     // use std::is_same instead.
238     if (std::is_same<T, bool>::value) {
239       format_specs& fmt_specs = *this->specs();
240       if (fmt_specs.type != 's') return base::operator()(value ? 1 : 0);
241       fmt_specs.type = 0;
242       this->write(value != 0);
243     } else if (std::is_same<T, char_type>::value) {
244       format_specs& fmt_specs = *this->specs();
245       if (fmt_specs.type && fmt_specs.type != 'c')
246         return (*this)(static_cast<int>(value));
247       fmt_specs.sign = sign::none;
248       fmt_specs.alt = false;
249       fmt_specs.align = align::right;
250       return base::operator()(value);
251     } else {
252       return base::operator()(value);
253     }
254     return this->out();
255   }
256 
257   template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value)>
258   iterator operator()(T value) {
259     return base::operator()(value);
260   }
261 
262   /** Formats a null-terminated C string. */
263   iterator operator()(const char* value) {
264     if (value)
265       base::operator()(value);
266     else if (this->specs()->type == 'p')
267       write_null_pointer(char_type());
268     else
269       this->write("(null)");
270     return this->out();
271   }
272 
273   /** Formats a null-terminated wide C string. */
274   iterator operator()(const wchar_t* value) {
275     if (value)
276       base::operator()(value);
277     else if (this->specs()->type == 'p')
278       write_null_pointer(char_type());
279     else
280       this->write(L"(null)");
281     return this->out();
282   }
283 
284   iterator operator()(basic_string_view<char_type> value) {
285     return base::operator()(value);
286   }
287 
288   iterator operator()(monostate value) { return base::operator()(value); }
289 
290   /** Formats a pointer. */
291   iterator operator()(const void* value) {
292     if (value) return base::operator()(value);
293     this->specs()->type = 0;
294     write_null_pointer(char_type());
295     return this->out();
296   }
297 
298   /** Formats an argument of a custom (user-defined) type. */
299   iterator operator()(typename basic_format_arg<context_type>::handle handle) {
300     handle.format(context_.parse_context(), context_);
301     return this->out();
302   }
303 };
304 
305 template <typename T> struct printf_formatter {
306   template <typename ParseContext>
307   auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
308     return ctx.begin();
309   }
310 
311   template <typename FormatContext>
312   auto format(const T& value, FormatContext& ctx) -> decltype(ctx.out()) {
313     internal::format_value(internal::get_container(ctx.out()), value);
314     return ctx.out();
315   }
316 };
317 
318 /** This template formats data and writes the output to a writer. */
319 template <typename OutputIt, typename Char> class basic_printf_context {
320  public:
321   /** The character type for the output. */
322   using char_type = Char;
323   using format_arg = basic_format_arg<basic_printf_context>;
324   template <typename T> using formatter_type = printf_formatter<T>;
325 
326  private:
327   using format_specs = basic_format_specs<char_type>;
328 
329   OutputIt out_;
330   basic_format_args<basic_printf_context> args_;
331   basic_format_parse_context<Char> parse_ctx_;
332 
333   static void parse_flags(format_specs& specs, const Char*& it,
334                           const Char* end);
335 
336   // Returns the argument with specified index or, if arg_index is -1, the next
337   // argument.
338   format_arg get_arg(int arg_index = -1);
339 
340   // Parses argument index, flags and width and returns the argument index.
341   int parse_header(const Char*& it, const Char* end, format_specs& specs);
342 
343  public:
344   /**
345    \rst
346    Constructs a ``printf_context`` object. References to the arguments and
347    the writer are stored in the context object so make sure they have
348    appropriate lifetimes.
349    \endrst
350    */
351   basic_printf_context(OutputIt out, basic_string_view<char_type> format_str,
352                        basic_format_args<basic_printf_context> args)
353       : out_(out), args_(args), parse_ctx_(format_str) {}
354 
355   OutputIt out() { return out_; }
356   void advance_to(OutputIt it) { out_ = it; }
357 
358   format_arg arg(int id) const { return args_.get(id); }
359 
360   basic_format_parse_context<Char>& parse_context() { return parse_ctx_; }
361 
362   FMT_CONSTEXPR void on_error(const char* message) {
363     parse_ctx_.on_error(message);
364   }
365 
366   /** Formats stored arguments and writes the output to the range. */
367   template <typename ArgFormatter = printf_arg_formatter<buffer_range<Char>>>
368   OutputIt format();
369 };
370 
371 template <typename OutputIt, typename Char>
372 void basic_printf_context<OutputIt, Char>::parse_flags(format_specs& specs,
373                                                        const Char*& it,
374                                                        const Char* end) {
375   for (; it != end; ++it) {
376     switch (*it) {
377     case '-':
378       specs.align = align::left;
379       break;
380     case '+':
381       specs.sign = sign::plus;
382       break;
383     case '0':
384       specs.fill[0] = '0';
385       break;
386     case ' ':
387       specs.sign = sign::space;
388       break;
389     case '#':
390       specs.alt = true;
391       break;
392     default:
393       return;
394     }
395   }
396 }
397 
398 template <typename OutputIt, typename Char>
399 typename basic_printf_context<OutputIt, Char>::format_arg
400 basic_printf_context<OutputIt, Char>::get_arg(int arg_index) {
401   if (arg_index < 0)
402     arg_index = parse_ctx_.next_arg_id();
403   else
404     parse_ctx_.check_arg_id(--arg_index);
405   return internal::get_arg(*this, arg_index);
406 }
407 
408 template <typename OutputIt, typename Char>
409 int basic_printf_context<OutputIt, Char>::parse_header(
410     const Char*& it, const Char* end, format_specs& specs) {
411   int arg_index = -1;
412   char_type c = *it;
413   if (c >= '0' && c <= '9') {
414     // Parse an argument index (if followed by '$') or a width possibly
415     // preceded with '0' flag(s).
416     internal::error_handler eh;
417     int value = parse_nonnegative_int(it, end, eh);
418     if (it != end && *it == '$') {  // value is an argument index
419       ++it;
420       arg_index = value;
421     } else {
422       if (c == '0') specs.fill[0] = '0';
423       if (value != 0) {
424         // Nonzero value means that we parsed width and don't need to
425         // parse it or flags again, so return now.
426         specs.width = value;
427         return arg_index;
428       }
429     }
430   }
431   parse_flags(specs, it, end);
432   // Parse width.
433   if (it != end) {
434     if (*it >= '0' && *it <= '9') {
435       internal::error_handler eh;
436       specs.width = parse_nonnegative_int(it, end, eh);
437     } else if (*it == '*') {
438       ++it;
439       specs.width = static_cast<int>(visit_format_arg(
440           internal::printf_width_handler<char_type>(specs), get_arg()));
441     }
442   }
443   return arg_index;
444 }
445 
446 template <typename OutputIt, typename Char>
447 template <typename ArgFormatter>
448 OutputIt basic_printf_context<OutputIt, Char>::format() {
449   auto out = this->out();
450   const Char* start = parse_ctx_.begin();
451   const Char* end = parse_ctx_.end();
452   auto it = start;
453   while (it != end) {
454     char_type c = *it++;
455     if (c != '%') continue;
456     if (it != end && *it == c) {
457       out = std::copy(start, it, out);
458       start = ++it;
459       continue;
460     }
461     out = std::copy(start, it - 1, out);
462 
463     format_specs specs;
464     specs.align = align::right;
465 
466     // Parse argument index, flags and width.
467     int arg_index = parse_header(it, end, specs);
468     if (arg_index == 0) on_error("argument index out of range");
469 
470     // Parse precision.
471     if (it != end && *it == '.') {
472       ++it;
473       c = it != end ? *it : 0;
474       if ('0' <= c && c <= '9') {
475         internal::error_handler eh;
476         specs.precision = parse_nonnegative_int(it, end, eh);
477       } else if (c == '*') {
478         ++it;
479         specs.precision =
480             static_cast<int>(visit_format_arg(internal::printf_precision_handler(), get_arg()));
481       } else {
482         specs.precision = 0;
483       }
484     }
485 
486     format_arg arg = get_arg(arg_index);
487     if (specs.alt && visit_format_arg(internal::is_zero_int(), arg))
488       specs.alt = false;
489     if (specs.fill[0] == '0') {
490       if (arg.is_arithmetic())
491         specs.align = align::numeric;
492       else
493         specs.fill[0] = ' ';  // Ignore '0' flag for non-numeric types.
494     }
495 
496     // Parse length and convert the argument to the required type.
497     c = it != end ? *it++ : 0;
498     char_type t = it != end ? *it : 0;
499     using internal::convert_arg;
500     switch (c) {
501     case 'h':
502       if (t == 'h') {
503         ++it;
504         t = it != end ? *it : 0;
505         convert_arg<signed char>(arg, t);
506       } else {
507         convert_arg<short>(arg, t);
508       }
509       break;
510     case 'l':
511       if (t == 'l') {
512         ++it;
513         t = it != end ? *it : 0;
514         convert_arg<long long>(arg, t);
515       } else {
516         convert_arg<long>(arg, t);
517       }
518       break;
519     case 'j':
520       convert_arg<intmax_t>(arg, t);
521       break;
522     case 'z':
523       convert_arg<std::size_t>(arg, t);
524       break;
525     case 't':
526       convert_arg<std::ptrdiff_t>(arg, t);
527       break;
528     case 'L':
529       // printf produces garbage when 'L' is omitted for long double, no
530       // need to do the same.
531       break;
532     default:
533       --it;
534       convert_arg<void>(arg, c);
535     }
536 
537     // Parse type.
538     if (it == end) FMT_THROW(format_error("invalid format string"));
539     specs.type = static_cast<char>(*it++);
540     if (arg.is_integral()) {
541       // Normalize type.
542       switch (specs.type) {
543       case 'i':
544       case 'u':
545         specs.type = 'd';
546         break;
547       case 'c':
548         visit_format_arg(internal::char_converter<basic_printf_context>(arg),
549                          arg);
550         break;
551       }
552     }
553 
554     start = it;
555 
556     // Format argument.
557     visit_format_arg(ArgFormatter(out, specs, *this), arg);
558   }
559   return std::copy(start, it, out);
560 }
561 
562 template <typename Char>
563 using basic_printf_context_t =
564     basic_printf_context<std::back_insert_iterator<internal::buffer<Char>>,
565                          Char>;
566 
567 using printf_context = basic_printf_context_t<char>;
568 using wprintf_context = basic_printf_context_t<wchar_t>;
569 
570 using printf_args = basic_format_args<printf_context>;
571 using wprintf_args = basic_format_args<wprintf_context>;
572 
573 /**
574   \rst
575   Constructs an `~fmt::format_arg_store` object that contains references to
576   arguments and can be implicitly converted to `~fmt::printf_args`.
577   \endrst
578  */
579 template <typename... Args>
580 inline format_arg_store<printf_context, Args...> make_printf_args(
581     const Args&... args) {
582   return {args...};
583 }
584 
585 /**
586   \rst
587   Constructs an `~fmt::format_arg_store` object that contains references to
588   arguments and can be implicitly converted to `~fmt::wprintf_args`.
589   \endrst
590  */
591 template <typename... Args>
592 inline format_arg_store<wprintf_context, Args...> make_wprintf_args(
593     const Args&... args) {
594   return {args...};
595 }
596 
597 template <typename S, typename Char = char_t<S>>
598 inline std::basic_string<Char> vsprintf(
599     const S& format, basic_format_args<basic_printf_context_t<Char>> args) {
600   basic_memory_buffer<Char> buffer;
601   printf(buffer, to_string_view(format), args);
602   return to_string(buffer);
603 }
604 
605 /**
606   \rst
607   Formats arguments and returns the result as a string.
608 
609   **Example**::
610 
611     std::string message = fmt::sprintf("The answer is %d", 42);
612   \endrst
613 */
614 template <typename S, typename... Args,
615           typename Char = enable_if_t<internal::is_string<S>::value, char_t<S>>>
616 inline std::basic_string<Char> sprintf(const S& format, const Args&... args) {
617   using context = basic_printf_context_t<Char>;
618   return vsprintf(to_string_view(format), {make_format_args<context>(args...)});
619 }
620 
621 template <typename S, typename Char = char_t<S>>
622 inline int vfprintf(std::FILE* f, const S& format,
623                     basic_format_args<basic_printf_context_t<Char>> args) {
624   basic_memory_buffer<Char> buffer;
625   printf(buffer, to_string_view(format), args);
626   std::size_t size = buffer.size();
627   return std::fwrite(buffer.data(), sizeof(Char), size, f) < size
628              ? -1
629              : static_cast<int>(size);
630 }
631 
632 /**
633   \rst
634   Prints formatted data to the file *f*.
635 
636   **Example**::
637 
638     fmt::fprintf(stderr, "Don't %s!", "panic");
639   \endrst
640  */
641 template <typename S, typename... Args,
642           typename Char = enable_if_t<internal::is_string<S>::value, char_t<S>>>
643 inline int fprintf(std::FILE* f, const S& format, const Args&... args) {
644   using context = basic_printf_context_t<Char>;
645   return vfprintf(f, to_string_view(format),
646                   {make_format_args<context>(args...)});
647 }
648 
649 template <typename S, typename Char = char_t<S>>
650 inline int vprintf(const S& format,
651                    basic_format_args<basic_printf_context_t<Char>> args) {
652   return vfprintf(stdout, to_string_view(format), args);
653 }
654 
655 /**
656   \rst
657   Prints formatted data to ``stdout``.
658 
659   **Example**::
660 
661     fmt::printf("Elapsed time: %.2f seconds", 1.23);
662   \endrst
663  */
664 template <typename S, typename... Args,
665           FMT_ENABLE_IF(internal::is_string<S>::value)>
666 inline int printf(const S& format_str, const Args&... args) {
667   using context = basic_printf_context_t<char_t<S>>;
668   return vprintf(to_string_view(format_str),
669                  {make_format_args<context>(args...)});
670 }
671 
672 template <typename S, typename Char = char_t<S>>
673 inline int vfprintf(std::basic_ostream<Char>& os, const S& format,
674                     basic_format_args<basic_printf_context_t<Char>> args) {
675   basic_memory_buffer<Char> buffer;
676   printf(buffer, to_string_view(format), args);
677   internal::write(os, buffer);
678   return static_cast<int>(buffer.size());
679 }
680 
681 /** Formats arguments and writes the output to the range. */
682 template <typename ArgFormatter, typename Char,
683           typename Context =
684               basic_printf_context<typename ArgFormatter::iterator, Char>>
685 typename ArgFormatter::iterator vprintf(internal::buffer<Char>& out,
686                                         basic_string_view<Char> format_str,
687                                         basic_format_args<Context> args) {
688   typename ArgFormatter::iterator iter(out);
689   Context(iter, format_str, args).template format<ArgFormatter>();
690   return iter;
691 }
692 
693 /**
694   \rst
695   Prints formatted data to the stream *os*.
696 
697   **Example**::
698 
699     fmt::fprintf(cerr, "Don't %s!", "panic");
700   \endrst
701  */
702 template <typename S, typename... Args, typename Char = char_t<S>>
703 inline int fprintf(std::basic_ostream<Char>& os, const S& format_str,
704                    const Args&... args) {
705   using context = basic_printf_context_t<Char>;
706   return vfprintf(os, to_string_view(format_str),
707                   {make_format_args<context>(args...)});
708 }
709 FMT_END_NAMESPACE
710 
711 #endif  // FMT_PRINTF_H_
712