diff options
| author | Kenichi Handa | 2004-03-04 00:54:46 +0000 |
|---|---|---|
| committer | Kenichi Handa | 2004-03-04 00:54:46 +0000 |
| commit | 8583605b9565734a7f0896f55f151e1b2d280283 (patch) | |
| tree | 1381c889e4d09997c7cee84423c84e08ddf659e7 /src | |
| parent | 16431d3c7eb3e628e615c35f22f5b9de1fe7953f (diff) | |
| download | emacs-8583605b9565734a7f0896f55f151e1b2d280283.tar.gz emacs-8583605b9565734a7f0896f55f151e1b2d280283.zip | |
(Ftranslate_region_internal): Renamed from
Ftranslate_region. Accept a char-table in TABLE.
(syms_of_editfns): Defsubr Stranslate_region_internal.
Diffstat (limited to 'src')
| -rw-r--r-- | src/editfns.c | 121 |
1 files changed, 72 insertions, 49 deletions
diff --git a/src/editfns.c b/src/editfns.c index fafa654bed1..5c43c2f4db0 100644 --- a/src/editfns.c +++ b/src/editfns.c | |||
| @@ -2752,8 +2752,10 @@ Both characters must have the same length of multi-byte form. */) | |||
| 2752 | return Qnil; | 2752 | return Qnil; |
| 2753 | } | 2753 | } |
| 2754 | 2754 | ||
| 2755 | DEFUN ("translate-region", Ftranslate_region, Stranslate_region, 3, 3, 0, | 2755 | DEFUN ("translate-region-internal", Ftranslate_region_internal, |
| 2756 | doc: /* From START to END, translate characters according to TABLE. | 2756 | Stranslate_region_internal, 3, 3, 0, |
| 2757 | doc: /* Internal use only. | ||
| 2758 | From START to END, translate characters according to TABLE. | ||
| 2757 | TABLE is a string; the Nth character in it is the mapping | 2759 | TABLE is a string; the Nth character in it is the mapping |
| 2758 | for the character with code N. | 2760 | for the character with code N. |
| 2759 | This function does not alter multibyte characters. | 2761 | This function does not alter multibyte characters. |
| @@ -2763,78 +2765,99 @@ It returns the number of characters changed. */) | |||
| 2763 | Lisp_Object end; | 2765 | Lisp_Object end; |
| 2764 | register Lisp_Object table; | 2766 | register Lisp_Object table; |
| 2765 | { | 2767 | { |
| 2766 | register int pos_byte, stop; /* Limits of the region. */ | ||
| 2767 | register unsigned char *tt; /* Trans table. */ | 2768 | register unsigned char *tt; /* Trans table. */ |
| 2768 | register int nc; /* New character. */ | 2769 | register int nc; /* New character. */ |
| 2769 | int cnt; /* Number of changes made. */ | 2770 | int cnt; /* Number of changes made. */ |
| 2770 | int size; /* Size of translate table. */ | 2771 | int size; /* Size of translate table. */ |
| 2771 | int pos; | 2772 | int pos, pos_byte; |
| 2772 | int multibyte = !NILP (current_buffer->enable_multibyte_characters); | 2773 | int multibyte = !NILP (current_buffer->enable_multibyte_characters); |
| 2774 | int string_multibyte; | ||
| 2775 | Lisp_Object val; | ||
| 2773 | 2776 | ||
| 2774 | validate_region (&start, &end); | 2777 | validate_region (&start, &end); |
| 2775 | CHECK_STRING (table); | 2778 | if (CHAR_TABLE_P (table)) |
| 2776 | 2779 | tt = NULL; | |
| 2777 | size = SBYTES (table); | 2780 | else |
| 2778 | tt = SDATA (table); | 2781 | { |
| 2782 | CHECK_STRING (table); | ||
| 2783 | |||
| 2784 | if (multibyte != (SCHARS (table) < SBYTES (table))) | ||
| 2785 | table = (multibyte | ||
| 2786 | ? string_make_multibyte (table) | ||
| 2787 | : string_make_unibyte (table)); | ||
| 2788 | string_multibyte = SCHARS (table) < SBYTES (table); | ||
| 2789 | size = SBYTES (table); | ||
| 2790 | tt = SDATA (table); | ||
| 2791 | } | ||
| 2779 | 2792 | ||
| 2780 | pos_byte = CHAR_TO_BYTE (XINT (start)); | ||
| 2781 | stop = CHAR_TO_BYTE (XINT (end)); | ||
| 2782 | modify_region (current_buffer, XINT (start), XINT (end)); | ||
| 2783 | pos = XINT (start); | 2793 | pos = XINT (start); |
| 2794 | pos_byte = CHAR_TO_BYTE (pos); | ||
| 2795 | modify_region (current_buffer, XINT (start), XINT (end)); | ||
| 2784 | 2796 | ||
| 2785 | cnt = 0; | 2797 | cnt = 0; |
| 2786 | for (; pos_byte < stop; ) | 2798 | for (; pos < end; ) |
| 2787 | { | 2799 | { |
| 2788 | register unsigned char *p = BYTE_POS_ADDR (pos_byte); | 2800 | register unsigned char *p = BYTE_POS_ADDR (pos_byte); |
| 2789 | int len; | 2801 | unsigned char *str, buf[MAX_MULTIBYTE_LENGTH]; |
| 2802 | int len, str_len; | ||
| 2790 | int oc; | 2803 | int oc; |
| 2791 | int pos_byte_next; | ||
| 2792 | 2804 | ||
| 2793 | if (multibyte) | 2805 | if (multibyte) |
| 2794 | oc = STRING_CHAR_AND_LENGTH (p, stop - pos_byte, len); | 2806 | nc = oc = STRING_CHAR_AND_LENGTH (p, stop - pos_byte, len); |
| 2795 | else | 2807 | else |
| 2796 | oc = *p, len = 1; | 2808 | nc = oc = *p, len = 1; |
| 2797 | pos_byte_next = pos_byte + len; | 2809 | if (tt) |
| 2798 | if (oc < size && len == 1) | ||
| 2799 | { | 2810 | { |
| 2800 | nc = tt[oc]; | 2811 | if (oc < size) |
| 2801 | if (nc != oc) | ||
| 2802 | { | 2812 | { |
| 2803 | /* Take care of the case where the new character | 2813 | if (string_multibyte) |
| 2804 | combines with neighboring bytes. */ | ||
| 2805 | if (!ASCII_BYTE_P (nc) | ||
| 2806 | && (CHAR_HEAD_P (nc) | ||
| 2807 | ? ! CHAR_HEAD_P (FETCH_BYTE (pos_byte + 1)) | ||
| 2808 | : (pos_byte > BEG_BYTE | ||
| 2809 | && ! ASCII_BYTE_P (FETCH_BYTE (pos_byte - 1))))) | ||
| 2810 | { | 2814 | { |
| 2811 | Lisp_Object string; | 2815 | str = tt + string_char_to_byte (table, oc); |
| 2812 | 2816 | nc = STRING_CHAR_AND_LENGTH (str, 0, str_len); | |
| 2813 | string = make_multibyte_string (tt + oc, 1, 1); | ||
| 2814 | /* This is less efficient, because it moves the gap, | ||
| 2815 | but it handles combining correctly. */ | ||
| 2816 | replace_range (pos, pos + 1, string, | ||
| 2817 | 1, 0, 1); | ||
| 2818 | pos_byte_next = CHAR_TO_BYTE (pos); | ||
| 2819 | if (pos_byte_next > pos_byte) | ||
| 2820 | /* Before combining happened. We should not | ||
| 2821 | increment POS. So, to cancel the later | ||
| 2822 | increment of POS, we decrease it now. */ | ||
| 2823 | pos--; | ||
| 2824 | else | ||
| 2825 | INC_POS (pos_byte_next); | ||
| 2826 | } | 2817 | } |
| 2827 | else | 2818 | else |
| 2828 | { | 2819 | { |
| 2829 | record_change (pos, 1); | 2820 | str = tt + oc; |
| 2830 | *p = nc; | 2821 | nc = tt[oc], str_len = 1; |
| 2831 | signal_after_change (pos, 1, 1); | ||
| 2832 | update_compositions (pos, pos + 1, CHECK_BORDER); | ||
| 2833 | } | 2822 | } |
| 2834 | ++cnt; | ||
| 2835 | } | 2823 | } |
| 2836 | } | 2824 | } |
| 2837 | pos_byte = pos_byte_next; | 2825 | else |
| 2826 | { | ||
| 2827 | Lisp_Object val; | ||
| 2828 | |||
| 2829 | val = CHAR_TABLE_REF (table, oc); | ||
| 2830 | if (CHARACTERP (val)) | ||
| 2831 | { | ||
| 2832 | nc = XFASTINT (val); | ||
| 2833 | str_len = CHAR_STRING (nc, buf); | ||
| 2834 | str = buf; | ||
| 2835 | } | ||
| 2836 | } | ||
| 2837 | |||
| 2838 | if (nc != oc) | ||
| 2839 | { | ||
| 2840 | if (len != str_len) | ||
| 2841 | { | ||
| 2842 | Lisp_Object string; | ||
| 2843 | |||
| 2844 | /* This is less efficient, because it moves the gap, | ||
| 2845 | but it should multibyte characters correctly. */ | ||
| 2846 | string = make_multibyte_string (str, 1, str_len); | ||
| 2847 | replace_range (pos, pos + 1, string, 1, 0, 1); | ||
| 2848 | len = str_len; | ||
| 2849 | } | ||
| 2850 | else | ||
| 2851 | { | ||
| 2852 | record_change (pos, 1); | ||
| 2853 | while (str_len-- > 0) | ||
| 2854 | *p++ = *str++; | ||
| 2855 | signal_after_change (pos, 1, 1); | ||
| 2856 | update_compositions (pos, pos + 1, CHECK_BORDER); | ||
| 2857 | } | ||
| 2858 | ++cnt; | ||
| 2859 | } | ||
| 2860 | pos_byte += len; | ||
| 2838 | pos++; | 2861 | pos++; |
| 2839 | } | 2862 | } |
| 2840 | 2863 | ||
| @@ -4327,7 +4350,7 @@ functions if all the text being accessed has this property. */); | |||
| 4327 | defsubr (&Sinsert_buffer_substring); | 4350 | defsubr (&Sinsert_buffer_substring); |
| 4328 | defsubr (&Scompare_buffer_substrings); | 4351 | defsubr (&Scompare_buffer_substrings); |
| 4329 | defsubr (&Ssubst_char_in_region); | 4352 | defsubr (&Ssubst_char_in_region); |
| 4330 | defsubr (&Stranslate_region); | 4353 | defsubr (&Stranslate_region_internal); |
| 4331 | defsubr (&Sdelete_region); | 4354 | defsubr (&Sdelete_region); |
| 4332 | defsubr (&Sdelete_and_extract_region); | 4355 | defsubr (&Sdelete_and_extract_region); |
| 4333 | defsubr (&Swiden); | 4356 | defsubr (&Swiden); |