aboutsummaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rw-r--r--scripts/dispatch_deprecated.lua77
-rw-r--r--scripts/gendispatch.lua (renamed from scripts/msgpack-gen.lua)219
-rw-r--r--scripts/geneval.lua66
-rw-r--r--scripts/genvimvim.lua27
4 files changed, 284 insertions, 105 deletions
diff --git a/scripts/dispatch_deprecated.lua b/scripts/dispatch_deprecated.lua
new file mode 100644
index 0000000000..f3b299e3fc
--- /dev/null
+++ b/scripts/dispatch_deprecated.lua
@@ -0,0 +1,77 @@
+local deprecated_aliases = {
+ nvim_buf_line_count="buffer_line_count",
+ nvim_buf_get_lines="buffer_get_lines",
+ nvim_buf_set_lines="buffer_set_lines",
+ nvim_buf_get_var="buffer_get_var",
+ nvim_buf_set_var="buffer_set_var",
+ nvim_buf_del_var="buffer_del_var",
+ nvim_buf_get_option="buffer_get_option",
+ nvim_buf_set_option="buffer_set_option",
+ nvim_buf_get_number="buffer_get_number",
+ nvim_buf_get_name="buffer_get_name",
+ nvim_buf_set_name="buffer_set_name",
+ nvim_buf_is_valid="buffer_is_valid",
+ nvim_buf_get_mark="buffer_get_mark",
+ nvim_buf_add_highlight="buffer_add_highlight",
+ nvim_buf_clear_highlight="buffer_clear_highlight",
+ nvim_tabpage_get_windows="tabpage_get_windows",
+ nvim_tabpage_get_var="tabpage_get_var",
+ nvim_tabpage_set_var="tabpage_set_var",
+ nvim_tabpage_del_var="tabpage_del_var",
+ nvim_tabpage_get_window="tabpage_get_window",
+ nvim_tabpage_is_valid="tabpage_is_valid",
+ nvim_ui_detach="ui_detach",
+ nvim_ui_try_resize="ui_try_resize",
+ nvim_command="vim_command",
+ nvim_feedkeys="vim_feedkeys",
+ nvim_input="vim_input",
+ nvim_replace_termcodes="vim_replace_termcodes",
+ nvim_command_output="vim_command_output",
+ nvim_eval="vim_eval",
+ nvim_call_function="vim_call_function",
+ nvim_strwidth="vim_strwidth",
+ nvim_list_runtime_paths="vim_list_runtime_paths",
+ nvim_change_directory="vim_change_directory",
+ nvim_get_var="vim_get_var",
+ nvim_set_var="vim_set_var",
+ nvim_del_var="vim_del_var",
+ nvim_get_vvar="vim_get_vvar",
+ nvim_get_option="vim_get_option",
+ nvim_set_option="vim_set_option",
+ nvim_out_write="vim_out_write",
+ nvim_err_write="vim_err_write",
+ nvim_report_error="vim_report_error",
+ nvim_get_buffers="vim_get_buffers",
+ nvim_get_current_buffer="vim_get_current_buffer",
+ nvim_set_current_buffer="vim_set_current_buffer",
+ nvim_get_windows="vim_get_windows",
+ nvim_get_current_window="vim_get_current_window",
+ nvim_set_current_window="vim_set_current_window",
+ nvim_get_tabpages="vim_get_tabpages",
+ nvim_get_current_tabpage="vim_get_current_tabpage",
+ nvim_set_current_tabpage="vim_set_current_tabpage",
+ nvim_set_current_line="vim_set_current_line",
+ nvim_get_current_line="vim_get_current_line",
+ nvim_del_current_line="vim_del_current_line",
+ nvim_subscribe="vim_subscribe",
+ nvim_unsubscribe="vim_unsubscribe",
+ nvim_name_to_color="vim_name_to_color",
+ nvim_get_color_map="vim_get_color_map",
+ nvim_get_api_info="vim_get_api_info",
+ nvim_win_get_buffer="window_get_buffer",
+ nvim_win_get_cursor="window_get_cursor",
+ nvim_win_set_cursor="window_set_cursor",
+ nvim_win_get_height="window_get_height",
+ nvim_win_set_height="window_set_height",
+ nvim_win_get_width="window_get_width",
+ nvim_win_set_width="window_set_width",
+ nvim_win_get_var="window_get_var",
+ nvim_win_set_var="window_set_var",
+ nvim_win_del_var="window_del_var",
+ nvim_win_get_option="window_get_option",
+ nvim_win_set_option="window_set_option",
+ nvim_win_get_position="window_get_position",
+ nvim_win_get_tabpage="window_get_tabpage",
+ nvim_win_is_valid="window_is_valid"
+}
+return deprecated_aliases
diff --git a/scripts/msgpack-gen.lua b/scripts/gendispatch.lua
index 2da3c174f9..12d6261b5a 100644
--- a/scripts/msgpack-gen.lua
+++ b/scripts/gendispatch.lua
@@ -37,22 +37,28 @@ c_proto = Ct(
Cg(Cc(false), 'async') *
(fill * Cg((P('FUNC_API_ASYNC') * Cc(true)), 'async') ^ -1) *
(fill * Cg((P('FUNC_API_NOEXPORT') * Cc(true)), 'noexport') ^ -1) *
+ (fill * Cg((P('FUNC_API_NOEVAL') * Cc(true)), 'noeval') ^ -1) *
fill * P(';')
)
grammar = Ct((c_proto + c_comment + c_preproc + ws) ^ 1)
--- we need at least 2 arguments since the last one is the output file
-assert(#arg >= 1)
+-- we need at least 4 arguments since the last two are output files
+assert(#arg >= 3)
functions = {}
+local scriptdir = arg[1]
+package.path = scriptdir .. '/?.lua;' .. package.path
+
-- names of all headers relative to the source root (for inclusion in the
-- generated file)
headers = {}
--- output file(dispatch function + metadata serialized with msgpack)
-outputf = arg[#arg]
+-- output c file(dispatch function + metadata serialized with msgpack)
+outputf = arg[#arg-1]
+-- output mpack file (metadata)
+mpack_outputf = arg[#arg]
-- read each input file, parse and append to the api metadata
-for i = 1, #arg - 1 do
+for i = 2, #arg - 2 do
local full_path = arg[i]
local parts = {}
for part in string.gmatch(full_path, '[^/]+') do
@@ -84,6 +90,45 @@ for i = 1, #arg - 1 do
input:close()
end
+local function shallowcopy(orig)
+ local copy = {}
+ for orig_key, orig_value in pairs(orig) do
+ copy[orig_key] = orig_value
+ end
+ return copy
+end
+
+local function startswith(String,Start)
+ return string.sub(String,1,string.len(Start))==Start
+end
+
+-- Export functions under older deprecated names.
+-- These will be removed eventually.
+local deprecated_aliases = require("dispatch_deprecated")
+for i,f in ipairs(shallowcopy(functions)) do
+ local ismethod = false
+ if startswith(f.name, "nvim_buf_") then
+ ismethod = true
+ elseif startswith(f.name, "nvim_win_") then
+ ismethod = true
+ elseif startswith(f.name, "nvim_tabpage_") then
+ ismethod = true
+ elseif not startswith(f.name, "nvim_") then
+ f.noeval = true
+ f.deprecated_since = 1
+ end
+ f.method = ismethod
+ local newname = deprecated_aliases[f.name]
+ if newname ~= nil then
+ local newf = shallowcopy(f)
+ newf.name = newname
+ newf.impl_name = f.name
+ newf.noeval = true
+ newf.deprecated_since = 1
+ functions[#functions+1] = newf
+ end
+end
+
-- start building the output
output = io.open(outputf, 'wb')
@@ -99,7 +144,7 @@ output:write([[
#include "nvim/log.h"
#include "nvim/vim.h"
#include "nvim/msgpack_rpc/helpers.h"
-#include "nvim/msgpack_rpc/defs.h"
+#include "nvim/api/private/dispatch.h"
#include "nvim/api/private/helpers.h"
#include "nvim/api/private/defs.h"
]])
@@ -163,99 +208,95 @@ end
-- the real API.
for i = 1, #functions do
local fn = functions[i]
- local args = {}
-
- output:write('static Object handle_'..fn.name..'(uint64_t channel_id, uint64_t request_id, Array args, Error *error)')
- output:write('\n{')
- output:write('\n Object ret = NIL;')
- -- Declare/initialize variables that will hold converted arguments
- for j = 1, #fn.parameters do
- local param = fn.parameters[j]
- local converted = 'arg_'..j
- output:write('\n '..param[1]..' '..converted..' api_init_'..string.lower(real_type(param[1]))..';')
- end
- output:write('\n')
- output:write('\n if (args.size != '..#fn.parameters..') {')
- output:write('\n snprintf(error->msg, sizeof(error->msg), "Wrong number of arguments: expecting '..#fn.parameters..' but got %zu", args.size);')
- output:write('\n error->set = true;')
- output:write('\n goto cleanup;')
- output:write('\n }\n')
-
- -- Validation/conversion for each argument
- for j = 1, #fn.parameters do
- local converted, convert_arg, param, arg
- param = fn.parameters[j]
- converted = 'arg_'..j
- local rt = real_type(param[1])
- if rt ~= 'Object' then
- output:write('\n if (args.items['..(j - 1)..'].type == kObjectType'..rt..') {')
- output:write('\n '..converted..' = args.items['..(j - 1)..'].data.'..rt:lower()..';')
- if rt:match('^Buffer$') or rt:match('^Window$') or rt:match('^Tabpage$') or rt:match('^Boolean$') then
- -- accept positive integers for Buffers, Windows and Tabpages
- output:write('\n } else if (args.items['..(j - 1)..'].type == kObjectTypeInteger && args.items['..(j - 1)..'].data.integer > 0) {')
- output:write('\n '..converted..' = (unsigned)args.items['..(j - 1)..'].data.integer;')
- end
- output:write('\n } else {')
- output:write('\n snprintf(error->msg, sizeof(error->msg), "Wrong type for argument '..j..', expecting '..param[1]..'");')
- output:write('\n error->set = true;')
- output:write('\n goto cleanup;')
- output:write('\n }\n')
- else
- output:write('\n '..converted..' = args.items['..(j - 1)..'];\n')
+ if fn.impl_name == nil then
+ local args = {}
+
+ output:write('Object handle_'..fn.name..'(uint64_t channel_id, uint64_t request_id, Array args, Error *error)')
+ output:write('\n{')
+ output:write('\n Object ret = NIL;')
+ -- Declare/initialize variables that will hold converted arguments
+ for j = 1, #fn.parameters do
+ local param = fn.parameters[j]
+ local converted = 'arg_'..j
+ output:write('\n '..param[1]..' '..converted..' api_init_'..string.lower(real_type(param[1]))..';')
end
+ output:write('\n')
+ output:write('\n if (args.size != '..#fn.parameters..') {')
+ output:write('\n snprintf(error->msg, sizeof(error->msg), "Wrong number of arguments: expecting '..#fn.parameters..' but got %zu", args.size);')
+ output:write('\n error->set = true;')
+ output:write('\n goto cleanup;')
+ output:write('\n }\n')
- args[#args + 1] = converted
- end
+ -- Validation/conversion for each argument
+ for j = 1, #fn.parameters do
+ local converted, convert_arg, param, arg
+ param = fn.parameters[j]
+ converted = 'arg_'..j
+ local rt = real_type(param[1])
+ if rt ~= 'Object' then
+ output:write('\n if (args.items['..(j - 1)..'].type == kObjectType'..rt..') {')
+ output:write('\n '..converted..' = args.items['..(j - 1)..'].data.'..rt:lower()..';')
+ if rt:match('^Buffer$') or rt:match('^Window$') or rt:match('^Tabpage$') or rt:match('^Boolean$') then
+ -- accept nonnegative integers for Booleans, Buffers, Windows and Tabpages
+ output:write('\n } else if (args.items['..(j - 1)..'].type == kObjectTypeInteger && args.items['..(j - 1)..'].data.integer >= 0) {')
+ output:write('\n '..converted..' = (handle_T)args.items['..(j - 1)..'].data.integer;')
+ end
+ output:write('\n } else {')
+ output:write('\n snprintf(error->msg, sizeof(error->msg), "Wrong type for argument '..j..', expecting '..param[1]..'");')
+ output:write('\n error->set = true;')
+ output:write('\n goto cleanup;')
+ output:write('\n }\n')
+ else
+ output:write('\n '..converted..' = args.items['..(j - 1)..'];\n')
+ end
- -- function call
- local call_args = table.concat(args, ', ')
- output:write('\n ')
- if fn.return_type ~= 'void' then
- -- has a return value, prefix the call with a declaration
- output:write(fn.return_type..' rv = ')
- end
+ args[#args + 1] = converted
+ end
- -- write the function name and the opening parenthesis
- output:write(fn.name..'(')
+ -- function call
+ local call_args = table.concat(args, ', ')
+ output:write('\n ')
+ if fn.return_type ~= 'void' then
+ -- has a return value, prefix the call with a declaration
+ output:write(fn.return_type..' rv = ')
+ end
- if fn.receives_channel_id then
- -- if the function receives the channel id, pass it as first argument
- if #args > 0 or fn.can_fail then
- output:write('channel_id, '..call_args)
+ -- write the function name and the opening parenthesis
+ output:write(fn.name..'(')
+
+ if fn.receives_channel_id then
+ -- if the function receives the channel id, pass it as first argument
+ if #args > 0 or fn.can_fail then
+ output:write('channel_id, '..call_args)
+ else
+ output:write('channel_id')
+ end
else
- output:write('channel_id')
+ output:write(call_args)
end
- else
- output:write(call_args)
- end
- if fn.can_fail then
- -- if the function can fail, also pass a pointer to the local error object
- if #args > 0 then
- output:write(', error);\n')
+ if fn.can_fail then
+ -- if the function can fail, also pass a pointer to the local error object
+ if #args > 0 then
+ output:write(', error);\n')
+ else
+ output:write('error);\n')
+ end
+ -- and check for the error
+ output:write('\n if (error->set) {')
+ output:write('\n goto cleanup;')
+ output:write('\n }\n')
else
- output:write('error);\n')
+ output:write(');\n')
end
- -- and check for the error
- output:write('\n if (error->set) {')
- output:write('\n goto cleanup;')
- output:write('\n }\n')
- else
- output:write(');\n')
- end
- if fn.return_type ~= 'void' then
- output:write('\n ret = '..string.upper(real_type(fn.return_type))..'_OBJ(rv);')
- end
- -- Now generate the cleanup label for freeing memory allocated for the
- -- arguments
- output:write('\n\ncleanup:');
+ if fn.return_type ~= 'void' then
+ output:write('\n ret = '..string.upper(real_type(fn.return_type))..'_OBJ(rv);')
+ end
+ output:write('\n\ncleanup:');
- for j = 1, #fn.parameters do
- local param = fn.parameters[j]
- output:write('\n api_free_'..string.lower(real_type(param[1]))..'(arg_'..j..');')
+ output:write('\n return ret;\n}\n\n');
end
- output:write('\n return ret;\n}\n\n');
end
-- Generate a function that initializes method names with handler functions
@@ -281,7 +322,7 @@ for i = 1, #functions do
output:write(' msgpack_rpc_add_method_handler('..
'(String) {.data = "'..fn.name..'", '..
'.size = sizeof("'..fn.name..'") - 1}, '..
- '(MsgpackRpcRequestHandler) {.fn = handle_'.. fn.name..
+ '(MsgpackRpcRequestHandler) {.fn = handle_'.. (fn.impl_name or fn.name)..
', .async = '..tostring(fn.async)..'});\n')
if #fn.name > max_fname_len then
@@ -311,3 +352,7 @@ MsgpackRpcRequestHandler msgpack_rpc_get_handler_for(const char *name,
]])
output:close()
+
+mpack_output = io.open(mpack_outputf, 'wb')
+mpack_output:write(packed)
+mpack_output:close()
diff --git a/scripts/geneval.lua b/scripts/geneval.lua
new file mode 100644
index 0000000000..b1ba76296c
--- /dev/null
+++ b/scripts/geneval.lua
@@ -0,0 +1,66 @@
+mpack = require('mpack')
+
+local nvimsrcdir = arg[1]
+local autodir = arg[2]
+local metadata_file = arg[3]
+local funcs_file = arg[4]
+
+if nvimsrcdir == '--help' then
+ print([[
+Usage:
+ lua geneval.lua src/nvim build/src/nvim/auto
+
+Will generate build/src/nvim/auto/funcs.generated.h with definition of functions
+static const array.
+]])
+ os.exit(0)
+end
+
+package.path = nvimsrcdir .. '/?.lua;' .. package.path
+
+local funcsfname = autodir .. '/funcs.generated.h'
+
+local gperfpipe = io.open(funcsfname .. '.gperf', 'wb')
+
+local funcs = require('eval').funcs
+local metadata = mpack.unpack(io.open(arg[3], 'rb'):read("*all"))
+for i,fun in ipairs(metadata) do
+ if not fun.noeval then
+ funcs[fun.name] = {
+ args=#fun.parameters,
+ func='api_wrapper',
+ data='&handle_'..fun.name,
+ }
+ end
+end
+
+local funcsdata = io.open(funcs_file, 'w')
+funcsdata:write(mpack.pack(funcs))
+funcsdata:close()
+
+gperfpipe:write([[
+%language=ANSI-C
+%global-table
+%define initializer-suffix ,0,0,NULL,NULL
+%define word-array-name functions
+%define hash-function-name hash_internal_func_gperf
+%define lookup-function-name find_internal_func_gperf
+%omit-struct-type
+%struct-type
+VimLFuncDef;
+%%
+]])
+
+for name, def in pairs(funcs) do
+ args = def.args or 0
+ if type(args) == 'number' then
+ args = {args, args}
+ elseif #args == 1 then
+ args[2] = 'MAX_FUNC_ARGS'
+ end
+ func = def.func or ('f_' .. name)
+ data = def.data or "NULL"
+ gperfpipe:write(('%s, %s, %s, &%s, (FunPtr)%s\n')
+ :format(name, args[1], args[2], func, data))
+end
+gperfpipe:close()
diff --git a/scripts/genvimvim.lua b/scripts/genvimvim.lua
index 667af7be6c..24c147b811 100644
--- a/scripts/genvimvim.lua
+++ b/scripts/genvimvim.lua
@@ -1,3 +1,5 @@
+mpack = require('mpack')
+
if arg[1] == '--help' then
print('Usage: lua genvimvim.lua src/nvim runtime/syntax/vim/generated.vim')
os.exit(0)
@@ -5,6 +7,7 @@ end
local nvimsrcdir = arg[1]
local syntax_file = arg[2]
+local funcs_file = arg[3]
package.path = nvimsrcdir .. '/?.lua;' .. package.path
@@ -111,28 +114,16 @@ end
w('\n\nsyn case match')
local vimfun_start = 'syn keyword vimFuncName contained '
w('\n\n' .. vimfun_start)
-eval_fd = io.open(nvimsrcdir .. '/eval.c', 'r')
+funcs = mpack.unpack(io.open(funcs_file):read("*all"))
local started = 0
-for line in eval_fd:lines() do
- if line == '} functions[] =' then
- started = 1
- elseif started == 1 then
- assert (line == '{')
- started = 2
- elseif started == 2 then
- if line == '};' then
- break
- end
- local func_name = line:match('^ { "([%w_]+)",')
- if func_name then
- if lld.line_length > 850 then
- w('\n' .. vimfun_start)
- end
- w(' ' .. func_name)
+for name, def in pairs(funcs) do
+ if name then
+ if lld.line_length > 850 then
+ w('\n' .. vimfun_start)
end
+ w(' ' .. name)
end
end
-eval_fd:close()
w('\n')
syn_fd:close()