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