diff --git a/ldblib.c b/ldblib.c index 441c478c..d8224a8e 100644 --- a/ldblib.c +++ b/ldblib.c @@ -1,5 +1,5 @@ /* -** $Id: ldblib.c,v 1.104 2005/12/29 15:32:11 roberto Exp roberto $ +** $Id: ldblib.c,v 1.105 2006/09/11 14:07:24 roberto Exp roberto $ ** Interface from Lua to its debug API ** See Copyright Notice in lua.h */ @@ -319,21 +319,18 @@ static int db_debug (lua_State *L) { #define LEVELS2 10 /* size of the second part of the stack */ static int db_errorfb (lua_State *L) { - int level; + lua_Debug ar; int firstpart = 1; /* still before eventual `...' */ int arg; lua_State *L1 = getthread(L, &arg); - lua_Debug ar; - if (lua_isnumber(L, arg+2)) { - level = (int)lua_tointeger(L, arg+2); - lua_pop(L, 1); - } - else - level = (L == L1) ? 1 : 0; /* level 0 may be this own function */ - if (lua_gettop(L) == arg) - lua_pushliteral(L, ""); - else if (!lua_isstring(L, arg+1)) return 1; /* message is not a string */ - else lua_pushliteral(L, "\n"); + const char *msg = lua_tostring(L, arg + 1); + int level = (lua_isnumber(L, arg + 2)) ? + (int)lua_tointeger(L, arg + 2) : + (L == L1) ? 1 : 0; /* level 0 may be this own function */ + lua_settop(L, ++arg); + if (msg) lua_pushfstring(L, "%s\n", msg); + else if (!lua_isnil(L, arg)) /* is there a non-string 'msg'? */ + return 1; /* return it untouched */ lua_pushliteral(L, "stack traceback:"); while (lua_getstack(L1, level++, &ar)) { if (level > LEVELS1 && firstpart) { diff --git a/lua.c b/lua.c index 38419c14..c8951a1f 100644 --- a/lua.c +++ b/lua.c @@ -1,5 +1,5 @@ /* -** $Id: lua.c,v 1.163 2006/09/18 14:03:18 roberto Exp roberto $ +** $Id: lua.c,v 1.164 2006/10/10 17:40:17 roberto Exp roberto $ ** Lua stand-alone interpreter ** See Copyright Notice in lua.h */ @@ -41,7 +41,7 @@ static void laction (int i) { static void print_usage (void) { fprintf(stderr, - "usage: %s [options] [script [args]].\n" + "usage: %s [options] [script [args]]\n" "Available options are:\n" " -e stat execute string " LUA_QL("stat") "\n" " -l name require library " LUA_QL("name") "\n" @@ -73,20 +73,27 @@ static int report (lua_State *L, int status) { } -static int traceback (lua_State *L) { +static int gettraceback (lua_State *L) { lua_getfield(L, LUA_GLOBALSINDEX, "debug"); - if (!lua_istable(L, -1)) { - lua_pop(L, 1); - return 1; + if (!lua_istable(L, -1)) return 0; + lua_getfield(L, -1, "traceback"); /* check 'debug.traceback' */ + if (!lua_isfunction(L, -1)) return 0; + return 1; /* there is a function 'debug.traceback' */ +} + + +static int traceback (lua_State *L) { + if (lua_isnoneornil(L, 1)) /* no error object? */ + return 1; /* keep it that way */ + if (!gettraceback(L)) /* no 'debug.traceback' function? */ + lua_pushvalue(L, 1); /* keep original message */ + else { + lua_pushvalue(L, 1); /* pass error message */ + lua_pushinteger(L, 2); /* skip this function and traceback */ + lua_call(L, 2, 1); /* call traceback */ } - lua_getfield(L, -1, "traceback"); - if (!lua_isfunction(L, -1)) { - lua_pop(L, 2); - return 1; - } - lua_pushvalue(L, 1); /* pass error message */ - lua_pushinteger(L, 2); /* skip this function and traceback */ - lua_call(L, 2, 1); /* call debug.traceback */ + if (!lua_isstring(L, -1) && !luaL_callmeta(L, 1, "__tostring")) + lua_pushliteral(L, "(no error message)"); return 1; } @@ -96,6 +103,7 @@ static int docall (lua_State *L, int narg, int clear) { int base = lua_gettop(L) - narg; /* function index */ lua_pushcfunction(L, traceback); /* push traceback function */ lua_insert(L, base); /* put it under chunk and args */ + globalL = L; /* to be available to 'laction' */ signal(SIGINT, laction); status = lua_pcall(L, narg, (clear ? 0 : LUA_MULTRET), base); signal(SIGINT, SIG_DFL); @@ -160,7 +168,7 @@ static const char *get_prompt (lua_State *L, int firstline) { } /* mark in error messages for incomplete statements */ -#define mark LUA_QL("") +#define mark "" #define marklen (sizeof(mark) - 1) static int incomplete (lua_State *L, int status) { @@ -344,7 +352,6 @@ static int pmain (lua_State *L) { char **argv = s->argv; int script; int has_i = 0, has_v = 0, has_e = 0; - globalL = L; if (argv[0] && argv[0][0]) progname = argv[0]; lua_gc(L, LUA_GCSTOP, 0); /* stop collector during initialization */ luaL_openlibs(L); /* open libraries */