diff options
Diffstat (limited to 'src/lbaselib.c')
-rw-r--r-- | src/lbaselib.c | 80 |
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)); } |