diff options
| -rw-r--r-- | scripts/gendispatch.lua | 102 | ||||
| -rw-r--r-- | src/nvim/CMakeLists.txt | 10 | ||||
| -rw-r--r-- | src/nvim/api/private/dispatch.c | 45 | ||||
| -rw-r--r-- | src/nvim/api/private/dispatch.h | 1 | ||||
| -rw-r--r-- | src/nvim/api/private/helpers.c | 21 | 
5 files changed, 89 insertions, 90 deletions
| diff --git a/scripts/gendispatch.lua b/scripts/gendispatch.lua index 00ed84212b..4f00783825 100644 --- a/scripts/gendispatch.lua +++ b/scripts/gendispatch.lua @@ -52,16 +52,18 @@ package.path = nvimsrcdir .. '/?.lua;' .. package.path  -- names of all headers relative to the source root (for inclusion in the  -- generated file)  headers = {} --- output c file(dispatch function + metadata serialized with msgpack) -outputf = arg[#arg-1] --- output mpack file (metadata) +-- output h file with generated dispatch functions +dispatch_outputf = arg[#arg-2] +-- 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]  -- set of function names, used to detect duplicates  function_names = {}  -- 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 parts = {}    for part in string.gmatch(full_path, '[^/]+') do @@ -165,66 +167,27 @@ for _,f in ipairs(functions) do  end --- start building the output -output = io.open(outputf, 'wb') - -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" +funcs_metadata_output = io.open(funcs_metadata_outputf, 'wb') +funcs_metadata_output:write([[ +static const uint8_t funcs_metadata[] = {  ]]) -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  -- binary for easy querying by clients  packed_exported_functions = mpack.pack(exported_functions)  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 -    output:write('\n  ') +    funcs_metadata_output:write('\n  ')    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 rv = type @@ -336,22 +299,12 @@ end  -- Generate a function that initializes method names with handler functions  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)  {    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    local fn = functions[i]    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)..                 ', .async = '..tostring(fn.async)..'});\n') -  if #fn.name > max_fname_len then -    max_fname_len = #fn.name -  end  end  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()  mpack_output = io.open(mpack_outputf, 'wb') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index cbea6a05c9..49edfda838 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -18,7 +18,8 @@ set(API_METADATA ${PROJECT_BINARY_DIR}/api_metadata.mpack)  set(FUNCS_DATA ${PROJECT_BINARY_DIR}/funcs_data.mpack)  set(HEADER_GENERATOR ${PROJECT_SOURCE_DIR}/scripts/gendeclarations.lua)  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_DEFS ${GENERATED_DIR}/ex_cmds_defs.generated.h)  set(GENERATED_FUNCS_HASH_INPUT ${GENERATED_DIR}/funcs.generated.h.gperf) @@ -197,8 +198,11 @@ add_custom_command(OUTPUT ${GENERATED_UNICODE_TABLES}      ${UNICODE_FILES}  ) -add_custom_command(OUTPUT ${GENERATED_API_DISPATCH} ${API_METADATA} -    COMMAND ${LUA_PRG} ${DISPATCH_GENERATOR} ${CMAKE_CURRENT_LIST_DIR} ${API_HEADERS} ${GENERATED_API_DISPATCH} ${API_METADATA} +add_custom_command(OUTPUT ${GENERATED_API_DISPATCH} ${GENERATED_FUNCS_METADATA} +                          ${API_METADATA} +  COMMAND ${LUA_PRG} ${DISPATCH_GENERATOR} ${CMAKE_CURRENT_LIST_DIR} +                     ${API_HEADERS} ${GENERATED_API_DISPATCH} +                     ${GENERATED_FUNCS_METADATA} ${API_METADATA}    DEPENDS      ${API_HEADERS}      ${MSGPACK_RPC_HEADERS} diff --git a/src/nvim/api/private/dispatch.c b/src/nvim/api/private/dispatch.c new file mode 100644 index 0000000000..9b3bcc380a --- /dev/null +++ b/src/nvim/api/private/dispatch.c @@ -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 diff --git a/src/nvim/api/private/dispatch.h b/src/nvim/api/private/dispatch.h index d91456c306..c12cf9e698 100644 --- a/src/nvim/api/private/dispatch.h +++ b/src/nvim/api/private/dispatch.h @@ -18,6 +18,7 @@ typedef struct {  #ifdef INCLUDE_GENERATED_DECLARATIONS  # include "api/private/dispatch.h.generated.h" +# include "api/private/dispatch_wrappers.h.generated.h"  #endif  #endif  // NVIM_API_PRIVATE_DISPATCH_H diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c index d80ee7dc67..c0ee735d1a 100644 --- a/src/nvim/api/private/helpers.c +++ b/src/nvim/api/private/helpers.c @@ -7,6 +7,7 @@  #include "nvim/api/private/helpers.h"  #include "nvim/api/private/defs.h"  #include "nvim/api/private/handle.h" +#include "nvim/msgpack_rpc/helpers.h"  #include "nvim/ascii.h"  #include "nvim/vim.h"  #include "nvim/buffer.h" @@ -27,6 +28,7 @@ typedef struct {  #ifdef INCLUDE_GENERATED_DECLARATIONS  # include "api/private/helpers.c.generated.h" +# include "api/private/funcs_metadata.generated.h"  #endif  /// Start block that may cause vimscript exceptions @@ -761,7 +763,7 @@ Dictionary api_metadata(void)    static Dictionary metadata = ARRAY_DICT_INIT;    if (!metadata.size) { -    msgpack_rpc_init_function_metadata(&metadata); +    init_function_metadata(&metadata);      init_error_type_metadata(&metadata);      init_type_metadata(&metadata);    } @@ -769,6 +771,22 @@ Dictionary api_metadata(void)    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)  {    Dictionary types = ARRAY_DICT_INIT; @@ -784,6 +802,7 @@ static void init_error_type_metadata(Dictionary *metadata)    PUT(*metadata, "error_types", DICTIONARY_OBJ(types));  } +  static void init_type_metadata(Dictionary *metadata)  {    Dictionary types = ARRAY_DICT_INIT; | 
