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