6 void js_newregexp(js_State *J, const char *pattern, int flags)
13 obj = jsV_newobject(J, JS_CREGEXP, J->RegExp_prototype);
16 if (flags & JS_REGEXP_I) opts |= REG_ICASE;
17 if (flags & JS_REGEXP_M) opts |= REG_NEWLINE;
19 prog = js_regcomp(pattern, opts, &error);
21 js_syntaxerror(J, "regular expression: %s", error);
24 obj->u.r.source = pattern;
25 obj->u.r.flags = flags;
27 js_pushobject(J, obj);
30 void js_RegExp_prototype_exec(js_State *J, js_Regexp *re, const char *text)
37 if (re->flags & JS_REGEXP_G) {
38 if (re->last > strlen(text)) {
49 if (!js_regexec(re->prog, text, &m, opts)) {
51 js_pushstring(J, text);
52 js_setproperty(J, -2, "input");
53 js_pushnumber(J, js_utfptrtoidx(text, m.sub[0].sp));
54 js_setproperty(J, -2, "index");
55 for (i = 0; i < m.nsub; ++i) {
56 js_pushlstring(J, m.sub[i].sp, m.sub[i].ep - m.sub[i].sp);
57 js_setindex(J, -2, i);
59 if (re->flags & JS_REGEXP_G)
60 re->last = re->last + (m.sub[0].ep - text);
64 if (re->flags & JS_REGEXP_G)
70 static void Rp_test(js_State *J)
77 re = js_toregexp(J, 0);
78 text = js_tostring(J, 1);
81 if (re->flags & JS_REGEXP_G) {
82 if (re->last > strlen(text)) {
93 if (!js_regexec(re->prog, text, &m, opts)) {
94 if (re->flags & JS_REGEXP_G)
95 re->last = re->last + (m.sub[0].ep - text);
100 if (re->flags & JS_REGEXP_G)
103 js_pushboolean(J, 0);
106 static void jsB_new_RegExp(js_State *J)
112 if (js_isregexp(J, 1)) {
113 if (js_isdefined(J, 2))
114 js_typeerror(J, "cannot supply flags when creating one RegExp from another");
115 old = js_toregexp(J, 1);
116 pattern = old->source;
118 } else if (js_isundefined(J, 1)) {
122 pattern = js_tostring(J, 1);
126 if (js_isdefined(J, 2)) {
127 const char *s = js_tostring(J, 2);
128 int g = 0, i = 0, m = 0;
131 else if (*s == 'i') ++i;
132 else if (*s == 'm') ++m;
133 else js_syntaxerror(J, "invalid regular expression flag: '%c'", *s);
136 if (g > 1) js_syntaxerror(J, "invalid regular expression flag: 'g'");
137 if (i > 1) js_syntaxerror(J, "invalid regular expression flag: 'i'");
138 if (m > 1) js_syntaxerror(J, "invalid regular expression flag: 'm'");
139 if (g) flags |= JS_REGEXP_G;
140 if (i) flags |= JS_REGEXP_I;
141 if (m) flags |= JS_REGEXP_M;
144 js_newregexp(J, pattern, flags);
147 static void jsB_RegExp(js_State *J)
149 if (js_gettop(J) == 2 && js_isregexp(J, 1))
154 static void Rp_toString(js_State *J)
159 re = js_toregexp(J, 0);
161 out = js_malloc(J, strlen(re->source) + 6); /* extra space for //gim */
163 strcat(out, re->source);
165 if (re->flags & JS_REGEXP_G) strcat(out, "g");
166 if (re->flags & JS_REGEXP_I) strcat(out, "i");
167 if (re->flags & JS_REGEXP_M) strcat(out, "m");
174 js_pushstring(J, out);
179 static void Rp_exec(js_State *J)
181 js_RegExp_prototype_exec(J, js_toregexp(J, 0), js_tostring(J, 1));
184 void jsB_initregexp(js_State *J)
186 js_pushobject(J, J->RegExp_prototype);
188 jsB_propf(J, "toString", Rp_toString, 0);
189 jsB_propf(J, "test", Rp_test, 0);
190 jsB_propf(J, "exec", Rp_exec, 0);
192 js_newcconstructor(J, jsB_RegExp, jsB_new_RegExp, "RegExp", 1);
193 js_defglobal(J, "RegExp", JS_DONTENUM);