Mercurial > emacs
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 |