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