Print formatted string. * * Print string formatted according to the fmt parameter and variadic arguments. * Each formatting directive must have the following form: * * \% [ FLAGS ] [ WIDTH ] [ .PRECISION ] [ TYPE ] CONVERSION * * FLAGS:@n * - "#" Force to print prefix. For \%o conversion, the prefix is 0, for * \%x and \%X prefixes are 0x and 0X and for conversion \%b the *
| 619 | * |
| 620 | */ |
| 621 | int printf_core(const char *fmt, printf_spec_t *ps, va_list ap) |
| 622 | { |
| 623 | size_t i; /* Index of the currently processed character from fmt */ |
| 624 | size_t nxt = 0; /* Index of the next character from fmt */ |
| 625 | size_t j = 0; /* Index to the first not printed nonformating character */ |
| 626 | |
| 627 | size_t counter = 0; /* Number of characters printed */ |
| 628 | int retval; /* Return values from nested functions */ |
| 629 | |
| 630 | while (true) { |
| 631 | i = nxt; |
| 632 | char32_t uc = str_decode(fmt, &nxt, STR_NO_LIMIT); |
| 633 | |
| 634 | if (uc == 0) |
| 635 | break; |
| 636 | |
| 637 | /* Control character */ |
| 638 | if (uc == '%') { |
| 639 | /* Print common characters if any processed */ |
| 640 | if (i > j) { |
| 641 | if ((retval = printf_putnchars(&fmt[j], i - j, ps)) < 0) { |
| 642 | /* Error */ |
| 643 | counter = -counter; |
| 644 | goto out; |
| 645 | } |
| 646 | counter += retval; |
| 647 | } |
| 648 | |
| 649 | j = i; |
| 650 | |
| 651 | /* Parse modifiers */ |
| 652 | uint32_t flags = 0; |
| 653 | bool end = false; |
| 654 | |
| 655 | do { |
| 656 | i = nxt; |
| 657 | uc = str_decode(fmt, &nxt, STR_NO_LIMIT); |
| 658 | switch (uc) { |
| 659 | case '#': |
| 660 | flags |= __PRINTF_FLAG_PREFIX; |
| 661 | break; |
| 662 | case '-': |
| 663 | flags |= __PRINTF_FLAG_LEFTALIGNED; |
| 664 | break; |
| 665 | case '+': |
| 666 | flags |= __PRINTF_FLAG_SHOWPLUS; |
| 667 | break; |
| 668 | case ' ': |
| 669 | flags |= __PRINTF_FLAG_SPACESIGN; |
| 670 | break; |
| 671 | case '0': |
| 672 | flags |= __PRINTF_FLAG_ZEROPADDED; |
| 673 | break; |
| 674 | default: |
| 675 | end = true; |
| 676 | } |
| 677 | } while (!end); |
| 678 |
no test coverage detected