summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/developer/scripting.rst6
-rw-r--r--lib/frrlua.c41
-rw-r--r--lib/frrlua.h26
-rw-r--r--lib/frrscript.c2
-rw-r--r--lib/frrscript.h21
-rw-r--r--tests/lib/test_frrlua.c12
-rw-r--r--tests/lib/test_frrscript.c4
7 files changed, 66 insertions, 46 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) \
diff --git a/lib/frrlua.c b/lib/frrlua.c
index e626efe20b..2cab1a5460 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_SCRIPT_RES, sizeof(int));
lua_decode_integerp(L, idx, num);
return num;
@@ -332,32 +332,39 @@ void lua_pushnexthop_group(lua_State *L, const struct nexthop_group *ng)
}
}
-void lua_decode_stringp(lua_State *L, int idx, char *str)
+void lua_pushlonglongp(lua_State *L, const long long *num)
{
- strlcpy(str, lua_tostring(L, idx), strlen(str) + 1);
+ /* 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_tostringp(lua_State *L, int idx)
+void *lua_tolonglongp(lua_State *L, int idx)
{
- char *string = XSTRDUP(MTYPE_SCRIPT_RES, lua_tostring(L, idx));
+ long long *num = XCALLOC(MTYPE_SCRIPT_RES, sizeof(long long));
- return string;
+ lua_decode_longlongp(L, idx, num);
+ return num;
}
-/*
- * Decoder for const values, since we cannot modify them.
- */
-void lua_decode_noop(lua_State *L, int idx, const void *ptr)
+void lua_decode_stringp(lua_State *L, int idx, char *str)
{
+ strlcpy(str, lua_tostring(L, idx), strlen(str) + 1);
+ lua_pop(L, 1);
}
-
-/*
- * Noop decoder for int.
- */
-void lua_decode_integer_noop(lua_State *L, int idx, int i)
+void *lua_tostringp(lua_State *L, int idx)
{
+ char *string = XSTRDUP(MTYPE_SCRIPT_RES, lua_tostring(L, idx));
+
+ return string;
}
/*
diff --git a/lib/frrlua.h b/lib/frrlua.h
index d248312d62..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);
/*
@@ -144,13 +159,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.
*
* key
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..ce313a1b63 100644
--- a/lib/frrscript.h
+++ b/lib/frrscript.h
@@ -181,6 +181,11 @@ void frrscript_fini(void);
} 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.
*
@@ -192,7 +197,9 @@ void frrscript_fini(void);
#define ENCODE_ARGS_WITH_STATE(L, value) \
_Generic((value), \
int : lua_pushinteger, \
-long long * : lua_pushintegerp, \
+int * : lua_pushintegerp, \
+long long : lua_pushinteger, \
+long long * : lua_pushlonglongp, \
struct prefix * : lua_pushprefix, \
struct interface * : lua_pushinterface, \
struct in_addr * : lua_pushinaddr, \
@@ -211,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, \
@@ -220,13 +227,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))
/*
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;
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 */