summaryrefslogtreecommitdiff
path: root/lib/frrscript.c
diff options
context:
space:
mode:
authorQuentin Young <qlyoung@nvidia.com>2020-11-29 02:00:26 -0500
committerQuentin Young <qlyoung@nvidia.com>2020-12-01 18:37:14 -0500
commit3b002f19166ca8933c42ebf8f5a7b7794acd53bf (patch)
tree4ab7473da05b47108dd4c9dcf84fe93a621ddb32 /lib/frrscript.c
parent923431ef80fc92b313d812605764b005397fa9bb (diff)
lib: allow passing arguments to scripts
- Add ability to pass arguments when calling a script - Add macros to define arguments and results Signed-off-by: Quentin Young <qlyoung@nvidia.com>
Diffstat (limited to 'lib/frrscript.c')
-rw-r--r--lib/frrscript.c71
1 files changed, 65 insertions, 6 deletions
diff --git a/lib/frrscript.c b/lib/frrscript.c
index e7390a8d94..e523fcb475 100644
--- a/lib/frrscript.c
+++ b/lib/frrscript.c
@@ -18,6 +18,7 @@
*/
#include <zebra.h>
+#include <stdarg.h>
#include "frrscript.h"
#include "memory.h"
@@ -73,13 +74,64 @@ static void encoder_free(struct encoder *e)
int frrscript_lua_call(struct frrscript *fs, ...)
{
- /* Process arguments according to argspec in fs */
- /* ... */
+ va_list vl;
+ va_start(vl, fs);
- int ret = lua_pcall(fs->L, 0, 0, 0);
+ int nargs = va_arg(vl, int);
+ assert(nargs % 3 == 0);
- /* Process stack result according to argspec in fs */
- /* ... */
+ zlog_debug("%s: Script '%s' called with # args: %d", __func__, fs->name,
+ nargs);
+
+ struct encoder e = {};
+ void *arg;
+ const char *bindname;
+
+ /* Encode script arguments */
+ for (int i = 0; i < nargs; i += 3) {
+ bindname = va_arg(vl, const char *);
+ e.typename = va_arg(vl, char *);
+ arg = va_arg(vl, void *);
+
+ zlog_debug("Script argument | Bind name: %s | Type: %s",
+ bindname, e.typename);
+
+ struct encoder *enc = hash_lookup(encoder_hash, &e);
+ assert(enc
+ && "No encoder for type; rerun with debug logs to see more");
+ enc->encoder(fs->L, arg);
+
+ lua_setglobal(fs->L, bindname);
+ }
+
+ int nresults = va_arg(vl, int);
+ zlog_debug("Expected script results: %d", nresults);
+
+ int ret = lua_pcall(fs->L, 0, nresults, 0);
+
+ switch (ret) {
+ case LUA_ERRRUN:
+ zlog_err("Script '%s' runtime error", fs->name);
+ break;
+ case LUA_ERRMEM:
+ zlog_err("Script '%s' memory error", fs->name);
+ break;
+ case LUA_ERRERR:
+ zlog_err("Script '%s' error handler error", fs->name);
+ break;
+ case LUA_ERRGCMM:
+ zlog_err("Script '%s' garbage collector error", fs->name);
+ break;
+ default:
+ zlog_err("Script '%s' unknown error", fs->name);
+ break;
+ }
+
+ /* After script returns, decode results */
+ for (int i = 0; i < nresults; i++) {
+ const char *resultname = va_arg(vl, const char *);
+ fprintf(stderr, "result: %s\n", resultname);
+ }
/* LUA_OK is 0, so we can just return lua_pcall's result directly */
return ret;
@@ -129,5 +181,12 @@ void frrscript_unload(struct frrscript *fs)
void frrscript_init()
{
- encoder_hash = hash_create(encoder_hash_key, encoder_hash_cmp, "Lua type encoders");
+ encoder_hash = hash_create(encoder_hash_key, encoder_hash_cmp,
+ "Lua type encoders");
+
+ /* Register core library types */
+ frrscript_register_type_encoder("prefix",
+ (encoder_func)frrlua_newtable_prefix);
+ frrscript_register_type_encoder(
+ "interface", (encoder_func)frrlua_newtable_interface);
}