summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2024-07-02 22:23:05 +0800
committerGitHub <[email protected]>2024-07-02 22:23:05 +0800
commitcc13475cd3157afeceea81f0ee05d7aee358e197 (patch)
treec6062d4d40208a1c6f3592d7e3982a750d253920
parent59327827e900ee5b61abba74e85d6081933d2a5a (diff)
parent563923795457256a71b5b4f97bb6e7fe2292219b (diff)
Merge pull request #5293 from xmake-io/json
Improve pure json support
-rw-r--r--core/src/lua-cjson/xmake.lua2
-rwxr-xr-xtests/modules/json/test.lua70
-rw-r--r--xmake/core/base/json.lua54
-rw-r--r--xmake/core/sandbox/modules/import/core/base/json.lua1
4 files changed, 90 insertions, 37 deletions
diff --git a/core/src/lua-cjson/xmake.lua b/core/src/lua-cjson/xmake.lua
index e4206c9fc..79f07d656 100644
--- a/core/src/lua-cjson/xmake.lua
+++ b/core/src/lua-cjson/xmake.lua
@@ -14,8 +14,6 @@ target("lua-cjson")
add_defines("NDEBUG", "USE_INTERNAL_FPCONV")
add_defines("XM_CONFIG_API_HAVE_LUA_CJSON", {public = true})
if is_plat("windows") then
- -- Windows sprintf()/strtod() handle NaN/inf differently. Not supported.
- add_defines("DISABLE_INVALID_NUMBERS")
add_defines("inline=__inline")
end
diff --git a/tests/modules/json/test.lua b/tests/modules/json/test.lua
index 901546259..a09f0918a 100755
--- a/tests/modules/json/test.lua
+++ b/tests/modules/json/test.lua
@@ -1,22 +1,62 @@
import("core.base.json")
--- test decode
+local json_null = json.null
+local json_pure_null = json.purenull
+
+function json_decode(jsonstr)
+ return json.decode(jsonstr)
+end
+
+function json_encode(luatable)
+ return json.encode(luatable)
+end
+
+function json_pure_decode(jsonstr)
+ return json.decode(jsonstr, {pure = true})
+end
+
+function json_pure_encode(luatable)
+ return json.encode(luatable, {pure = true})
+end
+
function test_json_decode(t)
- t:are_equal(json.decode('{}'), {})
- t:are_equal(json.decode('[]'), {})
- t:are_equal(json.is_marked_as_array(json.decode('[]')), true)
- t:are_equal(not json.is_marked_as_array(json.decode('{}')), true)
- t:are_equal(json.decode('{"a":1, "b":"2", "c":true, "d":false, "e":null, "f":[]}'), {a = 1, b = "2", c = true, d = false, e = json.null, f = {}})
- t:are_equal(json.decode('{"a":[], "b":[1,2], "c":{"a":1}}'), {a = {}, b = {1,2}, c = {a = 1}})
- t:are_equal(json.decode('[1,"2"]'), {1, "2"})
- t:are_equal(json.decode('[1,"2", {"a":1, "b":true}]'), {1, "2", {a = 1, b = true}})
+ t:are_equal(json_decode('{}'), {})
+ t:are_equal(json_decode('[]'), {})
+ t:are_equal(json.is_marked_as_array(json_decode('[]')), true)
+ t:are_equal(not json.is_marked_as_array(json_decode('{}')), true)
+ t:are_equal(json_decode('{"a":1, "b":"2", "c":true, "d":false, "e":null, "f":[]}'), {a = 1, b = "2", c = true, d = false, e = json_null, f = {}})
+ t:are_equal(json_decode('{"a":[], "b":[1,2], "c":{"a":1}}'), {a = {}, b = {1,2}, c = {a = 1}})
+ t:are_equal(json_decode('[1,"2"]'), {1, "2"})
+ t:are_equal(json_decode('[1,"2", {"a":1, "b":true}]'), {1, "2", {a = 1, b = true}})
+ t:are_equal(json_decode('[1,0xa,0xdeadbeef, 0xffffffff,-1]'), {1, 0xa, 0xdeadbeef, 0xffffffff, -1})
end
--- test encode
function test_json_encode(t)
- t:are_equal(json.encode({}), '{}')
- t:are_equal(json.encode(json.mark_as_array({})), '[]')
- t:are_equal(json.encode({json.null, 1, "2", false, true}), '[null,1,"2",false,true]')
- t:are_equal(json.encode({1, "2", {a = 1}}), '[1,"2",{"a":1}]')
- t:are_equal(json.encode({1, "2", {b = true}}), '[1,"2",{"b":true}]')
+ t:are_equal(json_encode({}), '{}')
+ t:are_equal(json_encode(json.mark_as_array({})), '[]')
+ t:are_equal(json_encode({json_null, 1, "2", false, true}), '[null,1,"2",false,true]')
+ t:are_equal(json_encode({1, "2", {a = 1}}), '[1,"2",{"a":1}]')
+ t:are_equal(json_encode({1, "2", {b = true}}), '[1,"2",{"b":true}]')
+ t:are_equal(json_encode(json.mark_as_array({1, 0xa, 0xdeadbeef, 0xffffffff, -1})), '[1,10,3735928559,4294967295,-1]')
+end
+
+function test_pure_json_decode(t)
+ t:are_equal(json_pure_decode('{}'), {})
+ t:are_equal(json_pure_decode('[]'), {})
+ t:are_equal(json.is_marked_as_array(json_pure_decode('[]')), true)
+ t:are_equal(not json.is_marked_as_array(json_pure_decode('{}')), true)
+ t:are_equal(json_pure_decode('{"a":1, "b":"2", "c":true, "d":false, "e":null, "f":[]}'), {a = 1, b = "2", c = true, d = false, e = json_pure_null, f = {}})
+ t:are_equal(json_pure_decode('{"a":[], "b":[1,2], "c":{"a":1}}'), {a = {}, b = {1,2}, c = {a = 1}})
+ t:are_equal(json_pure_decode('[1,"2"]'), {1, "2"})
+ t:are_equal(json_pure_decode('[1,"2", {"a":1, "b":true}]'), {1, "2", {a = 1, b = true}})
+ t:are_equal(json_pure_decode('[1,0xa,0xdeadbeef, 0xffffffff,-1]'), {1, 0xa, 0xdeadbeef, 0xffffffff, -1})
+end
+
+function test_pure_json_encode(t)
+ t:are_equal(json_pure_encode({}), '{}')
+ t:are_equal(json_pure_encode(json.mark_as_array({})), '[]')
+ t:are_equal(json_pure_encode({json_pure_null, 1, "2", false, true}), '[null,1,"2",false,true]')
+ t:are_equal(json_pure_encode({1, "2", {a = 1}}), '[1,"2",{"a":1}]')
+ t:are_equal(json_pure_encode({1, "2", {b = true}}), '[1,"2",{"b":true}]')
+ t:are_equal(json_pure_encode(json.mark_as_array({1, 0xa, 0xdeadbeef, 0xffffffff, -1})), '[1,10,3735928559,4294967295,-1]')
end
diff --git a/xmake/core/base/json.lua b/xmake/core/base/json.lua
index 4c619e69a..3c84642c6 100644
--- a/xmake/core/base/json.lua
+++ b/xmake/core/base/json.lua
@@ -27,24 +27,25 @@ local os = require("base/os")
local utils = require("base/utils")
-- export null
+json.purenull = {}
+setmetatable(json.purenull, {
+ __is_json_null = true,
+ __eq = function (obj)
+ if type(obj) == "table" then
+ local mt = getmetatable(obj)
+ if mt and mt.__is_json_null then
+ return true
+ end
+ end
+ return false
+ end,
+ __tostring = function()
+ return "null"
+ end})
if cjson then
json.null = cjson.null
else
- json.null = {}
- setmetatable(json.null, {
- __is_json_null = true,
- __eq = function (obj)
- if type(obj) == "table" then
- local mt = getmetatable(obj)
- if mt and mt.__is_json_null then
- return true
- end
- end
- return false
- end,
- __tostring = function()
- return "null"
- end})
+ json.null = json.purenull
end
function json._pure_kind_of(obj)
@@ -54,7 +55,7 @@ function json._pure_kind_of(obj)
if json.is_marked_as_array(obj) then
return "array"
end
- if obj == json.null then
+ if obj == json.purenull then
return "nil"
end
local i = 1
@@ -116,7 +117,12 @@ function json._pure_parse_str_val(str, pos, val)
end
function json._pure_parse_num_val(str, pos)
- local num_str = str:match('^-?%d+%.?%d*[eE]?[+-]?%d*', pos)
+ local num_str
+ if str:sub(pos, pos + 1) == "0x" then
+ num_str = str:match('^-?0[xX][0-9a-fA-F]+', pos)
+ else
+ num_str = str:match('^-?%d+%.?%d*[eE]?[+-]?%d*', pos)
+ end
local val = tonumber(num_str)
if not val then
os.raise("error parsing number at position %d", pos)
@@ -212,7 +218,7 @@ function json._pure_parse(str, pos, end_delim)
-- end of an object or array.
return nil, pos + 1
else
- local literals = {["true"] = true, ["false"] = false, ["null"] = json.null}
+ local literals = {["true"] = true, ["false"] = false, ["null"] = json.purenull}
for lit_str, lit_val in pairs(literals) do
local lit_end = pos + #lit_str - 1
if str:sub(pos, lit_end) == lit_str then
@@ -256,7 +262,11 @@ end
-- @return the lua table
--
function json.decode(jsonstr, opt)
- local ok, luatable_or_errors = utils.trycall(cjson and cjson.decode or json._pure_decode, nil, jsonstr)
+ local decode = cjson and cjson.decode or json._pure_decode
+ if opt and opt.pure then
+ decode = json._pure_decode
+ end
+ local ok, luatable_or_errors = utils.trycall(decode, nil, jsonstr)
if not ok then
return nil, string.format("decode json failed, %s", luatable_or_errors)
end
@@ -271,7 +281,11 @@ end
-- @return the json string
--
function json.encode(luatable, opt)
- local ok, jsonstr_or_errors = utils.trycall(cjson and cjson.encode or json._pure_encode, nil, luatable)
+ local encode = cjson and cjson.encode or json._pure_encode
+ if opt and opt.pure then
+ encode = json._pure_encode
+ end
+ local ok, jsonstr_or_errors = utils.trycall(encode, nil, luatable)
if not ok then
return nil, string.format("encode json failed, %s", jsonstr_or_errors)
end
diff --git a/xmake/core/sandbox/modules/import/core/base/json.lua b/xmake/core/sandbox/modules/import/core/base/json.lua
index ed551993d..68f70a331 100644
--- a/xmake/core/sandbox/modules/import/core/base/json.lua
+++ b/xmake/core/sandbox/modules/import/core/base/json.lua
@@ -27,6 +27,7 @@ local raise = require("sandbox/modules/raise")
-- inherit some builtin interfaces
sandbox_core_base_json.null = json.null
+sandbox_core_base_json.purenull = json.purenull
sandbox_core_base_json.mark_as_array = json.mark_as_array
sandbox_core_base_json.is_marked_as_array = json.is_marked_as_array