// Handle errors with a Lua function, defined in lua-env.lua #include "luainterp.hpp" #include "BlHooks.hpp" #include "lauxlib.h" #include "lua.h" #include 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 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 { #ifdef _MSC_VER strncpy_s(buf, BLL_ARG_MAX, str, _TRUNCATE); #else strncpy(buf, str, BLL_ARG_MAX - 1); buf[BLL_ARG_MAX - 1] = '\0'; #endif return false; } } else { if (err) luaL_error(L, "argument to TS must be a string"); return true; } }