lib: create new frrscript_new

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>
This commit is contained in:
Donald Lee 2021-07-04 23:05:37 +08:00
parent 105ba9af8f
commit f0cddf950f
2 changed files with 41 additions and 16 deletions

View 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)

View 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.