aboutsummaryrefslogtreecommitdiffstats
path: root/src/casefiddle.c
diff options
context:
space:
mode:
authorMichal Nazarewicz2016-09-19 01:47:34 +0200
committerMichal Nazarewicz2017-04-06 20:54:57 +0200
commit2c87dabd0460cce83d2345b4ddff159969674fef (patch)
tree1fe96df4dd271c2d53d63b272d877b71a7507bef /src/casefiddle.c
parent13d813b1a093e9039a63b11021a8a92c9c5950d1 (diff)
downloademacs-2c87dabd0460cce83d2345b4ddff159969674fef.tar.gz
emacs-2c87dabd0460cce83d2345b4ddff159969674fef.zip
Split up casify_region function (bug#24603)
No functional changes at this time but splitting casify_region into a function dealing with multibyte and another dealing with unibyte buffers will make future code changes slightly easier. * src/casefiddle.c (casify_region): Move most of the code into two new functions: (do_casify_multibyte_region, do_casify_unibyte_region): new functions.
Diffstat (limited to 'src/casefiddle.c')
-rw-r--r--src/casefiddle.c159
1 files changed, 86 insertions, 73 deletions
diff --git a/src/casefiddle.c b/src/casefiddle.c
index a83469cbdc7..b1a5f8e236e 100644
--- a/src/casefiddle.c
+++ b/src/casefiddle.c
@@ -231,102 +231,115 @@ The argument object is not altered--the value is a copy. */)
231 return casify_object (CASE_CAPITALIZE_UP, obj); 231 return casify_object (CASE_CAPITALIZE_UP, obj);
232} 232}
233 233
234/* flag is CASE_UP, CASE_DOWN or CASE_CAPITALIZE or CASE_CAPITALIZE_UP. 234/* Based on CTX, case region in a unibyte buffer from POS to *ENDP. Return
235 b and e specify range of buffer to operate on. */ 235 first position that has changed and save last position in *ENDP. If no
236 236 characters were changed, return -1 and *ENDP is unspecified. */
237static void 237static ptrdiff_t
238casify_region (enum case_action flag, Lisp_Object b, Lisp_Object e) 238do_casify_unibyte_region (struct casing_context *ctx,
239 ptrdiff_t pos, ptrdiff_t *endp)
239{ 240{
240 bool multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters)); 241 ptrdiff_t first = -1, last = -1; /* Position of first and last changes. */
241 ptrdiff_t start, end; 242 ptrdiff_t end = *endp;
242 ptrdiff_t start_byte; 243 int ch, cased;
243 244
244 /* Position of first and last changes. */ 245 for (; pos < end; ++pos)
245 ptrdiff_t first = -1, last; 246 {
247 ch = FETCH_BYTE (pos);
248 MAKE_CHAR_MULTIBYTE (ch);
246 249
247 ptrdiff_t opoint = PT; 250 cased = case_character (ctx, ch);
248 ptrdiff_t opoint_byte = PT_BYTE; 251 if (cased == ch)
252 continue;
249 253
250 struct casing_context ctx; 254 last = pos;
255 if (first < 0)
256 first = pos;
251 257
252 if (EQ (b, e)) 258 MAKE_CHAR_UNIBYTE (cased);
253 /* Not modifying because nothing marked */ 259 FETCH_BYTE (pos) = cased;
254 return; 260 }
255 261
256 validate_region (&b, &e); 262 *endp = last + 1;
257 start = XFASTINT (b); 263 return first;
258 end = XFASTINT (e); 264}
259 modify_text (start, end);
260 record_change (start, end - start);
261 start_byte = CHAR_TO_BYTE (start);
262 265
263 prepare_casing_context (&ctx, flag, true); 266/* Based on CTX, case region in a multibyte buffer from POS to *ENDP. Return
267 first position that has changed and save last position in *ENDP. If no
268 characters were changed, return -1 and *ENDP is unspecified. */
269static ptrdiff_t
270do_casify_multibyte_region (struct casing_context *ctx,
271 ptrdiff_t pos, ptrdiff_t *endp)
272{
273 ptrdiff_t first = -1, last = -1; /* Position of first and last changes. */
274 ptrdiff_t pos_byte = CHAR_TO_BYTE (pos), end = *endp;
275 ptrdiff_t opoint = PT;
276 int ch, cased, len;
264 277
265 while (start < end) 278 while (pos < end)
266 { 279 {
267 int ch, cased, len; 280 ch = STRING_CHAR_AND_LENGTH (BYTE_POS_ADDR (pos_byte), len);
268 281 cased = case_character (ctx, ch);
269 if (multibyte) 282 if (cased != ch)
270 {
271 ch = FETCH_MULTIBYTE_CHAR (start_byte);
272 len = CHAR_BYTES (ch);
273 }
274 else
275 {
276 ch = FETCH_BYTE (start_byte);
277 MAKE_CHAR_MULTIBYTE (ch);
278 len = 1;
279 }
280 cased = case_character (&ctx, ch);
281 if (ch != cased)
282 { 283 {
283 last = start; 284 last = pos;
284 if (first < 0) 285 if (first < 0)
285 first = start; 286 first = pos;
286 287
287 if (! multibyte) 288 if (ASCII_CHAR_P (cased) && ASCII_CHAR_P (ch))
288 { 289 FETCH_BYTE (pos_byte) = cased;
289 MAKE_CHAR_UNIBYTE (cased);
290 FETCH_BYTE (start_byte) = cased;
291 }
292 else if (ASCII_CHAR_P (cased) && ASCII_CHAR_P (ch))
293 FETCH_BYTE (start_byte) = cased;
294 else 290 else
295 { 291 {
296 int tolen = CHAR_BYTES (cased);
297 int j;
298 unsigned char str[MAX_MULTIBYTE_LENGTH]; 292 unsigned char str[MAX_MULTIBYTE_LENGTH];
299 293 int totlen = CHAR_STRING (cased, str);
300 CHAR_STRING (cased, str); 294 if (len == totlen)
301 if (len == tolen) 295 memcpy (BYTE_POS_ADDR (pos_byte), str, len);
302 {
303 /* Length is unchanged. */
304 for (j = 0; j < len; ++j)
305 FETCH_BYTE (start_byte + j) = str[j];
306 }
307 else 296 else
308 { 297 /* Replace one character with the other(s), keeping text
309 /* Replace one character with the other, 298 properties the same. */
310 keeping text properties the same. */ 299 replace_range_2 (pos, pos_byte, pos + 1, pos_byte + len,
311 replace_range_2 (start, start_byte, 300 (char *) str, 9, totlen, 0);
312 start + 1, start_byte + len, 301 len = totlen;
313 (char *) str, 1, tolen,
314 0);
315 len = tolen;
316 }
317 } 302 }
318 } 303 }
319 start++; 304 pos++;
320 start_byte += len; 305 pos_byte += len;
321 } 306 }
322 307
323 if (PT != opoint) 308 if (PT != opoint)
324 TEMP_SET_PT_BOTH (opoint, opoint_byte); 309 TEMP_SET_PT_BOTH (opoint, CHAR_TO_BYTE (opoint));
310
311 *endp = last;
312 return first;
313}
314
315/* flag is CASE_UP, CASE_DOWN or CASE_CAPITALIZE or CASE_CAPITALIZE_UP.
316 b and e specify range of buffer to operate on. */
317static void
318casify_region (enum case_action flag, Lisp_Object b, Lisp_Object e)
319{
320 struct casing_context ctx;
321 ptrdiff_t start, end;
322
323 if (EQ (b, e))
324 /* Not modifying because nothing marked */
325 return;
326
327 validate_region (&b, &e);
328 start = XFASTINT (b);
329 end = XFASTINT (e);
330 modify_text (start, end);
331 record_change (start, end - start);
332 prepare_casing_context (&ctx, flag, true);
333
334 if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
335 start = do_casify_unibyte_region (&ctx, start, &end);
336 else
337 start = do_casify_multibyte_region (&ctx, start, &end);
325 338
326 if (first >= 0) 339 if (start >= 0)
327 { 340 {
328 signal_after_change (first, last + 1 - first, last + 1 - first); 341 signal_after_change (start, end + 1 - start, end + 1 - start);
329 update_compositions (first, last + 1, CHECK_ALL); 342 update_compositions (start, end + 1, CHECK_ALL);
330 } 343 }
331} 344}
332 345