| 719 | |
| 720 | template <typename Char> |
| 721 | void fmt::internal::PrintfFormatter<Char>::format( |
| 722 | BasicWriter<Char> &writer, BasicStringRef<Char> format, |
| 723 | const ArgList &args) { |
| 724 | const Char *start = format.c_str(); |
| 725 | set_args(args); |
| 726 | const Char *s = start; |
| 727 | while (*s) { |
| 728 | Char c = *s++; |
| 729 | if (c != '%') continue; |
| 730 | if (*s == c) { |
| 731 | write(writer, start, s); |
| 732 | start = ++s; |
| 733 | continue; |
| 734 | } |
| 735 | write(writer, start, s - 1); |
| 736 | |
| 737 | FormatSpec spec; |
| 738 | spec.align_ = ALIGN_RIGHT; |
| 739 | |
| 740 | // Parse argument index, flags and width. |
| 741 | unsigned arg_index = parse_header(s, spec); |
| 742 | |
| 743 | // Parse precision. |
| 744 | if (*s == '.') { |
| 745 | ++s; |
| 746 | if ('0' <= *s && *s <= '9') { |
| 747 | spec.precision_ = parse_nonnegative_int(s); |
| 748 | } else if (*s == '*') { |
| 749 | ++s; |
| 750 | spec.precision_ = PrecisionHandler().visit(get_arg(s)); |
| 751 | } |
| 752 | } |
| 753 | |
| 754 | Arg arg = get_arg(s, arg_index); |
| 755 | if (spec.flag(HASH_FLAG) && IsZeroInt().visit(arg)) |
| 756 | spec.flags_ &= ~HASH_FLAG; |
| 757 | if (spec.fill_ == '0') { |
| 758 | if (arg.type <= Arg::LAST_NUMERIC_TYPE) |
| 759 | spec.align_ = ALIGN_NUMERIC; |
| 760 | else |
| 761 | spec.fill_ = ' '; // Ignore '0' flag for non-numeric types. |
| 762 | } |
| 763 | |
| 764 | // Parse length and convert the argument to the required type. |
| 765 | switch (*s++) { |
| 766 | case 'h': |
| 767 | if (*s == 'h') |
| 768 | ArgConverter<signed char>(arg, *++s).visit(arg); |
| 769 | else |
| 770 | ArgConverter<short>(arg, *s).visit(arg); |
| 771 | break; |
| 772 | case 'l': |
| 773 | if (*s == 'l') |
| 774 | ArgConverter<fmt::LongLong>(arg, *++s).visit(arg); |
| 775 | else |
| 776 | ArgConverter<long>(arg, *s).visit(arg); |
| 777 | break; |
| 778 | case 'j': |
no test coverage detected