From e3358f4f18f81178aee0b92315df337094a8ec86 Mon Sep 17 00:00:00 2001 From: "msaboff@apple.com" Date: Sat, 3 Sep 2011 00:41:32 +0000 Subject: [PATCH] Add JSC:RegExp functional tests 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 | 34 + Source/JavaScriptCore/JavaScriptCore.exp | 1 + .../JavaScriptCore.xcodeproj/project.pbxproj | 136 +++ Source/JavaScriptCore/testRegExp.cpp | 506 ++++++++++ Source/JavaScriptCore/tests/regexp/RegExpTest.data | 1040 ++++++++++++++++++++ Tools/ChangeLog | 22 + Tools/Scripts/run-regexp-tests | 126 +++ 7 files changed, 1865 insertions(+) create mode 100644 Source/JavaScriptCore/testRegExp.cpp create mode 100644 Source/JavaScriptCore/tests/regexp/RegExpTest.data create mode 100755 Tools/Scripts/run-regexp-tests diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog index e461023..f709680 100644 --- a/Source/JavaScriptCore/ChangeLog +++ b/Source/JavaScriptCore/ChangeLog @@ -1,5 +1,39 @@ 2011-09-02 Michael Saboff + 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 + Add JSC:RegExp functional test data generator https://bugs.webkit.org/show_bug.cgi?id=67519 diff --git a/Source/JavaScriptCore/JavaScriptCore.exp b/Source/JavaScriptCore/JavaScriptCore.exp index 9b3c174..c50a5ad 100644 --- a/Source/JavaScriptCore/JavaScriptCore.exp +++ b/Source/JavaScriptCore/JavaScriptCore.exp @@ -268,6 +268,7 @@ __ZN3JSC6JSLock4lockENS_14JSLockBehaviorE __ZN3JSC6JSLock6unlockENS_14JSLockBehaviorE __ZN3JSC6JSLock9lockCountEv __ZN3JSC6JSLockC1EPNS_9ExecStateE +__ZN3JSC6RegExp5matchERNS_12JSGlobalDataERKNS_7UStringEiPN3WTF6VectorIiLm32EEE __ZN3JSC6RegExp6createERNS_12JSGlobalDataERKNS_7UStringENS_11RegExpFlagsE __ZN3JSC6RegExpD1Ev __ZN3JSC7JSArray13visitChildrenERNS_11SlotVisitorE diff --git a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj index 099244c..43d8bf4 100644 --- a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj +++ b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj @@ -27,6 +27,7 @@ 141214BF0A49190E00480255 /* PBXTargetDependency */, 932F5BE90822A1C700736975 /* PBXTargetDependency */, 14BD59C70A3E8FA400BAF59C /* PBXTargetDependency */, + 651123091404768B002B101D /* PBXTargetDependency */, ); name = All; productName = All; @@ -227,6 +228,9 @@ 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 */; }; @@ -676,6 +680,20 @@ 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 */; @@ -904,6 +922,10 @@ 5DBD18AF0C5401A700C15EAE /* MallocZoneSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MallocZoneSupport.h; sourceTree = ""; }; 5DE3D0F40DD8DDFB00468714 /* WebKitAvailability.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebKitAvailability.h; sourceTree = ""; }; 6507D2970E871E4A00D7D896 /* JSTypeInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSTypeInfo.h; sourceTree = ""; }; + 651122E5140469BA002B101D /* testRegExp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = testRegExp.cpp; sourceTree = ""; }; + 651122EE14046A19002B101D /* main.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 651122F014046A19002B101D /* regexp_test.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = regexp_test.1; sourceTree = ""; }; + 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 = ""; }; 651F6412039D5B5F0078395C /* dtoa.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dtoa.cpp; sourceTree = ""; tabWidth = 8; }; 651F6413039D5B5F0078395C /* dtoa.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = dtoa.h; sourceTree = ""; tabWidth = 8; }; @@ -1397,6 +1419,15 @@ ); 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; @@ -1427,6 +1458,7 @@ 932F5BE10822A1C700736975 /* jsc */, 141211200A48793C00480255 /* minidom */, 14BD59BF0A3E8F9000BAF59C /* testapi */, + 6511230514046A4C002B101D /* testRegExp */, ); name = Products; sourceTree = ""; @@ -1444,6 +1476,7 @@ 0867D691FE84028FC02AAC07 /* JavaScriptCore */ = { isa = PBXGroup; children = ( + 651122E5140469BA002B101D /* testRegExp.cpp */, A718F8211178EB4B002465A7 /* create_regex_tables */, 937B63CC09E766D200A671DD /* DerivedSources.make */, A7C225CC139981F100FF1662 /* KeywordLookupGenerator.py */, @@ -1471,6 +1504,7 @@ 86EAC48C0F93E8B9008EC948 /* yarr */, 1C90513E0BA9E8830081E9D0 /* Configurations */, 650FDF8D09D0FCA700769E54 /* Derived Sources */, + 651122ED14046A19002B101D /* regexp_test */, 0867D69AFE84028FC02AAC07 /* Frameworks */, 034768DFFF38A50411DB9C8B /* Products */, 932FC3C20824BB70005B3C75 /* Resources */, @@ -1705,6 +1739,15 @@ tabWidth = 4; usesTabs = 0; }; + 651122ED14046A19002B101D /* regexp_test */ = { + isa = PBXGroup; + children = ( + 651122EE14046A19002B101D /* main.cpp */, + 651122F014046A19002B101D /* regexp_test.1 */, + ); + path = regexp_test; + sourceTree = ""; + }; 65162EF108E6A21C007556CD /* wtf */ = { isa = PBXGroup; children = ( @@ -2733,6 +2776,25 @@ 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" */; @@ -2805,6 +2867,7 @@ 1412111F0A48793C00480255 /* minidom */, 14BD59BE0A3E8F9000BAF59C /* testapi */, 932F5BDA0822A1C700736975 /* jsc */, + 651122F714046A4C002B101D /* testRegExp */, ); }; /* End PBXProject section */ @@ -2872,6 +2935,21 @@ 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; @@ -2939,6 +3017,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 651122FA14046A4C002B101D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6511230714046B0A002B101D /* testRegExp.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 932F5B910822A1C700736975 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -3185,6 +3271,16 @@ 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 */; @@ -3341,6 +3437,35 @@ }; 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 = { @@ -3483,6 +3608,17 @@ 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 index 0000000..06c36cd --- /dev/null +++ b/Source/JavaScriptCore/testRegExp.cpp @@ -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 +#include +#include +#include + +#if !OS(WINDOWS) +#include +#endif + +#if HAVE(SYS_TIME_H) +#include +#endif + +#if COMPILER(MSVC) && !OS(WINCE) +#include +#include +#include +#endif + +#if PLATFORM(QT) +#include +#include +#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 arguments; + Vector 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((m_stopTime - m_startTime) * 1000); +} + +struct RegExpTest { + RegExpTest() + : offset(0) + , result(0) + { + } + + UString subject; + int offset; + int result; + Vector expectVector; +}; + +class GlobalObject : public JSGlobalObject { +private: + GlobalObject(JSGlobalData&, Structure*, const Vector& arguments); + +public: + typedef JSGlobalObject Base; + + static GlobalObject* create(JSGlobalData& globalData, Structure* structure, const Vector& arguments) + { + return new (allocateCell(globalData.heap)) GlobalObject(globalData, structure, arguments); + } + virtual UString className() const { return "global"; } +}; + +COMPILE_ASSERT(!IsInteger::value, WTF_IsInteger_GlobalObject_false); +ASSERT_CLASS_FITS_IN_CELL(GlobalObject); + +GlobalObject::GlobalObject(JSGlobalData& globalData, Structure* structure, const Vector& 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 . + ::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 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(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& files, bool verbose) +{ + UString script; + UString fileName; + Vector 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 index 0000000..3a77e0b --- /dev/null +++ b/Source/JavaScriptCore/tests/regexp/RegExpTest.data @@ -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) diff --git a/Tools/ChangeLog b/Tools/ChangeLog index e27b7cd..e2eae08 100644 --- a/Tools/ChangeLog +++ b/Tools/ChangeLog @@ -1,3 +1,25 @@ +2011-09-02 Michael Saboff + + 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 + + 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 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 index 0000000..dc35ce9 --- /dev/null +++ b/Tools/Scripts/run-regexp-tests @@ -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 = < \$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; + -- 1.8.3.1