]> git.puffer.fish Git - mirror/frr.git/commitdiff
lib: create new frrscript_new
authorDonald Lee <dlqs@gmx.com>
Sun, 4 Jul 2021 15:05:37 +0000 (23:05 +0800)
committerDonald Lee <dlqs@gmx.com>
Sat, 17 Jul 2021 22:32:03 +0000 (06:32 +0800)
frrscript_new now creates a new frrscript
frrscript_load now loads a function (by allocating a new lua stack)

Signed-off-by: Donald Lee <dlqs@gmx.com>
lib/frrscript.c
lib/frrscript.h

index d86e6acb1274e2cc5c9ed6931703e19f65d88b1d..ed9043d8d21a2fafba567fe9c53a63dc5ba59c1e 100644 (file)
@@ -217,56 +217,76 @@ void frrscript_register_type_codecs(struct frrscript_codec *codecs)
                frrscript_register_type_codec(&codecs[i]);
 }
 
-struct frrscript *frrscript_load(const char *name,
-                                int (*load_cb)(struct frrscript *))
+struct frrscript *frrscript_new(const char *name)
 {
        struct frrscript *fs = XCALLOC(MTYPE_SCRIPT, sizeof(struct frrscript));
 
        fs->name = XSTRDUP(MTYPE_SCRIPT, name);
-       fs->L = luaL_newstate();
-       frrlua_export_logging(fs->L);
+       fs->lua_function_hash =
+               hash_create(lua_function_hash_key, lua_function_hash_cmp,
+                           "Lua function state hash");
+       return fs;
+}
+
+int frrscript_load(struct frrscript *fs, const char *function_name,
+                  int (*load_cb)(struct frrscript *))
+{
+
+       /* Set up the Lua script */
+       lua_State *L = luaL_newstate();
+       frrlua_export_logging(L);
 
        char fname[MAXPATHLEN * 2];
-       snprintf(fname, sizeof(fname), "%s/%s.lua", scriptdir, fs->name);
 
-       int ret = luaL_loadfile(fs->L, fname);
+       snprintf(fname, sizeof(fname), "%s/%s.lua", scriptdir, fs->name);
+       int ret = luaL_dofile(L, fname);
 
        switch (ret) {
        case LUA_OK:
                break;
        case LUA_ERRSYNTAX:
                zlog_err("Failed loading script '%s': syntax error: %s", fname,
-                        lua_tostring(fs->L, -1));
+                        lua_tostring(L, -1));
                break;
        case LUA_ERRMEM:
                zlog_err("Failed loading script '%s': out-of-memory error: %s",
-                        fname, lua_tostring(fs->L, -1));
+                        fname, lua_tostring(L, -1));
                break;
        case LUA_ERRGCMM:
                zlog_err(
                        "Failed loading script '%s': garbage collector error: %s",
-                       fname, lua_tostring(fs->L, -1));
+                       fname, lua_tostring(L, -1));
                break;
        case LUA_ERRFILE:
                zlog_err("Failed loading script '%s': file read error: %s",
-                        fname, lua_tostring(fs->L, -1));
+                        fname, lua_tostring(L, -1));
                break;
        default:
                zlog_err("Failed loading script '%s': unknown error: %s", fname,
-                        lua_tostring(fs->L, -1));
+                        lua_tostring(L, -1));
                break;
        }
 
        if (ret != LUA_OK)
                goto fail;
 
+       /* Push the Lua function we want */
+       lua_getglobal(L, function_name);
+       if (lua_isfunction(L, lua_gettop(L)) == 0)
+               goto fail;
+
        if (load_cb && (*load_cb)(fs) != 0)
                goto fail;
 
-       return fs;
+       /* Add the Lua function state to frrscript */
+       struct lua_function_state key = {.name = function_name, .L = L};
+
+       hash_get(fs->lua_function_hash, &key, lua_function_alloc);
+
+       return 0;
 fail:
-       frrscript_unload(fs);
-       return NULL;
+       lua_close(L);
+       return 1;
 }
 
 void frrscript_unload(struct frrscript *fs)
index 97e543eb00e825d114ef9cbcb7f0b365f9a63c18..df72bba4cd5a25a97416bf33f3d3bee28d2ac552 100644 (file)
@@ -79,8 +79,13 @@ struct frrscript_env {
 /*
  * Create new FRR script.
  */
-struct frrscript *frrscript_load(const char *name,
-                                int (*load_cb)(struct frrscript *));
+struct frrscript *frrscript_new(const char *name);
+
+/*
+ * Load a function into frrscript, run callback if any
+ */
+int frrscript_load(struct frrscript *fs, const char *function_name,
+                  int (*load_cb)(struct frrscript *));
 
 /*
  * Destroy FRR script.