27 #include "interpreter.h"
28 #include "operations.h"
31 #include "regexp_object.h"
32 #include "error_object.h"
41 const ClassInfo RegExpPrototypeImp::info = {
"RegExp", 0, 0, 0};
43 RegExpPrototypeImp::RegExpPrototypeImp(
ExecState *exec,
44 ObjectPrototypeImp *objProto,
49 setInternalValue(
String(
""));
53 static const Identifier execPropertyName(
"exec");
54 putDirect(execPropertyName,
55 new RegExpProtoFuncImp(exec,funcProto,RegExpProtoFuncImp::Exec, 0, execPropertyName), DontEnum);
56 static const Identifier testPropertyName(
"test");
57 putDirect(testPropertyName,
58 new RegExpProtoFuncImp(exec,funcProto,RegExpProtoFuncImp::Test, 0, testPropertyName), DontEnum);
59 putDirect(toStringPropertyName,
60 new RegExpProtoFuncImp(exec,funcProto,RegExpProtoFuncImp::ToString, 0, toStringPropertyName), DontEnum);
61 static const Identifier compilePropertyName(
"compile");
62 putDirect(compilePropertyName,
63 new RegExpProtoFuncImp(exec,funcProto,RegExpProtoFuncImp::Compile, 1, compilePropertyName), DontEnum);
73 putDirect(lengthPropertyName, len, DontDelete|ReadOnly|DontEnum);
77 bool RegExpProtoFuncImp::implementsCall()
const
84 if (!thisObj.inherits(&RegExpImp::info)) {
85 if (thisObj.inherits(&RegExpPrototypeImp::info)) {
87 case ToString:
return String(
"//");
91 exec->setException(err);
95 RegExpImp *reimp =
static_cast<RegExpImp*
>(thisObj.imp());
96 RegExp *re = reimp->regExp();
103 s = args[0].toString(exec);
104 int length = s.value().
size();
107 Value lastIndex = thisObj.
get(exec,
"lastIndex");
109 bool globalFlag = thisObj.
get(exec,
"global").
toBoolean(exec);
112 if (i < 0 || i > length) {
113 thisObj.
put(exec,
"lastIndex",
Number(0), DontDelete | DontEnum);
120 int **ovector = regExpObj->registerRegexp( re, s.value() );
122 re->prepareMatch(s.value());
123 str = re->match(s.value(), i, 0L, ovector);
125 regExpObj->setSubPatterns(re->subPatterns());
133 thisObj.
put(exec,
"lastIndex",
Number(0), DontDelete | DontEnum);
139 thisObj.
put(exec,
"lastIndex",
Number( (*ovector)[1] ), DontDelete | DontEnum);
140 return regExpObj->arrayOfMatches(exec,str);
160 RegExp* newEngine = RegExpObjectImp::makeEngine(exec, args[0].toString(exec), args[1]);
162 return exec->exception();
163 reimp->setRegExp(newEngine);
174 const ClassInfo RegExpImp::info = {
"RegExp", 0, 0, 0};
176 RegExpImp::RegExpImp(RegExpPrototypeImp *regexpProto)
177 : ObjectImp(regexpProto), reg(0L)
181 RegExpImp::~RegExpImp()
186 void RegExpImp::setRegExp(RegExp *r)
192 putDirect(
"global", (r->flags() & RegExp::Global) ? BooleanImp::staticTrue : BooleanImp::staticFalse,
193 DontDelete | ReadOnly | DontEnum);
194 putDirect(
"ignoreCase", (r->flags() & RegExp::IgnoreCase) ? BooleanImp::staticTrue : BooleanImp::staticFalse,
195 DontDelete | ReadOnly | DontEnum);
196 putDirect(
"multiline", (r->flags() & RegExp::Multiline) ? BooleanImp::staticTrue : BooleanImp::staticFalse,
197 DontDelete | ReadOnly | DontEnum);
199 putDirect(
"source",
new StringImp(r->pattern()), DontDelete | ReadOnly | DontEnum);
200 putDirect(
"lastIndex", NumberImp::zero(), DontDelete | DontEnum);
205 RegExpObjectImp::RegExpObjectImp(
ExecState * ,
207 RegExpPrototypeImp *regProto)
213 putDirect(prototypePropertyName, regProto, DontEnum|DontDelete|ReadOnly);
216 putDirect(lengthPropertyName, NumberImp::two(), ReadOnly|DontDelete|DontEnum);
219 RegExpObjectImp::~RegExpObjectImp()
221 delete [] lastOvector;
224 int **RegExpObjectImp::registerRegexp(
const RegExp* re,
const UString& s )
227 delete [] lastOvector;
229 lastNrSubPatterns = re->subPatterns();
239 for (
unsigned int i = 1 ; i < lastNrSubPatterns + 1 ; ++i )
241 UString substring = lastString.
substr( lastOvector[2*i], lastOvector[2*i+1] - lastOvector[2*i] );
245 arr.
put(exec,
"index",
Number(lastOvector[0]));
246 arr.
put(exec,
"input",
String(lastString));
253 if (s[0] ==
'$' && lastOvector)
259 if (i < lastNrSubPatterns + 1)
261 UString substring = lastString.
substr( lastOvector[2*i], lastOvector[2*i+1] - lastOvector[2*i] );
267 return InternalFunctionImp::get(exec, p);
273 if (s[0] ==
'$' && lastOvector) {
280 return InternalFunctionImp::hasProperty(exec, p);
283 bool RegExpObjectImp::implementsConstruct()
const
290 UString flags = flagsInput.
type() == UndefinedType ?
UString(
"") : flagsInput.toString(exec);
293 for (
int pos = 0; pos < flags.
size(); ++pos) {
294 switch (flags[pos].unicode()) {
301 "Invalid regular expression flags");
302 exec->setException(err);
308 bool global = (flags.
find(
"g") >= 0);
309 bool ignoreCase = (flags.
find(
"i") >= 0);
310 bool multiline = (flags.
find(
"m") >= 0);
312 int reflags = RegExp::None;
314 reflags |= RegExp::Global;
316 reflags |= RegExp::IgnoreCase;
318 reflags |= RegExp::Multiline;
320 RegExp *re =
new RegExp(p, reflags);
321 if (!re->isValid()) {
323 "Invalid regular expression");
324 exec->setException(err);
339 if (a0.
isA(ObjectType) && a0.
toObject(exec).inherits(&RegExpImp::info)) {
341 if (args.
size() > 1 && args[1].type() != UndefinedType) {
343 exec->setException(err);
347 p = rimp->regExp()->pattern();
353 RegExp* re = makeEngine(exec, p, args[1]);
355 return exec->exception().
toObject(exec);
358 RegExpImp *dat =
new RegExpImp(proto);
365 bool RegExpObjectImp::implementsCall()
const
376 return construct(exec, args);
Value objects are act as wrappers ("smart pointers") around ValueImp objects and their descendents...
UString substr(int pos=0, int len=-1) const
Type type() const
Returns the type of value.
Base class for all function objects.
Value get(ExecState *exec, const Identifier &propertyName) const
Retrieves the specified property from the object.
Object construct(ExecState *exec, const List &args)
Creates a new object based on this object.
Represents an primitive Number value.
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
Represents an primitive Null value.
Interpreter * lexicalInterpreter() const
Returns the interpreter associated with the current scope's global object.
Object builtinRegExpPrototype() const
Returns the builtin "RegExp.prototype" object.
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) ...
int toInt32(ExecState *exec) const
Performs the ToInt32 type conversion operation on this value (ECMA 9.5)
Represents an primitive Undefined value.
Object toObject(ExecState *exec) const
Performs the ToObject type conversion operation on this value (ECMA 9.9)
bool isA(Type t) const
Checks whether or not the value is of a particular tpye.
Represents an primitive String value.
static Object dynamicCast(const Value &v)
Converts a Value into an Object.
const UString & ustring() const
returns a UString of the identifier
void put(ExecState *exec, const Identifier &propertyName, const Value &value, int attr=None)
Sets the specified property.
Represents an primitive Boolean value.
UString toString(ExecState *exec) const
Performs the ToString type conversion operation on this value (ECMA 9.8)
Object builtinArray() const
Returns the builtin "Array" object.
bool isValid() const
Returns whether or not this is a valid value.
Object builtinRegExp() const
Returns the builtin "RegExp" object.
unsigned long toULong(bool *ok, bool tolerateEmptyString) const
Attempts an conversion to an unsigned long integer.
Represents the current state of script execution.
Represents an Identifier for a Javascript object.