diff options
Diffstat (limited to 'ldblib.c')
-rw-r--r-- | ldblib.c | 94 |
1 files changed, 91 insertions, 3 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldblib.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $ | 2 | ** $Id: ldblib.c,v 1.43 2002/02/07 17:24:32 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 | */ |
@@ -167,17 +167,105 @@ static int setlinehook (lua_State *L) { | |||
167 | } | 167 | } |
168 | 168 | ||
169 | 169 | ||
170 | static int debug (lua_State *L) { | ||
171 | for (;;) { | ||
172 | char buffer[250]; | ||
173 | fprintf(stderr, "lua_debug> "); | ||
174 | if (fgets(buffer, sizeof(buffer), stdin) == 0 || | ||
175 | strcmp(buffer, "cont\n") == 0) | ||
176 | return 0; | ||
177 | lua_dostring(L, buffer); | ||
178 | lua_settop(L, 0); /* remove eventual returns */ | ||
179 | } | ||
180 | } | ||
181 | |||
182 | |||
183 | #define LEVELS1 12 /* size of the first part of the stack */ | ||
184 | #define LEVELS2 10 /* size of the second part of the stack */ | ||
185 | |||
186 | static int errorfb (lua_State *L) { | ||
187 | int level = 1; /* skip level 0 (it's this function) */ | ||
188 | int firstpart = 1; /* still before eventual `...' */ | ||
189 | lua_Debug ar; | ||
190 | luaL_Buffer b; | ||
191 | luaL_buffinit(L, &b); | ||
192 | luaL_addstring(&b, "error: "); | ||
193 | luaL_addstring(&b, luaL_check_string(L, 1)); | ||
194 | luaL_addstring(&b, "\n"); | ||
195 | while (lua_getstack(L, level++, &ar)) { | ||
196 | char buff[120]; /* enough to fit following `sprintf's */ | ||
197 | if (level == 2) | ||
198 | luaL_addstring(&b, "stack traceback:\n"); | ||
199 | else if (level > LEVELS1 && firstpart) { | ||
200 | /* no more than `LEVELS2' more levels? */ | ||
201 | if (!lua_getstack(L, level+LEVELS2, &ar)) | ||
202 | level--; /* keep going */ | ||
203 | else { | ||
204 | luaL_addstring(&b, " ...\n"); /* too many levels */ | ||
205 | while (lua_getstack(L, level+LEVELS2, &ar)) /* find last levels */ | ||
206 | level++; | ||
207 | } | ||
208 | firstpart = 0; | ||
209 | continue; | ||
210 | } | ||
211 | sprintf(buff, "%4d: ", level-1); | ||
212 | luaL_addstring(&b, buff); | ||
213 | lua_getinfo(L, "Snl", &ar); | ||
214 | switch (*ar.namewhat) { | ||
215 | case 'g': case 'l': /* global, local */ | ||
216 | sprintf(buff, "function `%.50s'", ar.name); | ||
217 | break; | ||
218 | case 'f': /* field */ | ||
219 | sprintf(buff, "method `%.50s'", ar.name); | ||
220 | break; | ||
221 | case 't': /* tag method */ | ||
222 | sprintf(buff, "`%.50s' tag method", ar.name); | ||
223 | break; | ||
224 | default: { | ||
225 | if (*ar.what == 'm') /* main? */ | ||
226 | sprintf(buff, "main of %.70s", ar.short_src); | ||
227 | else if (*ar.what == 'C') /* C function? */ | ||
228 | sprintf(buff, "%.70s", ar.short_src); | ||
229 | else | ||
230 | sprintf(buff, "function <%d:%.70s>", ar.linedefined, ar.short_src); | ||
231 | ar.source = NULL; /* do not print source again */ | ||
232 | } | ||
233 | } | ||
234 | luaL_addstring(&b, buff); | ||
235 | if (ar.currentline > 0) { | ||
236 | sprintf(buff, " at line %d", ar.currentline); | ||
237 | luaL_addstring(&b, buff); | ||
238 | } | ||
239 | if (ar.source) { | ||
240 | sprintf(buff, " [%.70s]", ar.short_src); | ||
241 | luaL_addstring(&b, buff); | ||
242 | } | ||
243 | luaL_addstring(&b, "\n"); | ||
244 | } | ||
245 | luaL_pushresult(&b); | ||
246 | lua_getglobal(L, LUA_ALERT); | ||
247 | if (lua_isfunction(L, -1)) { /* avoid loop if _ALERT is not defined */ | ||
248 | lua_pushvalue(L, -2); /* error message */ | ||
249 | lua_rawcall(L, 1, 0); | ||
250 | } | ||
251 | return 0; | ||
252 | } | ||
253 | |||
254 | |||
170 | static const luaL_reg dblib[] = { | 255 | static const luaL_reg dblib[] = { |
171 | {"getlocal", getlocal}, | 256 | {"getlocal", getlocal}, |
172 | {"getinfo", getinfo}, | 257 | {"getinfo", getinfo}, |
173 | {"setcallhook", setcallhook}, | 258 | {"setcallhook", setcallhook}, |
174 | {"setlinehook", setlinehook}, | 259 | {"setlinehook", setlinehook}, |
175 | {"setlocal", setlocal} | 260 | {"setlocal", setlocal}, |
261 | {"debug", debug}, | ||
262 | {NULL, NULL} | ||
176 | }; | 263 | }; |
177 | 264 | ||
178 | 265 | ||
179 | LUALIB_API int lua_dblibopen (lua_State *L) { | 266 | LUALIB_API int lua_dblibopen (lua_State *L) { |
180 | luaL_openl(L, dblib); | 267 | luaL_opennamedlib(L, "dbg", dblib); |
268 | lua_register(L, LUA_ERRORMESSAGE, errorfb); | ||
181 | return 0; | 269 | return 0; |
182 | } | 270 | } |
183 | 271 | ||