| 657 | #define TRACEBACK_LEVELS2 10 |
| 658 | |
| 659 | LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1, const char *msg, |
| 660 | int level) |
| 661 | { |
| 662 | int top = (int)(L->top - L->base); |
| 663 | int lim = TRACEBACK_LEVELS1; |
| 664 | lua_Debug ar; |
| 665 | if (msg) lua_pushfstring(L, "%s\n", msg); |
| 666 | lua_pushliteral(L, "stack traceback:"); |
| 667 | while (lua_getstack(L1, level++, &ar)) { |
| 668 | GCfunc *fn; |
| 669 | if (level > lim) { |
| 670 | if (!lua_getstack(L1, level + TRACEBACK_LEVELS2, &ar)) { |
| 671 | level--; |
| 672 | } else { |
| 673 | lua_pushliteral(L, "\n\t..."); |
| 674 | lua_getstack(L1, -10, &ar); |
| 675 | level = ar.i_ci - TRACEBACK_LEVELS2; |
| 676 | } |
| 677 | lim = 2147483647; |
| 678 | continue; |
| 679 | } |
| 680 | lua_getinfo(L1, "Snlf", &ar); |
| 681 | fn = funcV(L1->top-1); L1->top--; |
| 682 | if (isffunc(fn) && !*ar.namewhat) |
| 683 | lua_pushfstring(L, "\n\t[builtin#%d]:", fn->c.ffid); |
| 684 | else |
| 685 | lua_pushfstring(L, "\n\t%s:", ar.short_src); |
| 686 | if (ar.currentline > 0) |
| 687 | lua_pushfstring(L, "%d:", ar.currentline); |
| 688 | if (*ar.namewhat) { |
| 689 | lua_pushfstring(L, " in function " LUA_QS, ar.name); |
| 690 | } else { |
| 691 | if (*ar.what == 'm') { |
| 692 | lua_pushliteral(L, " in main chunk"); |
| 693 | } else if (*ar.what == 'C') { |
| 694 | lua_pushfstring(L, " at %p", fn->c.f); |
| 695 | } else { |
| 696 | lua_pushfstring(L, " in function <%s:%d>", |
| 697 | ar.short_src, ar.linedefined); |
| 698 | } |
| 699 | } |
| 700 | if ((int)(L->top - L->base) - top >= 15) |
| 701 | lua_concat(L, (int)(L->top - L->base) - top); |
| 702 | } |
| 703 | lua_concat(L, (int)(L->top - L->base) - top); |
| 704 | } |
| 705 |
no test coverage detected