Mercurial > emacs
changeset 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 | e8b95d8eb45a |
children | 7dced3c64549 |
files | src/search.c |
diffstat | 1 files changed, 78 insertions(+), 20 deletions(-) [+] |
line wrap: on
line diff
--- a/src/search.c Wed Jun 08 19:41:19 2005 +0000 +++ b/src/search.c Wed Jun 08 22:32:20 2005 +0000 @@ -2739,7 +2739,7 @@ return match_limit (subexp, 0); } -DEFUN ("match-data", Fmatch_data, Smatch_data, 0, 2, 0, +DEFUN ("match-data", Fmatch_data, Smatch_data, 0, 3, 0, doc: /* Return a list containing all info on what the last search matched. Element 2N is `(match-beginning N)'; element 2N + 1 is `(match-end N)'. All the elements are markers or nil (nil if the Nth pair didn't match) @@ -2751,17 +2751,35 @@ this case, and if the last match was in a buffer, the buffer will get stored as one additional element at the end of the list. -If REUSE is a list, reuse it as part of the value. If REUSE is long enough -to hold all the values, and if INTEGERS is non-nil, no consing is done. +If REUSE is a list, reuse it as part of the value. If REUSE is long +enough to hold all the values, and if INTEGERS is non-nil, no consing +is done. + +If optional third arg RESEAT is non-nil, any previous markers on the +REUSE list will be modified to point to nowhere. + +If RESEAT is `evaporate', put markers back on the free list. +Note: No other references to the markers must exist if you use this. Return value is undefined if the last search failed. */) - (integers, reuse) - Lisp_Object integers, reuse; + (integers, reuse, reseat) + Lisp_Object integers, reuse, reseat; { Lisp_Object tail, prev; Lisp_Object *data; int i, len; + if (!NILP (reseat)) + for (tail = reuse; CONSP (tail); tail = XCDR (tail)) + if (MARKERP (XCAR (tail))) + { + if (EQ (reseat, Qevaporate)) + free_marker (XCAR (tail)); + else + unchain_marker (XMARKER (XCAR (tail))); + XSETCAR (tail, Qnil); + } + if (NILP (last_thing_searched)) return Qnil; @@ -2797,10 +2815,10 @@ /* last_thing_searched must always be Qt, a buffer, or Qnil. */ abort (); - len = 2*(i+1); + len = 2 * i + 2; } else - data[2 * i] = data [2 * i + 1] = Qnil; + data[2 * i] = data[2 * i + 1] = Qnil; } if (BUFFERP (last_thing_searched) && !NILP (integers)) @@ -2834,11 +2852,15 @@ } -DEFUN ("set-match-data", Fset_match_data, Sset_match_data, 1, 1, 0, +DEFUN ("set-match-data", Fset_match_data, Sset_match_data, 1, 2, 0, doc: /* Set internal data on last search match from elements of LIST. -LIST should have been created by calling `match-data' previously. */) - (list) - register Lisp_Object list; +LIST should have been created by calling `match-data' previously. + +If optional arg RESEAT is non-nil, make markers on LIST point nowhere. +If RESEAT is `evaporate', put the markers back on the free list. +Note: No other references to the markers must exist if you use this. */) + (list, reseat) + register Lisp_Object list, reseat; { register int i; register Lisp_Object marker; @@ -2882,9 +2904,9 @@ search_regs.num_regs = length; } - for (i = 0;; i++) + for (i = 0; CONSP (list); i++) { - marker = Fcar (list); + marker = XCAR (list); if (BUFFERP (marker)) { last_thing_searched = marker; @@ -2895,12 +2917,14 @@ if (NILP (marker)) { search_regs.start[i] = -1; - list = Fcdr (list); + list = XCDR (list); } else { int from; - + Lisp_Object m; + + m = marker; if (MARKERP (marker)) { if (XMARKER (marker)->buffer == 0) @@ -2911,17 +2935,36 @@ CHECK_NUMBER_COERCE_MARKER (marker); from = XINT (marker); - list = Fcdr (list); - - marker = Fcar (list); + + if (!NILP (reseat) && MARKERP (m)) + { + if (EQ (reseat, Qevaporate)) + free_marker (m); + else + unchain_marker (XMARKER (m)); + } + + if ((list = XCDR (list), !CONSP (list))) + break; + + m = marker = XCAR (list); + if (MARKERP (marker) && XMARKER (marker)->buffer == 0) XSETFASTINT (marker, 0); CHECK_NUMBER_COERCE_MARKER (marker); search_regs.start[i] = from; search_regs.end[i] = XINT (marker); + + if (!NILP (reseat) && MARKERP (m)) + { + if (EQ (reseat, Qevaporate)) + free_marker (m); + else + unchain_marker (XMARKER (m)); + } } - list = Fcdr (list); + list = XCDR (list); } for (; i < search_regs.num_regs; i++) @@ -2959,7 +3002,7 @@ /* Called upon exit from filters and sentinels. */ void -restore_match_data () +restore_search_regs () { if (search_regs_saved) { @@ -2977,6 +3020,21 @@ } } +static Lisp_Object +unwind_set_match_data (list) + Lisp_Object list; +{ + return Fset_match_data (list, Qevaporate); +} + +/* Called to unwind protect the match data. */ +void +record_unwind_save_match_data () +{ + record_unwind_protect (unwind_set_match_data, + Fmatch_data (Qnil, Qnil, Qnil)); +} + /* Quote a string to inactivate reg-expr chars */ DEFUN ("regexp-quote", Fregexp_quote, Sregexp_quote, 1, 1, 0,