Changeset 5480:3e850c6e43fd
- Timestamp:
- 2008-08-19 00:39:44 (5 months ago)
- Author:
- Rocco Rutte <pdmef@…>
- Branch:
- HEAD
- Message:
-
Make text/enriched handler multibyte aware. Closes #3033.
- Files:
-
Legend:
- Unmodified
- Added
- Removed
-
|
r5437
|
r5480
|
|
| 450 | 450 | struct enriched_state |
| 451 | 451 | { |
| 452 | | char *buffer; |
| 453 | | char *line; |
| 454 | | char *param; |
| | 452 | wchar_t *buffer; |
| | 453 | wchar_t *line; |
| | 454 | wchar_t *param; |
| 455 | 455 | size_t buff_len; |
| 456 | 456 | size_t line_len; |
| … |
… |
|
| 467 | 467 | }; |
| 468 | 468 | |
| | 469 | static int enriched_cmp (const char *a, const wchar_t *b) |
| | 470 | { |
| | 471 | register const char *p = a; |
| | 472 | register const wchar_t *q = b; |
| | 473 | int i; |
| | 474 | |
| | 475 | if (!a && !b) |
| | 476 | return 0; |
| | 477 | if (!a && b) |
| | 478 | return -1; |
| | 479 | if (a && !b) |
| | 480 | return 1; |
| | 481 | |
| | 482 | for ( ; *p || *q; p++, q++) |
| | 483 | { |
| | 484 | if ((i = ascii_tolower (*p)) - ascii_tolower (((char) *q) & 0x7f)) |
| | 485 | return i; |
| | 486 | } |
| | 487 | return 0; |
| | 488 | } |
| | 489 | |
| 469 | 490 | static void enriched_wrap (struct enriched_state *stte) |
| 470 | 491 | { |
| … |
… |
|
| 479 | 500 | size_t y = stte->line_used - 1; |
| 480 | 501 | |
| 481 | | while (y && ISSPACE (stte->line[y])) |
| 482 | | { |
| 483 | | stte->line[y] = '\0'; |
| | 502 | while (y && iswspace (stte->line[y])) |
| | 503 | { |
| | 504 | stte->line[y] = (wchar_t) '\0'; |
| 484 | 505 | y--; |
| 485 | 506 | stte->line_used--; |
| … |
… |
|
| 491 | 512 | y = 0; |
| 492 | 513 | |
| 493 | | while (stte->line[y] && ISSPACE (stte->line[y])) |
| | 514 | while (stte->line[y] && iswspace (stte->line[y])) |
| 494 | 515 | y++; |
| 495 | 516 | if (y) |
| … |
… |
|
| 531 | 552 | } |
| 532 | 553 | } |
| 533 | | state_puts (stte->line, stte->s); |
| | 554 | state_putws ((const wchar_t*) stte->line, stte->s); |
| 534 | 555 | } |
| 535 | 556 | |
| 536 | 557 | state_putc ('\n', stte->s); |
| 537 | | stte->line[0] = '\0'; |
| | 558 | stte->line[0] = (wchar_t) '\0'; |
| 538 | 559 | stte->line_len = 0; |
| 539 | 560 | stte->line_used = 0; |
| … |
… |
|
| 586 | 607 | if (stte->buff_used) |
| 587 | 608 | { |
| 588 | | stte->buffer[stte->buff_used] = '\0'; |
| | 609 | stte->buffer[stte->buff_used] = (wchar_t) '\0'; |
| 589 | 610 | stte->line_used += stte->buff_used; |
| 590 | 611 | if (stte->line_used > stte->line_max) |
| 591 | 612 | { |
| 592 | 613 | stte->line_max = stte->line_used; |
| 593 | | safe_realloc (&stte->line, stte->line_max + 1); |
| 594 | | } |
| 595 | | strcat (stte->line, stte->buffer); /* __STRCAT_CHECKED__ */ |
| | 614 | safe_realloc (&stte->line, (stte->line_max + 1) * sizeof (wchar_t)); |
| | 615 | } |
| | 616 | wcscat (stte->line, stte->buffer); |
| 596 | 617 | stte->line_len += stte->word_len; |
| 597 | 618 | stte->word_len = 0; |
| … |
… |
|
| 603 | 624 | |
| 604 | 625 | |
| 605 | | static void enriched_putc (int c, struct enriched_state *stte) |
| | 626 | static void enriched_putwc (wchar_t c, struct enriched_state *stte) |
| 606 | 627 | { |
| 607 | 628 | if (stte->tag_level[RICH_PARAM]) |
| … |
… |
|
| 610 | 631 | { |
| 611 | 632 | if (stte->param_used + 1 >= stte->param_len) |
| 612 | | safe_realloc (&stte->param, (stte->param_len += STRING)); |
| | 633 | safe_realloc (&stte->param, (stte->param_len += STRING) * sizeof (wchar_t)); |
| 613 | 634 | |
| 614 | 635 | stte->param[stte->param_used++] = c; |
| … |
… |
|
| 621 | 642 | { |
| 622 | 643 | stte->buff_len += LONG_STRING; |
| 623 | | safe_realloc (&stte->buffer, stte->buff_len + 1); |
| 624 | | } |
| 625 | | |
| 626 | | if ((!stte->tag_level[RICH_NOFILL] && ISSPACE (c)) || c == '\0' ) |
| 627 | | { |
| 628 | | if (c == '\t') |
| | 644 | safe_realloc (&stte->buffer, (stte->buff_len + 1) * sizeof (wchar_t)); |
| | 645 | } |
| | 646 | |
| | 647 | if ((!stte->tag_level[RICH_NOFILL] && iswspace (c)) || c == (wchar_t) '\0') |
| | 648 | { |
| | 649 | if (c == (wchar_t) '\t') |
| 629 | 650 | stte->word_len += 8 - (stte->line_len + stte->word_len) % 8; |
| 630 | 651 | else |
| … |
… |
|
| 641 | 662 | { |
| 642 | 663 | stte->buffer[stte->buff_used++] = c; |
| 643 | | stte->buffer[stte->buff_used++] = '\010'; |
| | 664 | stte->buffer[stte->buff_used++] = (wchar_t) '\010'; |
| 644 | 665 | stte->buffer[stte->buff_used++] = c; |
| 645 | 666 | } |
| … |
… |
|
| 648 | 669 | |
| 649 | 670 | stte->buffer[stte->buff_used++] = '_'; |
| 650 | | stte->buffer[stte->buff_used++] = '\010'; |
| | 671 | stte->buffer[stte->buff_used++] = (wchar_t) '\010'; |
| 651 | 672 | stte->buffer[stte->buff_used++] = c; |
| 652 | 673 | } |
| … |
… |
|
| 654 | 675 | { |
| 655 | 676 | stte->buffer[stte->buff_used++] = c; |
| 656 | | stte->buffer[stte->buff_used++] = '\010'; |
| | 677 | stte->buffer[stte->buff_used++] = (wchar_t) '\010'; |
| 657 | 678 | stte->buffer[stte->buff_used++] = '_'; |
| 658 | 679 | } |
| … |
… |
|
| 670 | 691 | } |
| 671 | 692 | |
| 672 | | static void enriched_puts (char *s, struct enriched_state *stte) |
| 673 | | { |
| 674 | | char *c; |
| 675 | | |
| 676 | | if (stte->buff_len < stte->buff_used + mutt_strlen(s)) |
| | 693 | static void enriched_puts (const char *s, struct enriched_state *stte) |
| | 694 | { |
| | 695 | const char *c; |
| | 696 | |
| | 697 | if (stte->buff_len < stte->buff_used + mutt_strlen (s)) |
| 677 | 698 | { |
| 678 | 699 | stte->buff_len += LONG_STRING; |
| 679 | | safe_realloc (&stte->buffer, stte->buff_len + 1); |
| | 700 | safe_realloc (&stte->buffer, (stte->buff_len + 1) * sizeof (wchar_t)); |
| 680 | 701 | } |
| 681 | 702 | c = s; |
| 682 | 703 | while (*c) |
| 683 | 704 | { |
| 684 | | stte->buffer[stte->buff_used++] = *c; |
| | 705 | stte->buffer[stte->buff_used++] = (wchar_t) *c; |
| 685 | 706 | c++; |
| 686 | 707 | } |
| 687 | 708 | } |
| 688 | 709 | |
| 689 | | static void enriched_set_flags (const char *tag, struct enriched_state *stte) |
| 690 | | { |
| 691 | | const char *tagptr = tag; |
| | 710 | static void enriched_set_flags (const wchar_t *tag, struct enriched_state *stte) |
| | 711 | { |
| | 712 | const wchar_t *tagptr = tag; |
| 692 | 713 | int i, j; |
| 693 | 714 | |
| 694 | | if (*tagptr == '/') |
| | 715 | if (*tagptr == (wchar_t) '/') |
| 695 | 716 | tagptr++; |
| 696 | 717 | |
| 697 | 718 | for (i = 0, j = -1; EnrichedTags[i].tag_name; i++) |
| 698 | | if (ascii_strcasecmp (EnrichedTags[i].tag_name,tagptr) == 0) |
| | 719 | if (enriched_cmp (EnrichedTags[i].tag_name, tagptr) == 0) |
| 699 | 720 | { |
| 700 | 721 | j = EnrichedTags[i].index; |
| … |
… |
|
| 707 | 728 | enriched_flush (stte, 1); |
| 708 | 729 | |
| 709 | | if (*tag == '/') |
| | 730 | if (*tag == (wchar_t) '/') |
| 710 | 731 | { |
| 711 | 732 | if (stte->tag_level[j]) /* make sure not to go negative */ |
| … |
… |
|
| 713 | 734 | if ((stte->s->flags & M_DISPLAY) && j == RICH_PARAM && stte->tag_level[RICH_COLOR]) |
| 714 | 735 | { |
| 715 | | stte->param[stte->param_used] = '\0'; |
| 716 | | if (!ascii_strcasecmp(stte->param, "black")) |
| | 736 | stte->param[stte->param_used] = (wchar_t) '\0'; |
| | 737 | if (!enriched_cmp("black", stte->param)) |
| 717 | 738 | { |
| 718 | 739 | enriched_puts("\033[30m", stte); |
| 719 | 740 | } |
| 720 | | else if (!ascii_strcasecmp(stte->param, "red")) |
| | 741 | else if (!enriched_cmp("red", stte->param)) |
| 721 | 742 | { |
| 722 | 743 | enriched_puts("\033[31m", stte); |
| 723 | 744 | } |
| 724 | | else if (!ascii_strcasecmp(stte->param, "green")) |
| | 745 | else if (!enriched_cmp("green", stte->param)) |
| 725 | 746 | { |
| 726 | 747 | enriched_puts("\033[32m", stte); |
| 727 | 748 | } |
| 728 | | else if (!ascii_strcasecmp(stte->param, "yellow")) |
| | 749 | else if (!enriched_cmp("yellow", stte->param)) |
| 729 | 750 | { |
| 730 | 751 | enriched_puts("\033[33m", stte); |
| 731 | 752 | } |
| 732 | | else if (!ascii_strcasecmp(stte->param, "blue")) |
| | 753 | else if (!enriched_cmp("blue", stte->param)) |
| 733 | 754 | { |
| 734 | 755 | enriched_puts("\033[34m", stte); |
| 735 | 756 | } |
| 736 | | else if (!ascii_strcasecmp(stte->param, "magenta")) |
| | 757 | else if (!enriched_cmp("magenta", stte->param)) |
| 737 | 758 | { |
| 738 | 759 | enriched_puts("\033[35m", stte); |
| 739 | 760 | } |
| 740 | | else if (!ascii_strcasecmp(stte->param, "cyan")) |
| | 761 | else if (!enriched_cmp("cyan", stte->param)) |
| 741 | 762 | { |
| 742 | 763 | enriched_puts("\033[36m", stte); |
| 743 | 764 | } |
| 744 | | else if (!ascii_strcasecmp(stte->param, "white")) |
| | 765 | else if (!enriched_cmp("white", stte->param)) |
| 745 | 766 | { |
| 746 | 767 | enriched_puts("\033[37m", stte); |
| … |
… |
|
| 756 | 777 | { |
| 757 | 778 | stte->param_used = 0; |
| 758 | | stte->param[0] = '\0'; |
| | 779 | stte->param[0] = (wchar_t) '\0'; |
| 759 | 780 | } |
| 760 | 781 | } |
| … |
… |
|
| 775 | 796 | long bytes = a->length; |
| 776 | 797 | struct enriched_state stte; |
| 777 | | int c = 0; |
| | 798 | wchar_t wc = 0; |
| 778 | 799 | int tag_len = 0; |
| 779 | | char tag[LONG_STRING + 1]; |
| | 800 | wchar_t tag[LONG_STRING + 1]; |
| 780 | 801 | |
| 781 | 802 | memset (&stte, 0, sizeof (stte)); |
| … |
… |
|
| 783 | 804 | stte.WrapMargin = ((s->flags & M_DISPLAY) ? (COLS-4) : ((COLS-4)<72)?(COLS-4):72); |
| 784 | 805 | stte.line_max = stte.WrapMargin * 4; |
| 785 | | stte.line = (char *) safe_calloc (1, stte.line_max + 1); |
| 786 | | stte.param = (char *) safe_calloc (1, STRING); |
| | 806 | stte.line = (wchar_t *) safe_calloc (1, (stte.line_max + 1) * sizeof (wchar_t)); |
| | 807 | stte.param = (wchar_t *) safe_calloc (1, (STRING) * sizeof (wchar_t)); |
| 787 | 808 | |
| 788 | 809 | stte.param_len = STRING; |
| … |
… |
|
| 799 | 820 | if (state != ST_EOF) |
| 800 | 821 | { |
| 801 | | if (!bytes || (c = fgetc (s->fpin)) == EOF) |
| | 822 | if (!bytes || (wc = fgetwc (s->fpin)) == EOF) |
| 802 | 823 | state = ST_EOF; |
| 803 | 824 | else |
| … |
… |
|
| 808 | 829 | { |
| 809 | 830 | case TEXT : |
| 810 | | switch (c) |
| | 831 | switch (wc) |
| 811 | 832 | { |
| 812 | 833 | case '<' : |
| … |
… |
|
| 821 | 842 | else |
| 822 | 843 | { |
| 823 | | enriched_putc (' ', &stte); |
| | 844 | enriched_putwc ((wchar_t) ' ', &stte); |
| 824 | 845 | state = NEWLINE; |
| 825 | 846 | } |
| … |
… |
|
| 827 | 848 | |
| 828 | 849 | default: |
| 829 | | enriched_putc (c, &stte); |
| | 850 | enriched_putwc (wc, &stte); |
| 830 | 851 | } |
| 831 | 852 | break; |
| 832 | 853 | |
| 833 | 854 | case LANGLE : |
| 834 | | if (c == '<') |
| 835 | | { |
| 836 | | enriched_putc (c, &stte); |
| | 855 | if (wc == (wchar_t) '<') |
| | 856 | { |
| | 857 | enriched_putwc (wc, &stte); |
| 837 | 858 | state = TEXT; |
| 838 | 859 | break; |
| … |
… |
|
| 845 | 866 | /* Yes, fall through (it wasn't a <<, so this char is first in TAG) */ |
| 846 | 867 | case TAG : |
| 847 | | if (c == '>') |
| 848 | | { |
| 849 | | tag[tag_len] = '\0'; |
| | 868 | if (wc == (wchar_t) '>') |
| | 869 | { |
| | 870 | tag[tag_len] = (wchar_t) '\0'; |
| 850 | 871 | enriched_set_flags (tag, &stte); |
| 851 | 872 | state = TEXT; |
| 852 | 873 | } |
| 853 | 874 | else if (tag_len < LONG_STRING) /* ignore overly long tags */ |
| 854 | | tag[tag_len++] = c; |
| | 875 | tag[tag_len++] = wc; |
| 855 | 876 | else |
| 856 | 877 | state = BOGUS_TAG; |
| … |
… |
|
| 858 | 879 | |
| 859 | 880 | case BOGUS_TAG : |
| 860 | | if (c == '>') |
| | 881 | if (wc == (wchar_t) '>') |
| 861 | 882 | state = TEXT; |
| 862 | 883 | break; |
| 863 | 884 | |
| 864 | 885 | case NEWLINE : |
| 865 | | if (c == '\n') |
| | 886 | if (wc == (wchar_t) '\n') |
| 866 | 887 | enriched_flush (&stte, 1); |
| 867 | 888 | else |
| 868 | 889 | { |
| 869 | | ungetc (c, s->fpin); |
| | 890 | ungetwc (wc, s->fpin); |
| 870 | 891 | bytes++; |
| 871 | 892 | state = TEXT; |
| … |
… |
|
| 874 | 895 | |
| 875 | 896 | case ST_EOF : |
| 876 | | enriched_putc ('\0', &stte); |
| | 897 | enriched_putwc ((wchar_t) '\0', &stte); |
| 877 | 898 | enriched_flush (&stte, 1); |
| 878 | 899 | state = DONE; |
-
|
r5468
|
r5480
|
|
| 918 | 918 | #define state_puts(x,y) fputs(x,(y)->fpout) |
| 919 | 919 | #define state_putc(x,y) fputc(x,(y)->fpout) |
| | 920 | #define state_putws(x,y) fputws(x,(y)->fpout) |
| | 921 | #define state_putwc(x,y) fputwc(x,(y)->fpout) |
| 920 | 922 | |
| 921 | 923 | void state_mark_attach (STATE *); |