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