comparison src/casefiddle.c @ 18005:ad95aa134d60

(casify_object): Handle multibyte characters. (casify_region): Change the way of handling multibyte characters.
author Kenichi Handa <handa@m17n.org>
date Wed, 28 May 1997 04:36:35 +0000
parents 380442ed6a1c
children 015e9e4a90ed
comparison
equal deleted inserted replaced
18004:40ce43a92060 18005:ad95aa134d60
45 45
46 while (1) 46 while (1)
47 { 47 {
48 if (INTEGERP (obj)) 48 if (INTEGERP (obj))
49 { 49 {
50 tem = Faref (current_buffer->downcase_table, obj); 50 c = DOWNCASE (obj);
51 if (EQ (tem, Qidentity)) 51 if (!inword && c == XFASTINT (obj))
52 tem = obj; 52 c = UPCASE1 (obj);
53 if (inword) 53 XSETFASTINT (obj, c);
54 obj = tem;
55 else if (EQ (tem, obj))
56 {
57 tem = Faref (current_buffer->upcase_table, obj);
58 if (!EQ (tem, Qidentity))
59 obj = tem;
60 }
61 return obj; 54 return obj;
62 } 55 }
63 if (STRINGP (obj)) 56 if (STRINGP (obj))
64 { 57 {
58 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
59
65 obj = Fcopy_sequence (obj); 60 obj = Fcopy_sequence (obj);
66 len = XSTRING (obj)->size; 61 len = XSTRING (obj)->size;
67 for (i = 0; i < len; i++) 62 for (i = 0; i < len; i++)
68 { 63 {
69 c = XSTRING (obj)->data[i]; 64 c = XSTRING (obj)->data[i];
65 if (multibyte && c >= 0x80)
66 /* A multibyte character can't be handled in this
67 simple loop. */
68 break;
70 if (inword && flag != CASE_CAPITALIZE_UP) 69 if (inword && flag != CASE_CAPITALIZE_UP)
71 c = DOWNCASE (c); 70 c = DOWNCASE (c);
72 else if (!UPPERCASEP (c) 71 else if (!UPPERCASEP (c)
73 && (!inword || flag != CASE_CAPITALIZE_UP)) 72 && (!inword || flag != CASE_CAPITALIZE_UP))
74 c = UPCASE1 (c); 73 c = UPCASE1 (c);
75 XSTRING (obj)->data[i] = c; 74 XSTRING (obj)->data[i] = c;
76 if ((int) flag >= (int) CASE_CAPITALIZE) 75 if ((int) flag >= (int) CASE_CAPITALIZE)
77 inword = SYNTAX (c) == Sword; 76 inword = SYNTAX (c) == Sword;
78 } 77 }
78 if (i < len)
79 {
80 /* The work is not yet finished because of a multibyte
81 character just encountered. */
82 int fromlen, tolen, j = i;
83 char *buf
84 = (char *) alloca ((len - i) * MAX_LENGTH_OF_MULTI_BYTE_FORM
85 + i);
86 char *str, workbuf[4];
87
88 /* Copy data already handled. */
89 bcopy (XSTRING (obj)->data, buf, i);
90
91 while (i < len)
92 {
93 c = STRING_CHAR_AND_LENGTH (XSTRING (obj)->data + i,
94 len - i, fromlen);
95 if (inword && flag != CASE_CAPITALIZE_UP)
96 c = DOWNCASE (c);
97 else if (!UPPERCASEP (c)
98 && (!inword || flag != CASE_CAPITALIZE_UP))
99 c = UPCASE1 (c);
100 tolen = CHAR_STRING (c, workbuf, str);
101 bcopy (str, buf + j, tolen);
102 i += fromlen;
103 j += tolen;
104 if ((int) flag >= (int) CASE_CAPITALIZE)
105 inword = SYNTAX (c) == Sword;
106 }
107 obj = make_string (buf, j);
108 }
79 return obj; 109 return obj;
80 } 110 }
81 obj = wrong_type_argument (Qchar_or_string_p, obj); 111 obj = wrong_type_argument (Qchar_or_string_p, obj);
82 } 112 }
83 } 113 }
136 Lisp_Object b, e; 166 Lisp_Object b, e;
137 { 167 {
138 register int i; 168 register int i;
139 register int c; 169 register int c;
140 register int inword = flag == CASE_DOWN; 170 register int inword = flag == CASE_DOWN;
171 register int multibyte = !NILP (current_buffer->enable_multibyte_characters);
141 int start, end; 172 int start, end;
142 Lisp_Object ch, downch, val; 173 Lisp_Object ch, downch, val;
143 174
144 if (EQ (b, e)) 175 if (EQ (b, e))
145 /* Not modifying because nothing marked */ 176 /* Not modifying because nothing marked */
153 start = XFASTINT (b); 184 start = XFASTINT (b);
154 end = XFASTINT (e); 185 end = XFASTINT (e);
155 modify_region (current_buffer, start, end); 186 modify_region (current_buffer, start, end);
156 record_change (start, end - start); 187 record_change (start, end - start);
157 188
158 if (NILP (current_buffer->enable_multibyte_characters)) 189 for (i = start; i < end; i++)
159 { 190 {
160 for (i = start; i < end; i++) 191 c = FETCH_BYTE (i);
192 if (multibyte && c >= 0x80)
193 /* A multibyte character can't be handled in this simple loop. */
194 break;
195 if (inword && flag != CASE_CAPITALIZE_UP)
196 c = DOWNCASE (c);
197 else if (!UPPERCASEP (c)
198 && (!inword || flag != CASE_CAPITALIZE_UP))
199 c = UPCASE1 (c);
200 FETCH_BYTE (i) = c;
201 if ((int) flag >= (int) CASE_CAPITALIZE)
202 inword = SYNTAX (c) == Sword;
203 }
204 if (i < end)
205 {
206 /* The work is not yet finished because of a multibyte character
207 just encountered. */
208 int opoint = PT, c2;
209
210 while (i < end)
161 { 211 {
162 c = FETCH_BYTE (i); 212 if ((c = FETCH_BYTE (i)) >= 0x80)
213 c = FETCH_MULTIBYTE_CHAR (i);
214 c2 = c;
163 if (inword && flag != CASE_CAPITALIZE_UP) 215 if (inword && flag != CASE_CAPITALIZE_UP)
164 c = DOWNCASE (c); 216 c2 = DOWNCASE (c);
165 else if (!UPPERCASEP (c) 217 else if (!UPPERCASEP (c)
166 && (!inword || flag != CASE_CAPITALIZE_UP)) 218 && (!inword || flag != CASE_CAPITALIZE_UP))
167 c = UPCASE1 (c); 219 c2 = UPCASE1 (c);
168 FETCH_BYTE (i) = c; 220 if (c != c2)
169 if ((int) flag >= (int) CASE_CAPITALIZE)
170 inword = SYNTAX (c) == Sword;
171 }
172 }
173 else
174 {
175 Lisp_Object down, up;
176 int opoint = PT;
177
178 down = current_buffer->downcase_table;
179 up = current_buffer->upcase_table;
180 for (i = start; i < end;)
181 {
182 c = FETCH_MULTIBYTE_CHAR (i);
183 XSETFASTINT (ch, c);
184 downch = Faref (down, ch);
185 if (EQ (downch, Qidentity))
186 downch = ch;
187 if (inword && flag != CASE_CAPITALIZE_UP)
188 val = downch;
189 else if (EQ (downch, ch)
190 && (!inword || flag != CASE_CAPITALIZE_UP))
191 {
192 val = Faref (up, ch);
193 if (EQ (val, Qidentity))
194 val = ch;
195 }
196 else
197 val = ch;
198 if (!EQ (val, ch))
199 { 221 {
200 int fromlen, tolen, j; 222 int fromlen, tolen, j;
201 char workbuf[4], *str; 223 char workbuf[4], *str;
202 224
203 if (!NATNUMP (val))
204 error ("Inappropriate value found in case table");
205 /* Handle the most likely case */ 225 /* Handle the most likely case */
206 if (c < 0400 && XFASTINT (val) < 0400) 226 if (c < 0400 && c2 < 0400)
207 FETCH_BYTE (i) = XFASTINT (val); 227 FETCH_BYTE (i) = c2;
208 else if (fromlen = CHAR_STRING (c, workbuf, str), 228 else if (fromlen = CHAR_STRING (c, workbuf, str),
209 tolen = CHAR_STRING (XFASTINT (val), workbuf, str), 229 tolen = CHAR_STRING (c2, workbuf, str),
210 fromlen == tolen) 230 fromlen == tolen)
211 { 231 {
212 for (j = 0; j < tolen; ++j) 232 for (j = 0; j < tolen; ++j)
213 FETCH_BYTE (i + j) = str[j]; 233 FETCH_BYTE (i + j) = str[j];
214 } 234 }
225 } 245 }
226 #endif 246 #endif
227 } 247 }
228 } 248 }
229 if ((int) flag >= (int) CASE_CAPITALIZE) 249 if ((int) flag >= (int) CASE_CAPITALIZE)
230 inword = SYNTAX (XFASTINT (val)) == Sword; 250 inword = SYNTAX (c2) == Sword;
231 INC_POS (i); 251 INC_POS (i);
232 } 252 }
233 TEMP_SET_PT (opoint); 253 TEMP_SET_PT (opoint);
234 } 254 }
235 255