|
@@ -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},
|