Commit abd0071c authored by Kim F. Storm's avatar Kim F. Storm
Browse files

(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.
parent 72f23b85
...@@ -2739,7 +2739,7 @@ Zero means the entire text matched by the whole regexp or whole string. */) ...@@ -2739,7 +2739,7 @@ Zero means the entire text matched by the whole regexp or whole string. */)
return match_limit (subexp, 0); 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. 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)'. 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) All 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 ...@@ -2751,17 +2751,35 @@ integers \(rather than markers) to represent buffer positions. In
this case, and if the last match was in a buffer, the buffer will get 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. 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 If REUSE is a list, reuse it as part of the value. If REUSE is long
to hold all the values, and if INTEGERS is non-nil, no consing is done. 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. */) Return value is undefined if the last search failed. */)
(integers, reuse) (integers, reuse, reseat)
Lisp_Object integers, reuse; Lisp_Object integers, reuse, reseat;
{ {
Lisp_Object tail, prev; Lisp_Object tail, prev;
Lisp_Object *data; Lisp_Object *data;
int i, len; 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)) if (NILP (last_thing_searched))
return Qnil; return Qnil;
...@@ -2797,10 +2815,10 @@ Return value is undefined if the last search failed. */) ...@@ -2797,10 +2815,10 @@ Return value is undefined if the last search failed. */)
/* last_thing_searched must always be Qt, a buffer, or Qnil. */ /* last_thing_searched must always be Qt, a buffer, or Qnil. */
abort (); abort ();
len = 2*(i+1); len = 2 * i + 2;
} }
else else
data[2 * i] = data [2 * i + 1] = Qnil; data[2 * i] = data[2 * i + 1] = Qnil;
} }
if (BUFFERP (last_thing_searched) && !NILP (integers)) if (BUFFERP (last_thing_searched) && !NILP (integers))
...@@ -2834,11 +2852,15 @@ Return value is undefined if the last search failed. */) ...@@ -2834,11 +2852,15 @@ Return value is undefined if the last search failed. */)
} }
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. doc: /* Set internal data on last search match from elements of LIST.
LIST should have been created by calling `match-data' previously. */) LIST should have been created by calling `match-data' previously.
(list)
register Lisp_Object list; 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 int i;
register Lisp_Object marker; register Lisp_Object marker;
...@@ -2882,9 +2904,9 @@ LIST should have been created by calling `match-data' previously. */) ...@@ -2882,9 +2904,9 @@ LIST should have been created by calling `match-data' previously. */)
search_regs.num_regs = length; search_regs.num_regs = length;
} }
for (i = 0;; i++) for (i = 0; CONSP (list); i++)
{ {
marker = Fcar (list); marker = XCAR (list);
if (BUFFERP (marker)) if (BUFFERP (marker))
{ {
last_thing_searched = marker; last_thing_searched = marker;
...@@ -2895,12 +2917,14 @@ LIST should have been created by calling `match-data' previously. */) ...@@ -2895,12 +2917,14 @@ LIST should have been created by calling `match-data' previously. */)
if (NILP (marker)) if (NILP (marker))
{ {
search_regs.start[i] = -1; search_regs.start[i] = -1;
list = Fcdr (list); list = XCDR (list);
} }
else else
{ {
int from; int from;
Lisp_Object m;
m = marker;
if (MARKERP (marker)) if (MARKERP (marker))
{ {
if (XMARKER (marker)->buffer == 0) if (XMARKER (marker)->buffer == 0)
...@@ -2911,17 +2935,36 @@ LIST should have been created by calling `match-data' previously. */) ...@@ -2911,17 +2935,36 @@ LIST should have been created by calling `match-data' previously. */)
CHECK_NUMBER_COERCE_MARKER (marker); CHECK_NUMBER_COERCE_MARKER (marker);
from = XINT (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) if (MARKERP (marker) && XMARKER (marker)->buffer == 0)
XSETFASTINT (marker, 0); XSETFASTINT (marker, 0);
CHECK_NUMBER_COERCE_MARKER (marker); CHECK_NUMBER_COERCE_MARKER (marker);
search_regs.start[i] = from; search_regs.start[i] = from;
search_regs.end[i] = XINT (marker); 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++) for (; i < search_regs.num_regs; i++)
...@@ -2959,7 +3002,7 @@ save_search_regs () ...@@ -2959,7 +3002,7 @@ save_search_regs ()
/* Called upon exit from filters and sentinels. */ /* Called upon exit from filters and sentinels. */
void void
restore_match_data () restore_search_regs ()
{ {
if (search_regs_saved) if (search_regs_saved)
{ {
...@@ -2977,6 +3020,21 @@ restore_match_data () ...@@ -2977,6 +3020,21 @@ restore_match_data ()
} }
} }
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 */ /* Quote a string to inactivate reg-expr chars */
DEFUN ("regexp-quote", Fregexp_quote, Sregexp_quote, 1, 1, 0, DEFUN ("regexp-quote", Fregexp_quote, Sregexp_quote, 1, 1, 0,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment