From 27292f0d9ed90340792d4d065fefd2e4e248e4bd Mon Sep 17 00:00:00 2001 From: sanine-a Date: Sat, 24 Oct 2020 19:54:18 -0500 Subject: add honey_lua_pcall with traceback ability --- src/common.h | 8 ++++++++ src/honey_lua.c | 40 ++++++++++++++++++++++++++++++++++++++++ src/main.c | 6 +++--- 3 files changed, 51 insertions(+), 3 deletions(-) diff --git a/src/common.h b/src/common.h index 47b7ee4..63962db 100644 --- a/src/common.h +++ b/src/common.h @@ -153,4 +153,12 @@ void honey_lua_create_table(lua_State* L, honey_lua_element* elements, unsigned int n_elements); +/** @brief Get the traceback for use after an error. + */ +int honey_lua_traceback(lua_State* L); + +/** @brief Wrapper for lua_pcall that uses a honey_lua_traceback as an error handler. + */ +int honey_lua_pcall(lua_State* L, int nargs, int nret); + #endif diff --git a/src/honey_lua.c b/src/honey_lua.c index f397872..ded2a91 100644 --- a/src/honey_lua.c +++ b/src/honey_lua.c @@ -190,3 +190,43 @@ void honey_lua_push_element(lua_State* L, honey_lua_element element) break; } } + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +int honey_lua_traceback(lua_State* L) +{ + if (!lua_isstring(L, 1)) + /* 'message' is not a string, keep intact. */ + return 1; + + lua_getglobal(L, "debug"); + if (!lua_istable(L, -1)) { + lua_pop(L, 1); + return 1; + } + + lua_getfield(L, -1, "traceback"); + if (!lua_isfunction(L, -1)) { + lua_pop(L, 2); + return 1; + } + + lua_pushvalue(L, 1); + lua_pushinteger(L, 2); + lua_call(L, 2, 1); + return 1; +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +int honey_lua_pcall(lua_State* L, int nargs, int nret) +{ + int traceback_pos = lua_gettop(L) - nargs; + lua_pushcfunction(L, honey_lua_traceback); + lua_insert(L, traceback_pos); + + int result = lua_pcall(L, nargs, nret, traceback_pos); + lua_remove(L, traceback_pos); + return result; +} + diff --git a/src/main.c b/src/main.c index 14037fb..8d710a7 100644 --- a/src/main.c +++ b/src/main.c @@ -23,7 +23,7 @@ int main(int argc, char** argv) } if (luaL_loadfile(L, script) == 0) { - if (!lua_pcall(L, 0, 1, 0) == 0) { + if (!honey_lua_pcall(L, 0, 1) == 0) { const char* error = lua_tostring(L, -1); fprintf(stderr, "[honey] ERROR: %s\n", error); return 1; @@ -50,7 +50,7 @@ int main(int argc, char** argv) if (update_callback != LUA_NOREF) { lua_rawgeti(L, LUA_REGISTRYINDEX, update_callback); lua_pushnumber(L, dt); - int result = lua_pcall(L, 1, 0, 0); + int result = honey_lua_pcall(L, 1, 0); if (result != 0) { const char* error = lua_tostring(L, -1); fprintf(stderr, "[honey] ERROR: %s\n", error); @@ -60,7 +60,7 @@ int main(int argc, char** argv) if (draw_callback != LUA_NOREF) { lua_rawgeti(L, LUA_REGISTRYINDEX, draw_callback); - int result = lua_pcall(L, 0, 0, 0); + int result = honey_lua_pcall(L, 0, 0); if (result != 0) { const char* error = lua_tostring(L, -1); fprintf(stderr, "[honey] ERROR: %s\n", error); -- cgit v1.2.1