--- /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 <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(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);
+ };
+}
+