From 2faab06ed3bfad11fceb1108614420c1b9edbd5d Mon Sep 17 00:00:00 2001 From: Donald Lee Date: Tue, 10 Aug 2021 04:36:30 +0800 Subject: [PATCH 1/6] lib: Add polymorphic noop macro Co-authored-by: Quentin Young Signed-off-by: Quentin Young Signed-off-by: Donald Lee --- lib/frrscript.c | 2 ++ lib/frrscript.h | 13 ++++++------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/lib/frrscript.c b/lib/frrscript.c index 50410fb58b..acdd1df67b 100644 --- a/lib/frrscript.c +++ b/lib/frrscript.c @@ -25,6 +25,8 @@ DEFINE_MTYPE_STATIC(LIB, SCRIPT, "Scripting"); struct frrscript_names_head frrscript_names_hash; +void _lua_decode_noop(lua_State *L, ...) {} + /* * Wrapper for frrscript_names_add * Use this to register hook calls when a daemon starts up diff --git a/lib/frrscript.h b/lib/frrscript.h index df49b5718c..a662a808d7 100644 --- a/lib/frrscript.h +++ b/lib/frrscript.h @@ -180,6 +180,11 @@ void frrscript_fini(void); assert(lua_gettop(lfs->L) == 1); \ } while (0) +/* + * Noop function. Used below where we need a noop decoder for any type. + */ +void _lua_decode_noop(lua_State *, ...); + /* * Maps the type of value to its encoder/decoder. * Add new mappings here. @@ -220,13 +225,7 @@ struct in6_addr * : lua_decode_in6addr, \ union sockunion * : lua_decode_sockunion, \ char * : lua_decode_stringp, \ struct attr * : lua_decode_attr, \ -struct peer * : lua_decode_noop, \ -const struct prefix * : lua_decode_noop, \ -const struct ipaddr * : lua_decode_noop, \ -const struct ethaddr * : lua_decode_noop, \ -const struct nexthop_group * : lua_decode_noop, \ -const struct nexthop * : lua_decode_noop, \ -struct zebra_dplane_ctx * : lua_decode_noop \ +default : _lua_decode_noop \ )((L), -1, (value)) /* From ac3fdc60df78cb2b301943e6fdf78b5efe9df66a Mon Sep 17 00:00:00 2001 From: Donald Lee Date: Tue, 10 Aug 2021 04:37:32 +0800 Subject: [PATCH 2/6] lib: Add more Lua types to encoder/decoder Signed-off-by: Donald Lee --- lib/frrscript.h | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/frrscript.h b/lib/frrscript.h index a662a808d7..f842dd9f45 100644 --- a/lib/frrscript.h +++ b/lib/frrscript.h @@ -197,6 +197,7 @@ void _lua_decode_noop(lua_State *, ...); #define ENCODE_ARGS_WITH_STATE(L, value) \ _Generic((value), \ int : lua_pushinteger, \ +long long : lua_pushinteger, \ long long * : lua_pushintegerp, \ struct prefix * : lua_pushprefix, \ struct interface * : lua_pushinterface, \ From ac91b343d635f056e8de47224719ed6218e79dfb Mon Sep 17 00:00:00 2001 From: Donald Lee Date: Tue, 10 Aug 2021 04:39:15 +0800 Subject: [PATCH 3/6] lib: Remove old noop decoders Co-authored-by: Quentin Young Signed-off-by: Quentin Young Signed-off-by: Donald Lee --- lib/frrlua.c | 15 --------------- lib/frrlua.h | 7 ------- 2 files changed, 22 deletions(-) diff --git a/lib/frrlua.c b/lib/frrlua.c index e626efe20b..720e95491a 100644 --- a/lib/frrlua.c +++ b/lib/frrlua.c @@ -345,21 +345,6 @@ void *lua_tostringp(lua_State *L, int idx) return string; } -/* - * Decoder for const values, since we cannot modify them. - */ -void lua_decode_noop(lua_State *L, int idx, const void *ptr) -{ -} - - -/* - * Noop decoder for int. - */ -void lua_decode_integer_noop(lua_State *L, int idx, int i) -{ -} - /* * Logging. * diff --git a/lib/frrlua.h b/lib/frrlua.h index d248312d62..61fab328fe 100644 --- a/lib/frrlua.h +++ b/lib/frrlua.h @@ -143,13 +143,6 @@ void lua_decode_stringp(lua_State *L, int idx, char *str); */ void *lua_tostringp(lua_State *L, int idx); -/* - * No-op decoders - */ -void lua_decode_noop(lua_State *L, int idx, const void *ptr); - -void lua_decode_integer_noop(lua_State *L, int idx, int i); - /* * Retrieve an integer from table on the top of the stack. * From d2acf63f16837caaadd093927c236b742c19fd75 Mon Sep 17 00:00:00 2001 From: Donald Lee Date: Tue, 10 Aug 2021 04:41:25 +0800 Subject: [PATCH 4/6] lib: Create encoders for int and rename stuff Create encoders/decoders for int and rename current int encoders /decoders to long long. Signed-off-by: Donald Lee --- lib/frrlua.c | 28 +++++++++++++++++++++++++--- lib/frrlua.h | 19 +++++++++++++++++-- lib/frrscript.h | 7 ++++--- tests/lib/test_frrlua.c | 12 ++++++++++-- 4 files changed, 56 insertions(+), 10 deletions(-) diff --git a/lib/frrlua.c b/lib/frrlua.c index 720e95491a..0e95e49c6f 100644 --- a/lib/frrlua.c +++ b/lib/frrlua.c @@ -259,12 +259,12 @@ void *lua_tosockunion(lua_State *L, int idx) return su; } -void lua_pushintegerp(lua_State *L, const long long *num) +void lua_pushintegerp(lua_State *L, const int *num) { lua_pushinteger(L, *num); } -void lua_decode_integerp(lua_State *L, int idx, long long *num) +void lua_decode_integerp(lua_State *L, int idx, int *num) { int isnum; *num = lua_tonumberx(L, idx, &isnum); @@ -274,7 +274,7 @@ void lua_decode_integerp(lua_State *L, int idx, long long *num) void *lua_tointegerp(lua_State *L, int idx) { - long long *num = XCALLOC(MTYPE_SCRIPT_RES, sizeof(long long)); + int *num = XCALLOC(MTYPE_TMP, sizeof(int)); lua_decode_integerp(L, idx, num); return num; @@ -332,6 +332,28 @@ void lua_pushnexthop_group(lua_State *L, const struct nexthop_group *ng) } } +void lua_pushlonglongp(lua_State *L, const long long *num) +{ + /* lua library function; this can take a long long */ + lua_pushinteger(L, *num); +} + +void lua_decode_longlongp(lua_State *L, int idx, long long *num) +{ + int isnum; + *num = lua_tonumberx(L, idx, &isnum); + lua_pop(L, 1); + assert(isnum); +} + +void *lua_tolonglongp(lua_State *L, int idx) +{ + long long *num = XCALLOC(MTYPE_TMP, sizeof(long long)); + + lua_decode_longlongp(L, idx, num); + return num; +} + void lua_decode_stringp(lua_State *L, int idx, char *str) { strlcpy(str, lua_tostring(L, idx), strlen(str) + 1); diff --git a/lib/frrlua.h b/lib/frrlua.h index 61fab328fe..dc0f4d9986 100644 --- a/lib/frrlua.h +++ b/lib/frrlua.h @@ -121,9 +121,9 @@ void lua_pushnexthop(lua_State *L, const struct nexthop *nexthop); /* * Converts an int to a Lua value and pushes it on the stack. */ -void lua_pushintegerp(lua_State *L, const long long *num); +void lua_pushintegerp(lua_State *L, const int *num); -void lua_decode_integerp(lua_State *L, int idx, long long *num); +void lua_decode_integerp(lua_State *L, int idx, int *num); /* * Converts the Lua value at idx to an int. @@ -133,6 +133,21 @@ void lua_decode_integerp(lua_State *L, int idx, long long *num); */ void *lua_tointegerp(lua_State *L, int idx); +/* + * Converts a long long to a Lua value and pushes it on the stack. + */ +void lua_pushlonglongp(lua_State *L, const long long *num); + +void lua_decode_longlongp(lua_State *L, int idx, long long *num); + +/* + * Converts the Lua value at idx to a long long. + * + * Returns: + * long long allocated with MTYPE_TMP. + */ +void *lua_tolonglongp(lua_State *L, int idx); + void lua_decode_stringp(lua_State *L, int idx, char *str); /* diff --git a/lib/frrscript.h b/lib/frrscript.h index f842dd9f45..ce313a1b63 100644 --- a/lib/frrscript.h +++ b/lib/frrscript.h @@ -197,8 +197,9 @@ void _lua_decode_noop(lua_State *, ...); #define ENCODE_ARGS_WITH_STATE(L, value) \ _Generic((value), \ int : lua_pushinteger, \ +int * : lua_pushintegerp, \ long long : lua_pushinteger, \ -long long * : lua_pushintegerp, \ +long long * : lua_pushlonglongp, \ struct prefix * : lua_pushprefix, \ struct interface * : lua_pushinterface, \ struct in_addr * : lua_pushinaddr, \ @@ -217,8 +218,8 @@ struct zebra_dplane_ctx * : lua_pushzebra_dplane_ctx \ #define DECODE_ARGS_WITH_STATE(L, value) \ _Generic((value), \ -int : lua_decode_integer_noop, \ -long long * : lua_decode_integerp, \ +int * : lua_decode_integerp, \ +long long * : lua_decode_longlongp, \ struct prefix * : lua_decode_prefix, \ struct interface * : lua_decode_interface, \ struct in_addr * : lua_decode_inaddr, \ diff --git a/tests/lib/test_frrlua.c b/tests/lib/test_frrlua.c index 701e171c84..2760a273bd 100644 --- a/tests/lib/test_frrlua.c +++ b/tests/lib/test_frrlua.c @@ -13,14 +13,22 @@ static void test_encode_decode(void) { lua_State *L = luaL_newstate(); - long long a = 123; - long long b = a; + int a = 123; + int b = a; lua_pushintegerp(L, &a); lua_decode_integerp(L, -1, &a); assert(a == b); assert(lua_gettop(L) == 0); + long long ll_a = 123L; + long long ll_b = a; + + lua_pushlonglongp(L, &ll_a); + lua_decode_longlongp(L, -1, &ll_a); + assert(ll_a == ll_b); + assert(lua_gettop(L) == 0); + time_t time_a = 100; time_t time_b; From 5042b8e6beb9ff0b9f4a75fcf924c4d46b095bf2 Mon Sep 17 00:00:00 2001 From: Donald Lee Date: Fri, 9 Jul 2021 04:47:17 +0800 Subject: [PATCH 5/6] doc: Remove mention of const noop decoder Now handled by _lua_noop Signed-off-by: Donald Lee --- doc/developer/scripting.rst | 6 ------ 1 file changed, 6 deletions(-) diff --git a/doc/developer/scripting.rst b/doc/developer/scripting.rst index 202f0036f8..7a43314490 100644 --- a/doc/developer/scripting.rst +++ b/doc/developer/scripting.rst @@ -488,12 +488,6 @@ match *exactly*. In the above example, we defined encoders/decoders for a value of ``struct prefix *``, but not ``struct prefix`` or ``const struct prefix *``. -``const`` values are a special case. We want to use them in our Lua scripts -but not modify them, so creating a decoder for them would be meaningless. -But we still need a decoder for the type of value so that the compiler will be -satisfied. -For that, use ``lua_decode_noop``: - .. code-block:: diff #define DECODE_ARGS_WITH_STATE(L, value) \ From fca8ee275c1f51e19aa64a4cc5175cbc88bf8d41 Mon Sep 17 00:00:00 2001 From: Donald Lee Date: Tue, 10 Aug 2021 04:54:50 +0800 Subject: [PATCH 6/6] lib: Update int and ll decoders with new MTYPE In the master branch a new MTYPE_SCRIPT_RES was created for frrscript_get_results, lua_to decoders should use that Signed-off-by: Donald Lee --- lib/frrlua.c | 4 ++-- tests/lib/test_frrscript.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/frrlua.c b/lib/frrlua.c index 0e95e49c6f..2cab1a5460 100644 --- a/lib/frrlua.c +++ b/lib/frrlua.c @@ -274,7 +274,7 @@ void lua_decode_integerp(lua_State *L, int idx, int *num) void *lua_tointegerp(lua_State *L, int idx) { - int *num = XCALLOC(MTYPE_TMP, sizeof(int)); + int *num = XCALLOC(MTYPE_SCRIPT_RES, sizeof(int)); lua_decode_integerp(L, idx, num); return num; @@ -348,7 +348,7 @@ void lua_decode_longlongp(lua_State *L, int idx, long long *num) void *lua_tolonglongp(lua_State *L, int idx) { - long long *num = XCALLOC(MTYPE_TMP, sizeof(long long)); + long long *num = XCALLOC(MTYPE_SCRIPT_RES, sizeof(long long)); lua_decode_longlongp(L, idx, num); return num; diff --git a/tests/lib/test_frrscript.c b/tests/lib/test_frrscript.c index 7d4746cf3e..9698aeaa6c 100644 --- a/tests/lib/test_frrscript.c +++ b/tests/lib/test_frrscript.c @@ -32,7 +32,7 @@ int main(int argc, char **argv) assert(result == 0); result = frrscript_call(fs, "bar", ("a", &a), ("b", &b)); assert(result == 0); - long long *cptr = frrscript_get_result(fs, "bar", "c", lua_tointegerp); + long long *cptr = frrscript_get_result(fs, "bar", "c", lua_tolonglongp); /* a should not occur in the returned table in script */ assert(a == 100); @@ -47,7 +47,7 @@ int main(int argc, char **argv) result = frrscript_call(fs, "fact", ("n", &n)); assert(result == 0); long long *ansptr = - frrscript_get_result(fs, "fact", "ans", lua_tointegerp); + frrscript_get_result(fs, "fact", "ans", lua_tolonglongp); assert(*ansptr == 120); /* check consecutive call + get_result without re-loading */