aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDavid Kastrup2004-06-23 19:22:25 +0000
committerDavid Kastrup2004-06-23 19:22:25 +0000
commit41c0120526af39a1b27c784a9aebeeeae6200cde (patch)
tree407c3c48b1ffa83ec19914734da62600ca382332 /src
parent559cdd07454093b88346f8a41aff36fb58c86236 (diff)
downloademacs-41c0120526af39a1b27c784a9aebeeeae6200cde.tar.gz
emacs-41c0120526af39a1b27c784a9aebeeeae6200cde.zip
(Freplace_match): Adjust the match-data more
thoroughly when replacing strings in the buffer. search.c (match-data): When INTEGERS is non-nil and the last match was in a buffer, add the buffer as last element to the match data. (Fset_match_data): If an additional element of the match-data is a buffer, restore it to last_thing_searched. (save_search_regs): Save last_thing_searched as part of the match data. (restore_match_data): Restore it again.
Diffstat (limited to 'src')
-rw-r--r--src/search.c120
1 files changed, 73 insertions, 47 deletions
diff --git a/src/search.c b/src/search.c
index ec83065bbc3..dc1ca91e38f 100644
--- a/src/search.c
+++ b/src/search.c
@@ -2589,15 +2589,20 @@ since only regular expressions have distinguished subexpressions. */)
2589 /* Adjust search data for this change. */ 2589 /* Adjust search data for this change. */
2590 { 2590 {
2591 int oldend = search_regs.end[sub]; 2591 int oldend = search_regs.end[sub];
2592 int oldstart = search_regs.start[sub];
2592 int change = newpoint - search_regs.end[sub]; 2593 int change = newpoint - search_regs.end[sub];
2593 int i; 2594 int i;
2594 2595
2595 for (i = 0; i < search_regs.num_regs; i++) 2596 for (i = 0; i < search_regs.num_regs; i++)
2596 { 2597 {
2597 if (search_regs.start[i] > oldend) 2598 if (search_regs.start[i] >= oldend)
2598 search_regs.start[i] += change; 2599 search_regs.start[i] += change;
2599 if (search_regs.end[i] > oldend) 2600 else if (search_regs.start[i] > oldstart)
2601 search_regs.start[i] = oldstart;
2602 if (search_regs.end[i] >= oldend)
2600 search_regs.end[i] += change; 2603 search_regs.end[i] += change;
2604 else if (search_regs.end[i] > oldstart)
2605 search_regs.end[i] = oldstart;
2601 } 2606 }
2602 } 2607 }
2603 2608
@@ -2666,8 +2671,11 @@ All the elements are markers or nil (nil if the Nth pair didn't match)
2666if the last match was on a buffer; integers or nil if a string was matched. 2671if the last match was on a buffer; integers or nil if a string was matched.
2667Use `store-match-data' to reinstate the data in this list. 2672Use `store-match-data' to reinstate the data in this list.
2668 2673
2669If INTEGERS (the optional first argument) is non-nil, always use integers 2674If INTEGERS (the optional first argument) is non-nil, always use
2670\(rather than markers) to represent buffer positions. 2675integers \(rather than markers) to represent buffer positions. In
2676this case, and if the last match was in a buffer, the buffer will get
2677stored as one additional element at the end of the list.
2678
2671If REUSE is a list, reuse it as part of the value. If REUSE is long enough 2679If REUSE is a list, reuse it as part of the value. If REUSE is long enough
2672to hold all the values, and if INTEGERS is non-nil, no consing is done. 2680to hold all the values, and if INTEGERS is non-nil, no consing is done.
2673 2681
@@ -2684,10 +2692,10 @@ Return value is undefined if the last search failed. */)
2684 2692
2685 prev = Qnil; 2693 prev = Qnil;
2686 2694
2687 data = (Lisp_Object *) alloca ((2 * search_regs.num_regs) 2695 data = (Lisp_Object *) alloca ((2 * search_regs.num_regs + 1)
2688 * sizeof (Lisp_Object)); 2696 * sizeof (Lisp_Object));
2689 2697
2690 len = -1; 2698 len = 0;
2691 for (i = 0; i < search_regs.num_regs; i++) 2699 for (i = 0; i < search_regs.num_regs; i++)
2692 { 2700 {
2693 int start = search_regs.start[i]; 2701 int start = search_regs.start[i];
@@ -2714,22 +2722,29 @@ Return value is undefined if the last search failed. */)
2714 /* last_thing_searched must always be Qt, a buffer, or Qnil. */ 2722 /* last_thing_searched must always be Qt, a buffer, or Qnil. */
2715 abort (); 2723 abort ();
2716 2724
2717 len = i; 2725 len = 2*(i+1);
2718 } 2726 }
2719 else 2727 else
2720 data[2 * i] = data [2 * i + 1] = Qnil; 2728 data[2 * i] = data [2 * i + 1] = Qnil;
2721 } 2729 }
2722 2730
2731 if (BUFFERP(last_thing_searched)
2732 && ! NILP (integers))
2733 {
2734 XSETBUFFER(data[len], last_thing_searched);
2735 len++;
2736 }
2737
2723 /* If REUSE is not usable, cons up the values and return them. */ 2738 /* If REUSE is not usable, cons up the values and return them. */
2724 if (! CONSP (reuse)) 2739 if (! CONSP (reuse))
2725 return Flist (2 * len + 2, data); 2740 return Flist (len, data);
2726 2741
2727 /* If REUSE is a list, store as many value elements as will fit 2742 /* If REUSE is a list, store as many value elements as will fit
2728 into the elements of REUSE. */ 2743 into the elements of REUSE. */
2729 for (i = 0, tail = reuse; CONSP (tail); 2744 for (i = 0, tail = reuse; CONSP (tail);
2730 i++, tail = XCDR (tail)) 2745 i++, tail = XCDR (tail))
2731 { 2746 {
2732 if (i < 2 * len + 2) 2747 if (i < len)
2733 XSETCAR (tail, data[i]); 2748 XSETCAR (tail, data[i]);
2734 else 2749 else
2735 XSETCAR (tail, Qnil); 2750 XSETCAR (tail, Qnil);
@@ -2738,8 +2753,8 @@ Return value is undefined if the last search failed. */)
2738 2753
2739 /* If we couldn't fit all value elements into REUSE, 2754 /* If we couldn't fit all value elements into REUSE,
2740 cons up the rest of them and add them to the end of REUSE. */ 2755 cons up the rest of them and add them to the end of REUSE. */
2741 if (i < 2 * len + 2) 2756 if (i < len)
2742 XSETCDR (prev, Flist (2 * len + 2 - i, data + i)); 2757 XSETCDR (prev, Flist (len - i, data + i));
2743 2758
2744 return reuse; 2759 return reuse;
2745} 2760}
@@ -2760,8 +2775,8 @@ LIST should have been created by calling `match-data' previously. */)
2760 if (!CONSP (list) && !NILP (list)) 2775 if (!CONSP (list) && !NILP (list))
2761 list = wrong_type_argument (Qconsp, list); 2776 list = wrong_type_argument (Qconsp, list);
2762 2777
2763 /* Unless we find a marker with a buffer in LIST, assume that this 2778 /* Unless we find a marker with a buffer or an explicit buffer
2764 match data came from a string. */ 2779 in LIST, assume that this match data came from a string. */
2765 last_thing_searched = Qt; 2780 last_thing_searched = Qt;
2766 2781
2767 /* Allocate registers if they don't already exist. */ 2782 /* Allocate registers if they don't already exist. */
@@ -2792,42 +2807,49 @@ LIST should have been created by calling `match-data' previously. */)
2792 2807
2793 search_regs.num_regs = length; 2808 search_regs.num_regs = length;
2794 } 2809 }
2795 }
2796
2797 for (i = 0; i < search_regs.num_regs; i++)
2798 {
2799 marker = Fcar (list);
2800 if (NILP (marker))
2801 {
2802 search_regs.start[i] = -1;
2803 list = Fcdr (list);
2804 }
2805 else
2806 {
2807 int from;
2808
2809 if (MARKERP (marker))
2810 {
2811 if (XMARKER (marker)->buffer == 0)
2812 XSETFASTINT (marker, 0);
2813 else
2814 XSETBUFFER (last_thing_searched, XMARKER (marker)->buffer);
2815 }
2816 2810
2817 CHECK_NUMBER_COERCE_MARKER (marker); 2811 for (i = 0; i < length; i++)
2818 from = XINT (marker); 2812 {
2819 list = Fcdr (list); 2813 marker = Fcar (list);
2814 if (NILP (marker))
2815 {
2816 search_regs.start[i] = -1;
2817 list = Fcdr (list);
2818 }
2819 else
2820 {
2821 int from;
2822
2823 if (MARKERP (marker))
2824 {
2825 if (XMARKER (marker)->buffer == 0)
2826 XSETFASTINT (marker, 0);
2827 else
2828 XSETBUFFER (last_thing_searched, XMARKER (marker)->buffer);
2829 }
2830
2831 CHECK_NUMBER_COERCE_MARKER (marker);
2832 from = XINT (marker);
2833 list = Fcdr (list);
2834
2835 marker = Fcar (list);
2836 if (MARKERP (marker) && XMARKER (marker)->buffer == 0)
2837 XSETFASTINT (marker, 0);
2838
2839 CHECK_NUMBER_COERCE_MARKER (marker);
2840 search_regs.start[i] = from;
2841 search_regs.end[i] = XINT (marker);
2842 }
2843 list = Fcdr (list);
2844 }
2820 2845
2821 marker = Fcar (list); 2846 for (; i < search_regs.num_regs; i++)
2822 if (MARKERP (marker) && XMARKER (marker)->buffer == 0) 2847 search_regs.start[i] = -1;
2823 XSETFASTINT (marker, 0); 2848 }
2824 2849
2825 CHECK_NUMBER_COERCE_MARKER (marker); 2850 if (CONSP(list) && BUFFERP(XCAR(list))) {
2826 search_regs.start[i] = from; 2851 XSETBUFFER(last_thing_searched, XCAR(list));
2827 search_regs.end[i] = XINT (marker); 2852 }
2828 }
2829 list = Fcdr (list);
2830 }
2831 2853
2832 return Qnil; 2854 return Qnil;
2833} 2855}
@@ -2836,6 +2858,7 @@ LIST should have been created by calling `match-data' previously. */)
2836 during the execution of a sentinel or filter. */ 2858 during the execution of a sentinel or filter. */
2837static int search_regs_saved; 2859static int search_regs_saved;
2838static struct re_registers saved_search_regs; 2860static struct re_registers saved_search_regs;
2861static Lisp_Object saved_last_thing_searched;
2839 2862
2840/* Called from Flooking_at, Fstring_match, search_buffer, Fstore_match_data 2863/* Called from Flooking_at, Fstring_match, search_buffer, Fstore_match_data
2841 if asynchronous code (filter or sentinel) is running. */ 2864 if asynchronous code (filter or sentinel) is running. */
@@ -2847,6 +2870,8 @@ save_search_regs ()
2847 saved_search_regs.num_regs = search_regs.num_regs; 2870 saved_search_regs.num_regs = search_regs.num_regs;
2848 saved_search_regs.start = search_regs.start; 2871 saved_search_regs.start = search_regs.start;
2849 saved_search_regs.end = search_regs.end; 2872 saved_search_regs.end = search_regs.end;
2873 saved_last_thing_searched = last_thing_searched;
2874 last_thing_searched = Qnil;
2850 search_regs.num_regs = 0; 2875 search_regs.num_regs = 0;
2851 search_regs.start = 0; 2876 search_regs.start = 0;
2852 search_regs.end = 0; 2877 search_regs.end = 0;
@@ -2869,7 +2894,8 @@ restore_match_data ()
2869 search_regs.num_regs = saved_search_regs.num_regs; 2894 search_regs.num_regs = saved_search_regs.num_regs;
2870 search_regs.start = saved_search_regs.start; 2895 search_regs.start = saved_search_regs.start;
2871 search_regs.end = saved_search_regs.end; 2896 search_regs.end = saved_search_regs.end;
2872 2897 last_thing_searched = saved_last_thing_searched;
2898 saved_last_thing_searched = Qnil;
2873 search_regs_saved = 0; 2899 search_regs_saved = 0;
2874 } 2900 }
2875} 2901}