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 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