Mercurial > emacs
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, |