aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKenichi Handa2002-08-20 03:58:53 +0000
committerKenichi Handa2002-08-20 03:58:53 +0000
commit2422e50a5174bac265f12c7888bf29366dc44a6d (patch)
treeeabcc8d2b646b280e95365a0728704c200044cf3 /src
parent064808ae246cd108c0d410f52937a18d9417f5a6 (diff)
downloademacs-2422e50a5174bac265f12c7888bf29366dc44a6d.tar.gz
emacs-2422e50a5174bac265f12c7888bf29366dc44a6d.zip
(casify_object): Simplified. Handle the case that
the case conversion change the byte length. (casify_region): Likewise
Diffstat (limited to 'src')
-rw-r--r--src/casefiddle.c197
1 files changed, 83 insertions, 114 deletions
diff --git a/src/casefiddle.c b/src/casefiddle.c
index 0f060b8a0ae..31b88d3c15d 100644
--- a/src/casefiddle.c
+++ b/src/casefiddle.c
@@ -37,7 +37,7 @@ casify_object (flag, obj)
37 enum case_action flag; 37 enum case_action flag;
38 Lisp_Object obj; 38 Lisp_Object obj;
39{ 39{
40 register int i, c, len; 40 register int c, c1;
41 register int inword = flag == CASE_DOWN; 41 register int inword = flag == CASE_DOWN;
42 42
43 /* If the case table is flagged as modified, rescan it. */ 43 /* If the case table is flagged as modified, rescan it. */
@@ -51,13 +51,22 @@ casify_object (flag, obj)
51 int flagbits = (CHAR_ALT | CHAR_SUPER | CHAR_HYPER 51 int flagbits = (CHAR_ALT | CHAR_SUPER | CHAR_HYPER
52 | CHAR_SHIFT | CHAR_CTL | CHAR_META); 52 | CHAR_SHIFT | CHAR_CTL | CHAR_META);
53 int flags = XINT (obj) & flagbits; 53 int flags = XINT (obj) & flagbits;
54 int multibyte = ! NILP (current_buffer->enable_multibyte_characters);
54 55
55 c = DOWNCASE (XFASTINT (obj) & ~flagbits); 56 c1 = XFASTINT (obj) & ~flagbits;
56 if (inword) 57 if (! multibyte)
57 XSETFASTINT (obj, c | flags);
58 else if (c == (XFASTINT (obj) & ~flagbits))
59 { 58 {
60 c = UPCASE1 ((XFASTINT (obj) & ~flagbits)); 59 MAKE_CHAR_UNIBYTE (c1);
60 }
61 c = DOWNCASE (c1);
62 if (inword || c == c1)
63 {
64 if (! inword)
65 c = UPCASE1 (c1);
66 if (! multibyte)
67 {
68 MAKE_CHAR_MULTIBYTE (c);
69 }
61 XSETFASTINT (obj, c | flags); 70 XSETFASTINT (obj, c | flags);
62 } 71 }
63 return obj; 72 return obj;
@@ -66,66 +75,44 @@ casify_object (flag, obj)
66 if (STRINGP (obj)) 75 if (STRINGP (obj))
67 { 76 {
68 int multibyte = STRING_MULTIBYTE (obj); 77 int multibyte = STRING_MULTIBYTE (obj);
78 int i, i_byte, len;
79 int size = XSTRING (obj)->size;
69 80
70 obj = Fcopy_sequence (obj); 81 obj = Fcopy_sequence (obj);
71 len = STRING_BYTES (XSTRING (obj)); 82 for (i = i_byte = 0; i < size; i++, i_byte += len)
72
73 /* Scan all single-byte characters from start of string. */
74 for (i = 0; i < len;)
75 { 83 {
76 c = XSTRING (obj)->data[i]; 84 if (multibyte)
77 85 c = STRING_CHAR_AND_LENGTH (XSTRING (obj)->data + i_byte,
78 if (multibyte && c >= 0x80) 86 0, len);
79 /* A multibyte character can't be handled in this 87 else
80 simple loop. */ 88 {
81 break; 89 c = XSTRING (obj)->data[i_byte];
90 len = 1;
91 MAKE_CHAR_MULTIBYTE (c);
92 }
93 c1 = c;
82 if (inword && flag != CASE_CAPITALIZE_UP) 94 if (inword && flag != CASE_CAPITALIZE_UP)
83 c = DOWNCASE (c); 95 c = DOWNCASE (c);
84 else if (!UPPERCASEP (c) 96 else if (!UPPERCASEP (c)
85 && (!inword || flag != CASE_CAPITALIZE_UP)) 97 && (!inword || flag != CASE_CAPITALIZE_UP))
86 c = UPCASE1 (c); 98 c = UPCASE1 (c1);
87 /* If this char won't fit in a single-byte string.
88 fall out to the multibyte case. */
89 if (multibyte ? ! ASCII_BYTE_P (c)
90 : ! SINGLE_BYTE_CHAR_P (c))
91 break;
92
93 XSTRING (obj)->data[i] = c;
94 if ((int) flag >= (int) CASE_CAPITALIZE) 99 if ((int) flag >= (int) CASE_CAPITALIZE)
95 inword = SYNTAX (c) == Sword; 100 inword = SYNTAX (c) == Sword;
96 i++; 101 if (c != c1)
97 }
98
99 /* If we didn't do the whole string as single-byte,
100 scan the rest in a more complex way. */
101 if (i < len)
102 {
103 /* The work is not yet finished because of a multibyte
104 character just encountered. */
105 int fromlen, j_byte = i;
106 char *buf
107 = (char *) alloca ((len - i) * MAX_MULTIBYTE_LENGTH + i);
108
109 /* Copy data already handled. */
110 bcopy (XSTRING (obj)->data, buf, i);
111
112 /* From now on, I counts bytes. */
113 while (i < len)
114 { 102 {
115 c = STRING_CHAR_AND_LENGTH (XSTRING (obj)->data + i, 103 if (! multibyte)
116 len - i, fromlen); 104 {
117 if (inword && flag != CASE_CAPITALIZE_UP) 105 MAKE_CHAR_UNIBYTE (c);
118 c = DOWNCASE (c); 106 XSTRING (obj)->data[i_byte] = c;
119 else if (!UPPERCASEP (c) 107 }
120 && (!inword || flag != CASE_CAPITALIZE_UP)) 108 else if (ASCII_CHAR_P (c1) && ASCII_CHAR_P (c))
121 c = UPCASE1 (c); 109 XSTRING (obj)->data[i_byte] = c;
122 i += fromlen; 110 else
123 j_byte += CHAR_STRING (c, buf + j_byte); 111 {
124 if ((int) flag >= (int) CASE_CAPITALIZE) 112 Faset (obj, make_number (i), make_number (c));
125 inword = SYNTAX (c) == Sword; 113 i_byte += CHAR_BYTES (c) - len;
114 }
126 } 115 }
127 obj = make_multibyte_string (buf, XSTRING (obj)->size,
128 j_byte);
129 } 116 }
130 return obj; 117 return obj;
131 } 118 }
@@ -194,6 +181,8 @@ casify_region (flag, b, e)
194 int start, end; 181 int start, end;
195 int start_byte, end_byte; 182 int start_byte, end_byte;
196 int changed = 0; 183 int changed = 0;
184 int opoint = PT;
185 int opoint_byte = PT_BYTE;
197 186
198 if (EQ (b, e)) 187 if (EQ (b, e))
199 /* Not modifying because nothing marked */ 188 /* Not modifying because nothing marked */
@@ -211,83 +200,63 @@ casify_region (flag, b, e)
211 start_byte = CHAR_TO_BYTE (start); 200 start_byte = CHAR_TO_BYTE (start);
212 end_byte = CHAR_TO_BYTE (end); 201 end_byte = CHAR_TO_BYTE (end);
213 202
214 for (i = start_byte; i < end_byte; i++, start++) 203 while (start < end)
215 { 204 {
216 int c2; 205 int c2, len;
217 c = c2 = FETCH_BYTE (i); 206
218 if (multibyte && c >= 0x80) 207 if (multibyte)
219 /* A multibyte character can't be handled in this simple loop. */ 208 {
220 break; 209 c = FETCH_MULTIBYTE_CHAR (start_byte);
210 len = CHAR_BYTES (c);
211 }
212 else
213 {
214 c = FETCH_BYTE (start_byte);
215 MAKE_CHAR_MULTIBYTE (c);
216 len = 1;
217 }
218 c2 = c;
221 if (inword && flag != CASE_CAPITALIZE_UP) 219 if (inword && flag != CASE_CAPITALIZE_UP)
222 c = DOWNCASE (c); 220 c = DOWNCASE (c);
223 else if (!UPPERCASEP (c) 221 else if (!UPPERCASEP (c)
224 && (!inword || flag != CASE_CAPITALIZE_UP)) 222 && (!inword || flag != CASE_CAPITALIZE_UP))
225 c = UPCASE1 (c); 223 c = UPCASE1 (c);
226 FETCH_BYTE (i) = c;
227 if (c != c2)
228 changed = 1;
229 if ((int) flag >= (int) CASE_CAPITALIZE) 224 if ((int) flag >= (int) CASE_CAPITALIZE)
230 inword = SYNTAX (c) == Sword; 225 inword = SYNTAX (c) == Sword;
231 } 226 if (c != c2)
232 if (i < end_byte)
233 {
234 /* The work is not yet finished because of a multibyte character
235 just encountered. */
236 int opoint = PT;
237 int opoint_byte = PT_BYTE;
238 int c2;
239
240 while (i < end_byte)
241 { 227 {
242 if ((c = FETCH_BYTE (i)) >= 0x80) 228 changed = 1;
243 c = FETCH_MULTIBYTE_CHAR (i); 229 if (! multibyte)
244 c2 = c; 230 {
245 if (inword && flag != CASE_CAPITALIZE_UP) 231 MAKE_CHAR_UNIBYTE (c);
246 c2 = DOWNCASE (c); 232 FETCH_BYTE (start_byte) = c;
247 else if (!UPPERCASEP (c) 233 }
248 && (!inword || flag != CASE_CAPITALIZE_UP)) 234 else if (ASCII_CHAR_P (c2) && ASCII_CHAR_P (c))
249 c2 = UPCASE1 (c); 235 FETCH_BYTE (start_byte) = c;
250 if (c != c2) 236 else if (len == CHAR_BYTES (c))
251 { 237 {
252 int fromlen, tolen, j; 238 int j;
253 unsigned char str[MAX_MULTIBYTE_LENGTH]; 239 unsigned char str[MAX_MULTIBYTE_LENGTH];
254 240
255 changed = 1; 241 CHAR_STRING (c, str);
256 /* Handle the most likely case */ 242 for (j = 0; j < len; ++j)
257 if (multibyte ? (c < 0200 && c2 < 0200) 243 FETCH_BYTE (start_byte + j) = str[j];
258 : (c < 0400 && c2 < 0400)) 244 }
259 FETCH_BYTE (i) = c2; 245 else
260 else if (fromlen = CHAR_STRING (c, str), 246 {
261 tolen = CHAR_STRING (c2, str), 247 TEMP_SET_PT_BOTH (start, start_byte);
262 fromlen == tolen) 248 del_range_2 (start, start_byte, start + 1, start_byte + len, 0);
263 { 249 insert_char (c);
264 for (j = 0; j < tolen; ++j) 250 len = CHAR_BYTES (c);
265 FETCH_BYTE (i + j) = str[j];
266 }
267 else
268 {
269 error ("Can't casify letters that change length");
270#if 0 /* This is approximately what we'd like to be able to do here */
271 if (tolen < fromlen)
272 del_range_1 (i + tolen, i + fromlen, 0, 0);
273 else if (tolen > fromlen)
274 {
275 TEMP_SET_PT (i + fromlen);
276 insert_1 (str + fromlen, tolen - fromlen, 1, 0, 0);
277 }
278#endif
279 }
280 } 251 }
281 if ((int) flag >= (int) CASE_CAPITALIZE)
282 inword = SYNTAX (c2) == Sword;
283 INC_BOTH (start, i);
284 } 252 }
285 TEMP_SET_PT_BOTH (opoint, opoint_byte); 253 start++;
254 start_byte += len;
286 } 255 }
287 256
288 start = XFASTINT (b);
289 if (changed) 257 if (changed)
290 { 258 {
259 start = XFASTINT (b);
291 signal_after_change (start, end - start, end - start); 260 signal_after_change (start, end - start, end - start);
292 update_compositions (start, end, CHECK_ALL); 261 update_compositions (start, end, CHECK_ALL);
293 } 262 }