Mercurial > hg > xemacs-beta
diff src/search.c @ 1425:74cb069b8417
[xemacs-hg @ 2003-04-23 15:42:44 by stephent]
stale match data <87fzo99rje.fsf@tleepslib.sk.tsukuba.ac.jp>
new split-string <87d6jd9qis.fsf@tleepslib.sk.tsukuba.ac.jp>
support (info "(file)node") <87adeh9qa7.fsf@tleepslib.sk.tsukuba.ac.jp>
author | stephent |
---|---|
date | Wed, 23 Apr 2003 15:42:52 +0000 |
parents | 8d350b095c21 |
children | 0f42689481f0 |
line wrap: on
line diff
--- a/src/search.c Tue Apr 22 03:24:13 2003 +0000 +++ b/src/search.c Wed Apr 23 15:42:52 2003 +0000 @@ -93,6 +93,30 @@ */ static struct re_registers search_regs; +/* Every function that _may_ set the match data _must_ clear the search + registers on entry. An unsuccessful search should leave the search + registers cleared. Applications that are no-ops by definition (eg, + searches with a repetition count of 0) _must not_ clear the search + registers. + + XEmacs 21.5 up to beta 11 may have permitted the following idiom to + "win" in the sense that the match data was set to the last successful + match's match data, and not cleared as the current implemenation does: + + (while (search_forward "string")) + (use-match-data-of-last-successful-search) + + This no longer can work. You must use save-match-data to preserve the + match data: + + (let (md) + (while (when (search-forward "string") (setq md (match-data)))) + (set-match-data md)) + (use-match-data-of-last-successful-search) + */ +static void set_search_regs (struct buffer *buf, Charbpos beg, Charcount len); +static void clear_search_regs (struct re_registers *regp); + /* The buffer in which the last search was performed, or Qt if the last search was done in a string; Qnil if no searching has been done yet. */ @@ -110,8 +134,6 @@ /* range table for use with skip_chars. Only needed for Mule. */ Lisp_Object Vskip_chars_range_table; -static void set_search_regs (struct buffer *buf, Charbpos beg, Charcount len); -static void clear_unused_search_regs (struct re_registers *regp, int no_sub); static Charbpos simple_search (struct buffer *buf, Ibyte *base_pat, Bytecount len, Bytebpos pos, Bytebpos lim, EMACS_INT n, Lisp_Object trt); @@ -304,6 +326,9 @@ struct syntax_cache scache_struct; struct syntax_cache *scache = &scache_struct; + /* clear search registers *now*. no mercy, not even for errors */ + clear_search_regs (&search_regs); + CHECK_STRING (string); bufp = compile_pattern (string, &search_regs, (!NILP (buf->case_fold_search) @@ -394,6 +419,9 @@ data. Not necessary because we don't call process filters asynchronously (i.e. from within QUIT). */ + /* clear search registers *now*. no mercy, not even for errors */ + clear_search_regs (&search_regs); + CHECK_STRING (regexp); CHECK_STRING (string); @@ -1219,18 +1247,20 @@ data. Not necessary because we don't call process filters asynchronously (i.e. from within QUIT). */ + /* Searching 0 times means noop---don't move, don't touch registers. */ + if (n == 0) + return charbpos; + + /* clear the search regs now */ + clear_search_regs (&search_regs); + /* Null string is found at starting position. */ if (len == 0) { set_search_regs (buf, charbpos, 0); - clear_unused_search_regs (&search_regs, 0); return charbpos; } - /* Searching 0 times means noop---don't move, don't touch registers. */ - if (n == 0) - return charbpos; - pos = charbpos_to_bytebpos (buf, charbpos); lim = charbpos_to_bytebpos (buf, buflim); if (RE && !trivial_regexp_p (string)) @@ -1483,7 +1513,6 @@ end = bytebpos_to_charbpos (buf, pos + buf_len); } set_search_regs (buf, beg, end - beg); - clear_unused_search_regs (&search_regs, 0); return retval; } @@ -1617,6 +1646,10 @@ for (i = 0; i < 0400; i++) simple_translate[i] = (Ibyte) i; i = 0; + + /* clear search regs now */ + clear_search_regs (&search_regs); + while (i != infinity) { Ibyte *ptr = base_pat + i; @@ -1847,7 +1880,6 @@ Charbpos bufend = bytebpos_to_charbpos (buf, bytstart + len); set_search_regs (buf, bufstart, bufend - bufstart); - clear_unused_search_regs (&search_regs, 0); } if ((n -= direction) != 0) @@ -1938,7 +1970,6 @@ Charbpos bufend = bytebpos_to_charbpos (buf, bytstart + len); set_search_regs (buf, bufstart, bufend - bufstart); - clear_unused_search_regs (&search_regs, 0); } if ((n -= direction) != 0) @@ -1978,21 +2009,17 @@ last_thing_searched = wrap_buffer (buf); } -/* Clear unused search registers so match data will be null. +/* Clear search registers so match data will be null. REGP is a pointer to the register structure to clear, usually the global - search_regs. - NO_SUB is the number of subexpressions to allow for. (Does not count - the whole match, ie, for a string search NO_SUB == 0.) - It is an error if NO_SUB > REGP.num_regs - 1. */ + search_regs. */ static void -clear_unused_search_regs (struct re_registers *regp, int no_sub) +clear_search_regs (struct re_registers *regp) { /* This function has been Mule-ized. */ int i; - assert (no_sub >= 0 && no_sub < regp->num_regs); - for (i = no_sub + 1; i < regp->num_regs; i++) + for (i = 0; i < regp->num_regs; i++) regp->start[i] = regp->end[i] = -1; } @@ -2323,6 +2350,12 @@ the match. It says to replace just that subexpression instead of the whole match. This is useful only after a regular expression search or match since only regular expressions have distinguished subexpressions. + +If no match (including searches) has been conducted, the last match +operation failed, or the requested subexpression was not matched, an +`args-out-of-range' error will be signaled. (If no match has ever been +conducted in this instance of XEmacs, an `invalid-operation' error will +be signaled. This is very rare.) */ (replacement, fixedcase, literal, string, strbuffer)) {