ref: 9838735f9311cb9e134a561c68b6c4ac9be47263
parent: f10f1f06c8977927d05003b2b161372db1982ecf
author: Tor Andersson <tor@ccxvii.net>
date: Wed Feb 5 08:37:28 EST 2014
Handle global flag in RexExp.exec() and .test(). Does not expose last flag to javascript code.
--- a/jsregexp.c
+++ b/jsregexp.c
@@ -8,19 +8,29 @@
int js_RegExp_prototype_exec(js_State *J, int idx, const char *text)
{
- int flags, opts;
+ js_Object *obj;
+ int flags, opts, last;
regex_t *prog;
regmatch_t m[10];
int i;
prog = js_toregexp(J, idx, &flags);
+ obj = js_toobject(J, idx);
- opts = REG_EXTENDED;
- if (flags & JS_REGEXP_I) opts |= REG_ICASE;
- if (flags & JS_REGEXP_M) opts |= REG_NEWLINE;
+ opts = 0;
+ if (flags & JS_REGEXP_G) {
+ last = obj->u.r.last;
+ if (last < 0 || last > strlen(text)) {
+ obj->u.r.last = 0;
+ js_pushnull(J);
+ return 1;
+ }
+ if (last > 0) {
+ text += last;
+ opts |= REG_NOTBOL;
+ }
+ }
- // TODO: global and lastIndex
-
if (!regexec(prog, text, nelem(m), m, opts)) {
js_newarray(J);
for (i = 0; i < nelem(m) && m[i].rm_so >= 0; ++i) {
@@ -27,9 +37,14 @@
js_pushlstring(J, text + m[i].rm_so, m[i].rm_eo - m[i].rm_so);
js_setindex(J, -2, i);
}
+ if (flags & JS_REGEXP_G)
+ obj->u.r.last = last + m[0].rm_eo;
return 1;
}
+ if (flags & JS_REGEXP_G)
+ obj->u.r.last = 0;
+
js_pushnull(J);
return 1;
}
@@ -57,6 +72,7 @@
obj->u.r.prog = prog;
obj->u.r.flags = flags;
+ obj->u.r.last = 0;
js_pushobject(J, obj);
js_pushstring(J, pattern);
@@ -161,16 +177,41 @@
static int Rp_test(js_State *J, int argc)
{
- int flags;
+ int flags, opts, last;
+ js_Object *obj;
+ regmatch_t m[10];
regex_t *prog;
const char *text;
prog = js_toregexp(J, 0, &flags);
+ obj = js_toobject(J, 0);
text = js_tostring(J, 1);
- // TODO: global and lastIndex
+ opts = 0;
+ if (flags & JS_REGEXP_G) {
+ last = obj->u.r.last;
+ if (last < 0 || last > strlen(text)) {
+ obj->u.r.last = 0;
+ js_pushboolean(J, 0);
+ return 1;
+ }
+ if (last > 0) {
+ text += last;
+ opts |= REG_NOTBOL;
+ }
+ }
- js_pushboolean(J, !regexec(prog, text, 0, NULL, 0));
+ if (!regexec(prog, text, nelem(m), m, opts)) {
+ if (flags & JS_REGEXP_G)
+ obj->u.r.last = last + m[0].rm_eo;
+ js_pushboolean(J, 1);
+ return 1;
+ }
+
+ if (flags & JS_REGEXP_G)
+ obj->u.r.last = 0;
+
+ js_pushboolean(J, 0);
return 1;
}