aboutsummaryrefslogtreecommitdiffstats
path: root/src/casefiddle.c
diff options
context:
space:
mode:
authorKenichi Handa2003-09-08 12:53:41 +0000
committerKenichi Handa2003-09-08 12:53:41 +0000
commit8f924df7df019cce90537647de2627581043b5c4 (patch)
tree6c40bd05679425e710d6b2e5649eae3da5e40a52 /src/casefiddle.c
parent463f5630a5e7cbe7f042bc1175d1fa1c4e98860f (diff)
parent9d4807432a01f9b3cc519fcfa3ea92a70ffa7f43 (diff)
downloademacs-8f924df7df019cce90537647de2627581043b5c4.tar.gz
emacs-8f924df7df019cce90537647de2627581043b5c4.zip
*** empty log message ***
Diffstat (limited to 'src/casefiddle.c')
-rw-r--r--src/casefiddle.c201
1 files changed, 84 insertions, 117 deletions
diff --git a/src/casefiddle.c b/src/casefiddle.c
index 8b92d39cbb3..1e502af9c02 100644
--- a/src/casefiddle.c
+++ b/src/casefiddle.c
@@ -22,7 +22,7 @@ Boston, MA 02111-1307, USA. */
22#include <config.h> 22#include <config.h>
23#include "lisp.h" 23#include "lisp.h"
24#include "buffer.h" 24#include "buffer.h"
25#include "charset.h" 25#include "character.h"
26#include "commands.h" 26#include "commands.h"
27#include "syntax.h" 27#include "syntax.h"
28#include "composite.h" 28#include "composite.h"
@@ -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,18 @@ 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 MAKE_CHAR_MULTIBYTE (c1);
58 else if (c == (XFASTINT (obj) & ~flagbits)) 59 c = DOWNCASE (c1);
60 if (inword || c == c1)
59 { 61 {
60 c = UPCASE1 ((XFASTINT (obj) & ~flagbits)); 62 if (! inword)
63 c = UPCASE1 (c1);
64 if (! multibyte)
65 MAKE_CHAR_UNIBYTE (c);
61 XSETFASTINT (obj, c | flags); 66 XSETFASTINT (obj, c | flags);
62 } 67 }
63 return obj; 68 return obj;
@@ -66,66 +71,43 @@ casify_object (flag, obj)
66 if (STRINGP (obj)) 71 if (STRINGP (obj))
67 { 72 {
68 int multibyte = STRING_MULTIBYTE (obj); 73 int multibyte = STRING_MULTIBYTE (obj);
74 int i, i_byte, len;
75 int size = SCHARS (obj);
69 76
70 obj = Fcopy_sequence (obj); 77 obj = Fcopy_sequence (obj);
71 len = SBYTES (obj); 78 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 { 79 {
76 c = SREF (obj, i); 80 if (multibyte)
77 81 c = STRING_CHAR_AND_LENGTH (SDATA (obj) + i_byte, 0, len);
78 if (multibyte && c >= 0x80) 82 else
79 /* A multibyte character can't be handled in this 83 {
80 simple loop. */ 84 c = SREF (obj, i_byte);
81 break; 85 len = 1;
86 MAKE_CHAR_MULTIBYTE (c);
87 }
88 c1 = c;
82 if (inword && flag != CASE_CAPITALIZE_UP) 89 if (inword && flag != CASE_CAPITALIZE_UP)
83 c = DOWNCASE (c); 90 c = DOWNCASE (c);
84 else if (!UPPERCASEP (c) 91 else if (!UPPERCASEP (c)
85 && (!inword || flag != CASE_CAPITALIZE_UP)) 92 && (!inword || flag != CASE_CAPITALIZE_UP))
86 c = UPCASE1 (c); 93 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 SSET (obj, i, c);
94 if ((int) flag >= (int) CASE_CAPITALIZE) 94 if ((int) flag >= (int) CASE_CAPITALIZE)
95 inword = SYNTAX (c) == Sword; 95 inword = (SYNTAX (c) == Sword);
96 i++; 96 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 (SDATA (obj), buf, i);
111
112 /* From now on, I counts bytes. */
113 while (i < len)
114 { 97 {
115 c = STRING_CHAR_AND_LENGTH (SDATA (obj) + i, 98 if (! multibyte)
116 len - i, fromlen); 99 {
117 if (inword && flag != CASE_CAPITALIZE_UP) 100 MAKE_CHAR_UNIBYTE (c);
118 c = DOWNCASE (c); 101 SSET (obj, i_byte, c);
119 else if (!UPPERCASEP (c) 102 }
120 && (!inword || flag != CASE_CAPITALIZE_UP)) 103 else if (ASCII_CHAR_P (c1) && ASCII_CHAR_P (c))
121 c = UPCASE1 (c); 104 SSET (obj, i_byte, c);
122 i += fromlen; 105 else
123 j_byte += CHAR_STRING (c, buf + j_byte); 106 {
124 if ((int) flag >= (int) CASE_CAPITALIZE) 107 Faset (obj, make_number (i), make_number (c));
125 inword = SYNTAX (c) == Sword; 108 i_byte += CHAR_BYTES (c) - len;
109 }
126 } 110 }
127 obj = make_multibyte_string (buf, SCHARS (obj),
128 j_byte);
129 } 111 }
130 return obj; 112 return obj;
131 } 113 }
@@ -187,13 +169,14 @@ casify_region (flag, b, e)
187 enum case_action flag; 169 enum case_action flag;
188 Lisp_Object b, e; 170 Lisp_Object b, e;
189{ 171{
190 register int i;
191 register int c; 172 register int c;
192 register int inword = flag == CASE_DOWN; 173 register int inword = flag == CASE_DOWN;
193 register int multibyte = !NILP (current_buffer->enable_multibyte_characters); 174 register int multibyte = !NILP (current_buffer->enable_multibyte_characters);
194 int start, end; 175 int start, end;
195 int start_byte, end_byte; 176 int start_byte, end_byte;
196 int changed = 0; 177 int changed = 0;
178 int opoint = PT;
179 int opoint_byte = PT_BYTE;
197 180
198 if (EQ (b, e)) 181 if (EQ (b, e))
199 /* Not modifying because nothing marked */ 182 /* Not modifying because nothing marked */
@@ -211,82 +194,66 @@ casify_region (flag, b, e)
211 start_byte = CHAR_TO_BYTE (start); 194 start_byte = CHAR_TO_BYTE (start);
212 end_byte = CHAR_TO_BYTE (end); 195 end_byte = CHAR_TO_BYTE (end);
213 196
214 for (i = start_byte; i < end_byte; i++, start++) 197 while (start < end)
215 { 198 {
216 int c2; 199 int c2, len;
217 c = c2 = FETCH_BYTE (i); 200
218 if (multibyte && c >= 0x80) 201 if (multibyte)
219 /* A multibyte character can't be handled in this simple loop. */ 202 {
220 break; 203 c = FETCH_MULTIBYTE_CHAR (start_byte);
204 len = CHAR_BYTES (c);
205 }
206 else
207 {
208 c = FETCH_BYTE (start_byte);
209 MAKE_CHAR_MULTIBYTE (c);
210 len = 1;
211 }
212 c2 = c;
221 if (inword && flag != CASE_CAPITALIZE_UP) 213 if (inword && flag != CASE_CAPITALIZE_UP)
222 c = DOWNCASE (c); 214 c = DOWNCASE (c);
223 else if (!UPPERCASEP (c) 215 else if (!UPPERCASEP (c)
224 && (!inword || flag != CASE_CAPITALIZE_UP)) 216 && (!inword || flag != CASE_CAPITALIZE_UP))
225 c = UPCASE1 (c); 217 c = UPCASE1 (c);
226 FETCH_BYTE (i) = c;
227 if (c != c2)
228 changed = 1;
229 if ((int) flag >= (int) CASE_CAPITALIZE) 218 if ((int) flag >= (int) CASE_CAPITALIZE)
230 inword = SYNTAX (c) == Sword && (inword || !SYNTAX_PREFIX (c)); 219 inword = ((SYNTAX (c) == Sword) && (inword || !SYNTAX_PREFIX (c)));
231 } 220 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 { 221 {
242 if ((c = FETCH_BYTE (i)) >= 0x80) 222 changed = 1;
243 c = FETCH_MULTIBYTE_CHAR (i); 223 if (! multibyte)
244 c2 = c;
245 if (inword && flag != CASE_CAPITALIZE_UP)
246 c2 = DOWNCASE (c);
247 else if (!UPPERCASEP (c)
248 && (!inword || flag != CASE_CAPITALIZE_UP))
249 c2 = UPCASE1 (c);
250 if (c != c2)
251 { 224 {
252 int fromlen, tolen, j; 225 MAKE_CHAR_UNIBYTE (c);
226 FETCH_BYTE (start_byte) = c;
227 }
228 else if (ASCII_CHAR_P (c2) && ASCII_CHAR_P (c))
229 FETCH_BYTE (start_byte) = c;
230 else if (len == CHAR_BYTES (c))
231 {
232 int j;
253 unsigned char str[MAX_MULTIBYTE_LENGTH]; 233 unsigned char str[MAX_MULTIBYTE_LENGTH];
254 234
255 changed = 1; 235 CHAR_STRING (c, str);
256 /* Handle the most likely case */ 236 for (j = 0; j < len; ++j)
257 if (c < 0400 && c2 < 0400) 237 FETCH_BYTE (start_byte + j) = str[j];
258 FETCH_BYTE (i) = c2; 238 }
259 else if (fromlen = CHAR_STRING (c, str), 239 else
260 tolen = CHAR_STRING (c2, str), 240 {
261 fromlen == tolen) 241 TEMP_SET_PT_BOTH (start, start_byte);
262 { 242 del_range_2 (start, start_byte, start + 1, start_byte + len, 0);
263 for (j = 0; j < tolen; ++j) 243 insert_char (c);
264 FETCH_BYTE (i + j) = str[j]; 244 len = CHAR_BYTES (c);
265 }
266 else
267 {
268 error ("Can't casify letters that change length");
269#if 0 /* This is approximately what we'd like to be able to do here */
270 if (tolen < fromlen)
271 del_range_1 (i + tolen, i + fromlen, 0, 0);
272 else if (tolen > fromlen)
273 {
274 TEMP_SET_PT (i + fromlen);
275 insert_1 (str + fromlen, tolen - fromlen, 1, 0, 0);
276 }
277#endif
278 }
279 } 245 }
280 if ((int) flag >= (int) CASE_CAPITALIZE)
281 inword = SYNTAX (c2) == Sword;
282 INC_BOTH (start, i);
283 } 246 }
284 TEMP_SET_PT_BOTH (opoint, opoint_byte); 247 start++;
248 start_byte += len;
285 } 249 }
286 250
287 start = XFASTINT (b); 251 if (PT != opoint)
252 TEMP_SET_PT_BOTH (opoint, opoint_byte);
253
288 if (changed) 254 if (changed)
289 { 255 {
256 start = XFASTINT (b);
290 signal_after_change (start, end - start, end - start); 257 signal_after_change (start, end - start, end - start);
291 update_compositions (start, end, CHECK_ALL); 258 update_compositions (start, end, CHECK_ALL);
292 } 259 }