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);
Value objects are act as wrappers ("smart pointers") around ValueImp objects and their descendents...
UString toString(ExecState *exec) const
Performs the ToString type conversion operation on this value (ECMA 9.8)
Base class for all function objects.
Object toObject(ExecState *exec) const
Performs the ToObject type conversion operation on this value (ECMA 9.9)
UString substr(int pos=0, int len=-1) const
Object construct(ExecState *exec, const List &args)
Creates a new object based on this object.
Represents an primitive Number value.
Object builtinRegExp() const
Returns the builtin "RegExp" object.
void append(const Value &val)
Append an object to the end of the list.
bool toBoolean(ExecState *exec) const
Performs the ToBoolean type conversion operation on this value (ECMA 9.2)
int find(const UString &f, int pos=0) const
Value get(ExecState *exec, const Identifier &propertyName) const
Retrieves the specified property from the object.
Type type() const
Returns the type of value.
Interpreter * lexicalInterpreter() const
Returns the interpreter associated with the current scope's global object.
Represents an primitive Null value.
static Object create(ExecState *exec, ErrorType errtype=GeneralError, const char *message=0, int lineno=-1, int sourceId=-1)
Factory method for error objects.
The initial value of Function.prototype (and thus all objects created with the Function constructor) ...
Object builtinArray() const
Returns the builtin "Array" object.
bool isA(Type t) const
Checks whether or not the value is of a particular tpye.
unsigned long toULong(bool *ok, bool tolerateEmptyString) const
Attempts an conversion to an unsigned long integer.
Represents an primitive Undefined value.
Represents an primitive String value.
static Object dynamicCast(const Value &v)
Converts a Value into an Object.
Object builtinRegExpPrototype() const
Returns the builtin "RegExp.prototype" object.
bool isValid() const
Returns whether or not this is a valid value.
void put(ExecState *exec, const Identifier &propertyName, const Value &value, int attr=None)
Sets the specified property.
Represents an primitive Boolean value.
Represents the current state of script execution.
Represents an Identifier for a Javascript object.
int toInt32(ExecState *exec) const
Performs the ToInt32 type conversion operation on this value (ECMA 9.5)
const UString & ustring() const
returns a UString of the identifier