All pastes #424090 Raw Edit

Stuff

public text v1 · immutable
·published 2007-04-04 15:56 UTC
rendered paste body
/// An error handler that appends a stack traceback to the error message.
/// Pass this to setErrorHandler to use it.
// Copied from lua-5.0.2/src/lib/ldblib.c
intTracebackErrorHandler( lua_State *L )
{
    const int LEVELS1 = 12;      /* size of the first part of the stack */
    const int LEVELS2 = 10;      /* size of the second part of the stack */

    int level = 1;/* skip level 0 (it's this function) */
    int firstpart = 1;/* still before eventual `...' */
    lua_Debug ar;
    if (lua_gettop(L) == 0)
        lua_pushliteral(L, "");
    else if (!lua_isstring(L, 1)) return 1;/* no string message */
    else lua_pushliteral(L, "\n");
        lua_pushliteral(L, "stack traceback:");

    while (lua_getstack(L, level++, &ar)) {
        if (level > LEVELS1 && firstpart) {
            /* no more than `LEVELS2' more levels? */
            if (!lua_getstack(L, level+LEVELS2, &ar))
                level--;/* keep going */
            else {
                lua_pushliteral(L, "\n\t...");/* too many levels */
                while (lua_getstack(L, level+LEVELS2, &ar))/* find last levels */
                    level++;
            }
            firstpart = 0;
            continue;
        }
        lua_pushliteral(L, "\n\t");
        lua_getinfo(L, "Snl", &ar);
        lua_pushfstring(L, "%s:", ar.short_src);
        if (ar.currentline > 0)
            lua_pushfstring(L, "%d:", ar.currentline);
        switch (*ar.namewhat) {
            case 'g':/* global */
            case 'l':/* local */
            case 'f':/* field */
            case 'm':/* method */
                lua_pushfstring(L, " in function `%s'", ar.name);
                break;
            default: {
                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);
            }
        }
        lua_concat(L, lua_gettop(L));
    }
    lua_concat(L, lua_gettop(L));
    return 1;
}