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 | } |
