From 41bfa1b8419b073da4c79b780ebe83b3d4ac19ac Mon Sep 17 00:00:00 2001 From: helixhorned Date: Tue, 25 Dec 2012 16:13:41 +0000 Subject: [PATCH] Lunatic: print -> OSD_Printf, error reporting. git-svn-id: https://svn.eduke32.com/eduke32@3319 1a8010ca-5511-0410-912e-c29ae57300e0 --- polymer/eduke32/build/include/lunatic.h | 3 + polymer/eduke32/build/src/lunatic.c | 13 ++- polymer/eduke32/source/game.c | 4 + polymer/eduke32/source/lunatic/defs.ilua | 10 +- .../eduke32/source/lunatic/defs_common.lua | 9 ++ polymer/eduke32/source/lunatic/dynsymlist | 1 + polymer/eduke32/source/lunatic/dynsymlist_m32 | 1 + polymer/eduke32/source/lunatic/lunatic_game.c | 108 +++++++++++++++++- polymer/eduke32/source/lunatic/lunatic_game.h | 3 + polymer/eduke32/source/lunatic/test.elua | 11 +- polymer/eduke32/source/premap.c | 2 +- 11 files changed, 147 insertions(+), 18 deletions(-) diff --git a/polymer/eduke32/build/include/lunatic.h b/polymer/eduke32/build/include/lunatic.h index 6f7f1cb50..3af4c14c5 100644 --- a/polymer/eduke32/build/include/lunatic.h +++ b/polymer/eduke32/build/include/lunatic.h @@ -19,6 +19,9 @@ typedef struct void L_SetupDebugTraceback(lua_State *L); void L_CheckAndRegisterFunction(lua_State *L, void *regkeyaddr); +// Callback on Lua error. must be used immediately or strdup'd. +void (*L_ErrorFunc)(const char *str); + int L_CreateState(L_State *estate, const char *name, void (*StateSetupFunc)(lua_State *)); void L_DestroyState(L_State *estate); int L_RunOnce(L_State *estate, const char *fn); diff --git a/polymer/eduke32/build/src/lunatic.c b/polymer/eduke32/build/src/lunatic.c index 3e9639e89..d3ee9bc9c 100644 --- a/polymer/eduke32/build/src/lunatic.c +++ b/polymer/eduke32/build/src/lunatic.c @@ -112,6 +112,7 @@ void L_DestroyState(L_State *estate) estate->L = NULL; } +void (*L_ErrorFunc)(const char *) = NULL; int L_RunString(L_State *estate, char *buf, int dofreebuf) { @@ -139,7 +140,7 @@ int L_RunString(L_State *estate, char *buf, int dofreebuf) if (i == LUA_ERRSYNTAX) { - OSD_Printf("state \"%s\" syntax error: %s\n", estate->name, + OSD_Printf(OSD_ERROR "state \"%s\" syntax error: %s\n", estate->name, lua_tostring(L, -1)); // get err msg lua_pop(L, 2); // pop errmsg and debug.traceback return 3; @@ -159,11 +160,13 @@ int L_RunString(L_State *estate, char *buf, int dofreebuf) if (i == LUA_ERRRUN) { - int32_t stringp = (lua_type(L, -1)==LUA_TSTRING); - // get error message if possible - OSD_Printf("state \"%s\" runtime error: %s\n", estate->name, - stringp ? lua_tostring(L, -1) : "??? (errmsg not a string)"); + const char *errstr = (lua_type(L, -1)==LUA_TSTRING) ? + lua_tostring(L, -1) : "??? (errmsg not a string)"; + + OSD_Printf(OSD_ERROR "state \"%s\" runtime error: %s\n", estate->name, errstr); + if (L_ErrorFunc) + L_ErrorFunc(errstr); lua_pop(L, 2); // pop errmsg and debug.traceback return 4; } diff --git a/polymer/eduke32/source/game.c b/polymer/eduke32/source/game.c index 2923d8f33..54508431c 100644 --- a/polymer/eduke32/source/game.c +++ b/polymer/eduke32/source/game.c @@ -3013,6 +3013,10 @@ void G_DisplayRest(int32_t smoothratio) if (g_Debug) G_ShowCacheLocks(); +#ifdef LUNATIC + El_DisplayErrors(); +#endif + if (VOLUMEONE) { if (ud.show_help == 0 && g_showShareware > 0 && (g_player[myconnectindex].ps->gm&MODE_MENU) == 0) diff --git a/polymer/eduke32/source/lunatic/defs.ilua b/polymer/eduke32/source/lunatic/defs.ilua index c32044a30..2cda3abf4 100644 --- a/polymer/eduke32/source/lunatic/defs.ilua +++ b/polymer/eduke32/source/lunatic/defs.ilua @@ -20,10 +20,8 @@ local rawset = rawset local setmetatable = setmetatable local setfenv = setfenv local tonumber = tonumber -local type = type - -local print = print local tostring = tostring +local type = type --== First, load the definitions common to the game's and editor's Lua interface. @@ -61,6 +59,10 @@ local cansee = defs_c.cansee local strip_const = defs_c.strip_const local setmtonce = defs_c.setmtonce +-- Must be after loading "defs_common" which redefines "print" to use +-- OSD_Printf() +local print = print + ---=== EDuke32 game definitions ===--- @@ -963,7 +965,7 @@ G_.error = our_error G_.ipairs = ipairs G_.pairs = pairs G_.pcall = pcall -G_.print = print -- TODO: --> initprintf or OSD_Printf; why not needed on linux? +G_.print = print G_.module = our_module G_.next = next G_.require = our_require diff --git a/polymer/eduke32/source/lunatic/defs_common.lua b/polymer/eduke32/source/lunatic/defs_common.lua index a9fdcf560..0bb275ef1 100644 --- a/polymer/eduke32/source/lunatic/defs_common.lua +++ b/polymer/eduke32/source/lunatic/defs_common.lua @@ -16,6 +16,15 @@ local setmetatable = setmetatable local decl = decl local getfenv = getfenv +decl "void OSD_Printf(const char *fmt, ...);" +print = function(str) + str = tostring(str) + if (type(str) ~= "string") then + error("invalid argument to print: must be convertible to a string") + end + ffiC.OSD_Printf("%s\n", str) +end + local print=print diff --git a/polymer/eduke32/source/lunatic/dynsymlist b/polymer/eduke32/source/lunatic/dynsymlist index c2336c7b7..d6e980b3e 100644 --- a/polymer/eduke32/source/lunatic/dynsymlist +++ b/polymer/eduke32/source/lunatic/dynsymlist @@ -44,6 +44,7 @@ updatesectorz; updatesectorbreadth; gethitickms; +OSD_Printf; diff --git a/polymer/eduke32/source/lunatic/dynsymlist_m32 b/polymer/eduke32/source/lunatic/dynsymlist_m32 index 0ba224952..286d020c1 100644 --- a/polymer/eduke32/source/lunatic/dynsymlist_m32 +++ b/polymer/eduke32/source/lunatic/dynsymlist_m32 @@ -44,6 +44,7 @@ updatesectorz; updatesectorbreadth; gethitickms; +OSD_Printf; diff --git a/polymer/eduke32/source/lunatic/lunatic_game.c b/polymer/eduke32/source/lunatic/lunatic_game.c index d5c19a271..a3db9a64c 100644 --- a/polymer/eduke32/source/lunatic/lunatic_game.c +++ b/polymer/eduke32/source/lunatic/lunatic_game.c @@ -5,6 +5,8 @@ #include #include +#include "build.h" // printext256 + #include "lunatic_game.h" #include "osd.h" @@ -101,6 +103,92 @@ void El_PrintTimes(void) OSD_Printf(" },\n}\n"); } +////////// ERROR REPORTING ////////// +#define EL_MAXERRORS 2 +static int32_t el_numErrors=0, el_tooMuchErrors; +static char *el_errorMsgs[EL_MAXERRORS]; + +// Compare against all other error messages. +// Strictly seen, this is quadratic-time, but EL_MAXERRORS is small and +// errors should be fixed anyway. +static int32_t cmp_against_others(const char *str, int32_t slen) +{ + int32_t i; + for (i=0; iname, lua_tostring(L, -1)); // get err msg + OSD_Printf(OSD_ERROR "event \"%s\" (state \"%s\") runtime error: %s\n", + EventNames[eventidx], estate->name, errstr); + if (L_ErrorFunc) + L_ErrorFunc(errstr); lua_pop(L, 1); return -1; } @@ -247,6 +342,8 @@ int32_t El_CallActor(L_State *estate, int32_t actortile, int32_t iActor, int32_t if (i == LUA_ERRRUN) { + const char *errstr; + if (lua_isboolean(L, -1)) { int32_t killit = lua_toboolean(L, -1); @@ -255,8 +352,11 @@ int32_t El_CallActor(L_State *estate, int32_t actortile, int32_t iActor, int32_t } Bassert(lua_type(L, -1)==LUA_TSTRING); - OSD_Printf("actor %d (sprite %d, state \"%s\") runtime error: %s\n", actortile, iActor, - estate->name, lua_tostring(L, -1)); // get err msg + errstr = lua_tostring(L, -1); + OSD_Printf(OSD_ERROR "actor %d (sprite %d, state \"%s\") runtime error: %s\n", + actortile, iActor, estate->name, errstr); + if (L_ErrorFunc) + L_ErrorFunc(errstr); lua_pop(L, 1); return -1; } diff --git a/polymer/eduke32/source/lunatic/lunatic_game.h b/polymer/eduke32/source/lunatic/lunatic_game.h index 97496328b..7220b3e90 100644 --- a/polymer/eduke32/source/lunatic/lunatic_game.h +++ b/polymer/eduke32/source/lunatic/lunatic_game.h @@ -28,6 +28,9 @@ extern double g_eventTotalMs[MAXEVENTS], g_actorTotalMs[MAXTILES]; // -- functions -- void El_PrintTimes(void); +void El_ClearErrors(void); +void El_DisplayErrors(void); + int32_t El_CreateState(L_State *estate, const char *name); void El_DestroyState(L_State *estate); diff --git a/polymer/eduke32/source/lunatic/test.elua b/polymer/eduke32/source/lunatic/test.elua index 3f354fee7..8b0a53192 100644 --- a/polymer/eduke32/source/lunatic/test.elua +++ b/polymer/eduke32/source/lunatic/test.elua @@ -16,12 +16,13 @@ end local function checkfail(funcstr, expectedmsg) local status, errmsg = pcall(DBG_.loadstring(funcstr)) if (status) then - print('ERROR: '..funcstr.." DIDN'T fail") + print('^21ERROR:^O '..funcstr.." DIDN'T fail") else if (expectedmsg==nil or string.find(errmsg, expectedmsg, 1, true)) then - print('SUCCESS: '..funcstr.." failed: "..errmsg) + print("^11SUCCESS:^O "..funcstr.." failed: "..errmsg) else - print('ERROR*: '..funcstr.." failed: "..errmsg.. + -- XXX: beginning with "^10" is counted as error in OSD_Printf() + print("^10ERROR*:^O "..funcstr.." failed: "..errmsg.. ", but expected error message was: "..expectedmsg) end end @@ -182,13 +183,14 @@ checkfail("do local bt=require'bittest'; bt.QWE=1; end", "modifying module table -- the cdata returned by player[] can't be made into a pointer! checkfail("do local pl=player[0]; i=pl[1]; end") checkfail("do local ud=gv.ud.camera; end", "dummy variable: read access forbidden") -- test for proper decl() -checkfail("sprite[0]:set_picnum(-10)", "attempt to set invalid picnum") +checkfail("sprite[0]:set_picnum(-10)", "attempt to set invalid picnums") printf('ceilingbunch of sector 0: %d', getbunch(0, gv.CEILING)) gameevent(gv.EVENT_JUMP, function(actori, playeri, dist) printf("jump i=%d p=%d d=%d", actori, playeri, dist) + error("greetings from EVENT_JUMP") end ) @@ -263,6 +265,7 @@ gameactor(1680, TROOPSTRENGTH, "TROOPSTAND", -- LIZTROOP if (hs.n == 300) then printf("hitscan: %s", tostring(hs:getstats())) hs:reset() + error("greetings from LIZTROOP actor") end if (dist < 4096) then diff --git a/polymer/eduke32/source/premap.c b/polymer/eduke32/source/premap.c index b4ce013a3..9c9315bc4 100644 --- a/polymer/eduke32/source/premap.c +++ b/polymer/eduke32/source/premap.c @@ -1371,7 +1371,7 @@ static inline void prelevel(char g) { i = L_RunOnce(&g_ElState, "test.elua"); if (i) - OSD_Printf("Error running the test ELua script (code %d)\n", i); + OSD_Printf(OSD_ERROR "Error running the test ELua script (code %d)\n", i); else initprintf("ELua test script run ok!\n"); }