JavaScriptCore:
authorddkilzer <ddkilzer@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 3 Jun 2006 04:56:56 +0000 (04:56 +0000)
committerddkilzer <ddkilzer@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 3 Jun 2006 04:56:56 +0000 (04:56 +0000)
        Reviewed by ggaren.

        - http://bugzilla.opendarwin.org/show_bug.cgi?id=9234
          Implement $&, $' and $` replacement codes in String.prototype.replace

        Test: fast/js/string-replace-3.html

        * kjs/string_object.cpp:
        (substituteBackreferences): Added support for $& (matched substring),
        $` (everything preceding matched substring), $' (everything following
        matched substring) and 2-digit back references, and cleaned up a little.

LayoutTests:

        Reviewed by ggaren.

        - test for http://bugzilla.opendarwin.org/show_bug.cgi?id=9234
          Implement $&, $' and $` replacement codes in String.prototype.replace

        * fast/js/resources/string-replace-3.js: Added.
        * fast/js/string-replace-3-expected.txt: Added.
        * fast/js/string-replace-3.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@14705 268f45cc-cd09-0410-ab3c-d52691b4dbfc

JavaScriptCore/ChangeLog
JavaScriptCore/kjs/string_object.cpp
LayoutTests/ChangeLog
LayoutTests/fast/js/resources/string-replace-3.js [new file with mode: 0644]
LayoutTests/fast/js/string-replace-3-expected.txt [new file with mode: 0644]
LayoutTests/fast/js/string-replace-3.html [new file with mode: 0644]

index 637fa8e5fbf42dde6891dde1b41da9c03474f043..ba92d903f13f25287aeee6de46bf5fde9aee396e 100644 (file)
@@ -1,3 +1,17 @@
+2006-06-02  Mitz Pettel  <opendarwin.org@mitzpettel.com>
+
+        Reviewed by ggaren.
+
+        - http://bugzilla.opendarwin.org/show_bug.cgi?id=9234
+          Implement $&, $' and $` replacement codes in String.prototype.replace
+
+        Test: fast/js/string-replace-3.html
+
+        * kjs/string_object.cpp:
+        (substituteBackreferences): Added support for $& (matched substring),
+        $` (everything preceding matched substring), $' (everything following
+        matched substring) and 2-digit back references, and cleaned up a little.
+
 2006-06-02 Adele Peterson  <adele@apple.com>
 
         Reviewed by Darin.
index 884638e21e23e1cd4942003af6e7224a294369fe..841ce702d4d44b1042c1ca768a0c3d5e5d87c12b 100644 (file)
@@ -232,23 +232,49 @@ static inline UString substituteBackreferences(const UString &replacement, const
 {
   UString substitutedReplacement = replacement;
 
-  bool converted;
+  int i = -1;
+  while ((i = substitutedReplacement.find(UString("$"), i + 1)) != -1) {
+    if (i+1 == substitutedReplacement.size())
+        break;
 
-  for (int i = 0; (i = substitutedReplacement.find(UString("$"), i)) != -1; i++) {
-    if (i+1 < substitutedReplacement.size() && substitutedReplacement[i+1] == '$') {  // "$$" -> "$"
-      substitutedReplacement = substitutedReplacement.substr(0,i) + "$" + substitutedReplacement.substr(i+2);
-      continue;
-    }
-    // Assume number part is one char exactly
-    unsigned backrefIndex = substitutedReplacement.substr(i+1,1).toUInt32(&converted, false /* tolerate empty string */);
-    if (converted && backrefIndex <= (unsigned)reg->subPatterns()) {
-      int backrefStart = ovector[2*backrefIndex];
-      int backrefLength = ovector[2*backrefIndex+1] - backrefStart;
-      substitutedReplacement = substitutedReplacement.substr(0,i)
-        + source.substr(backrefStart, backrefLength)
-        + substitutedReplacement.substr(i+2);
-      i += backrefLength - 1; // -1 offsets i++
-    }
+    unsigned short ref = substitutedReplacement[i+1].unicode();
+    int backrefStart = 0;
+    int backrefLength = 0;
+    int advance = 0;
+
+    if (ref == '$') {  // "$$" -> "$"
+        substitutedReplacement = substitutedReplacement.substr(0, i + 1) + substitutedReplacement.substr(i + 2);
+        continue;
+    } else if (ref == '&') {
+        backrefStart = ovector[0];
+        backrefLength = ovector[1] - backrefStart;
+    } else if (ref == '`') {
+        backrefStart = 0;
+        backrefLength = ovector[0];
+    } else if (ref == '\'') {
+        backrefStart = ovector[1];
+        backrefLength = source.size() - backrefStart;
+    } else if (ref >= '0' && ref <= '9') {
+        // 1- and 2-digit back references are allowed
+        unsigned backrefIndex = ref - '0';
+        if (substitutedReplacement.size() > i + 2) {
+            ref = substitutedReplacement[i+2].unicode();
+            if (ref >= '0' && ref <= '9') {
+                backrefIndex = 10 * backrefIndex + ref - '0';
+                advance = 1;
+            }
+        }
+        if (backrefIndex > (unsigned)reg->subPatterns()) {
+            i += advance;
+            continue;
+        }
+        backrefStart = ovector[2 * backrefIndex];
+        backrefLength = ovector[2 * backrefIndex + 1] - backrefStart;
+    } else
+        continue;
+
+    substitutedReplacement = substitutedReplacement.substr(0, i) + source.substr(backrefStart, backrefLength) + substitutedReplacement.substr(i + 2 + advance);
+    i += backrefLength - 1; // - 1 offsets 'i + 1'
   }
 
   return substitutedReplacement;
