1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
---@diagnostic disable: no-unknown
local mpack = vim.mpack
local funcsfname = arg[1]
local metadata_file = arg[2]
local funcs_file = arg[3]
local eval_file = arg[4]
--Will generate funcs.generated.h with definition of functions static const array.
local hashy = require 'gen.hashy'
local hashpipe = assert(io.open(funcsfname, 'wb'))
hashpipe:write([[
#include "nvim/arglist.h"
#include "nvim/channel.h"
#include "nvim/cmdexpand.h"
#include "nvim/cmdhist.h"
#include "nvim/diff.h"
#include "nvim/digraph.h"
#include "nvim/eval.h"
#include "nvim/eval/buffer.h"
#include "nvim/eval/deprecated.h"
#include "nvim/eval/fs.h"
#include "nvim/eval/funcs.h"
#include "nvim/eval/list.h"
#include "nvim/eval/typval.h"
#include "nvim/eval/vars.h"
#include "nvim/eval/window.h"
#include "nvim/ex_docmd.h"
#include "nvim/ex_getln.h"
#include "nvim/fold.h"
#include "nvim/fuzzy.h"
#include "nvim/indent.h"
#include "nvim/indent_c.h"
#include "nvim/input.h"
#include "nvim/insexpand.h"
#include "nvim/mapping.h"
#include "nvim/match.h"
#include "nvim/mbyte.h"
#include "nvim/menu.h"
#include "nvim/mouse.h"
#include "nvim/move.h"
#include "nvim/quickfix.h"
#include "nvim/runtime.h"
#include "nvim/search.h"
#include "nvim/sign.h"
#include "nvim/state.h"
#include "nvim/strings.h"
#include "nvim/testing.h"
#include "nvim/undo.h"
]])
local funcs = loadfile(eval_file)().funcs
for name, func in pairs(funcs) do
local n = (func.func_float and 1 or 0) + (func.func_lua and 1 or 0) + (func.func and 1 or 0)
assert(n <= 1, name .. ': only one of func, func_float, func_lua can be set')
if func.func_float then
func.func = 'float_op_wrapper'
func.data = '{ .func_float = &' .. func.func_float .. ' }'
elseif func.func_lua then
func.func = 'lua_wrapper'
func.data = '{ .func_lua = "' .. func.func_lua .. '" }'
end
end
local metadata = mpack.decode(io.open(metadata_file, 'rb'):read('*all'))
for _, fun in ipairs(metadata) do
if fun.eval then
local args
if type(fun.opts_idx) == 'number' then
args = { fun.opts_idx - 1, #fun.parameters }
else
args = #fun.parameters
end
funcs[fun.name] = {
args = args,
func = 'api_wrapper',
data = '{ .func_api = &method_handlers[' .. fun.handler_id .. '] }',
}
end
end
local func_names = vim.tbl_filter(function(name)
return name:match('__%d*$') == nil
end, vim.tbl_keys(funcs))
table.sort(func_names)
local funcsdata = assert(io.open(funcs_file, 'w'))
funcsdata:write(mpack.encode(func_names))
funcsdata:close()
local neworder, hashfun = hashy.hashy_hash('find_internal_func', func_names, function(idx)
return 'functions[' .. idx .. '].name'
end)
hashpipe:write('static const EvalFuncDef functions[] = {\n')
for _, name in ipairs(neworder) do
local def = funcs[name]
local min_args = 0
local max_args = 0 --- @type integer|string
local def_args = def.args
if type(def_args) == 'number' then
min_args, max_args = def_args, def_args
elseif type(def_args) == 'table' then
min_args = def_args[1] or 0
max_args = def_args[2] or 'MAX_FUNC_ARGS'
end
local base = def.base or 'BASE_NONE'
local func = def.func or ('f_' .. name)
local data = def.data or '{ .null = NULL }'
local fast = def.fast and 'true' or 'false'
hashpipe:write(
(' { "%s", %s, %s, %s, %s, &%s, %s },\n'):format(
name,
min_args,
max_args,
base,
fast,
func,
data
)
)
end
hashpipe:write(' { NULL, 0, 0, BASE_NONE, false, NULL, { .null = NULL } },\n')
hashpipe:write('};\n\n')
hashpipe:write(hashfun)
hashpipe:close()
|