From 39b2d58c39fd0cd554b27ed071926bc439338964 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Mon, 8 Jul 2002 15:21:33 -0300 Subject: new interface for debug hooks --- ldblib.c | 89 ++++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 47 insertions(+), 42 deletions(-) (limited to 'ldblib.c') diff --git a/ldblib.c b/ldblib.c index a0601b14..b6c78588 100644 --- a/ldblib.c +++ b/ldblib.c @@ -1,5 +1,5 @@ /* -** $Id: ldblib.c,v 1.60 2002/06/18 17:42:52 roberto Exp roberto $ +** $Id: ldblib.c,v 1.61 2002/06/25 19:16:44 roberto Exp roberto $ ** Interface from Lua to its debug API ** See Copyright Notice in lua.h */ @@ -108,65 +108,70 @@ static int setlocal (lua_State *L) { -static const char KEY_CALLHOOK = 'c'; -static const char KEY_LINEHOOK = 'l'; +static const char KEY_HOOK = 'h'; -static void hookf (lua_State *L, void *key) { - lua_pushudataval(L, key); +static void hookf (lua_State *L, lua_Debug *ar) { + static const char *const hooknames[] = {"call", "return", "line", "count"}; + lua_pushudataval(L, (void *)&KEY_HOOK); lua_rawget(L, LUA_REGISTRYINDEX); if (lua_isfunction(L, -1)) { - lua_pushvalue(L, -2); /* original argument (below function) */ - lua_call(L, 1, 0); + lua_pushstring(L, hooknames[(int)ar->event]); + if (ar->currentline >= 0) lua_pushnumber(L, ar->currentline); + else lua_pushnil(L); + lua_assert(lua_getinfo(L, "lS", ar)); + lua_call(L, 2, 0); } else lua_pop(L, 1); /* pop result from gettable */ } -static void callf (lua_State *L, lua_Debug *ar) { - lua_pushstring(L, ar->event); - lua_assert(lua_getinfo(L, "lS", ar) && ar->currentline == -1); - hookf(L, (void *)&KEY_CALLHOOK); +static int makemask (const char *smask, int count) { + int mask = 0; + if (strchr(smask, 'c')) mask |= LUA_MASKCALL; + if (strchr(smask, 'r')) mask |= LUA_MASKRET; + if (strchr(smask, 'l')) mask |= LUA_MASKLINE; + return mask | lua_maskcount(count); } -static void linef (lua_State *L, lua_Debug *ar) { - lua_pushnumber(L, ar->currentline); - lua_assert((ar->currentline = ar->linedefined = -1, - lua_getinfo(L, "lS", ar) && - ar->currentline == lua_tonumber(L, -1) && - ar->linedefined >= 0)); - hookf(L, (void *)&KEY_LINEHOOK); +static char *unmakemask (int mask, char *smask) { + int i = 0; + if (mask & LUA_MASKCALL) smask[i++] = 'c'; + if (mask & LUA_MASKRET) smask[i++] = 'r'; + if (mask & LUA_MASKLINE) smask[i++] = 'l'; + smask[i] = '\0'; + return smask; } -static void sethook (lua_State *L, void *key, lua_Hook hook, - lua_Hook (*sethookf)(lua_State * L, lua_Hook h)) { - lua_settop(L, 1); - if (lua_isnoneornil(L, 1)) - (*sethookf)(L, NULL); - else if (lua_isfunction(L, 1)) - (*sethookf)(L, hook); - else - luaL_argerror(L, 1, "function expected"); - lua_pushudataval(L, key); - lua_rawget(L, LUA_REGISTRYINDEX); /* get old value */ - lua_pushudataval(L, key); +static int sethook (lua_State *L) { + if (lua_isnoneornil(L, 1)) { + lua_settop(L, 1); + lua_sethook(L, NULL, 0); /* turn off hooks */ + } + else { + const char *smask = luaL_check_string(L, 2); + int count = luaL_opt_int(L, 3, 0); + luaL_check_type(L, 1, LUA_TFUNCTION); + lua_sethook(L, hookf, makemask(smask, count)); + } + lua_pushudataval(L, (void *)&KEY_HOOK); lua_pushvalue(L, 1); - lua_rawset(L, LUA_REGISTRYINDEX); /* set new value */ -} - - -static int setcallhook (lua_State *L) { - sethook(L, (void *)&KEY_CALLHOOK, callf, lua_setcallhook); - return 1; + lua_rawset(L, LUA_REGISTRYINDEX); /* set new hook */ + return 0; } -static int setlinehook (lua_State *L) { - sethook(L, (void *)&KEY_LINEHOOK, linef, lua_setlinehook); - return 1; +static int gethook (lua_State *L) { + char buff[5]; + int mask = lua_gethookmask(L); + lua_pushudataval(L, (void *)&KEY_HOOK); + lua_rawget(L, LUA_REGISTRYINDEX); /* get hook */ + lua_pushstring(L, unmakemask(mask, buff)); + lua_pushnumber(L, lua_getmaskcount(mask)); + return 3; } @@ -245,8 +250,8 @@ static int errorfb (lua_State *L) { static const luaL_reg dblib[] = { {"getlocal", getlocal}, {"getinfo", getinfo}, - {"setcallhook", setcallhook}, - {"setlinehook", setlinehook}, + {"gethook", gethook}, + {"sethook", sethook}, {"setlocal", setlocal}, {"debug", debug}, {"traceback", errorfb}, -- cgit v1.2.3-55-g6feb