]> jfr.im git - irc/quakenet/newserv.git/blob - lua/luadebug.c
LUA: port luadb to dbapi2 to drop postgres dependency
[irc/quakenet/newserv.git] / lua / luadebug.c
1 #include <lua.h>
2 #include <lauxlib.h>
3 #include <lualib.h>
4
5 #define LEVELS1 12 /* size of the first part of the stack */
6 #define LEVELS2 10 /* size of the second part of the stack */
7
8 /* stolen from ldblib.c as I can't figure out how to import it! */
9
10 static lua_State *getthread (lua_State *L, int *arg) {
11 if (lua_isthread(L, 1)) {
12 *arg = 1;
13 return lua_tothread(L, 1);
14 }
15 else {
16 *arg = 0;
17 return L;
18 }
19 }
20
21 static int db_errorfb (lua_State *L) {
22 int level;
23 int firstpart = 1; /* still before eventual `...' */
24 int arg;
25 lua_State *L1 = getthread(L, &arg);
26 lua_Debug ar;
27 if (lua_isnumber(L, arg+2)) {
28 level = (int)lua_tointeger(L, arg+2);
29 lua_pop(L, 1);
30 }
31 else
32 level = (L == L1) ? 1 : 0; /* level 0 may be this own function */
33 if (lua_gettop(L) == arg)
34 lua_pushliteral(L, "");
35 else if (!lua_isstring(L, arg+1)) return 1; /* message is not a string */
36 else lua_pushliteral(L, "\n");
37
38 lua_pushliteral(L, "stack traceback:");
39 while (lua_getstack(L1, level++, &ar)) {
40 if (level > LEVELS1 && firstpart) {
41 /* no more than `LEVELS2' more levels? */
42 if (!lua_getstack(L1, level+LEVELS2, &ar))
43 level--; /* keep going */
44 else {
45 lua_pushliteral(L, "\n\t..."); /* too many levels */
46 while (lua_getstack(L1, level+LEVELS2, &ar)) /* find last levels */
47 level++;
48 }
49 firstpart = 0;
50 continue;
51 }
52 lua_pushliteral(L, "\n\t");
53 lua_getinfo(L1, "Snl", &ar);
54 lua_pushfstring(L, "%s:", ar.short_src);
55 if (ar.currentline > 0)
56 lua_pushfstring(L, "%d:", ar.currentline);
57 if (*ar.namewhat != '\0') /* is there a name? */
58 lua_pushfstring(L, " in function " LUA_QS, ar.name);
59 else {
60 if (*ar.what == 'm') /* main? */
61 lua_pushfstring(L, " in main chunk");
62 else if (*ar.what == 'C' || *ar.what == 't')
63 lua_pushliteral(L, " ?"); /* C function or tail call */
64 else
65 lua_pushfstring(L, " in function <%s:%d>",
66 ar.short_src, ar.linedefined);
67 }
68 lua_concat(L, lua_gettop(L) - arg);
69 }
70 lua_concat(L, lua_gettop(L) - arg);
71 return 1;
72 }
73
74 void lua_registerdebug(lua_State *l) {
75 lua_register(l, "traceback", db_errorfb);
76 }
77