116a5fed65808adf648004b34f98718301d718fa2darylm/* 216a5fed65808adf648004b34f98718301d718fa2darylm** $Id: lbaselib.c,v 1.276.1.1 2013/04/12 18:48:47 roberto Exp $ 316a5fed65808adf648004b34f98718301d718fa2darylm** Basic library 416a5fed65808adf648004b34f98718301d718fa2darylm** See Copyright Notice in lua.h 516a5fed65808adf648004b34f98718301d718fa2darylm*/ 616a5fed65808adf648004b34f98718301d718fa2darylm 716a5fed65808adf648004b34f98718301d718fa2darylm 816a5fed65808adf648004b34f98718301d718fa2darylm 916a5fed65808adf648004b34f98718301d718fa2darylm#include <ctype.h> 1016a5fed65808adf648004b34f98718301d718fa2darylm#include <stdio.h> 1116a5fed65808adf648004b34f98718301d718fa2darylm#include <stdlib.h> 1216a5fed65808adf648004b34f98718301d718fa2darylm#include <string.h> 1316a5fed65808adf648004b34f98718301d718fa2darylm 1416a5fed65808adf648004b34f98718301d718fa2darylm#define lbaselib_c 1516a5fed65808adf648004b34f98718301d718fa2darylm#define LUA_LIB 1616a5fed65808adf648004b34f98718301d718fa2darylm 1716a5fed65808adf648004b34f98718301d718fa2darylm#include "lua.h" 1816a5fed65808adf648004b34f98718301d718fa2darylm 1916a5fed65808adf648004b34f98718301d718fa2darylm#include "lauxlib.h" 2016a5fed65808adf648004b34f98718301d718fa2darylm#include "lualib.h" 2116a5fed65808adf648004b34f98718301d718fa2darylm 2216a5fed65808adf648004b34f98718301d718fa2darylm 2316a5fed65808adf648004b34f98718301d718fa2darylmstatic int luaB_print (lua_State *L) { 2416a5fed65808adf648004b34f98718301d718fa2darylm int n = lua_gettop(L); /* number of arguments */ 2516a5fed65808adf648004b34f98718301d718fa2darylm int i; 2616a5fed65808adf648004b34f98718301d718fa2darylm lua_getglobal(L, "tostring"); 2716a5fed65808adf648004b34f98718301d718fa2darylm for (i=1; i<=n; i++) { 2816a5fed65808adf648004b34f98718301d718fa2darylm const char *s; 2916a5fed65808adf648004b34f98718301d718fa2darylm size_t l; 3016a5fed65808adf648004b34f98718301d718fa2darylm lua_pushvalue(L, -1); /* function to be called */ 3116a5fed65808adf648004b34f98718301d718fa2darylm lua_pushvalue(L, i); /* value to print */ 3216a5fed65808adf648004b34f98718301d718fa2darylm lua_call(L, 1, 1); 3316a5fed65808adf648004b34f98718301d718fa2darylm s = lua_tolstring(L, -1, &l); /* get result */ 3416a5fed65808adf648004b34f98718301d718fa2darylm if (s == NULL) 3516a5fed65808adf648004b34f98718301d718fa2darylm return luaL_error(L, 3616a5fed65808adf648004b34f98718301d718fa2darylm LUA_QL("tostring") " must return a string to " LUA_QL("print")); 3716a5fed65808adf648004b34f98718301d718fa2darylm if (i>1) luai_writestring("\t", 1); 3816a5fed65808adf648004b34f98718301d718fa2darylm luai_writestring(s, l); 3916a5fed65808adf648004b34f98718301d718fa2darylm lua_pop(L, 1); /* pop result */ 4016a5fed65808adf648004b34f98718301d718fa2darylm } 4116a5fed65808adf648004b34f98718301d718fa2darylm luai_writeline(); 4216a5fed65808adf648004b34f98718301d718fa2darylm return 0; 4316a5fed65808adf648004b34f98718301d718fa2darylm} 4416a5fed65808adf648004b34f98718301d718fa2darylm 4516a5fed65808adf648004b34f98718301d718fa2darylm 4616a5fed65808adf648004b34f98718301d718fa2darylm#define SPACECHARS " \f\n\r\t\v" 4716a5fed65808adf648004b34f98718301d718fa2darylm 4816a5fed65808adf648004b34f98718301d718fa2darylmstatic int luaB_tonumber (lua_State *L) { 4916a5fed65808adf648004b34f98718301d718fa2darylm if (lua_isnoneornil(L, 2)) { /* standard conversion */ 5016a5fed65808adf648004b34f98718301d718fa2darylm int isnum; 5116a5fed65808adf648004b34f98718301d718fa2darylm lua_Number n = lua_tonumberx(L, 1, &isnum); 5216a5fed65808adf648004b34f98718301d718fa2darylm if (isnum) { 5316a5fed65808adf648004b34f98718301d718fa2darylm lua_pushnumber(L, n); 5416a5fed65808adf648004b34f98718301d718fa2darylm return 1; 5516a5fed65808adf648004b34f98718301d718fa2darylm } /* else not a number; must be something */ 5616a5fed65808adf648004b34f98718301d718fa2darylm luaL_checkany(L, 1); 5716a5fed65808adf648004b34f98718301d718fa2darylm } 5816a5fed65808adf648004b34f98718301d718fa2darylm else { 5916a5fed65808adf648004b34f98718301d718fa2darylm size_t l; 6016a5fed65808adf648004b34f98718301d718fa2darylm const char *s = luaL_checklstring(L, 1, &l); 6116a5fed65808adf648004b34f98718301d718fa2darylm const char *e = s + l; /* end point for 's' */ 6216a5fed65808adf648004b34f98718301d718fa2darylm int base = luaL_checkint(L, 2); 6316a5fed65808adf648004b34f98718301d718fa2darylm int neg = 0; 6416a5fed65808adf648004b34f98718301d718fa2darylm luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range"); 6516a5fed65808adf648004b34f98718301d718fa2darylm s += strspn(s, SPACECHARS); /* skip initial spaces */ 6616a5fed65808adf648004b34f98718301d718fa2darylm if (*s == '-') { s++; neg = 1; } /* handle signal */ 6716a5fed65808adf648004b34f98718301d718fa2darylm else if (*s == '+') s++; 6816a5fed65808adf648004b34f98718301d718fa2darylm if (isalnum((unsigned char)*s)) { 6916a5fed65808adf648004b34f98718301d718fa2darylm lua_Number n = 0; 7016a5fed65808adf648004b34f98718301d718fa2darylm do { 7116a5fed65808adf648004b34f98718301d718fa2darylm int digit = (isdigit((unsigned char)*s)) ? *s - '0' 7216a5fed65808adf648004b34f98718301d718fa2darylm : toupper((unsigned char)*s) - 'A' + 10; 7316a5fed65808adf648004b34f98718301d718fa2darylm if (digit >= base) break; /* invalid numeral; force a fail */ 7416a5fed65808adf648004b34f98718301d718fa2darylm n = n * (lua_Number)base + (lua_Number)digit; 7516a5fed65808adf648004b34f98718301d718fa2darylm s++; 7616a5fed65808adf648004b34f98718301d718fa2darylm } while (isalnum((unsigned char)*s)); 7716a5fed65808adf648004b34f98718301d718fa2darylm s += strspn(s, SPACECHARS); /* skip trailing spaces */ 7816a5fed65808adf648004b34f98718301d718fa2darylm if (s == e) { /* no invalid trailing characters? */ 7916a5fed65808adf648004b34f98718301d718fa2darylm lua_pushnumber(L, (neg) ? -n : n); 8016a5fed65808adf648004b34f98718301d718fa2darylm return 1; 8116a5fed65808adf648004b34f98718301d718fa2darylm } /* else not a number */ 8216a5fed65808adf648004b34f98718301d718fa2darylm } /* else not a number */ 8316a5fed65808adf648004b34f98718301d718fa2darylm } 8416a5fed65808adf648004b34f98718301d718fa2darylm lua_pushnil(L); /* not a number */ 8516a5fed65808adf648004b34f98718301d718fa2darylm return 1; 8616a5fed65808adf648004b34f98718301d718fa2darylm} 8716a5fed65808adf648004b34f98718301d718fa2darylm 8816a5fed65808adf648004b34f98718301d718fa2darylm 8916a5fed65808adf648004b34f98718301d718fa2darylmstatic int luaB_error (lua_State *L) { 9016a5fed65808adf648004b34f98718301d718fa2darylm int level = luaL_optint(L, 2, 1); 9116a5fed65808adf648004b34f98718301d718fa2darylm lua_settop(L, 1); 9216a5fed65808adf648004b34f98718301d718fa2darylm if (lua_isstring(L, 1) && level > 0) { /* add extra information? */ 9316a5fed65808adf648004b34f98718301d718fa2darylm luaL_where(L, level); 9416a5fed65808adf648004b34f98718301d718fa2darylm lua_pushvalue(L, 1); 9516a5fed65808adf648004b34f98718301d718fa2darylm lua_concat(L, 2); 9616a5fed65808adf648004b34f98718301d718fa2darylm } 9716a5fed65808adf648004b34f98718301d718fa2darylm return lua_error(L); 9816a5fed65808adf648004b34f98718301d718fa2darylm} 9916a5fed65808adf648004b34f98718301d718fa2darylm 10016a5fed65808adf648004b34f98718301d718fa2darylm 10116a5fed65808adf648004b34f98718301d718fa2darylmstatic int luaB_getmetatable (lua_State *L) { 10216a5fed65808adf648004b34f98718301d718fa2darylm luaL_checkany(L, 1); 10316a5fed65808adf648004b34f98718301d718fa2darylm if (!lua_getmetatable(L, 1)) { 10416a5fed65808adf648004b34f98718301d718fa2darylm lua_pushnil(L); 10516a5fed65808adf648004b34f98718301d718fa2darylm return 1; /* no metatable */ 10616a5fed65808adf648004b34f98718301d718fa2darylm } 10716a5fed65808adf648004b34f98718301d718fa2darylm luaL_getmetafield(L, 1, "__metatable"); 10816a5fed65808adf648004b34f98718301d718fa2darylm return 1; /* returns either __metatable field (if present) or metatable */ 10916a5fed65808adf648004b34f98718301d718fa2darylm} 11016a5fed65808adf648004b34f98718301d718fa2darylm 11116a5fed65808adf648004b34f98718301d718fa2darylm 11216a5fed65808adf648004b34f98718301d718fa2darylmstatic int luaB_setmetatable (lua_State *L) { 11316a5fed65808adf648004b34f98718301d718fa2darylm int t = lua_type(L, 2); 11416a5fed65808adf648004b34f98718301d718fa2darylm luaL_checktype(L, 1, LUA_TTABLE); 11516a5fed65808adf648004b34f98718301d718fa2darylm luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2, 11616a5fed65808adf648004b34f98718301d718fa2darylm "nil or table expected"); 11716a5fed65808adf648004b34f98718301d718fa2darylm if (luaL_getmetafield(L, 1, "__metatable")) 11816a5fed65808adf648004b34f98718301d718fa2darylm return luaL_error(L, "cannot change a protected metatable"); 11916a5fed65808adf648004b34f98718301d718fa2darylm lua_settop(L, 2); 12016a5fed65808adf648004b34f98718301d718fa2darylm lua_setmetatable(L, 1); 12116a5fed65808adf648004b34f98718301d718fa2darylm return 1; 12216a5fed65808adf648004b34f98718301d718fa2darylm} 12316a5fed65808adf648004b34f98718301d718fa2darylm 12416a5fed65808adf648004b34f98718301d718fa2darylm 12516a5fed65808adf648004b34f98718301d718fa2darylmstatic int luaB_rawequal (lua_State *L) { 12616a5fed65808adf648004b34f98718301d718fa2darylm luaL_checkany(L, 1); 12716a5fed65808adf648004b34f98718301d718fa2darylm luaL_checkany(L, 2); 12816a5fed65808adf648004b34f98718301d718fa2darylm lua_pushboolean(L, lua_rawequal(L, 1, 2)); 12916a5fed65808adf648004b34f98718301d718fa2darylm return 1; 13016a5fed65808adf648004b34f98718301d718fa2darylm} 13116a5fed65808adf648004b34f98718301d718fa2darylm 13216a5fed65808adf648004b34f98718301d718fa2darylm 13316a5fed65808adf648004b34f98718301d718fa2darylmstatic int luaB_rawlen (lua_State *L) { 13416a5fed65808adf648004b34f98718301d718fa2darylm int t = lua_type(L, 1); 13516a5fed65808adf648004b34f98718301d718fa2darylm luaL_argcheck(L, t == LUA_TTABLE || t == LUA_TSTRING, 1, 13616a5fed65808adf648004b34f98718301d718fa2darylm "table or string expected"); 13716a5fed65808adf648004b34f98718301d718fa2darylm lua_pushinteger(L, lua_rawlen(L, 1)); 13816a5fed65808adf648004b34f98718301d718fa2darylm return 1; 13916a5fed65808adf648004b34f98718301d718fa2darylm} 14016a5fed65808adf648004b34f98718301d718fa2darylm 14116a5fed65808adf648004b34f98718301d718fa2darylm 14216a5fed65808adf648004b34f98718301d718fa2darylmstatic int luaB_rawget (lua_State *L) { 14316a5fed65808adf648004b34f98718301d718fa2darylm luaL_checktype(L, 1, LUA_TTABLE); 14416a5fed65808adf648004b34f98718301d718fa2darylm luaL_checkany(L, 2); 14516a5fed65808adf648004b34f98718301d718fa2darylm lua_settop(L, 2); 14616a5fed65808adf648004b34f98718301d718fa2darylm lua_rawget(L, 1); 14716a5fed65808adf648004b34f98718301d718fa2darylm return 1; 14816a5fed65808adf648004b34f98718301d718fa2darylm} 14916a5fed65808adf648004b34f98718301d718fa2darylm 15016a5fed65808adf648004b34f98718301d718fa2darylmstatic int luaB_rawset (lua_State *L) { 15116a5fed65808adf648004b34f98718301d718fa2darylm luaL_checktype(L, 1, LUA_TTABLE); 15216a5fed65808adf648004b34f98718301d718fa2darylm luaL_checkany(L, 2); 15316a5fed65808adf648004b34f98718301d718fa2darylm luaL_checkany(L, 3); 15416a5fed65808adf648004b34f98718301d718fa2darylm lua_settop(L, 3); 15516a5fed65808adf648004b34f98718301d718fa2darylm lua_rawset(L, 1); 15616a5fed65808adf648004b34f98718301d718fa2darylm return 1; 15716a5fed65808adf648004b34f98718301d718fa2darylm} 15816a5fed65808adf648004b34f98718301d718fa2darylm 15916a5fed65808adf648004b34f98718301d718fa2darylm 16016a5fed65808adf648004b34f98718301d718fa2darylmstatic int luaB_collectgarbage (lua_State *L) { 16116a5fed65808adf648004b34f98718301d718fa2darylm static const char *const opts[] = {"stop", "restart", "collect", 16216a5fed65808adf648004b34f98718301d718fa2darylm "count", "step", "setpause", "setstepmul", 16316a5fed65808adf648004b34f98718301d718fa2darylm "setmajorinc", "isrunning", "generational", "incremental", NULL}; 16416a5fed65808adf648004b34f98718301d718fa2darylm static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT, 16516a5fed65808adf648004b34f98718301d718fa2darylm LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL, 16616a5fed65808adf648004b34f98718301d718fa2darylm LUA_GCSETMAJORINC, LUA_GCISRUNNING, LUA_GCGEN, LUA_GCINC}; 16716a5fed65808adf648004b34f98718301d718fa2darylm int o = optsnum[luaL_checkoption(L, 1, "collect", opts)]; 16816a5fed65808adf648004b34f98718301d718fa2darylm int ex = luaL_optint(L, 2, 0); 16916a5fed65808adf648004b34f98718301d718fa2darylm int res = lua_gc(L, o, ex); 17016a5fed65808adf648004b34f98718301d718fa2darylm switch (o) { 17116a5fed65808adf648004b34f98718301d718fa2darylm case LUA_GCCOUNT: { 17216a5fed65808adf648004b34f98718301d718fa2darylm int b = lua_gc(L, LUA_GCCOUNTB, 0); 17316a5fed65808adf648004b34f98718301d718fa2darylm lua_pushnumber(L, res + ((lua_Number)b/1024)); 17416a5fed65808adf648004b34f98718301d718fa2darylm lua_pushinteger(L, b); 17516a5fed65808adf648004b34f98718301d718fa2darylm return 2; 17616a5fed65808adf648004b34f98718301d718fa2darylm } 17716a5fed65808adf648004b34f98718301d718fa2darylm case LUA_GCSTEP: case LUA_GCISRUNNING: { 17816a5fed65808adf648004b34f98718301d718fa2darylm lua_pushboolean(L, res); 17916a5fed65808adf648004b34f98718301d718fa2darylm return 1; 18016a5fed65808adf648004b34f98718301d718fa2darylm } 18116a5fed65808adf648004b34f98718301d718fa2darylm default: { 18216a5fed65808adf648004b34f98718301d718fa2darylm lua_pushinteger(L, res); 18316a5fed65808adf648004b34f98718301d718fa2darylm return 1; 18416a5fed65808adf648004b34f98718301d718fa2darylm } 18516a5fed65808adf648004b34f98718301d718fa2darylm } 18616a5fed65808adf648004b34f98718301d718fa2darylm} 18716a5fed65808adf648004b34f98718301d718fa2darylm 18816a5fed65808adf648004b34f98718301d718fa2darylm 18916a5fed65808adf648004b34f98718301d718fa2darylmstatic int luaB_type (lua_State *L) { 19016a5fed65808adf648004b34f98718301d718fa2darylm luaL_checkany(L, 1); 19116a5fed65808adf648004b34f98718301d718fa2darylm lua_pushstring(L, luaL_typename(L, 1)); 19216a5fed65808adf648004b34f98718301d718fa2darylm return 1; 19316a5fed65808adf648004b34f98718301d718fa2darylm} 19416a5fed65808adf648004b34f98718301d718fa2darylm 19516a5fed65808adf648004b34f98718301d718fa2darylm 19616a5fed65808adf648004b34f98718301d718fa2darylmstatic int pairsmeta (lua_State *L, const char *method, int iszero, 19716a5fed65808adf648004b34f98718301d718fa2darylm lua_CFunction iter) { 19816a5fed65808adf648004b34f98718301d718fa2darylm if (!luaL_getmetafield(L, 1, method)) { /* no metamethod? */ 19916a5fed65808adf648004b34f98718301d718fa2darylm luaL_checktype(L, 1, LUA_TTABLE); /* argument must be a table */ 20016a5fed65808adf648004b34f98718301d718fa2darylm lua_pushcfunction(L, iter); /* will return generator, */ 20116a5fed65808adf648004b34f98718301d718fa2darylm lua_pushvalue(L, 1); /* state, */ 20216a5fed65808adf648004b34f98718301d718fa2darylm if (iszero) lua_pushinteger(L, 0); /* and initial value */ 20316a5fed65808adf648004b34f98718301d718fa2darylm else lua_pushnil(L); 20416a5fed65808adf648004b34f98718301d718fa2darylm } 20516a5fed65808adf648004b34f98718301d718fa2darylm else { 20616a5fed65808adf648004b34f98718301d718fa2darylm lua_pushvalue(L, 1); /* argument 'self' to metamethod */ 20716a5fed65808adf648004b34f98718301d718fa2darylm lua_call(L, 1, 3); /* get 3 values from metamethod */ 20816a5fed65808adf648004b34f98718301d718fa2darylm } 20916a5fed65808adf648004b34f98718301d718fa2darylm return 3; 21016a5fed65808adf648004b34f98718301d718fa2darylm} 21116a5fed65808adf648004b34f98718301d718fa2darylm 21216a5fed65808adf648004b34f98718301d718fa2darylm 21316a5fed65808adf648004b34f98718301d718fa2darylmstatic int luaB_next (lua_State *L) { 21416a5fed65808adf648004b34f98718301d718fa2darylm luaL_checktype(L, 1, LUA_TTABLE); 21516a5fed65808adf648004b34f98718301d718fa2darylm lua_settop(L, 2); /* create a 2nd argument if there isn't one */ 21616a5fed65808adf648004b34f98718301d718fa2darylm if (lua_next(L, 1)) 21716a5fed65808adf648004b34f98718301d718fa2darylm return 2; 21816a5fed65808adf648004b34f98718301d718fa2darylm else { 21916a5fed65808adf648004b34f98718301d718fa2darylm lua_pushnil(L); 22016a5fed65808adf648004b34f98718301d718fa2darylm return 1; 22116a5fed65808adf648004b34f98718301d718fa2darylm } 22216a5fed65808adf648004b34f98718301d718fa2darylm} 22316a5fed65808adf648004b34f98718301d718fa2darylm 22416a5fed65808adf648004b34f98718301d718fa2darylm 22516a5fed65808adf648004b34f98718301d718fa2darylmstatic int luaB_pairs (lua_State *L) { 22616a5fed65808adf648004b34f98718301d718fa2darylm return pairsmeta(L, "__pairs", 0, luaB_next); 22716a5fed65808adf648004b34f98718301d718fa2darylm} 22816a5fed65808adf648004b34f98718301d718fa2darylm 22916a5fed65808adf648004b34f98718301d718fa2darylm 23016a5fed65808adf648004b34f98718301d718fa2darylmstatic int ipairsaux (lua_State *L) { 23116a5fed65808adf648004b34f98718301d718fa2darylm int i = luaL_checkint(L, 2); 23216a5fed65808adf648004b34f98718301d718fa2darylm luaL_checktype(L, 1, LUA_TTABLE); 23316a5fed65808adf648004b34f98718301d718fa2darylm i++; /* next value */ 23416a5fed65808adf648004b34f98718301d718fa2darylm lua_pushinteger(L, i); 23516a5fed65808adf648004b34f98718301d718fa2darylm lua_rawgeti(L, 1, i); 23616a5fed65808adf648004b34f98718301d718fa2darylm return (lua_isnil(L, -1)) ? 1 : 2; 23716a5fed65808adf648004b34f98718301d718fa2darylm} 23816a5fed65808adf648004b34f98718301d718fa2darylm 23916a5fed65808adf648004b34f98718301d718fa2darylm 24016a5fed65808adf648004b34f98718301d718fa2darylmstatic int luaB_ipairs (lua_State *L) { 24116a5fed65808adf648004b34f98718301d718fa2darylm return pairsmeta(L, "__ipairs", 1, ipairsaux); 24216a5fed65808adf648004b34f98718301d718fa2darylm} 24316a5fed65808adf648004b34f98718301d718fa2darylm 24416a5fed65808adf648004b34f98718301d718fa2darylm 24516a5fed65808adf648004b34f98718301d718fa2darylmstatic int load_aux (lua_State *L, int status, int envidx) { 24616a5fed65808adf648004b34f98718301d718fa2darylm if (status == LUA_OK) { 24716a5fed65808adf648004b34f98718301d718fa2darylm if (envidx != 0) { /* 'env' parameter? */ 24816a5fed65808adf648004b34f98718301d718fa2darylm lua_pushvalue(L, envidx); /* environment for loaded function */ 24916a5fed65808adf648004b34f98718301d718fa2darylm if (!lua_setupvalue(L, -2, 1)) /* set it as 1st upvalue */ 25016a5fed65808adf648004b34f98718301d718fa2darylm lua_pop(L, 1); /* remove 'env' if not used by previous call */ 25116a5fed65808adf648004b34f98718301d718fa2darylm } 25216a5fed65808adf648004b34f98718301d718fa2darylm return 1; 25316a5fed65808adf648004b34f98718301d718fa2darylm } 25416a5fed65808adf648004b34f98718301d718fa2darylm else { /* error (message is on top of the stack) */ 25516a5fed65808adf648004b34f98718301d718fa2darylm lua_pushnil(L); 25616a5fed65808adf648004b34f98718301d718fa2darylm lua_insert(L, -2); /* put before error message */ 25716a5fed65808adf648004b34f98718301d718fa2darylm return 2; /* return nil plus error message */ 25816a5fed65808adf648004b34f98718301d718fa2darylm } 25916a5fed65808adf648004b34f98718301d718fa2darylm} 26016a5fed65808adf648004b34f98718301d718fa2darylm 26116a5fed65808adf648004b34f98718301d718fa2darylm 26216a5fed65808adf648004b34f98718301d718fa2darylmstatic int luaB_loadfile (lua_State *L) { 26316a5fed65808adf648004b34f98718301d718fa2darylm const char *fname = luaL_optstring(L, 1, NULL); 26416a5fed65808adf648004b34f98718301d718fa2darylm const char *mode = luaL_optstring(L, 2, NULL); 26516a5fed65808adf648004b34f98718301d718fa2darylm int env = (!lua_isnone(L, 3) ? 3 : 0); /* 'env' index or 0 if no 'env' */ 26616a5fed65808adf648004b34f98718301d718fa2darylm int status = luaL_loadfilex(L, fname, mode); 26716a5fed65808adf648004b34f98718301d718fa2darylm return load_aux(L, status, env); 26816a5fed65808adf648004b34f98718301d718fa2darylm} 26916a5fed65808adf648004b34f98718301d718fa2darylm 27016a5fed65808adf648004b34f98718301d718fa2darylm 27116a5fed65808adf648004b34f98718301d718fa2darylm/* 27216a5fed65808adf648004b34f98718301d718fa2darylm** {====================================================== 27316a5fed65808adf648004b34f98718301d718fa2darylm** Generic Read function 27416a5fed65808adf648004b34f98718301d718fa2darylm** ======================================================= 27516a5fed65808adf648004b34f98718301d718fa2darylm*/ 27616a5fed65808adf648004b34f98718301d718fa2darylm 27716a5fed65808adf648004b34f98718301d718fa2darylm 27816a5fed65808adf648004b34f98718301d718fa2darylm/* 27916a5fed65808adf648004b34f98718301d718fa2darylm** reserved slot, above all arguments, to hold a copy of the returned 28016a5fed65808adf648004b34f98718301d718fa2darylm** string to avoid it being collected while parsed. 'load' has four 28116a5fed65808adf648004b34f98718301d718fa2darylm** optional arguments (chunk, source name, mode, and environment). 28216a5fed65808adf648004b34f98718301d718fa2darylm*/ 28316a5fed65808adf648004b34f98718301d718fa2darylm#define RESERVEDSLOT 5 28416a5fed65808adf648004b34f98718301d718fa2darylm 28516a5fed65808adf648004b34f98718301d718fa2darylm 28616a5fed65808adf648004b34f98718301d718fa2darylm/* 28716a5fed65808adf648004b34f98718301d718fa2darylm** Reader for generic `load' function: `lua_load' uses the 28816a5fed65808adf648004b34f98718301d718fa2darylm** stack for internal stuff, so the reader cannot change the 28916a5fed65808adf648004b34f98718301d718fa2darylm** stack top. Instead, it keeps its resulting string in a 29016a5fed65808adf648004b34f98718301d718fa2darylm** reserved slot inside the stack. 29116a5fed65808adf648004b34f98718301d718fa2darylm*/ 29216a5fed65808adf648004b34f98718301d718fa2darylmstatic const char *generic_reader (lua_State *L, void *ud, size_t *size) { 29316a5fed65808adf648004b34f98718301d718fa2darylm (void)(ud); /* not used */ 29416a5fed65808adf648004b34f98718301d718fa2darylm luaL_checkstack(L, 2, "too many nested functions"); 29516a5fed65808adf648004b34f98718301d718fa2darylm lua_pushvalue(L, 1); /* get function */ 29616a5fed65808adf648004b34f98718301d718fa2darylm lua_call(L, 0, 1); /* call it */ 29716a5fed65808adf648004b34f98718301d718fa2darylm if (lua_isnil(L, -1)) { 29816a5fed65808adf648004b34f98718301d718fa2darylm lua_pop(L, 1); /* pop result */ 29916a5fed65808adf648004b34f98718301d718fa2darylm *size = 0; 30016a5fed65808adf648004b34f98718301d718fa2darylm return NULL; 30116a5fed65808adf648004b34f98718301d718fa2darylm } 30216a5fed65808adf648004b34f98718301d718fa2darylm else if (!lua_isstring(L, -1)) 30316a5fed65808adf648004b34f98718301d718fa2darylm luaL_error(L, "reader function must return a string"); 30416a5fed65808adf648004b34f98718301d718fa2darylm lua_replace(L, RESERVEDSLOT); /* save string in reserved slot */ 30516a5fed65808adf648004b34f98718301d718fa2darylm return lua_tolstring(L, RESERVEDSLOT, size); 30616a5fed65808adf648004b34f98718301d718fa2darylm} 30716a5fed65808adf648004b34f98718301d718fa2darylm 30816a5fed65808adf648004b34f98718301d718fa2darylm 30916a5fed65808adf648004b34f98718301d718fa2darylmstatic int luaB_load (lua_State *L) { 31016a5fed65808adf648004b34f98718301d718fa2darylm int status; 31116a5fed65808adf648004b34f98718301d718fa2darylm size_t l; 31216a5fed65808adf648004b34f98718301d718fa2darylm const char *s = lua_tolstring(L, 1, &l); 31316a5fed65808adf648004b34f98718301d718fa2darylm const char *mode = luaL_optstring(L, 3, "bt"); 31416a5fed65808adf648004b34f98718301d718fa2darylm int env = (!lua_isnone(L, 4) ? 4 : 0); /* 'env' index or 0 if no 'env' */ 31516a5fed65808adf648004b34f98718301d718fa2darylm if (s != NULL) { /* loading a string? */ 31616a5fed65808adf648004b34f98718301d718fa2darylm const char *chunkname = luaL_optstring(L, 2, s); 31716a5fed65808adf648004b34f98718301d718fa2darylm status = luaL_loadbufferx(L, s, l, chunkname, mode); 31816a5fed65808adf648004b34f98718301d718fa2darylm } 31916a5fed65808adf648004b34f98718301d718fa2darylm else { /* loading from a reader function */ 32016a5fed65808adf648004b34f98718301d718fa2darylm const char *chunkname = luaL_optstring(L, 2, "=(load)"); 32116a5fed65808adf648004b34f98718301d718fa2darylm luaL_checktype(L, 1, LUA_TFUNCTION); 32216a5fed65808adf648004b34f98718301d718fa2darylm lua_settop(L, RESERVEDSLOT); /* create reserved slot */ 32316a5fed65808adf648004b34f98718301d718fa2darylm status = lua_load(L, generic_reader, NULL, chunkname, mode); 32416a5fed65808adf648004b34f98718301d718fa2darylm } 32516a5fed65808adf648004b34f98718301d718fa2darylm return load_aux(L, status, env); 32616a5fed65808adf648004b34f98718301d718fa2darylm} 32716a5fed65808adf648004b34f98718301d718fa2darylm 32816a5fed65808adf648004b34f98718301d718fa2darylm/* }====================================================== */ 32916a5fed65808adf648004b34f98718301d718fa2darylm 33016a5fed65808adf648004b34f98718301d718fa2darylm 33116a5fed65808adf648004b34f98718301d718fa2darylmstatic int dofilecont (lua_State *L) { 33216a5fed65808adf648004b34f98718301d718fa2darylm return lua_gettop(L) - 1; 33316a5fed65808adf648004b34f98718301d718fa2darylm} 33416a5fed65808adf648004b34f98718301d718fa2darylm 33516a5fed65808adf648004b34f98718301d718fa2darylm 33616a5fed65808adf648004b34f98718301d718fa2darylmstatic int luaB_dofile (lua_State *L) { 33716a5fed65808adf648004b34f98718301d718fa2darylm const char *fname = luaL_optstring(L, 1, NULL); 33816a5fed65808adf648004b34f98718301d718fa2darylm lua_settop(L, 1); 33916a5fed65808adf648004b34f98718301d718fa2darylm if (luaL_loadfile(L, fname) != LUA_OK) 34016a5fed65808adf648004b34f98718301d718fa2darylm return lua_error(L); 34116a5fed65808adf648004b34f98718301d718fa2darylm lua_callk(L, 0, LUA_MULTRET, 0, dofilecont); 34216a5fed65808adf648004b34f98718301d718fa2darylm return dofilecont(L); 34316a5fed65808adf648004b34f98718301d718fa2darylm} 34416a5fed65808adf648004b34f98718301d718fa2darylm 34516a5fed65808adf648004b34f98718301d718fa2darylm 34616a5fed65808adf648004b34f98718301d718fa2darylmstatic int luaB_assert (lua_State *L) { 34716a5fed65808adf648004b34f98718301d718fa2darylm if (!lua_toboolean(L, 1)) 34816a5fed65808adf648004b34f98718301d718fa2darylm return luaL_error(L, "%s", luaL_optstring(L, 2, "assertion failed!")); 34916a5fed65808adf648004b34f98718301d718fa2darylm return lua_gettop(L); 35016a5fed65808adf648004b34f98718301d718fa2darylm} 35116a5fed65808adf648004b34f98718301d718fa2darylm 35216a5fed65808adf648004b34f98718301d718fa2darylm 35316a5fed65808adf648004b34f98718301d718fa2darylmstatic int luaB_select (lua_State *L) { 35416a5fed65808adf648004b34f98718301d718fa2darylm int n = lua_gettop(L); 35516a5fed65808adf648004b34f98718301d718fa2darylm if (lua_type(L, 1) == LUA_TSTRING && *lua_tostring(L, 1) == '#') { 35616a5fed65808adf648004b34f98718301d718fa2darylm lua_pushinteger(L, n-1); 35716a5fed65808adf648004b34f98718301d718fa2darylm return 1; 35816a5fed65808adf648004b34f98718301d718fa2darylm } 35916a5fed65808adf648004b34f98718301d718fa2darylm else { 36016a5fed65808adf648004b34f98718301d718fa2darylm int i = luaL_checkint(L, 1); 36116a5fed65808adf648004b34f98718301d718fa2darylm if (i < 0) i = n + i; 36216a5fed65808adf648004b34f98718301d718fa2darylm else if (i > n) i = n; 36316a5fed65808adf648004b34f98718301d718fa2darylm luaL_argcheck(L, 1 <= i, 1, "index out of range"); 36416a5fed65808adf648004b34f98718301d718fa2darylm return n - i; 36516a5fed65808adf648004b34f98718301d718fa2darylm } 36616a5fed65808adf648004b34f98718301d718fa2darylm} 36716a5fed65808adf648004b34f98718301d718fa2darylm 36816a5fed65808adf648004b34f98718301d718fa2darylm 36916a5fed65808adf648004b34f98718301d718fa2darylmstatic int finishpcall (lua_State *L, int status) { 37016a5fed65808adf648004b34f98718301d718fa2darylm if (!lua_checkstack(L, 1)) { /* no space for extra boolean? */ 37116a5fed65808adf648004b34f98718301d718fa2darylm lua_settop(L, 0); /* create space for return values */ 37216a5fed65808adf648004b34f98718301d718fa2darylm lua_pushboolean(L, 0); 37316a5fed65808adf648004b34f98718301d718fa2darylm lua_pushstring(L, "stack overflow"); 37416a5fed65808adf648004b34f98718301d718fa2darylm return 2; /* return false, msg */ 37516a5fed65808adf648004b34f98718301d718fa2darylm } 37616a5fed65808adf648004b34f98718301d718fa2darylm lua_pushboolean(L, status); /* first result (status) */ 37716a5fed65808adf648004b34f98718301d718fa2darylm lua_replace(L, 1); /* put first result in first slot */ 37816a5fed65808adf648004b34f98718301d718fa2darylm return lua_gettop(L); 37916a5fed65808adf648004b34f98718301d718fa2darylm} 38016a5fed65808adf648004b34f98718301d718fa2darylm 38116a5fed65808adf648004b34f98718301d718fa2darylm 38216a5fed65808adf648004b34f98718301d718fa2darylmstatic int pcallcont (lua_State *L) { 38316a5fed65808adf648004b34f98718301d718fa2darylm int status = lua_getctx(L, NULL); 38416a5fed65808adf648004b34f98718301d718fa2darylm return finishpcall(L, (status == LUA_YIELD)); 38516a5fed65808adf648004b34f98718301d718fa2darylm} 38616a5fed65808adf648004b34f98718301d718fa2darylm 38716a5fed65808adf648004b34f98718301d718fa2darylm 38816a5fed65808adf648004b34f98718301d718fa2darylmstatic int luaB_pcall (lua_State *L) { 38916a5fed65808adf648004b34f98718301d718fa2darylm int status; 39016a5fed65808adf648004b34f98718301d718fa2darylm luaL_checkany(L, 1); 39116a5fed65808adf648004b34f98718301d718fa2darylm lua_pushnil(L); 39216a5fed65808adf648004b34f98718301d718fa2darylm lua_insert(L, 1); /* create space for status result */ 39316a5fed65808adf648004b34f98718301d718fa2darylm status = lua_pcallk(L, lua_gettop(L) - 2, LUA_MULTRET, 0, 0, pcallcont); 39416a5fed65808adf648004b34f98718301d718fa2darylm return finishpcall(L, (status == LUA_OK)); 39516a5fed65808adf648004b34f98718301d718fa2darylm} 39616a5fed65808adf648004b34f98718301d718fa2darylm 39716a5fed65808adf648004b34f98718301d718fa2darylm 39816a5fed65808adf648004b34f98718301d718fa2darylmstatic int luaB_xpcall (lua_State *L) { 39916a5fed65808adf648004b34f98718301d718fa2darylm int status; 40016a5fed65808adf648004b34f98718301d718fa2darylm int n = lua_gettop(L); 40116a5fed65808adf648004b34f98718301d718fa2darylm luaL_argcheck(L, n >= 2, 2, "value expected"); 40216a5fed65808adf648004b34f98718301d718fa2darylm lua_pushvalue(L, 1); /* exchange function... */ 40316a5fed65808adf648004b34f98718301d718fa2darylm lua_copy(L, 2, 1); /* ...and error handler */ 40416a5fed65808adf648004b34f98718301d718fa2darylm lua_replace(L, 2); 40516a5fed65808adf648004b34f98718301d718fa2darylm status = lua_pcallk(L, n - 2, LUA_MULTRET, 1, 0, pcallcont); 40616a5fed65808adf648004b34f98718301d718fa2darylm return finishpcall(L, (status == LUA_OK)); 40716a5fed65808adf648004b34f98718301d718fa2darylm} 40816a5fed65808adf648004b34f98718301d718fa2darylm 40916a5fed65808adf648004b34f98718301d718fa2darylm 41016a5fed65808adf648004b34f98718301d718fa2darylmstatic int luaB_tostring (lua_State *L) { 41116a5fed65808adf648004b34f98718301d718fa2darylm luaL_checkany(L, 1); 41216a5fed65808adf648004b34f98718301d718fa2darylm luaL_tolstring(L, 1, NULL); 41316a5fed65808adf648004b34f98718301d718fa2darylm return 1; 41416a5fed65808adf648004b34f98718301d718fa2darylm} 41516a5fed65808adf648004b34f98718301d718fa2darylm 41616a5fed65808adf648004b34f98718301d718fa2darylm 41716a5fed65808adf648004b34f98718301d718fa2darylmstatic const luaL_Reg base_funcs[] = { 41816a5fed65808adf648004b34f98718301d718fa2darylm {"assert", luaB_assert}, 41916a5fed65808adf648004b34f98718301d718fa2darylm {"collectgarbage", luaB_collectgarbage}, 42016a5fed65808adf648004b34f98718301d718fa2darylm {"dofile", luaB_dofile}, 42116a5fed65808adf648004b34f98718301d718fa2darylm {"error", luaB_error}, 42216a5fed65808adf648004b34f98718301d718fa2darylm {"getmetatable", luaB_getmetatable}, 42316a5fed65808adf648004b34f98718301d718fa2darylm {"ipairs", luaB_ipairs}, 42416a5fed65808adf648004b34f98718301d718fa2darylm {"loadfile", luaB_loadfile}, 42516a5fed65808adf648004b34f98718301d718fa2darylm {"load", luaB_load}, 42616a5fed65808adf648004b34f98718301d718fa2darylm#if defined(LUA_COMPAT_LOADSTRING) 42716a5fed65808adf648004b34f98718301d718fa2darylm {"loadstring", luaB_load}, 42816a5fed65808adf648004b34f98718301d718fa2darylm#endif 42916a5fed65808adf648004b34f98718301d718fa2darylm {"next", luaB_next}, 43016a5fed65808adf648004b34f98718301d718fa2darylm {"pairs", luaB_pairs}, 43116a5fed65808adf648004b34f98718301d718fa2darylm {"pcall", luaB_pcall}, 43216a5fed65808adf648004b34f98718301d718fa2darylm {"print", luaB_print}, 43316a5fed65808adf648004b34f98718301d718fa2darylm {"rawequal", luaB_rawequal}, 43416a5fed65808adf648004b34f98718301d718fa2darylm {"rawlen", luaB_rawlen}, 43516a5fed65808adf648004b34f98718301d718fa2darylm {"rawget", luaB_rawget}, 43616a5fed65808adf648004b34f98718301d718fa2darylm {"rawset", luaB_rawset}, 43716a5fed65808adf648004b34f98718301d718fa2darylm {"select", luaB_select}, 43816a5fed65808adf648004b34f98718301d718fa2darylm {"setmetatable", luaB_setmetatable}, 43916a5fed65808adf648004b34f98718301d718fa2darylm {"tonumber", luaB_tonumber}, 44016a5fed65808adf648004b34f98718301d718fa2darylm {"tostring", luaB_tostring}, 44116a5fed65808adf648004b34f98718301d718fa2darylm {"type", luaB_type}, 44216a5fed65808adf648004b34f98718301d718fa2darylm {"xpcall", luaB_xpcall}, 44316a5fed65808adf648004b34f98718301d718fa2darylm {NULL, NULL} 44416a5fed65808adf648004b34f98718301d718fa2darylm}; 44516a5fed65808adf648004b34f98718301d718fa2darylm 44616a5fed65808adf648004b34f98718301d718fa2darylm 44716a5fed65808adf648004b34f98718301d718fa2darylmLUAMOD_API int luaopen_base (lua_State *L) { 44816a5fed65808adf648004b34f98718301d718fa2darylm /* set global _G */ 44916a5fed65808adf648004b34f98718301d718fa2darylm lua_pushglobaltable(L); 45016a5fed65808adf648004b34f98718301d718fa2darylm lua_pushglobaltable(L); 45116a5fed65808adf648004b34f98718301d718fa2darylm lua_setfield(L, -2, "_G"); 45216a5fed65808adf648004b34f98718301d718fa2darylm /* open lib into global table */ 45316a5fed65808adf648004b34f98718301d718fa2darylm luaL_setfuncs(L, base_funcs, 0); 45416a5fed65808adf648004b34f98718301d718fa2darylm lua_pushliteral(L, LUA_VERSION); 45516a5fed65808adf648004b34f98718301d718fa2darylm lua_setfield(L, -2, "_VERSION"); /* set global _VERSION */ 45616a5fed65808adf648004b34f98718301d718fa2darylm return 1; 45716a5fed65808adf648004b34f98718301d718fa2darylm} 45816a5fed65808adf648004b34f98718301d718fa2darylm 459