2 * Copyright (C) 1999-2001, 2004 Harri Porten (porten@kde.org)
3 * Copyright (c) 2007, 2008 Apple Inc. All rights reserved.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
26 #include <pcre/pcre.h>
30 #include <wrec/WREC.h>
31 #include <wtf/Assertions.h>
32 #include <wtf/OwnArrayPtr.h>
36 inline RegExp::RegExp(JSGlobalData* globalData, const UString& pattern)
40 , m_constructionError(0)
44 m_wrecFunction = CTI::compileRegExp(globalData->machine, pattern, &m_numSubpatterns, &m_constructionError);
47 // Fall through to non-WREC case.
49 UNUSED_PARAM(globalData);
51 m_regExp = jsRegExpCompile(reinterpret_cast<const UChar*>(pattern.data()), pattern.size(),
52 JSRegExpDoNotIgnoreCase, JSRegExpSingleLine, &m_numSubpatterns, &m_constructionError);
55 PassRefPtr<RegExp> RegExp::create(JSGlobalData* globalData, const UString& pattern)
57 return adoptRef(new RegExp(globalData, pattern));
60 inline RegExp::RegExp(JSGlobalData* globalData, const UString& pattern, const UString& flags)
65 , m_constructionError(0)
68 // NOTE: The global flag is handled on a case-by-case basis by functions like
69 // String::match and RegExpObject::match.
70 if (flags.find('g') != -1)
73 // FIXME: Eliminate duplication by adding a way ask a JSRegExp what its flags are?
74 JSRegExpIgnoreCaseOption ignoreCaseOption = JSRegExpDoNotIgnoreCase;
75 if (flags.find('i') != -1) {
76 m_flagBits |= IgnoreCase;
77 ignoreCaseOption = JSRegExpIgnoreCase;
80 JSRegExpMultilineOption multilineOption = JSRegExpSingleLine;
81 if (flags.find('m') != -1) {
82 m_flagBits |= Multiline;
83 multilineOption = JSRegExpMultiline;
87 m_wrecFunction = CTI::compileRegExp(globalData->machine, pattern, &m_numSubpatterns, &m_constructionError, (m_flagBits & IgnoreCase), (m_flagBits & Multiline));
90 // Fall through to non-WREC case.
92 UNUSED_PARAM(globalData);
94 m_regExp = jsRegExpCompile(reinterpret_cast<const UChar*>(pattern.data()), pattern.size(),
95 ignoreCaseOption, multilineOption, &m_numSubpatterns, &m_constructionError);
98 PassRefPtr<RegExp> RegExp::create(JSGlobalData* globalData, const UString& pattern, const UString& flags)
100 return adoptRef(new RegExp(globalData, pattern, flags));
105 jsRegExpFree(m_regExp);
108 WTF::fastFreeExecutable(m_wrecFunction);
112 int RegExp::match(const UString& s, int i, OwnArrayPtr<int>* ovector)
119 if (i > s.size() || s.isNull())
123 if (m_wrecFunction) {
124 int offsetVectorSize = (m_numSubpatterns + 1) * 2;
125 int* offsetVector = new int [offsetVectorSize];
126 for (int j = 0; j < offsetVectorSize; ++j)
127 offsetVector[j] = -1;
129 OwnArrayPtr<int> nonReturnedOvector;
131 nonReturnedOvector.set(offsetVector);
133 ovector->set(offsetVector);
135 int result = reinterpret_cast<WRECFunction>(m_wrecFunction)(s.data(), i, s.size(), offsetVector);
139 // TODO: define up a symbol, rather than magic -1
141 fprintf(stderr, "jsRegExpExecute failed with result %d\n", result);
150 // Set up the offset vector for the result.
151 // First 2/3 used for result, the last third used by PCRE.
153 int offsetVectorSize;
154 int fixedSizeOffsetVector[3];
156 offsetVectorSize = 3;
157 offsetVector = fixedSizeOffsetVector;
159 offsetVectorSize = (m_numSubpatterns + 1) * 3;
160 offsetVector = new int [offsetVectorSize];
161 ovector->set(offsetVector);
164 int numMatches = jsRegExpExecute(m_regExp, reinterpret_cast<const UChar*>(s.data()), s.size(), i, offsetVector, offsetVectorSize);
166 if (numMatches < 0) {
168 if (numMatches != JSRegExpErrorNoMatch)
169 fprintf(stderr, "jsRegExpExecute failed with result %d\n", numMatches);
176 return offsetVector[0];