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 "WRECGenerator.h"
27 #include <pcre/pcre.h>
31 #include <wtf/Assertions.h>
32 #include <wtf/OwnArrayPtr.h>
40 inline RegExp::RegExp(JSGlobalData
* globalData
, const UString
& pattern
)
44 , m_constructionError(0)
48 m_wrecFunction
= Generator::compileRegExp(globalData
, pattern
, &m_numSubpatterns
, &m_constructionError
, m_executablePool
);
49 if (m_wrecFunction
|| m_constructionError
)
51 // Fall through to non-WREC case.
53 UNUSED_PARAM(globalData
);
55 m_regExp
= jsRegExpCompile(reinterpret_cast<const UChar
*>(pattern
.data()), pattern
.size(),
56 JSRegExpDoNotIgnoreCase
, JSRegExpSingleLine
, &m_numSubpatterns
, &m_constructionError
);
59 PassRefPtr
<RegExp
> RegExp::create(JSGlobalData
* globalData
, const UString
& pattern
)
61 return adoptRef(new RegExp(globalData
, pattern
));
64 inline RegExp::RegExp(JSGlobalData
* globalData
, const UString
& pattern
, const UString
& flags
)
69 , m_constructionError(0)
72 // NOTE: The global flag is handled on a case-by-case basis by functions like
73 // String::match and RegExpObject::match.
74 if (flags
.find('g') != -1)
77 // FIXME: Eliminate duplication by adding a way ask a JSRegExp what its flags are?
78 JSRegExpIgnoreCaseOption ignoreCaseOption
= JSRegExpDoNotIgnoreCase
;
79 if (flags
.find('i') != -1) {
80 m_flagBits
|= IgnoreCase
;
81 ignoreCaseOption
= JSRegExpIgnoreCase
;
84 JSRegExpMultilineOption multilineOption
= JSRegExpSingleLine
;
85 if (flags
.find('m') != -1) {
86 m_flagBits
|= Multiline
;
87 multilineOption
= JSRegExpMultiline
;
91 m_wrecFunction
= Generator::compileRegExp(globalData
, pattern
, &m_numSubpatterns
, &m_constructionError
, m_executablePool
, (m_flagBits
& IgnoreCase
), (m_flagBits
& Multiline
));
92 if (m_wrecFunction
|| m_constructionError
)
94 // Fall through to non-WREC case.
96 UNUSED_PARAM(globalData
);
98 m_regExp
= jsRegExpCompile(reinterpret_cast<const UChar
*>(pattern
.data()), pattern
.size(),
99 ignoreCaseOption
, multilineOption
, &m_numSubpatterns
, &m_constructionError
);
102 PassRefPtr
<RegExp
> RegExp::create(JSGlobalData
* globalData
, const UString
& pattern
, const UString
& flags
)
104 return adoptRef(new RegExp(globalData
, pattern
, flags
));
109 jsRegExpFree(m_regExp
);
112 int RegExp::match(const UString
& s
, int startOffset
, OwnArrayPtr
<int>* ovector
)
119 if (startOffset
> 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
= m_wrecFunction(s
.data(), startOffset
, 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(), startOffset
, offsetVector
, offsetVectorSize
);
166 if (numMatches
< 0) {
168 if (numMatches
!= JSRegExpErrorNoMatch
)
169 fprintf(stderr
, "jsRegExpExecute failed with result %d\n", numMatches
);
176 return offsetVector
[0];