diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2009-02-27 15:17:13 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2009-02-27 15:17:13 -0300 |
commit | 9bf05e7364295cc6322f2ebb413994a2f42c4a80 (patch) | |
tree | d90fe89914e5b3a20af948a27fa91b43befd8be8 | |
parent | e39e758a73c08953d477c8e024ffbd1e2edfe6a5 (diff) | |
download | lua-9bf05e7364295cc6322f2ebb413994a2f42c4a80.tar.gz lua-9bf05e7364295cc6322f2ebb413994a2f42c4a80.tar.bz2 lua-9bf05e7364295cc6322f2ebb413994a2f42c4a80.zip |
code section 'Traceback' moved to the beginning of the file
-rw-r--r-- | lauxlib.c | 113 |
1 files changed, 61 insertions, 52 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lauxlib.c,v 1.181 2009/02/17 14:31:16 roberto Exp roberto $ | 2 | ** $Id: lauxlib.c,v 1.182 2009/02/18 17:20:56 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 | */ |
@@ -31,6 +31,66 @@ | |||
31 | 31 | ||
32 | /* | 32 | /* |
33 | ** {====================================================== | 33 | ** {====================================================== |
34 | ** Traceback | ||
35 | ** ======================================================= | ||
36 | */ | ||
37 | |||
38 | |||
39 | #define LEVELS1 12 /* size of the first part of the stack */ | ||
40 | #define LEVELS2 10 /* size of the second part of the stack */ | ||
41 | |||
42 | |||
43 | static void pushfuncname (lua_State *L, lua_Debug *ar) { | ||
44 | if (*ar->namewhat != '\0') /* is there a name? */ | ||
45 | lua_pushfstring(L, "function " LUA_QS, ar->name); | ||
46 | else if (*ar->what == 'm') /* main? */ | ||
47 | lua_pushfstring(L, "main chunk"); | ||
48 | else if (*ar->what == 'C' || *ar->what == 't') | ||
49 | lua_pushliteral(L, "?"); /* C function or tail call */ | ||
50 | else | ||
51 | lua_pushfstring(L, "function <%s:%d>", ar->short_src, ar->linedefined); | ||
52 | } | ||
53 | |||
54 | |||
55 | static int countlevels (lua_State *L) { | ||
56 | lua_Debug ar; | ||
57 | int level = 1; | ||
58 | while (lua_getstack(L, level, &ar)) level++; | ||
59 | return level; | ||
60 | } | ||
61 | |||
62 | |||
63 | LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1, | ||
64 | const char *msg, int level) { | ||
65 | lua_Debug ar; | ||
66 | int top = lua_gettop(L); | ||
67 | int numlevels = countlevels(L1); | ||
68 | int mark = (numlevels > LEVELS1 + LEVELS2) ? LEVELS1 : 0; | ||
69 | if (msg) lua_pushfstring(L, "%s\n", msg); | ||
70 | lua_pushliteral(L, "stack traceback:"); | ||
71 | while (lua_getstack(L1, level++, &ar)) { | ||
72 | if (level == mark) { /* too many levels? */ | ||
73 | lua_pushliteral(L, "\n\t..."); /* add a '...' */ | ||
74 | level = numlevels - LEVELS2; /* and skip to last ones */ | ||
75 | } | ||
76 | else { | ||
77 | lua_getinfo(L1, "Sln", &ar); | ||
78 | lua_pushfstring(L, "\n\t%s:", ar.short_src); | ||
79 | if (ar.currentline > 0) | ||
80 | lua_pushfstring(L, "%d:", ar.currentline); | ||
81 | lua_pushliteral(L, " in "); | ||
82 | pushfuncname(L, &ar); | ||
83 | lua_concat(L, lua_gettop(L) - top); | ||
84 | } | ||
85 | } | ||
86 | lua_concat(L, lua_gettop(L) - top); | ||
87 | } | ||
88 | |||
89 | /* }====================================================== */ | ||
90 | |||
91 | |||
92 | /* | ||
93 | ** {====================================================== | ||
34 | ** Error-report functions | 94 | ** Error-report functions |
35 | ** ======================================================= | 95 | ** ======================================================= |
36 | */ | 96 | */ |
@@ -87,57 +147,6 @@ LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) { | |||
87 | return lua_error(L); | 147 | return lua_error(L); |
88 | } | 148 | } |
89 | 149 | ||
90 | |||
91 | #define LEVELS1 12 /* size of the first part of the stack */ | ||
92 | #define LEVELS2 10 /* size of the second part of the stack */ | ||
93 | |||
94 | |||
95 | static void pushfuncname (lua_State *L, lua_Debug *ar) { | ||
96 | if (*ar->namewhat != '\0') /* is there a name? */ | ||
97 | lua_pushfstring(L, "function " LUA_QS, ar->name); | ||
98 | else if (*ar->what == 'm') /* main? */ | ||
99 | lua_pushfstring(L, "main chunk"); | ||
100 | else if (*ar->what == 'C' || *ar->what == 't') | ||
101 | lua_pushliteral(L, "?"); /* C function or tail call */ | ||
102 | else | ||
103 | lua_pushfstring(L, "function <%s:%d>", ar->short_src, ar->linedefined); | ||
104 | } | ||
105 | |||
106 | |||
107 | static int countlevels (lua_State *L) { | ||
108 | lua_Debug ar; | ||
109 | int level = 1; | ||
110 | while (lua_getstack(L, level, &ar)) level++; | ||
111 | return level; | ||
112 | } | ||
113 | |||
114 | |||
115 | LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1, | ||
116 | const char *msg, int level) { | ||
117 | lua_Debug ar; | ||
118 | int top = lua_gettop(L); | ||
119 | int numlevels = countlevels(L1); | ||
120 | int mark = (numlevels > LEVELS1 + LEVELS2) ? LEVELS1 : 0; | ||
121 | if (msg) lua_pushfstring(L, "%s\n", msg); | ||
122 | lua_pushliteral(L, "stack traceback:"); | ||
123 | while (lua_getstack(L1, level++, &ar)) { | ||
124 | if (level == mark) { /* too many levels? */ | ||
125 | lua_pushliteral(L, "\n\t..."); /* add a '...' */ | ||
126 | level = numlevels - LEVELS2; /* and skip to last ones */ | ||
127 | } | ||
128 | else { | ||
129 | lua_getinfo(L1, "Sln", &ar); | ||
130 | lua_pushfstring(L, "\n\t%s:", ar.short_src); | ||
131 | if (ar.currentline > 0) | ||
132 | lua_pushfstring(L, "%d:", ar.currentline); | ||
133 | lua_pushliteral(L, " in "); | ||
134 | pushfuncname(L, &ar); | ||
135 | lua_concat(L, lua_gettop(L) - top); | ||
136 | } | ||
137 | } | ||
138 | lua_concat(L, lua_gettop(L) - top); | ||
139 | } | ||
140 | |||
141 | /* }====================================================== */ | 150 | /* }====================================================== */ |
142 | 151 | ||
143 | 152 | ||