]> git.kaiwu.me - quickjs.git/commitdiff
better pretty printing of strings - removed String.prototype.__quote()
authorFabrice Bellard <fabrice@bellard.org>
Wed, 10 Sep 2025 16:25:34 +0000 (18:25 +0200)
committerFabrice Bellard <fabrice@bellard.org>
Wed, 10 Sep 2025 16:25:34 +0000 (18:25 +0200)
quickjs.c
tests/test_bjson.js

index b93e282a14df673ee0f3c5776c255a975650d39b..2ca46aa3259aa5c966fb527a389847ed56d18e1e 100644 (file)
--- a/quickjs.c
+++ b/quickjs.c
@@ -13126,18 +13126,61 @@ static uint32_t js_string_get_length(JSValueConst val)
     }
 }
 
-static void js_dump_char(JSPrintValueState *s, int c, int sep)
+/* pretty print the first 'len' characters of 'p' */
+static void js_print_string1(JSPrintValueState *s, JSString *p, int len, int sep)
 {
-    if (c == sep || c == '\\') {
-        js_putc(s, '\\');
-        js_putc(s, c);
-    } else if (c >= ' ' && c <= 126) {
-        js_putc(s, c);
-    } else if (c == '\n') {
-        js_putc(s, '\\');
-        js_putc(s, 'n');
-    } else {
-        js_printf(s, "\\u%04x", c);
+    uint8_t buf[UTF8_CHAR_LEN_MAX];
+    int l, i, c, c1;
+
+    for(i = 0; i < len; i++) {
+        c = string_get(p, i);
+        switch(c) {
+        case '\t':
+            c = 't';
+            goto quote;
+        case '\r':
+            c = 'r';
+            goto quote;
+        case '\n':
+            c = 'n';
+            goto quote;
+        case '\b':
+            c = 'b';
+            goto quote;
+        case '\f':
+            c = 'f';
+            goto quote;
+        case '\\':
+        quote:
+            js_putc(s, '\\');
+            js_putc(s, c);
+            break;
+        default:
+            if (c == sep)
+                goto quote;
+            if (c >= 32 && c <= 126) {
+                js_putc(s, c);
+            } else if (c < 32 || 
+                       (c >= 0x7f && c <= 0x9f)) {
+            escape:
+                js_printf(s, "\\u%04x", c);
+            } else {
+                if (is_hi_surrogate(c)) {
+                    if ((i + 1) >= len)
+                        goto escape;
+                    c1 = string_get(p, i + 1);
+                    if (!is_lo_surrogate(c1))
+                        goto escape;
+                    i++;
+                    c = from_surrogate(c, c1);
+                } else if (is_lo_surrogate(c)) {
+                    goto escape;
+                }
+                l = unicode_to_utf8(buf, c);
+                s->write_func(s->write_opaque, (char *)buf, l);
+            }
+            break;
+        }
     }
 }
 
@@ -13146,12 +13189,10 @@ static void js_print_string_rec(JSPrintValueState *s, JSValueConst val,
 {
     if (JS_VALUE_GET_TAG(val) == JS_TAG_STRING) {
         JSString *p = JS_VALUE_GET_STRING(val);
-        uint32_t i, len;
+        uint32_t len;
         if (pos < s->options.max_string_length) {
             len = min_uint32(p->len, s->options.max_string_length - pos);
-            for(i = 0; i < len; i++) {
-                js_dump_char(s, string_get(p, i), sep);
-            }
+            js_print_string1(s, p, len, sep);
         }
     } else if (JS_VALUE_GET_TAG(val) == JS_TAG_STRING_ROPE) {
         JSStringRope *r = JS_VALUE_GET_PTR(val);
@@ -13224,9 +13265,7 @@ static void js_print_atom(JSPrintValueState *s, JSAtom atom)
             }
         } else {
             js_putc(s, '"');
-            for(i = 0; i < p->len; i++) {
-                js_dump_char(s, string_get(p, i), '\"');
-            }
+            js_print_string1(s, p, p->len, '\"');
             js_putc(s, '"');
         }
     }
@@ -43859,12 +43898,6 @@ static JSValue js_string_trim(JSContext *ctx, JSValueConst this_val,
     return ret;
 }
 
-static JSValue js_string___quote(JSContext *ctx, JSValueConst this_val,
-                                 int argc, JSValueConst *argv)
-{
-    return JS_ToQuotedString(ctx, this_val);
-}
-
 /* return 0 if before the first char */
 static int string_prevc(JSString *p, int *pidx)
 {
@@ -44352,7 +44385,6 @@ static const JSCFunctionListEntry js_string_proto_funcs[] = {
     JS_ALIAS_DEF("trimLeft", "trimStart" ),
     JS_CFUNC_DEF("toString", 0, js_string_toString ),
     JS_CFUNC_DEF("valueOf", 0, js_string_toString ),
-    JS_CFUNC_DEF("__quote", 1, js_string___quote ),
     JS_CFUNC_MAGIC_DEF("toLowerCase", 0, js_string_toLowerCase, 1 ),
     JS_CFUNC_MAGIC_DEF("toUpperCase", 0, js_string_toLowerCase, 0 ),
     JS_CFUNC_MAGIC_DEF("toLocaleLowerCase", 0, js_string_toLowerCase, 1 ),
index a90bfe18dd5fc91813cb1cd395b90d79a40d59fe..8794b22d921d8232dd4cbaa07879a7c4479ca2a7 100644 (file)
@@ -86,7 +86,7 @@ function toStr(a)
     case "undefined":
         return "undefined";
     case "string":
-        return a.__quote();
+        return JSON.stringify(a);
     case "number":
         if (a == 0 && 1 / a < 0)
             return "-0";