static void Encode(js_State *J, const char *str, const char *unescaped) { js_Buffer *sb = NULL; static const char *HEX = "0123456789ABCDEF"; while (*str) { int c = (unsigned char) *str++; if (strchr(unescaped, c)) js_putc(J, &sb, c); else { js_putc(J, &sb, '%'); js_putc(J, &sb, HEX[(c >> 4) & 0xf]); js_putc(J, &sb, HEX[c & 0xf]); } } js_putc(J, &sb, 0); if (js_try(J)) { js_free(J, sb); js_throw(J); } js_pushstring(J, sb ? sb->s : ""); js_endtry(J); js_free(J, sb); }
static void fmtstr(js_State *J, js_Buffer **sb, const char *s) { static const char *HEX = "0123456789ABCDEF"; Rune c; js_putc(J, sb, '"'); while (*s) { s += chartorune(&c, s); switch (c) { case '"': js_puts(J, sb, "\\\""); break; case '\\': js_puts(J, sb, "\\\\"); break; case '\b': js_puts(J, sb, "\\b"); break; case '\f': js_puts(J, sb, "\\f"); break; case '\n': js_puts(J, sb, "\\n"); break; case '\r': js_puts(J, sb, "\\r"); break; case '\t': js_puts(J, sb, "\\t"); break; default: if (c < ' ') { js_puts(J, sb, "\\u"); js_putc(J, sb, HEX[(c>>12)&15]); js_putc(J, sb, HEX[(c>>8)&15]); js_putc(J, sb, HEX[(c>>4)&15]); js_putc(J, sb, HEX[c&15]); } else { js_putc(J, sb, c); break; } }
static void Sp_replace_string(js_State *J) { const char *source, *needle, *s, *r; js_Buffer *sb = NULL; int n; source = js_tostring(J, 0); needle = js_tostring(J, 1); s = strstr(source, needle); if (!s) { js_copy(J, 0); return; } n = strlen(needle); if (js_iscallable(J, 2)) { js_copy(J, 2); js_pushglobal(J); js_pushlstring(J, s, n); /* arg 1: substring that matched */ js_pushnumber(J, s - source); /* arg 2: offset within search string */ js_copy(J, 0); /* arg 3: search string */ js_call(J, 3); r = js_tostring(J, -1); js_putm(J, &sb, source, s); js_puts(J, &sb, r); js_puts(J, &sb, s + n); js_putc(J, &sb, 0); js_pop(J, 1); } else { r = js_tostring(J, 2); js_putm(J, &sb, source, s); while (*r) { if (*r == '$') { switch (*(++r)) { case '$': js_putc(J, &sb, '$'); break; case '&': js_putm(J, &sb, s, s + n); break; case '`': js_putm(J, &sb, source, s); break; case '\'': js_puts(J, &sb, s + n); break; default: js_putc(J, &sb, '$'); js_putc(J, &sb, *r); break; } ++r; } else { js_putc(J, &sb, *r++); } } js_puts(J, &sb, s + n); js_putc(J, &sb, 0); } if (js_try(J)) { js_free(J, sb); js_throw(J); } js_pushstring(J, sb ? sb->s : ""); js_endtry(J); js_free(J, sb); }
static void jsB_Function(js_State *J) { unsigned int i, top = js_gettop(J); js_Buffer *sb = NULL; const char *body; js_Ast *parse; js_Function *fun; /* p1, p2, ..., pn */ if (top > 2) { for (i = 1; i < top - 1; ++i) { if (i > 1) js_putc(J, &sb, ','); js_puts(J, &sb, js_tostring(J, i)); } js_putc(J, &sb, ')'); } /* body */ body = js_isdefined(J, top - 1) ? js_tostring(J, top - 1) : ""; if (js_try(J)) { js_free(J, sb); jsP_freeparse(J); js_throw(J); } parse = jsP_parsefunction(J, "[string]", sb ? sb->s : NULL, body); fun = jsC_compilefunction(J, parse); js_endtry(J); js_free(J, sb); jsP_freeparse(J); js_newfunction(J, fun, J->GE); }
static void Decode(js_State *J, const char *str, const char *reserved) { js_Buffer *sb = NULL; int a, b; while (*str) { int c = (unsigned char) *str++; if (c != '%') js_putc(J, &sb, c); else { if (!str[0] || !str[1]) js_urierror(J, "truncated escape sequence"); a = *str++; b = *str++; if (!jsY_ishex(a) || !jsY_ishex(b)) js_urierror(J, "invalid escape sequence"); c = jsY_tohex(a) << 4 | jsY_tohex(b); if (!strchr(reserved, c)) js_putc(J, &sb, c); else { js_putc(J, &sb, '%'); js_putc(J, &sb, a); js_putc(J, &sb, b); } } } js_putc(J, &sb, 0); if (js_try(J)) { js_free(J, sb); js_throw(J); } js_pushstring(J, sb ? sb->s : ""); js_endtry(J); js_free(J, sb); }
static void Sp_replace_regexp(js_State *J) { js_Regexp *re; const char *source, *s, *r; js_Buffer *sb = NULL; unsigned int n, x; Resub m; source = js_tostring(J, 0); re = js_toregexp(J, 1); if (js_regexec(re->prog, source, &m, 0)) { js_copy(J, 0); return; } re->last = 0; loop: s = m.sub[0].sp; n = m.sub[0].ep - m.sub[0].sp; if (js_iscallable(J, 2)) { js_copy(J, 2); js_pushglobal(J); for (x = 0; m.sub[x].sp; ++x) /* arg 0..x: substring and subexps that matched */ js_pushlstring(J, m.sub[x].sp, m.sub[x].ep - m.sub[x].sp); js_pushnumber(J, s - source); /* arg x+2: offset within search string */ js_copy(J, 0); /* arg x+3: search string */ js_call(J, 2 + x); r = js_tostring(J, -1); js_putm(J, &sb, source, s); js_puts(J, &sb, r); js_pop(J, 1); } else { r = js_tostring(J, 2); js_putm(J, &sb, source, s); while (*r) { if (*r == '$') { switch (*(++r)) { case '$': js_putc(J, &sb, '$'); break; case '`': js_putm(J, &sb, source, s); break; case '\'': js_puts(J, &sb, s + n); break; case '&': js_putm(J, &sb, s, s + n); break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': x = *r - '0'; if (r[1] >= '0' && r[1] <= '9') x = x * 10 + *(++r) - '0'; if (x > 0 && x < m.nsub) { js_putm(J, &sb, m.sub[x].sp, m.sub[x].ep); } else { js_putc(J, &sb, '$'); if (x > 10) { js_putc(J, &sb, '0' + x / 10); js_putc(J, &sb, '0' + x % 10); } else { js_putc(J, &sb, '0' + x); } } break; default: js_putc(J, &sb, '$'); js_putc(J, &sb, *r); break; } ++r; } else { js_putc(J, &sb, *r++); } } } if (re->flags & JS_REGEXP_G) { source = m.sub[0].ep; if (n == 0) { if (*source) js_putc(J, &sb, *source++); else goto end; } if (!js_regexec(re->prog, source, &m, REG_NOTBOL)) goto loop; } end: js_puts(J, &sb, s + n); js_putc(J, &sb, 0); if (js_try(J)) { js_free(J, sb); js_throw(J); } js_pushstring(J, sb ? sb->s : ""); js_endtry(J); js_free(J, sb); }