28 #include "interpreter.h"
29 #include "operations.h"
32 #include "regexp_object.h"
33 #include "error_object.h"
42 const ClassInfo RegExpPrototypeImp::info = {
"RegExp", 0, 0, 0};
44 RegExpPrototypeImp::RegExpPrototypeImp(
ExecState *exec,
45 ObjectPrototypeImp *objProto,
50 setInternalValue(
String(
""));
54 static const Identifier execPropertyName(
"exec");
55 putDirect(execPropertyName,
56 new RegExpProtoFuncImp(exec,funcProto,RegExpProtoFuncImp::Exec, 0, execPropertyName), DontEnum);
57 static const Identifier testPropertyName(
"test");
58 putDirect(testPropertyName,
59 new RegExpProtoFuncImp(exec,funcProto,RegExpProtoFuncImp::Test, 0, testPropertyName), DontEnum);
60 putDirect(toStringPropertyName,
61 new RegExpProtoFuncImp(exec,funcProto,RegExpProtoFuncImp::ToString, 0, toStringPropertyName), DontEnum);
62 static const Identifier compilePropertyName(
"compile");
63 putDirect(compilePropertyName,
64 new RegExpProtoFuncImp(exec,funcProto,RegExpProtoFuncImp::Compile, 1, compilePropertyName), DontEnum);
74 putDirect(lengthPropertyName, len, DontDelete|ReadOnly|DontEnum);
78 bool RegExpProtoFuncImp::implementsCall()
const
85 if (!thisObj.inherits(&RegExpImp::info)) {
86 if (thisObj.inherits(&RegExpPrototypeImp::info)) {
88 case ToString:
return String(
"//");
92 exec->setException(err);
96 RegExpImp *reimp =
static_cast<RegExpImp*
>(thisObj.imp());
97 RegExp *re = reimp->regExp();
104 s = args[0].toString(exec);
105 int length = s.value().
size();
108 Value lastIndex = thisObj.
get(exec,
"lastIndex");
110 bool globalFlag = thisObj.
get(exec,
"global").
toBoolean(exec);
113 if (i < 0 || i > length) {
114 thisObj.
put(exec,
"lastIndex",
Number(0), DontDelete | DontEnum);
121 int **ovector = regExpObj->registerRegexp( re, s.value() );
123 re->prepareMatch(s.value());
124 str = re->match(s.value(), i, 0L, ovector);
126 regExpObj->setSubPatterns(re->subPatterns());
134 thisObj.
put(exec,
"lastIndex",
Number(0), DontDelete | DontEnum);
140 thisObj.
put(exec,
"lastIndex",
Number( (*ovector)[1] ), DontDelete | DontEnum);
141 return regExpObj->arrayOfMatches(exec,str);
161 RegExp* newEngine = RegExpObjectImp::makeEngine(exec, args[0].toString(exec), args[1]);
163 return exec->exception();
164 reimp->setRegExp(newEngine);
175 const ClassInfo RegExpImp::info = {
"RegExp", 0, 0, 0};
177 RegExpImp::RegExpImp(RegExpPrototypeImp *regexpProto)
178 : ObjectImp(regexpProto), reg(0L)
182 RegExpImp::~RegExpImp()
187 void RegExpImp::setRegExp(RegExp *r)
193 putDirect(
"global", (r->flags() & RegExp::Global) ? BooleanImp::staticTrue : BooleanImp::staticFalse,
194 DontDelete | ReadOnly | DontEnum);
195 putDirect(
"ignoreCase", (r->flags() & RegExp::IgnoreCase) ? BooleanImp::staticTrue : BooleanImp::staticFalse,
196 DontDelete | ReadOnly | DontEnum);
197 putDirect(
"multiline", (r->flags() & RegExp::Multiline) ? BooleanImp::staticTrue : BooleanImp::staticFalse,
198 DontDelete | ReadOnly | DontEnum);
200 putDirect(
"source",
new StringImp(r->pattern()), DontDelete | ReadOnly | DontEnum);
201 putDirect(
"lastIndex", NumberImp::zero(), DontDelete | DontEnum);
206 RegExpObjectImp::RegExpObjectImp(
ExecState * ,
208 RegExpPrototypeImp *regProto)
214 putDirect(prototypePropertyName, regProto, DontEnum|DontDelete|ReadOnly);
217 putDirect(lengthPropertyName, NumberImp::two(), ReadOnly|DontDelete|DontEnum);
220 RegExpObjectImp::~RegExpObjectImp()
222 delete [] lastOvector;
225 int **RegExpObjectImp::registerRegexp(
const RegExp* re,
const UString& s )
228 delete [] lastOvector;
230 lastNrSubPatterns = re->subPatterns();
240 for (
unsigned int i = 1 ; i < lastNrSubPatterns + 1 ; ++i )
242 UString substring = lastString.
substr( lastOvector[2*i], lastOvector[2*i+1] - lastOvector[2*i] );
246 arr.
put(exec,
"index",
Number(lastOvector[0]));
247 arr.
put(exec,
"input",
String(lastString));
254 if (s[0] ==
'$' && lastOvector)
260 if (i < lastNrSubPatterns + 1)
262 UString substring = lastString.
substr( lastOvector[2*i], lastOvector[2*i+1] - lastOvector[2*i] );
268 return InternalFunctionImp::get(exec, p);
274 if (s[0] ==
'$' && lastOvector) {
281 return InternalFunctionImp::hasProperty(exec, p);
284 bool RegExpObjectImp::implementsConstruct()
const
291 UString flags = flagsInput.
type() == UndefinedType ?
UString(
"") : flagsInput.toString(exec);
294 for (
int pos = 0; pos < flags.
size(); ++pos) {
295 switch (flags[pos].unicode()) {
302 "Invalid regular expression flags");
303 exec->setException(err);
309 bool global = (flags.
find(
"g") >= 0);
310 bool ignoreCase = (flags.
find(
"i") >= 0);
311 bool multiline = (flags.
find(
"m") >= 0);
313 int reflags = RegExp::None;
315 reflags |= RegExp::Global;
317 reflags |= RegExp::IgnoreCase;
319 reflags |= RegExp::Multiline;
321 RegExp *re =
new RegExp(p, reflags);
322 if (!re->isValid()) {
324 "Invalid regular expression");
325 exec->setException(err);
340 if (a0.
isA(ObjectType) && a0.
toObject(exec).inherits(&RegExpImp::info)) {
342 if (args.
size() > 1 && args[1].type() != UndefinedType) {
344 exec->setException(err);
348 p = rimp->regExp()->pattern();
354 RegExp* re = makeEngine(exec, p, args[1]);
356 return exec->exception().
toObject(exec);
359 RegExpImp *dat =
new RegExpImp(proto);
366 bool RegExpObjectImp::implementsCall()
const
377 return construct(exec, args);