Add JSC:RegExp functional tests
authormsaboff@apple.com <msaboff@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 3 Sep 2011 00:41:32 +0000 (00:41 +0000)
committermsaboff@apple.com <msaboff@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 3 Sep 2011 00:41:32 +0000 (00:41 +0000)
https://bugs.webkit.org/show_bug.cgi?id=67339

Source/JavaScriptCore:

Added new test driver program (testRegExp) and corresponding data file
along with build scripts changes.

Reviewed by Gavin Barraclough.

* JavaScriptCore.exp:
* JavaScriptCore.xcodeproj/project.pbxproj:
* testRegExp.cpp: Added.
(Options::Options):
(StopWatch::start):
(StopWatch::stop):
(StopWatch::getElapsedMS):
(RegExpTest::RegExpTest):
(GlobalObject::create):
(GlobalObject::className):
(GlobalObject::GlobalObject):
(main):
(cleanupGlobalData):
(testOneRegExp):
(scanString):
(parseRegExpLine):
(parseTestLine):
(runFromFiles):
(printUsageStatement):
(parseArguments):
(realMain):
* tests/regexp: Added.
* tests/regexp/RegExpTest.data: Added.

Tools:

New perl script to build JavaScriptCore and run the RegExp tests.

Reviewed by Gavin Barraclough.

* Scripts/run-regexp-tests: Added.

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

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/JavaScriptCore.exp
Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
Source/JavaScriptCore/testRegExp.cpp [new file with mode: 0644]
Source/JavaScriptCore/tests/regexp/RegExpTest.data [new file with mode: 0644]
Tools/ChangeLog
Tools/Scripts/run-regexp-tests [new file with mode: 0755]

index e461023..f709680 100644 (file)
@@ -1,5 +1,39 @@
 2011-09-02  Michael Saboff  <msaboff@apple.com>
 
+        Add JSC:RegExp functional tests
+        https://bugs.webkit.org/show_bug.cgi?id=67339
+
+        Added new test driver program (testRegExp) and corresponding data file
+        along with build scripts changes.
+
+        Reviewed by Gavin Barraclough.
+
+        * JavaScriptCore.exp:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * testRegExp.cpp: Added.
+        (Options::Options):
+        (StopWatch::start):
+        (StopWatch::stop):
+        (StopWatch::getElapsedMS):
+        (RegExpTest::RegExpTest):
+        (GlobalObject::create):
+        (GlobalObject::className):
+        (GlobalObject::GlobalObject):
+        (main):
+        (cleanupGlobalData):
+        (testOneRegExp):
+        (scanString):
+        (parseRegExpLine):
+        (parseTestLine):
+        (runFromFiles):
+        (printUsageStatement):
+        (parseArguments):
+        (realMain):
+        * tests/regexp: Added.
+        * tests/regexp/RegExpTest.data: Added.
+
+2011-09-02  Michael Saboff  <msaboff@apple.com>
+
         Add JSC:RegExp functional test data generator
         https://bugs.webkit.org/show_bug.cgi?id=67519
 
index 9b3c174..c50a5ad 100644 (file)
@@ -268,6 +268,7 @@ __ZN3JSC6JSLock4lockENS_14JSLockBehaviorE
 __ZN3JSC6JSLock6unlockENS_14JSLockBehaviorE
 __ZN3JSC6JSLock9lockCountEv
 __ZN3JSC6JSLockC1EPNS_9ExecStateE
+__ZN3JSC6RegExp5matchERNS_12JSGlobalDataERKNS_7UStringEiPN3WTF6VectorIiLm32EEE
 __ZN3JSC6RegExp6createERNS_12JSGlobalDataERKNS_7UStringENS_11RegExpFlagsE
 __ZN3JSC6RegExpD1Ev
 __ZN3JSC7JSArray13visitChildrenERNS_11SlotVisitorE
index 099244c..43d8bf4 100644 (file)
@@ -27,6 +27,7 @@
                                141214BF0A49190E00480255 /* PBXTargetDependency */,
                                932F5BE90822A1C700736975 /* PBXTargetDependency */,
                                14BD59C70A3E8FA400BAF59C /* PBXTargetDependency */,
+                               651123091404768B002B101D /* PBXTargetDependency */,
                        );
                        name = All;
                        productName = All;
                5DBB1525131D0BD70056AD36 /* minidom.js in Copy Support Script */ = {isa = PBXBuildFile; fileRef = 1412110D0A48788700480255 /* minidom.js */; };
                5DE6E5B30E1728EC00180407 /* create_hash_table in Headers */ = {isa = PBXBuildFile; fileRef = F692A8540255597D01FF60F7 /* create_hash_table */; settings = {ATTRIBUTES = (); }; };
                6507D29E0E871E5E00D7D896 /* JSTypeInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 6507D2970E871E4A00D7D896 /* JSTypeInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               651122FD14046A4C002B101D /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 932F5BD90822A1C700736975 /* JavaScriptCore.framework */; };
+               651122FE14046A4C002B101D /* libedit.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 5D5D8AD00E0D0EBE00F9C692 /* libedit.dylib */; };
+               6511230714046B0A002B101D /* testRegExp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 651122E5140469BA002B101D /* testRegExp.cpp */; };
                651DCA04136A6FEF00F74194 /* PassTraits.h in Headers */ = {isa = PBXBuildFile; fileRef = 651DCA02136A6FAB00F74194 /* PassTraits.h */; settings = {ATTRIBUTES = (Private, ); }; };
                655EB29B10CE2581001A990E /* NodesCodegen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 655EB29A10CE2581001A990E /* NodesCodegen.cpp */; };
                65DFC93308EA173A00F7300B /* HashTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65DFC92D08EA173A00F7300B /* HashTable.cpp */; };
                        remoteGlobalIDString = 14BD59BE0A3E8F9000BAF59C;
                        remoteInfo = testapi;
                };
+               651122F914046A4C002B101D /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 932F5B3E0822A1C700736975;
+                       remoteInfo = JavaScriptCore;
+               };
+               651123081404768B002B101D /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 651122F714046A4C002B101D;
+                       remoteInfo = testRegExp;
+               };
                65FB3F7D09D11EF300F49DEB /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
                5DBD18AF0C5401A700C15EAE /* MallocZoneSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MallocZoneSupport.h; sourceTree = "<group>"; };
                5DE3D0F40DD8DDFB00468714 /* WebKitAvailability.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebKitAvailability.h; sourceTree = "<group>"; };
                6507D2970E871E4A00D7D896 /* JSTypeInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSTypeInfo.h; sourceTree = "<group>"; };
+               651122E5140469BA002B101D /* testRegExp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = testRegExp.cpp; sourceTree = "<group>"; };
+               651122EE14046A19002B101D /* main.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
+               651122F014046A19002B101D /* regexp_test.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = regexp_test.1; sourceTree = "<group>"; };
+               6511230514046A4C002B101D /* testRegExp */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testRegExp; sourceTree = BUILT_PRODUCTS_DIR; };
                651DCA02136A6FAB00F74194 /* PassTraits.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PassTraits.h; sourceTree = "<group>"; };
                651F6412039D5B5F0078395C /* dtoa.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dtoa.cpp; sourceTree = "<group>"; tabWidth = 8; };
                651F6413039D5B5F0078395C /* dtoa.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = dtoa.h; sourceTree = "<group>"; tabWidth = 8; };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               651122FC14046A4C002B101D /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               651122FD14046A4C002B101D /* JavaScriptCore.framework in Frameworks */,
+                               651122FE14046A4C002B101D /* libedit.dylib in Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
                932F5BD20822A1C700736975 /* Frameworks */ = {
                        isa = PBXFrameworksBuildPhase;
                        buildActionMask = 2147483647;
                                932F5BE10822A1C700736975 /* jsc */,
                                141211200A48793C00480255 /* minidom */,
                                14BD59BF0A3E8F9000BAF59C /* testapi */,
+                               6511230514046A4C002B101D /* testRegExp */,
                        );
                        name = Products;
                        sourceTree = "<group>";
                0867D691FE84028FC02AAC07 /* JavaScriptCore */ = {
                        isa = PBXGroup;
                        children = (
+                               651122E5140469BA002B101D /* testRegExp.cpp */,
                                A718F8211178EB4B002465A7 /* create_regex_tables */,
                                937B63CC09E766D200A671DD /* DerivedSources.make */,
                                A7C225CC139981F100FF1662 /* KeywordLookupGenerator.py */,
                                86EAC48C0F93E8B9008EC948 /* yarr */,
                                1C90513E0BA9E8830081E9D0 /* Configurations */,
                                650FDF8D09D0FCA700769E54 /* Derived Sources */,
+                               651122ED14046A19002B101D /* regexp_test */,
                                0867D69AFE84028FC02AAC07 /* Frameworks */,
                                034768DFFF38A50411DB9C8B /* Products */,
                                932FC3C20824BB70005B3C75 /* Resources */,
                        tabWidth = 4;
                        usesTabs = 0;
                };
+               651122ED14046A19002B101D /* regexp_test */ = {
+                       isa = PBXGroup;
+                       children = (
+                               651122EE14046A19002B101D /* main.cpp */,
+                               651122F014046A19002B101D /* regexp_test.1 */,
+                       );
+                       path = regexp_test;
+                       sourceTree = "<group>";
+               };
                65162EF108E6A21C007556CD /* wtf */ = {
                        isa = PBXGroup;
                        children = (
                        productReference = 14BD59BF0A3E8F9000BAF59C /* testapi */;
                        productType = "com.apple.product-type.tool";
                };
+               651122F714046A4C002B101D /* testRegExp */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 6511230014046A4C002B101D /* Build configuration list for PBXNativeTarget "testRegExp" */;
+                       buildPhases = (
+                               651122FA14046A4C002B101D /* Sources */,
+                               651122FC14046A4C002B101D /* Frameworks */,
+                               651122FF14046A4C002B101D /* Copy Into Framework */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                               651122F814046A4C002B101D /* PBXTargetDependency */,
+                       );
+                       name = testRegExp;
+                       productInstallPath = /usr/local/bin;
+                       productName = jsc;
+                       productReference = 6511230514046A4C002B101D /* testRegExp */;
+                       productType = "com.apple.product-type.tool";
+               };
                932F5B3E0822A1C700736975 /* JavaScriptCore */ = {
                        isa = PBXNativeTarget;
                        buildConfigurationList = 149C275D08902AFE008A9EFC /* Build configuration list for PBXNativeTarget "JavaScriptCore" */;
                                1412111F0A48793C00480255 /* minidom */,
                                14BD59BE0A3E8F9000BAF59C /* testapi */,
                                932F5BDA0822A1C700736975 /* jsc */,
+                               651122F714046A4C002B101D /* testRegExp */,
                        );
                };
 /* End PBXProject section */
                        shellPath = /bin/sh;
                        shellScript = "# Skip for Production builds.\nif [[ ${CONFIGURATION:=Debug} == \"Production\" ]]; then\n    exit\nfi\n\n# Copy and update the jsc binary to refer to JavaScriptcore.framework relative to its location.\nditto \"${BUILT_PRODUCTS_DIR}/jsc\" \"${BUILT_PRODUCTS_DIR}/JavaScriptCore.framework/Resources/jsc\"\ninstall_name_tool -change \"${BUILT_PRODUCTS_DIR}/JavaScriptCore.framework/Versions/A/JavaScriptCore\" \"@loader_path/../JavaScriptCore\" \"${BUILT_PRODUCTS_DIR}/JavaScriptCore.framework/Resources/jsc\"\n";
                };
