summaryrefslogtreecommitdiff
path: root/src/lbaselib.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lbaselib.c')
-rw-r--r--src/lbaselib.c80
1 files changed, 45 insertions, 35 deletions
diff --git a/src/lbaselib.c b/src/lbaselib.c
index e4daf5d4..472a96c8 100644
--- a/src/lbaselib.c
+++ b/src/lbaselib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lbaselib.c,v 1.264 2011/07/05 12:49:35 roberto Exp $
+** $Id: lbaselib.c,v 1.270 2011/11/23 17:29:04 roberto Exp $
** Basic library
** See Copyright Notice in lua.h
*/
@@ -46,20 +46,22 @@ static int luaB_print (lua_State *L) {
#define SPACECHARS " \f\n\r\t\v"
static int luaB_tonumber (lua_State *L) {
- int base = luaL_optint(L, 2, 10);
- luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range");
- if (base == 10) { /* standard conversion */
- luaL_checkany(L, 1);
- if (lua_isnumber(L, 1)) {
- lua_pushnumber(L, lua_tonumber(L, 1));
+ if (lua_isnoneornil(L, 2)) { /* standard conversion */
+ int isnum;
+ lua_Number n = lua_tonumberx(L, 1, &isnum);
+ if (isnum) {
+ lua_pushnumber(L, n);
return 1;
- } /* else not a number */
+ } /* else not a number; must be something */
+ luaL_checkany(L, 1);
}
else {
size_t l;
const char *s = luaL_checklstring(L, 1, &l);
const char *e = s + l; /* end point for 's' */
+ int base = luaL_checkint(L, 2);
int neg = 0;
+ luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range");
s += strspn(s, SPACECHARS); /* skip initial spaces */
if (*s == '-') { s++; neg = 1; } /* handle signal */
else if (*s == '+') s++;
@@ -158,7 +160,7 @@ static int luaB_rawset (lua_State *L) {
static int luaB_collectgarbage (lua_State *L) {
static const char *const opts[] = {"stop", "restart", "collect",
"count", "step", "setpause", "setstepmul",
- "setmajorinc", "isrunning", "gen", "inc", NULL};
+ "setmajorinc", "isrunning", "generational", "incremental", NULL};
static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT,
LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL,
LUA_GCSETMAJORINC, LUA_GCISRUNNING, LUA_GCGEN, LUA_GCINC};
@@ -253,7 +255,14 @@ static int load_aux (lua_State *L, int status) {
static int luaB_loadfile (lua_State *L) {
const char *fname = luaL_optstring(L, 1, NULL);
- return load_aux(L, luaL_loadfile(L, fname));
+ const char *mode = luaL_optstring(L, 2, NULL);
+ int env = !lua_isnone(L, 3); /* 'env' parameter? */
+ int status = luaL_loadfilex(L, fname, mode);
+ if (status == LUA_OK && env) { /* 'env' parameter? */
+ lua_pushvalue(L, 3);
+ lua_setupvalue(L, -2, 1); /* set it as 1st upvalue of loaded chunk */
+ }
+ return load_aux(L, status);
}
@@ -265,7 +274,6 @@ static int luaB_loadfile (lua_State *L) {
typedef struct {
-char c;
const char *mode;
} loaddata;
@@ -276,11 +284,11 @@ char c;
** pushed on the stack) in case of errors.
*/
static const char *checkrights (lua_State *L, const char *mode, const char *s) {
- if (strchr(mode, 'b') == NULL && *s == LUA_SIGNATURE[0])
- return lua_pushstring(L, "attempt to load a binary chunk");
- if (strchr(mode, 't') == NULL && *s != LUA_SIGNATURE[0])
- return lua_pushstring(L, "attempt to load a text chunk");
- return NULL; /* chunk in allowed format */
+ const char *x = (*s == LUA_SIGNATURE[0]) ? "binary" : "text";
+ if (strchr(mode, x[0]) == NULL)
+ return lua_pushfstring(L,
+ "attempt to load a %s chunk (mode is " LUA_QS ")", x, mode);
+ else return NULL;
}
@@ -390,27 +398,32 @@ static int luaB_select (lua_State *L) {
}
-static int pcallcont (lua_State *L) {
- int errfunc = 0; /* =0 to avoid warnings */
- int status = lua_getctx(L, &errfunc);
- lua_assert(status != LUA_OK);
- lua_pushboolean(L, (status == LUA_YIELD)); /* first result (status) */
- if (errfunc) /* came from xpcall? */
- lua_replace(L, 1); /* put first result in place of error function */
- else /* came from pcall */
- lua_insert(L, 1); /* open space for first result */
+static int finishpcall (lua_State *L, int status) {
+ if (!lua_checkstack(L, 1)) { /* no space for extra boolean? */
+ lua_settop(L, 0); /* create space for return values */
+ lua_pushboolean(L, 0);
+ lua_pushstring(L, "stack overflow");
+ return 2; /* return false, msg */
+ }
+ lua_pushboolean(L, status); /* first result (status) */
+ lua_replace(L, 1); /* put first result in first slot */
return lua_gettop(L);
}
+static int pcallcont (lua_State *L) {
+ int status = lua_getctx(L, NULL);
+ return finishpcall(L, (status == LUA_YIELD));
+}
+
+
static int luaB_pcall (lua_State *L) {
int status;
luaL_checkany(L, 1);
- status = lua_pcallk(L, lua_gettop(L) - 1, LUA_MULTRET, 0, 0, pcallcont);
- luaL_checkstack(L, 1, NULL);
- lua_pushboolean(L, (status == LUA_OK));
- lua_insert(L, 1);
- return lua_gettop(L); /* return status + all results */
+ lua_pushnil(L);
+ lua_insert(L, 1); /* create space for status result */
+ status = lua_pcallk(L, lua_gettop(L) - 2, LUA_MULTRET, 0, 0, pcallcont);
+ return finishpcall(L, (status == LUA_OK));
}
@@ -421,11 +434,8 @@ static int luaB_xpcall (lua_State *L) {
lua_pushvalue(L, 1); /* exchange function... */
lua_copy(L, 2, 1); /* ...and error handler */
lua_replace(L, 2);
- status = lua_pcallk(L, n - 2, LUA_MULTRET, 1, 1, pcallcont);
- luaL_checkstack(L, 1, NULL);
- lua_pushboolean(L, (status == LUA_OK));
- lua_replace(L, 1);
- return lua_gettop(L); /* return status + all results */
+ status = lua_pcallk(L, n - 2, LUA_MULTRET, 1, 0, pcallcont);
+ return finishpcall(L, (status == LUA_OK));
}