From 2ba224e1526681c1a0b1b2b095b1ef2b0874db48 Mon Sep 17 00:00:00 2001 From: bfredl Date: Sun, 26 Feb 2023 12:51:03 +0100 Subject: refactor(log): reduce compile time LOG_LEVEL granularity --- src/nvim/generators/gen_api_dispatch.lua | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/nvim/generators/gen_api_dispatch.lua') diff --git a/src/nvim/generators/gen_api_dispatch.lua b/src/nvim/generators/gen_api_dispatch.lua index 35f6bf8455..a0a67af78d 100644 --- a/src/nvim/generators/gen_api_dispatch.lua +++ b/src/nvim/generators/gen_api_dispatch.lua @@ -257,9 +257,8 @@ for i = 1, #functions do output:write('Object handle_'..fn.name..'(uint64_t channel_id, Array args, Arena* arena, Error *error)') output:write('\n{') - output:write('\n#if MIN_LOG_LEVEL <= LOGLVL_DBG') - output:write('\n logmsg(LOGLVL_DBG, "RPC: ", NULL, -1, true, "ch %" PRIu64 ": invoke ' - ..fn.name..'", channel_id);') + output:write('\n#ifdef NVIM_LOG_DEBUG') + output:write('\n DLOG("RPC: ch %" PRIu64 ": invoke '..fn.name..'", channel_id);') output:write('\n#endif') output:write('\n Object ret = NIL;') -- Declare/initialize variables that will hold converted arguments -- cgit From 4cba53e09e6e9d9cf06e87431146b9707347bcd6 Mon Sep 17 00:00:00 2001 From: bfredl Date: Mon, 20 Mar 2023 16:16:15 +0100 Subject: feat(lua): use vim.empty_dict() for empty return value in new api functions (#22737) --- src/nvim/generators/gen_api_dispatch.lua | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/nvim/generators/gen_api_dispatch.lua') diff --git a/src/nvim/generators/gen_api_dispatch.lua b/src/nvim/generators/gen_api_dispatch.lua index a0a67af78d..8aa1829364 100644 --- a/src/nvim/generators/gen_api_dispatch.lua +++ b/src/nvim/generators/gen_api_dispatch.lua @@ -619,9 +619,10 @@ local function process_function(fn) } ]], return_type)) else + local special = (fn.since ~= nil and fn.since < 11) write_shifted_output(output, string.format([[ - nlua_push_%s(lstate, ret, true); - ]], return_type)) + nlua_push_%s(lstate, ret, %s); + ]], return_type, tostring(special))) end write_shifted_output(output, string.format([[ -- cgit From efb0896f21e03f64e3a14e7c09994e81956f47b9 Mon Sep 17 00:00:00 2001 From: bfredl Date: Mon, 3 Apr 2023 15:21:24 +0200 Subject: refactor(api): make typed dicts appear as types in the source code problem: can we have Serde? solution: we have Serde at home This by itself is just a change of notation, that could be quickly merged to avoid messy merge conflicts, but upcoming changes are planned: - keysets no longer need to be defined in one single file. `keysets.h` is just the initial automatic conversion of the previous `keysets.lua`. keysets just used in a single api/{scope}.h can be moved to that file, later on. - Typed dicts will have more specific types than Object. this will enable most of the existing manual typechecking boilerplate to be eliminated. We will need some annotation for missing value, i e a boolean will need to be represented as a TriState (none/false/true) in some cases. - Eventually: optional parameters in form of a `Dict opts` final parameter will get added in some form to metadata. this will require a discussion/desicion about type forward compatibility. --- src/nvim/generators/gen_api_dispatch.lua | 140 +++++++++++++++++++++++-------- 1 file changed, 106 insertions(+), 34 deletions(-) (limited to 'src/nvim/generators/gen_api_dispatch.lua') diff --git a/src/nvim/generators/gen_api_dispatch.lua b/src/nvim/generators/gen_api_dispatch.lua index 8aa1829364..f292c265ec 100644 --- a/src/nvim/generators/gen_api_dispatch.lua +++ b/src/nvim/generators/gen_api_dispatch.lua @@ -8,6 +8,7 @@ if arg[1] == '--help' then print(' 3: functions metadata output file (funcs_metadata.generated.h)') print(' 4: API metadata output file (api_metadata.mpack)') print(' 5: lua C bindings output file (lua_api_c_bindings.generated.c)') + print(' 6: keyset definitions output file (keysets_defs.generated.h)') print(' rest: C files where API functions are defined') end assert(#arg >= 4) @@ -32,6 +33,7 @@ local funcs_metadata_outputf = arg[3] -- output metadata mpack file, for use by other build scripts local mpack_outputf = arg[4] local lua_c_bindings_outputf = arg[5] +local keysets_outputf = arg[6] -- set of function names, used to detect duplicates local function_names = {} @@ -42,8 +44,57 @@ local function startswith(String,Start) return string.sub(String,1,string.len(Start))==Start end +local function add_function(fn) + local public = startswith(fn.name, "nvim_") or fn.deprecated_since + if public and not fn.noexport then + functions[#functions + 1] = fn + function_names[fn.name] = true + if #fn.parameters >= 2 and fn.parameters[2][1] == 'Array' and fn.parameters[2][2] == 'uidata' then + -- function receives the "args" as a parameter + fn.receives_array_args = true + -- remove the args parameter + table.remove(fn.parameters, 2) + end + if #fn.parameters ~= 0 and fn.parameters[1][2] == 'channel_id' then + -- this function should receive the channel id + fn.receives_channel_id = true + -- remove the parameter since it won't be passed by the api client + table.remove(fn.parameters, 1) + end + if #fn.parameters ~= 0 and fn.parameters[#fn.parameters][1] == 'error' then + -- function can fail if the last parameter type is 'Error' + fn.can_fail = true + -- remove the error parameter, msgpack has it's own special field + -- for specifying errors + fn.parameters[#fn.parameters] = nil + end + if #fn.parameters ~= 0 and fn.parameters[#fn.parameters][1] == 'arena' then + -- return value is allocated in an arena + fn.arena_return = true + fn.parameters[#fn.parameters] = nil + end + if #fn.parameters ~= 0 and fn.parameters[#fn.parameters][1] == 'lstate' then + fn.has_lua_imp = true + fn.parameters[#fn.parameters] = nil + end + end +end + +local keysets = {} + +local function add_keyset(val) + local keys = {} + for _,field in ipairs(val.fields) do + if field.type ~= 'Object' then + error 'not yet implemented: types other than Object' + end + table.insert(keys, field.name) + end + table.insert(keysets, {val.keyset_name, keys}) +end + -- read each input file, parse and append to the api metadata -for i = 6, #arg do +for i = 7, #arg do local full_path = arg[i] local parts = {} for part in string.gmatch(full_path, '[^/]+') do @@ -55,39 +106,11 @@ for i = 6, #arg do local tmp = c_grammar.grammar:match(input:read('*all')) for j = 1, #tmp do - local fn = tmp[j] - local public = startswith(fn.name, "nvim_") or fn.deprecated_since - if public and not fn.noexport then - functions[#functions + 1] = tmp[j] - function_names[fn.name] = true - if #fn.parameters >= 2 and fn.parameters[2][1] == 'Array' and fn.parameters[2][2] == 'uidata' then - -- function receives the "args" as a parameter - fn.receives_array_args = true - -- remove the args parameter - table.remove(fn.parameters, 2) - end - if #fn.parameters ~= 0 and fn.parameters[1][2] == 'channel_id' then - -- this function should receive the channel id - fn.receives_channel_id = true - -- remove the parameter since it won't be passed by the api client - table.remove(fn.parameters, 1) - end - if #fn.parameters ~= 0 and fn.parameters[#fn.parameters][1] == 'error' then - -- function can fail if the last parameter type is 'Error' - fn.can_fail = true - -- remove the error parameter, msgpack has it's own special field - -- for specifying errors - fn.parameters[#fn.parameters] = nil - end - if #fn.parameters ~= 0 and fn.parameters[#fn.parameters][1] == 'arena' then - -- return value is allocated in an arena - fn.arena_return = true - fn.parameters[#fn.parameters] = nil - end - if #fn.parameters ~= 0 and fn.parameters[#fn.parameters][1] == 'lstate' then - fn.has_lua_imp = true - fn.parameters[#fn.parameters] = nil - end + local val = tmp[j] + if val.keyset_name then + add_keyset(val) + else + add_function(val) end end input:close() @@ -195,6 +218,7 @@ funcs_metadata_output:close() -- start building the dispatch wrapper output local output = io.open(dispatch_outputf, 'wb') +local keysets_defs = io.open(keysets_outputf, 'wb') -- =========================================================================== -- NEW API FILES MUST GO HERE. @@ -224,6 +248,52 @@ output:write([[ ]]) +for _,keyset in ipairs(keysets) do + local name, keys = unpack(keyset) + local special = {} + local function sanitize(key) + if special[key] then + return key .. "_" + end + return key + end + + for i = 1,#keys do + if vim.endswith(keys[i], "_") then + keys[i] = string.sub(keys[i],1, #(keys[i]) - 1) + special[keys[i]] = true + end + end + local neworder, hashfun = hashy.hashy_hash(name, keys, function (idx) + return name.."_table["..idx.."].str" + end) + + keysets_defs:write("extern KeySetLink "..name.."_table[];\n") + + output:write("KeySetLink "..name.."_table[] = {\n") + for _, key in ipairs(neworder) do + output:write(' {"'..key..'", offsetof(KeyDict_'..name..", "..sanitize(key)..")},\n") + end + output:write(' {NULL, 0},\n') + output:write("};\n\n") + + output:write(hashfun) + + output:write([[ +Object *KeyDict_]]..name..[[_get_field(void *retval, const char *str, size_t len) +{ + int hash = ]]..name..[[_hash(str, len); + if (hash == -1) { + return NULL; + } + + return (Object *)((char *)retval + ]]..name..[[_table[hash].ptr_off); +} + +]]) + keysets_defs:write("#define api_free_keydict_"..name.."(x) api_free_keydict(x, "..name.."_table)\n") +end + local function real_type(type) local rv = type local rmatch = string.match(type, "Dict%(([_%w]+)%)") @@ -475,6 +545,7 @@ output:write([[ #include "nvim/func_attr.h" #include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" +#include "nvim/api/private/dispatch.h" #include "nvim/lua/converter.h" #include "nvim/lua/executor.h" #include "nvim/memory.h" @@ -670,3 +741,4 @@ output:write([[ ]]) output:close() +keysets_defs:close() -- cgit From 1e60e8c0406f6b4b51c51abb5f53e25bd52fee5e Mon Sep 17 00:00:00 2001 From: bfredl Date: Sat, 15 Apr 2023 12:23:45 +0200 Subject: refactor(build): use vendored versions of mpack and luabitop --- src/nvim/generators/gen_api_dispatch.lua | 45 ++++++++++---------------------- 1 file changed, 14 insertions(+), 31 deletions(-) (limited to 'src/nvim/generators/gen_api_dispatch.lua') diff --git a/src/nvim/generators/gen_api_dispatch.lua b/src/nvim/generators/gen_api_dispatch.lua index f292c265ec..ad7018e385 100644 --- a/src/nvim/generators/gen_api_dispatch.lua +++ b/src/nvim/generators/gen_api_dispatch.lua @@ -1,40 +1,23 @@ local mpack = require('mpack') --- we need at least 4 arguments since the last two are output files -if arg[1] == '--help' then - print('Usage: genmsgpack.lua args') - print('Args: 1: source directory') - print(' 2: dispatch output file (dispatch_wrappers.generated.h)') - print(' 3: functions metadata output file (funcs_metadata.generated.h)') - print(' 4: API metadata output file (api_metadata.mpack)') - print(' 5: lua C bindings output file (lua_api_c_bindings.generated.c)') - print(' 6: keyset definitions output file (keysets_defs.generated.h)') - print(' rest: C files where API functions are defined') -end -assert(#arg >= 4) -local functions = {} - -local nvimdir = arg[1] -package.path = nvimdir .. '/?.lua;' .. package.path +local hashy = require'generators.hashy' -_G.vim = loadfile(nvimdir..'/../../runtime/lua/vim/shared.lua')() -_G.vim.inspect = loadfile(nvimdir..'/../../runtime/lua/vim/inspect.lua')() +assert(#arg >= 5) +-- output h file with generated dispatch functions (dispatch_wrappers.generated.h) +local dispatch_outputf = arg[1] +-- output h file with packed metadata (funcs_metadata.generated.h) +local funcs_metadata_outputf = arg[2] +-- output metadata mpack file, for use by other build scripts (api_metadata.mpack) +local mpack_outputf = arg[3] +local lua_c_bindings_outputf = arg[4] -- lua_api_c_bindings.generated.c +local keysets_outputf = arg[5] -- keysets_defs.generated.h -local hashy = require'generators.hashy' +local functions = {} -- names of all headers relative to the source root (for inclusion in the -- generated file) local headers = {} --- output h file with generated dispatch functions -local dispatch_outputf = arg[2] --- output h file with packed metadata -local funcs_metadata_outputf = arg[3] --- output metadata mpack file, for use by other build scripts -local mpack_outputf = arg[4] -local lua_c_bindings_outputf = arg[5] -local keysets_outputf = arg[6] - -- set of function names, used to detect duplicates local function_names = {} @@ -94,7 +77,7 @@ local function add_keyset(val) end -- read each input file, parse and append to the api metadata -for i = 7, #arg do +for i = 6, #arg do local full_path = arg[i] local parts = {} for part in string.gmatch(full_path, '[^/]+') do @@ -210,7 +193,7 @@ end -- serialize the API metadata using msgpack and embed into the resulting -- binary for easy querying by clients local funcs_metadata_output = io.open(funcs_metadata_outputf, 'wb') -local packed = mpack.pack(exported_functions) +local packed = mpack.encode(exported_functions) local dump_bin_array = require("generators.dump_bin_array") dump_bin_array(funcs_metadata_output, 'funcs_metadata', packed) funcs_metadata_output:close() @@ -514,7 +497,7 @@ output:write(hashfun) output:close() local mpack_output = io.open(mpack_outputf, 'wb') -mpack_output:write(mpack.pack(functions)) +mpack_output:write(mpack.encode(functions)) mpack_output:close() local function include_headers(output_handle, headers_to_include) -- cgit From ffaf74f1477d3182ffc70bcc9913effc44c90ea7 Mon Sep 17 00:00:00 2001 From: bfredl Date: Thu, 20 Apr 2023 14:41:47 +0200 Subject: fix(build): distinguish vim.mpack from global require'mpack' problem: the api of vim.mpack is not compatible with a system provided mpack solution: don't require 'mpack' directly from the system path --- src/nvim/generators/gen_api_dispatch.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/generators/gen_api_dispatch.lua') diff --git a/src/nvim/generators/gen_api_dispatch.lua b/src/nvim/generators/gen_api_dispatch.lua index ad7018e385..244921de31 100644 --- a/src/nvim/generators/gen_api_dispatch.lua +++ b/src/nvim/generators/gen_api_dispatch.lua @@ -1,4 +1,4 @@ -local mpack = require('mpack') +local mpack = vim.mpack local hashy = require'generators.hashy' -- cgit From 77118d0da8badc4135be430f4cbb15bc95bc760f Mon Sep 17 00:00:00 2001 From: Sean Dewar Date: Thu, 20 Apr 2023 21:17:25 +0100 Subject: fix(api): use text_locked() to check textlock Problem: some API functions that check textlock (usually those that can change curwin or curbuf) can break the cmdwin. Solution: make FUNC_API_CHECK_TEXTLOCK call text_locked() instead, which already checks for textlock, cmdwin and `` status. Add FUNC_API_TEXTLOCK_ALLOW_CMDWIN to allow such functions to be usable in the cmdwin if they can work properly there; the opt-in nature of this attribute should hopefully help mitigate future bugs. Also fix a regression in #22634 that made functions checking textlock usable in `` mappings, and rename FUNC_API_CHECK_TEXTLOCK to FUNC_API_TEXTLOCK. --- src/nvim/generators/gen_api_dispatch.lua | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) (limited to 'src/nvim/generators/gen_api_dispatch.lua') diff --git a/src/nvim/generators/gen_api_dispatch.lua b/src/nvim/generators/gen_api_dispatch.lua index 244921de31..bf211f5273 100644 --- a/src/nvim/generators/gen_api_dispatch.lua +++ b/src/nvim/generators/gen_api_dispatch.lua @@ -210,10 +210,11 @@ local keysets_defs = io.open(keysets_outputf, 'wb') -- so that the dispatcher can find the C functions that you are creating! -- =========================================================================== output:write([[ +#include "nvim/ex_docmd.h" +#include "nvim/ex_getln.h" #include "nvim/log.h" #include "nvim/map.h" #include "nvim/msgpack_rpc/helpers.h" -#include "nvim/vim.h" #include "nvim/api/autocmd.h" #include "nvim/api/buffer.h" @@ -389,8 +390,13 @@ for i = 1, #functions do args[#args + 1] = converted end - if fn.check_textlock then - output:write('\n if (textlock != 0) {') + if fn.textlock then + output:write('\n if (text_locked()) {') + output:write('\n api_set_error(error, kErrorTypeException, "%s", get_text_locked_msg());') + output:write('\n goto cleanup;') + output:write('\n }\n') + elseif fn.textlock_allow_cmdwin then + output:write('\n if (textlock != 0 || expr_map_locked()) {') output:write('\n api_set_error(error, kErrorTypeException, "%s", e_textlock);') output:write('\n goto cleanup;') output:write('\n }\n') @@ -525,6 +531,8 @@ output:write([[ #include #include +#include "nvim/ex_docmd.h" +#include "nvim/ex_getln.h" #include "nvim/func_attr.h" #include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" @@ -565,9 +573,16 @@ local function process_function(fn) ]], fn.name)) end - if fn.check_textlock then + if fn.textlock then + write_shifted_output(output, [[ + if (text_locked()) { + api_set_error(&err, kErrorTypeException, "%s", get_text_locked_msg()); + goto exit_0; + } + ]]) + elseif fn.textlock_allow_cmdwin then write_shifted_output(output, [[ - if (textlock != 0) { + if (textlock != 0 || expr_map_locked()) { api_set_error(&err, kErrorTypeException, "%s", e_textlock); goto exit_0; } -- cgit From 48d533272e57e91e4d14c93b26d4922957f40cd7 Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Tue, 1 Aug 2023 14:20:44 +0100 Subject: feat(lua-types): types for vim.api.* (#24523) --- src/nvim/generators/gen_api_dispatch.lua | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'src/nvim/generators/gen_api_dispatch.lua') diff --git a/src/nvim/generators/gen_api_dispatch.lua b/src/nvim/generators/gen_api_dispatch.lua index bf211f5273..1b0565d9b6 100644 --- a/src/nvim/generators/gen_api_dispatch.lua +++ b/src/nvim/generators/gen_api_dispatch.lua @@ -71,7 +71,7 @@ local function add_keyset(val) if field.type ~= 'Object' then error 'not yet implemented: types other than Object' end - table.insert(keys, field.name) + table.insert(keys, {field.name, field.type}) end table.insert(keysets, {val.keyset_name, keys}) end @@ -242,13 +242,16 @@ for _,keyset in ipairs(keysets) do return key end + local key_names = {} for i = 1,#keys do - if vim.endswith(keys[i], "_") then - keys[i] = string.sub(keys[i],1, #(keys[i]) - 1) - special[keys[i]] = true + local kname = keys[i][1] + if vim.endswith(kname, "_") then + kname = string.sub(kname,1, #kname - 1) + special[kname] = true end + key_names[i] = kname end - local neworder, hashfun = hashy.hashy_hash(name, keys, function (idx) + local neworder, hashfun = hashy.hashy_hash(name, key_names, function (idx) return name.."_table["..idx.."].str" end) @@ -502,6 +505,7 @@ output:write(hashfun) output:close() +functions.keysets = keysets local mpack_output = io.open(mpack_outputf, 'wb') mpack_output:write(mpack.encode(functions)) mpack_output:close() -- cgit From c01e624b0762b24a4988bf9474a57d5b6278d180 Mon Sep 17 00:00:00 2001 From: bfredl Date: Tue, 1 Aug 2023 23:19:17 +0200 Subject: feat(lua): more specific error messages for vim.api type checking --- src/nvim/generators/gen_api_dispatch.lua | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'src/nvim/generators/gen_api_dispatch.lua') diff --git a/src/nvim/generators/gen_api_dispatch.lua b/src/nvim/generators/gen_api_dispatch.lua index 1b0565d9b6..fe63cb883e 100644 --- a/src/nvim/generators/gen_api_dispatch.lua +++ b/src/nvim/generators/gen_api_dispatch.lua @@ -558,6 +558,7 @@ local function process_function(fn) static int %s(lua_State *lstate) { Error err = ERROR_INIT; + char *err_param = 0; if (lua_gettop(lstate) != %i) { api_set_error(&err, kErrorTypeValidation, "Expected %i argument%s"); goto exit_0; @@ -605,6 +606,7 @@ local function process_function(fn) extra = "true, " end local errshift = 0 + local seterr = '' if string.match(param_type, '^KeyDict_') then write_shifted_output(output, string.format([[ %s %s = { 0 }; nlua_pop_keydict(lstate, &%s, %s_get_field, %s&err);]], param_type, cparam, cparam, param_type, extra)) @@ -613,11 +615,13 @@ local function process_function(fn) else write_shifted_output(output, string.format([[ const %s %s = nlua_pop_%s(lstate, %s&err);]], param[1], cparam, param_type, extra)) + seterr = [[ + err_param = "]]..param[2]..[[";]] end write_shifted_output(output, string.format([[ - if (ERROR_SET(&err)) { + if (ERROR_SET(&err)) {]]..seterr..[[ goto exit_%u; } @@ -661,9 +665,14 @@ local function process_function(fn) exit_0: if (ERROR_SET(&err)) { luaL_where(lstate, 1); + if (err_param) { + lua_pushstring(lstate, "param '"); + lua_pushstring(lstate, err_param); + lua_pushstring(lstate, "': "); + } lua_pushstring(lstate, err.msg); api_clear_error(&err); - lua_concat(lstate, 2); + lua_concat(lstate, err_param ? 5 : 2); return lua_error(lstate); } ]] -- cgit From 7bc93e0e2f246dd78026a3472d929a0fe450f70d Mon Sep 17 00:00:00 2001 From: bfredl Date: Tue, 1 Aug 2023 14:01:19 +0200 Subject: refactor(api): use typed keysets Initially this is just for geting rid of boilerplate, but eventually the types could get exposed as metadata --- src/nvim/generators/gen_api_dispatch.lua | 87 ++++++++++++++++++++------------ 1 file changed, 54 insertions(+), 33 deletions(-) (limited to 'src/nvim/generators/gen_api_dispatch.lua') diff --git a/src/nvim/generators/gen_api_dispatch.lua b/src/nvim/generators/gen_api_dispatch.lua index fe63cb883e..9c15597fcc 100644 --- a/src/nvim/generators/gen_api_dispatch.lua +++ b/src/nvim/generators/gen_api_dispatch.lua @@ -67,13 +67,27 @@ local keysets = {} local function add_keyset(val) local keys = {} - for _,field in ipairs(val.fields) do + local types = {} + local is_set_name = 'is_set__' .. val.keyset_name .. '_' + local has_optional = false + for i,field in ipairs(val.fields) do if field.type ~= 'Object' then - error 'not yet implemented: types other than Object' + types[field.name] = field.type + end + if field.name ~= is_set_name and field.type ~= 'OptionalKeys' then + table.insert(keys, field.name) + else + if i > 1 then + error("'is_set__{type}_' must be first if present") + elseif field.name ~= is_set_name then + error(val.keyset_name..": name of first key should be "..is_set_name) + elseif field.type ~= 'OptionalKeys' then + error("'"..is_set_name.."' must have type 'OptionalKeys'") + end + has_optional = true end - table.insert(keys, {field.name, field.type}) end - table.insert(keysets, {val.keyset_name, keys}) + table.insert(keysets, {name=val.keyset_name, keys=keys, types=types, has_optional=has_optional}) end -- read each input file, parse and append to the api metadata @@ -232,53 +246,60 @@ output:write([[ ]]) -for _,keyset in ipairs(keysets) do - local name, keys = unpack(keyset) - local special = {} - local function sanitize(key) - if special[key] then - return key .. "_" - end - return key - end +for _,k in ipairs(keysets) do + local c_name = {} - local key_names = {} - for i = 1,#keys do - local kname = keys[i][1] - if vim.endswith(kname, "_") then - kname = string.sub(kname,1, #kname - 1) - special[kname] = true + for i = 1,#k.keys do + -- some keys, like "register" are c keywords and get + -- escaped with a trailing _ in the struct. + if vim.endswith(k.keys[i], "_") then + local orig = k.keys[i] + k.keys[i] = string.sub(k.keys[i],1, #(k.keys[i]) - 1) + c_name[k.keys[i]] = orig + k.types[k.keys[i]] = k.types[orig] end - key_names[i] = kname end - local neworder, hashfun = hashy.hashy_hash(name, key_names, function (idx) - return name.."_table["..idx.."].str" + + local neworder, hashfun = hashy.hashy_hash(k.name, k.keys, function (idx) + return k.name.."_table["..idx.."].str" end) - keysets_defs:write("extern KeySetLink "..name.."_table[];\n") + keysets_defs:write("extern KeySetLink "..k.name.."_table[];\n") - output:write("KeySetLink "..name.."_table[] = {\n") - for _, key in ipairs(neworder) do - output:write(' {"'..key..'", offsetof(KeyDict_'..name..", "..sanitize(key)..")},\n") + local function typename(type) + if type ~= nil then + return "kObjectType"..type + else + return "kObjectTypeNil" + end + end + + output:write("KeySetLink "..k.name.."_table[] = {\n") + for i, key in ipairs(neworder) do + local ind = -1 + if k.has_optional then + ind = i + keysets_defs:write("#define KEYSET_OPTIDX_"..k.name.."__"..key.." "..ind.."\n") + end + output:write(' {"'..key..'", offsetof(KeyDict_'..k.name..", "..(c_name[key] or key).."), "..typename(k.types[key])..", "..ind.."},\n") end - output:write(' {NULL, 0},\n') + output:write(' {NULL, 0, kObjectTypeNil, -1},\n') output:write("};\n\n") output:write(hashfun) output:write([[ -Object *KeyDict_]]..name..[[_get_field(void *retval, const char *str, size_t len) +KeySetLink *KeyDict_]]..k.name..[[_get_field(const char *str, size_t len) { - int hash = ]]..name..[[_hash(str, len); + int hash = ]]..k.name..[[_hash(str, len); if (hash == -1) { return NULL; } - - return (Object *)((char *)retval + ]]..name..[[_table[hash].ptr_off); + return &]]..k.name..[[_table[hash]; } ]]) - keysets_defs:write("#define api_free_keydict_"..name.."(x) api_free_keydict(x, "..name.."_table)\n") + keysets_defs:write("#define api_free_keydict_"..k.name.."(x) api_free_keydict(x, "..k.name.."_table)\n") end local function real_type(type) @@ -666,7 +687,7 @@ local function process_function(fn) if (ERROR_SET(&err)) { luaL_where(lstate, 1); if (err_param) { - lua_pushstring(lstate, "param '"); + lua_pushstring(lstate, "Invalid '"); lua_pushstring(lstate, err_param); lua_pushstring(lstate, "': "); } -- cgit From 6c0812d92e0c7937b913175b8856064cb45f55c2 Mon Sep 17 00:00:00 2001 From: bfredl Date: Tue, 1 Aug 2023 23:35:34 +0200 Subject: feat(lua): specific error messages for type checking `opts` params --- src/nvim/generators/gen_api_dispatch.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/generators/gen_api_dispatch.lua') diff --git a/src/nvim/generators/gen_api_dispatch.lua b/src/nvim/generators/gen_api_dispatch.lua index 9c15597fcc..02648e6c99 100644 --- a/src/nvim/generators/gen_api_dispatch.lua +++ b/src/nvim/generators/gen_api_dispatch.lua @@ -630,7 +630,7 @@ local function process_function(fn) local seterr = '' if string.match(param_type, '^KeyDict_') then write_shifted_output(output, string.format([[ - %s %s = { 0 }; nlua_pop_keydict(lstate, &%s, %s_get_field, %s&err);]], param_type, cparam, cparam, param_type, extra)) + %s %s = { 0 }; nlua_pop_keydict(lstate, &%s, %s_get_field, &err_param, &err);]], param_type, cparam, cparam, param_type)) cparam = '&'..cparam errshift = 1 -- free incomplete dict on error else -- cgit From 353a4be7e84fdc101318215bdcc8a7e780d737fe Mon Sep 17 00:00:00 2001 From: dundargoc Date: Sun, 12 Nov 2023 13:13:58 +0100 Subject: build: remove PVS We already have an extensive suite of static analysis tools we use, which causes a fair bit of redundancy as we get duplicate warnings. PVS is also prone to give false warnings which creates a lot of work to identify and disable. --- src/nvim/generators/gen_api_dispatch.lua | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/nvim/generators/gen_api_dispatch.lua') diff --git a/src/nvim/generators/gen_api_dispatch.lua b/src/nvim/generators/gen_api_dispatch.lua index 02648e6c99..6cdcf56783 100644 --- a/src/nvim/generators/gen_api_dispatch.lua +++ b/src/nvim/generators/gen_api_dispatch.lua @@ -550,8 +550,6 @@ end output = io.open(lua_c_bindings_outputf, 'wb') output:write([[ -// This is an open source non-commercial project. Dear PVS-Studio, please check -// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com #include #include #include -- cgit From 79b6ff28ad1204fbb4199b9092f5c578d88cb28e Mon Sep 17 00:00:00 2001 From: dundargoc Date: Tue, 28 Nov 2023 20:31:00 +0100 Subject: refactor: fix headers with IWYU --- src/nvim/generators/gen_api_dispatch.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/generators/gen_api_dispatch.lua') diff --git a/src/nvim/generators/gen_api_dispatch.lua b/src/nvim/generators/gen_api_dispatch.lua index 6cdcf56783..9720cca477 100644 --- a/src/nvim/generators/gen_api_dispatch.lua +++ b/src/nvim/generators/gen_api_dispatch.lua @@ -227,7 +227,7 @@ output:write([[ #include "nvim/ex_docmd.h" #include "nvim/ex_getln.h" #include "nvim/log.h" -#include "nvim/map.h" +#include "nvim/map_defs.h" #include "nvim/msgpack_rpc/helpers.h" #include "nvim/api/autocmd.h" -- cgit