]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix replace-in-string multibyteness problems with string-search
authorLars Ingebrigtsen <larsi@gnus.org>
Thu, 24 Sep 2020 23:53:07 +0000 (01:53 +0200)
committerLars Ingebrigtsen <larsi@gnus.org>
Thu, 24 Sep 2020 23:53:16 +0000 (01:53 +0200)
* lisp/subr.el (replace-in-string): Simplify by using the new
string-search function (bug#43598).

lisp/subr.el
test/lisp/subr-tests.el

index 377d914718ad65cbcf4ec3cbeda34c056e64804c..0f72b382fe8171226b28292ba8380810dab4edb7 100644 (file)
@@ -4430,37 +4430,18 @@ Unless optional argument INPLACE is non-nil, return a new string."
     newstr))
 
 (defun replace-in-string (fromstring tostring instring)
-  "Replace FROMSTRING with TOSTRING in INSTRING each time it occurs.
-This function returns a freshly created string."
-  (declare (side-effect-free t))
-  (let ((i 0)
-        (start 0)
-        (result nil))
-    (while (< i (length instring))
-      (if (eq (aref instring i)
-              (aref fromstring 0))
-          ;; See if we're in a match.
-          (let ((ii i)
-                (if 0))
-            (while (and (< ii (length instring))
-                        (< if (length fromstring))
-                        (eq (aref instring ii)
-                            (aref fromstring if)))
-              (setq ii (1+ ii)
-                    if (1+ if)))
-            (if (not (= if (length fromstring)))
-                ;; We didn't have a match after all.
-                (setq i (1+ i))
-              ;; We had one, so gather the previous part and the
-              ;; substitution.
-              (when (not (= start i))
-                (push (substring instring start i) result))
-              (push tostring result)
-              (setq i ii
-                    start ii)))
-        (setq i (1+ i))))
-    (when (not (= start i))
-      (push (substring instring start i) result))
+  "Replace FROMSTRING with TOSTRING in INSTRING each time it occurs."
+  (declare (pure t))
+  (let ((start 0)
+        (result nil)
+        pos)
+    (while (setq pos (string-search fromstring instring start))
+      (unless (= start pos)
+        (push (substring instring start pos) result))
+      (push tostring result)
+      (setq start (+ start (length fromstring))))
+    (unless (= start pos)
+      (push (substring instring start pos) result))
     (apply #'concat (nreverse result))))
 
 (defun replace-regexp-in-string (regexp rep string &optional
index 2adb4a62e86819a71d6f66929c6701e1d643cc98..14870d4adaba5c69f45b07f2e6c69868971d9804 100644 (file)
@@ -456,7 +456,15 @@ See https://debbugs.gnu.org/cgi/bugreport.cgi?bug=19350."
   (should (equal (replace-in-string "azot" "bar" "zat")
                  "zat"))
   (should (equal (replace-in-string "azot" "bar" "azot")
-                 "bar")))
+                 "bar"))
+
+  (should (equal (replace-in-string "azot" "bar" "foozotbar")
+                 "foozotbar"))
+
+  (should (equal (replace-in-string "\377" "x" "a\377b")
+                 "axxb"))
+  (should (equal (replace-in-string "\377" "x" "a\377ø")
+                 "axxø")))
 
 (provide 'subr-tests)
 ;;; subr-tests.el ends here