add some rudimentary lua support, by having a simple interactive console, and providing access to irc_client_quit
#include "lua_console.h"
#include "lua_objs.h"
#include "log.h"
#include <stdlib.h>
#include <lua5.1/lualib.h>
#include <lua5.1/lauxlib.h>
static void lua_console_on_line (const char *line, void *arg)
{
struct lua_console *lc = arg;
lua_State *L = lc->st;
int ret;
// ignore empty lines and EOF
if (!line || !(*line))
return;
// load the line as a lua function
if ((ret = luaL_loadstring(L, line)))
goto error;
// execute it
if ((ret = lua_pcall(L, 0, 0, 0)))
goto error;
// XXX: display results?
error:
if (ret) {
const char *error = lua_tostring(L, -1);
switch (ret) {
case LUA_ERRSYNTAX:
log_error("syntax error: %s", error);
break;
case LUA_ERRRUN:
log_error("runtime error: %s", error);
break;
case LUA_ERRMEM:
log_error("memory allocation error: %s", error);
break;
case LUA_ERRERR:
log_error("error handling error: %s", error);
break;
default:
log_error("unknown error: %s", error);
break;
};
lua_pop(L, 1);
}
}
static struct console_callbacks _console_callbacks = {
.on_line = &lua_console_on_line,
};
err_t lua_console_create (struct lua_console **lc_ptr, struct console *console, struct nexus *nexus, struct error_info *err)
{
struct lua_console *lc;
// allocate
if ((lc = calloc(1, sizeof(*lc))) == NULL)
return SET_ERROR(err, ERR_CALLOC);
// store
lc->console = console;
// set our console callbacks
console_set_callbacks(console, &_console_callbacks, lc);
// create the lua state
if ((lc->st = luaL_newstate()) == NULL)
JUMP_SET_ERROR(err, ERR_LUA_MEM);
// we can then load the core libs
// XXX: we don't need all of these
// XXX: errors?
luaL_openlibs(lc->st);
// then our own things
if ((ERROR_CODE(err) = lua_objs_init(lc->st, nexus)))
goto error;
// ok
*lc_ptr = lc;
return SUCCESS;
error:
// destroy
lua_console_destroy(lc);
return ERROR_CODE(err);
}
void lua_console_destroy (struct lua_console *lc)
{
// close the lua stuff
lua_close(lc->st);
// and the console
console_destroy(lc->console);
free(lc);
}