diff options
| author | Richard M. Stallman | 1999-12-23 04:45:26 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1999-12-23 04:45:26 +0000 |
| commit | 68e69fbd441b26c57cd4ecd143fb70596073d8c7 (patch) | |
| tree | d70d16edf8db90c1c12dbc58cfae609d2de55f3a /src | |
| parent | 0b863bd9ea7171a74e5ad887688b2cba2d370809 (diff) | |
| download | emacs-68e69fbd441b26c57cd4ecd143fb70596073d8c7.tar.gz emacs-68e69fbd441b26c57cd4ecd143fb70596073d8c7.zip | |
(Freplace_match): For nonliteral replacement,
construct all the new text first, then insert all at once.
Diffstat (limited to 'src')
| -rw-r--r-- | src/search.c | 67 |
1 files changed, 53 insertions, 14 deletions
diff --git a/src/search.c b/src/search.c index 7fb3a78666f..ccfc66003a2 100644 --- a/src/search.c +++ b/src/search.c | |||
| @@ -2426,42 +2426,81 @@ since only regular expressions have distinguished subexpressions.") | |||
| 2426 | Finsert_and_inherit (1, &newtext); | 2426 | Finsert_and_inherit (1, &newtext); |
| 2427 | else | 2427 | else |
| 2428 | { | 2428 | { |
| 2429 | struct gcpro gcpro1; | ||
| 2430 | int length = STRING_BYTES (XSTRING (newtext)); | 2429 | int length = STRING_BYTES (XSTRING (newtext)); |
| 2430 | unsigned char *substed; | ||
| 2431 | int substed_alloc_size, substed_len; | ||
| 2431 | 2432 | ||
| 2432 | GCPRO1 (newtext); | 2433 | substed_alloc_size = length * 2 + 100; |
| 2434 | substed = (unsigned char *) xmalloc (substed_alloc_size + 1); | ||
| 2435 | substed_len = 0; | ||
| 2436 | |||
| 2437 | /* Go thru NEWTEXT, producing the actual text to insert in SUBSTED. */ | ||
| 2433 | 2438 | ||
| 2434 | for (pos_byte = 0, pos = 0; pos_byte < length;) | 2439 | for (pos_byte = 0, pos = 0; pos_byte < length;) |
| 2435 | { | 2440 | { |
| 2436 | int offset = PT - search_regs.start[sub]; | 2441 | unsigned char str[MAX_MULTIBYTE_LENGTH]; |
| 2442 | unsigned char *add_stuff; | ||
| 2443 | int add_len; | ||
| 2444 | int idx = -1; | ||
| 2437 | 2445 | ||
| 2438 | FETCH_STRING_CHAR_ADVANCE (c, newtext, pos, pos_byte); | 2446 | FETCH_STRING_CHAR_ADVANCE (c, newtext, pos, pos_byte); |
| 2439 | 2447 | ||
| 2448 | /* Either set ADD_STUFF and ADD_LEN to the text to put in SUBSTED, | ||
| 2449 | or set IDX to a match index, which means put that part | ||
| 2450 | of the buffer text into SUBSTED. */ | ||
| 2451 | |||
| 2440 | if (c == '\\') | 2452 | if (c == '\\') |
| 2441 | { | 2453 | { |
| 2442 | FETCH_STRING_CHAR_ADVANCE (c, newtext, pos, pos_byte); | 2454 | FETCH_STRING_CHAR_ADVANCE (c, newtext, pos, pos_byte); |
| 2443 | if (c == '&') | 2455 | if (c == '&') |
| 2444 | Finsert_buffer_substring | 2456 | idx = sub; |
| 2445 | (Fcurrent_buffer (), | ||
| 2446 | make_number (search_regs.start[sub] + offset), | ||
| 2447 | make_number (search_regs.end[sub] + offset)); | ||
| 2448 | else if (c >= '1' && c <= '9' && c <= search_regs.num_regs + '0') | 2457 | else if (c >= '1' && c <= '9' && c <= search_regs.num_regs + '0') |
| 2449 | { | 2458 | { |
| 2450 | if (search_regs.start[c - '0'] >= 1) | 2459 | if (search_regs.start[c - '0'] >= 1) |
| 2451 | Finsert_buffer_substring | 2460 | idx = c - '0'; |
| 2452 | (Fcurrent_buffer (), | ||
| 2453 | make_number (search_regs.start[c - '0'] + offset), | ||
| 2454 | make_number (search_regs.end[c - '0'] + offset)); | ||
| 2455 | } | 2461 | } |
| 2456 | else if (c == '\\') | 2462 | else if (c == '\\') |
| 2457 | insert_char (c); | 2463 | add_len = 1, add_stuff = "\\"; |
| 2458 | else | 2464 | else |
| 2459 | error ("Invalid use of `\\' in replacement text"); | 2465 | error ("Invalid use of `\\' in replacement text"); |
| 2460 | } | 2466 | } |
| 2461 | else | 2467 | else |
| 2462 | insert_char (c); | 2468 | { |
| 2469 | add_len = CHAR_STRING (c, str); | ||
| 2470 | add_stuff = str; | ||
| 2471 | } | ||
| 2472 | |||
| 2473 | /* If we want to copy part of a previous match, | ||
| 2474 | set up ADD_STUFF and ADD_LEN to point to it. */ | ||
| 2475 | if (idx >= 0) | ||
| 2476 | { | ||
| 2477 | int begbyte = CHAR_TO_BYTE (search_regs.start[idx]); | ||
| 2478 | add_len = CHAR_TO_BYTE (search_regs.end[idx]) - begbyte; | ||
| 2479 | if (search_regs.start[idx] < GPT && GPT < search_regs.end[idx]) | ||
| 2480 | move_gap (search_regs.start[idx]); | ||
| 2481 | add_stuff = BYTE_POS_ADDR (begbyte); | ||
| 2482 | } | ||
| 2483 | |||
| 2484 | /* Now the stuff we want to add to SUBSTED | ||
| 2485 | is invariably ADD_LEN bytes starting at ADD_STUFF. */ | ||
| 2486 | |||
| 2487 | /* Make sure SUBSTED is big enough. */ | ||
| 2488 | if (substed_len + add_len >= substed_alloc_size) | ||
| 2489 | { | ||
| 2490 | substed_alloc_size = substed_len + add_len + 500; | ||
| 2491 | substed = (unsigned char *) xrealloc (substed, | ||
| 2492 | substed_alloc_size + 1); | ||
| 2493 | } | ||
| 2494 | |||
| 2495 | /* Now add to the end of SUBSTED. */ | ||
| 2496 | bcopy (add_stuff, substed + substed_len, add_len); | ||
| 2497 | substed_len += add_len; | ||
| 2463 | } | 2498 | } |
| 2464 | UNGCPRO; | 2499 | |
| 2500 | /* Now insert what we accumulated. */ | ||
| 2501 | insert_and_inherit (substed, substed_len); | ||
| 2502 | |||
| 2503 | xfree (substed); | ||
| 2465 | } | 2504 | } |
| 2466 | 2505 | ||
| 2467 | inslen = PT - (search_regs.start[sub]); | 2506 | inslen = PT - (search_regs.start[sub]); |