[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    branches/KDE/3.5/kdelibs/kjs
From:       Maks Orlovich <maksim () kde ! org>
Date:       2006-02-26 23:32:24
Message-ID: 1140996744.822926.3725.nullmailer () svn ! kde ! org
[Download RAW message or body]

SVN commit 513944 by orlovich:

- Support .compile on regexpen  (#120108)
- Error out if flags are invalid
- Don't leak RegExp objects on errors.
Reviewed by Harri
BUG: 120108


 M  +75 -28    regexp_object.cpp  
 M  +9 -2      regexp_object.h  


--- branches/KDE/3.5/kdelibs/kjs/regexp_object.cpp #513943:513944
@@ -59,6 +59,9 @@
 	    new RegExpProtoFuncImp(exec,funcProto,RegExpProtoFuncImp::Test,     0, \
testPropertyName), DontEnum);  putDirect(toStringPropertyName,
 	    new RegExpProtoFuncImp(exec,funcProto,RegExpProtoFuncImp::ToString, 0, \
toStringPropertyName), DontEnum); +  static const Identifier \
compilePropertyName("compile"); +  putDirect(compilePropertyName,
+            new RegExpProtoFuncImp(exec,funcProto,RegExpProtoFuncImp::Compile,  1, \
compilePropertyName), DontEnum);  }
 
 // ------------------------------ RegExpProtoFuncImp ---------------------------
@@ -152,7 +155,15 @@
       str += "m";
     }
     return String(str);
+  case Compile: {
+      RegExp* newEngine = RegExpObjectImp::makeEngine(exec, args[0].toString(exec), \
args[1]); +      if (!newEngine)
+        return exec->exception();
+      reimp->setRegExp(newEngine);
+      return Value(reimp);
+    }
   }
+  
 
   return Undefined();
 }
@@ -171,6 +182,23 @@
   delete reg;
 }
 
+void RegExpImp::setRegExp(RegExp *r)
+{
+  delete reg;
+  reg = r;
+
+  Object protect(this);//Protect self from GC (we are allocating a StringImp, and \
may be new) +  putDirect("global", (r->flags() & RegExp::Global) ? \
BooleanImp::staticTrue : BooleanImp::staticFalse,  +            DontDelete | ReadOnly \
| DontEnum); +  putDirect("ignoreCase", (r->flags() & RegExp::IgnoreCase) ? \
BooleanImp::staticTrue : BooleanImp::staticFalse,  +            DontDelete | ReadOnly \
| DontEnum); +  putDirect("multiline", (r->flags() & RegExp::Multiline) ? \
BooleanImp::staticTrue : BooleanImp::staticFalse,  +            DontDelete | ReadOnly \
| DontEnum); +
+  putDirect("source", new StringImp(r->pattern()), DontDelete | ReadOnly | \
DontEnum); +  putDirect("lastIndex", NumberImp::zero(), DontDelete | DontEnum);
+}
+
 // ------------------------------ RegExpObjectImp ------------------------------
 
 RegExpObjectImp::RegExpObjectImp(ExecState * /*exec*/,
@@ -243,6 +271,49 @@
   return true;
 }
 
+RegExp* RegExpObjectImp::makeEngine(ExecState *exec, const UString &p, const Value \
&flagsInput) +{
+  UString flags = flagsInput.type() == UndefinedType ? UString("") : \
flagsInput.toString(exec); +
+  // Check for validity of flags
+  for (int pos = 0; pos < flags.size(); ++pos) {
+    switch (flags[pos].unicode()) {
+    case 'g':
+    case 'i':
+    case 'm':
+      break;
+    default: {
+        Object err = Error::create(exec, SyntaxError,
+                    "Invalid regular expression flags");
+        exec->setException(err);
+        return 0;
+      }
+    }
+  }
+
+  bool global = (flags.find("g") >= 0);
+  bool ignoreCase = (flags.find("i") >= 0);
+  bool multiline = (flags.find("m") >= 0);
+
+  int reflags = RegExp::None;
+  if (global)
+      reflags |= RegExp::Global;
+  if (ignoreCase)
+      reflags |= RegExp::IgnoreCase;
+  if (multiline)
+      reflags |= RegExp::Multiline;
+
+  RegExp *re = new RegExp(p, reflags);
+  if (!re->isValid()) {
+    Object err = Error::create(exec, SyntaxError,
+                               "Invalid regular expression");
+    exec->setException(err);
+    delete re;
+    return 0;
+  }
+  return re;
+}
+
 // ECMA 15.10.4
 Object RegExpObjectImp::construct(ExecState *exec, const List &args)
 {
@@ -264,38 +335,14 @@
       p = a0.toString(exec);
     }
   }
