diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2009-02-27 15:18:19 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2009-02-27 15:18:19 -0300 |
commit | b4033173253a0ce443a27d95dcb6c575f1bc272e (patch) | |
tree | d696139b3e5e7b76c20d83163da8643430503939 | |
parent | 9bf05e7364295cc6322f2ebb413994a2f42c4a80 (diff) | |
download | lua-b4033173253a0ce443a27d95dcb6c575f1bc272e.tar.gz lua-b4033173253a0ce443a27d95dcb6c575f1bc272e.tar.bz2 lua-b4033173253a0ce443a27d95dcb6c575f1bc272e.zip |
error functions search global space for a name for a function when
no other name is available
-rw-r--r-- | lauxlib.c | 58 |
1 files changed, 55 insertions, 3 deletions
@@ -40,13 +40,65 @@ | |||
40 | #define LEVELS2 10 /* size of the second part of the stack */ | 40 | #define LEVELS2 10 /* size of the second part of the stack */ |
41 | 41 | ||
42 | 42 | ||
43 | |||
44 | /* | ||
45 | ** search for 'objidx' in table at index -1. | ||
46 | ** return 1 + string at top if find a good name. | ||
47 | */ | ||
48 | static int findfield (lua_State *L, int objidx, int level) { | ||
49 | int found = 0; | ||
50 | if (level == 0 || !lua_istable(L, -1)) | ||
51 | return 0; /* not found */ | ||
52 | lua_pushnil(L); /* start 'next' loop */ | ||
53 | while (!found && lua_next(L, -2)) { /* for each pair in table */ | ||
54 | if (lua_type(L, -2) == LUA_TSTRING) { /* ignore non-string keys */ | ||
55 | if (lua_rawequal(L, objidx, -1)) { /* found object? */ | ||
56 | lua_pop(L, 1); /* remove value (but keep name) */ | ||
57 | return 1; | ||
58 | } | ||
59 | else if (findfield(L, objidx, level - 1)) { /* try recursively */ | ||
60 | lua_remove(L, -2); /* remove table (but keep name) */ | ||
61 | lua_pushliteral(L, "."); | ||
62 | lua_insert(L, -2); /* place '.' between the two names */ | ||
63 | lua_concat(L, 3); | ||
64 | return 1; | ||
65 | } | ||
66 | } | ||
67 | lua_pop(L, 1); /* remove value */ | ||
68 | } | ||
69 | return 0; /* not found */ | ||
70 | } | ||
71 | |||
72 | |||
73 | static int pushglobalfuncname (lua_State *L, lua_Debug *ar) { | ||
74 | int top = lua_gettop(L); | ||
75 | lua_getinfo(L, "f", ar); /* push function */ | ||
76 | lua_pushvalue(L, LUA_GLOBALSINDEX); /* push global table */ | ||
77 | if (findfield(L, top + 1, 2)) { | ||
78 | lua_replace(L, top + 1); /* move name to proper place */ | ||
79 | lua_pop(L, 1); /* remove other pushed value */ | ||
80 | return 1; | ||
81 | } | ||
82 | else { | ||
83 | lua_settop(L, top); /* remove function and global table */ | ||
84 | return 0; | ||
85 | } | ||
86 | } | ||
87 | |||
88 | |||
43 | static void pushfuncname (lua_State *L, lua_Debug *ar) { | 89 | static void pushfuncname (lua_State *L, lua_Debug *ar) { |
44 | if (*ar->namewhat != '\0') /* is there a name? */ | 90 | if (*ar->namewhat != '\0') /* is there a name? */ |
45 | lua_pushfstring(L, "function " LUA_QS, ar->name); | 91 | lua_pushfstring(L, "function " LUA_QS, ar->name); |
46 | else if (*ar->what == 'm') /* main? */ | 92 | else if (*ar->what == 'm') /* main? */ |
47 | lua_pushfstring(L, "main chunk"); | 93 | lua_pushfstring(L, "main chunk"); |
48 | else if (*ar->what == 'C' || *ar->what == 't') | 94 | else if (*ar->what == 'C' || *ar->what == 't') { |
49 | lua_pushliteral(L, "?"); /* C function or tail call */ | 95 | if (pushglobalfuncname(L, ar)) { |
96 | lua_pushfstring(L, "function " LUA_QS, lua_tostring(L, -1)); | ||
97 | lua_remove(L, -2); /* remove name */ | ||
98 | } | ||
99 | else | ||
100 | lua_pushliteral(L, "?"); /* C function or tail call */ | ||
101 | } | ||
50 | else | 102 | else |
51 | lua_pushfstring(L, "function <%s:%d>", ar->short_src, ar->linedefined); | 103 | lua_pushfstring(L, "function <%s:%d>", ar->short_src, ar->linedefined); |
52 | } | 104 | } |
@@ -106,7 +158,7 @@ LUALIB_API int luaL_argerror (lua_State *L, int narg, const char *extramsg) { | |||
106 | return luaL_error(L, "calling " LUA_QS " on bad self", ar.name); | 158 | return luaL_error(L, "calling " LUA_QS " on bad self", ar.name); |
107 | } | 159 | } |
108 | if (ar.name == NULL) | 160 | if (ar.name == NULL) |
109 | ar.name = "?"; | 161 | ar.name = (pushglobalfuncname(L, &ar)) ? lua_tostring(L, -1) : "?"; |
110 | return luaL_error(L, "bad argument #%d to " LUA_QS " (%s)", | 162 | return luaL_error(L, "bad argument #%d to " LUA_QS " (%s)", |
111 | narg, ar.name, extramsg); | 163 | narg, ar.name, extramsg); |
112 | } | 164 | } |