Lua 5.1.4: lbaselib.c
L0001
L0006
L0007
L0008
L0009 #include <ctype.h>
L0010 #include <stdio.h>
L0011 #include <stdlib.h>
L0012 #include <string.h>
L0013
L0014 #define lbaselib_c
L0015 #define LUA_LIB
L0016
L0017 #include "lua.h"
L0018
L0019 #include "lauxlib.h"
L0020 #include "lualib.h"
L0021
L0022
L0023
L0024
L0025
L0031 static int luaB_print (lua_State *L) {
L0032 int n = lua_gettop(L);
L0033 int i;
L0034 lua_getglobal(L, "tostring");
L0035 for (i=1; i<=n; i++) {
L0036 const char *s;
L0037 lua_pushvalue(L, -1);
L0038 lua_pushvalue(L, i);
L0039 lua_call(L, 1, 1);
L0040 s = lua_tostring(L, -1);
L0041 if (s == NULL)
L0042 return luaL_error(L, LUA_QL("tostring") " must return a string to "
L0043 LUA_QL("print"));
L0044 if (i>1) fputs("\t", stdout);
L0045 fputs(s, stdout);
L0046 lua_pop(L, 1);
L0047 }
L0048 fputs("\n", stdout);
L0049 return 0;
L0050 }
L0051
L0052
L0053 static int luaB_tonumber (lua_State *L) {
L0054 int base = luaL_optint(L, 2, 10);
L0055 if (base == 10) {
L0056 luaL_checkany(L, 1);
L0057 if (lua_isnumber(L, 1)) {
L0058 lua_pushnumber(L, lua_tonumber(L, 1));
L0059 return 1;
L0060 }
L0061 }
L0062 else {
L0063 const char *s1 = luaL_checkstring(L, 1);
L0064 char *s2;
L0065 unsigned long n;
L0066 luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range");
L0067 n = strtoul(s1, &s2, base);
L0068 if (s1 != s2) {
L0069 while (isspace((unsigned char)(*s2))) s2++;
L0070 if (*s2 == '\0') {
L0071 lua_pushnumber(L, (lua_Number)n);
L0072 return 1;
L0073 }
L0074 }
L0075 }
L0076 lua_pushnil(L);
L0077 return 1;
L0078 }
L0079
L0080
L0081 static int luaB_error (lua_State *L) {
L0082 int level = luaL_optint(L, 2, 1);
L0083 lua_settop(L, 1);
L0084 if (lua_isstring(L, 1) && level > 0) {
L0085 luaL_where(L, level);
L0086 lua_pushvalue(L, 1);
L0087 lua_concat(L, 2);
L0088 }
L0089 return lua_error(L);
L0090 }
L0091
L0092
L0093 static int luaB_getmetatable (lua_State *L) {
L0094 luaL_checkany(L, 1);
L0095 if (!lua_getmetatable(L, 1)) {
L0096 lua_pushnil(L);
L0097 return 1;
L0098 }
L0099 luaL_getmetafield(L, 1, "__metatable");
L0100 return 1;
L0101 }
L0102
L0103
L0104 static int luaB_setmetatable (lua_State *L) {
L0105 int t = lua_type(L, 2);
L0106 luaL_checktype(L, 1, LUA_TTABLE);
L0107 luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
L0108 "nil or table expected");
L0109 if (luaL_getmetafield(L, 1, "__metatable"))
L0110 luaL_error(L, "cannot change a protected metatable");
L0111 lua_settop(L, 2);
L0112 lua_setmetatable(L, 1);
L0113 return 1;
L0114 }
L0115
L0116
L0117 static void getfunc (lua_State *L, int opt) {
L0118 if (lua_isfunction(L, 1)) lua_pushvalue(L, 1);
L0119 else {
L0120 lua_Debug ar;
L0121 int level = opt ? luaL_optint(L, 1, 1) : luaL_checkint(L, 1);
L0122 luaL_argcheck(L, level >= 0, 1, "level must be non-negative");
L0123 if (lua_getstack(L, level, &ar) == 0)
L0124 luaL_argerror(L, 1, "invalid level");
L0125 lua_getinfo(L, "f", &ar);
L0126 if (lua_isnil(L, -1))
L0127 luaL_error(L, "no function environment for tail call at level %d",
L0128 level);
L0129 }
L0130 }
L0131
L0132
L0133 static int luaB_getfenv (lua_State *L) {
L0134 getfunc(L, 1);
L0135 if (lua_iscfunction(L, -1))
L0136 lua_pushvalue(L, LUA_GLOBALSINDEX);
L0137 else
L0138 lua_getfenv(L, -1);
L0139 return 1;
L0140 }
L0141
L0142
L0143 static int luaB_setfenv (lua_State *L) {
L0144 luaL_checktype(L, 2, LUA_TTABLE);
L0145 getfunc(L, 0);
L0146 lua_pushvalue(L, 2);
L0147 if (lua_isnumber(L, 1) && lua_tonumber(L, 1) == 0) {
L0148
L0149 lua_pushthread(L);
L0150 lua_insert(L, -2);
L0151 lua_setfenv(L, -2);
L0152 return 0;
L0153 }
L0154 else if (lua_iscfunction(L, -2) || lua_setfenv(L, -2) == 0)
L0155 luaL_error(L,
L0156 LUA_QL("setfenv") " cannot change environment of given object");
L0157 return 1;
L0158 }
L0159
L0160
L0161 static int luaB_rawequal (lua_State *L) {
L0162 luaL_checkany(L, 1);
L0163 luaL_checkany(L, 2);
L0164 lua_pushboolean(L, lua_rawequal(L, 1, 2));
L0165 return 1;
L0166 }
L0167
L0168
L0169 static int luaB_rawget (lua_State *L) {
L0170 luaL_checktype(L, 1, LUA_TTABLE);
L0171 luaL_checkany(L, 2);
L0172 lua_settop(L, 2);
L0173 lua_rawget(L, 1);
L0174 return 1;
L0175 }
L0176
L0177 static int luaB_rawset (lua_State *L) {
L0178 luaL_checktype(L, 1, LUA_TTABLE);
L0179 luaL_checkany(L, 2);
L0180 luaL_checkany(L, 3);
L0181 lua_settop(L, 3);
L0182 lua_rawset(L, 1);
L0183 return 1;
L0184 }
L0185
L0186
L0187 static int luaB_gcinfo (lua_State *L) {
L0188 lua_pushinteger(L, lua_getgccount(L));
L0189 return 1;
L0190 }
L0191
L0192
L0193 static int luaB_collectgarbage (lua_State *L) {
L0194 static const char *const opts[] = {"stop", "restart", "collect",
L0195 "count", "step", "setpause", "setstepmul", NULL};
L0196 static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT,
L0197 LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL};
L0198 int o = luaL_checkoption(L, 1, "collect", opts);
L0199 int ex = luaL_optint(L, 2, 0);
L0200 int res = lua_gc(L, optsnum[o], ex);
L0201 switch (optsnum[o]) {
L0202 case LUA_GCCOUNT: {
L0203 int b = lua_gc(L, LUA_GCCOUNTB, 0);
L0204 lua_pushnumber(L, res + ((lua_Number)b/1024));
L0205 return 1;
L0206 }
L0207 case LUA_GCSTEP: {
L0208 lua_pushboolean(L, res);
L0209 return 1;
L0210 }
L0211 default: {
L0212 lua_pushnumber(L, res);
L0213 return 1;
L0214 }
L0215 }
L0216 }
L0217
L0218
L0219 static int luaB_type (lua_State *L) {
L0220 luaL_checkany(L, 1);
L0221 lua_pushstring(L, luaL_typename(L, 1));
L0222 return 1;
L0223 }
L0224
L0225
L0226 static int luaB_next (lua_State *L) {
L0227 luaL_checktype(L, 1, LUA_TTABLE);
L0228 lua_settop(L, 2);
L0229 if (lua_next(L, 1))
L0230 return 2;
L0231 else {
L0232 lua_pushnil(L);
L0233 return 1;
L0234 }
L0235 }
L0236
L0237
L0238 static int luaB_pairs (lua_State *L) {
L0239 luaL_checktype(L, 1, LUA_TTABLE);
L0240 lua_pushvalue(L, lua_upvalueindex(1));
L0241 lua_pushvalue(L, 1);
L0242 lua_pushnil(L);
L0243 return 3;
L0244 }
L0245
L0246
L0247 static int ipairsaux (lua_State *L) {
L0248 int i = luaL_checkint(L, 2);
L0249 luaL_checktype(L, 1, LUA_TTABLE);
L0250 i++;
L0251 lua_pushinteger(L, i);
L0252 lua_rawgeti(L, 1, i);
L0253 return (lua_isnil(L, -1)) ? 0 : 2;
L0254 }
L0255
L0256
L0257 static int luaB_ipairs (lua_State *L) {
L0258 luaL_checktype(L, 1, LUA_TTABLE);
L0259 lua_pushvalue(L, lua_upvalueindex(1));
L0260 lua_pushvalue(L, 1);
L0261 lua_pushinteger(L, 0);
L0262 return 3;
L0263 }
L0264
L0265
L0266 static int load_aux (lua_State *L, int status) {
L0267 if (status == 0)
L0268 return 1;
L0269 else {
L0270 lua_pushnil(L);
L0271 lua_insert(L, -2);
L0272 return 2;
L0273 }
L0274 }
L0275
L0276
L0277 static int luaB_loadstring (lua_State *L) {
L0278 size_t l;
L0279 const char *s = luaL_checklstring(L, 1, &l);
L0280 const char *chunkname = luaL_optstring(L, 2, s);
L0281 return load_aux(L, luaL_loadbuffer(L, s, l, chunkname));
L0282 }
L0283
L0284
L0285 static int luaB_loadfile (lua_State *L) {
L0286 const char *fname = luaL_optstring(L, 1, NULL);
L0287 return load_aux(L, luaL_loadfile(L, fname));
L0288 }
L0289
L0290
L0291
L0297 static const char *generic_reader (lua_State *L, void *ud, size_t *size) {
L0298 (void)ud;
L0299 luaL_checkstack(L, 2, "too many nested functions");
L0300 lua_pushvalue(L, 1);
L0301 lua_call(L, 0, 1);
L0302 if (lua_isnil(L, -1)) {
L0303 *size = 0;
L0304 return NULL;
L0305 }
L0306 else if (lua_isstring(L, -1)) {
L0307 lua_replace(L, 3);
L0308 return lua_tolstring(L, 3, size);
L0309 }
L0310 else luaL_error(L, "reader function must return a string");
L0311 return NULL;
L0312 }
L0313
L0314
L0315 static int luaB_load (lua_State *L) {
L0316 int status;
L0317 const char *cname = luaL_optstring(L, 2, "=(load)");
L0318 luaL_checktype(L, 1, LUA_TFUNCTION);
L0319 lua_settop(L, 3);
L0320 status = lua_load(L, generic_reader, NULL, cname);
L0321 return load_aux(L, status);
L0322 }
L0323
L0324
L0325 static int luaB_dofile (lua_State *L) {
L0326 const char *fname = luaL_optstring(L, 1, NULL);
L0327 int n = lua_gettop(L);
L0328 if (luaL_loadfile(L, fname) != 0) lua_error(L);
L0329 lua_call(L, 0, LUA_MULTRET);
L0330 return lua_gettop(L) - n;
L0331 }
L0332
L0333
L0334 static int luaB_assert (lua_State *L) {
L0335 luaL_checkany(L, 1);
L0336 if (!lua_toboolean(L, 1))
L0337 return luaL_error(L, "%s", luaL_optstring(L, 2, "assertion failed!"));
L0338 return lua_gettop(L);
L0339 }
L0340
L0341
L0342 static int luaB_unpack (lua_State *L) {
L0343 int i, e, n;
L0344 luaL_checktype(L, 1, LUA_TTABLE);
L0345 i = luaL_optint(L, 2, 1);
L0346 e = luaL_opt(L, luaL_checkint, 3, luaL_getn(L, 1));
L0347 if (i > e) return 0;
L0348 n = e - i + 1;
L0349 if (n <= 0 || !lua_checkstack(L, n))
L0350 return luaL_error(L, "too many results to unpack");
L0351 lua_rawgeti(L, 1, i);
L0352 while (i++ < e)
L0353 lua_rawgeti(L, 1, i);
L0354 return n;
L0355 }
L0356
L0357
L0358 static int luaB_select (lua_State *L) {
L0359 int n = lua_gettop(L);
L0360 if (lua_type(L, 1) == LUA_TSTRING && *lua_tostring(L, 1) == '#') {
L0361 lua_pushinteger(L, n-1);
L0362 return 1;
L0363 }
L0364 else {
L0365 int i = luaL_checkint(L, 1);
L0366 if (i < 0) i = n + i;
L0367 else if (i > n) i = n;
L0368 luaL_argcheck(L, 1 <= i, 1, "index out of range");
L0369 return n - i;
L0370 }
L0371 }
L0372
L0373
L0374 static int luaB_pcall (lua_State *L) {
L0375 int status;
L0376 luaL_checkany(L, 1);
L0377 status = lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0);
L0378 lua_pushboolean(L, (status == 0));
L0379 lua_insert(L, 1);
L0380 return lua_gettop(L);
L0381 }
L0382
L0383
L0384 static int luaB_xpcall (lua_State *L) {
L0385 int status;
L0386 luaL_checkany(L, 2);
L0387 lua_settop(L, 2);
L0388 lua_insert(L, 1);
L0389 status = lua_pcall(L, 0, LUA_MULTRET, 1);
L0390 lua_pushboolean(L, (status == 0));
L0391 lua_replace(L, 1);
L0392 return lua_gettop(L);
L0393 }
L0394
L0395
L0396 static int luaB_tostring (lua_State *L) {
L0397 luaL_checkany(L, 1);
L0398 if (luaL_callmeta(L, 1, "__tostring"))
L0399 return 1;
L0400 switch (lua_type(L, 1)) {
L0401 case LUA_TNUMBER:
L0402 lua_pushstring(L, lua_tostring(L, 1));
L0403 break;
L0404 case LUA_TSTRING:
L0405 lua_pushvalue(L, 1);
L0406 break;
L0407 case LUA_TBOOLEAN:
L0408 lua_pushstring(L, (lua_toboolean(L, 1) ? "true" : "false"));
L0409 break;
L0410 case LUA_TNIL:
L0411 lua_pushliteral(L, "nil");
L0412 break;
L0413 default:
L0414 lua_pushfstring(L, "%s: %p", luaL_typename(L, 1), lua_topointer(L, 1));
L0415 break;
L0416 }
L0417 return 1;
L0418 }
L0419
L0420
L0421 static int luaB_newproxy (lua_State *L) {
L0422 lua_settop(L, 1);
L0423 lua_newuserdata(L, 0);
L0424 if (lua_toboolean(L, 1) == 0)
L0425 return 1;
L0426 else if (lua_isboolean(L, 1)) {
L0427 lua_newtable(L);
L0428 lua_pushvalue(L, -1);
L0429 lua_pushboolean(L, 1);
L0430 lua_rawset(L, lua_upvalueindex(1));
L0431 }
L0432 else {
L0433 int validproxy = 0;
L0434 if (lua_getmetatable(L, 1)) {
L0435 lua_rawget(L, lua_upvalueindex(1));
L0436 validproxy = lua_toboolean(L, -1);
L0437 lua_pop(L, 1);
L0438 }
L0439 luaL_argcheck(L, validproxy, 1, "boolean or proxy expected");
L0440 lua_getmetatable(L, 1);
L0441 }
L0442 lua_setmetatable(L, 2);
L0443 return 1;
L0444 }
L0445
L0446
L0447 static const luaL_Reg base_funcs[] = {
L0448 {"assert", luaB_assert},
L0449 {"collectgarbage", luaB_collectgarbage},
L0450 {"dofile", luaB_dofile},
L0451 {"error", luaB_error},
L0452 {"gcinfo", luaB_gcinfo},
L0453 {"getfenv", luaB_getfenv},
L0454 {"getmetatable", luaB_getmetatable},
L0455 {"loadfile", luaB_loadfile},
L0456 {"load", luaB_load},
L0457 {"loadstring", luaB_loadstring},
L0458 {"next", luaB_next},
L0459 {"pcall", luaB_pcall},
L0460 {"print", luaB_print},
L0461 {"rawequal", luaB_rawequal},
L0462 {"rawget", luaB_rawget},
L0463 {"rawset", luaB_rawset},
L0464 {"select", luaB_select},
L0465 {"setfenv", luaB_setfenv},
L0466 {"setmetatable", luaB_setmetatable},
L0467 {"tonumber", luaB_tonumber},
L0468 {"tostring", luaB_tostring},
L0469 {"type", luaB_type},
L0470 {"unpack", luaB_unpack},
L0471 {"xpcall", luaB_xpcall},
L0472 {NULL, NULL}
L0473 };
L0474
L0475
L0476
L0481
L0482 #define CO_RUN 0 /* running */
L0483 #define CO_SUS 1 /* suspended */
L0484 #define CO_NOR 2 /* 'normal' (it resumed another coroutine) */
L0485 #define CO_DEAD 3
L0486
L0487 static const char *const statnames[] =
L0488 {"running", "suspended", "normal", "dead"};
L0489
L0490 static int costatus (lua_State *L, lua_State *co) {
L0491 if (L == co) return CO_RUN;
L0492 switch (lua_status(co)) {
L0493 case LUA_YIELD:
L0494 return CO_SUS;
L0495 case 0: {
L0496 lua_Debug ar;
L0497 if (lua_getstack(co, 0, &ar) > 0)
L0498 return CO_NOR;
L0499 else if (lua_gettop(co) == 0)
L0500 return CO_DEAD;
L0501 else
L0502 return CO_SUS;
L0503 }
L0504 default:
L0505 return CO_DEAD;
L0506 }
L0507 }
L0508
L0509
L0510 static int luaB_costatus (lua_State *L) {
L0511 lua_State *co = lua_tothread(L, 1);
L0512 luaL_argcheck(L, co, 1, "coroutine expected");
L0513 lua_pushstring(L, statnames[costatus(L, co)]);
L0514 return 1;
L0515 }
L0516
L0517
L0518 static int auxresume (lua_State *L, lua_State *co, int narg) {
L0519 int status = costatus(L, co);
L0520 if (!lua_checkstack(co, narg))
L0521 luaL_error(L, "too many arguments to resume");
L0522 if (status != CO_SUS) {
L0523 lua_pushfstring(L, "cannot resume %s coroutine", statnames[status]);
L0524 return -1;
L0525 }
L0526 lua_xmove(L, co, narg);
L0527 lua_setlevel(L, co);
L0528 status = lua_resume(co, narg);
L0529 if (status == 0 || status == LUA_YIELD) {
L0530 int nres = lua_gettop(co);
L0531 if (!lua_checkstack(L, nres + 1))
L0532 luaL_error(L, "too many results to resume");
L0533 lua_xmove(co, L, nres);
L0534 return nres;
L0535 }
L0536 else {
L0537 lua_xmove(co, L, 1);
L0538 return -1;
L0539 }
L0540 }
L0541
L0542
L0543 static int luaB_coresume (lua_State *L) {
L0544 lua_State *co = lua_tothread(L, 1);
L0545 int r;
L0546 luaL_argcheck(L, co, 1, "coroutine expected");
L0547 r = auxresume(L, co, lua_gettop(L) - 1);
L0548 if (r < 0) {
L0549 lua_pushboolean(L, 0);
L0550 lua_insert(L, -2);
L0551 return 2;
L0552 }
L0553 else {
L0554 lua_pushboolean(L, 1);
L0555 lua_insert(L, -(r + 1));
L0556 return r + 1;
L0557 }
L0558 }
L0559
L0560
L0561 static int luaB_auxwrap (lua_State *L) {
L0562 lua_State *co = lua_tothread(L, lua_upvalueindex(1));
L0563 int r = auxresume(L, co, lua_gettop(L));
L0564 if (r < 0) {
L0565 if (lua_isstring(L, -1)) {
L0566 luaL_where(L, 1);
L0567 lua_insert(L, -2);
L0568 lua_concat(L, 2);
L0569 }
L0570 lua_error(L);
L0571 }
L0572 return r;
L0573 }
L0574
L0575
L0576 static int luaB_cocreate (lua_State *L) {
L0577 lua_State *NL = lua_newthread(L);
L0578 luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1,
L0579 "Lua function expected");
L0580 lua_pushvalue(L, 1);
L0581 lua_xmove(L, NL, 1);
L0582 return 1;
L0583 }
L0584
L0585
L0586 static int luaB_cowrap (lua_State *L) {
L0587 luaB_cocreate(L);
L0588 lua_pushcclosure(L, luaB_auxwrap, 1);
L0589 return 1;
L0590 }
L0591
L0592
L0593 static int luaB_yield (lua_State *L) {
L0594 return lua_yield(L, lua_gettop(L));
L0595 }
L0596
L0597
L0598 static int luaB_corunning (lua_State *L) {
L0599 if (lua_pushthread(L))
L0600 lua_pushnil(L);
L0601 return 1;
L0602 }
L0603
L0604
L0605 static const luaL_Reg co_funcs[] = {
L0606 {"create", luaB_cocreate},
L0607 {"resume", luaB_coresume},
L0608 {"running", luaB_corunning},
L0609 {"status", luaB_costatus},
L0610 {"wrap", luaB_cowrap},
L0611 {"yield", luaB_yield},
L0612 {NULL, NULL}
L0613 };
L0614
L0615
L0616
L0617
L0618 static void auxopen (lua_State *L, const char *name,
L0619 lua_CFunction f, lua_CFunction u) {
L0620 lua_pushcfunction(L, u);
L0621 lua_pushcclosure(L, f, 1);
L0622 lua_setfield(L, -2, name);
L0623 }
L0624
L0625
L0626 static void base_open (lua_State *L) {
L0627
L0628 lua_pushvalue(L, LUA_GLOBALSINDEX);
L0629 lua_setglobal(L, "_G");
L0630
L0631 luaL_register(L, "_G", base_funcs);
L0632 lua_pushliteral(L, LUA_VERSION);
L0633 lua_setglobal(L, "_VERSION");
L0634
L0635 auxopen(L, "ipairs", luaB_ipairs, ipairsaux);
L0636 auxopen(L, "pairs", luaB_pairs, luaB_next);
L0637
L0638 lua_createtable(L, 0, 1);
L0639 lua_pushvalue(L, -1);
L0640 lua_setmetatable(L, -2);
L0641 lua_pushliteral(L, "kv");
L0642 lua_setfield(L, -2, "__mode");
L0643 lua_pushcclosure(L, luaB_newproxy, 1);
L0644 lua_setglobal(L, "newproxy");
L0645 }
L0646
L0647
L0648 LUALIB_API int luaopen_base (lua_State *L) {
L0649 base_open(L);
L0650 luaL_register(L, LUA_COLIBNAME, co_funcs);
L0651 return 2;
L0652 }
L0653
Generated by pretty.lua