-  UString flags = args[1].type() == UndefinedType ? UString("") : \
args[1].toString(exec);  
+  RegExp* re = makeEngine(exec, p, args[1]);
+  if (!re)
+    return exec->exception().toObject(exec);
+
   RegExpPrototypeImp *proto = \
static_cast<RegExpPrototypeImp*>(exec->lexicalInterpreter()->builtinRegExpPrototype().imp());
  RegExpImp *dat = new RegExpImp(proto);
   Object obj(dat); // protect from GC
-
-  bool global = (flags.find("g") >= 0);
-  bool ignoreCase = (flags.find("i") >= 0);
-  bool multiline = (flags.find("m") >= 0);
-  // TODO: throw a syntax error on invalid flags
-
-  dat->putDirect("global", global ? BooleanImp::staticTrue : \
                BooleanImp::staticFalse, DontDelete | ReadOnly | DontEnum);
-  dat->putDirect("ignoreCase", ignoreCase ? BooleanImp::staticTrue : \
                BooleanImp::staticFalse, DontDelete | ReadOnly | DontEnum);
-  dat->putDirect("multiline", multiline ? BooleanImp::staticTrue : \
                BooleanImp::staticFalse, DontDelete | ReadOnly | DontEnum);
-
-  dat->putDirect("source", new StringImp(p), DontDelete | ReadOnly | DontEnum);
-  dat->putDirect("lastIndex", NumberImp::zero(), DontDelete | DontEnum);
-
-  int reflags = RegExp::None;
-  if (global)
-      reflags |= RegExp::Global;
-  if (ignoreCase)
-      reflags |= RegExp::IgnoreCase;
-  if (multiline)
-      reflags |= RegExp::Multiline;
-  RegExp *re = new RegExp(p, reflags);
-  if (!re->isValid()) {
-    Object err = Error::create(exec, SyntaxError,
-                               "Invalid regular expression");
-    exec->setException(err);
-    return err;
-  }
   dat->setRegExp(re);
 
   return obj;
--- branches/KDE/3.5/kdelibs/kjs/regexp_object.h #513943:513944
@@ -45,7 +45,7 @@
     virtual bool implementsCall() const;
     virtual Value call(ExecState *exec, Object &thisObj, const List &args);
 
-    enum { Exec, Test, ToString };
+    enum { Exec, Test, ToString, Compile };
   private:
     int id;
   };
@@ -54,7 +54,7 @@
   public:
     RegExpImp(RegExpPrototypeImp *regexpProto);
     ~RegExpImp();
-    void setRegExp(RegExp *r) { reg = r; }
+    void setRegExp(RegExp *r);
     RegExp* regExp() { return reg; }
 
     virtual const ClassInfo *classInfo() const { return &info; }
@@ -78,6 +78,13 @@
     int ** registerRegexp( const RegExp* re, const UString& s );
     void setSubPatterns(int num) { lastNrSubPatterns = num; }
     Object arrayOfMatches(ExecState *exec, const UString &result) const;
+
+    /*
+     Attempts to create a new regular expression engine for the string p
+     and the flags stored in flagsInput. If this succeeds, it returns the 
+     engine. If not, it returns 0, and raises an exception in exec
+    */
+    static RegExp* makeEngine(ExecState *exec, const UString &p, const Value \
&flagsInput);  private:
     UString lastString;
     int *lastOvector;


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic