From c92a0248406711b5f1d6e27a22f45bab00dfc6b7 Mon Sep 17 00:00:00 2001 From: ruki Date: Thu, 19 Jan 2023 23:12:14 +0800 Subject: improve lua-cjson --- core/src/lua-cjson/xmake.lua | 1 + core/src/lua-cjson/xmake.sh | 1 + core/src/xmake/engine.c | 2 ++ core/src/xmake/xmake.sh | 13 ++++++++++++- core/xmake.sh | 22 +++++++++++++++++++--- 5 files changed, 35 insertions(+), 4 deletions(-) diff --git a/core/src/lua-cjson/xmake.lua b/core/src/lua-cjson/xmake.lua index 74406d67e..fa7855150 100644 --- a/core/src/lua-cjson/xmake.lua +++ b/core/src/lua-cjson/xmake.lua @@ -8,6 +8,7 @@ target("lua-cjson") add_files("lua-cjson/*.c|fpconv.c") -- Use internal strtod() / g_fmt() code for performance and disable multi-thread 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") diff --git a/core/src/lua-cjson/xmake.sh b/core/src/lua-cjson/xmake.sh index 134173051..f7d8b94b2 100755 --- a/core/src/lua-cjson/xmake.sh +++ b/core/src/lua-cjson/xmake.sh @@ -17,4 +17,5 @@ target "lua_cjson" add_files "lua-cjson/g_fmt.c" # Use internal strtod() / g_fmt() code for performance and disable multi-thread add_defines "NDEBUG" "USE_INTERNAL_FPCONV" + add_defines "XM_CONFIG_API_HAVE_LUA_CJSON" "{public}" diff --git a/core/src/xmake/engine.c b/core/src/xmake/engine.c index 0ecafd064..a0a019c33 100644 --- a/core/src/xmake/engine.c +++ b/core/src/xmake/engine.c @@ -1109,9 +1109,11 @@ xm_engine_ref_t xm_engine_init(tb_char_t const* name, xm_engine_lni_initalizer_c xm_lua_curses_register(engine->lua, "curses"); #endif +#ifdef XM_CONFIG_API_HAVE_LUA_CJSON // bind cjson luaopen_cjson(engine->lua); lua_setglobal(engine->lua, "cjson"); +#endif // init host xm_engine_init_host(engine); diff --git a/core/src/xmake/xmake.sh b/core/src/xmake/xmake.sh index f3fe92aa1..be0f6f911 100755 --- a/core/src/xmake/xmake.sh +++ b/core/src/xmake/xmake.sh @@ -5,7 +5,7 @@ target "xmake" set_default false # add deps - local libs="lua_cjson lz4 sv tbox" + local libs="lz4 sv tbox" for lib in $libs; do if has_config "$lib"; then add_options "$lib" "{public}" @@ -14,10 +14,21 @@ target "xmake" fi done if is_config "runtime" "luajit" && has_config "luajit"; then + if has_config "lua_cjson"; then + add_options "lua_cjson" "{public}" + else + add_deps "lua_cjson" + fi add_options "luajit" "{public}" elif has_config "lua"; then + if ! has_config "lua_cjson"; then + add_deps "lua_cjson" + fi add_options "lua" "{public}" else + if ! has_config "lua_cjson"; then + add_deps "lua_cjson" + fi add_deps "lua" fi diff --git a/core/xmake.sh b/core/xmake.sh index 759981225..c9e0db8a2 100755 --- a/core/xmake.sh +++ b/core/xmake.sh @@ -77,7 +77,8 @@ option_end # the lua-cjson option option "lua_cjson" - add_links "lua5.1-cjson" + add_defines "XM_CONFIG_API_HAVE_LUA_CJSON" + before_check "option_find_lua_cjson" add_csnippets " int luaopen_cjson(void *l);\n void test() {\n @@ -86,6 +87,17 @@ void test() {\n " option_end +option_find_lua_cjson() { + local ldflags="" + option "lua_cjson" + ldflags=`pkg-config --libs luajit 2>/dev/null` + if test_nz "${ldflags}"; then + ldflags="-llua5.1-cjson ${ldflags}" + fi + add_ldflags "${ldflags}" + option_end +} + # the lua option option "lua" add_cfuncs "lua_pushstring" @@ -116,8 +128,13 @@ option_end option_find_luajit() { local ldflags="" + local cflags="" option "luajit" - add_cflags `pkg-config --cflags luajit 2>/dev/null` + cflags=`pkg-config --cflags luajit 2>/dev/null` + if test_z "${cflags}"; then + cflags="/usr/include/luajit-2.1" + fi + add_cflags "${cflags}" ldflags=`pkg-config --libs luajit 2>/dev/null` if test_z "${ldflags}"; then ldflags="-lluajit" @@ -209,4 +226,3 @@ if ! has_config "tbox"; then fi includes "src/xmake" includes "src/demo" - -- cgit v1.3.1 From 802ddfa09619d26f4446c046c365545684ff5fb4 Mon Sep 17 00:00:00 2001 From: ruki Date: Thu, 19 Jan 2023 23:12:23 +0800 Subject: update comment --- core/xmake.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/xmake.sh b/core/xmake.sh index c9e0db8a2..8e20425b2 100755 --- a/core/xmake.sh +++ b/core/xmake.sh @@ -75,7 +75,7 @@ void test() {\n }" option_end -# the lua-cjson option +# the lua-cjson option, only for luajit/lua5.1 option "lua_cjson" add_defines "XM_CONFIG_API_HAVE_LUA_CJSON" before_check "option_find_lua_cjson" -- cgit v1.3.1 From 216be81132314c11d960fc998f2919345f3a7630 Mon Sep 17 00:00:00 2001 From: ruki Date: Thu, 19 Jan 2023 23:16:04 +0800 Subject: improve xmake.sh --- core/src/xmake/xmake.sh | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/core/src/xmake/xmake.sh b/core/src/xmake/xmake.sh index be0f6f911..59ec6b503 100755 --- a/core/src/xmake/xmake.sh +++ b/core/src/xmake/xmake.sh @@ -13,23 +13,26 @@ target "xmake" add_deps "$lib" fi done - if is_config "runtime" "luajit" && has_config "luajit"; then + if is_config "runtime" "luajit"; then if has_config "lua_cjson"; then add_options "lua_cjson" "{public}" else add_deps "lua_cjson" fi - add_options "luajit" "{public}" - elif has_config "lua"; then - if ! has_config "lua_cjson"; then - add_deps "lua_cjson" + if has_config "luajit"; then + add_options "luajit" "{public}" + else + add_deps "luajit" fi - add_options "lua" "{public}" else if ! has_config "lua_cjson"; then add_deps "lua_cjson" fi - add_deps "lua" + if has_config "lua"; then + add_options "lua" "{public}" + else + add_deps "lua" + fi fi # add options -- cgit v1.3.1 From 50e02b189f625a9a6de542545d5c864addfa4ce0 Mon Sep 17 00:00:00 2001 From: ruki Date: Thu, 19 Jan 2023 23:16:18 +0800 Subject: improve xmake.sh --- core/src/xmake/xmake.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/core/src/xmake/xmake.sh b/core/src/xmake/xmake.sh index 59ec6b503..ce6ec0481 100755 --- a/core/src/xmake/xmake.sh +++ b/core/src/xmake/xmake.sh @@ -25,9 +25,7 @@ target "xmake" add_deps "luajit" fi else - if ! has_config "lua_cjson"; then - add_deps "lua_cjson" - fi + add_deps "lua_cjson" if has_config "lua"; then add_options "lua" "{public}" else -- cgit v1.3.1 From 91da9c460373a6a3b43a71fc75493df0e2ae5c2e Mon Sep 17 00:00:00 2001 From: ruki Date: Thu, 19 Jan 2023 23:16:39 +0800 Subject: improve xmake.sh --- core/xmake.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/xmake.sh b/core/xmake.sh index 8e20425b2..9ca61aae7 100755 --- a/core/xmake.sh +++ b/core/xmake.sh @@ -212,7 +212,7 @@ if ! has_config "lua"; then includes "src/lua" fi fi -if ! has_config "lua_cjson"; then +if ! has_config "lua_cjson" || is_config "runtime" "lua"; then includes "src/lua-cjson" fi if ! has_config "lz4"; then -- cgit v1.3.1 From cb91361e8e1af7591a6c4eece6b8c7022961a610 Mon Sep 17 00:00:00 2001 From: ruki Date: Thu, 19 Jan 2023 23:17:10 +0800 Subject: add external option --- core/src/xmake/xmake.sh | 8 ++++---- core/xmake.sh | 39 ++++++++++++++++++++++----------------- 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/core/src/xmake/xmake.sh b/core/src/xmake/xmake.sh index ce6ec0481..d4195c2d0 100755 --- a/core/src/xmake/xmake.sh +++ b/core/src/xmake/xmake.sh @@ -9,26 +9,26 @@ target "xmake" for lib in $libs; do if has_config "$lib"; then add_options "$lib" "{public}" - else + elif ! has_config "external"; then add_deps "$lib" fi done if is_config "runtime" "luajit"; then if has_config "lua_cjson"; then add_options "lua_cjson" "{public}" - else + elif ! has_config "external"; then add_deps "lua_cjson" fi if has_config "luajit"; then add_options "luajit" "{public}" - else + elif ! has_config "external"; then add_deps "luajit" fi else add_deps "lua_cjson" if has_config "lua"; then add_options "lua" "{public}" - else + elif ! has_config "external"; then add_deps "lua" fi fi diff --git a/core/xmake.sh b/core/xmake.sh index 9ca61aae7..d093af445 100755 --- a/core/xmake.sh +++ b/core/xmake.sh @@ -35,6 +35,9 @@ fi # the runtime option, lua or luajit option "runtime" "Use luajit or lua runtime" "lua" +# always use external dependencies +option "external" "Always use external dependencies" false + # the readline option option "readline" add_links "readline" @@ -205,24 +208,26 @@ option_find_tbox() { } # add projects -if ! has_config "lua"; then - if is_config "runtime" "luajit"; then - includes "src/luajit" - else - includes "src/lua" +if ! has_config "external"; then + if ! has_config "lua"; then + if is_config "runtime" "luajit"; then + includes "src/luajit" + else + includes "src/lua" + fi + fi + if ! has_config "lua_cjson" || is_config "runtime" "lua"; then + includes "src/lua-cjson" + fi + if ! has_config "lz4"; then + includes "src/lz4" + fi + if ! has_config "sv"; then + includes "src/sv" + fi + if ! has_config "tbox"; then + includes "src/tbox" fi -fi -if ! has_config "lua_cjson" || is_config "runtime" "lua"; then - includes "src/lua-cjson" -fi -if ! has_config "lz4"; then - includes "src/lz4" -fi -if ! has_config "sv"; then - includes "src/sv" -fi -if ! has_config "tbox"; then - includes "src/tbox" fi includes "src/xmake" includes "src/demo" -- cgit v1.3.1 From 693a5383c31b1c5809fcc48bb17b834c52c50668 Mon Sep 17 00:00:00 2001 From: ruki Date: Thu, 19 Jan 2023 23:17:28 +0800 Subject: fix external option --- core/src/xmake/xmake.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/src/xmake/xmake.sh b/core/src/xmake/xmake.sh index d4195c2d0..709ff525b 100755 --- a/core/src/xmake/xmake.sh +++ b/core/src/xmake/xmake.sh @@ -25,7 +25,9 @@ target "xmake" add_deps "luajit" fi else - add_deps "lua_cjson" + if ! has_config "external"; then + add_deps "lua_cjson" + fi if has_config "lua"; then add_options "lua" "{public}" elif ! has_config "external"; then -- cgit v1.3.1 From b091805cdaf6225d84b85039c1d19b4133be6f0d Mon Sep 17 00:00:00 2001 From: ruki Date: Thu, 19 Jan 2023 23:19:07 +0800 Subject: wrap json --- xmake/core/base/json.lua | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/xmake/core/base/json.lua b/xmake/core/base/json.lua index e83f6b320..fa2e2b2c7 100644 --- a/xmake/core/base/json.lua +++ b/xmake/core/base/json.lua @@ -20,14 +20,23 @@ -- define module: json local json = json or {} -local cjson = cjson or {} -- load modules local io = require("base/io") local utils = require("base/utils") -- export null -json.null = cjson.null +json.null = cjson and cjson.null or {} + +-- decode json string using pure lua +function json._pure_decode(jsonstr, opt) + return {} +end + +-- encode json string using pua lua +function json._pure_encode(luatable, opt) + return "" +end -- support empty array -- @see https://github.com/mpx/lua-cjson/issues/11 @@ -51,7 +60,7 @@ end -- @return the lua table -- function json.decode(jsonstr, opt) - local ok, luatable_or_errors = utils.trycall(cjson.decode, nil, jsonstr) + local ok, luatable_or_errors = utils.trycall(cjson and cjson.decode or json._pure_decode, nil, jsonstr) if not ok then return nil, string.format("decode json failed, %s", luatable_or_errors) end @@ -66,7 +75,7 @@ end -- @return the json string -- function json.encode(luatable, opt) - local ok, jsonstr_or_errors = utils.trycall(cjson.encode, nil, luatable) + local ok, jsonstr_or_errors = utils.trycall(cjson and cjson.encode or json._pure_encode, nil, luatable) if not ok then return nil, string.format("encode json failed, %s", jsonstr_or_errors) end -- cgit v1.3.1 From 1ac6f521c877565eecfe4d6bdc583b93c9e747a9 Mon Sep 17 00:00:00 2001 From: ruki Date: Thu, 19 Jan 2023 23:19:17 +0800 Subject: disable cjson --- xmake/core/base/json.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/xmake/core/base/json.lua b/xmake/core/base/json.lua index fa2e2b2c7..672a5e06e 100644 --- a/xmake/core/base/json.lua +++ b/xmake/core/base/json.lua @@ -20,6 +20,7 @@ -- define module: json local json = json or {} +cjson = nil -- TODO disable it for testing -- load modules local io = require("base/io") -- cgit v1.3.1 From 8ecb7b7e3b84537c9778fa06c2b74802c34eb416 Mon Sep 17 00:00:00 2001 From: ruki Date: Thu, 19 Jan 2023 23:22:59 +0800 Subject: add pure json --- xmake/core/base/json.lua | 171 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 169 insertions(+), 2 deletions(-) diff --git a/xmake/core/base/json.lua b/xmake/core/base/json.lua index 672a5e06e..ff2b7add0 100644 --- a/xmake/core/base/json.lua +++ b/xmake/core/base/json.lua @@ -24,19 +24,186 @@ cjson = nil -- TODO disable it for testing -- load modules local io = require("base/io") +local os = require("base/os") local utils = require("base/utils") -- export null json.null = cjson and cjson.null or {} +function json._pure_kind_of(obj) + if type(obj) ~= 'table' then + return type(obj) + end + local i = 1 + for _ in pairs(obj) do + if obj[i] ~= nil then + i = i + 1 + else + return 'table' + end + end + if i == 1 then + return 'table' + else + return 'array' + end +end + +function json._pure_escape_str(s) + local in_char = {'\\', '"', '/', '\b', '\f', '\n', '\r', '\t'} + local out_char = {'\\', '"', '/', 'b', 'f', 'n', 'r', 't'} + for i, c in ipairs(in_char) do + s = s:gsub(c, '\\' .. out_char[i]) + end + return s +end + +-- returns pos, did_find; there are two cases: +-- 1. Delimiter found: pos = pos after leading space + delim; did_find = true. +-- 2. Delimiter not found: pos = pos after leading space; did_find = false. +-- this throws an error if err_if_missing is true and the delim is not found. +function json._pure_skip_delim(str, pos, delim, err_if_missing) + pos = pos + #str:match('^%s*', pos) + if str:sub(pos, pos) ~= delim then + if err_if_missing then + os.raise('expected ' .. delim .. ' near position ' .. pos) + end + return pos, false + end + return pos + 1, true +end + +-- expects the given pos to be the first character after the opening quote. +-- returns val, pos; the returned pos is after the closing quote character. +function json._pure_parse_str_val(str, pos, val) + val = val or '' + local early_end_error = 'end of input found while parsing string.' + if pos > #str then + os.raise(early_end_error) + end + local c = str:sub(pos, pos) + if c == '"' then + return val, pos + 1 + end + if c ~= '\\' then + return json._pure_parse_str_val(str, pos + 1, val .. c) + end + -- We must have a \ character. + local esc_map = {b = '\b', f = '\f', n = '\n', r = '\r', t = '\t'} + local nextc = str:sub(pos + 1, pos + 1) + if not nextc then + os.raise(early_end_error) + end + return json._pure_parse_str_val(str, pos + 2, val .. (esc_map[nextc] or nextc)) +end + +-- returns val, pos; the returned pos is after the number's final character. +function json._pure_parse_num_val(str, pos) + local num_str = str:match('^-?%d+%.?%d*[eE]?[+-]?%d*', pos) + local val = tonumber(num_str) + if not val then + os.raise('error parsing number at position ' .. pos .. '.') + end + return val, pos + #num_str +end + +function json._pure_stringify(obj, as_key) + local s = {} + local kind = json._pure_kind_of(obj) + if kind == 'array' then + if as_key then + os.raise('can\'t encode array as key.') + end + s[#s + 1] = '[' + for i, val in ipairs(obj) do + if i > 1 then s[#s + 1] = ', ' end + s[#s + 1] = json._pure_stringify(val) + end + s[#s + 1] = ']' + elseif kind == 'table' then + if as_key then + os.raise('can\'t encode table as key.') + end + s[#s + 1] = '{' + for k, v in pairs(obj) do + if #s > 1 then s[#s + 1] = ', ' end + s[#s + 1] = json._pure_stringify(k, true) + s[#s + 1] = ':' + s[#s + 1] = json._pure_stringify(v) + end + s[#s + 1] = '}' + elseif kind == 'string' then + return '"' .. json._pure_escape_str(obj) .. '"' + elseif kind == 'number' then + if as_key then + return '"' .. tostring(obj) .. '"' + end + return tostring(obj) + elseif kind == 'boolean' then + return tostring(obj) + elseif kind == 'nil' then + return 'null' + else + os.raise('Unjsonifiable type: ' .. kind .. '.') + end + return table.concat(s) +end + +function json._pure_parse(str, pos, end_delim) + pos = pos or 1 + if pos > #str then + os.raise('reached unexpected end of input.') + end + -- skip whitespace. + local pos = pos + #str:match('^%s*', pos) + local first = str:sub(pos, pos) + if first == '{' then + local obj, key, delim_found = {}, true, true + pos = pos + 1 + while true do + key, pos = json._pure_parse(str, pos, '}') + if key == nil then return obj, pos end + if not delim_found then os.raise('comma missing between object items.') end + pos = json._pure_skip_delim(str, pos, ':', true) -- true -> error if missing. + obj[key], pos = json._pure_parse(str, pos) + pos, delim_found = json._pure_skip_delim(str, pos, ',') + end + elseif first == '[' then + local arr, val, delim_found = {}, true, true + pos = pos + 1 + while true do + val, pos = json._pure_parse(str, pos, ']') + if val == nil then return arr, pos end + if not delim_found then os.raise('comma missing between array items.') end + arr[#arr + 1] = val + pos, delim_found = json._pure_skip_delim(str, pos, ',') + end + elseif first == '"' then + return json._pure_parse_str_val(str, pos + 1) + elseif first == '-' or first:match('%d') then + return json._pure_parse_num_val(str, pos) + elseif first == end_delim then + -- end of an object or array. + return nil, pos + 1 + else + local literals = {['true'] = true, ['false'] = false, ['null'] = json.null} + 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 return lit_val, lit_end + 1 end + end + local pos_info_str = 'position ' .. pos .. ': ' .. str:sub(pos, pos + 10) + os.raise('invalid json syntax starting at ' .. pos_info_str) + end +end + -- decode json string using pure lua function json._pure_decode(jsonstr, opt) - return {} + return json._pure_parse(jsonstr) end -- encode json string using pua lua function json._pure_encode(luatable, opt) - return "" + return json._pure_stringify(luatable) end -- support empty array -- cgit v1.3.1 From abf56ce85047cee83c245f56b40608368007e4a5 Mon Sep 17 00:00:00 2001 From: ruki Date: Thu, 19 Jan 2023 23:24:54 +0800 Subject: mark as array --- xmake/core/base/json.lua | 46 ++++++++++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/xmake/core/base/json.lua b/xmake/core/base/json.lua index ff2b7add0..45b629393 100644 --- a/xmake/core/base/json.lua +++ b/xmake/core/base/json.lua @@ -31,21 +31,24 @@ local utils = require("base/utils") json.null = cjson and cjson.null or {} function json._pure_kind_of(obj) - if type(obj) ~= 'table' then + if type(obj) ~= "table" then return type(obj) end + if json.is_marked_as_array(obj) then + return "array" + end local i = 1 for _ in pairs(obj) do if obj[i] ~= nil then i = i + 1 else - return 'table' + return "table" end end if i == 1 then - return 'table' + return "table" else - return 'array' + return "array" end end @@ -110,7 +113,7 @@ end function json._pure_stringify(obj, as_key) local s = {} local kind = json._pure_kind_of(obj) - if kind == 'array' then + if kind == "array" then if as_key then os.raise('can\'t encode array as key.') end @@ -120,7 +123,7 @@ function json._pure_stringify(obj, as_key) s[#s + 1] = json._pure_stringify(val) end s[#s + 1] = ']' - elseif kind == 'table' then + elseif kind == "table" then if as_key then os.raise('can\'t encode table as key.') end @@ -132,19 +135,19 @@ function json._pure_stringify(obj, as_key) s[#s + 1] = json._pure_stringify(v) end s[#s + 1] = '}' - elseif kind == 'string' then + elseif kind == "string" then return '"' .. json._pure_escape_str(obj) .. '"' - elseif kind == 'number' then + elseif kind == "number" then if as_key then return '"' .. tostring(obj) .. '"' end return tostring(obj) - elseif kind == 'boolean' then + elseif kind == "boolean" then return tostring(obj) - elseif kind == 'nil' then + elseif kind == "nil" then return 'null' else - os.raise('Unjsonifiable type: ' .. kind .. '.') + os.raise('unjsonifiable type: ' .. kind .. '.') end return table.concat(s) end @@ -162,19 +165,28 @@ function json._pure_parse(str, pos, end_delim) pos = pos + 1 while true do key, pos = json._pure_parse(str, pos, '}') - if key == nil then return obj, pos end - if not delim_found then os.raise('comma missing between object items.') end + if key == nil then + return obj, pos + end + if not delim_found then + os.raise('comma missing between object items.') + end pos = json._pure_skip_delim(str, pos, ':', true) -- true -> error if missing. obj[key], pos = json._pure_parse(str, pos) pos, delim_found = json._pure_skip_delim(str, pos, ',') end elseif first == '[' then local arr, val, delim_found = {}, true, true + json.mark_as_array(arr) pos = pos + 1 while true do val, pos = json._pure_parse(str, pos, ']') - if val == nil then return arr, pos end - if not delim_found then os.raise('comma missing between array items.') end + if val == nil then + return arr, pos + end + if not delim_found then + os.raise('comma missing between array items.') + end arr[#arr + 1] = val pos, delim_found = json._pure_skip_delim(str, pos, ',') end @@ -189,7 +201,9 @@ function json._pure_parse(str, pos, end_delim) local literals = {['true'] = true, ['false'] = false, ['null'] = json.null} 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 return lit_val, lit_end + 1 end + if str:sub(pos, lit_end) == lit_str then + return lit_val, lit_end + 1 + end end local pos_info_str = 'position ' .. pos .. ': ' .. str:sub(pos, pos + 10) os.raise('invalid json syntax starting at ' .. pos_info_str) -- cgit v1.3.1 From e8228184e4325be6adb4d44e2a21189124807fc8 Mon Sep 17 00:00:00 2001 From: ruki Date: Thu, 19 Jan 2023 23:26:35 +0800 Subject: improve json.null --- xmake/core/base/json.lua | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/xmake/core/base/json.lua b/xmake/core/base/json.lua index 45b629393..dcd3ffaa0 100644 --- a/xmake/core/base/json.lua +++ b/xmake/core/base/json.lua @@ -28,7 +28,25 @@ local os = require("base/os") local utils = require("base/utils") -- export null -json.null = cjson and cjson.null or {} +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}) +end function json._pure_kind_of(obj) if type(obj) ~= "table" then @@ -37,6 +55,9 @@ function json._pure_kind_of(obj) if json.is_marked_as_array(obj) then return "array" end + if obj == json.null then + return "nil" + end local i = 1 for _ in pairs(obj) do if obj[i] ~= nil then @@ -119,7 +140,7 @@ function json._pure_stringify(obj, as_key) end s[#s + 1] = '[' for i, val in ipairs(obj) do - if i > 1 then s[#s + 1] = ', ' end + if i > 1 then s[#s + 1] = ',' end s[#s + 1] = json._pure_stringify(val) end s[#s + 1] = ']' @@ -129,7 +150,7 @@ function json._pure_stringify(obj, as_key) end s[#s + 1] = '{' for k, v in pairs(obj) do - if #s > 1 then s[#s + 1] = ', ' end + if #s > 1 then s[#s + 1] = ',' end s[#s + 1] = json._pure_stringify(k, true) s[#s + 1] = ':' s[#s + 1] = json._pure_stringify(v) @@ -145,7 +166,7 @@ function json._pure_stringify(obj, as_key) elseif kind == "boolean" then return tostring(obj) elseif kind == "nil" then - return 'null' + return "null" else os.raise('unjsonifiable type: ' .. kind .. '.') end @@ -198,7 +219,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.null} 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 -- cgit v1.3.1 From 7efc8fc2f7739f5a6366d01567ea73bc844f886b Mon Sep 17 00:00:00 2001 From: ruki Date: Thu, 19 Jan 2023 23:27:08 +0800 Subject: remove some comments --- xmake/core/base/json.lua | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/xmake/core/base/json.lua b/xmake/core/base/json.lua index dcd3ffaa0..ef33d781b 100644 --- a/xmake/core/base/json.lua +++ b/xmake/core/base/json.lua @@ -82,10 +82,6 @@ function json._pure_escape_str(s) return s end --- returns pos, did_find; there are two cases: --- 1. Delimiter found: pos = pos after leading space + delim; did_find = true. --- 2. Delimiter not found: pos = pos after leading space; did_find = false. --- this throws an error if err_if_missing is true and the delim is not found. function json._pure_skip_delim(str, pos, delim, err_if_missing) pos = pos + #str:match('^%s*', pos) if str:sub(pos, pos) ~= delim then @@ -97,8 +93,6 @@ function json._pure_skip_delim(str, pos, delim, err_if_missing) return pos + 1, true end --- expects the given pos to be the first character after the opening quote. --- returns val, pos; the returned pos is after the closing quote character. function json._pure_parse_str_val(str, pos, val) val = val or '' local early_end_error = 'end of input found while parsing string.' @@ -112,7 +106,8 @@ function json._pure_parse_str_val(str, pos, val) if c ~= '\\' then return json._pure_parse_str_val(str, pos + 1, val .. c) end - -- We must have a \ character. + + -- we must have a \ character. local esc_map = {b = '\b', f = '\f', n = '\n', r = '\r', t = '\t'} local nextc = str:sub(pos + 1, pos + 1) if not nextc then @@ -121,7 +116,6 @@ function json._pure_parse_str_val(str, pos, val) return json._pure_parse_str_val(str, pos + 2, val .. (esc_map[nextc] or nextc)) end --- returns val, pos; the returned pos is after the number's final character. function json._pure_parse_num_val(str, pos) local num_str = str:match('^-?%d+%.?%d*[eE]?[+-]?%d*', pos) local val = tonumber(num_str) -- cgit v1.3.1 From 1f28695dd2044e30766e80bf73b002e9de976c63 Mon Sep 17 00:00:00 2001 From: ruki Date: Thu, 19 Jan 2023 23:27:39 +0800 Subject: format code --- xmake/core/base/json.lua | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/xmake/core/base/json.lua b/xmake/core/base/json.lua index ef33d781b..b99c6eb46 100644 --- a/xmake/core/base/json.lua +++ b/xmake/core/base/json.lua @@ -86,7 +86,7 @@ function json._pure_skip_delim(str, pos, delim, err_if_missing) pos = pos + #str:match('^%s*', pos) if str:sub(pos, pos) ~= delim then if err_if_missing then - os.raise('expected ' .. delim .. ' near position ' .. pos) + os.raise("expected %s near position %d", delim, pos) end return pos, false end @@ -95,7 +95,7 @@ end function json._pure_parse_str_val(str, pos, val) val = val or '' - local early_end_error = 'end of input found while parsing string.' + local early_end_error = "end of input found while parsing string." if pos > #str then os.raise(early_end_error) end @@ -120,7 +120,7 @@ function json._pure_parse_num_val(str, pos) local num_str = str:match('^-?%d+%.?%d*[eE]?[+-]?%d*', pos) local val = tonumber(num_str) if not val then - os.raise('error parsing number at position ' .. pos .. '.') + os.raise("error parsing number at position %d", pos) end return val, pos + #num_str end @@ -130,7 +130,7 @@ function json._pure_stringify(obj, as_key) local kind = json._pure_kind_of(obj) if kind == "array" then if as_key then - os.raise('can\'t encode array as key.') + os.raise("can\'t encode array as key.") end s[#s + 1] = '[' for i, val in ipairs(obj) do @@ -140,7 +140,7 @@ function json._pure_stringify(obj, as_key) s[#s + 1] = ']' elseif kind == "table" then if as_key then - os.raise('can\'t encode table as key.') + os.raise("can\'t encode table as key.") end s[#s + 1] = '{' for k, v in pairs(obj) do @@ -162,7 +162,7 @@ function json._pure_stringify(obj, as_key) elseif kind == "nil" then return "null" else - os.raise('unjsonifiable type: ' .. kind .. '.') + os.raise("unknown type: %s", kind) end return table.concat(s) end @@ -170,7 +170,7 @@ end function json._pure_parse(str, pos, end_delim) pos = pos or 1 if pos > #str then - os.raise('reached unexpected end of input.') + os.raise("reached unexpected end of input.") end -- skip whitespace. local pos = pos + #str:match('^%s*', pos) @@ -184,7 +184,7 @@ function json._pure_parse(str, pos, end_delim) return obj, pos end if not delim_found then - os.raise('comma missing between object items.') + os.raise("comma missing between object items.") end pos = json._pure_skip_delim(str, pos, ':', true) -- true -> error if missing. obj[key], pos = json._pure_parse(str, pos) @@ -200,14 +200,14 @@ function json._pure_parse(str, pos, end_delim) return arr, pos end if not delim_found then - os.raise('comma missing between array items.') + os.raise("comma missing between array items.") end arr[#arr + 1] = val pos, delim_found = json._pure_skip_delim(str, pos, ',') end elseif first == '"' then return json._pure_parse_str_val(str, pos + 1) - elseif first == '-' or first:match('%d') then + elseif first == '-' or first:match("%d") then return json._pure_parse_num_val(str, pos) elseif first == end_delim then -- end of an object or array. @@ -220,8 +220,8 @@ function json._pure_parse(str, pos, end_delim) return lit_val, lit_end + 1 end end - local pos_info_str = 'position ' .. pos .. ': ' .. str:sub(pos, pos + 10) - os.raise('invalid json syntax starting at ' .. pos_info_str) + local pos_info_str = "position " .. pos .. ": " .. str:sub(pos, pos + 10) + os.raise("invalid json syntax starting at " .. pos_info_str) end end -- cgit v1.3.1 From 68398872d2cdee46be82d8b097ee869278a514e7 Mon Sep 17 00:00:00 2001 From: ruki Date: Thu, 19 Jan 2023 23:29:01 +0800 Subject: fix xmake.sh --- core/xmake.sh | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/core/xmake.sh b/core/xmake.sh index d093af445..d464b2862 100755 --- a/core/xmake.sh +++ b/core/xmake.sh @@ -209,14 +209,17 @@ option_find_tbox() { # add projects if ! has_config "external"; then - if ! has_config "lua"; then - if is_config "runtime" "luajit"; then + if is_config "runtime" "luajit"; then + if ! has_config "luajit"; then includes "src/luajit" - else + fi + if ! has_config "lua_cjson"; then + includes "src/lua-cjson" + fi + else + if ! has_config "lua"; then includes "src/lua" fi - fi - if ! has_config "lua_cjson" || is_config "runtime" "lua"; then includes "src/lua-cjson" fi if ! has_config "lz4"; then -- cgit v1.3.1 From 0d836bc3b2351a72f9f28b18fb7a291220825441 Mon Sep 17 00:00:00 2001 From: ruki Date: Thu, 19 Jan 2023 23:30:49 +0800 Subject: fix luajit --- core/src/luajit/xmake.lua | 2 +- core/src/luajit/xmake.sh | 2 +- core/src/xmake/xmake.lua | 7 ++++++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/core/src/luajit/xmake.lua b/core/src/luajit/xmake.lua index 8ad0bf1af..1e6bca80a 100644 --- a/core/src/luajit/xmake.lua +++ b/core/src/luajit/xmake.lua @@ -22,7 +22,7 @@ end local autogendir = path.join("luajit", "autogen", plat, jit and "jit" or "nojit", arch) -- add target -target("lua") +target("luajit") -- make as a static library set_kind("static") diff --git a/core/src/luajit/xmake.sh b/core/src/luajit/xmake.sh index 459da8999..0a0b0002c 100755 --- a/core/src/luajit/xmake.sh +++ b/core/src/luajit/xmake.sh @@ -30,7 +30,7 @@ else fi jit_autogendir="luajit/autogen/${jit_plat}/${jit_dir}/${jit_arch}" -target "lua" +target "luajit" set_kind "static" set_default false set_warnings "all" diff --git a/core/src/xmake/xmake.lua b/core/src/xmake/xmake.lua index e100832ba..d770c129f 100644 --- a/core/src/xmake/xmake.lua +++ b/core/src/xmake/xmake.lua @@ -2,7 +2,12 @@ target("xmake") set_kind("static") -- add deps - add_deps("sv", "lua-cjson", "lua", "lz4", "tbox") + add_deps("sv", "lua-cjson", "lz4", "tbox") + if is_config("runtime", "luajit") then + add_deps("luajit") + else + add_deps("lua") + end if is_plat("windows") and has_config("pdcurses") then add_deps("pdcurses") end -- cgit v1.3.1 From 685000fcb6d6eed642e3b56b345dc25caec999c4 Mon Sep 17 00:00:00 2001 From: ruki Date: Thu, 19 Jan 2023 23:31:25 +0800 Subject: fix xmake.sh --- core/src/lua-cjson/xmake.lua | 6 +++++- core/src/lua-cjson/xmake.sh | 16 +++++++++++----- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/core/src/lua-cjson/xmake.lua b/core/src/lua-cjson/xmake.lua index fa7855150..e4206c9fc 100644 --- a/core/src/lua-cjson/xmake.lua +++ b/core/src/lua-cjson/xmake.lua @@ -1,7 +1,11 @@ target("lua-cjson") set_kind("static") set_warnings("all") - add_deps("lua") + if is_config("runtime", "luajit") then + add_deps("luajit") + else + add_deps("lua") + end if is_plat("windows") then set_languages("c89") end diff --git a/core/src/lua-cjson/xmake.sh b/core/src/lua-cjson/xmake.sh index f7d8b94b2..f3ab17546 100755 --- a/core/src/lua-cjson/xmake.sh +++ b/core/src/lua-cjson/xmake.sh @@ -4,12 +4,18 @@ target "lua_cjson" set_kind "static" set_default false set_warnings "all" - if is_config "runtime" "luajit" && has_config "luajit"; then - add_options "luajit" "{public}" - elif has_config "lua"; then - add_options "lua" "{public}" + if is_config "runtime" "luajit"; then + if has_config "luajit"; then + add_options "luajit" "{public}" + elif ! has_config "external"; then + add_deps "luajit" + fi else - add_deps "lua" + if has_config "lua"; then + add_options "lua" "{public}" + elif ! has_config "external"; then + add_deps "lua" + fi fi add_files "lua-cjson/dtoa.c" add_files "lua-cjson/lua_cjson.c" -- cgit v1.3.1 From b653884db6a9403f3ec8306f49420c5c4f1c660c Mon Sep 17 00:00:00 2001 From: ruki Date: Thu, 19 Jan 2023 23:36:22 +0800 Subject: improve lua-cjson option --- core/src/xmake/xmake.lua | 5 ++++- core/src/xmake/xmake.sh | 11 +++-------- core/xmake.lua | 16 ++++++++++------ core/xmake.sh | 31 +++++-------------------------- 4 files changed, 22 insertions(+), 41 deletions(-) diff --git a/core/src/xmake/xmake.lua b/core/src/xmake/xmake.lua index d770c129f..d4e11040e 100644 --- a/core/src/xmake/xmake.lua +++ b/core/src/xmake/xmake.lua @@ -2,12 +2,15 @@ target("xmake") set_kind("static") -- add deps - add_deps("sv", "lua-cjson", "lz4", "tbox") + add_deps("sv", "lz4", "tbox") if is_config("runtime", "luajit") then add_deps("luajit") else add_deps("lua") end + if has_config("lua_cjson") then + add_deps("lua-cjson") + end if is_plat("windows") and has_config("pdcurses") then add_deps("pdcurses") end diff --git a/core/src/xmake/xmake.sh b/core/src/xmake/xmake.sh index 709ff525b..06170e5bc 100755 --- a/core/src/xmake/xmake.sh +++ b/core/src/xmake/xmake.sh @@ -13,21 +13,16 @@ target "xmake" add_deps "$lib" fi done + if has_config "lua_cjson" && ! has_config "external"; then + add_deps "lua_cjson" + fi if is_config "runtime" "luajit"; then - if has_config "lua_cjson"; then - add_options "lua_cjson" "{public}" - elif ! has_config "external"; then - add_deps "lua_cjson" - fi if has_config "luajit"; then add_options "luajit" "{public}" elif ! has_config "external"; then add_deps "luajit" fi else - if ! has_config "external"; then - add_deps "lua_cjson" - fi if has_config "lua"; then add_options "lua" "{public}" elif ! has_config "external"; then diff --git a/core/xmake.lua b/core/xmake.lua index af92e54ea..b3c8bbed6 100644 --- a/core/xmake.lua +++ b/core/xmake.lua @@ -50,15 +50,19 @@ end -- the runtime option option("runtime") - set_showmenu(true) set_default("lua") set_description("Use luajit or lua runtime") set_values("luajit", "lua") option_end() +-- the lua-cjson option +option("lua_cjson") + set_default(true) + set_description("Use lua-cjson as json parser") +option_end() + -- the readline option option("readline") - set_showmenu(true) set_description("Enable or disable readline library") add_links("readline") add_cincludes("readline/readline.h") @@ -68,7 +72,6 @@ option_end() -- the curses option option("curses") - set_showmenu(true) set_description("Enable or disable curses library") add_links("curses") add_cincludes("curses.h") @@ -78,7 +81,6 @@ option_end() -- the pdcurses option option("pdcurses") set_default(true) - set_showmenu(true) set_description("Enable or disable pdcurses library") add_defines("PDCURSES") add_defines("XM_CONFIG_API_HAVE_CURSES") @@ -87,7 +89,6 @@ option_end() -- only build xmake libraries for development? option("onlylib") set_default(false) - set_showmenu(true) set_description("Only build xmake libraries for development") option_end() @@ -98,7 +99,10 @@ if is_plat("windows") then end -- add projects -includes("src/lua-cjson", "src/sv", "src/lz4", "src/tbox", "src/xmake", "src/demo") +includes("src/sv", "src/lz4", "src/tbox", "src/xmake", "src/demo") +if has_config("lua_cjson") then + includes("src/lua-cjson") +end if is_config("runtime", "luajit") then includes("src/luajit") else diff --git a/core/xmake.sh b/core/xmake.sh index d464b2862..af43f2ec1 100755 --- a/core/xmake.sh +++ b/core/xmake.sh @@ -38,6 +38,9 @@ option "runtime" "Use luajit or lua runtime" "lua" # always use external dependencies option "external" "Always use external dependencies" false +# use lua-cjson? +option "lua_cjson" "Use lua-cjson as json parser" true + # the readline option option "readline" add_links "readline" @@ -78,29 +81,6 @@ void test() {\n }" option_end -# the lua-cjson option, only for luajit/lua5.1 -option "lua_cjson" - add_defines "XM_CONFIG_API_HAVE_LUA_CJSON" - before_check "option_find_lua_cjson" - add_csnippets " -int luaopen_cjson(void *l);\n -void test() {\n - luaopen_cjson(0);\n -} -" -option_end - -option_find_lua_cjson() { - local ldflags="" - option "lua_cjson" - ldflags=`pkg-config --libs luajit 2>/dev/null` - if test_nz "${ldflags}"; then - ldflags="-llua5.1-cjson ${ldflags}" - fi - add_ldflags "${ldflags}" - option_end -} - # the lua option option "lua" add_cfuncs "lua_pushstring" @@ -213,13 +193,12 @@ if ! has_config "external"; then if ! has_config "luajit"; then includes "src/luajit" fi - if ! has_config "lua_cjson"; then - includes "src/lua-cjson" - fi else if ! has_config "lua"; then includes "src/lua" fi + fi + if has_config "lua_cjson"; then includes "src/lua-cjson" fi if ! has_config "lz4"; then -- cgit v1.3.1 From ed38818a56f40b2fbd51ea10957c1cd6ed0ced41 Mon Sep 17 00:00:00 2001 From: ruki Date: Thu, 19 Jan 2023 23:45:16 +0800 Subject: enable cjson --- xmake/core/base/json.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/xmake/core/base/json.lua b/xmake/core/base/json.lua index b99c6eb46..4c619e69a 100644 --- a/xmake/core/base/json.lua +++ b/xmake/core/base/json.lua @@ -20,7 +20,6 @@ -- define module: json local json = json or {} -cjson = nil -- TODO disable it for testing -- load modules local io = require("base/io") -- cgit v1.3.1