+               651122FF14046A4C002B101D /* Copy Into Framework */ = {
+                       isa = PBXShellScriptBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       inputPaths = (
+                               "$(BUILT_PRODUCTS_DIR)/JavaScriptCore.framework/Resources/jsc",
+                       );
+                       name = "Copy Into Framework";
+                       outputPaths = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+                       shellPath = /bin/sh;
+                       shellScript = "# Skip for Production builds.\nif [[ ${CONFIGURATION:=Debug} == \"Production\" ]]; then\n    exit\nfi\n\n# Copy and update the testRegExp binary to refer to JavaScriptcore.framework relative to its location.\nditto \"${BUILT_PRODUCTS_DIR}/testRegExp\" \"${BUILT_PRODUCTS_DIR}/JavaScriptCore.framework/Resources/testRegExp\"\ninstall_name_tool -change \"${BUILT_PRODUCTS_DIR}/JavaScriptCore.framework/Versions/A/JavaScriptCore\" \"@loader_path/../JavaScriptCore\" \"${BUILT_PRODUCTS_DIR}/JavaScriptCore.framework/Resources/testRegExp\"\n";
+               };
                65FB3F6509D11E9100F49DEB /* Generate Derived Sources */ = {
                        isa = PBXShellScriptBuildPhase;
                        buildActionMask = 2147483647;
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               651122FA14046A4C002B101D /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               6511230714046B0A002B101D /* testRegExp.cpp in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
                932F5B910822A1C700736975 /* Sources */ = {
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                        target = 14BD59BE0A3E8F9000BAF59C /* testapi */;
                        targetProxy = 14BD59C60A3E8FA400BAF59C /* PBXContainerItemProxy */;
                };
+               651122F814046A4C002B101D /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 932F5B3E0822A1C700736975 /* JavaScriptCore */;
+                       targetProxy = 651122F914046A4C002B101D /* PBXContainerItemProxy */;
+               };
+               651123091404768B002B101D /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 651122F714046A4C002B101D /* testRegExp */;
+                       targetProxy = 651123081404768B002B101D /* PBXContainerItemProxy */;
+               };
                65FB3F7E09D11EF300F49DEB /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        target = 65FB3F6609D11E9100F49DEB /* Derived Sources */;
                        };
                        name = Production;
                };
+               6511230114046A4C002B101D /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               PRODUCT_NAME = testRegExp;
+                       };
+                       name = Debug;
+               };
+               6511230214046A4C002B101D /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               PRODUCT_NAME = testRegExp;
+                       };
+                       name = Release;
+               };
+               6511230314046A4C002B101D /* Profiling */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               PRODUCT_NAME = testRegExp;
+                       };
+                       name = Profiling;
+               };
+               6511230414046A4C002B101D /* Production */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               INSTALL_PATH = "$(JAVASCRIPTCORE_FRAMEWORKS_DIR)/JavaScriptCore.framework/Resources";
+                               PRODUCT_NAME = testRegExp;
+                       };
+                       name = Production;
+               };
                65FB3F7809D11EBD00F49DEB /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Production;
                };
