LUALIB_API int luaL_argerror (lua_State *L, int arg, const char *extramsg) { lua_Debug ar; if (!lua_getstack(L, 0, &ar)) /* no stack frame? */ return luaL_error(L, "bad argument #%d (%s)", arg, extramsg); lua_getinfo(L, "n", &ar); if (strcmp(ar.namewhat, "method") == 0) { arg--; /* do not count 'self' */ if (arg == 0) /* error is in the self argument itself? */ return luaL_error(L, "calling '%s' on bad self (%s)", ar.name, extramsg); } if (ar.name == NULL) ar.name = (pushglobalfuncname(L, &ar)) ? lua_tostring(L, -1) : "?"; return luaL_error(L, "bad argument #%d to '%s' (%s)", arg, ar.name, extramsg); }
static std::string luaFormatStackInfo(lua_State *L, int level = 1) { lua_Debug ar; std::ostringstream os; if (lua_getstack(L, level, &ar) && lua_getinfo(L, "Sln", &ar)) { os << ar.short_src << ":" << ar.currentline << " ([" << ar.what << "] " << ar.namewhat << " " << (ar.name ? ar.name : "(?)") << ")"; } else { os << "???:0"; } return os.str(); }
int CLuaFile::EntityGetCharacterId(lua_State *L) { lua_getglobal(L, "pLUA"); CLuaFile *pSelf = (CLuaFile *)lua_touserdata(L, -1); lua_Debug Frame; lua_getstack(L, 1, &Frame); lua_getinfo(L, "nlSf", &Frame); CCharacter *pChr = (CCharacter *)pSelf->m_pServer->m_World.GetEntityByID(lua_tointeger(L, 1)); if (pChr) { lua_pushinteger(L, pChr->GetPlayer()->GetCID()); return 1; } return 0; }
static int getlocal (lua_State *L) { lua_Debug ar; const char *name; if (!lua_getstack(L, luaL_checkint(L, 1), &ar)) /* level out of range? */ return luaL_argerror(L, 1, "level out of range"); name = lua_getlocal(L, &ar, luaL_checkint(L, 2)); if (name) { lua_pushstring(L, name); lua_pushvalue(L, -2); return 2; } else { lua_pushnil(L); return 1; } }
int ts_trace(lua_State* L) { const int nargs = lua_gettop(L); if (nargs == 3) { CxxTest::TestTracker::tracker().trace(luaL_checkstring(L, -3), luaL_checkint(L, -2), luaL_checkstring(L, -1) ); } else if (nargs >= 1) { lua_Debug debug; lua_getstack(L, 1, &debug); lua_getinfo(L, "Sl", &debug); CxxTest::TestTracker::tracker().trace( debug.short_src, debug.currentline, luaL_checkstring(L, -1) ); } else { luaL_error(L, "TS_TRACE called with an illegal number of arguments"); } return 0; }
static int luaB_costatus(lua_State * L) { lua_State *co = lua_tothread(L, 1); luaL_argcheck(L, co, 1, "coroutine expected"); if (L == co) lua_pushliteral(L, "running"); else { lua_Debug ar; if (lua_getstack(co, 0, &ar) == 0 && lua_gettop(co) == 0) lua_pushliteral(L, "dead"); else lua_pushliteral(L, "suspended"); } return 1; }
static int luaLog( lua_State *_L ) { lua_Debug ar = { 0, xgc_nullptr, xgc_nullptr, xgc_nullptr, xgc_nullptr }; if( lua_getstack( _Lua, 1, &ar ) ) { lua_getinfo( _L, "Sl", &ar ); ar.name ? ar.name : "(unknowe)"; ar.source ? ar.source : "(null)"; get_logger( "LUA" ).write( logger_context( ar.source, ar.name, ar.currentline, logLevelTag<Level>::Tag ), "(%s)%s", ar.what, lua_tostring( _L, -1 ) ); } return 0; }
static void getfunc(lua_State * L) { if (lua_isfunction(L, 1)) lua_pushvalue(L, 1); else { lua_Debug ar; int level = luaL_optint(L, 1, 1); luaL_argcheck(L, level >= 0, 1, "level must be non-negative"); if (lua_getstack(L, level, &ar) == 0) luaL_argerror(L, 1, "invalid level"); lua_getinfo(L, "f", &ar); if (lua_isnil(L, -1)) luaL_error(L, "no function environment for tail call at level %d", level); } }
LUALIB_API int luaL_argerror (lua_State *L, int narg, const char *extramsg) { lua_Debug ar; if (!lua_getstack(L, 0, &ar)) /* no stack frame? */ return luaL_error(L, "bad argument #%d (%s)", narg, extramsg); lua_getinfo(L, "n", &ar); if (strcmp(ar.namewhat, "method") == 0) { narg--; /* do not count `self' */ if (narg == 0) /* error is in the self argument itself? */ return luaL_error(L, "calling " LUA_QS " on bad self (%s)", ar.name, extramsg); } if (ar.name == NULL) ar.name = "?"; return luaL_error(L, "bad argument #%d to " LUA_QS " (%s)", narg, ar.name, extramsg); }
// Checks for a valid argument count bool _Scripting::CheckArguments(lua_State *LuaObject, int Required) { int ArgumentCount = lua_gettop(LuaObject); // Check for arguments if(ArgumentCount != Required) { lua_Debug Record; lua_getstack(LuaObject, 0, &Record); lua_getinfo(LuaObject, "nl", &Record); Log.Write("Function %s requires %d arguments\n", Record.name, Required); return false; } return true; }
/* string tag string userstring thread co (default nil) integer level */ static int ltrace(lua_State *L) { struct skynet_context * context = lua_touserdata(L, lua_upvalueindex(1)); const char * tag = luaL_checkstring(L, 1); const char * user = luaL_checkstring(L, 2); if (lua_isthread(L, 3)) { lua_State * co = lua_tothread (L, 3); struct source_info si[MAX_LEVEL]; lua_Debug d; int level = luaL_checkinteger(L, 4); int index = 0; do { if (!lua_getstack(co, level, &d)) break; lua_getinfo(co, "Sl", &d); level++; si[index].source = d.source; si[index].line = d.currentline; if (d.currentline >= 0) ++index; } while (index < MAX_LEVEL); switch (index) { case 1: skynet_error(context, "<TRACE %s> %" PRId64 " %s : %s:%d", tag, get_time(), user, si[0].source, si[0].line); break; case 2: skynet_error(context, "<TRACE %s> %" PRId64 " %s : %s:%d %s:%d", tag, get_time(), user, si[0].source, si[0].line, si[1].source, si[1].line ); break; case 3: skynet_error(context, "<TRACE %s> %" PRId64 " %s : %s:%d %s:%d %s:%d", tag, get_time(), user, si[0].source, si[0].line, si[1].source, si[1].line, si[2].source, si[2].line ); break; default: skynet_error(context, "<TRACE %s> %" PRId64 " %s", tag, get_time(), user); break; } return 0; } skynet_error(context, "<TRACE %s> %" PRId64 " %s", tag, get_time(), user); return 0; }
int CLuaInstFileHelpers::FileHelpersCp(lua_State *L) { CLuaFileHelpers *D = FileHelpersCheckData(L, 1); if (!D) return 0; int numargs = lua_gettop(L) - 1; int min_numargs = 2; if (numargs < min_numargs) { printf("luascript cp: not enough arguments (%d, expected %d)\n", numargs, min_numargs); lua_pushboolean(L, false); return 1; } if (!lua_isstring(L, 2) || !lua_isstring(L, 3)) { printf("%s: argument 1 or 2 is not a string.\n",__func__); lua_pushboolean(L, false); return 1; } const char *from = luaL_checkstring(L, 2); const char *to = luaL_checkstring(L, 3); const char *flags = ""; if (numargs > min_numargs){ if (!lua_isstring(L, 4)) { printf("%s: argument 3 is not a string.\n",__func__); lua_pushboolean(L, false); return 1; } flags = luaL_checkstring(L, 4); } bool ret = false; CFileHelpers fh; fh.setConsoleQuiet(true); ret = fh.cp(from, to, flags); if (ret == false) { helpersDebugInfo di; fh.readDebugInfo(&di); lua_Debug ar; lua_getstack(L, 1, &ar); lua_getinfo(L, "Sl", &ar); printf(">>> Lua script error [%s:%d] %s\n (error from neutrino: [%s:%d])\n", ar.short_src, ar.currentline, di.msg.c_str(), di.file.c_str(), di.line); } lua_pushboolean(L, ret); return 1; }
LUALIB_API void luaL_where (lua_State *L, int level) { lua_Debug ar; if ( lua_getstack(L, level, &ar) ) { /* check function at level */ lua_getinfo(L, "Sl", &ar); /* get info about it */ if ( ar.currentline > 0 ) { /* is there info? */ lua_pushfstring(L, "%s:%d: ", ar.short_src, ar.currentline); return; } } lua_pushliteral(L, ""); /* else, no information available... */ }
/* ** Calls 'lua_getinfo' and collects all results in a new table. ** L1 needs stack space for an optional input (function) plus ** two optional outputs (function and line table) from function ** 'lua_getinfo'. */ static int db_getinfo (lua_State *L) { lua_Debug ar; int arg; lua_State *L1 = getthread(L, &arg); const char *options = luaL_optstring(L, arg+2, "flnStu"); checkstack(L, L1, 3); if (lua_isfunction(L, arg + 1)) { /* info about a function? */ options = lua_pushfstring(L, ">%s", options); /* add '>' to 'options' */ lua_pushvalue(L, arg + 1); /* move function to 'L1' stack */ lua_xmove(L, L1, 1); } else { /* stack level */ if (!lua_getstack(L1, (int)luaL_checkinteger(L, arg + 1), &ar)) { lua_pushnil(L); /* level out of range */ return 1; } } if (!lua_getinfo(L1, options, &ar)) return luaL_argerror(L, arg+2, "invalid option"); lua_newtable(L); /* table to collect results */ if (strchr(options, 'S')) { settabss(L, "source", ar.source); settabss(L, "short_src", ar.short_src); settabsi(L, "linedefined", ar.linedefined); settabsi(L, "lastlinedefined", ar.lastlinedefined); settabss(L, "what", ar.what); } if (strchr(options, 'l')) settabsi(L, "currentline", ar.currentline); if (strchr(options, 'u')) { settabsi(L, "nups", ar.nups); settabsi(L, "nparams", ar.nparams); settabsb(L, "isvararg", ar.isvararg); } if (strchr(options, 'n')) { settabss(L, "name", ar.name); settabss(L, "namewhat", ar.namewhat); } if (strchr(options, 't')) settabsb(L, "istailcall", ar.istailcall); if (strchr(options, 'L')) treatstackoption(L, L1, "activelines"); if (strchr(options, 'f')) treatstackoption(L, L1, "func"); return 1; /* return table */ }
//============================================================================ // int printMessage //--------------------------------------------------------------------------- // Prints a message to the console // // Parameter Dir Description // --------- --- ----------- // lua IN State variable // // Return // ------ // Number of return varaibles on the stack // //============================================================================ static int printMessage (lua_State *lua) { assert (lua_isstring (lua,1)); const char *msg = lua_tostring (lua, 1); // get caller lua_Debug ar; memset (&ar, 0, sizeof(ar)); lua_getstack (lua, 1, &ar); lua_getinfo (lua, "Snl", &ar); // debug output const char *str = ar.source; printf ("script: %s -- at %s(%d)\n", msg, str, ar.currentline); return 0; }
void luaPushError(lua_State *lua, char *error) { lua_Debug dbg; lua_newtable(lua); lua_pushstring(lua,"err"); /* Attempt to figure out where this function was called, if possible */ if(lua_getstack(lua, 1, &dbg) && lua_getinfo(lua, "nSl", &dbg)) { sds msg = sdscatprintf(sdsempty(), "%s: %d: %s", dbg.source, dbg.currentline, error); lua_pushstring(lua, msg); sdsfree(msg); } else { lua_pushstring(lua, error); } lua_settable(lua,-3); }
void CScriptDebugging::OutputDebugInfo ( lua_State* luaVM, int iLevel, unsigned char ucRed, unsigned char ucGreen, unsigned char ucBlue ) { char szDebugDump[255]; lua_Debug debugInfo; if ( lua_getstack ( luaVM, 1, &debugInfo ) ) { lua_getinfo ( luaVM, "nlS", &debugInfo ); // first version includes script path - makes much longer though // snprintf ( szDebugDump, 255, "Line: %d (%s + %d) %s", debugInfo.currentline, debugInfo.name, debugInfo.currentline - debugInfo.linedefined, debugInfo.short_src ); snprintf ( szDebugDump, 255, "Line: %d (%s + %d)", debugInfo.currentline, debugInfo.name, debugInfo.currentline - debugInfo.linedefined ); szDebugDump[255-1] = '\0'; LogString ( luaVM, szDebugDump, iLevel, ucRed, ucGreen, ucBlue ); } }
// typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar); static void LuaHookCall (lua_State *lua) { printf ("---- Call Stack ----\n"); // printf ("[Level] [Function] [# args] [@line] [src]\n"); lua_Debug ar; // Look at call stack for (int iLevel = 0; lua_getstack (lua, iLevel, &ar) != 0; ++iLevel) { if (lua_getinfo (lua, "Snlu", &ar) != 0) { printf ("%d %s %s %d @%d %s\n", iLevel, ar.namewhat, ar.name, ar.nups, ar.linedefined, ar.short_src); } } }
void CDbgLuaHelper::DrawLocalVariables() { debugger()->ClearLocalVariables(); int nLevel = debugger()->GetStackTraceLevel(); lua_Debug ar; if ( lua_getstack (L, nLevel, &ar) ) { int i = 1; const char *name; while ((name = lua_getlocal(L, &ar, i++)) != NULL) { DrawVariable(L,name,true); lua_pop(L, 1); /* remove variable value */ } } }
static int getinfo (lua_State *L) { lua_Debug ar; const char *options = luaL_optstring(L, 2, "flnSu"); if (lua_isnumber(L, 1)) { if (!lua_getstack(L, (int)(lua_tonumber(L, 1)), &ar)) { lua_pushnil(L); /* level out of range */ return 1; } } else if (lua_isfunction(L, 1)) { lua_pushfstring(L, ">%s", options); options = lua_tostring(L, -1); lua_pushvalue(L, 1); } else return luaL_argerror(L, 1, "function or level expected"); if (!lua_getinfo(L, options, &ar)) return luaL_argerror(L, 2, "invalid option"); lua_newtable(L); for (; *options; options++) { switch (*options) { case 'S': settabss(L, "source", ar.source); settabss(L, "short_src", ar.short_src); settabsi(L, "linedefined", ar.linedefined); settabss(L, "what", ar.what); break; case 'l': settabsi(L, "currentline", ar.currentline); break; case 'u': settabsi(L, "nups", ar.nups); break; case 'n': settabss(L, "name", ar.name); settabss(L, "namewhat", ar.namewhat); break; case 'f': lua_pushliteral(L, "func"); lua_pushvalue(L, -3); lua_rawset(L, -3); break; } } return 1; /* return table */ }
//------------------------------------------------------------------------------ void LuaSupport::DumpCallStack(lua_State* L) { for(int i = 1; i < 10; ++i) { lua_Debug ar; if(lua_getstack(L, i, &ar)) { lua_getinfo(L, "Sl", &ar); if(ar.currentline > 0) { FStringFixedBuffer(szTemp, 512); szTemp.Format("%s:%d\n", (ar.source)?ar.source:"", ar.currentline); OutputDebugString(szTemp.c_str()); } } } }
int CLuaFile::CharacterPredictedInput(lua_State *L) { lua_getglobal(L, "pLUA"); CLuaFile *pSelf = (CLuaFile *)lua_touserdata(L, -1); lua_Debug Frame; lua_getstack(L, 1, &Frame); lua_getinfo(L, "nlSf", &Frame); if (lua_isnumber(L, 1)) { if(lua_tointeger(L, 1) >= 0 && lua_tointeger(L, 1) < MAX_CLIENTS && pSelf->m_pServer->m_apPlayers[lua_tointeger(L, 1)] && pSelf->m_pServer->m_apPlayers[lua_tointeger(L, 1)]->GetCharacter()) { pSelf->m_pServer->m_apPlayers[lua_tointeger(L, 1)]->GetCharacter()->OnPredictedInput(pSelf->m_pServer->m_apPlayers[lua_tointeger(L, 1)]->GetCharacter()->GetInput()); } } return 0; }
String Util::where_am_i_lua( lua_State * L ) { std::ostringstream result; lua_Debug my_debug; if( lua_getstack( L, 1, &my_debug ) ) { if( lua_getinfo( L, "Sln", &my_debug ) ) { result << my_debug.source << ":" << my_debug.currentline; return result.str(); } } return String("(unknown)"); }
int Script::handle_error(lua_State* L){ lua_Debug d; lua_getstack(L, 1, &d); lua_getinfo(L, "Sln", &d); std::string err = lua_tostring(L, -1); lua_pop(L, 1); std::stringstream msg; msg << d.short_src << ":" << d.currentline; if (d.name != 0) { msg << "(" << d.namewhat << " " << d.name << ")"; } msg << " " << err; lua_pushstring(L, msg.str().c_str()); return 1; }
bool CDbgLuaHelper::GetCalltip(const char *szWord, char *szCalltip) { int nLevel = debugger()->GetStackTraceLevel(); lua_Debug ar; if ( lua_getstack (L, nLevel, &ar) ) { int i = 1; const char *name; while ((name = lua_getlocal(L, &ar, i++)) != NULL) { if ( xr_strcmp(name, szWord)==0 ) { char szRet[64]; Describe(szRet, -1); sprintf(szCalltip, "local %s : %s ", name, szRet); lua_pop(L, 1); /* remove variable value */ return true; } lua_pop(L, 1); /* remove variable value */ } } lua_pushvalue(L, LUA_GLOBALSINDEX); lua_pushnil(L); /* first key */ while (lua_next(L, -2)) { const char* name = lua_tostring(L, -2); if ( xr_strcmp(name, szWord)==0 ) { char szRet[64]; Describe(szRet, -1); sprintf(szCalltip, "global %s : %s ", name, szRet); lua_pop(L, 3); /* remove table, key, value */ return true; } lua_pop(L, 1); // pop value, keep key for next iteration; } lua_pop(L, 1); // pop table of globals; return false; }
void luaL_traceback (LuaThread *L, LuaThread *L1, const char *msg, int level) { THREAD_CHECK(L); LuaDebug ar; int top = L->stack_.getTopIndex(); int numlevels; { THREAD_CHANGE(L1); numlevels = countlevels(L1); } int mark = (numlevels > LEVELS1 + LEVELS2) ? LEVELS1 : 0; if (msg) { lua_pushfstring(L, "%s\n", msg); } lua_pushliteral(L, "stack traceback:"); { THREAD_CHANGE(L1); while (lua_getstack(L1, level++, &ar)) { if (level == mark) { /* too many levels? */ { THREAD_CHANGE(L); lua_pushliteral(L, "\n\t..."); /* add a '...' */ } level = numlevels - LEVELS2; /* and skip to last ones */ } else { lua_getinfo(L1, "Slnt", &ar); { THREAD_CHANGE(L); lua_pushfstring(L, "\n\t%s:", ar.short_src2.c_str()); if (ar.currentline > 0) { lua_pushfstring(L, "%d:", ar.currentline); } lua_pushliteral(L, " in "); pushfuncname(L, &ar); if (ar.istailcall) { lua_pushliteral(L, "\n\t(...tail calls...)"); } lua_concat(L, L->stack_.getTopIndex() - top); } } } } lua_concat(L, L->stack_.getTopIndex() - top); }
int CLuaInstFileHelpers::FileHelpersMkdir(lua_State *L) { CLuaFileHelpers *D = FileHelpersCheckData(L, 1); if (!D) return 0; int numargs = lua_gettop(L) - 1; int min_numargs = 1; if (numargs < min_numargs) { printf("luascript mkdir: not enough arguments (%d, expected %d)\n", numargs, min_numargs); lua_pushboolean(L, false); return 1; } if (!lua_isstring(L, 2)) { printf("%s: argument 1 is not a string.\n",__func__); lua_pushboolean(L, false); return 1; } const char *dir = luaL_checkstring(L, 2); mode_t mode = 0755; if (numargs > min_numargs) { int mode_i = luaL_checkint(L, 3); /* Hack for convert lua number to octal */ std::string mode_s = itoa(mode_i, 10); mode = (mode_t)(strtol(mode_s.c_str(), (char **)NULL, 8) & 0x0FFF); //printf("\n##### [%s:%d] str: %s, okt: %o \n \n", __func__, __LINE__, mode_s.c_str(), (int)mode); } bool ret = false; CFileHelpers* fh = CFileHelpers::getInstance(); fh->setConsoleQuiet(true); ret = fh->createDir(dir, mode); if (ret == false) { helpersDebugInfo di; fh->readDebugInfo(&di); lua_Debug ar; lua_getstack(L, 1, &ar); lua_getinfo(L, "Sl", &ar); printf(">>> Lua script error [%s:%d] %s\n (error from neutrino: [%s:%d])\n", ar.short_src, ar.currentline, di.msg.c_str(), di.file.c_str(), di.line); } lua_pushboolean(L, ret); return 1; }
//LaserCreate(Pos.x, Pos.y, Dir.x, Dir.y, StartEnergy, Owner) int CLuaFile::LaserCreate(lua_State *L) { lua_getglobal(L, "pLUA"); CLuaFile *pSelf = (CLuaFile *)lua_touserdata(L, -1); lua_Debug Frame; lua_getstack(L, 1, &Frame); lua_getinfo(L, "nlSf", &Frame); vec2 Pos; vec2 Dir; float StartEnergy = pSelf->m_pServer->Tuning()->m_LaserReach; int Owner; int Damage = -1; int MaxBounces = -1; int Delay = -1; int FakeEvalTick = -1; bool AutoDestroy = true; float DecreaseEnergyFactor = 1.0f; if(!lua_isnumber(L, 1) || !lua_isnumber(L, 2) || !lua_isnumber(L, 3) || !lua_isnumber(L, 4) || !lua_isnumber(L, 5)) return 0; Pos = vec2(lua_tonumber(L, 1), lua_tonumber(L, 2)); Dir = vec2(lua_tonumber(L, 3), lua_tonumber(L, 4)); Owner = lua_tointeger(L, 5); if (lua_tointeger(L, 6)) StartEnergy = lua_tonumber(L, 6); if (lua_isnumber(L, 7)) Damage = lua_tointeger(L, 7); if (lua_isnumber(L, 8)) MaxBounces = lua_tointeger(L, 8); if (lua_isnumber(L, 9)) Delay = lua_tointeger(L, 9); if (lua_isnumber(L, 10)) FakeEvalTick = lua_tointeger(L, 10); if (lua_isboolean(L, 11)) AutoDestroy = lua_toboolean(L, 11); if (lua_isboolean(L, 12)) DecreaseEnergyFactor = lua_tonumber(L, 12); CLaser *pTmp = new CLaser(&pSelf->m_pServer->m_World, Pos, Dir, StartEnergy, Owner, Damage, MaxBounces, Delay, FakeEvalTick, AutoDestroy, DecreaseEnergyFactor); lua_pushinteger(L, pTmp->GetID()); return 1; }
static int costatus (lua_State *L, lua_State *co) { if (L == co) return CO_RUN; switch (lua_status(co)) { case LUA_YIELD: return CO_SUS; case 0: { lua_Debug ar; if (lua_getstack(co, 0, &ar) > 0) /* does it have frames? */ return CO_NOR; /* it is running */ else if (lua_gettop(co) == 0) return CO_DEAD; else return CO_SUS; /* initial state */ } default: /* some error occured */ return CO_DEAD; } }
int luaL_argerror (LuaThread *L, int narg, const char *extramsg) { THREAD_CHECK(L); LuaDebug ar; if (!lua_getstack(L, 0, &ar)) /* no stack frame? */ return luaL_error(L, "bad argument #%d (%s)", narg, extramsg); lua_getinfo(L, "n", &ar); if (strcmp(ar.namewhat2.c_str(), "method") == 0) { narg--; /* do not count `self' */ if (narg == 0) /* error is in the self argument itself? */ return luaL_error(L, "calling " LUA_QS " on bad self", ar.name2.c_str()); } if (ar.name2.empty()) { LuaString* name = getglobalfuncname(L, &ar); ar.name2 = name ? name->c_str() : "?"; } return luaL_error(L, "bad argument #%d to " LUA_QS " (%s)", narg, ar.name2.c_str(), extramsg); }