aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard M. Stallman1999-12-23 04:45:26 +0000
committerRichard M. Stallman1999-12-23 04:45:26 +0000
commit68e69fbd441b26c57cd4ecd143fb70596073d8c7 (patch)
treed70d16edf8db90c1c12dbc58cfae609d2de55f3a
parent0b863bd9ea7171a74e5ad887688b2cba2d370809 (diff)
downloademacs-68e69fbd441b26c57cd4ecd143fb70596073d8c7.tar.gz
emacs-68e69fbd441b26c57cd4ecd143fb70596073d8c7.zip
(Freplace_match): For nonliteral replacement,
construct all the new text first, then insert all at once.
-rw-r--r--src/search.c67
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]);