Add js_pushlstring to avoid a lot of try/malloc/pushstring boilerplate.

This commit is contained in:
Tor Andersson
2014-01-31 16:14:51 +01:00
parent 6c37f967b4
commit b7afd400f6
5 changed files with 44 additions and 54 deletions

1
js.h
View File

@@ -107,6 +107,7 @@ void js_pushnull(js_State *J);
void js_pushboolean(js_State *J, int v);
void js_pushnumber(js_State *J, double v);
void js_pushstring(js_State *J, const char *v);
void js_pushlstring(js_State *J, const char *v, int n);
void js_pushliteral(js_State *J, const char *v);
void js_newobject(js_State *J);

View File

@@ -448,7 +448,7 @@ void jsB_initarray(js_State *J)
}
js_newcconstructor(J, jsB_new_Array, jsB_new_Array, 1);
{
/* ECMA-262-5 */
/* ES5 */
jsB_propf(J, "isArray", A_isArray, 1);
}
js_defglobal(J, "Array", JS_DONTENUM);

View File

@@ -11,8 +11,7 @@ int js_RegExp_prototype_exec(js_State *J, int idx, const char *text)
int flags, opts;
regex_t *prog;
regmatch_t m[10];
char *s;
int i, n;
int i;
prog = js_toregexp(J, idx, &flags);
@@ -22,23 +21,10 @@ int js_RegExp_prototype_exec(js_State *J, int idx, const char *text)
if (!regexec(prog, text, nelem(m), m, opts)) {
js_newarray(J);
s = malloc(strlen(text) + 1);
if (js_try(J)) {
free(s);
js_throw(J);
}
for (i = 0; i < nelem(m) && m[i].rm_so >= 0; ++i) {
n = m[i].rm_eo - m[i].rm_so;
memcpy(s, text + m[i].rm_so, n);
s[n] = 0;
js_pushstring(J, s);
js_pushlstring(J, text + m[i].rm_so, m[i].rm_eo - m[i].rm_so);
js_setindex(J, -2, i);
}
js_endtry(J);
free(s);
return 1;
}

21
jsrun.c
View File

@@ -50,6 +50,27 @@ void js_pushstring(js_State *J, const char *v)
++TOP;
}
void js_pushlstring(js_State *J, const char *v, int n)
{
char buf[256];
if (n + 1 < sizeof buf) {
memcpy(buf, v, n);
buf[n] = 0;
js_pushstring(J, buf);
} else {
char *s = malloc(n + 1);
memcpy(s, v, n);
s[n] = 0;
if (js_try(J)) {
free(s);
js_throw(J);
}
js_pushstring(J, s);
js_endtry(J);
free(s);
}
}
void js_pushliteral(js_State *J, const char *v)
{
STACK[TOP].type = JS_TSTRING;

View File

@@ -48,7 +48,7 @@ static inline Rune runeAt(const char *s, int i)
return rune;
}
static inline const char *utfindex(const char *s, int i)
static inline const char *utfidx(const char *s, int i)
{
Rune rune = 0;
while (i-- > 0) {
@@ -167,27 +167,13 @@ static int Sp_localeCompare(js_State *J, int argc)
return strcmp(a, b);
}
static char *substr(js_State *J, const char *src, int a, int b)
{
int n = b - a;
const char *s = utfindex(src, a);
char *dst = malloc(UTFmax * n + 1), *d = dst;
while (n--) {
Rune rune;
s += chartorune(&rune, s);
d += runetochar(d, &rune);
}
*d = 0;
return dst;
}
static int Sp_slice(js_State *J, int argc)
{
const char *str = js_tostring(J, 0);
const char *ss, *ee;
int len = utflen(str);
int s = js_tointeger(J, 1);
int e = argc > 1 ? js_tointeger(J, 2) : len;
char *out;
s = s < 0 ? s + len : s;
e = e < 0 ? e + len : e;
@@ -195,42 +181,38 @@ static int Sp_slice(js_State *J, int argc)
s = s < 0 ? 0 : s > len ? len : s;
e = e < 0 ? 0 : e > len ? len : e;
if (s < e)
out = substr(J, str, s, e);
else
out = substr(J, str, e, s);
if (js_try(J)) {
free(out);
js_throw(J);
if (s < e) {
ss = utfidx(str, s);
ee = utfidx(ss, e - s);
} else {
ss = utfidx(str, e);
ee = utfidx(ss, s - e);
}
js_pushstring(J, out);
js_endtry(J);
js_pushlstring(J, ss, ee - ss);
return 1;
}
static int Sp_substring(js_State *J, int argc)
{
const char *str = js_tostring(J, 0);
const char *ss, *ee;
int len = utflen(str);
int s = js_tointeger(J, 1);
int e = argc > 1 ? js_tointeger(J, 2) : len;
char *out;
s = s < 0 ? 0 : s > len ? len : s;
e = e < 0 ? 0 : e > len ? len : e;
if (s < e)
out = substr(J, str, s, e);
else
out = substr(J, str, e, s);
if (js_try(J)) {
free(out);
js_throw(J);
if (s < e) {
ss = utfidx(str, s);
ee = utfidx(ss, e - s);
} else {
ss = utfidx(str, e);
ee = utfidx(ss, s - e);
}
js_pushstring(J, out);
js_endtry(J);
js_pushlstring(J, ss, ee - ss);
return 1;
}