+               6511230014046A4C002B101D /* Build configuration list for PBXNativeTarget "testRegExp" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               6511230114046A4C002B101D /* Debug */,
+                               6511230214046A4C002B101D /* Release */,
+                               6511230314046A4C002B101D /* Profiling */,
+                               6511230414046A4C002B101D /* Production */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Production;
+               };
                65FB3F7709D11EBD00F49DEB /* Build configuration list for PBXAggregateTarget "Derived Sources" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
diff --git a/Source/JavaScriptCore/testRegExp.cpp b/Source/JavaScriptCore/testRegExp.cpp
new file mode 100644 (file)
index 0000000..06c36cd
--- /dev/null
@@ -0,0 +1,506 @@
+/*
+ *  Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "RegExp.h"
+
+#include "CurrentTime.h"
+#include "InitializeThreading.h"
+#include "JSGlobalObject.h"
+#include "UStringBuilder.h"
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if !OS(WINDOWS)
+#include <unistd.h>
+#endif
+
+#if HAVE(SYS_TIME_H)
+#include <sys/time.h>
+#endif
+
+#if COMPILER(MSVC) && !OS(WINCE)
+#include <crtdbg.h>
+#include <mmsystem.h>
+#include <windows.h>
+#endif
+
+#if PLATFORM(QT)
+#include <QCoreApplication>
+#include <QDateTime>
+#endif
+
+const int MaxLineLength = 100 * 1024;
+
+using namespace JSC;
+using namespace WTF;
+
+static void cleanupGlobalData(JSGlobalData*);
+
+struct Options {
+    Options()
+        : interactive(false)
+        , verbose(false)
+    {
+    }
+
+    bool interactive;
+    bool verbose;
+    Vector<UString> arguments;
+    Vector<UString> files;
+};
+
+class StopWatch {
+public:
+    void start();
+    void stop();
+    long getElapsedMS(); // call stop() first
+
+private:
+    double m_startTime;
+    double m_stopTime;
+};
+
+void StopWatch::start()
+{
+    m_startTime = currentTime();
+}
+
+void StopWatch::stop()
+{
+    m_stopTime = currentTime();
+}
+
+long StopWatch::getElapsedMS()
+{
+    return static_cast<long>((m_stopTime - m_startTime) * 1000);
+}
+
+struct RegExpTest {
+    RegExpTest()
+        : offset(0)
+        , result(0)
+    {
+    }
+
+    UString subject;
+    int offset;
+    int result;
+    Vector<int, 32> expectVector;
+};
+
+class GlobalObject : public JSGlobalObject {
+private:
+    GlobalObject(JSGlobalData&, Structure*, const Vector<UString>& arguments);
+
+public:
+    typedef JSGlobalObject Base;
+
+    static GlobalObject* create(JSGlobalData& globalData, Structure* structure, const Vector<UString>& arguments)
+    {
+        return new (allocateCell<GlobalObject>(globalData.heap)) GlobalObject(globalData, structure, arguments);
+    }
+    virtual UString className() const { return "global"; }
+};
+
+COMPILE_ASSERT(!IsInteger<GlobalObject>::value, WTF_IsInteger_GlobalObject_false);
+ASSERT_CLASS_FITS_IN_CELL(GlobalObject);
+
+GlobalObject::GlobalObject(JSGlobalData& globalData, Structure* structure, const Vector<UString>& arguments)
+    : JSGlobalObject(globalData, structure)
+{
+    UNUSED_PARAM(arguments);
+}
+
+// Use SEH for Release builds only to get rid of the crash report dialog
+// (luckily the same tests fail in Release and Debug builds so far). Need to
+// be in a separate main function because the realMain function requires object
+// unwinding.
+
+#if COMPILER(MSVC) && !COMPILER(INTEL) && !defined(_DEBUG) && !OS(WINCE)
+#define TRY       __try {
+#define EXCEPT(x) } __except (EXCEPTION_EXECUTE_HANDLER) { x; }
+#else
+#define TRY
+#define EXCEPT(x)
+#endif
+
+int realMain(int argc, char** argv, JSGlobalData*);
+
+int main(int argc, char** argv)
+{
+#if OS(WINDOWS)
+#if !OS(WINCE)
+    // Cygwin calls ::SetErrorMode(SEM_FAILCRITICALERRORS), which we will inherit. This is bad for
+    // testing/debugging, as it causes the post-mortem debugger not to be invoked. We reset the
+    // error mode here to work around Cygwin's behavior. See <http://webkit.org/b/55222>.
+    ::SetErrorMode(0);
+#endif
+
+#if defined(_DEBUG)
+    _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
+    _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
+    _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
+    _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE);
+    _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
+    _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE);
+#endif
+
+    timeBeginPeriod(1);
+#endif
+
+#if PLATFORM(QT)
+    QCoreApplication app(argc, argv);
+#endif
+
+    // Initialize JSC before getting JSGlobalData.
+    JSC::initializeThreading();
+
+    // We can't use destructors in the following code because it uses Windows
+    // Structured Exception Handling
+    int res = 0;
+    JSGlobalData* globalData = JSGlobalData::create(ThreadStackTypeLarge, LargeHeap).leakRef();
+    TRY
+        res = realMain(argc, argv, globalData);
+    EXCEPT(res = 3)
+
+    cleanupGlobalData(globalData);
+    return res;
+}
+
+static void cleanupGlobalData(JSGlobalData* globalData)
+{
+    JSLock lock(SilenceAssertionsOnly);
+    globalData->clearBuiltinStructures();
+    globalData->heap.destroy();
+    globalData->deref();
+}
+
+static bool testOneRegExp(JSGlobalData& globalData, RegExp* regexp, RegExpTest* regExpTest, bool verbose, unsigned int lineNumber)
+{
+    bool result = true;
+    Vector<int, 32> outVector;
+    outVector.resize(regExpTest->expectVector.size());
+    int matchResult = regexp->match(globalData, regExpTest->subject, regExpTest->offset, &outVector);
+
+    if (matchResult != regExpTest->result) {
+        result = false;
+        if (verbose)
+            printf("Line %d: results mismatch - expected %d got %d\n", lineNumber, regExpTest->result, matchResult);
+    } else if (matchResult != -1) {
+        if (outVector.size() != regExpTest->expectVector.size()) {
+            result = false;
+            if (verbose)
+                printf("Line %d: output vector size mismatch - expected %lu got %lu\n", lineNumber, regExpTest->expectVector.size(), outVector.size());
+        } else if (outVector.size() % 2) {
+            result = false;
+            if (verbose)
+                printf("Line %d: output vector size is odd (%lu), should be even\n", lineNumber, outVector.size());
+        } else {
+            // Check in pairs since the first value of the pair could be -1 in which case the second doesn't matter.
+            size_t pairCount = outVector.size() / 2;
+            for (size_t i = 0; i < pairCount; ++i) {
+                size_t startIndex = i*2;
+                if (outVector[startIndex] != regExpTest->expectVector[startIndex]) {
+                    result = false;
+                    if (verbose)
+                        printf("Line %d: output vector mismatch at index %lu - expected %d got %d\n", lineNumber, startIndex, regExpTest->expectVector[startIndex], outVector[startIndex]);
+                }
+                if ((i > 0) && (regExpTest->expectVector[startIndex] != -1) && (outVector[startIndex+1] != regExpTest->expectVector[startIndex+1])) {
+                    result = false;
+                    if (verbose)
+                        printf("Line %d: output vector mismatch at index %lu - expected %d got %d\n", lineNumber, startIndex+1, regExpTest->expectVector[startIndex+1], outVector[startIndex+1]);
+                }
+            }
+        }
+    }
+
+    return result;
+}
+
+static int scanString(char* buffer, int bufferLength, UStringBuilder& builder, char termChar)
+{
+    bool escape = false;
+    
+    for (int i = 0; i < bufferLength; ++i) {
+        UChar c = buffer[i];
+        
+        if (escape) {
+            switch (c) {
+            case '0':
+                c = '\0';
+                break;
+            case 'a':
+                c = '\a';
+                break;
+            case 'b':
+                c = '\b';
+                break;
+            case 'f':
+                c = '\f';
+                break;
+            case 'n':
+                c = '\n';
+                break;
+            case 'r':
+                c = '\r';
+                break;
+            case 't':
+                c = '\t';
+                break;
+            case 'v':
+                c = '\v';
+                break;
+            case '\\':
+                c = '\\';
+                break;
+            case '?':
+                c = '\?';
+                break;
+            case 'u':
+                if ((i + 4) >= bufferLength)
+                    return -1;
+                unsigned int charValue;
+                if (sscanf(buffer+i+1, "%04x", &charValue) != 1)
+                    return -1;
+                c = static_cast<UChar>(charValue);
+                i += 4;
+                break;
+            }
+            
+            builder.append(c);
+            escape = false;
+        } else {
+            if (c == termChar)
+                return i;
+
+            if (c == '\\')
+                escape = true;
+            else
+                builder.append(c);
+        }
+    }
+
+    return -1;
+}
+
+static RegExp* parseRegExpLine(JSGlobalData& globalData, char* line, int lineLength)
+{
+    UStringBuilder pattern;
+    
+    if (line[0] != '/')
+        return 0;
+
+    int i = scanString(line + 1, lineLength - 1, pattern, '/') + 1;
+
+    if ((i >= lineLength) || (line[i] != '/'))
+        return 0;
+
+    ++i;
+
+    return RegExp::create(globalData, pattern.toUString(), regExpFlags(line + i));
+}
+
+static RegExpTest* parseTestLine(char* line, int lineLength)
+{
+    UStringBuilder subjectString;
+    
+    if ((line[0] != ' ') || (line[1] != '"'))
+        return 0;
+
+    int i = scanString(line + 2, lineLength - 2, subjectString, '"') + 2;
+
+    if ((i >= (lineLength - 2)) || (line[i] != '"') || (line[i+1] != ',') || (line[i+2] != ' '))
+        return 0;
+
+    i += 3;
+    
+    int offset;
+    
+    if (sscanf(line + i, "%d, ", &offset) != 1)
+        return 0;
+
+    while (line[i] && line[i] != ' ')
+        ++i;
+
+    ++i;
+    
+    int matchResult;
+    
+    if (sscanf(line + i, "%d, ", &matchResult) != 1)
+        return 0;
+    
+    while (line[i] && line[i] != ' ')
+        ++i;
+    
+    ++i;
+    
+    if (line[i++] != '(')
+        return 0;
+
+    int start, end;
+    
+    RegExpTest* result = new RegExpTest();
+    
+    result->subject = subjectString.toUString();
+    result->offset = offset;
+    result->result = matchResult;
+
+    while (line[i] && line[i] != ')') {
+        if (sscanf(line + i, "%d, %d", &start, &end) != 2) {
+            delete result;
+            return 0;
+        }
+
+        result->expectVector.append(start);
+        result->expectVector.append(end);
+
+        while (line[i] && (line[i] != ',') && (line[i] != ')'))
+            i++;
+        i++;
+        while (line[i] && (line[i] != ',') && (line[i] != ')'))
+            i++;
+
+        if (line[i] == ')')
+            break;
+        if (!line[i] || (line[i] != ',')) {
+            delete result;
+            return 0;
+        }
+        i++;
+    }
+
+    return result;
+}
+
+static bool runFromFiles(GlobalObject* globalObject, const Vector<UString>& files, bool verbose)
+{
+    UString script;
+    UString fileName;
+    Vector<char> scriptBuffer;
+    unsigned tests = 0;
+    unsigned failures = 0;
+    char* lineBuffer = new char[MaxLineLength + 1];
+
+    JSGlobalData& globalData = globalObject->globalData();
+
+    bool success = true;
+    for (size_t i = 0; i < files.size(); i++) {
+        FILE* testCasesFile = fopen(files[i].utf8().data(), "rb");
+
+        if (!testCasesFile) {
+            printf("Unable to open test data file \"%s\"\n", files[i].utf8().data());
+            continue;
+        }
+            
+        RegExp* regexp = 0;
+        size_t lineLength = 0;
+        char* linePtr = 0;
+        unsigned int lineNumber = 0;
+
+        while ((linePtr = fgets(&lineBuffer[0], MaxLineLength, testCasesFile))) {
+            lineLength = strlen(linePtr);
+            if (linePtr[lineLength - 1] == '\n') {
+                linePtr[lineLength - 1] = '\0';
+                --lineLength;
+            }
+            ++lineNumber;
+
+            if (linePtr[0] == '#')
+                continue;
+
+            if (linePtr[0] == '/') {
+                regexp = parseRegExpLine(globalData, linePtr, lineLength);
+            } else if (linePtr[0] == ' ') {
+                RegExpTest* regExpTest = parseTestLine(linePtr, lineLength);
+                
+                if (regexp && regExpTest) {
+                    ++tests;
+                    if (!testOneRegExp(globalData, regexp, regExpTest, verbose, lineNumber)) {
+                        failures++;
+                        printf("Failure on line %u\n", lineNumber);
+                    }
+                }
+                
+                if (regExpTest)
+                    delete regExpTest;
+            }
+        }
+        
+        fclose(testCasesFile);
+    }
+
+    if (failures)
+        printf("%u tests run, %u failures\n", tests, failures);
+    else
+        printf("%u tests passed\n", tests);
+
+    delete[] lineBuffer;
+
+    globalData.dumpSampleData(globalObject->globalExec());
+#if ENABLE(REGEXP_TRACING)
+    globalData.dumpRegExpTrace();
+#endif
+    return success;
+}
+
+#define RUNNING_FROM_XCODE 0
+
+static NO_RETURN void printUsageStatement(JSGlobalData* globalData, bool help = false)
+{
+    fprintf(stderr, "Usage: regexp_test [options] file\n");
+    fprintf(stderr, "  -h|--help  Prints this help message\n");
+    fprintf(stderr, "  -v|--verbose  Verbose output\n");
+
+    cleanupGlobalData(globalData);
+    exit(help ? EXIT_SUCCESS : EXIT_FAILURE);
+}
+
+static void parseArguments(int argc, char** argv, Options& options, JSGlobalData* globalData)
+{
+    int i = 1;
+    for (; i < argc; ++i) {
+        const char* arg = argv[i];
+        if (!strcmp(arg, "-h") || !strcmp(arg, "--help"))
+            printUsageStatement(globalData, true);
+        if (!strcmp(arg, "-v") || !strcmp(arg, "--verbose"))
+            options.verbose = true;
+        else
+            options.files.append(argv[i]);
+    }
+
+    for (; i < argc; ++i)
+        options.arguments.append(argv[i]);
+}
+
+int realMain(int argc, char** argv, JSGlobalData* globalData)
+{
+    JSLock lock(SilenceAssertionsOnly);
+
+    Options options;
+    parseArguments(argc, argv, options, globalData);
+
+    GlobalObject* globalObject = GlobalObject::create(*globalData, GlobalObject::createStructure(*globalData, jsNull()), options.arguments);
+    bool success = runFromFiles(globalObject, options.files, options.verbose);
+
+    return success ? 0 : 3;
+}
diff --git a/Source/JavaScriptCore/tests/regexp/RegExpTest.data b/Source/JavaScriptCore/tests/regexp/RegExpTest.data
new file mode 100644 (file)
index 0000000..3a77e0b
--- /dev/null
@@ -0,0 +1,1040 @@
+# Test data file for JavaScriptCore::RegExp functional test.
+# The format of this file is:
+# # comment line
+# /{pattern}/{flags}
+#  "{string}", {offset}, {return-value}, {match-offset-vector}
+# Both the pattern and string accept backslash escapes.
+#
+/A/
+ "A", 0, 0, (0, 1)
+ "A2", 0, 0, (0, 1)
+/A2/
+ "A2", 0, 0, (0, 2)
+/\\u0041/
+ "A", 0, 0, (0, 1)
+/\\u00412/
+ "A2", 0, 0, (0, 2)
+/abc/
+ "abc", 0, 0, (0, 3)
+ "xabcy", 0, 1, (1, 4)
+ "ababc", 0, 2, (2, 5)
+ "xbc", 0, -1, (-1, -1)
+ "axc", 0, -1, (-1, -1)
+ "abx", 0, -1, (-1, -1)
+ "b", 0, -1, (-1, -1)
+/a|ab/
+ "abc", 0, 0, (0, 1)
+/(a|d|q|)x/i
+ "bcaDxqy", 0, 3, (3, 5, 3, 4)
+/(a|(e|q))(x|y)/
+ "bcaddxqy", 0, 6, (6, 8, 6, 7, 6, 7, 7, 8)
+/a*b/
+ "aaadaabaaa", 0, 4, (4, 7)
+ "xxx", 0, -1, (4, 4)
+/[^abc]def[abc]+/
+ "abxdefbb", 0, 2, (2, 8)
+/(a*)baa/
+ "ccdaaabaxaabaa", 0, 9, (9, 14, 9, 11)
+ "aabaa", 0, 0, (0, 5, 0, 2)
+/q(a|b)*q/
+ "xxqababqyy", 0, 2, (2, 8, 6, 7)
+/(a(.|[^d])c)*/
+ "adcaxc", 0, 0, (0, 6, 3, 6, 4, 5)
+/(a*)b\\1/
+ "abaaaxaabaayy", 0, 0, (0, 3, 0, 1)
+ "cccdaaabaxaabaayy", 0, 6, (6, 9, 6, 7)
+ "cccdaaabqxaabaayy", 0, 7, (7, 8, 7, 7)
+/x1g/
+ "x1g", 0, 0, (0, 3)
+/^x/
+ "x412", 0, 0, (0, 1)
+/\\u001g/
+ "u001g", 0, 0, (0, 5)
+/34/g
+ "343443444", 0, 0, (0, 2)
+ "343443444", 2, 2, (2, 4)
+ "343443444", 4, 5, (5, 7)
+ "343443444", 7, -1, (-1, -1)
+/\\d{1}/g
+ "123456abcde7890", 0, 0, (0, 1)
+ "123456abcde7890", 1, 1, (1, 2)
+ "123456abcde7890", 2, 2, (2, 3)
+ "123456abcde7890", 3, 3, (3, 4)
+ "123456abcde7890", 4, 4, (4, 5)
+ "123456abcde7890", 5, 5, (5, 6)
+ "123456abcde7890", 6, 11, (11, 12)
+ "123456abcde7890", 12, 12, (12, 13)
+ "123456abcde7890", 13, 13, (13, 14)
+ "123456abcde7890", 14, 14, (14, 15)
+ "123456abcde7890", 15, -1, (-1, -1)
+/\\d{2}/g
+ "123456abcde7890", 0, 0, (0, 2)
+ "123456abcde7890", 2, 2, (2, 4)
+ "123456abcde7890", 4, 4, (4, 6)
+ "123456abcde7890", 6, 11, (11, 13)
+ "123456abcde7890", 13, 13, (13, 15)
+ "123456abcde7890", 15, -1, (-1, -1)
+/\\D{2}/g
+ "123456abcde7890", 0, 6, (6, 8)
+ "123456abcde7890", 8, 8, (8, 10)
+ "123456abcde7890", 10, -1, (-1, -1)
+/([\\d]{5})([-\\ ]?[\\d]{4})?$/
+ "Boston, Mass. 02134", 0, 14, (14, 19, 14, 19, -1, -1)
+/l/
+ "hello", 0, 2, (2, 3)
+ "hello", 3, 3, (3, 4)
+ "hello", 4, -1, (-1, -1)
+/\\s/g
+ "x, x, x, x", 0, 2, (2, 3)
+ "x, x, x, x", 3, 5, (5, 6)
+ "x, x, x, x", 6, 8, (8, 9)
+ "x, x, x, x", 9, -1, (-1, -1)
+/((a)|(ab))((c)|(bc))/
+ "abc", 0, 0, (0, 3, 0, 1, 0, 1, -1, -1, 1, 3, -1, -1, 1, 3)
+/a[a-z]{2,4}/
+ "abcdefghi", 0, 0, (0, 5)
+/a[a-z]{2,4}?/
+ "abcdefghi", 0, 0, (0, 3)
+/(aa|aabaac|ba|b|c)*/
+ "aabaac", 0, 0, (0, 4, 2, 4)
+/^(a+)\\1*,\\1+$/
+ "aaaaaaaaaa,aaaaaaaaaaaaaaa", 0, 0, (0, 26, 0, 5)
+/(z)((a+)?(b+)?(c))*/
+ "zaacbbbcac", 0, 0, (0, 10, 0, 1, 8, 10, 8, 9, -1, -1, 9, 10)
+/(a*)*/
+ "b", 0, 0, (0, 0, -1, -1)
+ "ab", 0, 0, (0, 1, 0, 1)
+/(a*)b\\1+/
+ "baaaac", 0, 0, (0, 1, 0, 0)
+/(?=(a+))/
+ "baaabac", 0, 1, (1, 1, 1, 4)
+/(?=(a+))a*b\\1/
+ "baaabac", 0, 3, (3, 6, 3, 4)
+/(.*?)a(?!(a+)b\\2c)\\2(.*)/
+ "baaabaac", 0, 0, (0, 8, 0, 2, -1, -1, 3, 8)
+/\\w\\s\\w/g
+ "a b c d e", 0, 0, (0, 3)
+ "a b c d e", 3, 4, (4, 7)
+ "a b c d e", 7, -1, (-1, -1)
+/\\d\\d\\d/g
+ "12345678", 0, 0, (0, 3)
+ "12345678", 3, 3, (3, 6)
+ "12345678", 6, -1, (-1, -1)
+/abc/gi
+ "AbcaBcabC", 0, 0, (0, 3)
+ "AbcaBcabC", 3, 3, (3, 6)
+ "AbcaBcabC", 6, 6, (6, 9)
+ "AbcaBcabC", 9, -1, (-1, -1)
+/abc/i
+ "AbcaBcabC", 0, 0, (0, 3)
+ "ABC", 0, 0, (0, 3)
+ "XABCY", 0, 1, (1, 4)
+ "ABABC", 0, 2, (2, 5)
+ "XBC", 0, -1, (-1, -1)
+ "AXC", 0, -1, (-1, -1)
+ "ABX", 0, -1, (-1, -1)
+ "aaxabxbaxbbx", 0, -1, (-1, -1)
+/ab*c/
+ "abc", 0, 0, (0, 3)
+/ab*bc/
+ "abc", 0, 0, (0, 3)
+ "abbc", 0, 0, (0, 4)
+ "abbbbc", 0, 0, (0, 6)
+/.{1}/
+ "abbbbc", 0, 0, (0, 1)
+/.{3,4}/
+ "abbbbc", 0, 0, (0, 4)
+/ab{0,}bc/
+ "abbbbc", 0, 0, (0, 6)
+/ab+bc/
+ "abbc", 0, 0, (0, 4)
+ "abbbbc", 0, 0, (0, 6)
+ "abc", 0, -1, (0, 9)
+ "abq", 0, -1, (0, 9)
+ "abc", 0, -1, (0, -1)
+ "abq", 0, -1, (0, -1)
+/ab{1,}bc/
+ "abbbbc", 0, 0, (0, 6)
+ "abq", 0, -1, (0, 9)
+/ab{1,3}bc/
+ "abbbbc", 0, 0, (0, 6)
+ "abbbc", 0, 0, (0, 5)
+ "abbc", 0, 0, (0, 4)
+ "abc", 0, -1, (0, -1)
+ "abbbbbc", 0, -1, (4, -1)
+/ab{3,4}bc/
+ "abbbbc", 0, 0, (0, 6)
+/ab?bc/
+ "abbc", 0, 0, (0, 4)
+ "abc", 0, 0, (0, 3)
+ "abbbbc", 0, -1, (4, 9)
+/ab{0,1}bc/
+ "abc", 0, 0, (0, 3)
+/ab?c/
+ "abc", 0, 0, (0, 3)
+/ab{0,1}c/
+ "abc", 0, 0, (0, 3)
+/^abc$/
+ "abc", 0, 0, (0, 3)
+ "abcc", 0, -1, (-1, -1)
+ "aabc", 0, -1, (-1, -1)
+ "abbbbc", 0, -1, (-1, -1)
+ "qqq\nabc", 0, -1, (-1, -1)
+ "abc\nzzz", 0, -1, (-1, -1)
+ "qqq\nabc\nzzz", 0, -1, (-1, -1)
+/^abc/
+ "abcc", 0, 0, (0, 3)
+ "abcdefghi", 0, 0, (0, 3)
+ "abc", 0, 0, (0, 3)
+ "xyzabc", 0, -1, (-1, -1)
+/abc$/
+ "aabc", 0, 1, (1, 4)
+ "aabcd", 0, -1, (-1, -1)
+ "abc", 0, 0, (0, 3)
+ "abc\n", 0, -1, (-1, -1)
+ "abc\ndef", 0, -1, (-1, -1)
+/^/
+ "abc", 0, 0, (0, 0)
+ "test", 0, 0, (0, 0)
+/$/
+ "abc", 0, 3, (3, 3)
+ "a\nb\n", 0, 4, (4, 4)
+ "b\na\n", 0, 4, (4, 4)
+ "b\na", 0, 3, (3, 3)
+ "xxx", 0, 3, (3, 3)
+ "xxxx", 0, 4, (4, 4)
+/a.c/
+ "abc", 0, 0, (0, 3)
+ "axc", 0, 0, (0, 3)
+/a.*c/
+ "axyzc", 0, 0, (0, 5)
+ "axyzd", 0, -1, (4, 10)
+/a[bc]d/
+ "abd", 0, 0, (0, 3)
+ "abc", 0, -1, (-1, -1)
+ "axyzd", 0, -1, (-1, -1)
+/a[b-d]e/
+ "ace", 0, 0, (0, 3)
+ "abd", 0, -1, (-1, -1)
+/a[b-d]/
+ "aac", 0, 1, (1, 3)
+/a[-b]/
+ "a-", 0, 0, (0, 2)
+/a[b-]/
+ "a-", 0, 0, (0, 2)
+/a]/
+ "a]", 0, 0, (0, 2)
+/a[^bc]d/
+ "aed", 0, 0, (0, 3)
+ "abd", 0, -1, (-1, -1)
+/a[^-b]c/
+ "adc", 0, 0, (0, 3)
+ "a-c", 0, -1, (-1, -1)
+/\\ba\\b/
+ "a-", 0, 0, (0, 1)
+ "-a", 0, 1, (1, 2)
+ "-a-", 0, 1, (1, 2)
+/\\By\\b/
+ "xy", 0, 1, (1, 2)
+/\\by\\B/
+ "yz", 0, 0, (0, 1)
+/\\By\\B/
+ "xyz", 0, 1, (1, 2)
+/a\\Sb/
+ "a-b", 0, 0, (0, 3)
+ "a\tb a b a-b", 0, 8, (8, 11)
+ "a b", 0, -1, (-1, -1)
+/\\d/
+ "1", 0, 0, (0, 1)
+ "-", 0, -1, (-1, -1)
+ "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\f\n\r\t\v~`!@#$%^&*()-+={[}]|\\:;'<,>./? \"", 0, -1, (-1, -1)
+ "ab1cd", 0, 2, (2, 3)
+ "ab2cd", 0, 2, (2, 3)
+ "ab3cd", 0, 2, (2, 3)
+ "ab4cd", 0, 2, (2, 3)
+ "ab5cd", 0, 2, (2, 3)
+ "ab6cd", 0, 2, (2, 3)
+ "ab7cd", 0, 2, (2, 3)
+ "ab8cd", 0, 2, (2, 3)
+ "ab9cd", 0, 2, (2, 3)
+ "ab0cd", 0, 2, (2, 3)
+ "\u01003", 0, 1, (1, 2)
+/\\D/
+ "-", 0, 0, (0, 1)
+ "1", 0, -1, (-1, -1)
+ "1234567890", 0, -1, (-1, -1)
+ "12_34", 0, 2, (2, 3)
+ "12a34", 0, 2, (2, 3)
+ "12b34", 0, 2, (2, 3)
+ "1X2", 0, 1, (1, 2)
+ "1\u01002", 0, 1, (1, 2)
+/[\\w]/
+ "a", 0, 0, (0, 1)
+ "-", 0, -1, (-1, -1)
+/[\\W]/
+ "-", 0, 0, (0, 1)
+ "a", 0, -1, (-1, -1)
+/a[\\S]b/
+ "a-b", 0, 0, (0, 3)
+ "a b", 0, -1, (-1, -1)
+/[\\d]/
+ "1", 0, 0, (0, 1)
+ "-", 0, -1, (-1, -1)
+/[\\D]/
+ "-", 0, 0, (0, 1)
+ "1", 0, -1, (-1, -1)
+/ab|cd/
+ "abc", 0, 0, (0, 2)
+ "abcd", 0, 0, (0, 2)
+/()ef/
+ "def", 0, 1, (1, 3, 1, 1)
+/a\\(b/
+ "a(b", 0, 0, (0, 3)
+/a\\(*b/
+ "ab", 0, 0, (0, 2)
+ "a((b", 0, 0, (0, 4)
+/a\\\\b/
+ "a\\b", 0, 0, (0, 3)
+ "a\b", 0, -1, (-1, -1)
+/((a))/
+ "abc", 0, 0, (0, 1, 0, 1, 0, 1)
+/(a)b(c)/
+ "abc", 0, 0, (0, 3, 0, 1, 2, 3)
+/a+b+c/
+ "aabbabc", 0, 4, (4, 7)
+/a{1,}b{1,}c/
+ "aabbabc", 0, 4, (4, 7)
+/a.+?c/
+ "abcabc", 0, 0, (0, 3)
+/(a+|b)*/
+ "ab", 0, 0, (0, 2, 1, 2)
+/(a+|b){0,}/
+ "ab", 0, 0, (0, 2, 1, 2)
+/(a+|b)+/
+ "ab", 0, 0, (0, 2, 1, 2)
+/(a+|b){1,}/
+ "ab", 0, 0, (0, 2, 1, 2)
+/(a+|b)?/
+ "ab", 0, 0, (0, 1, 0, 1)
+/(a+|b){0,1}/
+ "ab", 0, 0, (0, 1, 0, 1)
+/[^ab]*/
+ "cde", 0, 0, (0, 3)
+/([abc])*d/
+ "abbbcd", 0, 0, (0, 6, 4, 5)
+/([abc])*bcd/
+ "abcd", 0, 0, (0, 4, 0, 1)
+/a|b|c|d|e/
+ "e", 0, 0, (0, 1)
+/(a|b|c|d|e)f/
+ "ef", 0, 0, (0, 2, 0, 1)
+/abcd*efg/
+ "abcdefg", 0, 0, (0, 7)
+/ab*/
+ "xabyabbbz", 0, 1, (1, 3)
+ "xayabbbz", 0, 1, (1, 2)
+/(ab|cd)e/
+ "abcde", 0, 2, (2, 5, 2, 4)
+/[abhgefdc]ij/
+ "hij", 0, 0, (0, 3)
+/(abc|)ef/
+ "abcdef", 0, 4, (4, 6, 4, 4)
+/(a|b)c*d/
+ "abcd", 0, 1, (1, 4, 1, 2)
+/(ab|ab*)bc/
+ "abc", 0, 0, (0, 3, 0, 1)
+/a([bc]*)c*/
+ "abc", 0, 0, (0, 3, 1, 3)
+/a([bc]*)(c*d)/
+ "abcd", 0, 0, (0, 4, 1, 3, 3, 4)
+/a([bc]+)(c*d)/
+ "abcd", 0, 0, (0, 4, 1, 3, 3, 4)
+/a([bc]*)(c+d)/
+ "abcd", 0, 0, (0, 4, 1, 2, 2, 4)
+/a[bcd]*dcdcde/
+ "adcdcde", 0, 0, (0, 7)
+/(ab|a)b*c/
+ "abc", 0, 0, (0, 3, 0, 2)
+/((a)(b)c)(d)/
+ "abcd", 0, 0, (0, 4, 0, 3, 0, 1, 1, 2, 3, 4)
+/[a-zA-Z_][a-zA-Z0-9_]*/
+ "alpha", 0, 0, (0, 5)
+/^a(bc+|b[eh])g|.h$/
+ "abh", 0, 1, (1, 3, -1, -1)
+/(bc+d$|ef*g.|h?i(j|k))/
+ "effgz", 0, 0, (0, 5, 0, 5, -1, -1)
+ "ij", 0, 0, (0, 2, 0, 2, 1, 2)
+ "reffgz", 0, 1, (1, 6, 1, 6, -1, -1)
+ "effg", 0, -1, (3, 10, -1, -1, -1, -1)
+ "bcdd", 0, -1, (3, 10, -1, -1, -1, -1)
+ "effg", 0, -1, (3, -1, -1, -1, -1, -1)
+ "bcdd", 0, -1, (3, -1, -1, -1, -1, -1)
+/((((((((((a))))))))))/
+ "a", 0, 0, (0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1)
+ "a!", 0, 0, (0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1)
+/((((((((((a))))))))))\\10/
+ "aa", 0, 0, (0, 2, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1)
+/(((((((((a)))))))))/
+ "a", 0, 0, (0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1)
+/(.*)c(.*)/
+ "abcde", 0, 0, (0, 5, 0, 2, 3, 5)
+/abcd/
+ "abcd", 0, 0, (0, 4)
+/a(bc)d/
+ "abcd", 0, 0, (0, 4, 1, 3)
+/a[-]?c/
+ "ac", 0, 0, (0, 2)
+/(abc)\\1/
+ "abcabc", 0, 0, (0, 6, 0, 3)
+/([a-c]*)\\1/
+ "abcabc", 0, 0, (0, 6, 0, 3)
+/(a)|\\1/
+ "a", 0, 0, (0, 1, 0, 1)
+ "x", 0, 0, (0, 0, -1, -1)
+ "ab", 0, 0, (0, 1, 0, 1)
+/(([a-c])b*?\\2)*/
+ "ababbbcbc", 0, 0, (0, 5, 3, 5, 3, 4)
+/(([a-c])b*?\\2){3}/
+ "ababbbcbc", 0, 0, (0, 9, 6, 9, 6, 7)
+/ab*c/i
+ "ABC", 0, 0, (0, 3)
+/ab*bc/i
+ "ABC", 0, 0, (0, 3)
+ "ABBC", 0, 0, (0, 4)
+/ab*?bc/i
+ "ABBBBC", 0, 0, (0, 6)
+/ab{0,}?bc/i
+ "ABBBBC", 0, 0, (0, 6)
+/ab+?bc/i
+ "ABBC", 0, 0, (0, 4)
+/ab+bc/i
+ "ABBBBC", 0, 0, (0, 6)
+ "ABC", 0, -1, (0, 10)
+ "ABQ", 0, -1, (0, 10)
+ "ABC", 0, -1, (0, -1)
+ "ABQ", 0, -1, (0, -1)
+/ab{1,}?bc/i
+ "ABBBBC", 0, 0, (0, 6)
+/ab{1,3}?bc/i
+ "ABBBBC", 0, 0, (0, 6)
+/ab{3,4}?bc/i
+ "ABBBBC", 0, 0, (0, 6)
+/ab??bc/i
+ "ABBC", 0, 0, (0, 4)
+ "ABC", 0, 0, (0, 3)
+ "ABBBBC", 0, -1, (4, 10)
+/ab{0,1}?bc/i
+ "ABC", 0, 0, (0, 3)
+/ab??c/i
+ "ABC", 0, 0, (0, 3)
+/ab{0,1}?c/i
+ "ABC", 0, 0, (0, 3)
+/^abc$/i
+ "ABC", 0, 0, (0, 3)
+ "ABCC", 0, -1, (-1, -1)
+ "AABC", 0, -1, (-1, -1)
+ "ABBBBC", 0, -1, (-1, -1)
+/^abc/i
+ "ABCC", 0, 0, (0, 3)
+/abc$/i
+ "AABC", 0, 1, (1, 4)
+/^/i
+ "ABC", 0, 0, (0, 0)
+/$/i
+ "ABC", 0, 3, (3, 3)
+/a.c/i
+ "ABC", 0, 0, (0, 3)
+ "AXC", 0, 0, (0, 3)
+/a.*?c/i
+ "AXYZC", 0, 0, (0, 5)
+ "ABCABC", 0, 0, (0, 3)
+/a[bc]d/i
+ "ABD", 0, 0, (0, 3)
+ "ABC", 0, -1, (-1, -1)
+/a[b-d]e/i
+ "ACE", 0, 0, (0, 3)
+ "ABD", 0, -1, (-1, -1)
+ "ABC", 0, -1, (-1, -1)
+/a[b-d]/i
+ "AAC", 0, 1, (1, 3)
+/a[-b]/i
+ "A-", 0, 0, (0, 2)
+/a[b-]/i
+ "A-", 0, 0, (0, 2)
+/a]/i
+ "A]", 0, 0, (0, 2)
+/a[^bc]d/i
+ "AED", 0, 0, (0, 3)
+ "ABD", 0, -1, (-1, -1)
+/a[^-b]c/i
+ "ADC", 0, 0, (0, 3)
+ "A-C", 0, -1, (-1, -1)
+ "ABD", 0, -1, (-1, -1)
+/ab|cd/i
+ "ABC", 0, 0, (0, 2)
+ "ABCD", 0, 0, (0, 2)
+/()ef/i
+ "DEF", 0, 1, (1, 3, 1, 1)
+/a\\(b/i
+ "A(B", 0, 0, (0, 3)
+/a\\(*b/i
+ "AB", 0, 0, (0, 2)
+ "A((B", 0, 0, (0, 4)
+/a\\\\b/i
+ "A\\B", 0, 0, (0, 3)
+ "AB", 0, -1, (-1, -1)
+/((a))/i
+ "ABC", 0, 0, (0, 1, 0, 1, 0, 1)
+/(a)b(c)/i
+ "ABC", 0, 0, (0, 3, 0, 1, 2, 3)
+/a+b+c/i
+ "AABBABC", 0, 4, (4, 7)
+/a{1,}b{1,}c/i
+ "AABBABC", 0, 4, (4, 7)
+/a.+?c/i
+ "ABCABC", 0, 0, (0, 3)
+/a.{0,5}?c/i
+ "ABCABC", 0, 0, (0, 3)
+/(a+|b)*/i
+ "AB", 0, 0, (0, 2, 1, 2)
+/(a+|b){0,}/i
+ "AB", 0, 0, (0, 2, 1, 2)
+/(a+|b)+/i
+ "AB", 0, 0, (0, 2, 1, 2)
+/(a+|b){1,}/i
+ "AB", 0, 0, (0, 2, 1, 2)
+/(a+|b)?/i
+ "AB", 0, 0, (0, 1, 0, 1)
+/(a+|b){0,1}/i
+ "AB", 0, 0, (0, 1, 0, 1)
+/(a+|b){0,1}?/i
+ "AB", 0, 0, (0, 0, -1, -1)
+/[^ab]*/i
+ "CDE", 0, 0, (0, 3)
+/([abc])*d/i
+ "ABBBCD", 0, 0, (0, 6, 4, 5)
+/([abc])*bcd/i
+ "ABCD", 0, 0, (0, 4, 0, 1)
+/a|b|c|d|e/i
+ "E", 0, 0, (0, 1)
+/(a|b|c|d|e)f/i
+ "EF", 0, 0, (0, 2, 0, 1)
+/abcd*efg/i
+ "ABCDEFG", 0, 0, (0, 7)
+/ab*/i
+ "XABYABBBZ", 0, 1, (1, 3)
+ "XAYABBBZ", 0, 1, (1, 2)
+/(ab|cd)e/i
+ "ABCDE", 0, 2, (2, 5, 2, 4)
+/[abhgefdc]ij/i
+ "HIJ", 0, 0, (0, 3)
+/(abc|)ef/i
+ "ABCDEF", 0, 4, (4, 6, 4, 4)
+/(a|b)c*d/i
+ "ABCD", 0, 1, (1, 4, 1, 2)
+/(ab|ab*)bc/i
+ "ABC", 0, 0, (0, 3, 0, 1)
+/a([bc]*)c*/i
+ "ABC", 0, 0, (0, 3, 1, 3)
+/a([bc]*)(c*d)/i
+ "ABCD", 0, 0, (0, 4, 1, 3, 3, 4)
+/a([bc]+)(c*d)/i
+ "ABCD", 0, 0, (0, 4, 1, 3, 3, 4)
+/a([bc]*)(c+d)/i
+ "ABCD", 0, 0, (0, 4, 1, 2, 2, 4)
+/a[bcd]*dcdcde/i
+ "ADCDCDE", 0, 0, (0, 7)
+/(ab|a)b*c/i
+ "ABC", 0, 0, (0, 3, 0, 2)
+/((a)(b)c)(d)/i
+ "ABCD", 0, 0, (0, 4, 0, 3, 0, 1, 1, 2, 3, 4)
+/[a-zA-Z_][a-zA-Z0-9_]*/i
+ "ALPHA", 0, 0, (0, 5)
+/^a(bc+|b[eh])g|.h$/i
+ "ABH", 0, 1, (1, 3, -1, -1)
+/(bc+d$|ef*g.|h?i(j|k))/i
+ "EFFGZ", 0, 0, (0, 5, 0, 5, -1, -1)
+ "IJ", 0, 0, (0, 2, 0, 2, 1, 2)
+ "REFFGZ", 0, 1, (1, 6, 1, 6, -1, -1)
+ "EFFG", 0, -1, (3, 10, -1, -1, -1, -1)
+ "BCDD", 0, -1, (3, 10, -1, -1, -1, -1)
+ "ADCDCDE", 0, -1, (6, -1, -1, -1, -1, -1)
+ "EFFG", 0, -1, (3, -1, -1, -1, -1, -1)
+ "BCDD", 0, -1, (3, -1, -1, -1, -1, -1)
+/((((((((((a))))))))))/i
+ "A", 0, 0, (0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1)
+ "A!", 0, 0, (0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1)
+/((((((((((a))))))))))\\10/i
+ "AA", 0, 0, (0, 2, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1)
+/(((((((((a)))))))))/i
+ "A", 0, 0, (0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1)
+/(?:(?:(?:(?:(?:(?:(?:(?:(?:(a))))))))))/i
+ "A", 0, 0, (0, 1, 0, 1)
+/(?:(?:(?:(?:(?:(?:(?:(?:(?:(a|b|c))))))))))/i
+ "C", 0, 0, (0, 1, 0, 1)
+/(.*)c(.*)/i
+ "ABCDE", 0, 0, (0, 5, 0, 2, 3, 5)
+/abcd/i
+ "ABCD", 0, 0, (0, 4)
+/a(bc)d/i
+ "ABCD", 0, 0, (0, 4, 1, 3)
+/a[-]?c/i
+ "AC", 0, 0, (0, 2)
+/(abc)\\1/i
+ "ABCABC", 0, 0, (0, 6, 0, 3)
+ "abcabc", 0, 0, (0, 6, 0, 3)
+ "ABCabc", 0, 0, (0, 6, 0, 3)
+ "abcABC", 0, 0, (0, 6, 0, 3)
+/([a-c]*)\\1/i
+ "ABCABC", 0, 0, (0, 6, 0, 3)
+/a(?!b)./
+ "abad", 0, 2, (2, 4)
+/a(?=d)./
+ "abad", 0, 2, (2, 4)
+/a(?=c|d)./
+ "abad", 0, 2, (2, 4)
+/a(?:b|c|d)(.)/
+ "ace", 0, 0, (0, 3, 2, 3)
+/a(?:b|c|d)*(.)/
+ "ace", 0, 0, (0, 3, 2, 3)
+/a(?:b|c|d)+?(.)/
+ "ace", 0, 0, (0, 3, 2, 3)
+ "acdbcdbe", 0, 0, (0, 3, 2, 3)
+/a(?:b|c|d)+(.)/
+ "acdbcdbe", 0, 0, (0, 8, 7, 8)
+/a(?:b|c|d){2}(.)/
+ "acdbcdbe", 0, 0, (0, 4, 3, 4)
+/a(?:b|c|d){4,5}(.)/
+ "acdbcdbe", 0, 0, (0, 7, 6, 7)
+/a(?:b|c|d){4,5}?(.)/
+ "acdbcdbe", 0, 0, (0, 6, 5, 6)
+/((foo)|(bar))*/
+ "foobar", 0, 0, (0, 6, 3, 6, -1, -1, 3, 6)
+/a(?:b|c|d){6,7}(.)/
+ "acdbcdbe", 0, 0, (0, 8, 7, 8)
+/a(?:b|c|d){6,7}?(.)/
+ "acdbcdbe", 0, 0, (0, 8, 7, 8)
+/a(?:b|c|d){5,6}(.)/
+ "acdbcdbe", 0, 0, (0, 8, 7, 8)
+/a(?:b|c|d){5,6}?(.)/
+ "acdbcdbe", 0, 0, (0, 7, 6, 7)
+/a(?:b|c|d){5,7}(.)/
+ "acdbcdbe", 0, 0, (0, 8, 7, 8)
+/a(?:b|c|d){5,7}?(.)/
+ "acdbcdbe", 0, 0, (0, 7, 6, 7)
+/a(?:b|(c|e){1,2}?|d)+?(.)/
+ "ace", 0, 0, (0, 3, 1, 2, 2, 3)
+/^(.+)?B/
+ "AB", 0, 0, (0, 2, 0, 1)
+/^([^a-z])|(\\^)$/
+ ".", 0, 0, (0, 1, 0, 1, -1, -1)
+/^[<>]&/
+ "<&OUT", 0, 0, (0, 2)
+/((a{4})+)/
+ "aaaaaaaaa", 0, 0, (0, 8, 0, 8, 4, 8)
+/(((aa){2})+)/
+ "aaaaaaaaaa", 0, 0, (0, 8, 0, 8, 4, 8, 6, 8)
+/(((a{2}){2})+)/
+ "aaaaaaaaaa", 0, 0, (0, 8, 0, 8, 4, 8, 6, 8)
+/(?:(f)(o)(o)|(b)(a)(r))*/
+ "foobar", 0, 0, (0, 6, -1, -1, -1, -1, -1, -1, 3, 4, 4, 5, 5, 6)
+/(?:..)*a/
+ "aba", 0, 0, (0, 3)
+/(?:..)*?a/
+ "aba", 0, 0, (0, 1)
+/^(?:b|a(?=(.)))*\\1/
+ "abc", 0, 0, (0, 2, -1, -1)
+/^(){3,5}/
+ "abc", 0, 0, (0, 0, 0, 0)
+/^(a+)*ax/
+ "aax", 0, 0, (0, 3, 0, 1)
+/^((a|b)+)*ax/
+ "aax", 0, 0, (0, 3, 0, 1, 0, 1)
+/^((a|bc)+)*ax/
+ "aax", 0, 0, (0, 3, 0, 1, 0, 1)
+/(a|x)*ab/
+ "cab", 0, 1, (1, 3, -1, -1)
+/(a)*ab/
+ "cab", 0, 1, (1, 3, -1, -1)
+/(?:c|d)(?:)(?:a(?:)(?:b)(?:b(?:))(?:b(?:)(?:b)))/
+ "cabbbb", 0, 0, (0, 6)
+/(?:c|d)(?:)(?:aaaaaaaa(?:)(?:bbbbbbbb)(?:bbbbbbbb(?:))(?:bbbbbbbb(?:)(?:bbbbbbbb)))/
+ "caaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", 0, 0, (0, 41)
+/(ab)\\d\\1/i
+ "Ab4ab", 0, 0, (0, 5, 0, 2)
+ "ab4Ab", 0, 0, (0, 5, 0, 2)
+/foo\\w*\\d{4}baz/
+ "foobar1234baz", 0, 0, (0, 13)
+/x(~~)*(?:(?:F)?)?/
+ "x~~", 0, 0, (0, 3, 1, 3)
+/(?=(a+?))(\\1ab)/
+ "aaab", 0, 1, (1, 4, 1, 2, 1, 4)
+/(\\w+:)+/
+ "one:", 0, 0, (0, 4, 0, 4)
+/([\\w:]+::)?(\\w+)$/
+ "abcd", 0, 0, (0, 4, -1, -1, 0, 4)
+ "xy:z:::abcd", 0, 0, (0, 11, 0, 7, 7, 11)
+ "abcd:", 0, -1, (6, 11, -1, -1, -1, -1)
+ "abcd:", 0, -1, (6, -1, -1, -1, -1, -1)
+/^[^bcd]*(c+)/
+ "aexycd", 0, 0, (0, 5, 4, 5)
+/(a*)b+/
+ "caab", 0, 1, (1, 4, 1, 3)
+/([[:]+)/
+ "a:[b]:", 0, 1, (1, 3, 1, 3)
+/([[=]+)/
+ "a=[b]=", 0, 1, (1, 3, 1, 3)
+/([[.]+)/
+ "a.[b].", 0, 1, (1, 3, 1, 3)
+/$/m
+ "a\nb\n", 0, 1, (1, 1)
+ "b\na\n", 0, 1, (1, 1)
+ "b\na", 0, 1, (1, 1)
+/a$/
+ "b\na", 0, 2, (2, 3)
+ "a\nb\n", 0, -1, (-1, -1)
+ "aaab", 0, -1, (-1, -1)
+/a$/m
+ "a\nb\n", 0, 0, (0, 1)
+ "b\na\n", 0, 2, (2, 3)
+ "b\na", 0, 2, (2, 3)
+/aa$/
+ "b\naa", 0, 2, (2, 4)
+ "aa\nb\n", 0, -1, (-1, -1)
+ "ac\nb\n", 0, -1, (-1, -1)
+ "b\nac\n", 0, -1, (-1, -1)
+ "b\nac", 0, -1, (-1, -1)
+ "ca\nb\n", 0, -1, (-1, -1)
+ "b\nca\n", 0, -1, (-1, -1)
+ "b\nca", 0, -1, (-1, -1)
+/aa$/m
+ "aa\nb\n", 0, 0, (0, 2)
+ "b\naa\n", 0, 2, (2, 4)
+ "b\naa", 0, 2, (2, 4)
+ "ac\nb\n", 0, -1, (-1, -1)
+ "b\nac\n", 0, -1, (-1, -1)
+ "b\nac", 0, -1, (-1, -1)
+ "ca\nb\n", 0, -1, (-1, -1)
+ "b\nca\n", 0, -1, (-1, -1)
+ "b\nca", 0, -1, (-1, -1)
+/ab$/
+ "b\nab", 0, 2, (2, 4)
+ "ab\nb\n", 0, -1, (-1, -1)
+ "ac\nb\n", 0, -1, (-1, -1)
+ "b\nac\n", 0, -1, (-1, -1)
+ "b\nac", 0, -1, (-1, -1)
+ "ca\nb\n", 0, -1, (-1, -1)
+ "b\nca\n", 0, -1, (-1, -1)
+ "b\nca", 0, -1, (-1, -1)
+/ab$/m
+ "ab\nb\n", 0, 0, (0, 2)
+ "b\nab\n", 0, 2, (2, 4)
+ "b\nab", 0, 2, (2, 4)
+ "ac\nb\n", 0, -1, (-1, -1)
+ "b\nac\n", 0, -1, (-1, -1)
+ "b\nac", 0, -1, (-1, -1)
+ "ca\nb\n", 0, -1, (-1, -1)
+ "b\nca\n", 0, -1, (-1, -1)
+ "b\nca", 0, -1, (-1, -1)
+/abb$/
+ "b\nabb", 0, 2, (2, 5)
+ "abb\nb\n", 0, -1, (-1, -1)
+ "ac\nb\n", 0, -1, (-1, -1)
+ "b\nac\n", 0, -1, (-1, -1)
+ "b\nac", 0, -1, (-1, -1)
+ "ca\nb\n", 0, -1, (-1, -1)
+ "b\nca\n", 0, -1, (-1, -1)
+ "b\nca", 0, -1, (-1, -1)
+/abb$/m
+ "abb\nb\n", 0, 0, (0, 3)
+ "b\nabb\n", 0, 2, (2, 5)
+ "b\nabb", 0, 2, (2, 5)
+ "ac\nb\n", 0, -1, (-1, -1)
+ "b\nac\n", 0, -1, (-1, -1)
+ "b\nac", 0, -1, (-1, -1)
+ "ca\nb\n", 0, -1, (-1, -1)
+ "b\nca\n", 0, -1, (-1, -1)
+ "b\nca", 0, -1, (-1, -1)
+/(^|x)(c)/
+ "ca", 0, 0, (0, 1, 0, 0, 0, 1)
+/foo.bart/
+ "foo.bart", 0, 0, (0, 8)
+/^d[x][x][x]/m
+ "abcd\ndxxx", 0, 5, (5, 9)
+/tt+$/
+ "xxxtt", 0, 3, (3, 5)
+/(\\d+\\.\\d+)/
+ "3.1415926", 0, 0, (0, 9, 0, 9)
+/\\.c(pp|xx|c)?$/i
+ "IO.c", 0, 2, (2, 4, -1, -1)
+ "Changes", 0, -1, (6, 11, -1, -1)
+/(\\.c(pp|xx|c)?$)/i
+ "IO.c", 0, 2, (2, 4, 2, 4, -1, -1)
+/(^|a)b/
+ "ab", 0, 0, (0, 2, 0, 1)
+/^([ab]*?)(b)?(c)$/
+ "abac", 0, 0, (0, 4, 0, 3, -1, -1, 3, 4)
+/^(?:.,){2}c/i
+ "a,b,c", 0, 0, (0, 5)
+/^(.,){2}c/i
+ "a,b,c", 0, 0, (0, 5, 2, 4)
+/^(?:[^,]*,){2}c/
+ "a,b,c", 0, 0, (0, 5)
+/^([^,]*,){2}c/
+ "a,b,c", 0, 0, (0, 5, 2, 4)
+/^([^,]*,){3}d/
+ "aaa,b,c,d", 0, 0, (0, 9, 6, 8)
+/^([^,]*,){3,}d/
+ "aaa,b,c,d", 0, 0, (0, 9, 6, 8)
+/^([^,]*,){0,3}d/
+ "aaa,b,c,d", 0, 0, (0, 9, 6, 8)
+/^([^,]{1,3},){3}d/i
+ "aaa,b,c,d", 0, 0, (0, 9, 6, 8)
+/^([^,]{1,3},){3,}d/
+ "aaa,b,c,d", 0, 0, (0, 9, 6, 8)
+/^([^,]{1,3},){0,3}d/
+ "aaa,b,c,d", 0, 0, (0, 9, 6, 8)
+/^([^,]{1,},){3}d/
+ "aaa,b,c,d", 0, 0, (0, 9, 6, 8)
+/^([^,]{1,},){3,}d/
+ "aaa,b,c,d", 0, 0, (0, 9, 6, 8)
+/^([^,]{1,},){0,3}d/
+ "aaa,b,c,d", 0, 0, (0, 9, 6, 8)
+/^([^,]{0,3},){3}d/i
+ "aaa,b,c,d", 0, 0, (0, 9, 6, 8)
+/^([^,]{0,3},){3,}d/
+ "aaa,b,c,d", 0, 0, (0, 9, 6, 8)
+/^([^,]{0,3},){0,3}d/
+ "aaa,b,c,d", 0, 0, (0, 9, 6, 8)
+/^(a(b)?)+$/
+ "aba", 0, 0, (0, 3, 2, 3, -1, -1)
+/^(aa(bb)?)+$/
+ "aabbaa", 0, 0, (0, 6, 4, 6, -1, -1)
+/^.{9}abc.*\\n/m
+ "123\nabcabcabcabc\n", 0, 4, (4, 17)
+/^(a)?a$/
+ "a", 0, 0, (0, 1, -1, -1)
+/^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$/
+ "aaaaaa", 0, 0, (0, 6, 0, 1, 1, 3, 3, 4, 4, 6)
+ "a", 0, -1, (-1, -1, -1, -1, -1, -1, -1, -1, -1, -1)
+ "aa", 0, -1, (-1, -1, -1, -1, -1, -1, -1, -1, -1, -1)
+ "aaa", 0, -1, (-1, -1, -1, -1, -1, -1, -1, -1, -1, -1)
+ "aaaa", 0, 0, (0, 4, 0, 1, 1, 2, 2, 3, 3, 4)
+ "aaaaa", 0, 0, (0, 5, 0, 1, 1, 3, 3, 4, 4, 5)
+ "aaaaaaa", 0, 0, (0, 7, 0, 1, 1, 3, 3, 6, 6, 7)
+ "aaaaaaaa", 0, -1, (-1, -1, -1, -1, -1, -1, -1, -1, -1, -1)
+ "aaaaaaaaa", 0, -1, (-1, -1, -1, -1, -1, -1, -1, -1, -1, -1)
+ "aaaaaaaaaa", 0, 0, (0, 10, 0, 1, 1, 3, 3, 6, 6, 10)
+ "aaaaaaaaaaa", 0, -1, (-1, -1, -1, -1, -1, -1, -1, -1, -1, -1)
+ "aaaaaaaaaaaa", 0, -1, (-1, -1, -1, -1, -1, -1, -1, -1, -1, -1)
+ "aaaaaaaaaaaaa", 0, -1, (-1, -1, -1, -1, -1, -1, -1, -1, -1, -1)
+ "aaaaaaaaaaaaaa", 0, -1, (-1, -1, -1, -1, -1, -1, -1, -1, -1, -1)
+ "aaaaaaaaaaaaaaa", 0, -1, (-1, -1, -1, -1, -1, -1, -1, -1, -1, -1)
+ "aaaaaaaaaaaaaaaa", 0, -1, (-1, -1, -1, -1, -1, -1, -1, -1, -1, -1)
+/^(0+)?(?:x(1))?/
+ "x1", 0, 0, (0, 2, -1, -1, 1, 2)
+/^([0-9a-fA-F]+)(?:x([0-9a-fA-F]+)?)(?:x([0-9a-fA-F]+))?/
+ "012cxx0190", 0, 0, (0, 10, 0, 4, -1, -1, 6, 10)
+/^(b+?|a){1,2}c/
+ "bbbac", 0, 0, (0, 5, 3, 4)
+ "bbbbac", 0, 0, (0, 6, 4, 5)
+/((?:aaaa|bbbb)cccc)?/
+ "aaaacccc", 0, 0, (0, 8, 0, 8)
+ "bbbbcccc", 0, 0, (0, 8, 0, 8)
+/ab{4,5}bc/
+ "abbbbc", 0, -1, (0, 9)
+ "abq", 0, -1, (0, -1)
+ "abbbbc", 0, -1, (0, -1)
+/a[^]b]c/
+ "a]c", 0, -1, (-1, -1)
+/\\by\\b/
+ "xy", 0, -1, (-1, -1)
+ "yz", 0, -1, (-1, -1)
+ "xyz", 0, -1, (-1, -1)
+/\\Ba\\B/
+ "a-", 0, -1, (-1, -1)
+ "-a", 0, -1, (-1, -1)
+ "-a-", 0, -1, (-1, -1)
+/a\\sb/
+ "a-b", 0, -1, (-1, -1)
+ "a b", 0, 0, (0, 3)
+/a[\\s]b/
+ "a-b", 0, -1, (-1, -1)
+ "a b", 0, 0, (0, 3)
+/$b/
+ "b", 0, -1, (-1, -1)
+/^(ab|cd)e/
+ "abcde", 0, -1, (0, 10, -1, -1)
+/a[bcd]+dcdcde/
+ "adcdcde", 0, -1, (0, 10)
+ "abcde", 0, -1, (0, -1)
+ "adcdcde", 0, -1, (0, -1)
+/[k]/
+ "ab", 0, -1, (-1, -1)
+/((\\3|b)\\2(a)x)+/
+ "aaxabxbaxbbx", 0, 1, (1, 3, 1, 3, 1, 1, 1, 2)
+ "aaaxabaxbaaxbbax", 0, 2, (2, 4, 2, 4, 2, 2, 2, 3)
+/ab{1,}bc/i
+ "ABQ", 0, -1, (0, 10)
+/ab{4,5}?bc/i
+ "ABBBBC", 0, -1, (0, 10)
+ "ABQ", 0, -1, (0, -1)
+ "ABBBBC", 0, -1, (0, -1)
+/a.*c/i
+ "AXYZD", 0, -1, (4, 10)
+ "AABC", 0, 0, (0, 4)
+ "AXYZD", 0, -1, (4, -1)
+/a[^]b]c/i
+ "A]C", 0, -1, (-1, -1)
+/$b/i
+ "B", 0, -1, (-1, -1)
+ "A]C", 0, -1, (-1, -1)
+/^(ab|cd)e/i
+ "ABCDE", 0, -1, (0, 10, -1, -1)
+ "ABCDE", 0, -1, (0, -1, -1, -1)
+/a[bcd]+dcdcde/i
+ "ADCDCDE", 0, -1, (0, 10)
+/[k]/i
+ "AB", 0, -1, (-1, -1)
+/^(a\\1?){4}$/
+ "aaaaaaaaa", 0, -1, (-1, -1, -1, -1)
+ "aaaaaaaaaaa", 0, -1, (-1, -1, -1, -1)
+ "a", 0, -1, (-1, -1, -1, -1)
+ "aa", 0, -1, (-1, -1, -1, -1)
+ "aaa", 0, -1, (-1, -1, -1, -1)
+ "aaaa", 0, 0, (0, 4, 3, 4)
+ "aaaaa", 0, -1, (-1, -1, -1, -1)
+ "aaaaaaa", 0, -1, (-1, -1, -1, -1)
+ "aaaaaaaa", 0, -1, (-1, -1, -1, -1)
+ "aaaaaaaaaa", 0, -1, (-1, -1, -1, -1)
+ "aaaaaaaaaaaa", 0, -1, (-1, -1, -1, -1)
+ "aaaaaaaaaaaaa", 0, -1, (-1, -1, -1, -1)
+ "aaaaaaaaaaaaaa", 0, -1, (-1, -1, -1, -1)
+ "aaaaaaaaaaaaaaa", 0, -1, (-1, -1, -1, -1)
+ "aaaaaaaaaaaaaaaa", 0, -1, (-1, -1, -1, -1)
+ "AB", 0, -1, (-1, -1, -1, -1)
+/^(?:a?b?)*$/
+ "a--", 0, -1, (-1, -1)
+ "", 0, 0, (0, 0)
+ "a", 0, 0, (0, 1)
+ "ab", 0, 0, (0, 2)
+ "aaa", 0, 0, (0, 3)
+ "dbcb", 0, -1, (-1, -1)
+ "aa--", 0, -1, (-1, -1)
+/^b/
+ "a\nb\nc\n", 0, -1, (-1, -1)
+/()^b/
+ "a\nb\nc\n", 0, -1, (7, 10, -1, -1)
+ "a\nb\nc\n", 0, -1, (7, -1, -1, -1)
+/^(?=(a+?))\\1ab/
+ "aaab", 0, -1, (-1, -1, 0, 1)
+/(>a+)ab/
+ "aaab", 0, -1, (1, 11, -1, -1)
+/a\\Z/
+ "a\nb\n", 0, -1, (-1, -1)
+/a\\z/
+ "a\nb\n", 0, -1, (-1, -1)
+ "b\na\n", 0, -1, (-1, -1)
+ "az", 0, 0, (0, 2)
+/a\\z/m
+ "a\nb\n", 0, -1, (-1, -1)
+ "b\na\n", 0, -1, (-1, -1)
+/aa\\Z/
+ "aa\nb\n", 0, -1, (-1, -1)
+ "ac\nb\n", 0, -1, (-1, -1)
+ "b\nac\n", 0, -1, (-1, -1)
+ "b\nac", 0, -1, (-1, -1)
+ "ca\nb\n", 0, -1, (-1, -1)
+ "b\nca\n", 0, -1, (-1, -1)
+ "b\nca", 0, -1, (-1, -1)
+/aa\\z/
+ "aa\nb\n", 0, -1, (-1, -1)
+ "b\naa\n", 0, -1, (-1, -1)
+ "ac\nb\n", 0, -1, (-1, -1)
+ "b\nac\n", 0, -1, (-1, -1)
+ "b\nac", 0, -1, (-1, -1)
+ "ca\nb\n", 0, -1, (-1, -1)
+ "b\nca\n", 0, -1, (-1, -1)
+ "b\nca", 0, -1, (-1, -1)
+/aa\\z/m
+ "aa\nb\n", 0, -1, (-1, -1)
+ "b\naa\n", 0, -1, (-1, -1)
+ "ac\nb\n", 0, -1, (-1, -1)
+ "b\nac\n", 0, -1, (-1, -1)
+ "b\nac", 0, -1, (-1, -1)
+ "ca\nb\n", 0, -1, (-1, -1)
+ "b\nca\n", 0, -1, (-1, -1)
+ "b\nca", 0, -1, (-1, -1)
+/aa\\Z/m
+ "ac\nb\n", 0, -1, (-1, -1)
+ "b\nac\n", 0, -1, (-1, -1)
+ "b\nac", 0, -1, (-1, -1)
+ "ca\nb\n", 0, -1, (-1, -1)
+ "b\nca\n", 0, -1, (-1, -1)
+ "b\nca", 0, -1, (-1, -1)
+/ab\\Z/
+ "ab\nb\n", 0, -1, (-1, -1)
+ "ac\nb\n", 0, -1, (-1, -1)
+ "b\nac\n", 0, -1, (-1, -1)
+ "b\nac", 0, -1, (-1, -1)
+ "ca\nb\n", 0, -1, (-1, -1)
+ "b\nca\n", 0, -1, (-1, -1)
+ "b\nca", 0, -1, (-1, -1)
+/ab\\z/
+ "ab\nb\n", 0, -1, (-1, -1)
+ "b\nab\n", 0, -1, (-1, -1)
+ "ac\nb\n", 0, -1, (-1, -1)
+ "b\nac\n", 0, -1, (-1, -1)
+ "b\nac", 0, -1, (-1, -1)
+ "ca\nb\n", 0, -1, (-1, -1)
+ "b\nca\n", 0, -1, (-1, -1)
+ "b\nca", 0, -1, (-1, -1)
+/ab\\z/m
+ "ab\nb\n", 0, -1, (-1, -1)
+ "b\nab\n", 0, -1, (-1, -1)
+ "ac\nb\n", 0, -1, (-1, -1)
+ "b\nac\n", 0, -1, (-1, -1)
+ "b\nac", 0, -1, (-1, -1)
+ "ca\nb\n", 0, -1, (-1, -1)
+ "b\nca\n", 0, -1, (-1, -1)
+ "b\nca", 0, -1, (-1, -1)
+/ab\\Z/m
+ "ac\nb\n", 0, -1, (-1, -1)
+ "b\nac\n", 0, -1, (-1, -1)
+ "b\nac", 0, -1, (-1, -1)
+ "ca\nb\n", 0, -1, (-1, -1)
+ "b\nca\n", 0, -1, (-1, -1)
+ "b\nca", 0, -1, (-1, -1)
+/abb\\Z/
+ "abb\nb\n", 0, -1, (-1, -1)
+ "ac\nb\n", 0, -1, (-1, -1)
+ "b\nac\n", 0, -1, (-1, -1)
+ "b\nac", 0, -1, (-1, -1)
+ "ca\nb\n", 0, -1, (-1, -1)
+ "b\nca\n", 0, -1, (-1, -1)
+ "b\nca", 0, -1, (-1, -1)
+/abb\\z/
+ "abb\nb\n", 0, -1, (-1, -1)
+ "b\nabb\n", 0, -1, (-1, -1)
+ "ac\nb\n", 0, -1, (-1, -1)
+ "b\nac\n", 0, -1, (-1, -1)
+ "b\nac", 0, -1, (-1, -1)
+ "ca\nb\n", 0, -1, (-1, -1)
+ "b\nca\n", 0, -1, (-1, -1)
+ "b\nca", 0, -1, (-1, -1)
+/abb\\z/m
+ "abb\nb\n", 0, -1, (-1, -1)
+ "b\nabb\n", 0, -1, (-1, -1)
+ "ac\nb\n", 0, -1, (-1, -1)
+ "b\nac\n", 0, -1, (-1, -1)
+ "b\nac", 0, -1, (-1, -1)
+ "ca\nb\n", 0, -1, (-1, -1)
+ "b\nca\n", 0, -1, (-1, -1)
+ "b\nca", 0, -1, (-1, -1)
+/abb\\Z/m
+ "ac\nb\n", 0, -1, (-1, -1)
+ "b\nac\n", 0, -1, (-1, -1)
+ "b\nac", 0, -1, (-1, -1)
+ "ca\nb\n", 0, -1, (-1, -1)
+ "b\nca\n", 0, -1, (-1, -1)
+ "b\nca", 0, -1, (-1, -1)
index e27b7cd..e2eae08 100644 (file)
@@ -1,3 +1,25 @@
+2011-09-02  Michael Saboff  <msaboff@apple.com>
+
+        Add JSC:RegExp functional tests
+        https://bugs.webkit.org/show_bug.cgi?id=67339
+
+        New perl script to build JavaScriptCore and run the RegExp tests.
+
+        Reviewed by Gavin Barraclough.
+
+        * Scripts/run-regexp-tests: Added.
+
+2011-09-02  Michael Saboff  <msaboff@apple.com>
+
+        Add JSC:RegExp functional tests
+        https://bugs.webkit.org/show_bug.cgi?id=67339
+
+        New perl script to build JavaScriptCore and run the RegExp tests.
+
+        Reviewed by Gavin Barraclough.
+
+        * Scripts/run-regexp-tests: Added.
+
 2011-09-02  Eric Seidel  <eric@webkit.org>
 
         Reshuffle some code in WebKitDriver._read_block in preparation for reading stderr/stdout separately
diff --git a/Tools/Scripts/run-regexp-tests b/Tools/Scripts/run-regexp-tests
new file mode 100755 (executable)
index 0000000..dc35ce9
--- /dev/null
@@ -0,0 +1,126 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2011 Apple Computer, Inc.  All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer. 
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution. 
+# 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+#     its contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Script to run the WebKit Open Source Project Regular Expression functional tests.
+
+use strict;
+use FindBin;
+use Getopt::Long qw(:config pass_through);
+use lib $FindBin::Bin;
+use webkitdirs;
+use POSIX;
+
+# determine configuration
+setConfiguration();
+my $configuration = configuration();
+
+my $defaultTestFile = "RegExpTest.data";
+
+# These variables are intentionally left undefined.
+my $root;
+my $testFile;
+my $showHelp;
+my $verbose;
+
+my $buildJSC = 1;
+
+my $programName = basename($0);
+my $buildJSCDefault = $buildJSC ? "will check" : "will not check";
+my $usage = <<EOF;
+Usage: $programName [options] [options to pass to build system]
+  --help                        Show this help message
+  --file=                       File to use instead of default ($defaultTestFile)
+  --root=                       Path to pre-built root containing jsc
+  --[no-]build                  Check (or don't check) to see if the jsc build is up-to-date (default: $buildJSCDefault)
+  --verbose                     Increase test output on failures
+EOF
+
+GetOptions(
+    'verbose' => \$verbose,
+    'root=s' => \$root,
+    'file=s' => \$testFile,
+    'build!' => \$buildJSC,
+    'help' => \$showHelp
+);
+
+# Assume any arguments left over from GetOptions are assumed to be build arguments
+my @buildArgs = @ARGV;
+
+
+if ($showHelp) {
+   print STDERR $usage;
+   exit 1;
+}
+
+setConfigurationProductDir(Cwd::abs_path($root)) if (defined($root));
+
+if (!defined($root) && $buildJSC) {
+    chdirWebKit();
+
+    push(@buildArgs, argumentsForConfiguration());
+    
+    print "Running: build-jsc " . join(" ", @buildArgs) . "\n";
+    my $buildResult = system "perl", "Tools/Scripts/build-jsc", @buildArgs;
+    if ($buildResult) {
+        print STDERR "Compiling jsc failed!\n";
+        exit exitStatus($buildResult);
+    }
+}
+
+my $productDir = jscProductDir();
+$ENV{DYLD_FRAMEWORK_PATH} = $productDir;
+setPathForRunningWebKitApp(\%ENV) if isCygwin();
+
+sub testapiPath($)
+{
+    my ($productDir) = @_;
+    my $jscName = "testapi";
+    $jscName .= "_debug" if configurationForVisualStudio() eq "Debug_All";
+    return "$productDir/$jscName";
+}
+
+# Find JavaScriptCore directory
+if (!defined($testFile)) {
+    $testFile = $defaultTestFile;
+    chdirWebKit();
+    chdir("Source/JavaScriptCore");
+    chdir "tests/regexp" or die;
+}
+
+my $command = $productDir . "/testRegExp";
+
+if (defined($verbose) && $verbose) {
+    $command .= " --verbose";
+}
+
+$command .= " " . $testFile;
+
+printf "Running: " . $command . "\n";
+my $result = system $command;
+exit exitStatus($result)  if $result;
+