ref: b749e23cb4ff42e06d9e1e75196745be4ca40a59
parent: 96667d99b197808927bad6c1231296f040812df7
author: Tor Andersson <tor@ccxvii.net>
date: Tue Feb 4 10:04:45 EST 2014
String.split().
--- a/jsregexp.c
+++ b/jsregexp.c
@@ -83,8 +83,10 @@
js_pop(J, 1);
} else if (js_isundefined(J, 1)) {
pattern = "";
+ flags = 0;
} else {
pattern = js_tostring(J, 1);
+ flags = 0;
}
if (argc > 1) {
--- a/jsstring.c
+++ b/jsstring.c
@@ -513,6 +513,119 @@
return Sp_replace_string(J, argc);
}
+static int Sp_split_regexp(js_State *J, int argc)
+{
+ const char *str = js_tostring(J, 0);
+ unsigned int limit = !js_isundefined(J, 2) ? js_touint32(J, 2) : 1 << 30;
+ regmatch_t m[10];
+ regex_t *prog;
+ int flags;
+ unsigned int len, k, e;
+ unsigned int p, a, b, c;
+
+ prog = js_toregexp(J, 1, &flags);
+
+ js_newarray(J);
+ len = 0;
+
+ e = strlen(str);
+
+ /* splitting the empty string */
+ if (e == 0) {
+ if (regexec(prog, str, nelem(m), m, 0)) {
+ if (len == limit) return 1;
+ js_pushliteral(J, "");
+ js_setindex(J, -2, 0);
+ }
+ return 1;
+ }
+
+ p = a = 0;
+ while (a < e) {
+ if (regexec(prog, str + a, nelem(m), m, a > 0 ? REG_NOTBOL : 0))
+ break; /* no match */
+
+ b = a + m[0].rm_so;
+ c = a + m[0].rm_eo;
+
+ /* empty string at end of last match */
+ if (b == p) {
+ ++a;
+ continue;
+ }
+
+ if (len == limit) return 1;
+ js_pushlstring(J, str + p, b - p);
+ js_setindex(J, -2, len++);
+
+ for (k = 1; k < nelem(m) && m[k].rm_so >= 0; ++k) {
+ if (len == limit) return 1;
+ js_pushlstring(J, str + a + m[k].rm_so, m[k].rm_eo - m[k].rm_so);
+ js_setindex(J, -2, len++);
+ }
+
+ a = p = c;
+ }
+
+ if (len == limit) return 1;
+ js_pushstring(J, str + p);
+ js_setindex(J, -2, len);
+
+ return 1;
+}
+
+static int Sp_split_string(js_State *J, int argc)
+{
+ const char *str = js_tostring(J, 0);
+ const char *sep = js_tostring(J, 1);
+ unsigned int limit = !js_isundefined(J, 2) ? js_touint32(J, 2) : 1 << 30;
+ unsigned int i, n;
+
+ js_newarray(J);
+
+ n = strlen(sep);
+
+ /* empty string */
+ if (n == 0) {
+ Rune rune;
+ for (i = 0; *str && i < limit; ++i) {
+ n = chartorune(&rune, str);
+ js_pushlstring(J, str, n);
+ js_setindex(J, -2, i);
+ str += n;
+ }
+ return 1;
+ }
+
+ for (i = 0; str && i < limit; ++i) {
+ const char *s = strstr(str, sep);
+ if (s) {
+ js_pushlstring(J, str, s-str);
+ js_setindex(J, -2, i);
+ str = s + n;
+ } else {
+ js_pushstring(J, str);
+ js_setindex(J, -2, i);
+ str = NULL;
+ }
+ }
+
+ return 1;
+}
+
+static int Sp_split(js_State *J, int argc)
+{
+ if (js_isundefined(J, 1)) {
+ js_newarray(J);
+ js_copy(J, 0);
+ js_setindex(J, -2, 0);
+ return 1;
+ }
+ if (js_isregexp(J, 1))
+ return Sp_split_regexp(J, argc);
+ return Sp_split_string(J, argc);
+}
+
void jsB_initstring(js_State *J)
{
J->String_prototype->u.string = "";
@@ -531,7 +644,7 @@
jsB_propf(J, "replace", Sp_replace, 2);
jsB_propf(J, "search", Sp_search, 1);
jsB_propf(J, "slice", Sp_slice, 2);
- // split (uses regexp)
+ jsB_propf(J, "split", Sp_split, 2);
jsB_propf(J, "substring", Sp_substring, 2);
jsB_propf(J, "toLowerCase", Sp_toLowerCase, 0);
jsB_propf(J, "toLocaleLowerCase", Sp_toLowerCase, 0);