Lua 5.1.4: ldblib.c
L0001
L0006
L0007
L0008 #include <stdio.h>
L0009 #include <stdlib.h>
L0010 #include <string.h>
L0011
L0012 #define ldblib_c
L0013 #define LUA_LIB
L0014
L0015 #include "lua.h"
L0016
L0017 #include "lauxlib.h"
L0018 #include "lualib.h"
L0019
L0020
L0021
L0022 static int db_getregistry (lua_State *L) {
L0023 lua_pushvalue(L, LUA_REGISTRYINDEX);
L0024 return 1;
L0025 }
L0026
L0027
L0028 static int db_getmetatable (lua_State *L) {
L0029 luaL_checkany(L, 1);
L0030 if (!lua_getmetatable(L, 1)) {
L0031 lua_pushnil(L);
L0032 }
L0033 return 1;
L0034 }
L0035
L0036
L0037 static int db_setmetatable (lua_State *L) {
L0038 int t = lua_type(L, 2);
L0039 luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
L0040 "nil or table expected");
L0041 lua_settop(L, 2);
L0042 lua_pushboolean(L, lua_setmetatable(L, 1));
L0043 return 1;
L0044 }
L0045
L0046
L0047 static int db_getfenv (lua_State *L) {
L0048 lua_getfenv(L, 1);
L0049 return 1;
L0050 }
L0051
L0052
L0053 static int db_setfenv (lua_State *L) {
L0054 luaL_checktype(L, 2, LUA_TTABLE);
L0055 lua_settop(L, 2);
L0056 if (lua_setfenv(L, 1) == 0)
L0057 luaL_error(L, LUA_QL("setfenv")
L0058 " cannot change environment of given object");
L0059 return 1;
L0060 }
L0061
L0062
L0063 static void settabss (lua_State *L, const char *i, const char *v) {
L0064 lua_pushstring(L, v);
L0065 lua_setfield(L, -2, i);
L0066 }
L0067
L0068
L0069 static void settabsi (lua_State *L, const char *i, int v) {
L0070 lua_pushinteger(L, v);
L0071 lua_setfield(L, -2, i);
L0072 }
L0073
L0074
L0075 static lua_State *getthread (lua_State *L, int *arg) {
L0076 if (lua_isthread(L, 1)) {
L0077 *arg = 1;
L0078 return lua_tothread(L, 1);
L0079 }
L0080 else {
L0081 *arg = 0;
L0082 return L;
L0083 }
L0084 }
L0085
L0086
L0087 static void treatstackoption (lua_State *L, lua_State *L1, const char *fname) {
L0088 if (L == L1) {
L0089 lua_pushvalue(L, -2);
L0090 lua_remove(L, -3);
L0091 }
L0092 else
L0093 lua_xmove(L1, L, 1);
L0094 lua_setfield(L, -2, fname);
L0095 }
L0096
L0097
L0098 static int db_getinfo (lua_State *L) {
L0099 lua_Debug ar;
L0100 int arg;
L0101 lua_State *L1 = getthread(L, &arg);
L0102 const char *options = luaL_optstring(L, arg+2, "flnSu");
L0103 if (lua_isnumber(L, arg+1)) {
L0104 if (!lua_getstack(L1, (int)lua_tointeger(L, arg+1), &ar)) {
L0105 lua_pushnil(L);
L0106 return 1;
L0107 }
L0108 }
L0109 else if (lua_isfunction(L, arg+1)) {
L0110 lua_pushfstring(L, ">%s", options);
L0111 options = lua_tostring(L, -1);
L0112 lua_pushvalue(L, arg+1);
L0113 lua_xmove(L, L1, 1);
L0114 }
L0115 else
L0116 return luaL_argerror(L, arg+1, "function or level expected");
L0117 if (!lua_getinfo(L1, options, &ar))
L0118 return luaL_argerror(L, arg+2, "invalid option");
L0119 lua_createtable(L, 0, 2);
L0120 if (strchr(options, 'S')) {
L0121 settabss(L, "source", ar.source);
L0122 settabss(L, "short_src", ar.short_src);
L0123 settabsi(L, "linedefined", ar.linedefined);
L0124 settabsi(L, "lastlinedefined", ar.lastlinedefined);
L0125 settabss(L, "what", ar.what);
L0126 }
L0127 if (strchr(options, 'l'))
L0128 settabsi(L, "currentline", ar.currentline);
L0129 if (strchr(options, 'u'))
L0130 settabsi(L, "nups", ar.nups);
L0131 if (strchr(options, 'n')) {
L0132 settabss(L, "name", ar.name);
L0133 settabss(L, "namewhat", ar.namewhat);
L0134 }
L0135 if (strchr(options, 'L'))
L0136 treatstackoption(L, L1, "activelines");
L0137 if (strchr(options, 'f'))
L0138 treatstackoption(L, L1, "func");
L0139 return 1;
L0140 }
L0141
L0142
L0143 static int db_getlocal (lua_State *L) {
L0144 int arg;
L0145 lua_State *L1 = getthread(L, &arg);
L0146 lua_Debug ar;
L0147 const char *name;
L0148 if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar))
L0149 return luaL_argerror(L, arg+1, "level out of range");
L0150 name = lua_getlocal(L1, &ar, luaL_checkint(L, arg+2));
L0151 if (name) {
L0152 lua_xmove(L1, L, 1);
L0153 lua_pushstring(L, name);
L0154 lua_pushvalue(L, -2);
L0155 return 2;
L0156 }
L0157 else {
L0158 lua_pushnil(L);
L0159 return 1;
L0160 }
L0161 }
L0162
L0163
L0164 static int db_setlocal (lua_State *L) {
L0165 int arg;
L0166 lua_State *L1 = getthread(L, &arg);
L0167 lua_Debug ar;
L0168 if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar))
L0169 return luaL_argerror(L, arg+1, "level out of range");
L0170 luaL_checkany(L, arg+3);
L0171 lua_settop(L, arg+3);
L0172 lua_xmove(L, L1, 1);
L0173 lua_pushstring(L, lua_setlocal(L1, &ar, luaL_checkint(L, arg+2)));
L0174 return 1;
L0175 }
L0176
L0177
L0178 static int auxupvalue (lua_State *L, int get) {
L0179 const char *name;
L0180 int n = luaL_checkint(L, 2);
L0181 luaL_checktype(L, 1, LUA_TFUNCTION);
L0182 if (lua_iscfunction(L, 1)) return 0;
L0183 name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n);
L0184 if (name == NULL) return 0;
L0185 lua_pushstring(L, name);
L0186 lua_insert(L, -(get+1));
L0187 return get + 1;
L0188 }
L0189
L0190
L0191 static int db_getupvalue (lua_State *L) {
L0192 return auxupvalue(L, 1);
L0193 }
L0194
L0195
L0196 static int db_setupvalue (lua_State *L) {
L0197 luaL_checkany(L, 3);
L0198 return auxupvalue(L, 0);
L0199 }
L0200
L0201
L0202
L0203 static const char KEY_HOOK = 'h';
L0204
L0205
L0206 static void hookf (lua_State *L, lua_Debug *ar) {
L0207 static const char *const hooknames[] =
L0208 {"call", "return", "line", "count", "tail return"};
L0209 lua_pushlightuserdata(L, (void *)&KEY_HOOK);
L0210 lua_rawget(L, LUA_REGISTRYINDEX);
L0211 lua_pushlightuserdata(L, L);
L0212 lua_rawget(L, -2);
L0213 if (lua_isfunction(L, -1)) {
L0214 lua_pushstring(L, hooknames[(int)ar->event]);
L0215 if (ar->currentline >= 0)
L0216 lua_pushinteger(L, ar->currentline);
L0217 else lua_pushnil(L);
L0218 lua_assert(lua_getinfo(L, "lS", ar));
L0219 lua_call(L, 2, 0);
L0220 }
L0221 }
L0222
L0223
L0224 static int makemask (const char *smask, int count) {
L0225 int mask = 0;
L0226 if (strchr(smask, 'c')) mask |= LUA_MASKCALL;
L0227 if (strchr(smask, 'r')) mask |= LUA_MASKRET;
L0228 if (strchr(smask, 'l')) mask |= LUA_MASKLINE;
L0229 if (count > 0) mask |= LUA_MASKCOUNT;
L0230 return mask;
L0231 }
L0232
L0233
L0234 static char *unmakemask (int mask, char *smask) {
L0235 int i = 0;
L0236 if (mask & LUA_MASKCALL) smask[i++] = 'c';
L0237 if (mask & LUA_MASKRET) smask[i++] = 'r';
L0238 if (mask & LUA_MASKLINE) smask[i++] = 'l';
L0239 smask[i] = '\0';
L0240 return smask;
L0241 }
L0242
L0243
L0244 static void gethooktable (lua_State *L) {
L0245 lua_pushlightuserdata(L, (void *)&KEY_HOOK);
L0246 lua_rawget(L, LUA_REGISTRYINDEX);
L0247 if (!lua_istable(L, -1)) {
L0248 lua_pop(L, 1);
L0249 lua_createtable(L, 0, 1);
L0250 lua_pushlightuserdata(L, (void *)&KEY_HOOK);
L0251 lua_pushvalue(L, -2);
L0252 lua_rawset(L, LUA_REGISTRYINDEX);
L0253 }
L0254 }
L0255
L0256
L0257 static int db_sethook (lua_State *L) {
L0258 int arg, mask, count;
L0259 lua_Hook func;
L0260 lua_State *L1 = getthread(L, &arg);
L0261 if (lua_isnoneornil(L, arg+1)) {
L0262 lua_settop(L, arg+1);
L0263 func = NULL; mask = 0; count = 0;
L0264 }
L0265 else {
L0266 const char *smask = luaL_checkstring(L, arg+2);
L0267 luaL_checktype(L, arg+1, LUA_TFUNCTION);
L0268 count = luaL_optint(L, arg+3, 0);
L0269 func = hookf; mask = makemask(smask, count);
L0270 }
L0271 gethooktable(L);
L0272 lua_pushlightuserdata(L, L1);
L0273 lua_pushvalue(L, arg+1);
L0274 lua_rawset(L, -3);
L0275 lua_pop(L, 1);
L0276 lua_sethook(L1, func, mask, count);
L0277 return 0;
L0278 }
L0279
L0280
L0281 static int db_gethook (lua_State *L) {
L0282 int arg;
L0283 lua_State *L1 = getthread(L, &arg);
L0284 char buff[5];
L0285 int mask = lua_gethookmask(L1);
L0286 lua_Hook hook = lua_gethook(L1);
L0287 if (hook != NULL && hook != hookf)
L0288 lua_pushliteral(L, "external hook");
L0289 else {
L0290 gethooktable(L);
L0291 lua_pushlightuserdata(L, L1);
L0292 lua_rawget(L, -2);
L0293 lua_remove(L, -2);
L0294 }
L0295 lua_pushstring(L, unmakemask(mask, buff));
L0296 lua_pushinteger(L, lua_gethookcount(L1));
L0297 return 3;
L0298 }
L0299
L0300
L0301 static int db_debug (lua_State *L) {
L0302 for (;;) {
L0303 char buffer[250];
L0304 fputs("lua_debug> ", stderr);
L0305 if (fgets(buffer, sizeof(buffer), stdin) == 0 ||
L0306 strcmp(buffer, "cont\n") == 0)
L0307 return 0;
L0308 if (luaL_loadbuffer(L, buffer, strlen(buffer), "=(debug command)") ||
L0309 lua_pcall(L, 0, 0, 0)) {
L0310 fputs(lua_tostring(L, -1), stderr);
L0311 fputs("\n", stderr);
L0312 }
L0313 lua_settop(L, 0);
L0314 }
L0315 }
L0316
L0317
L0318 #define LEVELS1 12 /* size of the first part of the stack */
L0319 #define LEVELS2 10 /* size of the second part of the stack */
L0320
L0321 static int db_errorfb (lua_State *L) {
L0322 int level;
L0323 int firstpart = 1;
L0324 int arg;
L0325 lua_State *L1 = getthread(L, &arg);
L0326 lua_Debug ar;
L0327 if (lua_isnumber(L, arg+2)) {
L0328 level = (int)lua_tointeger(L, arg+2);
L0329 lua_pop(L, 1);
L0330 }
L0331 else
L0332 level = (L == L1) ? 1 : 0;
L0333 if (lua_gettop(L) == arg)
L0334 lua_pushliteral(L, "");
L0335 else if (!lua_isstring(L, arg+1)) return 1;
L0336 else lua_pushliteral(L, "\n");
L0337 lua_pushliteral(L, "stack traceback:");
L0338 while (lua_getstack(L1, level++, &ar)) {
L0339 if (level > LEVELS1 && firstpart) {
L0340
L0341 if (!lua_getstack(L1, level+LEVELS2, &ar))
L0342 level--;
L0343 else {
L0344 lua_pushliteral(L, "\n\t...");
L0345 while (lua_getstack(L1, level+LEVELS2, &ar))
L0346 level++;
L0347 }
L0348 firstpart = 0;
L0349 continue;
L0350 }
L0351 lua_pushliteral(L, "\n\t");
L0352 lua_getinfo(L1, "Snl", &ar);
L0353 lua_pushfstring(L, "%s:", ar.short_src);
L0354 if (ar.currentline > 0)
L0355 lua_pushfstring(L, "%d:", ar.currentline);
L0356 if (*ar.namewhat != '\0')
L0357 lua_pushfstring(L, " in function " LUA_QS, ar.name);
L0358 else {
L0359 if (*ar.what == 'm')
L0360 lua_pushfstring(L, " in main chunk");
L0361 else if (*ar.what == 'C' || *ar.what == 't')
L0362 lua_pushliteral(L, " ?");
L0363 else
L0364 lua_pushfstring(L, " in function <%s:%d>",
L0365 ar.short_src, ar.linedefined);
L0366 }
L0367 lua_concat(L, lua_gettop(L) - arg);
L0368 }
L0369 lua_concat(L, lua_gettop(L) - arg);
L0370 return 1;
L0371 }
L0372
L0373
L0374 static const luaL_Reg dblib[] = {
L0375 {"debug", db_debug},
L0376 {"getfenv", db_getfenv},
L0377 {"gethook", db_gethook},
L0378 {"getinfo", db_getinfo},
L0379 {"getlocal", db_getlocal},
L0380 {"getregistry", db_getregistry},
L0381 {"getmetatable", db_getmetatable},
L0382 {"getupvalue", db_getupvalue},
L0383 {"setfenv", db_setfenv},
L0384 {"sethook", db_sethook},
L0385 {"setlocal", db_setlocal},
L0386 {"setmetatable", db_setmetatable},
L0387 {"setupvalue", db_setupvalue},
L0388 {"traceback", db_errorfb},
L0389 {NULL, NULL}
L0390 };
L0391
L0392
L0393 LUALIB_API int luaopen_debug (lua_State *L) {
L0394 luaL_register(L, LUA_DBLIBNAME, dblib);
L0395 return 1;
L0396 }
L0397
Generated by pretty.lua