// Handle errors with a Lua function, defined in lua-env.lua int bll_error_handler(lua_State *L) { lua_getfield(L, LUA_GLOBALSINDEX, "_bllua_on_error"); if (!lua_isfunction(L, -1)) { BlPrintf(" Lua error handler: _bllua_on_error not defined."); lua_pop(L, 1); return 1; } // move function to before arg int hpos = lua_gettop(L) - 1; lua_insert(L, hpos); lua_pcall(L, 1, 1, 0); return 1; } int bll_pcall(lua_State* L, int nargs, int nret) { // calculate stack position for message handler int hpos = lua_gettop(L) - nargs; // push custom error message handler lua_pushcfunction(L, bll_error_handler); // move it before function and arguments lua_insert(L, hpos); // call lua_pcall function with custom handler int ret = lua_pcall(L, nargs, nret, hpos); // remove custom error message handler from stack lua_remove(L, hpos); return ret; } // Display the last Lua error in the BL console void bll_printError(lua_State* L, const char* operation, const char* item) { //error_handler(L); BlPrintf("\x03Lua error: %s", lua_tostring(L, -1)); BlPrintf("\x03 (%s: %s)", operation, item); lua_pop(L, 1); } // Eval a string of Lua code bool bll_LuaEval(lua_State* L, const char* str) { if(luaL_loadbuffer(L, str, strlen(str), "input") || bll_pcall(L, 0, 1)) { bll_printError(L, "eval", str); return false; } return true; } // Convert a Lua stack entry into a string for providing to TS // Use static buffer to avoid excessive malloc #define BLL_ARG_COUNT 20 #define BLL_ARG_MAX 8192 char bll_arg_buffer[BLL_ARG_COUNT][BLL_ARG_MAX]; bool bll_toarg(lua_State* L, char* buf, int i, bool err) { if(lua_isstring(L, i)) { const char* str = lua_tostring(L, i); if(strlen(str) >= BLL_ARG_MAX) { if(err) luaL_error(L, "argument to TS is too long - max length is 8192"); return true; } else { strcpy(buf, str); return false; } } else { if(err) luaL_error(L, "argument to TS must be a string"); return true; } }