diff options
Diffstat (limited to 'ldblib.c')
| -rw-r--r-- | ldblib.c | 89 |
1 files changed, 47 insertions, 42 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldblib.c,v 1.60 2002/06/18 17:42:52 roberto Exp roberto $ | 2 | ** $Id: ldblib.c,v 1.61 2002/06/25 19:16:44 roberto Exp roberto $ |
| 3 | ** Interface from Lua to its debug API | 3 | ** Interface from Lua to its debug API |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -108,65 +108,70 @@ static int setlocal (lua_State *L) { | |||
| 108 | 108 | ||
| 109 | 109 | ||
| 110 | 110 | ||
| 111 | static const char KEY_CALLHOOK = 'c'; | 111 | static const char KEY_HOOK = 'h'; |
| 112 | static const char KEY_LINEHOOK = 'l'; | ||
| 113 | 112 | ||
| 114 | 113 | ||
| 115 | static void hookf (lua_State *L, void *key) { | 114 | static void hookf (lua_State *L, lua_Debug *ar) { |
| 116 | lua_pushudataval(L, key); | 115 | static const char *const hooknames[] = {"call", "return", "line", "count"}; |
| 116 | lua_pushudataval(L, (void *)&KEY_HOOK); | ||
| 117 | lua_rawget(L, LUA_REGISTRYINDEX); | 117 | lua_rawget(L, LUA_REGISTRYINDEX); |
| 118 | if (lua_isfunction(L, -1)) { | 118 | if (lua_isfunction(L, -1)) { |
| 119 | lua_pushvalue(L, -2); /* original argument (below function) */ | 119 | lua_pushstring(L, hooknames[(int)ar->event]); |
| 120 | lua_call(L, 1, 0); | 120 | if (ar->currentline >= 0) lua_pushnumber(L, ar->currentline); |
| 121 | else lua_pushnil(L); | ||
| 122 | lua_assert(lua_getinfo(L, "lS", ar)); | ||
| 123 | lua_call(L, 2, 0); | ||
| 121 | } | 124 | } |
| 122 | else | 125 | else |
| 123 | lua_pop(L, 1); /* pop result from gettable */ | 126 | lua_pop(L, 1); /* pop result from gettable */ |
| 124 | } | 127 | } |
| 125 | 128 | ||
| 126 | 129 | ||
| 127 | static void callf (lua_State *L, lua_Debug *ar) { | 130 | static int makemask (const char *smask, int count) { |
| 128 | lua_pushstring(L, ar->event); | 131 | int mask = 0; |
| 129 | lua_assert(lua_getinfo(L, "lS", ar) && ar->currentline == -1); | 132 | if (strchr(smask, 'c')) mask |= LUA_MASKCALL; |
| 130 | hookf(L, (void *)&KEY_CALLHOOK); | 133 | if (strchr(smask, 'r')) mask |= LUA_MASKRET; |
| 134 | if (strchr(smask, 'l')) mask |= LUA_MASKLINE; | ||
| 135 | return mask | lua_maskcount(count); | ||
| 131 | } | 136 | } |
| 132 | 137 | ||
| 133 | 138 | ||
| 134 | static void linef (lua_State *L, lua_Debug *ar) { | 139 | static char *unmakemask (int mask, char *smask) { |
| 135 | lua_pushnumber(L, ar->currentline); | 140 | int i = 0; |
| 136 | lua_assert((ar->currentline = ar->linedefined = -1, | 141 | if (mask & LUA_MASKCALL) smask[i++] = 'c'; |
| 137 | lua_getinfo(L, "lS", ar) && | 142 | if (mask & LUA_MASKRET) smask[i++] = 'r'; |
| 138 | ar->currentline == lua_tonumber(L, -1) && | 143 | if (mask & LUA_MASKLINE) smask[i++] = 'l'; |
| 139 | ar->linedefined >= 0)); | 144 | smask[i] = '\0'; |
| 140 | hookf(L, (void *)&KEY_LINEHOOK); | 145 | return smask; |
| 141 | } | 146 | } |
| 142 | 147 | ||
| 143 | 148 | ||
| 144 | static void sethook (lua_State *L, void *key, lua_Hook hook, | 149 | static int sethook (lua_State *L) { |
| 145 | lua_Hook (*sethookf)(lua_State * L, lua_Hook h)) { | 150 | if (lua_isnoneornil(L, 1)) { |
| 146 | lua_settop(L, 1); | 151 | lua_settop(L, 1); |
| 147 | if (lua_isnoneornil(L, 1)) | 152 | lua_sethook(L, NULL, 0); /* turn off hooks */ |
| 148 | (*sethookf)(L, NULL); | 153 | } |
| 149 | else if (lua_isfunction(L, 1)) | 154 | else { |
| 150 | (*sethookf)(L, hook); | 155 | const char *smask = luaL_check_string(L, 2); |
| 151 | else | 156 | int count = luaL_opt_int(L, 3, 0); |
| 152 | luaL_argerror(L, 1, "function expected"); | 157 | luaL_check_type(L, 1, LUA_TFUNCTION); |
| 153 | lua_pushudataval(L, key); | 158 | lua_sethook(L, hookf, makemask(smask, count)); |
| 154 | lua_rawget(L, LUA_REGISTRYINDEX); /* get old value */ | 159 | } |
| 155 | lua_pushudataval(L, key); | 160 | lua_pushudataval(L, (void *)&KEY_HOOK); |
| 156 | lua_pushvalue(L, 1); | 161 | lua_pushvalue(L, 1); |
| 157 | lua_rawset(L, LUA_REGISTRYINDEX); /* set new value */ | 162 | lua_rawset(L, LUA_REGISTRYINDEX); /* set new hook */ |
| 158 | } | 163 | return 0; |
| 159 | |||
| 160 | |||
| 161 | static int setcallhook (lua_State *L) { | ||
| 162 | sethook(L, (void *)&KEY_CALLHOOK, callf, lua_setcallhook); | ||
| 163 | return 1; | ||
| 164 | } | 164 | } |
| 165 | 165 | ||
| 166 | 166 | ||
| 167 | static int setlinehook (lua_State *L) { | 167 | static int gethook (lua_State *L) { |
| 168 | sethook(L, (void *)&KEY_LINEHOOK, linef, lua_setlinehook); | 168 | char buff[5]; |
| 169 | return 1; | 169 | int mask = lua_gethookmask(L); |
| 170 | lua_pushudataval(L, (void *)&KEY_HOOK); | ||
| 171 | lua_rawget(L, LUA_REGISTRYINDEX); /* get hook */ | ||
| 172 | lua_pushstring(L, unmakemask(mask, buff)); | ||
| 173 | lua_pushnumber(L, lua_getmaskcount(mask)); | ||
| 174 | return 3; | ||
| 170 | } | 175 | } |
| 171 | 176 | ||
| 172 | 177 | ||
| @@ -245,8 +250,8 @@ static int errorfb (lua_State *L) { | |||
| 245 | static const luaL_reg dblib[] = { | 250 | static const luaL_reg dblib[] = { |
| 246 | {"getlocal", getlocal}, | 251 | {"getlocal", getlocal}, |
| 247 | {"getinfo", getinfo}, | 252 | {"getinfo", getinfo}, |
| 248 | {"setcallhook", setcallhook}, | 253 | {"gethook", gethook}, |
| 249 | {"setlinehook", setlinehook}, | 254 | {"sethook", sethook}, |
| 250 | {"setlocal", setlocal}, | 255 | {"setlocal", setlocal}, |
| 251 | {"debug", debug}, | 256 | {"debug", debug}, |
| 252 | {"traceback", errorfb}, | 257 | {"traceback", errorfb}, |
