summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFabrice Bellard <fabrice@bellard.org>2025-05-05 16:46:21 +0200
committerFabrice Bellard <fabrice@bellard.org>2025-05-05 16:46:21 +0200
commitc95b024d3e4b396c9569719173e4269091dc0bf7 (patch)
tree8dd9f92b0f1f58f498a0a75cca924933a5c2fe9d
parent0a6160d7b3290710daf2dbeaba73d4d50e93b684 (diff)
downloadquickjs-c95b024d3e4b396c9569719173e4269091dc0bf7.tar.gz
quickjs-c95b024d3e4b396c9569719173e4269091dc0bf7.zip
added RegExp.escape (bnoordhuis)
-rw-r--r--quickjs.c53
-rw-r--r--test262.conf2
2 files changed, 54 insertions, 1 deletions
diff --git a/quickjs.c b/quickjs.c
index a39a474..5d61957 100644
--- a/quickjs.c
+++ b/quickjs.c
@@ -44570,6 +44570,58 @@ void *lre_realloc(void *opaque, void *ptr, size_t size)
return js_realloc_rt(ctx->rt, ptr, size);
}
+static JSValue js_regexp_escape(JSContext *ctx, JSValueConst this_val,
+ int argc, JSValueConst *argv)
+{
+ JSValue str;
+ StringBuffer b_s, *b = &b_s;
+ JSString *p;
+ uint32_t c, i;
+ char s[16];
+
+ if (!JS_IsString(argv[0]))
+ return JS_ThrowTypeError(ctx, "not a string");
+ str = JS_ToString(ctx, argv[0]); /* must call it to linearlize ropes */
+ if (JS_IsException(str))
+ return JS_EXCEPTION;
+ p = JS_VALUE_GET_STRING(str);
+ string_buffer_init2(ctx, b, 0, p->is_wide_char);
+ for (i = 0; i < p->len; i++) {
+ c = string_get(p, i);
+ if (c < 33) {
+ if (c >= 9 && c <= 13) {
+ string_buffer_putc8(b, '\\');
+ string_buffer_putc8(b, "tnvfr"[c - 9]);
+ } else {
+ goto hex2;
+ }
+ } else if (c < 128) {
+ if ((c >= '0' && c <= '9')
+ || (c >= 'A' && c <= 'Z')
+ || (c >= 'a' && c <= 'z')) {
+ if (i == 0)
+ goto hex2;
+ } else if (strchr(",-=<>#&!%:;@~'`\"", c)) {
+ goto hex2;
+ } else if (c != '_') {
+ string_buffer_putc8(b, '\\');
+ }
+ string_buffer_putc8(b, c);
+ } else if (c < 256) {
+ hex2:
+ snprintf(s, sizeof(s), "\\x%02x", c);
+ string_buffer_puts8(b, s);
+ } else if (is_surrogate(c) || lre_is_space(c)) {
+ snprintf(s, sizeof(s), "\\u%04x", c);
+ string_buffer_puts8(b, s);
+ } else {
+ string_buffer_putc16(b, c);
+ }
+ }
+ JS_FreeValue(ctx, str);
+ return string_buffer_end(b);
+}
+
static JSValue js_regexp_exec(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv)
{
@@ -45617,6 +45669,7 @@ done:
}
static const JSCFunctionListEntry js_regexp_funcs[] = {
+ JS_CFUNC_DEF("escape", 1, js_regexp_escape ),
JS_CGETSET_DEF("[Symbol.species]", js_get_this, NULL ),
//JS_CFUNC_DEF("__RegExpExec", 2, js_regexp___RegExpExec ),
//JS_CFUNC_DEF("__RegExpDelete", 2, js_regexp___RegExpDelete ),
diff --git a/test262.conf b/test262.conf
index 6890682..4116804 100644
--- a/test262.conf
+++ b/test262.conf
@@ -181,7 +181,7 @@ regexp-modifiers=skip
regexp-named-groups
regexp-unicode-property-escapes
regexp-v-flag=skip
-RegExp.escape=skip
+RegExp.escape
resizable-arraybuffer=skip
rest-parameters
Set