aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKenichi Handa2004-03-01 06:19:10 +0000
committerKenichi Handa2004-03-01 06:19:10 +0000
commit10475277ce0d5f813792940aabbd270ebd717f02 (patch)
tree9556da817f047dbb8f3bb694c00c96582e0bb0a3 /src
parent83797c58bfe922c1d39fc809722260cc99c579a9 (diff)
downloademacs-10475277ce0d5f813792940aabbd270ebd717f02.tar.gz
emacs-10475277ce0d5f813792940aabbd270ebd717f02.zip
(Ftranslate_region): Handle multibyte chars in the arg
TABLE correctly.
Diffstat (limited to 'src')
-rw-r--r--src/editfns.c37
1 files changed, 25 insertions, 12 deletions
diff --git a/src/editfns.c b/src/editfns.c
index 9a1ce81f316..31493e3c774 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -2741,7 +2741,6 @@ DEFUN ("translate-region", Ftranslate_region, Stranslate_region, 3, 3, 0,
2741 doc: /* From START to END, translate characters according to TABLE. 2741 doc: /* From START to END, translate characters according to TABLE.
2742TABLE is a string; the Nth character in it is the mapping 2742TABLE is a string; the Nth character in it is the mapping
2743for the character with code N. 2743for the character with code N.
2744This function does not alter multibyte characters.
2745It returns the number of characters changed. */) 2744It returns the number of characters changed. */)
2746 (start, end, table) 2745 (start, end, table)
2747 Lisp_Object start; 2746 Lisp_Object start;
@@ -2755,11 +2754,18 @@ It returns the number of characters changed. */)
2755 int size; /* Size of translate table. */ 2754 int size; /* Size of translate table. */
2756 int pos; 2755 int pos;
2757 int multibyte = !NILP (current_buffer->enable_multibyte_characters); 2756 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
2757 int string_multibyte;
2758 2758
2759 validate_region (&start, &end); 2759 validate_region (&start, &end);
2760 CHECK_STRING (table); 2760 CHECK_STRING (table);
2761 2761
2762 size = SBYTES (table); 2762 if (multibyte != (SCHARS (table) < SBYTES (table)))
2763 table = (multibyte
2764 ? string_make_multibyte (table)
2765 : string_make_unibyte (table));
2766 string_multibyte = SCHARS (table) < SBYTES (table);
2767
2768 size = SCHARS (table);
2763 tt = SDATA (table); 2769 tt = SDATA (table);
2764 2770
2765 pos_byte = CHAR_TO_BYTE (XINT (start)); 2771 pos_byte = CHAR_TO_BYTE (XINT (start));
@@ -2771,7 +2777,8 @@ It returns the number of characters changed. */)
2771 for (; pos_byte < stop; ) 2777 for (; pos_byte < stop; )
2772 { 2778 {
2773 register unsigned char *p = BYTE_POS_ADDR (pos_byte); 2779 register unsigned char *p = BYTE_POS_ADDR (pos_byte);
2774 int len; 2780 unsigned char *str;
2781 int len, str_len;
2775 int oc; 2782 int oc;
2776 int pos_byte_next; 2783 int pos_byte_next;
2777 2784
@@ -2780,22 +2787,27 @@ It returns the number of characters changed. */)
2780 else 2787 else
2781 oc = *p, len = 1; 2788 oc = *p, len = 1;
2782 pos_byte_next = pos_byte + len; 2789 pos_byte_next = pos_byte + len;
2783 if (oc < size && len == 1) 2790 if (oc < size)
2784 { 2791 {
2785 nc = tt[oc]; 2792 if (string_multibyte)
2793 {
2794 str = tt + string_char_to_byte (table, oc);
2795 nc = STRING_CHAR_AND_LENGTH (str, MAX_MULTIBYTE_LENGTH, str_len);
2796 }
2797 else
2798 {
2799 str = tt + oc;
2800 nc = tt[oc], str_len = 1;
2801 }
2786 if (nc != oc) 2802 if (nc != oc)
2787 { 2803 {
2788 /* Take care of the case where the new character 2804 /* Take care of the case where the new character
2789 combines with neighboring bytes. */ 2805 combines with neighboring bytes. */
2790 if (!ASCII_BYTE_P (nc) 2806 if (len > 1 || str_len > 1)
2791 && (CHAR_HEAD_P (nc)
2792 ? ! CHAR_HEAD_P (FETCH_BYTE (pos_byte + 1))
2793 : (pos_byte > BEG_BYTE
2794 && ! ASCII_BYTE_P (FETCH_BYTE (pos_byte - 1)))))
2795 { 2807 {
2796 Lisp_Object string; 2808 Lisp_Object string;
2797 2809
2798 string = make_multibyte_string (tt + oc, 1, 1); 2810 string = make_multibyte_string (str, 1, str_len);
2799 /* This is less efficient, because it moves the gap, 2811 /* This is less efficient, because it moves the gap,
2800 but it handles combining correctly. */ 2812 but it handles combining correctly. */
2801 replace_range (pos, pos + 1, string, 2813 replace_range (pos, pos + 1, string,
@@ -2812,7 +2824,8 @@ It returns the number of characters changed. */)
2812 else 2824 else
2813 { 2825 {
2814 record_change (pos, 1); 2826 record_change (pos, 1);
2815 *p = nc; 2827 while (str_len-- > 0)
2828 *p++ = *str++;
2816 signal_after_change (pos, 1, 1); 2829 signal_after_change (pos, 1, 1);
2817 update_compositions (pos, pos + 1, CHECK_BORDER); 2830 update_compositions (pos, pos + 1, CHECK_BORDER);
2818 } 2831 }