comparison src/search.c @ 63145:73d9b884e8c8

(Fmatch_data): Add optional RESEAT arg. Unchain markers in REUSE list if non-nil; free them if equal to evaporate. (Fset_match_data): Add optional RESEAT arg. Unchain markers in LIST if non-nil; free them if equal to evaporate. Use XCAR/XCDR. (restore_search_regs): Rename from restore_match_data. Uses changed. (unwind_set_match_data): New function. (record_unwind_save_match_data): New function like save-match-data.
author Kim F. Storm <storm@cua.dk>
date Wed, 08 Jun 2005 22:32:20 +0000
parents 0015a00ccb5a
children 3f80de0be046
comparison
equal deleted inserted replaced
63144:e8b95d8eb45a 63145:73d9b884e8c8
2737 Lisp_Object subexp; 2737 Lisp_Object subexp;
2738 { 2738 {
2739 return match_limit (subexp, 0); 2739 return match_limit (subexp, 0);
2740 } 2740 }
2741 2741
2742 DEFUN ("match-data", Fmatch_data, Smatch_data, 0, 2, 0, 2742 DEFUN ("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.
2744 Element 2N is `(match-beginning N)'; element 2N + 1 is `(match-end N)'. 2744 Element 2N is `(match-beginning N)'; element 2N + 1 is `(match-end N)'.
2745 All the elements are markers or nil (nil if the Nth pair didn't match) 2745 All the elements are markers or nil (nil if the Nth pair didn't match)
2746 if the last match was on a buffer; integers or nil if a string was matched. 2746 if the last match was on a buffer; integers or nil if a string was matched.
2747 Use `store-match-data' to reinstate the data in this list. 2747 Use `store-match-data' to reinstate the data in this list.
2749 If INTEGERS (the optional first argument) is non-nil, always use 2749 If INTEGERS (the optional first argument) is non-nil, always use
2750 integers \(rather than markers) to represent buffer positions. In 2750 integers \(rather than markers) to represent buffer positions. In
2751 this case, and if the last match was in a buffer, the buffer will get 2751 this case, and if the last match was in a buffer, the buffer will get
2752 stored as one additional element at the end of the list. 2752 stored as one additional element at the end of the list.
2753 2753
2754 If REUSE is a list, reuse it as part of the value. If REUSE is long enough 2754 If REUSE is a list, reuse it as part of the value. If REUSE is long
2755 to hold all the values, and if INTEGERS is non-nil, no consing is done. 2755 enough to hold all the values, and if INTEGERS is non-nil, no consing
2756 is done.
2757
2758 If optional third arg RESEAT is non-nil, any previous markers on the
2759 REUSE list will be modified to point to nowhere.
2760
2761 If RESEAT is `evaporate', put markers back on the free list.
2762 Note: No other references to the markers must exist if you use this.
2756 2763
2757 Return value is undefined if the last search failed. */) 2764 Return 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;
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 }
2764 2782
2765 if (NILP (last_thing_searched)) 2783 if (NILP (last_thing_searched))
2766 return Qnil; 2784 return Qnil;
2767 2785
2768 prev = Qnil; 2786 prev = Qnil;
2795 } 2813 }
2796 else 2814 else
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))
2807 { 2825 {
2808 data[len] = last_thing_searched; 2826 data[len] = last_thing_searched;
2832 2850
2833 return reuse; 2851 return reuse;
2834 } 2852 }
2835 2853
2836 2854
2837 DEFUN ("set-match-data", Fset_match_data, Sset_match_data, 1, 1, 0, 2855 DEFUN ("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.
2839 LIST should have been created by calling `match-data' previously. */) 2857 LIST should have been created by calling `match-data' previously.
2840 (list) 2858
2841 register Lisp_Object list; 2859 If optional arg RESEAT is non-nil, make markers on LIST point nowhere.
2860 If RESEAT is `evaporate', put the markers back on the free list.
2861 Note: 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;
2845 2867
2846 if (running_asynch_code) 2868 if (running_asynch_code)
2880 search_regs.start[i] = -1; 2902 search_regs.start[i] = -1;
2881 2903
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;
2891 break; 2913 break;
2892 } 2914 }
2893 if (i >= length) 2915 if (i >= length)
2894 break; 2916 break;
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;
2903 2925 Lisp_Object m;
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)
2907 XSETFASTINT (marker, 0); 2931 XSETFASTINT (marker, 0);
2908 else 2932 else
2909 XSETBUFFER (last_thing_searched, XMARKER (marker)->buffer); 2933 XSETBUFFER (last_thing_searched, XMARKER (marker)->buffer);
2910 } 2934 }
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); 2938
2915 2939 if (!NILP (reseat) && MARKERP (m))
2916 marker = Fcar (list); 2940 {
2941 if (EQ (reseat, Qevaporate))
2942 free_marker (m);
2943 else
2944 unchain_marker (XMARKER (m));
2945 }
2946
2947 if ((list = XCDR (list), !CONSP (list)))
2948 break;
2949
2950 m = marker = XCAR (list);
2951
2917 if (MARKERP (marker) && XMARKER (marker)->buffer == 0) 2952 if (MARKERP (marker) && XMARKER (marker)->buffer == 0)
2918 XSETFASTINT (marker, 0); 2953 XSETFASTINT (marker, 0);
2919 2954
2920 CHECK_NUMBER_COERCE_MARKER (marker); 2955 CHECK_NUMBER_COERCE_MARKER (marker);
2921 search_regs.start[i] = from; 2956 search_regs.start[i] = from;
2922 search_regs.end[i] = XINT (marker); 2957 search_regs.end[i] = XINT (marker);
2958
2959 if (!NILP (reseat) && MARKERP (m))
2960 {
2961 if (EQ (reseat, Qevaporate))
2962 free_marker (m);
2963 else
2964 unchain_marker (XMARKER (m));
2965 }
2923 } 2966 }
2924 list = Fcdr (list); 2967 list = XCDR (list);
2925 } 2968 }
2926 2969
2927 for (; i < search_regs.num_regs; i++) 2970 for (; i < search_regs.num_regs; i++)
2928 search_regs.start[i] = -1; 2971 search_regs.start[i] = -1;
2929 } 2972 }
2957 } 3000 }
2958 } 3001 }
2959 3002
2960 /* Called upon exit from filters and sentinels. */ 3003 /* Called upon exit from filters and sentinels. */
2961 void 3004 void
2962 restore_match_data () 3005 restore_search_regs ()
2963 { 3006 {
2964 if (search_regs_saved) 3007 if (search_regs_saved)
2965 { 3008 {
2966 if (search_regs.num_regs > 0) 3009 if (search_regs.num_regs > 0)
2967 { 3010 {
2973 search_regs.end = saved_search_regs.end; 3016 search_regs.end = saved_search_regs.end;
2974 last_thing_searched = saved_last_thing_searched; 3017 last_thing_searched = saved_last_thing_searched;
2975 saved_last_thing_searched = Qnil; 3018 saved_last_thing_searched = Qnil;
2976 search_regs_saved = 0; 3019 search_regs_saved = 0;
2977 } 3020 }
3021 }
3022
3023 static Lisp_Object
3024 unwind_set_match_data (list)
3025 Lisp_Object list;
3026 {
3027 return Fset_match_data (list, Qevaporate);
3028 }
3029
3030 /* Called to unwind protect the match data. */
3031 void
3032 record_unwind_save_match_data ()
3033 {
3034 record_unwind_protect (unwind_set_match_data,
3035 Fmatch_data (Qnil, Qnil, Qnil));
2978 } 3036 }
2979 3037
2980 /* Quote a string to inactivate reg-expr chars */ 3038 /* Quote a string to inactivate reg-expr chars */
2981 3039
2982 DEFUN ("regexp-quote", Fregexp_quote, Sregexp_quote, 1, 1, 0, 3040 DEFUN ("regexp-quote", Fregexp_quote, Sregexp_quote, 1, 1, 0,