/* ** Basic implementation of _ERRORMESSAGE. ** The library `liolib' redefines _ERRORMESSAGE for better error information. */ static int luaB__ERRORMESSAGE (lua_State *L) { luaL_checktype(L, 1, LUA_TSTRING); lua_getglobal(L, LUA_ALERT); if (lua_isfunction(L, -1)) /* avoid error loop if _ALERT is not defined */ { lua_Debug ar; lua_pushstring(L, "error: "); lua_pushvalue(L, 1); if (lua_getstack(L, 1, &ar)) { lua_getinfo(L, "Sl", &ar); if (ar.source && ar.currentline > 0) { char buff[100]; sprintf(buff, "\n <%.70s: line %d>", ar.short_src, ar.currentline); lua_pushstring(L, buff); lua_concat(L, 2); } } lua_pushstring(L, "\n"); lua_concat(L, 3); lua_rawcall(L, 1, 0); } return 0; }
static void add_s (lua_State *L, luaL_Buffer *b, struct Capture *cap) { if (lua_isstring(L, 3)) { const char *news = lua_tostring(L, 3); size_t l = lua_strlen(L, 3); size_t i; for (i=0; i<l; i++) { if (news[i] != ESC) luaL_putchar(b, news[i]); else { i++; /* skip ESC */ if (!isdigit((unsigned char)news[i])) luaL_putchar(b, news[i]); else { int level = check_capture(L, news[i], cap); luaL_addlstring(b, cap->capture[level].init, cap->capture[level].len); } } } } else { /* is a function */ int n; lua_pushvalue(L, 3); n = push_captures(L, cap); lua_rawcall(L, n, 1); if (lua_isstring(L, -1)) luaL_addvalue(b); /* add return to accumulated result */ else lua_pop(L, 1); /* function result is not a string: pop it */ } }
/* ** call corresponding function inserting `globals' as first argument */ static int deprecated_func (lua_State *L) { lua_insert(L, 1); /* upvalue is the function to be called */ lua_getglobals(L); lua_insert(L, 2); /* table of globals is 1o argument */ lua_rawcall(L, lua_gettop(L)-1, LUA_MULTRET); return lua_gettop(L); /* return all results */ }
static void hookf (lua_State *L, void *key) { lua_getregistry(L); lua_pushuserdata(L, key); lua_gettable(L, -2); if (lua_isfunction(L, -1)) { lua_pushvalue(L, 1); lua_rawcall(L, 1, 0); } else lua_pop(L, 1); /* pop result from gettable */ lua_pop(L, 1); /* pop table */ }
static int xsort_comp (lua_State *L, int a, int b) { int res; lua_pushvalue(L, 2); lua_pushvalue(L, a-1); /* -1 to compensate function */ lua_pushvalue(L, b-2); /* -2 to compensate function and `a' */ lua_pushvalue(L, 3); lua_rawcall(L, 3, 1); res = lua_tonumber(L, -1); lua_pop(L, 1); return res; }
static int sort_comp (lua_State *L, int a, int b) { /* WARNING: the caller (auxsort) must ensure stack space */ if (!lua_isnil(L, 2)) { /* function? */ int res; lua_pushvalue(L, 2); lua_pushvalue(L, a-1); /* -1 to compensate function */ lua_pushvalue(L, b-2); /* -2 to compensate function and `a' */ lua_rawcall(L, 2, 1); res = !lua_isnil(L, -1); lua_pop(L, 1); return res; } else /* a < b? */ return lua_lessthan(L, a, b); }
static int luaB_foreach (lua_State *L) { luaL_checktype(L, 1, LUA_TTABLE); luaL_checktype(L, 2, LUA_TFUNCTION); lua_pushnil(L); /* first index */ for (;;) { if (lua_next(L, 1) == 0) return 0; lua_pushvalue(L, 2); /* function */ lua_pushvalue(L, -3); /* key */ lua_pushvalue(L, -3); /* value */ lua_rawcall(L, 2, 1); if (!lua_isnil(L, -1)) return 1; lua_pop(L, 2); /* remove value and result */ } }
static int luaB_foreachi (lua_State *L) { int n, i; luaL_checktype(L, 1, LUA_TTABLE); luaL_checktype(L, 2, LUA_TFUNCTION); n = lua_getn(L, 1); for (i=1; i<=n; i++) { lua_pushvalue(L, 2); /* function */ lua_pushnumber(L, i); /* 1st argument */ lua_rawgeti(L, 1, i); /* 2nd argument */ lua_rawcall(L, 2, 1); if (!lua_isnil(L, -1)) return 1; lua_pop(L, 1); /* remove nil result */ } return 0; }
/* ** If your system does not support `stdout', you can just remove this function. ** If you need, you can define your own `print' function, following this ** model but changing `fputs' to put the strings at a proper place ** (a console window or a log file, for instance). */ static int luaB_print (lua_State *L) { int n = lua_gettop(L); /* number of arguments */ int i; lua_getglobal(L, "tostring"); for (i=1; i<=n; i++) { const char *s; lua_pushvalue(L, -1); /* function to be called */ lua_pushvalue(L, i); /* value to print */ lua_rawcall(L, 1, 1); s = lua_tostring(L, -1); /* get result */ if (s == NULL) lua_error(L, "`tostring' must return a string to `print'"); if (i>1) fputs("\t", stdout); fputs(s, stdout); lua_pop(L, 1); /* pop result */ } fputs("\n", stdout); return 0; }
int CLuaConsoleDlg::lua_Print(lua_State *L) { // Snatched this from the Lua source code, // replacing writes to stdout with my custom // output to the LuaConsole's edit box int n = lua_gettop(L); // number of arguments int i; lua_getglobal(L, "tostring"); for (i=1; i<=n; i++) { CString s; lua_pushvalue(L, -1); // function to be called lua_pushvalue(L, i); // value to print lua_rawcall(L, 1, 1); s = lua_tostring(L, -1); // get result if (i>1) pThis->ToOutput("\t"); else pThis->ToOutput("--> "); pThis->ToOutput(s); lua_pop(L, 1); // pop result } pThis->ToOutput("\r\n"); return 0; }
static int errorfb (lua_State *L) { int level = 1; /* skip level 0 (it's this function) */ int firstpart = 1; /* still before eventual `...' */ lua_Debug ar; luaL_Buffer b; luaL_buffinit(L, &b); luaL_addstring(&b, "error: "); luaL_addstring(&b, luaL_check_string(L, 1)); luaL_addstring(&b, "\n"); while (lua_getstack(L, level++, &ar)) { char buff[120]; /* enough to fit following `sprintf's */ if (level == 2) luaL_addstring(&b, "stack traceback:\n"); else if (level > LEVELS1 && firstpart) { /* no more than `LEVELS2' more levels? */ if (!lua_getstack(L, level+LEVELS2, &ar)) level--; /* keep going */ else { luaL_addstring(&b, " ...\n"); /* too many levels */ while (lua_getstack(L, level+LEVELS2, &ar)) /* find last levels */ level++; } firstpart = 0; continue; } sprintf(buff, "%4d: ", level-1); luaL_addstring(&b, buff); lua_getinfo(L, "Snl", &ar); switch (*ar.namewhat) { case 'g': case 'l': /* global, local */ sprintf(buff, "function `%.50s'", ar.name); break; case 'f': /* field */ sprintf(buff, "method `%.50s'", ar.name); break; case 't': /* tag method */ sprintf(buff, "`%.50s' tag method", ar.name); break; default: { if (*ar.what == 'm') /* main? */ sprintf(buff, "main of %.70s", ar.short_src); else if (*ar.what == 'C') /* C function? */ sprintf(buff, "%.70s", ar.short_src); else sprintf(buff, "function <%d:%.70s>", ar.linedefined, ar.short_src); ar.source = NULL; /* do not print source again */ } } luaL_addstring(&b, buff); if (ar.currentline > 0) { sprintf(buff, " at line %d", ar.currentline); luaL_addstring(&b, buff); } if (ar.source) { sprintf(buff, " [%.70s]", ar.short_src); luaL_addstring(&b, buff); } luaL_addstring(&b, "\n"); } luaL_pushresult(&b); lua_getglobal(L, LUA_ALERT); if (lua_isfunction(L, -1)) { /* avoid loop if _ALERT is not defined */ lua_pushvalue(L, -2); /* error message */ lua_rawcall(L, 1, 0); } return 0; }