In process of adding luaconsole.cpp
This commit is contained in:
89
luprex/cpp/traceback.cpp
Normal file
89
luprex/cpp/traceback.cpp
Normal file
@@ -0,0 +1,89 @@
|
||||
#include "traceback.hpp"
|
||||
|
||||
#define TRACEBACK_LEVELS1 12
|
||||
#define TRACEBACK_LEVELS2 10
|
||||
|
||||
|
||||
static int traceback_general(lua_State *L, lua_State *L1, int msgindex) {
|
||||
int top = lua_gettop(L);
|
||||
|
||||
// Convert message to a string and push the string.
|
||||
if (lua_tostring(L, msgindex)) {
|
||||
lua_pushvalue(L, msgindex);
|
||||
} else {
|
||||
luaL_callmeta(L, msgindex, "__tostring");
|
||||
}
|
||||
|
||||
// If we didn't end up with exactly one string on
|
||||
// the stack, then clear the stack and push 'unknown error'.
|
||||
if ((lua_gettop(L) != top + 1) || (!lua_tostring(L, -1))) {
|
||||
lua_settop(L, top);
|
||||
lua_pushstring(L, "unknown error");
|
||||
}
|
||||
|
||||
// Append the traceback.
|
||||
lua_Debug ar;
|
||||
int level = 1;
|
||||
int firstpart = 1;
|
||||
while (lua_getstack(L1, level++, &ar)) {
|
||||
if (level > TRACEBACK_LEVELS1 && firstpart) {
|
||||
/* no more than `LEVELS2' more levels? */
|
||||
if (!lua_getstack(L1, level + TRACEBACK_LEVELS2, &ar))
|
||||
level--; /* keep going */
|
||||
else {
|
||||
lua_pushliteral(L, "\n\t..."); /* too many levels */
|
||||
while (lua_getstack(L1, level + TRACEBACK_LEVELS2, &ar)) /* find last levels */
|
||||
level++;
|
||||
}
|
||||
firstpart = 0;
|
||||
continue;
|
||||
}
|
||||
lua_getinfo(L1, "Snl", &ar);
|
||||
if ((ar.currentline > 0) || (*ar.namewhat != 0) || (*ar.what != 'C')) {
|
||||
lua_pushliteral(L, "\n\t");
|
||||
lua_pushfstring(L, "%s:", ar.short_src);
|
||||
if (ar.currentline > 0)
|
||||
lua_pushfstring(L, "%d:", ar.currentline);
|
||||
if (*ar.namewhat != '\0') /* is there a name? */
|
||||
lua_pushfstring(L, " in function " LUA_QS, ar.name);
|
||||
else {
|
||||
if (*ar.what == 'm') /* main? */
|
||||
lua_pushfstring(L, " in main chunk");
|
||||
else if (*ar.what == 'C' || *ar.what == 't')
|
||||
lua_pushliteral(L, " ?"); /* C function or tail call */
|
||||
else
|
||||
lua_pushfstring(L, " in function <%s:%d>",
|
||||
ar.short_src, ar.linedefined);
|
||||
}
|
||||
if (lua_gettop(L) - top > 5) {
|
||||
lua_concat(L, lua_gettop(L) - top);
|
||||
}
|
||||
}
|
||||
}
|
||||
lua_pushstring(L, "\n");
|
||||
if (lua_gettop(L) - top > 1) {
|
||||
lua_concat(L, lua_gettop(L) - top);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
LuaDefine(traceback_handler, "c") {
|
||||
return traceback_general(L, L, lua_gettop(L));
|
||||
}
|
||||
|
||||
LuaDefine(traceback_coroutine, "c") {
|
||||
LuaArg thread, message;
|
||||
LuaStack LS(L, thread, message);
|
||||
lua_State *L1 = LS.ckthread(thread);
|
||||
return traceback_general(L, L1, message.index());
|
||||
}
|
||||
|
||||
int traceback_pcall(lua_State *L, int narg, int nret) {
|
||||
int status;
|
||||
int base = lua_gettop(L) - narg; /* function index */
|
||||
lua_pushcfunction(L, traceback_handler); /* push traceback function */
|
||||
lua_insert(L, base); /* put it under chunk and args */
|
||||
status = lua_pcall(L, narg, nret, base);
|
||||
lua_remove(L, base); /* remove traceback function */
|
||||
return status;
|
||||
}
|
||||
Reference in New Issue
Block a user