#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, error_t *err)
{
struct nexus_lua *lua;
// alloc
if ((lua = calloc(1, sizeof(*lua))) == NULL)
return SET_ERROR_MEM(err);
// store
lua->nexus = nexus;
// create the lua state
if ((lua->st = luaL_newstate()) == NULL)
JUMP_SET_ERROR(err, &lua_errors, 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, error_t *err)
{
int ret;
bool loaded = false;
error_reset(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, error_t *err)
{
// XXX: this can raise an erorr itself
const char *error = lua_tostring(L, -1);
switch (ret) {
case 0: return SUCCESS;
case LUA_ERRSYNTAX: return SET_ERROR_STR(err, &lua_errors, ERR_LUA_SYNTAX, error);
case LUA_ERRRUN: return SET_ERROR_STR(err, &lua_errors, ERR_LUA_RUN, error);
case LUA_ERRMEM: return SET_ERROR_STR(err, &lua_errors, ERR_LUA_MEM, error);
case LUA_ERRERR: return SET_ERROR_STR(err, &lua_errors, ERR_LUA_ERR, error);
case LUA_ERRFILE: return SET_ERROR_STR(err, &lua_errors, ERR_LUA_FILE, error);
default: return SET_ERROR(err, &general_errors, ERR_UNKNOWN);
};
}