diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2007-06-22 12:33:54 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2007-06-22 12:33:54 -0300 |
| commit | 3f78748ef357cbb128c96d7a07866f0953be1792 (patch) | |
| tree | f24acd60228a0aed334c11b1db60cbadf3347ddf /lauxlib.c | |
| parent | d26bfb5ae4fd11b784298317b39a390ea2a5beb5 (diff) | |
| download | lua-3f78748ef357cbb128c96d7a07866f0953be1792.tar.gz lua-3f78748ef357cbb128c96d7a07866f0953be1792.tar.bz2 lua-3f78748ef357cbb128c96d7a07866f0953be1792.zip | |
traceback function moved to auxlib
Diffstat (limited to 'lauxlib.c')
| -rw-r--r-- | lauxlib.c | 54 |
1 files changed, 53 insertions, 1 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lauxlib.c,v 1.168 2007/06/21 13:48:04 roberto Exp roberto $ | 2 | ** $Id: lauxlib.c,v 1.169 2007/06/21 14:09:59 roberto Exp roberto $ |
| 3 | ** Auxiliary functions for building Lua libraries | 3 | ** Auxiliary functions for building Lua libraries |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -89,6 +89,58 @@ LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) { | |||
| 89 | return lua_error(L); | 89 | return lua_error(L); |
| 90 | } | 90 | } |
| 91 | 91 | ||
| 92 | |||
| 93 | #define LEVELS1 12 /* size of the first part of the stack */ | ||
| 94 | #define LEVELS2 10 /* size of the second part of the stack */ | ||
| 95 | |||
| 96 | |||
| 97 | static void pushfuncname (lua_State *L, lua_Debug *ar) { | ||
| 98 | if (*ar->namewhat != '\0') /* is there a name? */ | ||
| 99 | lua_pushfstring(L, "function " LUA_QS, ar->name); | ||
| 100 | else if (*ar->what == 'm') /* main? */ | ||
| 101 | lua_pushfstring(L, "main chunk"); | ||
| 102 | else if (*ar->what == 'C' || *ar->what == 't') | ||
| 103 | lua_pushliteral(L, " ?"); /* C function or tail call */ | ||
| 104 | else | ||
| 105 | lua_pushfstring(L, "function <%s:%d>", ar->short_src, ar->linedefined); | ||
| 106 | } | ||
| 107 | |||
| 108 | |||
| 109 | static int countlevels (lua_State *L) { | ||
| 110 | lua_Debug ar; | ||
| 111 | int level = 1; | ||
| 112 | while (lua_getstack(L, level, &ar)) level++; | ||
| 113 | return level; | ||
| 114 | } | ||
| 115 | |||
| 116 | |||
| 117 | LUALIB_API const char *luaL_traceback (lua_State *L, lua_State *L1, | ||
| 118 | const char *msg, int level) { | ||
| 119 | lua_Debug ar; | ||
| 120 | int top = lua_gettop(L); | ||
| 121 | int numlevels = countlevels(L1); | ||
| 122 | int mark = (numlevels > LEVELS1 + LEVELS2) ? LEVELS1 : 0; | ||
| 123 | if (msg) lua_pushfstring(L, "%s\n", msg); | ||
| 124 | lua_pushliteral(L, "stack traceback:"); | ||
| 125 | while (lua_getstack(L1, level++, &ar)) { | ||
| 126 | if (level == mark) { /* too many levels? */ | ||
| 127 | lua_pushliteral(L, "\n\t..."); /* add a '...' */ | ||
| 128 | level = numlevels - LEVELS2; /* and skip to last ones */ | ||
| 129 | } | ||
| 130 | else { | ||
| 131 | lua_getinfo(L1, "Sln", &ar); | ||
| 132 | lua_pushfstring(L, "\n\t%s:", ar.short_src); | ||
| 133 | if (ar.currentline > 0) | ||
| 134 | lua_pushfstring(L, "%d:", ar.currentline); | ||
| 135 | lua_pushliteral(L, " in "); | ||
| 136 | pushfuncname(L, &ar); | ||
| 137 | lua_concat(L, lua_gettop(L) - top); | ||
| 138 | } | ||
| 139 | } | ||
| 140 | lua_concat(L, lua_gettop(L) - top); | ||
| 141 | return lua_tostring(L, -1); | ||
| 142 | } | ||
| 143 | |||
| 92 | /* }====================================================== */ | 144 | /* }====================================================== */ |
| 93 | 145 | ||
| 94 | 146 | ||
