diff --git a/doc/quickjs.texi b/doc/quickjs.texi index 7e6e85c..c3e6930 100644 --- a/doc/quickjs.texi +++ b/doc/quickjs.texi @@ -451,20 +451,6 @@ optional properties: @end table -@item parseExtJSON(str) - - Parse @code{str} using a superset of @code{JSON.parse}. The - following extensions are accepted: - - @itemize - @item Single line and multiline comments - @item unquoted properties (ASCII-only Javascript identifiers) - @item trailing comma in array and object definitions - @item single quoted strings - @item @code{\f} and @code{\v} are accepted as space characters - @item leading plus in numbers - @item octal (@code{0o} prefix) and hexadecimal (@code{0x} prefix) numbers - @end itemize @end table FILE prototype: diff --git a/quickjs-libc.c b/quickjs-libc.c index 12dc798..d3ac5be 100644 --- a/quickjs-libc.c +++ b/quickjs-libc.c @@ -822,21 +822,6 @@ static JSValue js_std_strerror(JSContext *ctx, JSValueConst this_val, return JS_NewString(ctx, strerror(err)); } -static JSValue js_std_parseExtJSON(JSContext *ctx, JSValueConst this_val, - int argc, JSValueConst *argv) -{ - JSValue obj; - const char *str; - size_t len; - - str = JS_ToCStringLen(ctx, &len, argv[0]); - if (!str) - return JS_EXCEPTION; - obj = JS_ParseJSON2(ctx, str, len, "", JS_PARSE_JSON_EXT); - JS_FreeCString(ctx, str); - return obj; -} - static JSValue js_new_std_file(JSContext *ctx, FILE *f, BOOL close_in_finalizer, BOOL is_popen) @@ -1492,7 +1477,6 @@ static const JSCFunctionListEntry js_std_funcs[] = { JS_CFUNC_DEF("urlGet", 1, js_std_urlGet ), JS_CFUNC_DEF("loadFile", 1, js_std_loadFile ), JS_CFUNC_DEF("strerror", 1, js_std_strerror ), - JS_CFUNC_DEF("parseExtJSON", 1, js_std_parseExtJSON ), /* FILE I/O */ JS_CFUNC_DEF("open", 2, js_std_open ), diff --git a/quickjs.c b/quickjs.c index c00de09..d5eecad 100644 --- a/quickjs.c +++ b/quickjs.c @@ -19464,7 +19464,6 @@ typedef struct JSParseState { JSFunctionDef *cur_func; BOOL is_module; /* parsing a module */ BOOL allow_html_comments; - BOOL ext_json; /* true if accepting JSON superset */ } JSParseState; typedef struct JSOpCode { @@ -20563,11 +20562,8 @@ static __exception int json_next_token(JSParseState *s) } break; case '\'': - if (!s->ext_json) { - /* JSON does not accept single quoted strings */ - goto def_token; - } - /* fall through */ + /* JSON does not accept single quoted strings */ + goto def_token; case '\"': if (js_parse_string(s, c, TRUE, p + 1, &s->token, &p)) goto fail; @@ -20583,72 +20579,15 @@ static __exception int json_next_token(JSParseState *s) goto redo; case '\f': case '\v': - if (!s->ext_json) { - /* JSONWhitespace does not match , nor */ - goto def_token; - } - /* fall through */ + /* JSONWhitespace does not match , nor */ + goto def_token; case ' ': case '\t': p++; goto redo; case '/': - if (!s->ext_json) { - /* JSON does not accept comments */ - goto def_token; - } - if (p[1] == '*') { - /* comment */ - p += 2; - for(;;) { - if (*p == '\0' && p >= s->buf_end) { - js_parse_error(s, "unexpected end of comment"); - goto fail; - } - if (p[0] == '*' && p[1] == '/') { - p += 2; - break; - } - if (*p == '\n') { - s->line_num++; - p++; - } else if (*p == '\r') { - p++; - } else if (*p >= 0x80) { - c = unicode_from_utf8(p, UTF8_CHAR_LEN_MAX, &p); - if (c == -1) { - p++; /* skip invalid UTF-8 */ - } - } else { - p++; - } - } - goto redo; - } else if (p[1] == '/') { - /* line comment */ - p += 2; - for(;;) { - if (*p == '\0' && p >= s->buf_end) - break; - if (*p == '\r' || *p == '\n') - break; - if (*p >= 0x80) { - c = unicode_from_utf8(p, UTF8_CHAR_LEN_MAX, &p); - /* LS or PS are considered as line terminator */ - if (c == CP_LS || c == CP_PS) { - break; - } else if (c == -1) { - p++; /* skip invalid UTF-8 */ - } - } else { - p++; - } - } - goto redo; - } else { - goto def_token; - } - break; + /* JSON does not accept comments */ + goto def_token; case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': @@ -20676,7 +20615,7 @@ static __exception int json_next_token(JSParseState *s) s->token.val = TOK_IDENT; break; case '+': - if (!s->ext_json || !is_digit(p[1])) + if (!is_digit(p[1])) goto def_token; goto parse_number; case '0': @@ -20693,17 +20632,7 @@ static __exception int json_next_token(JSParseState *s) /* number */ parse_number: { - JSValue ret; - int flags, radix; - if (!s->ext_json) { - flags = 0; - radix = 10; - } else { - flags = ATOD_ACCEPT_BIN_OCT; - radix = 0; - } - ret = js_atof(s->ctx, (const char *)p, (const char **)&p, radix, - flags); + JSValue ret = js_atof(s->ctx, (const char *)p, (const char **)&p, 10, 0); if (JS_IsException(ret)) goto fail; s->token.val = TOK_NUMBER; @@ -42935,8 +42864,6 @@ static JSValue json_parse_value(JSParseState *s) prop_name = JS_ValueToAtom(ctx, s->token.u.str.str); if (prop_name == JS_ATOM_NULL) goto fail; - } else if (s->ext_json && s->token.val == TOK_IDENT) { - prop_name = JS_DupAtom(ctx, s->token.u.ident.atom); } else { js_parse_error(s, "expecting property name"); goto fail; @@ -42961,8 +42888,6 @@ static JSValue json_parse_value(JSParseState *s) break; if (json_next_token(s)) goto fail; - if (s->ext_json && s->token.val == '}') - break; } } if (json_parse_expect(s, '}')) @@ -42993,8 +42918,6 @@ static JSValue json_parse_value(JSParseState *s) if (json_next_token(s)) goto fail; idx++; - if (s->ext_json && s->token.val == ']') - break; } } if (json_parse_expect(s, ']')) @@ -43039,14 +42962,12 @@ static JSValue json_parse_value(JSParseState *s) return JS_EXCEPTION; } -JSValue JS_ParseJSON2(JSContext *ctx, const char *buf, size_t buf_len, - const char *filename, int flags) +JSValue JS_ParseJSON(JSContext *ctx, const char *buf, size_t buf_len, const char *filename) { JSParseState s1, *s = &s1; JSValue val = JS_UNDEFINED; js_parse_init(ctx, s, buf, buf_len, filename); - s->ext_json = ((flags & JS_PARSE_JSON_EXT) != 0); if (json_next_token(s)) goto fail; val = json_parse_value(s); @@ -43063,12 +42984,6 @@ JSValue JS_ParseJSON2(JSContext *ctx, const char *buf, size_t buf_len, return JS_EXCEPTION; } -JSValue JS_ParseJSON(JSContext *ctx, const char *buf, size_t buf_len, - const char *filename) -{ - return JS_ParseJSON2(ctx, buf, buf_len, filename, 0); -} - static JSValue internalize_json_property(JSContext *ctx, JSValueConst holder, JSAtom name, JSValueConst reviver) { diff --git a/quickjs.h b/quickjs.h index 13d7a64..bb7e81b 100644 --- a/quickjs.h +++ b/quickjs.h @@ -777,9 +777,6 @@ void *JS_GetOpaque2(JSContext *ctx, JSValueConst obj, JSClassID class_id); /* 'buf' must be zero terminated i.e. buf[buf_len] = '\0'. */ JSValue JS_ParseJSON(JSContext *ctx, const char *buf, size_t buf_len, const char *filename); -#define JS_PARSE_JSON_EXT (1 << 0) /* allow extended JSON */ -JSValue JS_ParseJSON2(JSContext *ctx, const char *buf, size_t buf_len, - const char *filename, int flags); JSValue JS_JSONStringify(JSContext *ctx, JSValueConst obj, JSValueConst replacer, JSValueConst space0); diff --git a/tests/test_std.js b/tests/test_std.js index 362606e..7e6ff43 100644 --- a/tests/test_std.js +++ b/tests/test_std.js @@ -104,7 +104,7 @@ function test_getline() f.close(); } - + function test_popen() { var str, f, fname = "tmp_file.txt"; @@ -127,20 +127,6 @@ function test_popen() os.remove(fname); } -function test_ext_json() -{ - var expected, input, obj; - expected = '{"x":false,"y":true,"z2":null,"a":[1,8,160],"s":"str"}'; - input = `{ "x":false, /*comments are allowed */ - "y":true, // also a comment - z2:null, // unquoted property names - "a":[+1,0o10,0xa0,], // plus prefix, octal, hexadecimal - "s":"str",} // trailing comma in objects and arrays - `; - obj = std.parseExtJSON(input); - assert(JSON.stringify(obj), expected); -} - function test_os() { var fd, fpath, fname, fdir, buf, buf2, i, files, err, fdate, st, link_path; @@ -283,4 +269,3 @@ test_popen(); test_os(); !isWin && test_os_exec(); test_timer(); -test_ext_json();