From a26824e5cbc454a3614b32d131bbdd74f3c03735 Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Thu, 7 Oct 2021 20:46:50 +0200 Subject: [PATCH] Make 'inhibit-changing-match-data' obsolete and adjust callers * doc/lispref/searching.texi (Regexp Search): (POSIX Regexps): Document this. * lisp/subr.el (inhibit-changing-match-data): Make obsolete. (looking-at-p): Adjust call. * lisp/vc/vc-hg.el (vc-hg--raw-dirstate-search): (vc-hg--ignore-patterns-ignored-p): (vc-hg--cached-dirstate-search): Don't use `inhibit-changing-match-data'. * src/minibuf.c (Ftry_completion): (Fall_completions): (Ftest_completion): Adjust Fstring_match calls. * src/search.c (looking_at_1): Pass in modify_data. (Flooking_at): Add optional inhibit-modify parameter. (string_match_1): Pass in modify_data. (Fstring_match): (Fposix_looking_at, Fposix_string_match): Add optional inhibit-modify parameter. --- doc/lispref/searching.texi | 22 ++++++---- etc/NEWS | 5 +++ lisp/subr.el | 7 ++- lisp/vc/vc-hg.el | 7 ++- src/minibuf.c | 6 +-- src/search.c | 88 +++++++++++++++++++++----------------- 6 files changed, 76 insertions(+), 59 deletions(-) diff --git a/doc/lispref/searching.texi b/doc/lispref/searching.texi index d27cfb8c0c7..f5a42406ae0 100644 --- a/doc/lispref/searching.texi +++ b/doc/lispref/searching.texi @@ -1986,7 +1986,7 @@ feature for matching regular expressions from end to beginning. It's not worth the trouble of implementing that. @end deffn -@defun string-match regexp string &optional start +@defun string-match regexp string &optional start inhibit-modify This function returns the index of the start of the first match for the regular expression @var{regexp} in @var{string}, or @code{nil} if there is no match. If @var{start} is non-@code{nil}, the search starts @@ -2011,8 +2011,10 @@ For example, The index of the first character of the string is 0, the index of the second character is 1, and so on. -If this function finds a match, the index of the first character beyond -the match is available as @code{(match-end 0)}. @xref{Match Data}. +By default, if this function finds a match, the index of the first +character beyond the match is available as @code{(match-end 0)}. +@xref{Match Data}. If @var{inhibit-modify} is non-@code{nil}, the +match data isn't modified. @example @group @@ -2033,16 +2035,18 @@ This predicate function does what @code{string-match} does, but it avoids modifying the match data. @end defun -@defun looking-at regexp +@defun looking-at regexp &optional inhibit-modify This function determines whether the text in the current buffer directly following point matches the regular expression @var{regexp}. ``Directly following'' means precisely that: the search is ``anchored'' and it can succeed only starting with the first character following point. The result is @code{t} if so, @code{nil} otherwise. -This function does not move point, but it does update the match data. -@xref{Match Data}. If you need to test for a match without modifying -the match data, use @code{looking-at-p}, described below. +This function does not move point, but it does update the match data +(if @var{inhibit-modify} is @code{nil} or missing, which is the +default). @xref{Match Data}. As a convenience, instead of using the +@var{inhibit-modify} argument, you can use @code{looking-at-p}, +described below. In this example, point is located directly before the @samp{T}. If it were anywhere else, the result would be @code{nil}. @@ -2149,13 +2153,13 @@ backtracking specified by the POSIX standard for regular expression matching. @end deffn -@defun posix-looking-at regexp +@defun posix-looking-at regexp &optional inhibit-modify This is like @code{looking-at} except that it performs the full backtracking specified by the POSIX standard for regular expression matching. @end defun -@defun posix-string-match regexp string &optional start +@defun posix-string-match regexp string &optional start inhibit-modify This is like @code{string-match} except that it performs the full backtracking specified by the POSIX standard for regular expression matching. diff --git a/etc/NEWS b/etc/NEWS index ab15b1efaf0..eb651873706 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -117,6 +117,11 @@ Emacs buffers, like indentation and the like. The new ert function * Incompatible Lisp Changes in Emacs 29.1 +--- +** The 'inhibit-changing-match-data' variable is now obsolete. +Instead functions like 'string-match' and 'looking-at' now takes an +optional 'inhibit-modify' argument. + --- ** 'gnus-define-keys' is now obsolete. Use 'define-keymap' instead. diff --git a/lisp/subr.el b/lisp/subr.el index 9f0fe42f923..4173e9f449b 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -1752,6 +1752,7 @@ be a list of the form returned by `event-start' and `event-end'." (make-obsolete 'window-redisplay-end-trigger nil "23.1") (make-obsolete 'set-window-redisplay-end-trigger nil "23.1") (make-obsolete-variable 'operating-system-release nil "28.1") +(make-obsolete-variable 'inhibit-changing-match-data nil "29.1") (make-obsolete 'run-window-configuration-change-hook nil "27.1") @@ -4761,14 +4762,12 @@ wherever possible, since it is slow." (defsubst looking-at-p (regexp) "\ Same as `looking-at' except this function does not change the match data." - (let ((inhibit-changing-match-data t)) - (looking-at regexp))) + (looking-at regexp t)) (defsubst string-match-p (regexp string &optional start) "\ Same as `string-match' except this function does not change the match data." - (let ((inhibit-changing-match-data t)) - (string-match regexp string start))) + (string-match regexp string start t)) (defun subregexp-context-p (regexp pos &optional start) "Return non-nil if POS is in a normal subregexp context in REGEXP. diff --git a/lisp/vc/vc-hg.el b/lisp/vc/vc-hg.el index 0ed9f7c31fe..6bec9edbf35 100644 --- a/lisp/vc/vc-hg.el +++ b/lisp/vc/vc-hg.el @@ -672,7 +672,6 @@ Return the byte's value as an integer." (let* ((result nil) (flen (length fname)) (case-fold-search nil) - (inhibit-changing-match-data t) ;; Find a conservative bound for the loop below by using ;; Boyer-Moore on the raw dirstate without parsing it; we ;; know we can't possibly find fname _after_ the last place @@ -976,10 +975,9 @@ REPO must be the directory name of an hg repository." "Test whether the ignore pattern set HGIP says to ignore FILENAME. FILENAME must be the file's true absolute name." (let ((patterns (vc-hg--ignore-patterns-ignore-patterns hgip)) - (inhibit-changing-match-data t) (ignored nil)) (while (and patterns (not ignored)) - (setf ignored (string-match (pop patterns) filename))) + (setf ignored (string-match-p (pop patterns) filename))) ignored)) (defvar vc-hg--cached-ignore-patterns nil @@ -1043,7 +1041,8 @@ Avoids the need to repeatedly scan dirstate on repeated calls to (equal size (pop cache)) (equal ascii-fname (pop cache))) (pop cache) - (let ((result (vc-hg--raw-dirstate-search dirstate ascii-fname))) + (let ((result (save-match-data + (vc-hg--raw-dirstate-search dirstate ascii-fname)))) (setf vc-hg--dirstate-scan-cache (list dirstate mtime size ascii-fname result)) result)))) diff --git a/src/minibuf.c b/src/minibuf.c index 5455a93f694..0dc340e9670 100644 --- a/src/minibuf.c +++ b/src/minibuf.c @@ -1684,7 +1684,7 @@ is used to further constrain the set of candidates. */) specbind (Qcase_fold_search, completion_ignore_case ? Qt : Qnil); } - tem = Fstring_match (XCAR (regexps), eltstring, zero); + tem = Fstring_match (XCAR (regexps), eltstring, zero, Qnil); if (NILP (tem)) break; } @@ -1948,7 +1948,7 @@ with a space are ignored unless STRING itself starts with a space. */) specbind (Qcase_fold_search, completion_ignore_case ? Qt : Qnil); } - tem = Fstring_match (XCAR (regexps), eltstring, zero); + tem = Fstring_match (XCAR (regexps), eltstring, zero, Qnil); if (NILP (tem)) break; } @@ -2163,7 +2163,7 @@ the values STRING, PREDICATE and `lambda'. */) { /* We can test against STRING, because if we got here, then the element is equivalent to it. */ - if (NILP (Fstring_match (XCAR (regexps), string, Qnil))) + if (NILP (Fstring_match (XCAR (regexps), string, Qnil, Qnil))) return unbind_to (count, Qnil); } unbind_to (count, Qnil); diff --git a/src/search.c b/src/search.c index 08f1e9474f1..66e77d42b4a 100644 --- a/src/search.c +++ b/src/search.c @@ -260,7 +260,7 @@ compile_pattern (Lisp_Object pattern, struct re_registers *regp, static Lisp_Object -looking_at_1 (Lisp_Object string, bool posix) +looking_at_1 (Lisp_Object string, bool posix, bool modify_data) { Lisp_Object val; unsigned char *p1, *p2; @@ -278,11 +278,11 @@ looking_at_1 (Lisp_Object string, bool posix) CHECK_STRING (string); /* Snapshot in case Lisp changes the value. */ - bool preserve_match_data = NILP (Vinhibit_changing_match_data); + bool modify_match_data = NILP (Vinhibit_changing_match_data) && modify_data; struct regexp_cache *cache_entry = compile_pattern ( string, - preserve_match_data ? &search_regs : NULL, + modify_match_data ? &search_regs : NULL, (!NILP (BVAR (current_buffer, case_fold_search)) ? BVAR (current_buffer, case_canon_table) : Qnil), posix, @@ -316,7 +316,7 @@ looking_at_1 (Lisp_Object string, bool posix) re_match_object = Qnil; i = re_match_2 (&cache_entry->buf, (char *) p1, s1, (char *) p2, s2, PT_BYTE - BEGV_BYTE, - preserve_match_data ? &search_regs : NULL, + modify_match_data ? &search_regs : NULL, ZV_BYTE - BEGV_BYTE); if (i == -2) @@ -326,7 +326,7 @@ looking_at_1 (Lisp_Object string, bool posix) } val = (i >= 0 ? Qt : Qnil); - if (preserve_match_data && i >= 0) + if (modify_match_data && i >= 0) { for (i = 0; i < search_regs.num_regs; i++) if (search_regs.start[i] >= 0) @@ -343,35 +343,37 @@ looking_at_1 (Lisp_Object string, bool posix) return unbind_to (count, val); } -DEFUN ("looking-at", Flooking_at, Slooking_at, 1, 1, 0, +DEFUN ("looking-at", Flooking_at, Slooking_at, 1, 2, 0, doc: /* Return t if text after point matches regular expression REGEXP. -This function modifies the match data that `match-beginning', -`match-end' and `match-data' access; save and restore the match -data if you want to preserve them. */) - (Lisp_Object regexp) +By default, this function modifies the match data that +`match-beginning', `match-end' and `match-data' access. If +INHIBIT-MODIFY is non-nil, don't modify the match data. */) + (Lisp_Object regexp, Lisp_Object inhibit_modify) { - return looking_at_1 (regexp, 0); + return looking_at_1 (regexp, 0, NILP (inhibit_modify)); } -DEFUN ("posix-looking-at", Fposix_looking_at, Sposix_looking_at, 1, 1, 0, +DEFUN ("posix-looking-at", Fposix_looking_at, Sposix_looking_at, 1, 2, 0, doc: /* Return t if text after point matches REGEXP according to Posix rules. Find the longest match, in accordance with Posix regular expression rules. -This function modifies the match data that `match-beginning', -`match-end' and `match-data' access; save and restore the match -data if you want to preserve them. */) - (Lisp_Object regexp) + +By default, this function modifies the match data that +`match-beginning', `match-end' and `match-data' access. If +INHIBIT-MODIFY is non-nil, don't modify the match data. */) + (Lisp_Object regexp, Lisp_Object inhibit_modify) { - return looking_at_1 (regexp, 1); + return looking_at_1 (regexp, 1, NILP (inhibit_modify)); } static Lisp_Object string_match_1 (Lisp_Object regexp, Lisp_Object string, Lisp_Object start, - bool posix) + bool posix, bool modify_data) { ptrdiff_t val; struct re_pattern_buffer *bufp; EMACS_INT pos; ptrdiff_t pos_byte, i; + bool modify_match_data = NILP (Vinhibit_changing_match_data) && modify_data; if (running_asynch_code) save_search_regs (); @@ -400,8 +402,7 @@ string_match_1 (Lisp_Object regexp, Lisp_Object string, Lisp_Object start, BVAR (current_buffer, case_eqv_table)); bufp = &compile_pattern (regexp, - (NILP (Vinhibit_changing_match_data) - ? &search_regs : NULL), + (modify_match_data ? &search_regs : NULL), (!NILP (BVAR (current_buffer, case_fold_search)) ? BVAR (current_buffer, case_canon_table) : Qnil), posix, @@ -410,18 +411,17 @@ string_match_1 (Lisp_Object regexp, Lisp_Object string, Lisp_Object start, val = re_search (bufp, SSDATA (string), SBYTES (string), pos_byte, SBYTES (string) - pos_byte, - (NILP (Vinhibit_changing_match_data) - ? &search_regs : NULL)); + (modify_match_data ? &search_regs : NULL)); /* Set last_thing_searched only when match data is changed. */ - if (NILP (Vinhibit_changing_match_data)) + if (modify_match_data) last_thing_searched = Qt; if (val == -2) matcher_overflow (); if (val < 0) return Qnil; - if (NILP (Vinhibit_changing_match_data)) + if (modify_match_data) for (i = 0; i < search_regs.num_regs; i++) if (search_regs.start[i] >= 0) { @@ -434,32 +434,42 @@ string_match_1 (Lisp_Object regexp, Lisp_Object string, Lisp_Object start, return make_fixnum (string_byte_to_char (string, val)); } -DEFUN ("string-match", Fstring_match, Sstring_match, 2, 3, 0, +DEFUN ("string-match", Fstring_match, Sstring_match, 2, 4, 0, doc: /* Return index of start of first match for REGEXP in STRING, or nil. Matching ignores case if `case-fold-search' is non-nil. If third arg START is non-nil, start search at that index in STRING. -For index of first char beyond the match, do (match-end 0). -`match-end' and `match-beginning' also give indices of substrings -matched by parenthesis constructs in the pattern. -You can use the function `match-string' to extract the substrings -matched by the parenthesis constructions in REGEXP. */) - (Lisp_Object regexp, Lisp_Object string, Lisp_Object start) +If INHIBIT-MODIFY is non-nil, match data is not changed. + +If INHIBIT-MODIFY is nil or missing, match data is changed, and +`match-end' and `match-beginning' give indices of substrings matched +by parenthesis constructs in the pattern. You can use the function +`match-string' to extract the substrings matched by the parenthesis +constructions in REGEXP. For index of first char beyond the match, do +(match-end 0). */) + (Lisp_Object regexp, Lisp_Object string, Lisp_Object start, + Lisp_Object inhibit_modify) { - return string_match_1 (regexp, string, start, 0); + return string_match_1 (regexp, string, start, 0, NILP (inhibit_modify)); } -DEFUN ("posix-string-match", Fposix_string_match, Sposix_string_match, 2, 3, 0, +DEFUN ("posix-string-match", Fposix_string_match, Sposix_string_match, 2, 4, 0, doc: /* Return index of start of first match for Posix REGEXP in STRING, or nil. Find the longest match, in accord with Posix regular expression rules. Case is ignored if `case-fold-search' is non-nil in the current buffer. -If third arg START is non-nil, start search at that index in STRING. -For index of first char beyond the match, do (match-end 0). -`match-end' and `match-beginning' also give indices of substrings -matched by parenthesis constructs in the pattern. */) - (Lisp_Object regexp, Lisp_Object string, Lisp_Object start) + +If INHIBIT-MODIFY is non-nil, match data is not changed. + +If INHIBIT-MODIFY is nil or missing, match data is changed, and +`match-end' and `match-beginning' give indices of substrings matched +by parenthesis constructs in the pattern. You can use the function +`match-string' to extract the substrings matched by the parenthesis +constructions in REGEXP. For index of first char beyond the match, do +(match-end 0). */) + (Lisp_Object regexp, Lisp_Object string, Lisp_Object start, + Lisp_Object inhibit_modify) { - return string_match_1 (regexp, string, start, 1); + return string_match_1 (regexp, string, start, 1, NILP (inhibit_modify)); } /* Match REGEXP against STRING using translation table TABLE, -- 2.39.2