diff options
| author | Michal Nazarewicz | 2016-09-19 01:47:34 +0200 |
|---|---|---|
| committer | Michal Nazarewicz | 2017-04-06 20:54:57 +0200 |
| commit | 2c87dabd0460cce83d2345b4ddff159969674fef (patch) | |
| tree | 1fe96df4dd271c2d53d63b272d877b71a7507bef /src | |
| parent | 13d813b1a093e9039a63b11021a8a92c9c5950d1 (diff) | |
| download | emacs-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')
| -rw-r--r-- | src/casefiddle.c | 159 |
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. */ | |
| 237 | static void | 237 | static ptrdiff_t |
| 238 | casify_region (enum case_action flag, Lisp_Object b, Lisp_Object e) | 238 | do_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. */ | ||
| 269 | static ptrdiff_t | ||
| 270 | do_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. */ | ||
| 317 | static void | ||
| 318 | casify_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 | ||