#include "nexus_lua.h"
#include "lua_objs.h"
#include "lua_irc.h"
#include <stdlib.h>
#include <lua5.1/lualib.h>
#include <lua5.1/lauxlib.h>
/**
* Initialize the lua state, in protected mode
*/
int nexus_lua_init (lua_State *L)
{
struct nexus_lua *lua;
// read the nexus_lua off the stack
if ((lua = lua_touserdata(L, 1)) == NULL)
luaL_error(L, "lua_touserdata: NULL");
// open the standard libraries
luaL_openlibs(L);
// open our core lua api
lua_objs_init(lua);
// and the irc_* stuff
lua_irc_init(lua);
// ok
return 0;
}
err_t nexus_lua_create (struct nexus_lua **lua_ptr, struct nexus *nexus, struct error_info *err)
{
struct nexus_lua *lua;
// alloc
if ((lua = calloc(1, sizeof(*lua))) == NULL)
return SET_ERROR(err, ERR_CALLOC);
// store
lua->nexus = nexus;
// create the lua state
if ((lua->st = luaL_newstate()) == NULL)
JUMP_SET_ERROR(err, ERR_LUA_MEM);
// init in protected mode
if (nexus_lua_error(lua->st, lua_cpcall(lua->st, &nexus_lua_init, lua), err))
goto error;
// ok
*lua_ptr = lua;
return SUCCESS;
error:
nexus_lua_destroy(lua);
return ERROR_CODE(err);
}
void nexus_lua_destroy (struct nexus_lua *lua)
{
// close the lua stuff
lua_close(lua->st);
free(lua);
}
err_t nexus_lua_eval (struct nexus_lua *lua, const char *chunk, struct error_info *err)
{
int ret;
bool loaded = false;
RESET_ERROR(err);
// load the line as a lua function
if ((ret = luaL_loadstring(lua->st, chunk)))
goto error;
loaded = true;
// execute it
if ((ret = lua_pcall(lua->st, 0, 0, 0)))
goto error;
error:
if (ret) {
// build the error_info
nexus_lua_error(lua->st, ret, err);
// pop the error message
// XXX: err points at GC:able memory
lua_pop(lua->st, 1);
}
return ERROR_CODE(err);
}
err_t nexus_lua_error (lua_State *L, int ret, struct error_info *err)
{
// XXX: this can raise an erorr itself
const char *error = lua_tostring(L, -1);
switch (ret) {
case 0: RETURN_SET_ERROR(err, SUCCESS);
case LUA_ERRSYNTAX: RETURN_SET_ERROR_STR(err, ERR_LUA_SYNTAX, error);
case LUA_ERRRUN: RETURN_SET_ERROR_STR(err, ERR_LUA_RUN, error);
case LUA_ERRMEM: RETURN_SET_ERROR_STR(err, ERR_LUA_MEM, error);
case LUA_ERRERR: RETURN_SET_ERROR_STR(err, ERR_LUA_ERR, error);
case LUA_ERRFILE: RETURN_SET_ERROR_STR(err, ERR_LUA_FILE, error);
default: RETURN_SET_ERROR_EXTRA(err, ERR_UNKNOWN, ret);
};
}