diff options
| author | David Kastrup | 2004-06-23 19:22:25 +0000 |
|---|---|---|
| committer | David Kastrup | 2004-06-23 19:22:25 +0000 |
| commit | 41c0120526af39a1b27c784a9aebeeeae6200cde (patch) | |
| tree | 407c3c48b1ffa83ec19914734da62600ca382332 /src | |
| parent | 559cdd07454093b88346f8a41aff36fb58c86236 (diff) | |
| download | emacs-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.c | 120 |
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) | |||
| 2666 | if the last match was on a buffer; integers or nil if a string was matched. | 2671 | if the last match was on a buffer; integers or nil if a string was matched. |
| 2667 | Use `store-match-data' to reinstate the data in this list. | 2672 | Use `store-match-data' to reinstate the data in this list. |
| 2668 | 2673 | ||
| 2669 | If INTEGERS (the optional first argument) is non-nil, always use integers | 2674 | If INTEGERS (the optional first argument) is non-nil, always use |
| 2670 | \(rather than markers) to represent buffer positions. | 2675 | integers \(rather than markers) to represent buffer positions. In |
| 2676 | this case, and if the last match was in a buffer, the buffer will get | ||
| 2677 | stored as one additional element at the end of the list. | ||
| 2678 | |||
| 2671 | If REUSE is a list, reuse it as part of the value. If REUSE is long enough | 2679 | If REUSE is a list, reuse it as part of the value. If REUSE is long enough |
| 2672 | to hold all the values, and if INTEGERS is non-nil, no consing is done. | 2680 | to 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. */ |
| 2837 | static int search_regs_saved; | 2859 | static int search_regs_saved; |
| 2838 | static struct re_registers saved_search_regs; | 2860 | static struct re_registers saved_search_regs; |
| 2861 | static 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 | } |