aboutsummaryrefslogtreecommitdiffstats
path: root/src/search.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/search.c')
-rw-r--r--src/search.c96
1 files changed, 78 insertions, 18 deletions
diff --git a/src/search.c b/src/search.c
index 73ec3a78e58..c1f2fd77cec 100644
--- a/src/search.c
+++ b/src/search.c
@@ -2739,7 +2739,7 @@ Zero means the entire text matched by the whole regexp or whole string. */)
2739 return match_limit (subexp, 0); 2739 return match_limit (subexp, 0);
2740} 2740}
2741 2741
2742DEFUN ("match-data", Fmatch_data, Smatch_data, 0, 2, 0, 2742DEFUN ("match-data", Fmatch_data, Smatch_data, 0, 3, 0,
2743 doc: /* Return a list containing all info on what the last search matched. 2743 doc: /* Return a list containing all info on what the last search matched.
2744Element 2N is `(match-beginning N)'; element 2N + 1 is `(match-end N)'. 2744Element 2N is `(match-beginning N)'; element 2N + 1 is `(match-end N)'.
2745All the elements are markers or nil (nil if the Nth pair didn't match) 2745All the elements are markers or nil (nil if the Nth pair didn't match)
@@ -2751,17 +2751,35 @@ integers \(rather than markers) to represent buffer positions. In
2751this case, and if the last match was in a buffer, the buffer will get 2751this case, and if the last match was in a buffer, the buffer will get
2752stored as one additional element at the end of the list. 2752stored as one additional element at the end of the list.
2753 2753
2754If REUSE is a list, reuse it as part of the value. If REUSE is long enough 2754If REUSE is a list, reuse it as part of the value. If REUSE is long
2755to hold all the values, and if INTEGERS is non-nil, no consing is done. 2755enough to hold all the values, and if INTEGERS is non-nil, no consing
2756is done.
2757
2758If optional third arg RESEAT is non-nil, any previous markers on the
2759REUSE list will be modified to point to nowhere.
2760
2761If RESEAT is `evaporate', put markers back on the free list.
2762Note: No other references to the markers must exist if you use this.
2756 2763
2757Return value is undefined if the last search failed. */) 2764Return value is undefined if the last search failed. */)
2758 (integers, reuse) 2765 (integers, reuse, reseat)
2759 Lisp_Object integers, reuse; 2766 Lisp_Object integers, reuse, reseat;
2760{ 2767{
2761 Lisp_Object tail, prev; 2768 Lisp_Object tail, prev;
2762 Lisp_Object *data; 2769 Lisp_Object *data;
2763 int i, len; 2770 int i, len;
2764 2771
2772 if (!NILP (reseat))
2773 for (tail = reuse; CONSP (tail); tail = XCDR (tail))
2774 if (MARKERP (XCAR (tail)))
2775 {
2776 if (EQ (reseat, Qevaporate))
2777 free_marker (XCAR (tail));
2778 else
2779 unchain_marker (XMARKER (XCAR (tail)));
2780 XSETCAR (tail, Qnil);
2781 }
2782
2765 if (NILP (last_thing_searched)) 2783 if (NILP (last_thing_searched))
2766 return Qnil; 2784 return Qnil;
2767 2785
@@ -2797,10 +2815,10 @@ Return value is undefined if the last search failed. */)
2797 /* last_thing_searched must always be Qt, a buffer, or Qnil. */ 2815 /* last_thing_searched must always be Qt, a buffer, or Qnil. */
2798 abort (); 2816 abort ();
2799 2817
2800 len = 2*(i+1); 2818 len = 2 * i + 2;
2801 } 2819 }
2802 else 2820 else
2803 data[2 * i] = data [2 * i + 1] = Qnil; 2821 data[2 * i] = data[2 * i + 1] = Qnil;
2804 } 2822 }
2805 2823
2806 if (BUFFERP (last_thing_searched) && !NILP (integers)) 2824 if (BUFFERP (last_thing_searched) && !NILP (integers))
@@ -2834,11 +2852,15 @@ Return value is undefined if the last search failed. */)
2834} 2852}
2835 2853
2836 2854
2837DEFUN ("set-match-data", Fset_match_data, Sset_match_data, 1, 1, 0, 2855DEFUN ("set-match-data", Fset_match_data, Sset_match_data, 1, 2, 0,
2838 doc: /* Set internal data on last search match from elements of LIST. 2856 doc: /* Set internal data on last search match from elements of LIST.
2839LIST should have been created by calling `match-data' previously. */) 2857LIST should have been created by calling `match-data' previously.
2840 (list) 2858
2841 register Lisp_Object list; 2859If optional arg RESEAT is non-nil, make markers on LIST point nowhere.
2860If RESEAT is `evaporate', put the markers back on the free list.
2861Note: No other references to the markers must exist if you use this. */)
2862 (list, reseat)
2863 register Lisp_Object list, reseat;
2842{ 2864{
2843 register int i; 2865 register int i;
2844 register Lisp_Object marker; 2866 register Lisp_Object marker;
@@ -2882,9 +2904,9 @@ LIST should have been created by calling `match-data' previously. */)
2882 search_regs.num_regs = length; 2904 search_regs.num_regs = length;
2883 } 2905 }
2884 2906
2885 for (i = 0;; i++) 2907 for (i = 0; CONSP (list); i++)
2886 { 2908 {
2887 marker = Fcar (list); 2909 marker = XCAR (list);
2888 if (BUFFERP (marker)) 2910 if (BUFFERP (marker))
2889 { 2911 {
2890 last_thing_searched = marker; 2912 last_thing_searched = marker;
@@ -2895,12 +2917,14 @@ LIST should have been created by calling `match-data' previously. */)
2895 if (NILP (marker)) 2917 if (NILP (marker))
2896 { 2918 {
2897 search_regs.start[i] = -1; 2919 search_regs.start[i] = -1;
2898 list = Fcdr (list); 2920 list = XCDR (list);
2899 } 2921 }
2900 else 2922 else
2901 { 2923 {
2902 int from; 2924 int from;
2925 Lisp_Object m;
2903 2926
2927 m = marker;
2904 if (MARKERP (marker)) 2928 if (MARKERP (marker))
2905 { 2929 {
2906 if (XMARKER (marker)->buffer == 0) 2930 if (XMARKER (marker)->buffer == 0)
@@ -2911,17 +2935,38 @@ LIST should have been created by calling `match-data' previously. */)
2911 2935
2912 CHECK_NUMBER_COERCE_MARKER (marker); 2936 CHECK_NUMBER_COERCE_MARKER (marker);
2913 from = XINT (marker); 2937 from = XINT (marker);
2914 list = Fcdr (list);
2915 2938
2916 marker = Fcar (list); 2939 if (!NILP (reseat) && MARKERP (m))
2940 {
2941 if (EQ (reseat, Qevaporate))
2942 free_marker (m);
2943 else
2944 unchain_marker (XMARKER (m));
2945 XSETCAR (list, Qnil);
2946 }
2947
2948 if ((list = XCDR (list), !CONSP (list)))
2949 break;
2950
2951 m = marker = XCAR (list);
2952
2917 if (MARKERP (marker) && XMARKER (marker)->buffer == 0) 2953 if (MARKERP (marker) && XMARKER (marker)->buffer == 0)
2918 XSETFASTINT (marker, 0); 2954 XSETFASTINT (marker, 0);
2919 2955
2920 CHECK_NUMBER_COERCE_MARKER (marker); 2956 CHECK_NUMBER_COERCE_MARKER (marker);
2921 search_regs.start[i] = from; 2957 search_regs.start[i] = from;
2922 search_regs.end[i] = XINT (marker); 2958 search_regs.end[i] = XINT (marker);
2959
2960 if (!NILP (reseat) && MARKERP (m))
2961 {
2962 if (EQ (reseat, Qevaporate))
2963 free_marker (m);
2964 else
2965 unchain_marker (XMARKER (m));
2966 XSETCAR (list, Qnil);
2967 }
2923 } 2968 }
2924 list = Fcdr (list); 2969 list = XCDR (list);
2925 } 2970 }
2926 2971
2927 for (; i < search_regs.num_regs; i++) 2972 for (; i < search_regs.num_regs; i++)
@@ -2959,7 +3004,7 @@ save_search_regs ()
2959 3004
2960/* Called upon exit from filters and sentinels. */ 3005/* Called upon exit from filters and sentinels. */
2961void 3006void
2962restore_match_data () 3007restore_search_regs ()
2963{ 3008{
2964 if (search_regs_saved) 3009 if (search_regs_saved)
2965 { 3010 {
@@ -2977,6 +3022,21 @@ restore_match_data ()
2977 } 3022 }
2978} 3023}
2979 3024
3025static Lisp_Object
3026unwind_set_match_data (list)
3027 Lisp_Object list;
3028{
3029 return Fset_match_data (list, Qevaporate);
3030}
3031
3032/* Called to unwind protect the match data. */
3033void
3034record_unwind_save_match_data ()
3035{
3036 record_unwind_protect (unwind_set_match_data,
3037 Fmatch_data (Qnil, Qnil, Qnil));
3038}
3039
2980/* Quote a string to inactivate reg-expr chars */ 3040/* Quote a string to inactivate reg-expr chars */
2981 3041
2982DEFUN ("regexp-quote", Fregexp_quote, Sregexp_quote, 1, 1, 0, 3042DEFUN ("regexp-quote", Fregexp_quote, Sregexp_quote, 1, 1, 0,