# HG changeset patch # User Kenichi Handa # Date 1078121950 0 # Node ID 29d4d158e5ebcda775c6aa039dac0b062b792764 # Parent ba850aa09d2d25bed5a3ffdc947d50c13bec8a53 (Ftranslate_region): Handle multibyte chars in the arg TABLE correctly. diff -r ba850aa09d2d -r 29d4d158e5eb src/editfns.c --- a/src/editfns.c Mon Mar 01 04:12:47 2004 +0000 +++ b/src/editfns.c Mon Mar 01 06:19:10 2004 +0000 @@ -2741,7 +2741,6 @@ doc: /* From START to END, translate characters according to TABLE. TABLE is a string; the Nth character in it is the mapping for the character with code N. -This function does not alter multibyte characters. It returns the number of characters changed. */) (start, end, table) Lisp_Object start; @@ -2755,11 +2754,18 @@ int size; /* Size of translate table. */ int pos; int multibyte = !NILP (current_buffer->enable_multibyte_characters); + int string_multibyte; validate_region (&start, &end); CHECK_STRING (table); - size = SBYTES (table); + if (multibyte != (SCHARS (table) < SBYTES (table))) + table = (multibyte + ? string_make_multibyte (table) + : string_make_unibyte (table)); + string_multibyte = SCHARS (table) < SBYTES (table); + + size = SCHARS (table); tt = SDATA (table); pos_byte = CHAR_TO_BYTE (XINT (start)); @@ -2771,7 +2777,8 @@ for (; pos_byte < stop; ) { register unsigned char *p = BYTE_POS_ADDR (pos_byte); - int len; + unsigned char *str; + int len, str_len; int oc; int pos_byte_next; @@ -2780,22 +2787,27 @@ else oc = *p, len = 1; pos_byte_next = pos_byte + len; - if (oc < size && len == 1) + if (oc < size) { - nc = tt[oc]; + if (string_multibyte) + { + str = tt + string_char_to_byte (table, oc); + nc = STRING_CHAR_AND_LENGTH (str, MAX_MULTIBYTE_LENGTH, str_len); + } + else + { + str = tt + oc; + nc = tt[oc], str_len = 1; + } if (nc != oc) { /* Take care of the case where the new character combines with neighboring bytes. */ - if (!ASCII_BYTE_P (nc) - && (CHAR_HEAD_P (nc) - ? ! CHAR_HEAD_P (FETCH_BYTE (pos_byte + 1)) - : (pos_byte > BEG_BYTE - && ! ASCII_BYTE_P (FETCH_BYTE (pos_byte - 1))))) + if (len > 1 || str_len > 1) { Lisp_Object string; - string = make_multibyte_string (tt + oc, 1, 1); + string = make_multibyte_string (str, 1, str_len); /* This is less efficient, because it moves the gap, but it handles combining correctly. */ replace_range (pos, pos + 1, string, @@ -2812,7 +2824,8 @@ else { record_change (pos, 1); - *p = nc; + while (str_len-- > 0) + *p++ = *str++; signal_after_change (pos, 1, 1); update_compositions (pos, pos + 1, CHECK_BORDER); }