Rev 4185 | Rev 4200 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 4185 | Rev 4199 | ||
|---|---|---|---|
| Line 255... | Line 255... | ||
| 255 | 255 | ||
| 256 | /* Print leading spaces */ |
256 | /* Print leading spaces */ |
| 257 | size_t size = strlen_utf8(str); |
257 | size_t size = strlen_utf8(str); |
| 258 | if (precision == 0) |
258 | if (precision == 0) |
| 259 | precision = size; |
259 | precision = size; |
| 260 | 260 | ||
| 261 | count_t counter = 0; |
261 | count_t counter = 0; |
| 262 | width -= precision; |
262 | width -= precision; |
| 263 | if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) { |
263 | if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) { |
| 264 | while (width-- > 0) { |
264 | while (width-- > 0) { |
| 265 | if (printf_putchar(' ', ps) == 1) |
265 | if (printf_putchar(' ', ps) == 1) |
| 266 | counter++; |
266 | counter++; |
| 267 | } |
267 | } |
| 268 | } |
268 | } |
| 269 | 269 | ||
| 270 | int retval; |
270 | int retval; |
| 271 | size_t bytes = utf8_count_bytes(str, min(size, precision)); |
271 | size_t bytes = utf8_count_bytes(str, min(size, precision)); |
| 272 | if ((retval = printf_putnchars_utf8(str, bytes, ps)) < 0) |
272 | if ((retval = printf_putnchars_utf8(str, bytes, ps)) < 0) |
| 273 | return -counter; |
273 | return -counter; |
| 274 | 274 | ||
| Line 276... | Line 276... | ||
| 276 | 276 | ||
| 277 | while (width-- > 0) { |
277 | while (width-- > 0) { |
| 278 | if (printf_putchar(' ', ps) == 1) |
278 | if (printf_putchar(' ', ps) == 1) |
| 279 | counter++; |
279 | counter++; |
| 280 | } |
280 | } |
| 281 | 281 | ||
| 282 | return ((int) counter); |
282 | return ((int) counter); |
| 283 | } |
283 | } |
| 284 | 284 | ||
| 285 | /** Print UTF-32 string. |
285 | /** Print UTF-32 string. |
| 286 | * |
286 | * |
| Line 583... | Line 583... | ||
| 583 | * |
583 | * |
| 584 | */ |
584 | */ |
| 585 | int printf_core(const char *fmt, printf_spec_t *ps, va_list ap) |
585 | int printf_core(const char *fmt, printf_spec_t *ps, va_list ap) |
| 586 | { |
586 | { |
| 587 | index_t i = 0; /* Index of the currently processed character from fmt */ |
587 | index_t i = 0; /* Index of the currently processed character from fmt */ |
| - | 588 | index_t nxt = 0; |
|
| 588 | index_t j = 0; /* Index to the first not printed nonformating character */ |
589 | index_t j = 0; /* Index to the first not printed nonformating character */ |
| 589 | 590 | ||
| 590 | wchar_t uc; /* Current UTF-32 character decoded from fmt */ |
591 | wchar_t uc; /* Current UTF-32 character decoded from fmt */ |
| 591 | count_t counter = 0; /* Number of UTF-8 characters printed */ |
592 | count_t counter = 0; /* Number of UTF-8 characters printed */ |
| 592 | int retval; /* Return values from nested functions */ |
593 | int retval; /* Return values from nested functions */ |
| 593 | 594 | ||
| - | 595 | while (true) { |
|
| - | 596 | i = nxt; |
|
| 594 | while ((uc = utf8_decode(fmt, &i, UTF8_NO_LIMIT)) != 0) { |
597 | uc = utf8_decode(fmt, &nxt, UTF8_NO_LIMIT); |
| - | 598 | ||
| - | 599 | if (uc == '\0') break; |
|
| - | 600 | ||
| 595 | /* Control character */ |
601 | /* Control character */ |
| 596 | if (uc == '%') { |
602 | if (uc == '%') { |
| 597 | /* Print common characters if any processed */ |
603 | /* Print common characters if any processed */ |
| 598 | if (i > j) { |
604 | if (i > j) { |
| 599 | if ((retval = printf_putnchars_utf8(&fmt[j], i - j, ps)) < 0) { |
605 | if ((retval = printf_putnchars_utf8(&fmt[j], i - j, ps)) < 0) { |
| Line 609... | Line 615... | ||
| 609 | /* Parse modifiers */ |
615 | /* Parse modifiers */ |
| 610 | uint32_t flags = 0; |
616 | uint32_t flags = 0; |
| 611 | bool end = false; |
617 | bool end = false; |
| 612 | 618 | ||
| 613 | do { |
619 | do { |
| 614 | i++; |
620 | i = nxt; |
| 615 | uc = utf8_decode(fmt, &i, UTF8_NO_LIMIT); |
621 | uc = utf8_decode(fmt, &nxt, UTF8_NO_LIMIT); |
| 616 | switch (uc) { |
622 | switch (uc) { |
| 617 | case '#': |
623 | case '#': |
| 618 | flags |= __PRINTF_FLAG_PREFIX; |
624 | flags |= __PRINTF_FLAG_PREFIX; |
| 619 | break; |
625 | break; |
| 620 | case '-': |
626 | case '-': |
| Line 635... | Line 641... | ||
| 635 | } while (!end); |
641 | } while (!end); |
| 636 | 642 | ||
| 637 | /* Width & '*' operator */ |
643 | /* Width & '*' operator */ |
| 638 | int width = 0; |
644 | int width = 0; |
| 639 | if (isdigit(uc)) { |
645 | if (isdigit(uc)) { |
| 640 | while ((uc = utf8_decode(fmt, &i, UTF8_NO_LIMIT)) != 0) { |
- | |
| 641 | if (!isdigit(uc)) |
646 | while (true) { |
| 642 | break; |
- | |
| 643 | - | ||
| 644 | width *= 10; |
647 | width *= 10; |
| 645 | width += uc - '0'; |
648 | width += uc - '0'; |
| - | 649 | ||
| 646 | i++; |
650 | i = nxt; |
| - | 651 | uc = utf8_decode(fmt, &nxt, UTF8_NO_LIMIT); |
|
| - | 652 | if (uc == '\0') |
|
| - | 653 | break; |
|
| - | 654 | if (!isdigit(uc)) |
|
| - | 655 | break; |
|
| 647 | } |
656 | } |
| 648 | } else if (uc == '*') { |
657 | } else if (uc == '*') { |
| 649 | /* Get width value from argument list */ |
658 | /* Get width value from argument list */ |
| 650 | i++; |
659 | i = nxt; |
| 651 | uc = utf8_decode(fmt, &i, UTF8_NO_LIMIT); |
660 | uc = utf8_decode(fmt, &nxt, UTF8_NO_LIMIT); |
| 652 | width = (int) va_arg(ap, int); |
661 | width = (int) va_arg(ap, int); |
| 653 | if (width < 0) { |
662 | if (width < 0) { |
| 654 | /* Negative width sets '-' flag */ |
663 | /* Negative width sets '-' flag */ |
| 655 | width *= -1; |
664 | width *= -1; |
| 656 | flags |= __PRINTF_FLAG_LEFTALIGNED; |
665 | flags |= __PRINTF_FLAG_LEFTALIGNED; |
| Line 658... | Line 667... | ||
| 658 | } |
667 | } |
| 659 | 668 | ||
| 660 | /* Precision and '*' operator */ |
669 | /* Precision and '*' operator */ |
| 661 | int precision = 0; |
670 | int precision = 0; |
| 662 | if (uc == '.') { |
671 | if (uc == '.') { |
| 663 | i++; |
672 | i = nxt; |
| 664 | uc = utf8_decode(fmt, &i, UTF8_NO_LIMIT); |
673 | uc = utf8_decode(fmt, &nxt, UTF8_NO_LIMIT); |
| 665 | if (isdigit(uc)) { |
674 | if (isdigit(uc)) { |
| 666 | while ((uc = utf8_decode(fmt, &i, UTF8_NO_LIMIT)) != 0) { |
- | |
| 667 | if (!isdigit(uc)) |
675 | while (true) { |
| 668 | break; |
- | |
| 669 | - | ||
| 670 | precision *= 10; |
676 | precision *= 10; |
| 671 | precision += uc - '0'; |
677 | precision += uc - '0'; |
| - | 678 | ||
| 672 | i++; |
679 | i = nxt; |
| - | 680 | uc = utf8_decode(fmt, &nxt, UTF8_NO_LIMIT); |
|
| - | 681 | if (uc == '\0') |
|
| - | 682 | break; |
|
| - | 683 | if (!isdigit(uc)) |
|
| - | 684 | break; |
|
| 673 | } |
685 | } |
| 674 | } else if (fmt[i] == '*') { |
686 | } else if (uc == '*') { |
| 675 | /* Get precision value from the argument list */ |
687 | /* Get precision value from the argument list */ |
| 676 | i++; |
688 | i = nxt; |
| 677 | uc = utf8_decode(fmt, &i, UTF8_NO_LIMIT); |
689 | uc = utf8_decode(fmt, &nxt, UTF8_NO_LIMIT); |
| 678 | precision = (int) va_arg(ap, int); |
690 | precision = (int) va_arg(ap, int); |
| 679 | if (precision < 0) { |
691 | if (precision < 0) { |
| 680 | /* Ignore negative precision */ |
692 | /* Ignore negative precision */ |
| 681 | precision = 0; |
693 | precision = 0; |
| 682 | } |
694 | } |
| Line 690... | Line 702... | ||
| 690 | * t ptrdiff_t - ISO C 99 |
702 | * t ptrdiff_t - ISO C 99 |
| 691 | */ |
703 | */ |
| 692 | case 'h': |
704 | case 'h': |
| 693 | /* Char or short */ |
705 | /* Char or short */ |
| 694 | qualifier = PrintfQualifierShort; |
706 | qualifier = PrintfQualifierShort; |
| 695 | i++; |
707 | i = nxt; |
| 696 | uc = utf8_decode(fmt, &i, UTF8_NO_LIMIT); |
708 | uc = utf8_decode(fmt, &nxt, UTF8_NO_LIMIT); |
| 697 | if (uc == 'h') { |
709 | if (uc == 'h') { |
| 698 | i++; |
710 | i = nxt; |
| 699 | uc = utf8_decode(fmt, &i, UTF8_NO_LIMIT); |
711 | uc = utf8_decode(fmt, &nxt, UTF8_NO_LIMIT); |
| 700 | qualifier = PrintfQualifierByte; |
712 | qualifier = PrintfQualifierByte; |
| 701 | } |
713 | } |
| 702 | break; |
714 | break; |
| 703 | case 'l': |
715 | case 'l': |
| 704 | /* Long or long long */ |
716 | /* Long or long long */ |
| 705 | qualifier = PrintfQualifierLong; |
717 | qualifier = PrintfQualifierLong; |
| 706 | i++; |
718 | i = nxt; |
| 707 | uc = utf8_decode(fmt, &i, UTF8_NO_LIMIT); |
719 | uc = utf8_decode(fmt, &nxt, UTF8_NO_LIMIT); |
| 708 | if (uc == 'l') { |
720 | if (uc == 'l') { |
| 709 | i++; |
721 | i = nxt; |
| 710 | uc = utf8_decode(fmt, &i, UTF8_NO_LIMIT); |
722 | uc = utf8_decode(fmt, &nxt, UTF8_NO_LIMIT); |
| 711 | qualifier = PrintfQualifierLongLong; |
723 | qualifier = PrintfQualifierLongLong; |
| 712 | } |
724 | } |
| 713 | break; |
725 | break; |
| 714 | default: |
726 | default: |
| 715 | /* Default type */ |
727 | /* Default type */ |
| Line 732... | Line 744... | ||
| 732 | counter = -counter; |
744 | counter = -counter; |
| 733 | goto out; |
745 | goto out; |
| 734 | } |
746 | } |
| 735 | 747 | ||
| 736 | counter += retval; |
748 | counter += retval; |
| 737 | j = i + 1; |
749 | j = nxt; |
| 738 | goto next_char; |
750 | goto next_char; |
| 739 | case 'c': |
751 | case 'c': |
| 740 | if (qualifier == PrintfQualifierLong) |
752 | if (qualifier == PrintfQualifierLong) |
| 741 | retval = print_wchar(va_arg(ap, wchar_t), width, flags, ps); |
753 | retval = print_wchar(va_arg(ap, wchar_t), width, flags, ps); |
| 742 | else |
754 | else |
| Line 746... | Line 758... | ||
| 746 | counter = -counter; |
758 | counter = -counter; |
| 747 | goto out; |
759 | goto out; |
| 748 | }; |
760 | }; |
| 749 | 761 | ||
| 750 | counter += retval; |
762 | counter += retval; |
| 751 | j = i + 1; |
763 | j = nxt; |
| 752 | goto next_char; |
764 | goto next_char; |
| 753 | 765 | ||
| 754 | /* |
766 | /* |
| 755 | * Integer values |
767 | * Integer values |
| 756 | */ |
768 | */ |
| Line 850... | Line 862... | ||
| 850 | counter = -counter; |
862 | counter = -counter; |
| 851 | goto out; |
863 | goto out; |
| 852 | } |
864 | } |
| 853 | 865 | ||
| 854 | counter += retval; |
866 | counter += retval; |
| 855 | j = i + 1; |
867 | j = nxt; |
| 856 | } |
868 | } |
| 857 | next_char: |
869 | next_char: |
| 858 | 870 | ; |
|
| 859 | i++; |
- | |
| 860 | } |
871 | } |
| 861 | 872 | ||
| 862 | if (i > j) { |
873 | if (i > j) { |
| 863 | if ((retval = printf_putnchars_utf8(&fmt[j], i - j, ps)) < 0) { |
874 | if ((retval = printf_putnchars_utf8(&fmt[j], i - j, ps)) < 0) { |
| 864 | /* Error */ |
875 | /* Error */ |