diff -r 7728d6ec3abf -r 5229a5d098b2 src/spbot/nexus_lua.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/spbot/nexus_lua.c Thu May 28 00:35:02 2009 +0300 @@ -0,0 +1,117 @@ +#include "nexus_lua.h" +#include "../lua_objs.h" +#include "../lua_irc.h" + +#include + +#include +#include + +/** + * 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(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, error_t *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, error_t *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); + }; +} +