From 545acf2024ea2653ae6937d570a37aa0340caa5e Mon Sep 17 00:00:00 2001 From: Thiago de Arruda Date: Fri, 12 Sep 2014 11:24:01 -0300 Subject: api metadata: Allow typed container information in api functions Adapt gendeclarations.lua/msgpack-gen.lua to allow the `ArrayOf(...)` and `DictionaryOf(...)` types in function headers. These are simple macros that expand to Array and Dictionary respectively, but the information is kept in the metadata object, which is useful for building clients in statically typed languages. --- scripts/gendeclarations.lua | 15 +++++++++++---- scripts/msgpack-gen.lua | 28 +++++++++++++++++++++++----- 2 files changed, 34 insertions(+), 9 deletions(-) (limited to 'scripts') diff --git a/scripts/gendeclarations.lua b/scripts/gendeclarations.lua index 76711cc214..bc55b48a0a 100755 --- a/scripts/gendeclarations.lua +++ b/scripts/gendeclarations.lua @@ -59,9 +59,16 @@ local right_word = concat( raw_word, neg_look_ahead(aw) ) -local word = concat( - neg_look_behind(aw), - right_word +local word = branch( + concat( + branch(lit('ArrayOf('), lit('DictionaryOf(')), -- typed container macro + one_or_more(any_character - lit(')')), + lit(')') + ), + concat( + neg_look_behind(aw), + right_word + ) ) local spaces = any_amount(branch( s, @@ -204,7 +211,7 @@ while init ~= nil do declaration = declaration:gsub('\n', ' ') declaration = declaration:gsub('%s+', ' ') declaration = declaration:gsub(' ?%( ?', '(') - declaration = declaration:gsub(' ?%) ?', ')') + -- declaration = declaration:gsub(' ?%) ?', ')') declaration = declaration:gsub(' ?, ?', ', ') declaration = declaration:gsub(' ?(%*+) ?', ' %1') declaration = declaration:gsub(' ?(FUNC_ATTR_)', ' %1') diff --git a/scripts/msgpack-gen.lua b/scripts/msgpack-gen.lua index 8fbf64ebc0..68faa18c31 100644 --- a/scripts/msgpack-gen.lua +++ b/scripts/msgpack-gen.lua @@ -16,7 +16,12 @@ ws = S(' \t') + nl fill = ws ^ 0 c_comment = P('//') * (not_nl ^ 0) c_preproc = P('#') * (not_nl ^ 0) -c_id = letter * (alpha ^ 0) +typed_container = + (P('ArrayOf(') + P('DictionaryOf(')) * ((any - P(')')) ^ 1) * P(')') +c_id = ( + typed_container + + (letter * (alpha ^ 0)) +) c_void = P('void') c_param_type = ( ((P('Error') * fill * P('*') * fill) * Cc('error')) + @@ -90,6 +95,7 @@ output:write([[ #include "nvim/os/msgpack_rpc.h" #include "nvim/os/msgpack_rpc_helpers.h" #include "nvim/api/private/helpers.h" +#include "nvim/api/private/defs.h" ]]) for i = 1, #headers do @@ -132,6 +138,18 @@ void msgpack_rpc_init_function_metadata(Dictionary *metadata) ]]) +local function real_type(type) + local rv = type + if typed_container:match(rv) then + if rv:match('Array') then + rv = 'Array' + else + rv = 'Dictionary' + end + end + return rv +end + -- start the handler functions. Visit each function metadata to build the -- handler function with code generated for validating arguments and calling to -- the real API. @@ -146,7 +164,7 @@ for i = 1, #functions do 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(param[1])..';') + output:write('\n '..param[1]..' '..converted..' api_init_'..string.lower(real_type(param[1]))..';') end output:write('\n') output:write('\n if (req->via.array.ptr[3].via.array.size != '..#fn.parameters..') {') @@ -161,7 +179,7 @@ for i = 1, #functions do param = fn.parameters[j] arg = '(req->via.array.ptr[3].via.array.ptr + '..(j - 1)..')' converted = 'arg_'..j - convert_arg = 'msgpack_rpc_to_'..string.lower(param[1]) + convert_arg = 'msgpack_rpc_to_'..real_type(param[1]):lower() output:write('\n if (!'..convert_arg..'('..arg..', &'..converted..')) {') output:write('\n snprintf(error->msg, sizeof(error->msg), "Wrong type for argument '..j..', expecting '..param[1]..'");') output:write('\n error->set = true;') @@ -208,7 +226,7 @@ for i = 1, #functions do end if fn.return_type ~= 'void' then - output:write('\n Object ret = '..string.upper(fn.return_type)..'_OBJ(rv);') + output:write('\n Object ret = '..string.upper(real_type(fn.return_type))..'_OBJ(rv);') end -- Now generate the cleanup label for freeing memory allocated for the -- arguments @@ -216,7 +234,7 @@ for i = 1, #functions do for j = 1, #fn.parameters do local param = fn.parameters[j] - output:write('\n api_free_'..string.lower(param[1])..'(arg_'..j..');') + output:write('\n api_free_'..string.lower(real_type(param[1]))..'(arg_'..j..');') end if fn.return_type ~= 'void' then output:write('\n return ret;\n}\n\n'); -- cgit