index ad2eb8c9e552626764f29233a927e26f2dcebd18..eb36311ba7e0086dff5423f740c1a375741659e8 100644 (file)
@@ -1,3 +1,14 @@
+2006-06-02  Mitz Pettel  <opendarwin.org@mitzpettel.com>
+
+        Reviewed by ggaren.
+
+        - test for http://bugzilla.opendarwin.org/show_bug.cgi?id=9234
+          Implement $&, $' and $` replacement codes in String.prototype.replace
+
+        * fast/js/resources/string-replace-3.js: Added.
+        * fast/js/string-replace-3-expected.txt: Added.
+        * fast/js/string-replace-3.html: Added.
+
 2006-06-02  David Carson  <dacarson@gmail.com>
 
         Reviewed by Hyatt, checked in by Tim H.
diff --git a/LayoutTests/fast/js/resources/string-replace-3.js b/LayoutTests/fast/js/resources/string-replace-3.js
new file mode 100644 (file)
index 0000000..2cd5ce3
--- /dev/null
@@ -0,0 +1,17 @@
+description(
+"String.replace(&hellip;) test &mdash; $&amp;, $`, $' and $nn"
+);
+
+var testString = "It's the end of the world as we know it, and I feel fine.";
+shouldBe("testString",
+         "\"It's the end of the world as we know it, and I feel fine.\"");
+shouldBe("testString.replace(/I feel/, 'yet $& just')",
+         "\"It's the end of the world as we know it, and yet I feel just fine.\"");
+shouldBe("testString.replace(/the end/, 'nice. $`a picture')",
+         "\"It's nice. It's a picture of the world as we know it, and I feel fine.\"");
+shouldBe('testString.replace(/feel fin/, "am gon$\' By")',
+         "\"It's the end of the world as we know it, and I am gone. Bye.\"");
+shouldBe("testString.replace(/(t)(h)(e e)(n)(d)( o)(f)( )(t)(h)(e )([^r]*)(rld)/, 'not $12olly mammoth')",
+         "\"It's not woolly mammoth as we know it, and I feel fine.\"");
+
+var successfullyParsed = true;
diff --git a/LayoutTests/fast/js/string-replace-3-expected.txt b/LayoutTests/fast/js/string-replace-3-expected.txt
new file mode 100644 (file)
index 0000000..9d835ad
--- /dev/null
@@ -0,0 +1,14 @@
+String.replace(…) test — $&, $`, $' and $nn
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS testString is "It's the end of the world as we know it, and I feel fine."
+PASS testString.replace(/I feel/, 'yet $& just') is "It's the end of the world as we know it, and yet I feel just fine."
+PASS testString.replace(/the end/, 'nice. $`a picture') is "It's nice. It's a picture of the world as we know it, and I feel fine."
+PASS testString.replace(/feel fin/, "am gon$' By") is "It's the end of the world as we know it, and I am gone. Bye."
+PASS testString.replace(/(t)(h)(e e)(n)(d)( o)(f)( )(t)(h)(e )([^r]*)(rld)/, 'not $12olly mammoth') is "It's not woolly mammoth as we know it, and I feel fine."
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/js/string-replace-3.html b/LayoutTests/fast/js/string-replace-3.html
new file mode 100644 (file)
index 0000000..7862ef6
--- /dev/null
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href="resources/js-test-style.css">
+<script src="resources/js-test-pre.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script src="resources/string-replace-3.js"></script>
+<script src="resources/js-test-post.js"></script>
+</body>
+</html>