mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
Merge pull request #5393 from bfredl/dispatchfix
refactor gendispatch.lua to move verbatim c code to .c files
This commit is contained in:
commit
2d961403ba
@ -52,16 +52,18 @@ package.path = nvimsrcdir .. '/?.lua;' .. package.path
|
|||||||
-- names of all headers relative to the source root (for inclusion in the
|
-- names of all headers relative to the source root (for inclusion in the
|
||||||
-- generated file)
|
-- generated file)
|
||||||
headers = {}
|
headers = {}
|
||||||
-- output c file(dispatch function + metadata serialized with msgpack)
|
-- output h file with generated dispatch functions
|
||||||
outputf = arg[#arg-1]
|
dispatch_outputf = arg[#arg-2]
|
||||||
-- output mpack file (metadata)
|
-- output h file with packed metadata
|
||||||
|
funcs_metadata_outputf = arg[#arg-1]
|
||||||
|
-- output metadata mpack file, for use by other build scripts
|
||||||
mpack_outputf = arg[#arg]
|
mpack_outputf = arg[#arg]
|
||||||
|
|
||||||
-- set of function names, used to detect duplicates
|
-- set of function names, used to detect duplicates
|
||||||
function_names = {}
|
function_names = {}
|
||||||
|
|
||||||
-- read each input file, parse and append to the api metadata
|
-- read each input file, parse and append to the api metadata
|
||||||
for i = 2, #arg - 2 do
|
for i = 2, #arg - 3 do
|
||||||
local full_path = arg[i]
|
local full_path = arg[i]
|
||||||
local parts = {}
|
local parts = {}
|
||||||
for part in string.gmatch(full_path, '[^/]+') do
|
for part in string.gmatch(full_path, '[^/]+') do
|
||||||
@ -165,66 +167,27 @@ for _,f in ipairs(functions) do
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- start building the output
|
funcs_metadata_output = io.open(funcs_metadata_outputf, 'wb')
|
||||||
output = io.open(outputf, 'wb')
|
funcs_metadata_output:write([[
|
||||||
|
static const uint8_t funcs_metadata[] = {
|
||||||
output:write([[
|
|
||||||
#include <inttypes.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include <msgpack.h>
|
|
||||||
|
|
||||||
#include "nvim/map.h"
|
|
||||||
#include "nvim/log.h"
|
|
||||||
#include "nvim/vim.h"
|
|
||||||
#include "nvim/msgpack_rpc/helpers.h"
|
|
||||||
#include "nvim/api/private/dispatch.h"
|
|
||||||
#include "nvim/api/private/helpers.h"
|
|
||||||
#include "nvim/api/private/defs.h"
|
|
||||||
]])
|
]])
|
||||||
|
|
||||||
for i = 1, #headers do
|
|
||||||
if headers[i]:sub(-12) ~= '.generated.h' then
|
|
||||||
output:write('\n#include "nvim/'..headers[i]..'"')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
output:write([[
|
|
||||||
|
|
||||||
|
|
||||||
static const uint8_t msgpack_metadata[] = {
|
|
||||||
|
|
||||||
]])
|
|
||||||
-- serialize the API metadata using msgpack and embed into the resulting
|
-- serialize the API metadata using msgpack and embed into the resulting
|
||||||
-- binary for easy querying by clients
|
-- binary for easy querying by clients
|
||||||
packed_exported_functions = mpack.pack(exported_functions)
|
packed_exported_functions = mpack.pack(exported_functions)
|
||||||
for i = 1, #packed_exported_functions do
|
for i = 1, #packed_exported_functions do
|
||||||
output:write(string.byte(packed_exported_functions, i)..', ')
|
funcs_metadata_output:write(string.byte(packed_exported_functions, i)..', ')
|
||||||
if i % 10 == 0 then
|
if i % 10 == 0 then
|
||||||
output:write('\n ')
|
funcs_metadata_output:write('\n ')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
output:write([[
|
funcs_metadata_output:write([[
|
||||||
};
|
};
|
||||||
|
|
||||||
void msgpack_rpc_init_function_metadata(Dictionary *metadata)
|
|
||||||
{
|
|
||||||
msgpack_unpacked unpacked;
|
|
||||||
msgpack_unpacked_init(&unpacked);
|
|
||||||
if (msgpack_unpack_next(&unpacked,
|
|
||||||
(const char *)msgpack_metadata,
|
|
||||||
sizeof(msgpack_metadata),
|
|
||||||
NULL) != MSGPACK_UNPACK_SUCCESS) {
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
Object functions;
|
|
||||||
msgpack_rpc_to_object(&unpacked.data, &functions);
|
|
||||||
msgpack_unpacked_destroy(&unpacked);
|
|
||||||
PUT(*metadata, "functions", functions);
|
|
||||||
}
|
|
||||||
|
|
||||||
]])
|
]])
|
||||||
|
funcs_metadata_output:close()
|
||||||
|
|
||||||
|
-- start building the dispatch wrapper output
|
||||||
|
output = io.open(dispatch_outputf, 'wb')
|
||||||
|
|
||||||
local function real_type(type)
|
local function real_type(type)
|
||||||
local rv = type
|
local rv = type
|
||||||
@ -336,22 +299,12 @@ end
|
|||||||
|
|
||||||
-- Generate a function that initializes method names with handler functions
|
-- Generate a function that initializes method names with handler functions
|
||||||
output:write([[
|
output:write([[
|
||||||
static Map(String, MsgpackRpcRequestHandler) *methods = NULL;
|
|
||||||
|
|
||||||
void msgpack_rpc_add_method_handler(String method, MsgpackRpcRequestHandler handler)
|
|
||||||
{
|
|
||||||
map_put(String, MsgpackRpcRequestHandler)(methods, method, handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
void msgpack_rpc_init_method_table(void)
|
void msgpack_rpc_init_method_table(void)
|
||||||
{
|
{
|
||||||
methods = map_new(String, MsgpackRpcRequestHandler)();
|
methods = map_new(String, MsgpackRpcRequestHandler)();
|
||||||
|
|
||||||
]])
|
]])
|
||||||
|
|
||||||
-- Keep track of the maximum method name length in order to avoid walking
|
|
||||||
-- strings longer than that when searching for a method handler
|
|
||||||
local max_fname_len = 0
|
|
||||||
for i = 1, #functions do
|
for i = 1, #functions do
|
||||||
local fn = functions[i]
|
local fn = functions[i]
|
||||||
output:write(' msgpack_rpc_add_method_handler('..
|
output:write(' msgpack_rpc_add_method_handler('..
|
||||||
@ -360,32 +313,9 @@ for i = 1, #functions do
|
|||||||
'(MsgpackRpcRequestHandler) {.fn = handle_'.. (fn.impl_name or fn.name)..
|
'(MsgpackRpcRequestHandler) {.fn = handle_'.. (fn.impl_name or fn.name)..
|
||||||
', .async = '..tostring(fn.async)..'});\n')
|
', .async = '..tostring(fn.async)..'});\n')
|
||||||
|
|
||||||
if #fn.name > max_fname_len then
|
|
||||||
max_fname_len = #fn.name
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
output:write('\n}\n\n')
|
output:write('\n}\n\n')
|
||||||
|
|
||||||
output:write([[
|
|
||||||
MsgpackRpcRequestHandler msgpack_rpc_get_handler_for(const char *name,
|
|
||||||
size_t name_len)
|
|
||||||
{
|
|
||||||
String m = {
|
|
||||||
.data=(char *)name,
|
|
||||||
.size=MIN(name_len, ]]..max_fname_len..[[)
|
|
||||||
};
|
|
||||||
MsgpackRpcRequestHandler rv =
|
|
||||||
map_get(String, MsgpackRpcRequestHandler)(methods, m);
|
|
||||||
|
|
||||||
if (!rv.fn) {
|
|
||||||
rv.fn = msgpack_rpc_handle_missing_method;
|
|
||||||
}
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
]])
|
|
||||||
|
|
||||||
output:close()
|
output:close()
|
||||||
|
|
||||||
mpack_output = io.open(mpack_outputf, 'wb')
|
mpack_output = io.open(mpack_outputf, 'wb')
|
||||||
|
@ -18,7 +18,8 @@ set(API_METADATA ${PROJECT_BINARY_DIR}/api_metadata.mpack)
|
|||||||
set(FUNCS_DATA ${PROJECT_BINARY_DIR}/funcs_data.mpack)
|
set(FUNCS_DATA ${PROJECT_BINARY_DIR}/funcs_data.mpack)
|
||||||
set(HEADER_GENERATOR ${PROJECT_SOURCE_DIR}/scripts/gendeclarations.lua)
|
set(HEADER_GENERATOR ${PROJECT_SOURCE_DIR}/scripts/gendeclarations.lua)
|
||||||
set(GENERATED_INCLUDES_DIR ${PROJECT_BINARY_DIR}/include)
|
set(GENERATED_INCLUDES_DIR ${PROJECT_BINARY_DIR}/include)
|
||||||
set(GENERATED_API_DISPATCH ${GENERATED_DIR}/api/private/dispatch.c)
|
set(GENERATED_API_DISPATCH ${GENERATED_DIR}/api/private/dispatch_wrappers.generated.h)
|
||||||
|
set(GENERATED_FUNCS_METADATA ${GENERATED_DIR}/api/private/funcs_metadata.generated.h)
|
||||||
set(GENERATED_EX_CMDS_ENUM ${GENERATED_INCLUDES_DIR}/ex_cmds_enum.generated.h)
|
set(GENERATED_EX_CMDS_ENUM ${GENERATED_INCLUDES_DIR}/ex_cmds_enum.generated.h)
|
||||||
set(GENERATED_EX_CMDS_DEFS ${GENERATED_DIR}/ex_cmds_defs.generated.h)
|
set(GENERATED_EX_CMDS_DEFS ${GENERATED_DIR}/ex_cmds_defs.generated.h)
|
||||||
set(GENERATED_FUNCS_HASH_INPUT ${GENERATED_DIR}/funcs.generated.h.gperf)
|
set(GENERATED_FUNCS_HASH_INPUT ${GENERATED_DIR}/funcs.generated.h.gperf)
|
||||||
@ -197,8 +198,11 @@ add_custom_command(OUTPUT ${GENERATED_UNICODE_TABLES}
|
|||||||
${UNICODE_FILES}
|
${UNICODE_FILES}
|
||||||
)
|
)
|
||||||
|
|
||||||
add_custom_command(OUTPUT ${GENERATED_API_DISPATCH} ${API_METADATA}
|
add_custom_command(OUTPUT ${GENERATED_API_DISPATCH} ${GENERATED_FUNCS_METADATA}
|
||||||
COMMAND ${LUA_PRG} ${DISPATCH_GENERATOR} ${CMAKE_CURRENT_LIST_DIR} ${API_HEADERS} ${GENERATED_API_DISPATCH} ${API_METADATA}
|
${API_METADATA}
|
||||||
|
COMMAND ${LUA_PRG} ${DISPATCH_GENERATOR} ${CMAKE_CURRENT_LIST_DIR}
|
||||||
|
${API_HEADERS} ${GENERATED_API_DISPATCH}
|
||||||
|
${GENERATED_FUNCS_METADATA} ${API_METADATA}
|
||||||
DEPENDS
|
DEPENDS
|
||||||
${API_HEADERS}
|
${API_HEADERS}
|
||||||
${MSGPACK_RPC_HEADERS}
|
${MSGPACK_RPC_HEADERS}
|
||||||
|
45
src/nvim/api/private/dispatch.c
Normal file
45
src/nvim/api/private/dispatch.c
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
#include <inttypes.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <msgpack.h>
|
||||||
|
|
||||||
|
#include "nvim/map.h"
|
||||||
|
#include "nvim/log.h"
|
||||||
|
#include "nvim/vim.h"
|
||||||
|
#include "nvim/msgpack_rpc/helpers.h"
|
||||||
|
#include "nvim/api/private/dispatch.h"
|
||||||
|
#include "nvim/api/private/helpers.h"
|
||||||
|
#include "nvim/api/private/defs.h"
|
||||||
|
|
||||||
|
#include "nvim/api/buffer.h"
|
||||||
|
#include "nvim/api/tabpage.h"
|
||||||
|
#include "nvim/api/ui.h"
|
||||||
|
#include "nvim/api/vim.h"
|
||||||
|
#include "nvim/api/window.h"
|
||||||
|
|
||||||
|
static Map(String, MsgpackRpcRequestHandler) *methods = NULL;
|
||||||
|
|
||||||
|
static void msgpack_rpc_add_method_handler(String method,
|
||||||
|
MsgpackRpcRequestHandler handler)
|
||||||
|
{
|
||||||
|
map_put(String, MsgpackRpcRequestHandler)(methods, method, handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
MsgpackRpcRequestHandler msgpack_rpc_get_handler_for(const char *name,
|
||||||
|
size_t name_len)
|
||||||
|
{
|
||||||
|
String m = { .data = (char *)name, .size = name_len };
|
||||||
|
MsgpackRpcRequestHandler rv =
|
||||||
|
map_get(String, MsgpackRpcRequestHandler)(methods, m);
|
||||||
|
|
||||||
|
if (!rv.fn) {
|
||||||
|
rv.fn = msgpack_rpc_handle_missing_method;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
|
#include "api/private/dispatch_wrappers.generated.h"
|
||||||
|
#endif
|
@ -18,6 +18,7 @@ typedef struct {
|
|||||||
|
|
||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
# include "api/private/dispatch.h.generated.h"
|
# include "api/private/dispatch.h.generated.h"
|
||||||
|
# include "api/private/dispatch_wrappers.h.generated.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // NVIM_API_PRIVATE_DISPATCH_H
|
#endif // NVIM_API_PRIVATE_DISPATCH_H
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "nvim/api/private/helpers.h"
|
#include "nvim/api/private/helpers.h"
|
||||||
#include "nvim/api/private/defs.h"
|
#include "nvim/api/private/defs.h"
|
||||||
#include "nvim/api/private/handle.h"
|
#include "nvim/api/private/handle.h"
|
||||||
|
#include "nvim/msgpack_rpc/helpers.h"
|
||||||
#include "nvim/ascii.h"
|
#include "nvim/ascii.h"
|
||||||
#include "nvim/vim.h"
|
#include "nvim/vim.h"
|
||||||
#include "nvim/buffer.h"
|
#include "nvim/buffer.h"
|
||||||
@ -27,6 +28,7 @@ typedef struct {
|
|||||||
|
|
||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
# include "api/private/helpers.c.generated.h"
|
# include "api/private/helpers.c.generated.h"
|
||||||
|
# include "api/private/funcs_metadata.generated.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// Start block that may cause vimscript exceptions
|
/// Start block that may cause vimscript exceptions
|
||||||
@ -761,7 +763,7 @@ Dictionary api_metadata(void)
|
|||||||
static Dictionary metadata = ARRAY_DICT_INIT;
|
static Dictionary metadata = ARRAY_DICT_INIT;
|
||||||
|
|
||||||
if (!metadata.size) {
|
if (!metadata.size) {
|
||||||
msgpack_rpc_init_function_metadata(&metadata);
|
init_function_metadata(&metadata);
|
||||||
init_error_type_metadata(&metadata);
|
init_error_type_metadata(&metadata);
|
||||||
init_type_metadata(&metadata);
|
init_type_metadata(&metadata);
|
||||||
}
|
}
|
||||||
@ -769,6 +771,22 @@ Dictionary api_metadata(void)
|
|||||||
return copy_object(DICTIONARY_OBJ(metadata)).data.dictionary;
|
return copy_object(DICTIONARY_OBJ(metadata)).data.dictionary;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void init_function_metadata(Dictionary *metadata)
|
||||||
|
{
|
||||||
|
msgpack_unpacked unpacked;
|
||||||
|
msgpack_unpacked_init(&unpacked);
|
||||||
|
if (msgpack_unpack_next(&unpacked,
|
||||||
|
(const char *)funcs_metadata,
|
||||||
|
sizeof(funcs_metadata),
|
||||||
|
NULL) != MSGPACK_UNPACK_SUCCESS) {
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
Object functions;
|
||||||
|
msgpack_rpc_to_object(&unpacked.data, &functions);
|
||||||
|
msgpack_unpacked_destroy(&unpacked);
|
||||||
|
PUT(*metadata, "functions", functions);
|
||||||
|
}
|
||||||
|
|
||||||
static void init_error_type_metadata(Dictionary *metadata)
|
static void init_error_type_metadata(Dictionary *metadata)
|
||||||
{
|
{
|
||||||
Dictionary types = ARRAY_DICT_INIT;
|
Dictionary types = ARRAY_DICT_INIT;
|
||||||
@ -784,6 +802,7 @@ static void init_error_type_metadata(Dictionary *metadata)
|
|||||||
|
|
||||||
PUT(*metadata, "error_types", DICTIONARY_OBJ(types));
|
PUT(*metadata, "error_types", DICTIONARY_OBJ(types));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void init_type_metadata(Dictionary *metadata)
|
static void init_type_metadata(Dictionary *metadata)
|
||||||
{
|
{
|
||||||
Dictionary types = ARRAY_DICT_INIT;
|
Dictionary types = ARRAY_DICT_INIT;
|
||||||
|
Loading…
Reference in New Issue
Block a user