1*088332b5SXin Li /*
2*088332b5SXin Li ** $Id: lbaselib.c $
3*088332b5SXin Li ** Basic library
4*088332b5SXin Li ** See Copyright Notice in lua.h
5*088332b5SXin Li */
6*088332b5SXin Li
7*088332b5SXin Li #define lbaselib_c
8*088332b5SXin Li #define LUA_LIB
9*088332b5SXin Li
10*088332b5SXin Li #include "lprefix.h"
11*088332b5SXin Li
12*088332b5SXin Li
13*088332b5SXin Li #include <ctype.h>
14*088332b5SXin Li #include <stdio.h>
15*088332b5SXin Li #include <stdlib.h>
16*088332b5SXin Li #include <string.h>
17*088332b5SXin Li
18*088332b5SXin Li #include "lua.h"
19*088332b5SXin Li
20*088332b5SXin Li #include "lauxlib.h"
21*088332b5SXin Li #include "lualib.h"
22*088332b5SXin Li
23*088332b5SXin Li
luaB_print(lua_State * L)24*088332b5SXin Li static int luaB_print (lua_State *L) {
25*088332b5SXin Li int n = lua_gettop(L); /* number of arguments */
26*088332b5SXin Li int i;
27*088332b5SXin Li for (i = 1; i <= n; i++) { /* for each argument */
28*088332b5SXin Li size_t l;
29*088332b5SXin Li const char *s = luaL_tolstring(L, i, &l); /* convert it to string */
30*088332b5SXin Li if (i > 1) /* not the first element? */
31*088332b5SXin Li lua_writestring("\t", 1); /* add a tab before it */
32*088332b5SXin Li lua_writestring(s, l); /* print it */
33*088332b5SXin Li lua_pop(L, 1); /* pop result */
34*088332b5SXin Li }
35*088332b5SXin Li lua_writeline();
36*088332b5SXin Li return 0;
37*088332b5SXin Li }
38*088332b5SXin Li
39*088332b5SXin Li
40*088332b5SXin Li /*
41*088332b5SXin Li ** Creates a warning with all given arguments.
42*088332b5SXin Li ** Check first for errors; otherwise an error may interrupt
43*088332b5SXin Li ** the composition of a warning, leaving it unfinished.
44*088332b5SXin Li */
luaB_warn(lua_State * L)45*088332b5SXin Li static int luaB_warn (lua_State *L) {
46*088332b5SXin Li int n = lua_gettop(L); /* number of arguments */
47*088332b5SXin Li int i;
48*088332b5SXin Li luaL_checkstring(L, 1); /* at least one argument */
49*088332b5SXin Li for (i = 2; i <= n; i++)
50*088332b5SXin Li luaL_checkstring(L, i); /* make sure all arguments are strings */
51*088332b5SXin Li for (i = 1; i < n; i++) /* compose warning */
52*088332b5SXin Li lua_warning(L, lua_tostring(L, i), 1);
53*088332b5SXin Li lua_warning(L, lua_tostring(L, n), 0); /* close warning */
54*088332b5SXin Li return 0;
55*088332b5SXin Li }
56*088332b5SXin Li
57*088332b5SXin Li
58*088332b5SXin Li #define SPACECHARS " \f\n\r\t\v"
59*088332b5SXin Li
b_str2int(const char * s,int base,lua_Integer * pn)60*088332b5SXin Li static const char *b_str2int (const char *s, int base, lua_Integer *pn) {
61*088332b5SXin Li lua_Unsigned n = 0;
62*088332b5SXin Li int neg = 0;
63*088332b5SXin Li s += strspn(s, SPACECHARS); /* skip initial spaces */
64*088332b5SXin Li if (*s == '-') { s++; neg = 1; } /* handle sign */
65*088332b5SXin Li else if (*s == '+') s++;
66*088332b5SXin Li if (!isalnum((unsigned char)*s)) /* no digit? */
67*088332b5SXin Li return NULL;
68*088332b5SXin Li do {
69*088332b5SXin Li int digit = (isdigit((unsigned char)*s)) ? *s - '0'
70*088332b5SXin Li : (toupper((unsigned char)*s) - 'A') + 10;
71*088332b5SXin Li if (digit >= base) return NULL; /* invalid numeral */
72*088332b5SXin Li n = n * base + digit;
73*088332b5SXin Li s++;
74*088332b5SXin Li } while (isalnum((unsigned char)*s));
75*088332b5SXin Li s += strspn(s, SPACECHARS); /* skip trailing spaces */
76*088332b5SXin Li *pn = (lua_Integer)((neg) ? (0u - n) : n);
77*088332b5SXin Li return s;
78*088332b5SXin Li }
79*088332b5SXin Li
80*088332b5SXin Li
luaB_tonumber(lua_State * L)81*088332b5SXin Li static int luaB_tonumber (lua_State *L) {
82*088332b5SXin Li if (lua_isnoneornil(L, 2)) { /* standard conversion? */
83*088332b5SXin Li if (lua_type(L, 1) == LUA_TNUMBER) { /* already a number? */
84*088332b5SXin Li lua_settop(L, 1); /* yes; return it */
85*088332b5SXin Li return 1;
86*088332b5SXin Li }
87*088332b5SXin Li else {
88*088332b5SXin Li size_t l;
89*088332b5SXin Li const char *s = lua_tolstring(L, 1, &l);
90*088332b5SXin Li if (s != NULL && lua_stringtonumber(L, s) == l + 1)
91*088332b5SXin Li return 1; /* successful conversion to number */
92*088332b5SXin Li /* else not a number */
93*088332b5SXin Li luaL_checkany(L, 1); /* (but there must be some parameter) */
94*088332b5SXin Li }
95*088332b5SXin Li }
96*088332b5SXin Li else {
97*088332b5SXin Li size_t l;
98*088332b5SXin Li const char *s;
99*088332b5SXin Li lua_Integer n = 0; /* to avoid warnings */
100*088332b5SXin Li lua_Integer base = luaL_checkinteger(L, 2);
101*088332b5SXin Li luaL_checktype(L, 1, LUA_TSTRING); /* no numbers as strings */
102*088332b5SXin Li s = lua_tolstring(L, 1, &l);
103*088332b5SXin Li luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range");
104*088332b5SXin Li if (b_str2int(s, (int)base, &n) == s + l) {
105*088332b5SXin Li lua_pushinteger(L, n);
106*088332b5SXin Li return 1;
107*088332b5SXin Li } /* else not a number */
108*088332b5SXin Li } /* else not a number */
109*088332b5SXin Li luaL_pushfail(L); /* not a number */
110*088332b5SXin Li return 1;
111*088332b5SXin Li }
112*088332b5SXin Li
113*088332b5SXin Li
luaB_error(lua_State * L)114*088332b5SXin Li static int luaB_error (lua_State *L) {
115*088332b5SXin Li int level = (int)luaL_optinteger(L, 2, 1);
116*088332b5SXin Li lua_settop(L, 1);
117*088332b5SXin Li if (lua_type(L, 1) == LUA_TSTRING && level > 0) {
118*088332b5SXin Li luaL_where(L, level); /* add extra information */
119*088332b5SXin Li lua_pushvalue(L, 1);
120*088332b5SXin Li lua_concat(L, 2);
121*088332b5SXin Li }
122*088332b5SXin Li return lua_error(L);
123*088332b5SXin Li }
124*088332b5SXin Li
125*088332b5SXin Li
luaB_getmetatable(lua_State * L)126*088332b5SXin Li static int luaB_getmetatable (lua_State *L) {
127*088332b5SXin Li luaL_checkany(L, 1);
128*088332b5SXin Li if (!lua_getmetatable(L, 1)) {
129*088332b5SXin Li lua_pushnil(L);
130*088332b5SXin Li return 1; /* no metatable */
131*088332b5SXin Li }
132*088332b5SXin Li luaL_getmetafield(L, 1, "__metatable");
133*088332b5SXin Li return 1; /* returns either __metatable field (if present) or metatable */
134*088332b5SXin Li }
135*088332b5SXin Li
136*088332b5SXin Li
luaB_setmetatable(lua_State * L)137*088332b5SXin Li static int luaB_setmetatable (lua_State *L) {
138*088332b5SXin Li int t = lua_type(L, 2);
139*088332b5SXin Li luaL_checktype(L, 1, LUA_TTABLE);
140*088332b5SXin Li luaL_argexpected(L, t == LUA_TNIL || t == LUA_TTABLE, 2, "nil or table");
141*088332b5SXin Li if (luaL_getmetafield(L, 1, "__metatable") != LUA_TNIL)
142*088332b5SXin Li return luaL_error(L, "cannot change a protected metatable");
143*088332b5SXin Li lua_settop(L, 2);
144*088332b5SXin Li lua_setmetatable(L, 1);
145*088332b5SXin Li return 1;
146*088332b5SXin Li }
147*088332b5SXin Li
148*088332b5SXin Li
luaB_rawequal(lua_State * L)149*088332b5SXin Li static int luaB_rawequal (lua_State *L) {
150*088332b5SXin Li luaL_checkany(L, 1);
151*088332b5SXin Li luaL_checkany(L, 2);
152*088332b5SXin Li lua_pushboolean(L, lua_rawequal(L, 1, 2));
153*088332b5SXin Li return 1;
154*088332b5SXin Li }
155*088332b5SXin Li
156*088332b5SXin Li
luaB_rawlen(lua_State * L)157*088332b5SXin Li static int luaB_rawlen (lua_State *L) {
158*088332b5SXin Li int t = lua_type(L, 1);
159*088332b5SXin Li luaL_argexpected(L, t == LUA_TTABLE || t == LUA_TSTRING, 1,
160*088332b5SXin Li "table or string");
161*088332b5SXin Li lua_pushinteger(L, lua_rawlen(L, 1));
162*088332b5SXin Li return 1;
163*088332b5SXin Li }
164*088332b5SXin Li
165*088332b5SXin Li
luaB_rawget(lua_State * L)166*088332b5SXin Li static int luaB_rawget (lua_State *L) {
167*088332b5SXin Li luaL_checktype(L, 1, LUA_TTABLE);
168*088332b5SXin Li luaL_checkany(L, 2);
169*088332b5SXin Li lua_settop(L, 2);
170*088332b5SXin Li lua_rawget(L, 1);
171*088332b5SXin Li return 1;
172*088332b5SXin Li }
173*088332b5SXin Li
luaB_rawset(lua_State * L)174*088332b5SXin Li static int luaB_rawset (lua_State *L) {
175*088332b5SXin Li luaL_checktype(L, 1, LUA_TTABLE);
176*088332b5SXin Li luaL_checkany(L, 2);
177*088332b5SXin Li luaL_checkany(L, 3);
178*088332b5SXin Li lua_settop(L, 3);
179*088332b5SXin Li lua_rawset(L, 1);
180*088332b5SXin Li return 1;
181*088332b5SXin Li }
182*088332b5SXin Li
183*088332b5SXin Li
pushmode(lua_State * L,int oldmode)184*088332b5SXin Li static int pushmode (lua_State *L, int oldmode) {
185*088332b5SXin Li lua_pushstring(L, (oldmode == LUA_GCINC) ? "incremental" : "generational");
186*088332b5SXin Li return 1;
187*088332b5SXin Li }
188*088332b5SXin Li
189*088332b5SXin Li
luaB_collectgarbage(lua_State * L)190*088332b5SXin Li static int luaB_collectgarbage (lua_State *L) {
191*088332b5SXin Li static const char *const opts[] = {"stop", "restart", "collect",
192*088332b5SXin Li "count", "step", "setpause", "setstepmul",
193*088332b5SXin Li "isrunning", "generational", "incremental", NULL};
194*088332b5SXin Li static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT,
195*088332b5SXin Li LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL,
196*088332b5SXin Li LUA_GCISRUNNING, LUA_GCGEN, LUA_GCINC};
197*088332b5SXin Li int o = optsnum[luaL_checkoption(L, 1, "collect", opts)];
198*088332b5SXin Li switch (o) {
199*088332b5SXin Li case LUA_GCCOUNT: {
200*088332b5SXin Li int k = lua_gc(L, o);
201*088332b5SXin Li int b = lua_gc(L, LUA_GCCOUNTB);
202*088332b5SXin Li lua_pushnumber(L, (lua_Number)k + ((lua_Number)b/1024));
203*088332b5SXin Li return 1;
204*088332b5SXin Li }
205*088332b5SXin Li case LUA_GCSTEP: {
206*088332b5SXin Li int step = (int)luaL_optinteger(L, 2, 0);
207*088332b5SXin Li int res = lua_gc(L, o, step);
208*088332b5SXin Li lua_pushboolean(L, res);
209*088332b5SXin Li return 1;
210*088332b5SXin Li }
211*088332b5SXin Li case LUA_GCSETPAUSE:
212*088332b5SXin Li case LUA_GCSETSTEPMUL: {
213*088332b5SXin Li int p = (int)luaL_optinteger(L, 2, 0);
214*088332b5SXin Li int previous = lua_gc(L, o, p);
215*088332b5SXin Li lua_pushinteger(L, previous);
216*088332b5SXin Li return 1;
217*088332b5SXin Li }
218*088332b5SXin Li case LUA_GCISRUNNING: {
219*088332b5SXin Li int res = lua_gc(L, o);
220*088332b5SXin Li lua_pushboolean(L, res);
221*088332b5SXin Li return 1;
222*088332b5SXin Li }
223*088332b5SXin Li case LUA_GCGEN: {
224*088332b5SXin Li int minormul = (int)luaL_optinteger(L, 2, 0);
225*088332b5SXin Li int majormul = (int)luaL_optinteger(L, 3, 0);
226*088332b5SXin Li return pushmode(L, lua_gc(L, o, minormul, majormul));
227*088332b5SXin Li }
228*088332b5SXin Li case LUA_GCINC: {
229*088332b5SXin Li int pause = (int)luaL_optinteger(L, 2, 0);
230*088332b5SXin Li int stepmul = (int)luaL_optinteger(L, 3, 0);
231*088332b5SXin Li int stepsize = (int)luaL_optinteger(L, 4, 0);
232*088332b5SXin Li return pushmode(L, lua_gc(L, o, pause, stepmul, stepsize));
233*088332b5SXin Li }
234*088332b5SXin Li default: {
235*088332b5SXin Li int res = lua_gc(L, o);
236*088332b5SXin Li lua_pushinteger(L, res);
237*088332b5SXin Li return 1;
238*088332b5SXin Li }
239*088332b5SXin Li }
240*088332b5SXin Li }
241*088332b5SXin Li
242*088332b5SXin Li
luaB_type(lua_State * L)243*088332b5SXin Li static int luaB_type (lua_State *L) {
244*088332b5SXin Li int t = lua_type(L, 1);
245*088332b5SXin Li luaL_argcheck(L, t != LUA_TNONE, 1, "value expected");
246*088332b5SXin Li lua_pushstring(L, lua_typename(L, t));
247*088332b5SXin Li return 1;
248*088332b5SXin Li }
249*088332b5SXin Li
250*088332b5SXin Li
luaB_next(lua_State * L)251*088332b5SXin Li static int luaB_next (lua_State *L) {
252*088332b5SXin Li luaL_checktype(L, 1, LUA_TTABLE);
253*088332b5SXin Li lua_settop(L, 2); /* create a 2nd argument if there isn't one */
254*088332b5SXin Li if (lua_next(L, 1))
255*088332b5SXin Li return 2;
256*088332b5SXin Li else {
257*088332b5SXin Li lua_pushnil(L);
258*088332b5SXin Li return 1;
259*088332b5SXin Li }
260*088332b5SXin Li }
261*088332b5SXin Li
262*088332b5SXin Li
luaB_pairs(lua_State * L)263*088332b5SXin Li static int luaB_pairs (lua_State *L) {
264*088332b5SXin Li luaL_checkany(L, 1);
265*088332b5SXin Li if (luaL_getmetafield(L, 1, "__pairs") == LUA_TNIL) { /* no metamethod? */
266*088332b5SXin Li lua_pushcfunction(L, luaB_next); /* will return generator, */
267*088332b5SXin Li lua_pushvalue(L, 1); /* state, */
268*088332b5SXin Li lua_pushnil(L); /* and initial value */
269*088332b5SXin Li }
270*088332b5SXin Li else {
271*088332b5SXin Li lua_pushvalue(L, 1); /* argument 'self' to metamethod */
272*088332b5SXin Li lua_call(L, 1, 3); /* get 3 values from metamethod */
273*088332b5SXin Li }
274*088332b5SXin Li return 3;
275*088332b5SXin Li }
276*088332b5SXin Li
277*088332b5SXin Li
278*088332b5SXin Li /*
279*088332b5SXin Li ** Traversal function for 'ipairs'
280*088332b5SXin Li */
ipairsaux(lua_State * L)281*088332b5SXin Li static int ipairsaux (lua_State *L) {
282*088332b5SXin Li lua_Integer i = luaL_checkinteger(L, 2) + 1;
283*088332b5SXin Li lua_pushinteger(L, i);
284*088332b5SXin Li return (lua_geti(L, 1, i) == LUA_TNIL) ? 1 : 2;
285*088332b5SXin Li }
286*088332b5SXin Li
287*088332b5SXin Li
288*088332b5SXin Li /*
289*088332b5SXin Li ** 'ipairs' function. Returns 'ipairsaux', given "table", 0.
290*088332b5SXin Li ** (The given "table" may not be a table.)
291*088332b5SXin Li */
luaB_ipairs(lua_State * L)292*088332b5SXin Li static int luaB_ipairs (lua_State *L) {
293*088332b5SXin Li luaL_checkany(L, 1);
294*088332b5SXin Li lua_pushcfunction(L, ipairsaux); /* iteration function */
295*088332b5SXin Li lua_pushvalue(L, 1); /* state */
296*088332b5SXin Li lua_pushinteger(L, 0); /* initial value */
297*088332b5SXin Li return 3;
298*088332b5SXin Li }
299*088332b5SXin Li
300*088332b5SXin Li
load_aux(lua_State * L,int status,int envidx)301*088332b5SXin Li static int load_aux (lua_State *L, int status, int envidx) {
302*088332b5SXin Li if (status == LUA_OK) {
303*088332b5SXin Li if (envidx != 0) { /* 'env' parameter? */
304*088332b5SXin Li lua_pushvalue(L, envidx); /* environment for loaded function */
305*088332b5SXin Li if (!lua_setupvalue(L, -2, 1)) /* set it as 1st upvalue */
306*088332b5SXin Li lua_pop(L, 1); /* remove 'env' if not used by previous call */
307*088332b5SXin Li }
308*088332b5SXin Li return 1;
309*088332b5SXin Li }
310*088332b5SXin Li else { /* error (message is on top of the stack) */
311*088332b5SXin Li luaL_pushfail(L);
312*088332b5SXin Li lua_insert(L, -2); /* put before error message */
313*088332b5SXin Li return 2; /* return fail plus error message */
314*088332b5SXin Li }
315*088332b5SXin Li }
316*088332b5SXin Li
317*088332b5SXin Li
luaB_loadfile(lua_State * L)318*088332b5SXin Li static int luaB_loadfile (lua_State *L) {
319*088332b5SXin Li const char *fname = luaL_optstring(L, 1, NULL);
320*088332b5SXin Li const char *mode = luaL_optstring(L, 2, NULL);
321*088332b5SXin Li int env = (!lua_isnone(L, 3) ? 3 : 0); /* 'env' index or 0 if no 'env' */
322*088332b5SXin Li int status = luaL_loadfilex(L, fname, mode);
323*088332b5SXin Li return load_aux(L, status, env);
324*088332b5SXin Li }
325*088332b5SXin Li
326*088332b5SXin Li
327*088332b5SXin Li /*
328*088332b5SXin Li ** {======================================================
329*088332b5SXin Li ** Generic Read function
330*088332b5SXin Li ** =======================================================
331*088332b5SXin Li */
332*088332b5SXin Li
333*088332b5SXin Li
334*088332b5SXin Li /*
335*088332b5SXin Li ** reserved slot, above all arguments, to hold a copy of the returned
336*088332b5SXin Li ** string to avoid it being collected while parsed. 'load' has four
337*088332b5SXin Li ** optional arguments (chunk, source name, mode, and environment).
338*088332b5SXin Li */
339*088332b5SXin Li #define RESERVEDSLOT 5
340*088332b5SXin Li
341*088332b5SXin Li
342*088332b5SXin Li /*
343*088332b5SXin Li ** Reader for generic 'load' function: 'lua_load' uses the
344*088332b5SXin Li ** stack for internal stuff, so the reader cannot change the
345*088332b5SXin Li ** stack top. Instead, it keeps its resulting string in a
346*088332b5SXin Li ** reserved slot inside the stack.
347*088332b5SXin Li */
generic_reader(lua_State * L,void * ud,size_t * size)348*088332b5SXin Li static const char *generic_reader (lua_State *L, void *ud, size_t *size) {
349*088332b5SXin Li (void)(ud); /* not used */
350*088332b5SXin Li luaL_checkstack(L, 2, "too many nested functions");
351*088332b5SXin Li lua_pushvalue(L, 1); /* get function */
352*088332b5SXin Li lua_call(L, 0, 1); /* call it */
353*088332b5SXin Li if (lua_isnil(L, -1)) {
354*088332b5SXin Li lua_pop(L, 1); /* pop result */
355*088332b5SXin Li *size = 0;
356*088332b5SXin Li return NULL;
357*088332b5SXin Li }
358*088332b5SXin Li else if (!lua_isstring(L, -1))
359*088332b5SXin Li luaL_error(L, "reader function must return a string");
360*088332b5SXin Li lua_replace(L, RESERVEDSLOT); /* save string in reserved slot */
361*088332b5SXin Li return lua_tolstring(L, RESERVEDSLOT, size);
362*088332b5SXin Li }
363*088332b5SXin Li
364*088332b5SXin Li
luaB_load(lua_State * L)365*088332b5SXin Li static int luaB_load (lua_State *L) {
366*088332b5SXin Li int status;
367*088332b5SXin Li size_t l;
368*088332b5SXin Li const char *s = lua_tolstring(L, 1, &l);
369*088332b5SXin Li const char *mode = luaL_optstring(L, 3, "bt");
370*088332b5SXin Li int env = (!lua_isnone(L, 4) ? 4 : 0); /* 'env' index or 0 if no 'env' */
371*088332b5SXin Li if (s != NULL) { /* loading a string? */
372*088332b5SXin Li const char *chunkname = luaL_optstring(L, 2, s);
373*088332b5SXin Li status = luaL_loadbufferx(L, s, l, chunkname, mode);
374*088332b5SXin Li }
375*088332b5SXin Li else { /* loading from a reader function */
376*088332b5SXin Li const char *chunkname = luaL_optstring(L, 2, "=(load)");
377*088332b5SXin Li luaL_checktype(L, 1, LUA_TFUNCTION);
378*088332b5SXin Li lua_settop(L, RESERVEDSLOT); /* create reserved slot */
379*088332b5SXin Li status = lua_load(L, generic_reader, NULL, chunkname, mode);
380*088332b5SXin Li }
381*088332b5SXin Li return load_aux(L, status, env);
382*088332b5SXin Li }
383*088332b5SXin Li
384*088332b5SXin Li /* }====================================================== */
385*088332b5SXin Li
386*088332b5SXin Li
dofilecont(lua_State * L,int d1,lua_KContext d2)387*088332b5SXin Li static int dofilecont (lua_State *L, int d1, lua_KContext d2) {
388*088332b5SXin Li (void)d1; (void)d2; /* only to match 'lua_Kfunction' prototype */
389*088332b5SXin Li return lua_gettop(L) - 1;
390*088332b5SXin Li }
391*088332b5SXin Li
392*088332b5SXin Li
luaB_dofile(lua_State * L)393*088332b5SXin Li static int luaB_dofile (lua_State *L) {
394*088332b5SXin Li const char *fname = luaL_optstring(L, 1, NULL);
395*088332b5SXin Li lua_settop(L, 1);
396*088332b5SXin Li if (luaL_loadfile(L, fname) != LUA_OK)
397*088332b5SXin Li return lua_error(L);
398*088332b5SXin Li lua_callk(L, 0, LUA_MULTRET, 0, dofilecont);
399*088332b5SXin Li return dofilecont(L, 0, 0);
400*088332b5SXin Li }
401*088332b5SXin Li
402*088332b5SXin Li
luaB_assert(lua_State * L)403*088332b5SXin Li static int luaB_assert (lua_State *L) {
404*088332b5SXin Li if (lua_toboolean(L, 1)) /* condition is true? */
405*088332b5SXin Li return lua_gettop(L); /* return all arguments */
406*088332b5SXin Li else { /* error */
407*088332b5SXin Li luaL_checkany(L, 1); /* there must be a condition */
408*088332b5SXin Li lua_remove(L, 1); /* remove it */
409*088332b5SXin Li lua_pushliteral(L, "assertion failed!"); /* default message */
410*088332b5SXin Li lua_settop(L, 1); /* leave only message (default if no other one) */
411*088332b5SXin Li return luaB_error(L); /* call 'error' */
412*088332b5SXin Li }
413*088332b5SXin Li }
414*088332b5SXin Li
415*088332b5SXin Li
luaB_select(lua_State * L)416*088332b5SXin Li static int luaB_select (lua_State *L) {
417*088332b5SXin Li int n = lua_gettop(L);
418*088332b5SXin Li if (lua_type(L, 1) == LUA_TSTRING && *lua_tostring(L, 1) == '#') {
419*088332b5SXin Li lua_pushinteger(L, n-1);
420*088332b5SXin Li return 1;
421*088332b5SXin Li }
422*088332b5SXin Li else {
423*088332b5SXin Li lua_Integer i = luaL_checkinteger(L, 1);
424*088332b5SXin Li if (i < 0) i = n + i;
425*088332b5SXin Li else if (i > n) i = n;
426*088332b5SXin Li luaL_argcheck(L, 1 <= i, 1, "index out of range");
427*088332b5SXin Li return n - (int)i;
428*088332b5SXin Li }
429*088332b5SXin Li }
430*088332b5SXin Li
431*088332b5SXin Li
432*088332b5SXin Li /*
433*088332b5SXin Li ** Continuation function for 'pcall' and 'xpcall'. Both functions
434*088332b5SXin Li ** already pushed a 'true' before doing the call, so in case of success
435*088332b5SXin Li ** 'finishpcall' only has to return everything in the stack minus
436*088332b5SXin Li ** 'extra' values (where 'extra' is exactly the number of items to be
437*088332b5SXin Li ** ignored).
438*088332b5SXin Li */
finishpcall(lua_State * L,int status,lua_KContext extra)439*088332b5SXin Li static int finishpcall (lua_State *L, int status, lua_KContext extra) {
440*088332b5SXin Li if (status != LUA_OK && status != LUA_YIELD) { /* error? */
441*088332b5SXin Li lua_pushboolean(L, 0); /* first result (false) */
442*088332b5SXin Li lua_pushvalue(L, -2); /* error message */
443*088332b5SXin Li return 2; /* return false, msg */
444*088332b5SXin Li }
445*088332b5SXin Li else
446*088332b5SXin Li return lua_gettop(L) - (int)extra; /* return all results */
447*088332b5SXin Li }
448*088332b5SXin Li
449*088332b5SXin Li
luaB_pcall(lua_State * L)450*088332b5SXin Li static int luaB_pcall (lua_State *L) {
451*088332b5SXin Li int status;
452*088332b5SXin Li luaL_checkany(L, 1);
453*088332b5SXin Li lua_pushboolean(L, 1); /* first result if no errors */
454*088332b5SXin Li lua_insert(L, 1); /* put it in place */
455*088332b5SXin Li status = lua_pcallk(L, lua_gettop(L) - 2, LUA_MULTRET, 0, 0, finishpcall);
456*088332b5SXin Li return finishpcall(L, status, 0);
457*088332b5SXin Li }
458*088332b5SXin Li
459*088332b5SXin Li
460*088332b5SXin Li /*
461*088332b5SXin Li ** Do a protected call with error handling. After 'lua_rotate', the
462*088332b5SXin Li ** stack will have <f, err, true, f, [args...]>; so, the function passes
463*088332b5SXin Li ** 2 to 'finishpcall' to skip the 2 first values when returning results.
464*088332b5SXin Li */
luaB_xpcall(lua_State * L)465*088332b5SXin Li static int luaB_xpcall (lua_State *L) {
466*088332b5SXin Li int status;
467*088332b5SXin Li int n = lua_gettop(L);
468*088332b5SXin Li luaL_checktype(L, 2, LUA_TFUNCTION); /* check error function */
469*088332b5SXin Li lua_pushboolean(L, 1); /* first result */
470*088332b5SXin Li lua_pushvalue(L, 1); /* function */
471*088332b5SXin Li lua_rotate(L, 3, 2); /* move them below function's arguments */
472*088332b5SXin Li status = lua_pcallk(L, n - 2, LUA_MULTRET, 2, 2, finishpcall);
473*088332b5SXin Li return finishpcall(L, status, 2);
474*088332b5SXin Li }
475*088332b5SXin Li
476*088332b5SXin Li
luaB_tostring(lua_State * L)477*088332b5SXin Li static int luaB_tostring (lua_State *L) {
478*088332b5SXin Li luaL_checkany(L, 1);
479*088332b5SXin Li luaL_tolstring(L, 1, NULL);
480*088332b5SXin Li return 1;
481*088332b5SXin Li }
482*088332b5SXin Li
483*088332b5SXin Li
484*088332b5SXin Li static const luaL_Reg base_funcs[] = {
485*088332b5SXin Li {"assert", luaB_assert},
486*088332b5SXin Li {"collectgarbage", luaB_collectgarbage},
487*088332b5SXin Li {"dofile", luaB_dofile},
488*088332b5SXin Li {"error", luaB_error},
489*088332b5SXin Li {"getmetatable", luaB_getmetatable},
490*088332b5SXin Li {"ipairs", luaB_ipairs},
491*088332b5SXin Li {"loadfile", luaB_loadfile},
492*088332b5SXin Li {"load", luaB_load},
493*088332b5SXin Li {"next", luaB_next},
494*088332b5SXin Li {"pairs", luaB_pairs},
495*088332b5SXin Li {"pcall", luaB_pcall},
496*088332b5SXin Li {"print", luaB_print},
497*088332b5SXin Li {"warn", luaB_warn},
498*088332b5SXin Li {"rawequal", luaB_rawequal},
499*088332b5SXin Li {"rawlen", luaB_rawlen},
500*088332b5SXin Li {"rawget", luaB_rawget},
501*088332b5SXin Li {"rawset", luaB_rawset},
502*088332b5SXin Li {"select", luaB_select},
503*088332b5SXin Li {"setmetatable", luaB_setmetatable},
504*088332b5SXin Li {"tonumber", luaB_tonumber},
505*088332b5SXin Li {"tostring", luaB_tostring},
506*088332b5SXin Li {"type", luaB_type},
507*088332b5SXin Li {"xpcall", luaB_xpcall},
508*088332b5SXin Li /* placeholders */
509*088332b5SXin Li {LUA_GNAME, NULL},
510*088332b5SXin Li {"_VERSION", NULL},
511*088332b5SXin Li {NULL, NULL}
512*088332b5SXin Li };
513*088332b5SXin Li
514*088332b5SXin Li
luaopen_base(lua_State * L)515*088332b5SXin Li LUAMOD_API int luaopen_base (lua_State *L) {
516*088332b5SXin Li /* open lib into global table */
517*088332b5SXin Li lua_pushglobaltable(L);
518*088332b5SXin Li luaL_setfuncs(L, base_funcs, 0);
519*088332b5SXin Li /* set global _G */
520*088332b5SXin Li lua_pushvalue(L, -1);
521*088332b5SXin Li lua_setfield(L, -2, LUA_GNAME);
522*088332b5SXin Li /* set global _VERSION */
523*088332b5SXin Li lua_pushliteral(L, LUA_VERSION);
524*088332b5SXin Li lua_setfield(L, -2, "_VERSION");
525*088332b5SXin Li return 1;
526*088332b5SXin Li }
527*088332b5SXin Li
528