Speed up match-substitute-replacement

* lisp/subr.el (match-substitute-replacement): Use match-data--translate.
* src/search.c (Fmatch_data__translate): Remove string restriction.
* test/lisp/subr-tests.el (subr-match-substitute-replacement): New test.
This commit is contained in:
Mattias Engdegård 2020-12-04 18:37:21 +01:00
parent a5fa79d50e
commit 7bdc40e8d1
3 changed files with 27 additions and 7 deletions

View file

@ -4259,11 +4259,7 @@ Optional FIXEDCASE, LITERAL, STRING and SUBEXP have the same
meaning as for `replace-match'."
(let ((match (match-string 0 string)))
(save-match-data
(set-match-data (mapcar (lambda (x)
(if (numberp x)
(- x (match-beginning 0))
x))
(match-data t)))
(match-data--translate (- (match-beginning 0)))
(replace-match replacement fixedcase literal match subexp))))

View file

@ -3033,12 +3033,12 @@ If optional arg RESEAT is non-nil, make markers on LIST point nowhere. */)
DEFUN ("match-data--translate", Fmatch_data__translate, Smatch_data__translate,
1, 1, 0,
doc: /* Add N to all string positions in the match data. Internal. */)
doc: /* Add N to all positions in the match data. Internal. */)
(Lisp_Object n)
{
CHECK_FIXNUM (n);
EMACS_INT delta = XFIXNUM (n);
if (EQ (last_thing_searched, Qt)) /* String match data only. */
if (!NILP (last_thing_searched))
for (ptrdiff_t i = 0; i < search_regs.num_regs; i++)
if (search_regs.start[i] >= 0)
{

View file

@ -551,6 +551,30 @@ See https://debbugs.gnu.org/cgi/bugreport.cgi?bug=19350."
(should (equal (replace-regexp-in-string "\\`\\|x" "z" "--xx--")
"z--zz--")))
(ert-deftest subr-match-substitute-replacement ()
(with-temp-buffer
(insert "Alpha Beta Gamma Delta Epsilon")
(goto-char (point-min))
(re-search-forward "B\\(..\\)a")
(should (equal (match-substitute-replacement "carrot")
"Carrot"))
(should (equal (match-substitute-replacement "<\\&>")
"<Beta>"))
(should (equal (match-substitute-replacement "m\\1a")
"Meta"))
(should (equal (match-substitute-replacement "ernin" nil nil nil 1)
"Bernina")))
(let ((s "Tau Beta Gamma Delta Epsilon"))
(string-match "B\\(..\\)a" s)
(should (equal (match-substitute-replacement "carrot" nil nil s)
"Carrot"))
(should (equal (match-substitute-replacement "<\\&>" nil nil s)
"<Beta>"))
(should (equal (match-substitute-replacement "m\\1a" nil nil s)
"Meta"))
(should (equal (match-substitute-replacement "ernin" nil nil s 1)
"Bernina"))))
(ert-deftest subr-tests--change-group-33341 ()
(with-temp-buffer
(buffer-enable-undo)