summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile6
-rw-r--r--src/lapi.c40
-rw-r--r--src/lauxlib.c53
-rw-r--r--src/lauxlib.h18
-rw-r--r--src/lbaselib.c51
-rw-r--r--src/lbitlib.c26
-rw-r--r--src/lcorolib.c4
-rw-r--r--src/ldblib.c50
-rw-r--r--src/ldebug.c4
-rw-r--r--src/ldo.c17
-rw-r--r--src/lgc.c126
-rw-r--r--src/liolib.c30
-rw-r--r--src/llex.c21
-rw-r--r--src/lmathlib.c14
-rw-r--r--src/lmem.h24
-rw-r--r--src/loadlib.c19
-rw-r--r--src/lobject.c23
-rw-r--r--src/lobject.h6
-rw-r--r--src/lopcodes.h4
-rw-r--r--src/loslib.c9
-rw-r--r--src/lparser.c14
-rw-r--r--src/lstate.h12
-rw-r--r--src/lstrlib.c517
-rw-r--r--src/ltable.c138
-rw-r--r--src/ltable.h9
-rw-r--r--src/ltablib.c68
-rw-r--r--src/lua.c43
-rw-r--r--src/lua.h22
-rw-r--r--src/luaconf.h89
-rw-r--r--src/lutf8lib.c12
-rw-r--r--src/lvm.c10
-rw-r--r--src/lvm.h6
32 files changed, 842 insertions, 643 deletions
diff --git a/src/Makefile b/src/Makefile
index a30a75ef..7be16dc3 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -92,7 +92,11 @@ aix:
$(MAKE) $(ALL) CC="xlc" CFLAGS="-O2 -DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-ldl" SYSLDFLAGS="-brtl -bexpall"
ansi:
- $(MAKE) $(ALL) SYSCFLAGS="-DLUA_ANSI"
+ $(MAKE) $(ALL) SYSCFLAGS="-DLUA_ANSI -DLUA_32BITS"
+ @echo ""
+ @echo "Note: in ANSI mode, Lua is built with 32-bit numbers"
+ @echo " because ANSI C89 does not support 'long long'"
+ @echo ""
bsd:
$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-Wl,-E"
diff --git a/src/lapi.c b/src/lapi.c
index 9bd78308..24c943d1 100644
--- a/src/lapi.c
+++ b/src/lapi.c
@@ -1,5 +1,5 @@
/*
-** $Id: lapi.c,v 2.232 2014/07/30 14:00:14 roberto Exp $
+** $Id: lapi.c,v 2.238 2014/10/17 19:17:55 roberto Exp $
** Lua API
** See Copyright Notice in lua.h
*/
@@ -332,7 +332,7 @@ LUA_API int lua_compare (lua_State *L, int index1, int index2, int op) {
}
-LUA_API size_t lua_strtonum (lua_State *L, const char *s) {
+LUA_API size_t lua_stringtonumber (lua_State *L, const char *s) {
size_t sz = luaO_str2num(s, L->top);
if (sz != 0)
api_incr_top(L);
@@ -611,6 +611,18 @@ LUA_API int lua_getfield (lua_State *L, int idx, const char *k) {
}
+LUA_API int lua_geti (lua_State *L, int idx, lua_Integer n) {
+ StkId t;
+ lua_lock(L);
+ t = index2addr(L, idx);
+ setivalue(L->top, n);
+ api_incr_top(L);
+ luaV_gettable(L, t, L->top - 1, L->top - 1);
+ lua_unlock(L);
+ return ttnov(L->top - 1);
+}
+
+
LUA_API int lua_rawget (lua_State *L, int idx) {
StkId t;
lua_lock(L);
@@ -664,7 +676,7 @@ LUA_API void lua_createtable (lua_State *L, int narray, int nrec) {
LUA_API int lua_getmetatable (lua_State *L, int objindex) {
const TValue *obj;
Table *mt = NULL;
- int res;
+ int res = 0;
lua_lock(L);
obj = index2addr(L, objindex);
switch (ttnov(obj)) {
@@ -678,9 +690,7 @@ LUA_API int lua_getmetatable (lua_State *L, int objindex) {
mt = G(L)->mt[ttnov(obj)];
break;
}
- if (mt == NULL)
- res = 0;
- else {
+ if (mt != NULL) {
sethvalue(L, L->top, mt);
api_incr_top(L);
res = 1;
@@ -743,6 +753,18 @@ LUA_API void lua_setfield (lua_State *L, int idx, const char *k) {
}
+LUA_API void lua_seti (lua_State *L, int idx, lua_Integer n) {
+ StkId t;
+ lua_lock(L);
+ api_checknelems(L, 1);
+ t = index2addr(L, idx);
+ setivalue(L->top++, n);
+ luaV_settable(L, t, L->top - 1, L->top - 2);
+ L->top -= 2; /* pop value and key */
+ lua_unlock(L);
+}
+
+
LUA_API void lua_rawset (lua_State *L, int idx) {
StkId o;
Table *t;
@@ -854,8 +876,8 @@ LUA_API void lua_setuservalue (lua_State *L, int idx) {
"results from function overflow current stack size")
-LUA_API void lua_callk (lua_State *L, int nargs, int nresults, lua_Ctx ctx,
- lua_KFunction k) {
+LUA_API void lua_callk (lua_State *L, int nargs, int nresults,
+ lua_KContext ctx, lua_KFunction k) {
StkId func;
lua_lock(L);
api_check(k == NULL || !isLua(L->ci),
@@ -894,7 +916,7 @@ static void f_call (lua_State *L, void *ud) {
LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc,
- lua_Ctx ctx, lua_KFunction k) {
+ lua_KContext ctx, lua_KFunction k) {
struct CallS c;
int status;
ptrdiff_t func;
diff --git a/src/lauxlib.c b/src/lauxlib.c
index abf589ae..0a6cea0a 100644
--- a/src/lauxlib.c
+++ b/src/lauxlib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lauxlib.c,v 1.267 2014/07/19 14:37:09 roberto Exp $
+** $Id: lauxlib.c,v 1.270 2014/10/22 11:44:20 roberto Exp $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/
@@ -82,12 +82,12 @@ static int pushglobalfuncname (lua_State *L, lua_Debug *ar) {
static void pushfuncname (lua_State *L, lua_Debug *ar) {
if (*ar->namewhat != '\0') /* is there a name? */
- lua_pushfstring(L, "function " LUA_QS, ar->name);
+ lua_pushfstring(L, "function '%s'", ar->name);
else if (*ar->what == 'm') /* main? */
lua_pushliteral(L, "main chunk");
else if (*ar->what == 'C') {
if (pushglobalfuncname(L, ar)) {
- lua_pushfstring(L, "function " LUA_QS, lua_tostring(L, -1));
+ lua_pushfstring(L, "function '%s'", lua_tostring(L, -1));
lua_remove(L, -2); /* remove name */
}
else
@@ -158,25 +158,25 @@ LUALIB_API int luaL_argerror (lua_State *L, int arg, const char *extramsg) {
if (strcmp(ar.namewhat, "method") == 0) {
arg--; /* do not count `self' */
if (arg == 0) /* error is in the self argument itself? */
- return luaL_error(L, "calling " LUA_QS " on bad self (%s)",
+ return luaL_error(L, "calling '%s' on bad self (%s)",
ar.name, extramsg);
}
if (ar.name == NULL)
ar.name = (pushglobalfuncname(L, &ar)) ? lua_tostring(L, -1) : "?";
- return luaL_error(L, "bad argument #%d to " LUA_QS " (%s)",
+ return luaL_error(L, "bad argument #%d to '%s' (%s)",
arg, ar.name, extramsg);
}
static int typeerror (lua_State *L, int arg, const char *tname) {
const char *msg;
- const char *typearg = luaL_typename(L, arg);
- if (lua_getmetatable(L, arg)) {
- if (lua_getfield(L, -1, "__name") == LUA_TSTRING)
- typearg = lua_tostring(L, -1);
- }
+ const char *typearg; /* name for the type of the actual argument */
+ if (luaL_getmetafield(L, arg, "__name") == LUA_TSTRING)
+ typearg = lua_tostring(L, -1); /* use the given type name */
else if (lua_type(L, arg) == LUA_TLIGHTUSERDATA)
- typearg = "light userdata";
+ typearg = "light userdata"; /* special name for messages */
+ else
+ typearg = luaL_typename(L, arg); /* standard name */
msg = lua_pushfstring(L, "%s expected, got %s", tname, typearg);
return luaL_argerror(L, arg, msg);
}
@@ -229,7 +229,7 @@ LUALIB_API int luaL_fileresult (lua_State *L, int stat, const char *fname) {
}
-#if !defined(inspectstat) /* { */
+#if !defined(l_inspectstat) /* { */
#if defined(LUA_USE_POSIX)
@@ -238,13 +238,13 @@ LUALIB_API int luaL_fileresult (lua_State *L, int stat, const char *fname) {
/*
** use appropriate macros to interpret 'pclose' return status
*/
-#define inspectstat(stat,what) \
+#define l_inspectstat(stat,what) \
if (WIFEXITED(stat)) { stat = WEXITSTATUS(stat); } \
else if (WIFSIGNALED(stat)) { stat = WTERMSIG(stat); what = "signal"; }
#else
-#define inspectstat(stat,what) /* no op */
+#define l_inspectstat(stat,what) /* no op */
#endif
@@ -256,7 +256,7 @@ LUALIB_API int luaL_execresult (lua_State *L, int stat) {
if (stat == -1) /* error? */
return luaL_fileresult(L, 0, NULL);
else {
- inspectstat(stat, what); /* interpret result */
+ l_inspectstat(stat, what); /* interpret result */
if (*what == 'e' && stat == 0) /* successful termination? */
lua_pushboolean(L, 1);
else
@@ -335,7 +335,7 @@ LUALIB_API int luaL_checkoption (lua_State *L, int arg, const char *def,
if (strcmp(lst[i], name) == 0)
return i;
return luaL_argerror(L, arg,
- lua_pushfstring(L, "invalid option " LUA_QS, name));
+ lua_pushfstring(L, "invalid option '%s'", name));
}
@@ -701,22 +701,23 @@ LUALIB_API int luaL_loadstring (lua_State *L, const char *s) {
LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) {
if (!lua_getmetatable(L, obj)) /* no metatable? */
- return 0;
- lua_pushstring(L, event);
- if (lua_rawget(L, -2) == LUA_TNIL) { /* is metafield nil? */
- lua_pop(L, 2); /* remove metatable and metafield */
- return 0;
- }
+ return LUA_TNIL;
else {
- lua_remove(L, -2); /* remove only metatable */
- return 1;
+ int tt;
+ lua_pushstring(L, event);
+ tt = lua_rawget(L, -2);
+ if (tt == LUA_TNIL) /* is metafield nil? */
+ lua_pop(L, 2); /* remove metatable and metafield */
+ else
+ lua_remove(L, -2); /* remove only metatable */
+ return tt; /* return metafield type */
}
}
LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) {
obj = lua_absindex(L, obj);
- if (!luaL_getmetafield(L, obj, event)) /* no metafield? */
+ if (luaL_getmetafield(L, obj, event) == LUA_TNIL) /* no metafield? */
return 0;
lua_pushvalue(L, obj);
lua_call(L, 1, 1);
@@ -822,7 +823,7 @@ LUALIB_API void luaL_pushmodule (lua_State *L, const char *modname,
/* try global variable (and create one if it does not exist) */
lua_pushglobaltable(L);
if (luaL_findtable(L, 0, modname, sizehint) != NULL)
- luaL_error(L, "name conflict for module " LUA_QS, modname);
+ luaL_error(L, "name conflict for module '%s'", modname);
lua_pushvalue(L, -1);
lua_setfield(L, -3, modname); /* _LOADED[modname] = new table */
}
diff --git a/src/lauxlib.h b/src/lauxlib.h
index b5560143..cecceb3f 100644
--- a/src/lauxlib.h
+++ b/src/lauxlib.h
@@ -1,5 +1,5 @@
/*
-** $Id: lauxlib.h,v 1.125 2014/06/26 17:25:11 roberto Exp $
+** $Id: lauxlib.h,v 1.126 2014/10/01 11:54:56 roberto Exp $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/
@@ -115,10 +115,6 @@ LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname,
((void)((cond) || luaL_argerror(L, (arg), (extramsg))))
#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL))
#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL))
-#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n)))
-#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d)))
-#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n)))
-#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d)))
#define luaL_typename(L,i) lua_typename(L, lua_type(L,(i)))
@@ -210,15 +206,21 @@ LUALIB_API void (luaL_openlib) (lua_State *L, const char *libname,
/*
** {============================================================
-** Compatibility with deprecated unsigned conversions
+** Compatibility with deprecated conversions
** =============================================================
*/
-#if defined(LUA_COMPAT_APIUNSIGNED)
+#if defined(LUA_COMPAT_APIINTCASTS)
-#define luaL_checkunsigned(L,a) ((lua_Unsigned)luaL_checkinteger(L,a))
+#define luaL_checkunsigned(L,a) ((lua_Unsigned)luaL_checkinteger(L,a))
#define luaL_optunsigned(L,a,d) \
((lua_Unsigned)luaL_optinteger(L,a,(lua_Integer)(d)))
+#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n)))
+#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d)))
+
+#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n)))
+#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d)))
+
#endif
/* }============================================================ */
diff --git a/src/lbaselib.c b/src/lbaselib.c
index de1a767f..af04db0d 100644
--- a/src/lbaselib.c
+++ b/src/lbaselib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lbaselib.c,v 1.293 2014/07/24 19:33:29 roberto Exp $
+** $Id: lbaselib.c,v 1.303 2014/10/17 19:17:55 roberto Exp $
** Basic library
** See Copyright Notice in lua.h
*/
@@ -32,8 +32,7 @@ static int luaB_print (lua_State *L) {
lua_call(L, 1, 1);
s = lua_tolstring(L, -1, &l); /* get result */
if (s == NULL)
- return luaL_error(L,
- LUA_QL("tostring") " must return a string to " LUA_QL("print"));
+ return luaL_error(L, "'tostring' must return a string to 'print'");
if (i>1) luai_writestring("\t", 1);
luai_writestring(s, l);
lua_pop(L, 1); /* pop result */
@@ -78,7 +77,7 @@ static int luaB_tonumber (lua_State *L) {
else {
size_t l;
const char *s = lua_tolstring(L, 1, &l);
- if (s != NULL && lua_strtonum(L, s) == l + 1)
+ if (s != NULL && lua_stringtonumber(L, s) == l + 1)
return 1; /* successful conversion to number */
/* else not a number */
}
@@ -87,11 +86,11 @@ static int luaB_tonumber (lua_State *L) {
size_t l;
const char *s;
lua_Integer n = 0; /* to avoid warnings */
- int base = luaL_checkint(L, 2);
+ lua_Integer base = luaL_checkinteger(L, 2);
luaL_checktype(L, 1, LUA_TSTRING); /* before 'luaL_checklstring'! */
s = luaL_checklstring(L, 1, &l);
luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range");
- if (b_str2int(s, base, &n) == s + l) {
+ if (b_str2int(s, (int)base, &n) == s + l) {
lua_pushinteger(L, n);
return 1;
} /* else not a number */
@@ -102,7 +101,7 @@ static int luaB_tonumber (lua_State *L) {
static int luaB_error (lua_State *L) {
- int level = luaL_optint(L, 2, 1);
+ int level = (int)luaL_optinteger(L, 2, 1);
lua_settop(L, 1);
if (lua_isstring(L, 1) && level > 0) { /* add extra information? */
luaL_where(L, level);
@@ -129,7 +128,7 @@ static int luaB_setmetatable (lua_State *L) {
luaL_checktype(L, 1, LUA_TTABLE);
luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
"nil or table expected");
- if (luaL_getmetafield(L, 1, "__metatable"))
+ if (luaL_getmetafield(L, 1, "__metatable") != LUA_TNIL)
return luaL_error(L, "cannot change a protected metatable");
lua_settop(L, 2);
lua_setmetatable(L, 1);
@@ -180,7 +179,7 @@ static int luaB_collectgarbage (lua_State *L) {
LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL,
LUA_GCISRUNNING};
int o = optsnum[luaL_checkoption(L, 1, "collect", opts)];
- int ex = luaL_optint(L, 2, 0);
+ int ex = (int)luaL_optinteger(L, 2, 0);
int res = lua_gc(L, o, ex);
switch (o) {
case LUA_GCCOUNT: {
@@ -212,7 +211,7 @@ static int luaB_type (lua_State *L) {
static int pairsmeta (lua_State *L, const char *method, int iszero,
lua_CFunction iter) {
- if (!luaL_getmetafield(L, 1, method)) { /* no metamethod? */
+ if (luaL_getmetafield(L, 1, method) == LUA_TNIL) { /* no metamethod? */
luaL_checktype(L, 1, LUA_TTABLE); /* argument must be a table */
lua_pushcfunction(L, iter); /* will return generator, */
lua_pushvalue(L, 1); /* state, */
@@ -248,7 +247,7 @@ static int luaB_pairs (lua_State *L) {
** Traversal function for 'ipairs' for raw tables
*/
static int ipairsaux_raw (lua_State *L) {
- int i = luaL_checkint(L, 2) + 1;
+ lua_Integer i = luaL_checkinteger(L, 2) + 1;
luaL_checktype(L, 1, LUA_TTABLE);
lua_pushinteger(L, i);
return (lua_rawgeti(L, 1, i) == LUA_TNIL) ? 1 : 2;
@@ -259,17 +258,9 @@ static int ipairsaux_raw (lua_State *L) {
** Traversal function for 'ipairs' for tables with metamethods
*/
static int ipairsaux (lua_State *L) {
- int i = luaL_checkint(L, 2) + 1;
- if (i > luaL_len(L, 1)) { /* larger than length? */
- lua_pushnil(L); /* end traversal */
- return 1;
- }
- else {
- lua_pushinteger(L, i);
- lua_pushinteger(L, i); /* key for indexing table */
- lua_gettable(L, 1);
- return 2;
- }
+ lua_Integer i = luaL_checkinteger(L, 2) + 1;
+ lua_pushinteger(L, i);
+ return (lua_geti(L, 1, i) == LUA_TNIL) ? 1 : 2;
}
@@ -279,10 +270,8 @@ static int ipairsaux (lua_State *L) {
** that can affect the traversal.
*/
static int luaB_ipairs (lua_State *L) {
- lua_CFunction iter =
- (luaL_getmetafield(L, 1, "__len") ||
- luaL_getmetafield(L, 1, "__index"))
- ? ipairsaux : ipairsaux_raw;
+ lua_CFunction iter = (luaL_getmetafield(L, 1, "__index") != LUA_TNIL)
+ ? ipairsaux : ipairsaux_raw;
#if defined(LUA_COMPAT_IPAIRS)
return pairsmeta(L, "__ipairs", 1, iter);
#else
@@ -380,7 +369,7 @@ static int luaB_load (lua_State *L) {
/* }====================================================== */
-static int dofilecont (lua_State *L, int d1, lua_Ctx d2) {
+static int dofilecont (lua_State *L, int d1, lua_KContext d2) {
(void)d1; (void)d2; /* only to match 'lua_Kfunction' prototype */
return lua_gettop(L) - 1;
}
@@ -415,11 +404,11 @@ static int luaB_select (lua_State *L) {
return 1;
}
else {
- int i = luaL_checkint(L, 1);
+ lua_Integer i = luaL_checkinteger(L, 1);
if (i < 0) i = n + i;
else if (i > n) i = n;
luaL_argcheck(L, 1 <= i, 1, "index out of range");
- return n - i;
+ return n - (int)i;
}
}
@@ -431,14 +420,14 @@ static int luaB_select (lua_State *L) {
** 'extra' values (where 'extra' is exactly the number of items to be
** ignored).
*/
-static int finishpcall (lua_State *L, int status, lua_Ctx extra) {
+static int finishpcall (lua_State *L, int status, lua_KContext extra) {
if (status != LUA_OK && status != LUA_YIELD) { /* error? */
lua_pushboolean(L, 0); /* first result (false) */
lua_pushvalue(L, -2); /* error message */
return 2; /* return false, msg */
}
else
- return lua_gettop(L) - extra; /* return all results */
+ return lua_gettop(L) - (int)extra; /* return all results */
}
diff --git a/src/lbitlib.c b/src/lbitlib.c
index dfec1d31..cca6f402 100644
--- a/src/lbitlib.c
+++ b/src/lbitlib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lbitlib.c,v 1.26 2014/05/15 19:28:34 roberto Exp $
+** $Id: lbitlib.c,v 1.27 2014/10/01 11:54:56 roberto Exp $
** Standard library for bitwise operations
** See Copyright Notice in lua.h
*/
@@ -89,7 +89,7 @@ static int b_not (lua_State *L) {
}
-static int b_shift (lua_State *L, lua_Unsigned r, int i) {
+static int b_shift (lua_State *L, lua_Unsigned r, lua_Integer i) {
if (i < 0) { /* shift right? */
i = -i;
r = trim(r);
@@ -107,18 +107,18 @@ static int b_shift (lua_State *L, lua_Unsigned r, int i) {
static int b_lshift (lua_State *L) {
- return b_shift(L, luaL_checkunsigned(L, 1), luaL_checkint(L, 2));
+ return b_shift(L, luaL_checkunsigned(L, 1), luaL_checkinteger(L, 2));
}
static int b_rshift (lua_State *L) {
- return b_shift(L, luaL_checkunsigned(L, 1), -luaL_checkint(L, 2));
+ return b_shift(L, luaL_checkunsigned(L, 1), -luaL_checkinteger(L, 2));
}
static int b_arshift (lua_State *L) {
lua_Unsigned r = luaL_checkunsigned(L, 1);
- int i = luaL_checkint(L, 2);
+ lua_Integer i = luaL_checkinteger(L, 2);
if (i < 0 || !(r & ((lua_Unsigned)1 << (LUA_NBITS - 1))))
return b_shift(L, r, -i);
else { /* arithmetic shift for 'negative' number */
@@ -131,9 +131,9 @@ static int b_arshift (lua_State *L) {
}
-static int b_rot (lua_State *L, int i) {
+static int b_rot (lua_State *L, lua_Integer d) {
lua_Unsigned r = luaL_checkunsigned(L, 1);
- i &= (LUA_NBITS - 1); /* i = i % NBITS */
+ int i = d & (LUA_NBITS - 1); /* i = d % NBITS */
r = trim(r);
if (i != 0) /* avoid undefined shift of LUA_NBITS when i == 0 */
r = (r << i) | (r >> (LUA_NBITS - i));
@@ -143,12 +143,12 @@ static int b_rot (lua_State *L, int i) {
static int b_lrot (lua_State *L) {
- return b_rot(L, luaL_checkint(L, 2));
+ return b_rot(L, luaL_checkinteger(L, 2));
}
static int b_rrot (lua_State *L) {
- return b_rot(L, -luaL_checkint(L, 2));
+ return b_rot(L, -luaL_checkinteger(L, 2));
}
@@ -159,14 +159,14 @@ static int b_rrot (lua_State *L) {
** 'width' being used uninitialized.)
*/
static int fieldargs (lua_State *L, int farg, int *width) {
- int f = luaL_checkint(L, farg);
- int w = luaL_optint(L, farg + 1, 1);
+ lua_Integer f = luaL_checkinteger(L, farg);
+ lua_Integer w = luaL_optinteger(L, farg + 1, 1);
luaL_argcheck(L, 0 <= f, farg, "field cannot be negative");
luaL_argcheck(L, 0 < w, farg + 1, "width must be positive");
if (f + w > LUA_NBITS)
luaL_error(L, "trying to access non-existent bits");
- *width = w;
- return f;
+ *width = (int)w;
+ return (int)f;
}
diff --git a/src/lcorolib.c b/src/lcorolib.c
index fae85b95..cb6cfe5a 100644
--- a/src/lcorolib.c
+++ b/src/lcorolib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lcorolib.c,v 1.6 2014/05/08 13:52:20 roberto Exp $
+** $Id: lcorolib.c,v 1.7 2014/09/01 18:00:04 roberto Exp $
** Coroutine Library
** See Copyright Notice in lua.h
*/
@@ -19,7 +19,7 @@
static lua_State *getco (lua_State *L) {
lua_State *co = lua_tothread(L, 1);
- luaL_argcheck(L, co, 1, "coroutine expected");
+ luaL_argcheck(L, co, 1, "thread expected");
return co;
}
diff --git a/src/ldblib.c b/src/ldblib.c
index db79de38..3be75b55 100644
--- a/src/ldblib.c
+++ b/src/ldblib.c
@@ -1,5 +1,5 @@
/*
-** $Id: ldblib.c,v 1.139 2014/05/15 19:27:33 roberto Exp $
+** $Id: ldblib.c,v 1.143 2014/10/17 11:07:26 roberto Exp $
** Interface from Lua to its debug API
** See Copyright Notice in lua.h
*/
@@ -21,33 +21,6 @@
#define HOOKKEY "_HKEY"
-static int db_Csize (lua_State *L) {
- static struct {
- char c;
- unsigned char sz;
- } sizes[] = {
- {'I', sizeof(lua_Integer)},
- {'F', sizeof(lua_Number)},
- {'b', CHAR_BIT}, /* here is number of bits (not bytes) */
- {'h', sizeof(short)},
- {'i', sizeof(int)},
- {'l', sizeof(long)},
- {'z', sizeof(size_t)},
- {'f', sizeof(float)},
- {'d', sizeof(double)}
- };
- const char *s = luaL_checkstring(L, 1);
- int i;
- for (i = 0; i < (int)(sizeof(sizes)/sizeof(sizes[0])); i++) {
- if (*s == sizes[i].c) {
- lua_pushinteger(L, sizes[i].sz);
- return 1;
- }
- }
- return luaL_argerror(L, 1, lua_pushfstring(L, "invalid option '%c'", *s));
-}
-
-
static int db_getregistry (lua_State *L) {
lua_pushvalue(L, LUA_REGISTRYINDEX);
return 1;
@@ -160,7 +133,7 @@ static int db_getinfo (lua_State *L) {
lua_xmove(L, L1, 1);
}
else { /* stack level */
- if (!lua_getstack(L1, luaL_checkint(L, arg + 1), &ar)) {
+ if (!lua_getstack(L1, (int)luaL_checkinteger(L, arg + 1), &ar)) {
lua_pushnil(L); /* level out of range */
return 1;
}
@@ -201,14 +174,15 @@ static int db_getlocal (lua_State *L) {
lua_State *L1 = getthread(L, &arg);
lua_Debug ar;
const char *name;
- int nvar = luaL_checkint(L, arg+2); /* local-variable index */
+ int nvar = (int)luaL_checkinteger(L, arg + 2); /* local-variable index */
if (lua_isfunction(L, arg + 1)) { /* function argument? */
lua_pushvalue(L, arg + 1); /* push function */
lua_pushstring(L, lua_getlocal(L, NULL, nvar)); /* push local name */
return 1; /* return only name (there is no value) */
}
else { /* stack-level argument */
- if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */
+ int level = (int)luaL_checkinteger(L, arg + 1);
+ if (!lua_getstack(L1, level, &ar)) /* out of range? */
return luaL_argerror(L, arg+1, "level out of range");
name = lua_getlocal(L1, &ar, nvar);
if (name) {
@@ -229,12 +203,13 @@ static int db_setlocal (lua_State *L) {
int arg;
lua_State *L1 = getthread(L, &arg);
lua_Debug ar;
- if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */
+ int level = (int)luaL_checkinteger(L, arg + 1);
+ if (!lua_getstack(L1, level, &ar)) /* out of range? */
return luaL_argerror(L, arg+1, "level out of range");
luaL_checkany(L, arg+3);
lua_settop(L, arg+3);
lua_xmove(L, L1, 1);
- lua_pushstring(L, lua_setlocal(L1, &ar, luaL_checkint(L, arg+2)));
+ lua_pushstring(L, lua_setlocal(L1, &ar, (int)luaL_checkinteger(L, arg+2)));
return 1;
}
@@ -244,7 +219,7 @@ static int db_setlocal (lua_State *L) {
*/
static int auxupvalue (lua_State *L, int get) {
const char *name;
- int n = luaL_checkint(L, 2); /* upvalue index */
+ int n = (int)luaL_checkinteger(L, 2); /* upvalue index */
luaL_checktype(L, 1, LUA_TFUNCTION); /* closure */
name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n);
if (name == NULL) return 0;
@@ -270,7 +245,7 @@ static int db_setupvalue (lua_State *L) {
** returns its index
*/
static int checkupval (lua_State *L, int argf, int argnup) {
- int nup = luaL_checkint(L, argnup); /* upvalue index */
+ int nup = (int)luaL_checkinteger(L, argnup); /* upvalue index */
luaL_checktype(L, argf, LUA_TFUNCTION); /* closure */
luaL_argcheck(L, (lua_getupvalue(L, argf, nup) != NULL), argnup,
"invalid upvalue index");
@@ -359,7 +334,7 @@ static int db_sethook (lua_State *L) {
else {
const char *smask = luaL_checkstring(L, arg+2);
luaL_checktype(L, arg+1, LUA_TFUNCTION);
- count = luaL_optint(L, arg+3, 0);
+ count = (int)luaL_optinteger(L, arg + 3, 0);
func = hookf; mask = makemask(smask, count);
}
if (gethooktable(L) == 0) { /* creating hook table? */
@@ -418,7 +393,7 @@ static int db_traceback (lua_State *L) {
if (msg == NULL && !lua_isnoneornil(L, arg + 1)) /* non-string 'msg'? */
lua_pushvalue(L, arg + 1); /* return it untouched */
else {
- int level = luaL_optint(L, arg + 2, (L == L1) ? 1 : 0);
+ int level = (int)luaL_optinteger(L, arg + 2, (L == L1) ? 1 : 0);
luaL_traceback(L, L1, msg, level);
}
return 1;
@@ -426,7 +401,6 @@ static int db_traceback (lua_State *L) {
static const luaL_Reg dblib[] = {
- {"Csize", db_Csize},
{"debug", db_debug},
{"getuservalue", db_getuservalue},
{"gethook", db_gethook},
diff --git a/src/ldebug.c b/src/ldebug.c
index 3321d9f1..cf7d7ca6 100644
--- a/src/ldebug.c
+++ b/src/ldebug.c
@@ -1,5 +1,5 @@
/*
-** $Id: ldebug.c,v 2.100 2014/07/30 14:00:14 roberto Exp $
+** $Id: ldebug.c,v 2.101 2014/10/17 16:28:21 roberto Exp $
** Debug Interface
** See Copyright Notice in lua.h
*/
@@ -515,7 +515,7 @@ static const char *varinfo (lua_State *L, const TValue *o) {
kind = getobjname(ci_func(ci)->p, currentpc(ci),
cast_int(o - ci->u.l.base), &name);
}
- return (kind) ? luaO_pushfstring(L, " (%s " LUA_QS ")", kind, name) : "";
+ return (kind) ? luaO_pushfstring(L, " (%s '%s')", kind, name) : "";
}
diff --git a/src/ldo.c b/src/ldo.c
index 500de40d..a2c64234 100644
--- a/src/ldo.c
+++ b/src/ldo.c
@@ -1,5 +1,5 @@
/*
-** $Id: ldo.c,v 2.126 2014/07/17 13:53:37 roberto Exp $
+** $Id: ldo.c,v 2.130 2014/10/17 16:28:21 roberto Exp $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
@@ -111,15 +111,16 @@ l_noret luaD_throw (lua_State *L, int errcode) {
LUAI_THROW(L, L->errorJmp); /* jump to it */
}
else { /* thread has no error handler */
+ global_State *g = G(L);
L->status = cast_byte(errcode); /* mark it as dead */
- if (G(L)->mainthread->errorJmp) { /* main thread has a handler? */
- setobjs2s(L, G(L)->mainthread->top++, L->top - 1); /* copy error obj. */
- luaD_throw(G(L)->mainthread, errcode); /* re-throw in main thread */
+ if (g->mainthread->errorJmp) { /* main thread has a handler? */
+ setobjs2s(L, g->mainthread->top++, L->top - 1); /* copy error obj. */
+ luaD_throw(g->mainthread, errcode); /* re-throw in main thread */
}
else { /* no handler at all; abort */
- if (G(L)->panic) { /* panic function? */
+ if (g->panic) { /* panic function? */
lua_unlock(L);
- G(L)->panic(L); /* call it (last chance to jump out) */
+ g->panic(L); /* call it (last chance to jump out) */
}
abort();
}
@@ -593,7 +594,7 @@ LUA_API int lua_isyieldable (lua_State *L) {
}
-LUA_API int lua_yieldk (lua_State *L, int nresults, lua_Ctx ctx,
+LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx,
lua_KFunction k) {
CallInfo *ci = L->ci;
luai_userstateyield(L, nresults);
@@ -661,7 +662,7 @@ struct SParser { /* data to `f_parser' */
static void checkmode (lua_State *L, const char *mode, const char *x) {
if (mode && strchr(mode, x[0]) == NULL) {
luaO_pushfstring(L,
- "attempt to load a %s chunk (mode is " LUA_QS ")", x, mode);
+ "attempt to load a %s chunk (mode is '%s')", x, mode);
luaD_throw(L, LUA_ERRSYNTAX);
}
}
diff --git a/src/lgc.c b/src/lgc.c
index 84e8778d..ebeae89e 100644
--- a/src/lgc.c
+++ b/src/lgc.c
@@ -1,5 +1,5 @@
/*
-** $Id: lgc.c,v 2.192 2014/07/29 16:22:24 roberto Exp $
+** $Id: lgc.c,v 2.196 2014/10/03 12:54:37 roberto Exp $
** Garbage Collector
** See Copyright Notice in lua.h
*/
@@ -100,9 +100,9 @@ static void reallymarkobject (global_State *g, GCObject *o);
/*
-** link table 'h' into list pointed by 'p'
+** link collectable object 'o' into list pointed by 'p'
*/
-#define linktable(h,p) ((h)->gclist = *(p), *(p) = obj2gco(h))
+#define linkgclist(o,p) ((o)->gclist = (p), (p) = obj2gco(o))
/*
@@ -159,8 +159,7 @@ void luaC_barrierback_ (lua_State *L, Table *t) {
global_State *g = G(L);
lua_assert(isblack(t) && !isdead(g, t));
black2gray(t); /* make table gray (again) */
- t->gclist = g->grayagain;
- g->grayagain = obj2gco(t);
+ linkgclist(t, g->grayagain);
}
@@ -243,27 +242,23 @@ static void reallymarkobject (global_State *g, GCObject *o) {
break;
}
case LUA_TLCL: {
- gco2lcl(o)->gclist = g->gray;
- g->gray = o;
+ linkgclist(gco2lcl(o), g->gray);
break;
}
case LUA_TCCL: {
- gco2ccl(o)->gclist = g->gray;
- g->gray = o;
+ linkgclist(gco2ccl(o), g->gray);
break;
}
case LUA_TTABLE: {
- linktable(gco2t(o), &g->gray);
+ linkgclist(gco2t(o), g->gray);
break;
}
case LUA_TTHREAD: {
- gco2th(o)->gclist = g->gray;
- g->gray = o;
+ linkgclist(gco2th(o), g->gray);
break;
}
case LUA_TPROTO: {
- gco2p(o)->gclist = g->gray;
- g->gray = o;
+ linkgclist(gco2p(o), g->gray);
break;
}
default: lua_assert(0); break;
@@ -340,12 +335,18 @@ static void restartcollection (global_State *g) {
** =======================================================
*/
+/*
+** Traverse a table with weak values and link it to proper list. During
+** propagate phase, keep it in 'grayagain' list, to be revisited in the
+** atomic phase. In the atomic phase, if table has any white value,
+** put it in 'weak' list, to be cleared.
+*/
static void traverseweakvalue (global_State *g, Table *h) {
Node *n, *limit = gnodelast(h);
- /* if there is array part, assume it may have white values (do not
- traverse it just to check) */
+ /* if there is array part, assume it may have white values (it is not
+ worth traversing it now just to check) */
int hasclears = (h->sizearray > 0);
- for (n = gnode(h, 0); n < limit; n++) {
+ for (n = gnode(h, 0); n < limit; n++) { /* traverse hash part */
checkdeadkey(n);
if (ttisnil(gval(n))) /* entry is empty? */
removeentry(n); /* remove it */
@@ -356,20 +357,30 @@ static void traverseweakvalue (global_State *g, Table *h) {
hasclears = 1; /* table will have to be cleared */
}
}
- if (hasclears)
- linktable(h, &g->weak); /* has to be cleared later */
- else /* no white values */
- linktable(h, &g->grayagain); /* no need to clean */
+ if (g->gcstate == GCSpropagate)
+ linkgclist(h, g->grayagain); /* must retraverse it in atomic phase */
+ else if (hasclears)
+ linkgclist(h, g->weak); /* has to be cleared later */
}
+/*
+** Traverse an ephemeron table and link it to proper list. Returns true
+** iff any object was marked during this traversal (which implies that
+** convergence has to continue). During propagation phase, keep table
+** in 'grayagain' list, to be visited again in the atomic phase. In
+** the atomic phase, if table has any white->white entry, it has to
+** be revisited during ephemeron convergence (as that key may turn
+** black). Otherwise, if it has any white key, table has to be cleared
+** (in the atomic phase).
+*/
static int traverseephemeron (global_State *g, Table *h) {
int marked = 0; /* true if an object is marked in this traversal */
int hasclears = 0; /* true if table has white keys */
- int prop = 0; /* true if table has entry "white-key -> white-value" */
+ int hasww = 0; /* true if table has entry "white-key -> white-value" */
Node *n, *limit = gnodelast(h);
- int i;
- /* traverse array part (numeric keys are 'strong') */
+ unsigned int i;
+ /* traverse array part */
for (i = 0; i < h->sizearray; i++) {
if (valiswhite(&h->array[i])) {
marked = 1;
@@ -384,26 +395,27 @@ static int traverseephemeron (global_State *g, Table *h) {
else if (iscleared(g, gkey(n))) { /* key is not marked (yet)? */
hasclears = 1; /* table must be cleared */
if (valiswhite(gval(n))) /* value not marked yet? */
- prop = 1; /* must propagate again */
+ hasww = 1; /* white-white entry */
}
else if (valiswhite(gval(n))) { /* value not marked yet? */
marked = 1;
reallymarkobject(g, gcvalue(gval(n))); /* mark it now */
}
}
- if (prop)
- linktable(h, &g->ephemeron); /* have to propagate again */
- else if (hasclears) /* does table have white keys? */
- linktable(h, &g->allweak); /* may have to clean white keys */
- else /* no white keys */
- linktable(h, &g->grayagain); /* no need to clean */
+ /* link table into proper list */
+ if (g->gcstate == GCSpropagate)
+ linkgclist(h, g->grayagain); /* must retraverse it in atomic phase */
+ else if (hasww) /* table has white->white entries? */
+ linkgclist(h, g->ephemeron); /* have to propagate again */
+ else if (hasclears) /* table has white keys? */
+ linkgclist(h, g->allweak); /* may have to clean white keys */
return marked;
}
static void traversestrongtable (global_State *g, Table *h) {
Node *n, *limit = gnodelast(h);
- int i;
+ unsigned int i;
for (i = 0; i < h->sizearray; i++) /* traverse array part */
markvalue(g, &h->array[i]);
for (n = gnode(h, 0); n < limit; n++) { /* traverse hash part */
@@ -433,7 +445,7 @@ static lu_mem traversetable (global_State *g, Table *h) {
else if (!weakvalue) /* strong values? */
traverseephemeron(g, h);
else /* all weak */
- linktable(h, &g->allweak); /* nothing to traverse now */
+ linkgclist(h, g->allweak); /* nothing to traverse now */
}
else /* not weak */
traversestrongtable(g, h);
@@ -548,8 +560,7 @@ static void propagatemark (global_State *g) {
case LUA_TTHREAD: {
lua_State *th = gco2th(o);
g->gray = th->gclist; /* remove from 'gray' list */
- th->gclist = g->grayagain;
- g->grayagain = o; /* insert into 'grayagain' list */
+ linkgclist(th, g->grayagain); /* insert into 'grayagain' list */
black2gray(o);
size = traversethread(g, th);
break;
@@ -571,35 +582,12 @@ static void propagateall (global_State *g) {
}
-static void propagatelist (global_State *g, GCObject *l) {
- lua_assert(g->gray == NULL); /* no grays left */
- g->gray = l;
- propagateall(g); /* traverse all elements from 'l' */
-}
-
-/*
-** retraverse all gray lists. Because tables may be reinserted in other
-** lists when traversed, traverse the original lists to avoid traversing
-** twice the same table (which is not wrong, but inefficient)
-*/
-static void retraversegrays (global_State *g) {
- GCObject *weak = g->weak; /* save original lists */
- GCObject *grayagain = g->grayagain;
- GCObject *ephemeron = g->ephemeron;
- g->weak = g->grayagain = g->ephemeron = NULL;
- propagateall(g); /* traverse main gray list */
- propagatelist(g, grayagain);
- propagatelist(g, weak);
- propagatelist(g, ephemeron);
-}
-
-
static void convergeephemerons (global_State *g) {
int changed;
do {
GCObject *w;
GCObject *next = g->ephemeron; /* get ephemeron list */
- g->ephemeron = NULL; /* tables will return to this list when traversed */
+ g->ephemeron = NULL; /* tables may return to this list when traversed */
changed = 0;
while ((w = next) != NULL) {
next = gco2t(w)->gclist;
@@ -647,7 +635,7 @@ static void clearvalues (global_State *g, GCObject *l, GCObject *f) {
for (; l != f; l = gco2t(l)->gclist) {
Table *h = gco2t(l);
Node *n, *limit = gnodelast(h);
- int i;
+ unsigned int i;
for (i = 0; i < h->sizearray; i++) {
TValue *o = &h->array[i];
if (iscleared(g, o)) /* value was collected? */
@@ -864,7 +852,7 @@ static GCObject **findlast (GCObject **p) {
/*
** move all unreachable objects (or 'all' objects) that need
-** finalization from list 'p' to list 'tobefnz' (to be finalized)
+** finalization from list 'finobj' to list 'tobefnz' (to be finalized)
*/
static void separatetobefnz (global_State *g, int all) {
GCObject *curr;
@@ -875,7 +863,7 @@ static void separatetobefnz (global_State *g, int all) {
if (!(iswhite(curr) || all)) /* not being collected? */
p = &curr->next; /* don't bother with it */
else {
- *p = curr->next; /* remove 'curr' from "fin" list */
+ *p = curr->next; /* remove 'curr' from 'finobj' list */
curr->next = *lastnext; /* link at the end of 'tobefnz' list */
*lastnext = curr;
lastnext = &curr->next;
@@ -903,7 +891,7 @@ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) {
/* search for pointer pointing to 'o' */
for (p = &g->allgc; *p != o; p = &(*p)->next) { /* empty */ }
*p = o->next; /* remove 'o' from 'allgc' list */
- o->next = g->finobj; /* link it in "fin" list */
+ o->next = g->finobj; /* link it in 'finobj' list */
g->finobj = o;
l_setbit(o->marked, FINALIZEDBIT); /* mark it as such */
}
@@ -972,19 +960,21 @@ static l_mem atomic (lua_State *L) {
global_State *g = G(L);
l_mem work;
GCObject *origweak, *origall;
- g->GCmemtrav = 0; /* start counting work */
+ GCObject *grayagain = g->grayagain; /* save original list */
+ lua_assert(g->ephemeron == NULL && g->weak == NULL);
lua_assert(!iswhite(g->mainthread));
g->gcstate = GCSinsideatomic;
+ g->GCmemtrav = 0; /* start counting work */
markobject(g, L); /* mark running thread */
/* registry and global metatables may be changed by API */
markvalue(g, &g->l_registry);
- markmt(g); /* mark basic metatables */
+ markmt(g); /* mark global metatables */
/* remark occasional upvalues of (maybe) dead threads */
remarkupvals(g);
propagateall(g); /* propagate changes */
- work = g->GCmemtrav; /* stop counting (do not (re)count grays) */
- /* traverse objects caught by write barrier and by 'remarkupvals' */
- retraversegrays(g);
+ work = g->GCmemtrav; /* stop counting (do not recount gray-agains) */
+ g->gray = grayagain;
+ propagateall(g); /* traverse 'grayagain' list */
g->GCmemtrav = 0; /* restart counting */
convergeephemerons(g);
/* at this point, all strongly accessible objects are marked. */
diff --git a/src/liolib.c b/src/liolib.c
index 96cb1a31..9101ecae 100644
--- a/src/liolib.c
+++ b/src/liolib.c
@@ -1,5 +1,5 @@
/*
-** $Id: liolib.c,v 2.128 2014/07/29 16:01:00 roberto Exp $
+** $Id: liolib.c,v 2.136 2014/10/22 16:55:57 roberto Exp $
** Standard I/O (and system) library
** See Copyright Notice in lua.h
*/
@@ -70,7 +70,7 @@
/* ANSI definitions */
#define l_popen(L,c,m) \
((void)((void)c, m), \
- luaL_error(L, LUA_QL("popen") " not supported"), \
+ luaL_error(L, "'popen' not supported"), \
(FILE*)0)
#define l_pclose(L,file) ((void)L, (void)file, -1)
@@ -135,6 +135,7 @@
#define IO_PREFIX "_IO_"
+#define IOPREF_LEN (sizeof(IO_PREFIX)/sizeof(char) - 1)
#define IO_INPUT (IO_PREFIX "input")
#define IO_OUTPUT (IO_PREFIX "output")
@@ -193,9 +194,14 @@ static LStream *newprefile (lua_State *L) {
}
+/*
+** Calls the 'close' function from a file handle. The 'volatile' avoids
+** a bug in some versions of the Clang compiler (e.g., clang 3.0 for
+** 32 bits).
+*/
static int aux_close (lua_State *L) {
LStream *p = tolstream(L);
- lua_CFunction cf = p->closef;
+ volatile lua_CFunction cf = p->closef;
p->closef = NULL; /* mark stream as closed */
return (*cf)(L); /* close it */
}
@@ -239,7 +245,7 @@ static void opencheck (lua_State *L, const char *fname, const char *mode) {
LStream *p = newfile(L);
p->f = fopen(fname, mode);
if (p->f == NULL)
- luaL_error(L, "cannot open file " LUA_QS " (%s)", fname, strerror(errno));
+ luaL_error(L, "cannot open file '%s' (%s)", fname, strerror(errno));
}
@@ -285,7 +291,7 @@ static FILE *getiofile (lua_State *L, const char *findex) {
lua_getfield(L, LUA_REGISTRYINDEX, findex);
p = (LStream *)lua_touserdata(L, -1);
if (isclosed(p))
- luaL_error(L, "standard %s file is closed", findex + strlen(IO_PREFIX));
+ luaL_error(L, "standard %s file is closed", findex + IOPREF_LEN);
return p->f;
}
@@ -413,15 +419,15 @@ static int readdigits (RN *rn, int hex) {
/* access to locale "radix character" (decimal point) */
-#if !defined(getlocaledecpoint)
-#define getlocaledecpoint() (localeconv()->decimal_point[0])
+#if !defined(l_getlocaledecpoint)
+#define l_getlocaledecpoint() (localeconv()->decimal_point[0])
#endif
/*
** Read a number: first reads a valid prefix of a numeral into a buffer.
-** Then it calls 'lua_strtonum' to check whether the format is correct
-** and to convert it to a Lua number
+** Then it calls 'lua_stringtonumber' to check whether the format is
+** correct and to convert it to a Lua number
*/
static int read_number (lua_State *L, FILE *f) {
RN rn;
@@ -429,7 +435,7 @@ static int read_number (lua_State *L, FILE *f) {
int hex = 0;
char decp[2] = ".";
rn.f = f; rn.n = 0;
- decp[0] = getlocaledecpoint(); /* get decimal point from locale */
+ decp[0] = l_getlocaledecpoint(); /* get decimal point from locale */
l_lockfile(rn.f);
do { rn.c = l_getc(rn.f); } while (isspace(rn.c)); /* skip spaces */
test2(&rn, "-+"); /* optional signal */
@@ -447,7 +453,7 @@ static int read_number (lua_State *L, FILE *f) {
ungetc(rn.c, rn.f); /* unread look-ahead char */
l_unlockfile(rn.f);
rn.buff[rn.n] = '\0'; /* finish string */
- if (lua_strtonum(L, rn.buff)) /* is this a valid number? */
+ if (lua_stringtonumber(L, rn.buff)) /* is this a valid number? */
return 1; /* ok */
else { /* invalid format */
lua_pushnil(L); /* "result" to be removed */
@@ -576,7 +582,7 @@ static int io_readline (lua_State *L) {
lua_pushvalue(L, lua_upvalueindex(3 + i));
n = g_read(L, p->f, 2); /* 'n' is number of results */
lua_assert(n > 0); /* should return at least a nil */
- if (!lua_isnil(L, -n)) /* read at least one value? */
+ if (lua_toboolean(L, -n)) /* read at least one value? */
return n; /* return them */
else { /* first result is nil: EOF or error */
if (n > 1) { /* is there error information? */
diff --git a/src/llex.c b/src/llex.c
index 6a052080..af204f52 100644
--- a/src/llex.c
+++ b/src/llex.c
@@ -1,5 +1,5 @@
/*
-** $Id: llex.c,v 2.80 2014/07/18 13:36:14 roberto Exp $
+** $Id: llex.c,v 2.84 2014/10/22 11:44:20 roberto Exp $
** Lexical Analyzer
** See Copyright Notice in lua.h
*/
@@ -78,14 +78,13 @@ void luaX_init (lua_State *L) {
const char *luaX_token2str (LexState *ls, int token) {
if (token < FIRST_RESERVED) { /* single-byte symbols? */
- lua_assert(token == cast(unsigned char, token));
- return (lisprint(token)) ? luaO_pushfstring(ls->L, LUA_QL("%c"), token) :
- luaO_pushfstring(ls->L, "char(%d)", token);
+ lua_assert(token == cast_uchar(token));
+ return luaO_pushfstring(ls->L, "'%c'", token);
}
else {
const char *s = luaX_tokens[token - FIRST_RESERVED];
if (token < TK_EOS) /* fixed format (symbols and reserved words)? */
- return luaO_pushfstring(ls->L, LUA_QS, s);
+ return luaO_pushfstring(ls->L, "'%s'", s);
else /* names, strings, and numerals */
return s;
}
@@ -97,7 +96,7 @@ static const char *txtToken (LexState *ls, int token) {
case TK_NAME: case TK_STRING:
case TK_FLT: case TK_INT:
save(ls, '\0');
- return luaO_pushfstring(ls->L, LUA_QS, luaZ_buffer(ls->buff));
+ return luaO_pushfstring(ls->L, "'%s'", luaZ_buffer(ls->buff));
default:
return luaX_token2str(ls, token);
}
@@ -219,8 +218,8 @@ static void buffreplace (LexState *ls, char from, char to) {
}
-#if !defined(getlocaledecpoint)
-#define getlocaledecpoint() (localeconv()->decimal_point[0])
+#if !defined(l_getlocaledecpoint)
+#define l_getlocaledecpoint() (localeconv()->decimal_point[0])
#endif
@@ -232,7 +231,7 @@ static void buffreplace (LexState *ls, char from, char to) {
*/
static void trydecpoint (LexState *ls, TValue *o) {
char old = ls->decpoint;
- ls->decpoint = getlocaledecpoint();
+ ls->decpoint = l_getlocaledecpoint();
buffreplace(ls, old, ls->decpoint); /* try new decimal separator */
if (!buff2num(ls->buff, o)) {
/* format error with correct decimal point: no more options */
@@ -360,8 +359,8 @@ static int readhexaesc (LexState *ls) {
}
-static unsigned int readutf8esc (LexState *ls) {
- unsigned int r;
+static unsigned long readutf8esc (LexState *ls) {
+ unsigned long r;
int i = 4; /* chars to be removed: '\', 'u', '{', and first digit */
save_and_next(ls); /* skip 'u' */
esccheck(ls, ls->current == '{', "missing '{'");
diff --git a/src/lmathlib.c b/src/lmathlib.c
index 312df517..523e0b64 100644
--- a/src/lmathlib.c
+++ b/src/lmathlib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lmathlib.c,v 1.108 2014/07/28 17:35:47 roberto Exp $
+** $Id: lmathlib.c,v 1.110 2014/10/08 19:57:31 roberto Exp $
** Standard mathematical library
** See Copyright Notice in lua.h
*/
@@ -153,7 +153,7 @@ static int math_modf (lua_State *L) {
lua_Number ip = (n < 0) ? l_mathop(ceil)(n) : l_mathop(floor)(n);
pushnumint(L, ip);
/* fractional part (test needed for inf/-inf) */
- lua_pushnumber(L, (n == ip) ? 0.0 : (n - ip));
+ lua_pushnumber(L, (n == ip) ? l_mathop(0.0) : (n - ip));
}
return 2;
}
@@ -192,12 +192,12 @@ static int math_exp (lua_State *L) {
}
static int math_deg (lua_State *L) {
- lua_pushnumber(L, luaL_checknumber(L, 1) * (180.0 / PI));
+ lua_pushnumber(L, luaL_checknumber(L, 1) * (l_mathop(180.0) / PI));
return 1;
}
static int math_rad (lua_State *L) {
- lua_pushnumber(L, luaL_checknumber(L, 1) * (PI / 180.0));
+ lua_pushnumber(L, luaL_checknumber(L, 1) * (PI / l_mathop(180.0)));
return 1;
}
@@ -239,7 +239,7 @@ static int math_random (lua_State *L) {
double r = (double)l_rand() * (1.0 / ((double)RAND_MAX + 1.0));
switch (lua_gettop(L)) { /* check number of arguments */
case 0: { /* no arguments */
- lua_pushnumber(L, r); /* Number between 0 and 1 */
+ lua_pushnumber(L, (lua_Number)r); /* Number between 0 and 1 */
return 1;
}
case 1: { /* only upper limit */
@@ -324,7 +324,7 @@ static int math_frexp (lua_State *L) {
static int math_ldexp (lua_State *L) {
lua_Number x = luaL_checknumber(L, 1);
- int ep = luaL_checkint(L, 2);
+ int ep = (int)luaL_checkinteger(L, 2);
lua_pushnumber(L, l_mathop(ldexp)(x, ep));
return 1;
}
@@ -389,7 +389,7 @@ LUAMOD_API int luaopen_math (lua_State *L) {
luaL_newlib(L, mathlib);
lua_pushnumber(L, PI);
lua_setfield(L, -2, "pi");
- lua_pushnumber(L, HUGE_VAL);
+ lua_pushnumber(L, (lua_Number)HUGE_VAL);
lua_setfield(L, -2, "huge");
lua_pushinteger(L, LUA_MAXINTEGER);
lua_setfield(L, -2, "maxinteger");
diff --git a/src/lmem.h b/src/lmem.h
index 5f850999..f701ae0f 100644
--- a/src/lmem.h
+++ b/src/lmem.h
@@ -1,5 +1,5 @@
/*
-** $Id: lmem.h,v 1.40 2013/02/20 14:08:21 roberto Exp $
+** $Id: lmem.h,v 1.41 2014/10/08 20:25:51 roberto Exp $
** Interface to Memory Manager
** See Copyright Notice in lua.h
*/
@@ -15,20 +15,26 @@
/*
-** This macro avoids the runtime division MAX_SIZET/(e), as 'e' is
-** always constant.
-** The macro is somewhat complex to avoid warnings:
-** +1 avoids warnings of "comparison has constant result";
-** cast to 'void' avoids warnings of "value unused".
+** This macro reallocs a vector 'b' from 'on' to 'n' elements, where
+** each element has size 'e'. In case of arithmetic overflow of the
+** product 'n'*'e', it raises an error (calling 'luaM_toobig'). Because
+** 'e' is always constant, it avoids the runtime division MAX_SIZET/(e).
+**
+** (The macro is somewhat complex to avoid warnings: The 'sizeof'
+** comparison avoids a runtime comparison when overflow cannot occur.
+** The compiler should be able to optimize the real test by itself, but
+** when it does it, it may give a warning about "comparison is always
+** false due to limited range of data type"; the +1 tricks the compiler,
+** avoiding this warning but also this optimization.)
*/
#define luaM_reallocv(L,b,on,n,e) \
- (cast(void, \
- (cast(size_t, (n)+1) > MAX_SIZET/(e)) ? (luaM_toobig(L), 0) : 0), \
+ (((sizeof(n) >= sizeof(size_t) && cast(size_t, (n)) + 1 > MAX_SIZET/(e)) \
+ ? luaM_toobig(L) : cast_void(0)) , \
luaM_realloc_(L, (b), (on)*(e), (n)*(e)))
#define luaM_freemem(L, b, s) luaM_realloc_(L, (b), (s), 0)
#define luaM_free(L, b) luaM_realloc_(L, (b), sizeof(*(b)), 0)
-#define luaM_freearray(L, b, n) luaM_reallocv(L, (b), n, 0, sizeof((b)[0]))
+#define luaM_freearray(L, b, n) luaM_realloc_(L, (b), (n)*sizeof(*(b)), 0)
#define luaM_malloc(L,s) luaM_realloc_(L, NULL, 0, (s))
#define luaM_new(L,t) cast(t *, luaM_malloc(L, sizeof(t)))
diff --git a/src/loadlib.c b/src/loadlib.c
index 4894188a..9cf5e69d 100644
--- a/src/loadlib.c
+++ b/src/loadlib.c
@@ -1,5 +1,5 @@
/*
-** $Id: loadlib.c,v 1.116 2014/07/29 16:01:00 roberto Exp $
+** $Id: loadlib.c,v 1.117 2014/10/17 16:28:21 roberto Exp $
** Dynamic library loader for Lua
** See Copyright Notice in lua.h
**
@@ -396,7 +396,7 @@ static const char *searchpath (lua_State *L, const char *name,
lua_remove(L, -2); /* remove path template */
if (readable(filename)) /* does file exist and is readable? */
return filename; /* return that file name */
- lua_pushfstring(L, "\n\tno file " LUA_QS, filename);
+ lua_pushfstring(L, "\n\tno file '%s'", filename);
lua_remove(L, -2); /* remove file name */
luaL_addvalue(&msg); /* concatenate error msg. entry */
}
@@ -426,7 +426,7 @@ static const char *findfile (lua_State *L, const char *name,
lua_getfield(L, lua_upvalueindex(1), pname);
path = lua_tostring(L, -1);
if (path == NULL)
- luaL_error(L, LUA_QL("package.%s") " must be a string", pname);
+ luaL_error(L, "'package.%s' must be a string", pname);
return searchpath(L, name, path, ".", dirsep);
}
@@ -437,8 +437,7 @@ static int checkload (lua_State *L, int stat, const char *filename) {
return 2; /* return open function and file name */
}
else
- return luaL_error(L, "error loading module " LUA_QS
- " from file " LUA_QS ":\n\t%s",
+ return luaL_error(L, "error loading module '%s' from file '%s':\n\t%s",
lua_tostring(L, 1), filename, lua_tostring(L, -1));
}
@@ -499,8 +498,7 @@ static int searcher_Croot (lua_State *L) {
if (stat != ERRFUNC)
return checkload(L, 0, filename); /* real error */
else { /* open function not found */
- lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS,
- name, filename);
+ lua_pushfstring(L, "\n\tno module '%s' in file '%s'", name, filename);
return 1;
}
}
@@ -524,14 +522,13 @@ static void findloader (lua_State *L, const char *name) {
luaL_buffinit(L, &msg);
lua_getfield(L, lua_upvalueindex(1), "searchers"); /* will be at index 3 */
if (!lua_istable(L, 3))
- luaL_error(L, LUA_QL("package.searchers") " must be a table");
+ luaL_error(L, "'package.searchers' must be a table");
/* iterate over available searchers to find a loader */
for (i = 1; ; i++) {
if (lua_rawgeti(L, 3, i) == LUA_TNIL) { /* no more searchers? */
lua_pop(L, 1); /* remove nil */
luaL_pushresult(&msg); /* create error message */
- luaL_error(L, "module " LUA_QS " not found:%s",
- name, lua_tostring(L, -1));
+ luaL_error(L, "module '%s' not found:%s", name, lua_tostring(L, -1));
}
lua_pushstring(L, name);
lua_call(L, 1, 2); /* call it */
@@ -589,7 +586,7 @@ static void set_env (lua_State *L) {
if (lua_getstack(L, 1, &ar) == 0 ||
lua_getinfo(L, "f", &ar) == 0 || /* get calling function */
lua_iscfunction(L, -1))
- luaL_error(L, LUA_QL("module") " not called from a Lua function");
+ luaL_error(L, "'module' not called from a Lua function");
lua_pushvalue(L, -2); /* copy new environment table to top */
lua_setupvalue(L, -2, 1);
lua_pop(L, 1); /* remove function */
diff --git a/src/lobject.c b/src/lobject.c
index 2bcdbfa1..28048dd7 100644
--- a/src/lobject.c
+++ b/src/lobject.c
@@ -1,5 +1,5 @@
/*
-** $Id: lobject.c,v 2.88 2014/07/30 14:00:14 roberto Exp $
+** $Id: lobject.c,v 2.93 2014/10/17 16:28:21 roberto Exp $
** Some generic functions over Lua objects
** See Copyright Notice in lua.h
*/
@@ -310,10 +310,11 @@ size_t luaO_str2num (const char *s, TValue *o) {
}
-int luaO_utf8esc (char *buff, unsigned int x) {
+int luaO_utf8esc (char *buff, unsigned long x) {
int n = 1; /* number of bytes put in buffer (backwards) */
+ lua_assert(x <= 0x10FFFF);
if (x < 0x80) /* ascii? */
- buff[UTF8BUFFSZ - 1] = x;
+ buff[UTF8BUFFSZ - 1] = cast(char, x);
else { /* need continuation bytes */
unsigned int mfb = 0x3f; /* maximum that fits in first byte */
do {
@@ -321,7 +322,7 @@ int luaO_utf8esc (char *buff, unsigned int x) {
x >>= 6; /* remove added bits */
mfb >>= 1; /* now there is one less bit available in first byte */
} while (x > mfb); /* still needs continuation byte? */
- buff[UTF8BUFFSZ - n] = (~mfb << 1) | x; /* add first byte */
+ buff[UTF8BUFFSZ - n] = cast(char, (~mfb << 1) | x); /* add first byte */
}
return n;
}
@@ -359,7 +360,7 @@ static void pushstr (lua_State *L, const char *str, size_t l) {
/* this function handles only '%d', '%c', '%f', '%p', and '%s'
- conventional formats, plus Lua-specific '%L' and '%U' */
+ conventional formats, plus Lua-specific '%I' and '%U' */
const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
int n = 0;
for (;;) {
@@ -376,7 +377,10 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
}
case 'c': {
char buff = cast(char, va_arg(argp, int));
- pushstr(L, &buff, 1);
+ if (lisprint(cast_uchar(buff)))
+ pushstr(L, &buff, 1);
+ else /* non-printable character; print its code */
+ luaO_pushfstring(L, "<\\%d>", cast_uchar(buff));
break;
}
case 'd': {
@@ -402,7 +406,7 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
}
case 'U': {
char buff[UTF8BUFFSZ];
- int l = luaO_utf8esc(buff, va_arg(argp, int));
+ int l = luaO_utf8esc(buff, cast(long, va_arg(argp, long)));
pushstr(L, buff + UTF8BUFFSZ - l, l);
break;
}
@@ -411,9 +415,8 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
break;
}
default: {
- luaG_runerror(L,
- "invalid option " LUA_QL("%%%c") " to " LUA_QL("lua_pushfstring"),
- *(e + 1));
+ luaG_runerror(L, "invalid option '%%%c' to 'lua_pushfstring'",
+ *(e + 1));
}
}
n += 2;
diff --git a/src/lobject.h b/src/lobject.h
index 9972e08b..054df783 100644
--- a/src/lobject.h
+++ b/src/lobject.h
@@ -1,5 +1,5 @@
/*
-** $Id: lobject.h,v 2.101 2014/07/30 14:00:14 roberto Exp $
+** $Id: lobject.h,v 2.103 2014/10/01 11:52:33 roberto Exp $
** Type definitions for Lua objects
** See Copyright Notice in lua.h
*/
@@ -487,7 +487,7 @@ typedef struct Table {
CommonHeader;
lu_byte flags; /* 1<<p means tagmethod(p) is not present */
lu_byte lsizenode; /* log2 of size of `node' array */
- int sizearray; /* size of `array' array */
+ unsigned int sizearray; /* size of `array' array */
TValue *array; /* array part */
Node *node;
Node *lastfree; /* any free position is before this position */
@@ -521,7 +521,7 @@ LUAI_DDEC const TValue luaO_nilobject_;
LUAI_FUNC int luaO_int2fb (unsigned int x);
LUAI_FUNC int luaO_fb2int (int x);
-LUAI_FUNC int luaO_utf8esc (char *buff, unsigned int x);
+LUAI_FUNC int luaO_utf8esc (char *buff, unsigned long x);
LUAI_FUNC int luaO_ceillog2 (unsigned int x);
LUAI_FUNC void luaO_arith (lua_State *L, int op, const TValue *p1,
const TValue *p2, TValue *res);
diff --git a/src/lopcodes.h b/src/lopcodes.h
index 3f5d0153..eb6c2a0d 100644
--- a/src/lopcodes.h
+++ b/src/lopcodes.h
@@ -1,5 +1,5 @@
/*
-** $Id: lopcodes.h,v 1.146 2013/12/30 20:47:58 roberto Exp $
+** $Id: lopcodes.h,v 1.147 2014/10/20 18:29:55 roberto Exp $
** Opcodes for Lua virtual machine
** See Copyright Notice in lua.h
*/
@@ -203,7 +203,7 @@ OP_LEN,/* A B R(A) := length of R(B) */
OP_CONCAT,/* A B C R(A) := R(B).. ... ..R(C) */
-OP_JMP,/* A sBx pc+=sBx; if (A) close all upvalues >= R(A) + 1 */
+OP_JMP,/* A sBx pc+=sBx; if (A) close all upvalues >= R(A - 1) */
OP_EQ,/* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */
OP_LT,/* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */
OP_LE,/* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */
diff --git a/src/loslib.c b/src/loslib.c
index 3be1d999..c721e711 100644
--- a/src/loslib.c
+++ b/src/loslib.c
@@ -1,5 +1,5 @@
/*
-** $Id: loslib.c,v 1.46 2014/04/29 17:05:13 roberto Exp $
+** $Id: loslib.c,v 1.49 2014/10/17 16:28:21 roberto Exp $
** Standard Operating System library
** See Copyright Notice in lua.h
*/
@@ -189,7 +189,7 @@ static int getfield (lua_State *L, const char *key, int d) {
res = (int)lua_tointegerx(L, -1, &isnum);
if (!isnum) {
if (d < 0)
- return luaL_error(L, "field " LUA_QS " missing in date table", key);
+ return luaL_error(L, "field '%s' missing in date table", key);
res = d;
}
lua_pop(L, 1);
@@ -295,7 +295,8 @@ static int os_time (lua_State *L) {
static int os_difftime (lua_State *L) {
- lua_pushnumber(L, difftime((l_checktime(L, 1)), (l_checktime(L, 2))));
+ double res = difftime((l_checktime(L, 1)), (l_checktime(L, 2)));
+ lua_pushnumber(L, (lua_Number)res);
return 1;
}
@@ -319,7 +320,7 @@ static int os_exit (lua_State *L) {
if (lua_isboolean(L, 1))
status = (lua_toboolean(L, 1) ? EXIT_SUCCESS : EXIT_FAILURE);
else
- status = luaL_optint(L, 1, EXIT_SUCCESS);
+ status = (int)luaL_optinteger(L, 1, EXIT_SUCCESS);
if (lua_toboolean(L, 2))
lua_close(L);
if (L) exit(status); /* 'if' to avoid warnings for unreachable 'return' */
diff --git a/src/lparser.c b/src/lparser.c
index 1e7e244a..2c009658 100644
--- a/src/lparser.c
+++ b/src/lparser.c
@@ -1,5 +1,5 @@
/*
-** $Id: lparser.c,v 2.142 2014/07/21 16:02:10 roberto Exp $
+** $Id: lparser.c,v 2.143 2014/10/17 16:28:21 roberto Exp $
** Lua Parser
** See Copyright Notice in lua.h
*/
@@ -340,7 +340,7 @@ static void closegoto (LexState *ls, int g, Labeldesc *label) {
if (gt->nactvar < label->nactvar) {
TString *vname = getlocvar(fs, gt->nactvar)->varname;
const char *msg = luaO_pushfstring(ls->L,
- "<goto %s> at line %d jumps into the scope of local " LUA_QS,
+ "<goto %s> at line %d jumps into the scope of local '%s'",
getstr(gt->name), gt->line, getstr(vname));
semerror(ls, msg);
}
@@ -457,7 +457,7 @@ static void breaklabel (LexState *ls) {
static l_noret undefgoto (LexState *ls, Labeldesc *gt) {
const char *msg = isreserved(gt->name)
? "<%s> at line %d not inside a loop"
- : "no visible label " LUA_QS " for <goto> at line %d";
+ : "no visible label '%s' for <goto> at line %d";
msg = luaO_pushfstring(ls->L, msg, getstr(gt->name), gt->line);
semerror(ls, msg);
}
@@ -761,7 +761,7 @@ static void parlist (LexState *ls) {
f->is_vararg = 1;
break;
}
- default: luaX_syntaxerror(ls, "<name> or " LUA_QL("...") " expected");
+ default: luaX_syntaxerror(ls, "<name> or '...' expected");
}
} while (!f->is_vararg && testnext(ls, ','));
}
@@ -953,7 +953,7 @@ static void simpleexp (LexState *ls, expdesc *v) {
case TK_DOTS: { /* vararg */
FuncState *fs = ls->fs;
check_condition(ls, fs->f->is_vararg,
- "cannot use " LUA_QL("...") " outside a vararg function");
+ "cannot use '...' outside a vararg function");
init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0));
break;
}
@@ -1200,7 +1200,7 @@ static void checkrepeated (FuncState *fs, Labellist *ll, TString *label) {
for (i = fs->bl->firstlabel; i < ll->n; i++) {
if (eqstr(label, ll->arr[i].name)) {
const char *msg = luaO_pushfstring(fs->ls->L,
- "label " LUA_QS " already defined on line %d",
+ "label '%s' already defined on line %d",
getstr(label), ll->arr[i].line);
semerror(fs->ls, msg);
}
@@ -1367,7 +1367,7 @@ static void forstat (LexState *ls, int line) {
switch (ls->t.token) {
case '=': fornum(ls, varname, line); break;
case ',': case TK_IN: forlist(ls, varname); break;
- default: luaX_syntaxerror(ls, LUA_QL("=") " or " LUA_QL("in") " expected");
+ default: luaX_syntaxerror(ls, "'=' or 'in' expected");
}
check_match(ls, TK_END, TK_FOR, line);
leaveblock(fs); /* loop scope (`break' jumps to this point) */
diff --git a/src/lstate.h b/src/lstate.h
index 698bea0d..3ecd4977 100644
--- a/src/lstate.h
+++ b/src/lstate.h
@@ -1,5 +1,5 @@
/*
-** $Id: lstate.h,v 2.114 2014/07/23 17:15:43 roberto Exp $
+** $Id: lstate.h,v 2.117 2014/10/07 18:29:13 roberto Exp $
** Global State
** See Copyright Notice in lua.h
*/
@@ -54,7 +54,13 @@ typedef struct stringtable {
/*
-** information about a call
+** Information about a call.
+** When a thread yields, 'func' is adjusted to pretend that the
+** top function has only the yielded values in its stack; in that
+** case, the actual 'func' value is saved in field 'extra'.
+** When a function calls another with a continuation, 'extra' keeps
+** the function index so that, in case of errors, the continuation
+** function can be called with the correct top.
*/
typedef struct CallInfo {
StkId func; /* function index in the stack */
@@ -68,7 +74,7 @@ typedef struct CallInfo {
struct { /* only for C functions */
lua_KFunction k; /* continuation in case of yields */
ptrdiff_t old_errfunc;
- lua_Ctx ctx; /* context info. in case of yields */
+ lua_KContext ctx; /* context info. in case of yields */
} c;
} u;
ptrdiff_t extra;
diff --git a/src/lstrlib.c b/src/lstrlib.c
index 05330c80..748e2a81 100644
--- a/src/lstrlib.c
+++ b/src/lstrlib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lstrlib.c,v 1.200 2014/07/30 13:59:24 roberto Exp $
+** $Id: lstrlib.c,v 1.205 2014/10/20 16:44:54 roberto Exp $
** Standard library for string operations and pattern-matching
** See Copyright Notice in lua.h
*/
@@ -250,14 +250,14 @@ static const char *classend (MatchState *ms, const char *p) {
switch (*p++) {
case L_ESC: {
if (p == ms->p_end)
- luaL_error(ms->L, "malformed pattern (ends with " LUA_QL("%%") ")");
+ luaL_error(ms->L, "malformed pattern (ends with '%%')");
return p+1;
}
case '[': {
if (*p == '^') p++;
do { /* look for a `]' */
if (p == ms->p_end)
- luaL_error(ms->L, "malformed pattern (missing " LUA_QL("]") ")");
+ luaL_error(ms->L, "malformed pattern (missing ']')");
if (*(p++) == L_ESC && p < ms->p_end)
p++; /* skip escapes (e.g. `%]') */
} while (*p != ']');
@@ -332,8 +332,7 @@ static int singlematch (MatchState *ms, const char *s, const char *p,
static const char *matchbalance (MatchState *ms, const char *s,
const char *p) {
if (p >= ms->p_end - 1)
- luaL_error(ms->L, "malformed pattern "
- "(missing arguments to " LUA_QL("%%b") ")");
+ luaL_error(ms->L, "malformed pattern (missing arguments to '%%b')");
if (*s != *p) return NULL;
else {
int b = *p;
@@ -450,8 +449,7 @@ static const char *match (MatchState *ms, const char *s, const char *p) {
const char *ep; char previous;
p += 2;
if (*p != '[')
- luaL_error(ms->L, "missing " LUA_QL("[") " after "
- LUA_QL("%%f") " in pattern");
+ luaL_error(ms->L, "missing '[' after '%%f' in pattern");
ep = classend(ms, p); /* points to what is next */
previous = (s == ms->src_init) ? '\0' : *(s - 1);
if (!matchbracketclass(uchar(previous), p, ep - 1) &&
@@ -694,8 +692,7 @@ static void add_s (MatchState *ms, luaL_Buffer *b, const char *s,
i++; /* skip ESC */
if (!isdigit(uchar(news[i]))) {
if (news[i] != L_ESC)
- luaL_error(L, "invalid use of " LUA_QL("%c")
- " in replacement string", L_ESC);
+ luaL_error(L, "invalid use of '%c' in replacement string", L_ESC);
luaL_addchar(b, news[i]);
}
else if (news[i] == '0')
@@ -890,7 +887,7 @@ static int str_format (lua_State *L) {
strfrmt = scanformat(L, strfrmt, form);
switch (*strfrmt++) {
case 'c': {
- nb = sprintf(buff, form, luaL_checkint(L, arg));
+ nb = sprintf(buff, form, (int)luaL_checkinteger(L, arg));
break;
}
case 'd': case 'i':
@@ -929,8 +926,8 @@ static int str_format (lua_State *L) {
}
}
default: { /* also treat cases `pnLlh' */
- return luaL_error(L, "invalid option " LUA_QL("%%%c") " to "
- LUA_QL("format"), *(strfrmt - 1));
+ return luaL_error(L, "invalid option '%%%c' to 'format'",
+ *(strfrmt - 1));
}
}
luaL_addsize(&b, nb);
@@ -950,212 +947,394 @@ static int str_format (lua_State *L) {
*/
+/* maximum size for the binary representation of an integer */
+#define MAXINTSIZE 16
+
/* number of bits in a character */
#define NB CHAR_BIT
/* mask for one character (NB 1's) */
#define MC ((1 << NB) - 1)
-/* mask for one character without sign bit ((NB - 1) 1's) */
-#define SM (MC >> 1)
-
/* size of a lua_Integer */
#define SZINT ((int)sizeof(lua_Integer))
-/* maximum size for the binary representation of an integer */
-#define MAXINTSIZE 12
+/* mask for all ones in last byte in a lua Integer */
+#define HIGHERBYTE ((lua_Unsigned)MC << (NB * (SZINT - 1)))
-static union {
+/* dummy union to get native endianness */
+static const union {
int dummy;
char little; /* true iff machine is little endian */
-} const nativeendian = {1};
+} nativeendian = {1};
-static int getendian (lua_State *L, int arg) {
- const char *endian = luaL_optstring(L, arg,
- (nativeendian.little ? "l" : "b"));
- if (*endian == 'n') /* native? */
- return nativeendian.little;
- luaL_argcheck(L, *endian == 'l' || *endian == 'b', arg,
- "endianness must be 'l'/'b'/'n'");
- return (*endian == 'l');
-}
+/* dummy structure to get native alignment requirements */
+struct cD {
+ char c;
+ union { double d; void *p; lua_Integer i; lua_Number n; } u;
+};
+#define MAXALIGN (offsetof(struct cD, u))
-static int getintsize (lua_State *L, int arg) {
- int size = luaL_optint(L, arg, 0);
- if (size == 0) size = SZINT;
- luaL_argcheck(L, 1 <= size && size <= MAXINTSIZE, arg,
- "integer size out of valid range");
- return size;
-}
+/*
+** Union for serializing floats
+*/
+typedef union Ftypes {
+ float f;
+ double d;
+ lua_Number n;
+ char buff[5 * sizeof(lua_Number)]; /* enough for any float type */
+} Ftypes;
-/* mask for all ones in last byte in a lua Integer */
-#define HIGHERBYTE ((lua_Unsigned)MC << (NB * (SZINT - 1)))
+/*
+** information to pack/unpack stuff
+*/
+typedef struct Header {
+ lua_State *L;
+ int islittle;
+ int maxalign;
+} Header;
-static int dumpint (char *buff, lua_Integer m, int littleendian, int size) {
- int i;
- lua_Unsigned n = (lua_Unsigned)m;
- lua_Unsigned mask = (m >= 0) ? 0 : HIGHERBYTE; /* sign extension */
- if (littleendian) {
- for (i = 0; i < size - 1; i++) {
- buff[i] = (n & MC);
- n = (n >> NB) | mask;
- }
- }
+
+/*
+** options for pack/unpack
+*/
+typedef enum KOption {
+ Kint, /* signed integers */
+ Kuint, /* unsigned integers */
+ Kfloat, /* floating-point numbers */
+ Kchar, /* fixed-length strings */
+ Kstring, /* strings with prefixed length */
+ Kzstr, /* zero-terminated strings */
+ Kpadding, /* padding */
+ Kpaddalign, /* padding for alignment */
+ Knop, /* no-op (configuration or spaces) */
+ Keof /* end of format */
+} KOption;
+
+
+/*
+** Read an integer numeral from string 'fmt' or return 'df' if
+** there is no numeral
+*/
+static int digit (int c) { return '0' <= c && c <= '9'; }
+
+static int getnum (const char **fmt, int df) {
+ if (!digit(**fmt)) /* no number? */
+ return df; /* return default value */
else {
- for (i = size - 1; i > 0; i--) {
- buff[i] = (n & MC);
- n = (n >> NB) | mask;
- }
- }
- buff[i] = (n & MC); /* last byte */
- if (size < SZINT) { /* need test for overflow? */
- /* OK if there are only zeros left in higher bytes,
- or only ones left (excluding non-signal bits in last byte) */
- return ((n & ~(lua_Unsigned)MC) == 0 ||
- (n | SM) == ~(lua_Unsigned)0);
+ int a = 0;
+ do {
+ a = a*10 + *((*fmt)++) - '0';
+ } while (digit(**fmt) && a < (INT_MAX/10 - 10));
+ return a;
}
- else return 1; /* no overflow can occur with full size */
}
-static int dumpint_l (lua_State *L) {
- char buff[MAXINTSIZE];
- lua_Integer n = luaL_checkinteger(L, 1);
- int size = getintsize(L, 2);
- int endian = getendian(L, 3);
- if (dumpint(buff, n, endian, size))
- lua_pushlstring(L, buff, size);
- else
- luaL_error(L, "integer does not fit into given size (%d)", size);
- return 1;
+/*
+** Read an integer numeral and raises an error if it is larger
+** than the maximum size for integers.
+*/
+static int getnumlimit (Header *h, const char **fmt, int df) {
+ int sz = getnum(fmt, df);
+ if (sz > MAXINTSIZE || sz <= 0)
+ luaL_error(h->L, "integral size (%d) out of limits [1,%d]", sz, MAXINTSIZE);
+ return sz;
}
-/* mask to check higher-order byte + signal bit of next (lower) byte */
-#define HIGHERBYTE1 (HIGHERBYTE | (HIGHERBYTE >> 1))
+/*
+** Initialize Header
+*/
+static void initheader (lua_State *L, Header *h) {
+ h->L = L;
+ h->islittle = nativeendian.little;
+ h->maxalign = 1;
+}
-static int undumpint (const char *buff, lua_Integer *res,
- int littleendian, int size) {
- lua_Unsigned n = 0;
- int i;
- for (i = 0; i < size; i++) {
- if (i >= SZINT) { /* will throw away a byte? */
- /* check for overflow: it is OK to throw away leading zeros for a
- positive number, leading ones for a negative number, and a
- leading zero byte to allow unsigned integers with a 1 in
- its "signal bit" */
- if (!((n & HIGHERBYTE1) == 0 || /* zeros for positive number */
- (n & HIGHERBYTE1) == HIGHERBYTE1 || /* ones for negative number */
- (i == size - 1 && (n & HIGHERBYTE) == 0))) /* leading zero */
- return 0; /* overflow */
+/*
+** Read and classify next option. 'size' is filled with option's size.
+*/
+static KOption getoption (Header *h, const char **fmt, int *size) {
+ int opt = *((*fmt)++);
+ *size = 0; /* default */
+ switch (opt) {
+ case 'b': *size = sizeof(char); return Kint;
+ case 'B': *size = sizeof(char); return Kuint;
+ case 'h': *size = sizeof(short); return Kint;
+ case 'H': *size = sizeof(short); return Kuint;
+ case 'l': *size = sizeof(long); return Kint;
+ case 'L': *size = sizeof(long); return Kuint;
+ case 'j': *size = sizeof(lua_Integer); return Kint;
+ case 'J': *size = sizeof(lua_Integer); return Kuint;
+ case 'T': *size = sizeof(size_t); return Kuint;
+ case 'f': *size = sizeof(float); return Kfloat;
+ case 'd': *size = sizeof(double); return Kfloat;
+ case 'n': *size = sizeof(lua_Number); return Kfloat;
+ case 'i': *size = getnumlimit(h, fmt, sizeof(int)); return Kint;
+ case 'I': *size = getnumlimit(h, fmt, sizeof(int)); return Kuint;
+ case 's': *size = getnumlimit(h, fmt, sizeof(size_t)); return Kstring;
+ case 'c': *size = getnum(fmt, 1); return Kchar;
+ case 'z': return Kzstr;
+ case 'x': *size = 1; return Kpadding;
+ case 'X': return Kpaddalign;
+ case ' ': return Knop;
+ case '\0': return Keof;
+ case '<': h->islittle = 1; return Knop;
+ case '>': h->islittle = 0; return Knop;
+ case '!': h->maxalign = getnumlimit(h, fmt, MAXALIGN); return Knop;
+ default: {
+ luaL_error(h->L, "invalid format option '%c'", opt);
+ return Knop;
}
- n <<= NB;
- n |= (lua_Unsigned)(unsigned char)buff[littleendian ? size - 1 - i : i];
- }
- if (size < SZINT) { /* need sign extension? */
- lua_Unsigned mask = (lua_Unsigned)1 << (size*NB - 1);
- *res = (lua_Integer)((n ^ mask) - mask); /* do sign extension */
}
- else
- *res = (lua_Integer)n;
- return 1;
}
-static int undumpint_l (lua_State *L) {
- lua_Integer res;
- size_t len;
- const char *s = luaL_checklstring(L, 1, &len);
- lua_Integer pos = posrelat(luaL_optinteger(L, 2, 1), len);
- int size = getintsize(L, 3);
- int endian = getendian(L, 4);
- luaL_argcheck(L, 1 <= pos && (size_t)pos + size - 1 <= len, 1,
- "string too short");
- if(undumpint(s + pos - 1, &res, endian, size))
- lua_pushinteger(L, res);
- else
- luaL_error(L, "result does not fit into a Lua integer");
- return 1;
+/*
+** Read, classify, and fill other details about the next option.
+** 'psize' is filled with option's size, 'notoalign' with its
+** alignment requirements.
+** Local variable 'size' gets the size to be aligned. (Kpadal option
+** always gets its full alignment, other options are limited by
+** the maximum alignment ('maxalign). Kchar option needs no aligment
+** despite its size.
+*/
+static KOption getdetails (Header *h, size_t totalsize,
+ const char **fmt, int *psize, int *ntoalign) {
+ int align;
+ KOption opt;
+ do {
+ opt = getoption(h, fmt, psize);
+ } while (opt == Knop); /* skip no-op options */
+ align = *psize; /* usually, alignment follows size */
+ if (opt == Kpaddalign) { /* 'X' gets alignment from following option */
+ if (getoption(h, fmt, &align) == Kchar || align == 0)
+ luaL_argerror(h->L, 1, "invalid next option for option 'X'");
+ }
+ if (align <= 1 || opt == Kchar) /* need no alignment? */
+ *ntoalign = 0;
+ else {
+ if (align > h->maxalign) /* enforce maximum alignment */
+ align = h->maxalign;
+ if ((align & (align - 1)) != 0) /* is 'align' not a power of 2? */
+ luaL_argerror(h->L, 1, "format asks for alignment not power of 2");
+ *ntoalign = (align - (int)(totalsize & (align - 1))) & (align - 1);
+ }
+ return opt;
}
-static void correctendianness (lua_State *L, char *b, int size, int endianarg) {
- int endian = getendian(L, endianarg);
- if (endian != nativeendian.little) { /* not native endianness? */
- int i = 0;
- while (i < --size) {
- char temp = b[i];
- b[i++] = b[size];
- b[size] = temp;
- }
+static void packint (luaL_Buffer *b, lua_Unsigned n,
+ int islittle, int size, lua_Unsigned mask) {
+ char *buff = luaL_prepbuffsize(b, size);
+ int i;
+ for (i = 0; i < size - 1; i++) {
+ buff[islittle ? i : size - 1 - i] = (n & MC);
+ n = (n >> NB) | mask;
}
+ buff[islittle ? i : size - 1 - i] = (n & MC);
+ luaL_addsize(b, size); /* add result to buffer */
}
-static int getfloatsize (lua_State *L, int arg) {
- const char *size = luaL_optstring(L, arg, "n");
- if (*size == 'n') return sizeof(lua_Number);
- luaL_argcheck(L, *size == 'd' || *size == 'f', arg,
- "size must be 'f'/'d'/'n'");
- return (*size == 'd' ? sizeof(double) : sizeof(float));
+/*
+** Copy 'size' bytes from 'src' to 'dest', correcting endianness if
+** given 'islittle' is different from native endianness.
+*/
+static void copywithendian (volatile char *dest, volatile const char *src,
+ int size, int islittle) {
+ if (islittle == nativeendian.little) {
+ while (size-- != 0)
+ *(dest++) = *(src++);
+ }
+ else {
+ dest += size - 1;
+ while (size-- != 0)
+ *(dest--) = *(src++);
+ }
}
-static int dumpfloat_l (lua_State *L) {
- float f; double d;
- char *pn; /* pointer to number */
- lua_Number n = luaL_checknumber(L, 1);
- int size = getfloatsize(L, 2);
- if (size == sizeof(lua_Number))
- pn = (char*)&n;
- else if (size == sizeof(float)) {
- f = (float)n;
- pn = (char*)&f;
- }
- else { /* native lua_Number may be neither float nor double */
- lua_assert(size == sizeof(double));
- d = (double)n;
- pn = (char*)&d;
+static int str_pack (lua_State *L) {
+ luaL_Buffer b;
+ Header h;
+ const char *fmt = luaL_checkstring(L, 1); /* format string */
+ int arg = 1; /* current argument to pack */
+ size_t totalsize = 0; /* accumulate total size of result */
+ initheader(L, &h);
+ lua_pushnil(L); /* mark to separate arguments from string buffer */
+ luaL_buffinit(L, &b);
+ for (;;) {
+ int size, ntoalign;
+ KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign);
+ totalsize += ntoalign + size;
+ while (ntoalign-- > 0) luaL_addchar(&b, '\0'); /* fill alignment */
+ arg++;
+ switch (opt) {
+ case Kint: { /* signed integers */
+ lua_Integer n = luaL_checkinteger(L, arg);
+ lua_Unsigned mask = (n < 0) ? HIGHERBYTE : 0; /* sign extension */
+ if (size < SZINT) { /* need overflow check? */
+ lua_Integer lim = (lua_Integer)1 << ((size * NB) - 1);
+ luaL_argcheck(L, -lim <= n && n < lim, arg, "integer overflow");
+ }
+ packint(&b, (lua_Unsigned)n, h.islittle, size, mask);
+ break;
+ }
+ case Kuint: { /* unsigned integers */
+ lua_Integer n = luaL_checkinteger(L, arg);
+ if (size < SZINT) /* need overflow check? */
+ luaL_argcheck(L, (lua_Unsigned)n < ((lua_Unsigned)1 << (size * NB)),
+ arg, "unsigned overflow");
+ packint(&b, (lua_Unsigned)n, h.islittle, size, 0);
+ break;
+ }
+ case Kfloat: { /* floating-point options */
+ volatile Ftypes u;
+ char *buff = luaL_prepbuffsize(&b, size);
+ lua_Number n = luaL_checknumber(L, arg); /* get argument */
+ if (size == sizeof(u.f)) u.f = (float)n; /* copy it into 'u' */
+ else if (size == sizeof(u.d)) u.d = (double)n;
+ else u.n = n;
+ /* move 'u' to final result, correcting endianness if needed */
+ copywithendian(buff, u.buff, size, h.islittle);
+ luaL_addsize(&b, size);
+ break;
+ }
+ case Kchar: { /* fixed-size string */
+ size_t len;
+ const char *s = luaL_checklstring(L, arg, &len);
+ luaL_argcheck(L, len == (size_t)size, arg, "wrong length");
+ luaL_addlstring(&b, s, size);
+ break;
+ }
+ case Kstring: { /* strings with length count */
+ size_t len;
+ const char *s = luaL_checklstring(L, arg, &len);
+ luaL_argcheck(L, size >= (int)sizeof(size_t) ||
+ len < ((size_t)1 << (size * NB)),
+ arg, "string length does not fit in given size");
+ packint(&b, (lua_Unsigned)len, h.islittle, size, 0); /* pack length */
+ luaL_addlstring(&b, s, len);
+ totalsize += len;
+ break;
+ }
+ case Kzstr: { /* zero-terminated string */
+ size_t len;
+ const char *s = luaL_checklstring(L, arg, &len);
+ luaL_argcheck(L, strlen(s) == len, arg, "string contains zeros");
+ luaL_addlstring(&b, s, len);
+ luaL_addchar(&b, '\0'); /* add zero at the end */
+ totalsize += len + 1;
+ break;
+ }
+ case Kpadding: luaL_addchar(&b, '\0'); /* go through */
+ case Kpaddalign: case Knop:
+ arg--; /* undo increment */
+ break;
+ case Keof: /* end of format */
+ luaL_pushresult(&b);
+ return 1;
+ }
}
- correctendianness(L, pn, size, 3);
- lua_pushlstring(L, pn, size);
- return 1;
}
-static int undumpfloat_l (lua_State *L) {
- lua_Number res;
- size_t len;
- const char *s = luaL_checklstring(L, 1, &len);
- lua_Integer pos = posrelat(luaL_optinteger(L, 2, 1), len);
- int size = getfloatsize(L, 3);
- luaL_argcheck(L, 1 <= pos && (size_t)pos + size - 1 <= len, 1,
- "string too short");
- if (size == sizeof(lua_Number)) {
- memcpy(&res, s + pos - 1, size);
- correctendianness(L, (char*)&res, size, 4);
+static lua_Integer unpackint (lua_State *L, const char *str,
+ int islittle, int size, int issigned) {
+ lua_Unsigned res = 0;
+ int i;
+ int limit = (size <= SZINT) ? size : SZINT;
+ for (i = limit - 1; i >= 0; i--) {
+ res <<= NB;
+ res |= (lua_Unsigned)(unsigned char)str[islittle ? i : size - 1 - i];
}
- else if (size == sizeof(float)) {
- float f;
- memcpy(&f, s + pos - 1, size);
- correctendianness(L, (char*)&f, size, 4);
- res = (lua_Number)f;
- }
- else { /* native lua_Number may be neither float nor double */
- double d;
- lua_assert(size == sizeof(double));
- memcpy(&d, s + pos - 1, size);
- correctendianness(L, (char*)&d, size, 4);
- res = (lua_Number)d;
+ if (size < SZINT) { /* real size smaller than lua_Integer? */
+ if (issigned) { /* needs sign extension? */
+ lua_Unsigned mask = (lua_Unsigned)1 << (size*NB - 1);
+ res = ((res ^ mask) - mask); /* do sign extension */
+ }
+ }
+ else { /* must check unread bytes */
+ int mask = (!issigned || (lua_Integer)res >= 0) ? 0 : MC;
+ for (i = limit; i < size; i++) {
+ if ((unsigned char)str[islittle ? i : size - 1 - i] != mask)
+ luaL_error(L, "%d-bit integer does not fit into Lua Integer", size);
+ }
+ }
+ return (lua_Integer)res;
+}
+
+
+static int str_unpack (lua_State *L) {
+ Header h;
+ const char *fmt = luaL_checkstring(L, 1);
+ size_t ld;
+ const char *data = luaL_checklstring(L, 2, &ld);
+ size_t pos = (size_t)posrelat(luaL_optinteger(L, 3, 1), ld) - 1;
+ int n = 0; /* number of results */
+ luaL_argcheck(L, pos <= ld, 3, "initial position out of string");
+ initheader(L, &h);
+ for (;;) {
+ int size, ntoalign;
+ KOption opt = getdetails(&h, pos, &fmt, &size, &ntoalign);
+ if ((size_t)ntoalign + size > ~pos || pos + ntoalign + size > ld)
+ luaL_argerror(L, 2, "data string too short");
+ pos += ntoalign;
+ /* stack space for item + next position */
+ luaL_checkstack(L, 2, "too many results");
+ n++;
+ switch (opt) {
+ case Kint:
+ case Kuint: {
+ lua_Integer res = unpackint(L, data + pos, h.islittle, size,
+ (opt == Kint));
+ lua_pushinteger(L, res);
+ break;
+ }
+ case Kfloat: {
+ volatile Ftypes u;
+ lua_Number num;
+ copywithendian(u.buff, data + pos, size, h.islittle);
+ if (size == sizeof(u.f)) num = (lua_Number)u.f;
+ else if (size == sizeof(u.d)) num = (lua_Number)u.d;
+ else num = u.n;
+ lua_pushnumber(L, num);
+ break;
+ }
+ case Kchar: {
+ lua_pushlstring(L, data + pos, size);
+ break;
+ }
+ case Kstring: {
+ size_t len = (size_t)unpackint(L, data + pos, h.islittle, size, 0);
+ luaL_argcheck(L, pos + len + size <= ld, 2, "data string too short");
+ lua_pushlstring(L, data + pos + size, len);
+ pos += len;
+ break;
+ }
+ case Kzstr: {
+ size_t len = (int)strlen(data + pos);
+ lua_pushlstring(L, data + pos, len);
+ pos += len + 1; /* skip final '\0' */
+ break;
+ }
+ case Kpaddalign: case Kpadding: case Knop:
+ n--; /* undo increment */
+ break;
+ case Keof: /* end of format */
+ lua_pushinteger(L, pos + 1); /* next position */
+ return n;
+ }
+ pos += size;
}
- lua_pushnumber(L, res);
- return 1;
}
/* }====================================================== */
@@ -1176,10 +1355,8 @@ static const luaL_Reg strlib[] = {
{"reverse", str_reverse},
{"sub", str_sub},
{"upper", str_upper},
- {"dumpfloat", dumpfloat_l},
- {"dumpint", dumpint_l},
- {"undumpfloat", undumpfloat_l},
- {"undumpint", undumpint_l},
+ {"pack", str_pack},
+ {"unpack", str_unpack},
{NULL, NULL}
};
diff --git a/src/ltable.c b/src/ltable.c
index 6ba80e3b..f7b836d5 100644
--- a/src/ltable.c
+++ b/src/ltable.c
@@ -1,5 +1,5 @@
/*
-** $Id: ltable.c,v 2.93 2014/07/29 16:22:24 roberto Exp $
+** $Id: ltable.c,v 2.96 2014/10/17 16:28:21 roberto Exp $
** Lua tables (hash)
** See Copyright Notice in lua.h
*/
@@ -40,14 +40,19 @@
/*
-** Maximum size of array part (MAXASIZE) is 2^MAXBITS. (SIZEINT is the
-** minimum between size of int and size of LUA_INTEGER; array indices
-** are limited by both types.)
+** Maximum size of array part (MAXASIZE) is 2^MAXABITS. MAXABITS is
+** the largest integer such that MAXASIZE fits in an unsigned int.
*/
-#define SIZEINT \
- (sizeof(int) < sizeof(LUA_INTEGER) ? sizeof(int) : sizeof(LUA_INTEGER))
-#define MAXBITS cast_int(SIZEINT * CHAR_BIT - 2)
-#define MAXASIZE (1 << MAXBITS)
+#define MAXABITS cast_int(sizeof(int) * CHAR_BIT - 1)
+#define MAXASIZE (1u << MAXABITS)
+
+/*
+** Maximum size of hash part is 2^MAXHBITS. MAXHBITS is the largest
+** integer such that 2^MAXHBITS fits in a signed int. (Note that the
+** maximum number of elements in a table, 2^MAXABITS + 2^MAXHBITS, still
+** fits comfortably in an unsigned int.)
+*/
+#define MAXHBITS (MAXABITS - 1)
#define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t))))
@@ -139,29 +144,29 @@ static Node *mainposition (const Table *t, const TValue *key) {
/*
** returns the index for `key' if `key' is an appropriate key to live in
-** the array part of the table, -1 otherwise.
+** the array part of the table, 0 otherwise.
*/
-static int arrayindex (const TValue *key) {
+static unsigned int arrayindex (const TValue *key) {
if (ttisinteger(key)) {
lua_Integer k = ivalue(key);
- if (0 < k && k <= MAXASIZE) /* is `key' an appropriate array index? */
- return cast_int(k);
+ if (0 < k && (lua_Unsigned)k <= MAXASIZE)
+ return cast(unsigned int, k); /* 'key' is an appropriate array index */
}
- return -1; /* `key' did not match some condition */
+ return 0; /* `key' did not match some condition */
}
/*
** returns the index of a `key' for table traversals. First goes all
** elements in the array part, then elements in the hash part. The
-** beginning of a traversal is signaled by -1.
+** beginning of a traversal is signaled by 0.
*/
-static int findindex (lua_State *L, Table *t, StkId key) {
- int i;
- if (ttisnil(key)) return -1; /* first iteration */
+static unsigned int findindex (lua_State *L, Table *t, StkId key) {
+ unsigned int i;
+ if (ttisnil(key)) return 0; /* first iteration */
i = arrayindex(key);
- if (0 < i && i <= t->sizearray) /* is `key' inside array part? */
- return i-1; /* yes; that's the index (corrected to C) */
+ if (i != 0 && i <= t->sizearray) /* is `key' inside array part? */
+ return i; /* yes; that's the index */
else {
int nx;
Node *n = mainposition(t, key);
@@ -172,11 +177,11 @@ static int findindex (lua_State *L, Table *t, StkId key) {
deadvalue(gkey(n)) == gcvalue(key))) {
i = cast_int(n - gnode(t, 0)); /* key index in hash table */
/* hash elements are numbered after array ones */
- return i + t->sizearray;
+ return (i + 1) + t->sizearray;
}
nx = gnext(n);
if (nx == 0)
- luaG_runerror(L, "invalid key to " LUA_QL("next")); /* key not found */
+ luaG_runerror(L, "invalid key to 'next'"); /* key not found */
else n += nx;
}
}
@@ -184,15 +189,15 @@ static int findindex (lua_State *L, Table *t, StkId key) {
int luaH_next (lua_State *L, Table *t, StkId key) {
- int i = findindex(L, t, key); /* find original element */
- for (i++; i < t->sizearray; i++) { /* try first array part */
+ unsigned int i = findindex(L, t, key); /* find original element */
+ for (; i < t->sizearray; i++) { /* try first array part */
if (!ttisnil(&t->array[i])) { /* a non-nil value? */
setivalue(key, i + 1);
setobj2s(L, key+1, &t->array[i]);
return 1;
}
}
- for (i -= t->sizearray; i < sizenode(t); i++) { /* then hash part */
+ for (i -= t->sizearray; cast_int(i) < sizenode(t); i++) { /* hash part */
if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */
setobj2s(L, key, gkey(gnode(t, i)));
setobj2s(L, key+1, gval(gnode(t, i)));
@@ -209,19 +214,24 @@ int luaH_next (lua_State *L, Table *t, StkId key) {
** ==============================================================
*/
-
-static int computesizes (int nums[], int *narray) {
+/*
+** Compute the optimal size for the array part of table 't'. 'nums' is a
+** "count array" where 'nums[i]' is the number of integers in the table
+** between 2^(i - 1) + 1 and 2^i. Put in '*narray' the optimal size, and
+** return the number of elements that will go to that part.
+*/
+static unsigned int computesizes (unsigned int nums[], unsigned int *narray) {
int i;
- int twotoi; /* 2^i */
- int a = 0; /* number of elements smaller than 2^i */
- int na = 0; /* number of elements to go to array part */
- int n = 0; /* optimal size for array part */
+ unsigned int twotoi; /* 2^i */
+ unsigned int a = 0; /* number of elements smaller than 2^i */
+ unsigned int na = 0; /* number of elements to go to array part */
+ unsigned int n = 0; /* optimal size for array part */
for (i = 0, twotoi = 1; twotoi/2 < *narray; i++, twotoi *= 2) {
if (nums[i] > 0) {
a += nums[i];
if (a > twotoi/2) { /* more than half elements present? */
n = twotoi; /* optimal size (till now) */
- na = a; /* all elements smaller than n will go to array part */
+ na = a; /* all elements up to 'n' will go to array part */
}
}
if (a == *narray) break; /* all elements already counted */
@@ -232,9 +242,9 @@ static int computesizes (int nums[], int *narray) {
}
-static int countint (const TValue *key, int *nums) {
- int k = arrayindex(key);
- if (k > 0) { /* is `key' an appropriate array index? */
+static int countint (const TValue *key, unsigned int *nums) {
+ unsigned int k = arrayindex(key);
+ if (k != 0) { /* is `key' an appropriate array index? */
nums[luaO_ceillog2(k)]++; /* count as such */
return 1;
}
@@ -243,20 +253,21 @@ static int countint (const TValue *key, int *nums) {
}
-static int numusearray (const Table *t, int *nums) {
+static unsigned int numusearray (const Table *t, unsigned int *nums) {
int lg;
- int ttlg; /* 2^lg */
- int ause = 0; /* summation of `nums' */
- int i = 1; /* count to traverse all array keys */
- for (lg=0, ttlg=1; lg<=MAXBITS; lg++, ttlg*=2) { /* for each slice */
- int lc = 0; /* counter */
- int lim = ttlg;
+ unsigned int ttlg; /* 2^lg */
+ unsigned int ause = 0; /* summation of `nums' */
+ unsigned int i = 1; /* count to traverse all array keys */
+ /* traverse each slice */
+ for (lg = 0, ttlg = 1; lg <= MAXABITS; lg++, ttlg *= 2) {
+ unsigned int lc = 0; /* counter */
+ unsigned int lim = ttlg;
if (lim > t->sizearray) {
lim = t->sizearray; /* adjust upper limit */
if (i > lim)
break; /* no more elements to count */
}
- /* count elements in range (2^(lg-1), 2^lg] */
+ /* count elements in range (2^(lg - 1), 2^lg] */
for (; i <= lim; i++) {
if (!ttisnil(&t->array[i-1]))
lc++;
@@ -268,9 +279,10 @@ static int numusearray (const Table *t, int *nums) {
}
-static int numusehash (const Table *t, int *nums, int *pnasize) {
+static int numusehash (const Table *t, unsigned int *nums,
+ unsigned int *pnasize) {
int totaluse = 0; /* total number of elements */
- int ause = 0; /* summation of `nums' */
+ int ause = 0; /* elements added to 'nums' (can go to array part) */
int i = sizenode(t);
while (i--) {
Node *n = &t->node[i];
@@ -284,8 +296,8 @@ static int numusehash (const Table *t, int *nums, int *pnasize) {
}
-static void setarrayvector (lua_State *L, Table *t, int size) {
- int i;
+static void setarrayvector (lua_State *L, Table *t, unsigned int size) {
+ unsigned int i;
luaM_reallocvector(L, t->array, t->sizearray, size, TValue);
for (i=t->sizearray; i<size; i++)
setnilvalue(&t->array[i]);
@@ -293,7 +305,7 @@ static void setarrayvector (lua_State *L, Table *t, int size) {
}
-static void setnodevector (lua_State *L, Table *t, int size) {
+static void setnodevector (lua_State *L, Table *t, unsigned int size) {
int lsize;
if (size == 0) { /* no elements to hash part? */
t->node = cast(Node *, dummynode); /* use common `dummynode' */
@@ -302,11 +314,11 @@ static void setnodevector (lua_State *L, Table *t, int size) {
else {
int i;
lsize = luaO_ceillog2(size);
- if (lsize > MAXBITS)
+ if (lsize > MAXHBITS)
luaG_runerror(L, "table overflow");
size = twoto(lsize);
t->node = luaM_newvector(L, size, Node);
- for (i=0; i<size; i++) {
+ for (i = 0; i < (int)size; i++) {
Node *n = gnode(t, i);
gnext(n) = 0;
setnilvalue(wgkey(n));
@@ -318,9 +330,11 @@ static void setnodevector (lua_State *L, Table *t, int size) {
}
-void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize) {
- int i;
- int oldasize = t->sizearray;
+void luaH_resize (lua_State *L, Table *t, unsigned int nasize,
+ unsigned int nhsize) {
+ unsigned int i;
+ int j;
+ unsigned int oldasize = t->sizearray;
int oldhsize = t->lsizenode;
Node *nold = t->node; /* save old hash ... */
if (nasize > oldasize) /* array part must grow? */
@@ -338,8 +352,8 @@ void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize) {
luaM_reallocvector(L, t->array, oldasize, nasize, TValue);
}
/* re-insert elements from hash part */
- for (i = twoto(oldhsize) - 1; i >= 0; i--) {
- Node *old = nold+i;
+ for (j = twoto(oldhsize) - 1; j >= 0; j--) {
+ Node *old = nold + j;
if (!ttisnil(gval(old))) {
/* doesn't need barrier/invalidate cache, as entry was
already present in the table */
@@ -351,18 +365,20 @@ void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize) {
}
-void luaH_resizearray (lua_State *L, Table *t, int nasize) {
+void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize) {
int nsize = isdummy(t->node) ? 0 : sizenode(t);
luaH_resize(L, t, nasize, nsize);
}
-
+/*
+** nums[i] = number of keys 'k' where 2^(i - 1) < k <= 2^i
+*/
static void rehash (lua_State *L, Table *t, const TValue *ek) {
- int nasize, na;
- int nums[MAXBITS+1]; /* nums[i] = number of keys with 2^(i-1) < k <= 2^i */
+ unsigned int nasize, na;
+ unsigned int nums[MAXABITS + 1];
int i;
int totaluse;
- for (i=0; i<=MAXBITS; i++) nums[i] = 0; /* reset counts */
+ for (i = 0; i <= MAXABITS; i++) nums[i] = 0; /* reset counts */
nasize = numusearray(t, nums); /* count keys in array part */
totaluse = nasize; /* all those keys are integer keys */
totaluse += numusehash(t, nums, &nasize); /* count keys in hash part */
@@ -440,7 +456,7 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
Node *f = getfreepos(t); /* get a free place */
if (f == NULL) { /* cannot find a free place? */
rehash(L, t, key); /* grow table */
- /* whatever called 'newkey' take care of TM cache and GC barrier */
+ /* whatever called 'newkey' takes care of TM cache and GC barrier */
return luaH_set(L, t, key); /* insert key into grown table */
}
lua_assert(!isdummy(f));
@@ -478,7 +494,7 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
*/
const TValue *luaH_getint (Table *t, lua_Integer key) {
/* (1 <= key && key <= t->sizearray) */
- if (l_castS2U(key - 1) < cast(unsigned int, t->sizearray))
+ if (l_castS2U(key - 1) < t->sizearray)
return &t->array[key - 1];
else {
Node *n = hashint(t, key);
diff --git a/src/ltable.h b/src/ltable.h
index 45ff45f2..53d25511 100644
--- a/src/ltable.h
+++ b/src/ltable.h
@@ -1,5 +1,5 @@
/*
-** $Id: ltable.h,v 2.19 2014/07/29 16:22:24 roberto Exp $
+** $Id: ltable.h,v 2.20 2014/09/04 18:15:29 roberto Exp $
** Lua tables (hash)
** See Copyright Notice in lua.h
*/
@@ -30,14 +30,15 @@
LUAI_FUNC const TValue *luaH_getint (Table *t, lua_Integer key);
LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key,
- TValue *value);
+ TValue *value);
LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key);
LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key);
LUAI_FUNC TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key);
LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key);
LUAI_FUNC Table *luaH_new (lua_State *L);
-LUAI_FUNC void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize);
-LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, int nasize);
+LUAI_FUNC void luaH_resize (lua_State *L, Table *t, unsigned int nasize,
+ unsigned int nhsize);
+LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize);
LUAI_FUNC void luaH_free (lua_State *L, Table *t);
LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key);
LUAI_FUNC int luaH_getn (Table *t);
diff --git a/src/ltablib.c b/src/ltablib.c
index bc353866..908acfbc 100644
--- a/src/ltablib.c
+++ b/src/ltablib.c
@@ -1,5 +1,5 @@
/*
-** $Id: ltablib.c,v 1.73 2014/07/29 16:01:00 roberto Exp $
+** $Id: ltablib.c,v 1.77 2014/10/17 16:28:21 roberto Exp $
** Library for Table Manipulation
** See Copyright Notice in lua.h
*/
@@ -28,41 +28,25 @@ typedef struct {
/*
-** equivalent to 'lua_rawgeti', but not raw
-*/
-static int geti (lua_State *L, int idx, lua_Integer n) {
- lua_pushinteger(L, n);
- return lua_gettable(L, idx); /* assume 'idx' is not negative */
-}
-
-
-/*
-** equivalent to 'lua_rawseti', but not raw
-*/
-static void seti (lua_State *L, int idx, lua_Integer n) {
- lua_pushinteger(L, n);
- lua_rotate(L, -2, 1); /* exchange key and value */
- lua_settable(L, idx); /* assume 'idx' is not negative */
-}
-
-
-/*
** Check that 'arg' has a table and set access functions in 'ta' to raw
** or non-raw according to the presence of corresponding metamethods.
*/
static void checktab (lua_State *L, int arg, TabA *ta) {
- luaL_checktype(L, arg, LUA_TTABLE);
- if (!lua_getmetatable(L, arg)) { /* fast track */
- ta->geti = lua_rawgeti; /* with no metatable, all is raw */
- ta->seti = lua_rawseti;
- }
- else {
+ ta->geti = NULL; ta->seti = NULL;
+ if (lua_getmetatable(L, arg)) {
lua_pushliteral(L, "__index"); /* 'index' metamethod */
- ta->geti = (lua_rawget(L, -2) == LUA_TNIL) ? lua_rawgeti : geti;
+ if (lua_rawget(L, -2) != LUA_TNIL)
+ ta->geti = lua_geti;
lua_pushliteral(L, "__newindex"); /* 'newindex' metamethod */
- ta->seti = (lua_rawget(L, -3) == LUA_TNIL) ? lua_rawseti : seti;
+ if (lua_rawget(L, -3) != LUA_TNIL)
+ ta->seti = lua_seti;
lua_pop(L, 3); /* pop metatable plus both metamethods */
}
+ if (ta->geti == NULL || ta->seti == NULL) {
+ luaL_checktype(L, arg, LUA_TTABLE); /* must be table for raw methods */
+ if (ta->geti == NULL) ta->geti = lua_rawgeti;
+ if (ta->seti == NULL) ta->seti = lua_rawseti;
+ }
}
@@ -107,7 +91,7 @@ static int tinsert (lua_State *L) {
break;
}
default: {
- return luaL_error(L, "wrong number of arguments to " LUA_QL("insert"));
+ return luaL_error(L, "wrong number of arguments to 'insert'");
}
}
(*ta.seti)(L, 1, pos); /* t[pos] = v */
@@ -132,24 +116,22 @@ static int tremove (lua_State *L) {
}
-static int tcopy (lua_State *L) {
+static int tmove (lua_State *L) {
TabA ta;
lua_Integer f = luaL_checkinteger(L, 2);
lua_Integer e = luaL_checkinteger(L, 3);
- lua_Integer t;
- int tt = 4; /* destination table */
+ lua_Integer t = luaL_checkinteger(L, 4);
+ int tt = !lua_isnoneornil(L, 5) ? 5 : 1; /* destination table */
/* the following restriction avoids several problems with overflows */
luaL_argcheck(L, f > 0, 2, "initial position must be positive");
- if (lua_istable(L, tt))
- t = luaL_checkinteger(L, 5);
- else {
- tt = 1; /* destination table is equal to source */
- t = luaL_checkinteger(L, 4);
- }
if (e >= f) { /* otherwise, nothing to move */
lua_Integer n, i;
- ta.geti = (!luaL_getmetafield(L, 1, "__index")) ? lua_rawgeti : geti;
- ta.seti = (!luaL_getmetafield(L, tt, "__newindex")) ? lua_rawseti : seti;
+ ta.geti = (luaL_getmetafield(L, 1, "__index") == LUA_TNIL)
+ ? (luaL_checktype(L, 1, LUA_TTABLE), lua_rawgeti)
+ : lua_geti;
+ ta.seti = (luaL_getmetafield(L, tt, "__newindex") == LUA_TNIL)
+ ? (luaL_checktype(L, tt, LUA_TTABLE), lua_rawseti)
+ : lua_seti;
n = e - f + 1; /* number of elements to move */
if (t > f) {
for (i = n - 1; i >= 0; i--) {
@@ -172,8 +154,8 @@ static int tcopy (lua_State *L) {
static void addfield (lua_State *L, luaL_Buffer *b, TabA *ta, lua_Integer i) {
(*ta->geti)(L, 1, i);
if (!lua_isstring(L, -1))
- luaL_error(L, "invalid value (%s) at index %d in table for "
- LUA_QL("concat"), luaL_typename(L, -1), i);
+ luaL_error(L, "invalid value (%s) at index %d in table for 'concat'",
+ luaL_typename(L, -1), i);
luaL_addvalue(b);
}
@@ -355,7 +337,7 @@ static const luaL_Reg tab_funcs[] = {
{"pack", pack},
{"unpack", unpack},
{"remove", tremove},
- {"copy", tcopy},
+ {"move", tmove},
{"sort", sort},
{NULL, NULL}
};
diff --git a/src/lua.c b/src/lua.c
index f46f9fb3..b23bb005 100644
--- a/src/lua.c
+++ b/src/lua.c
@@ -1,5 +1,5 @@
/*
-** $Id: lua.c,v 1.213 2014/06/30 19:48:08 roberto Exp $
+** $Id: lua.c,v 1.217 2014/10/20 22:21:05 roberto Exp $
** Lua stand-alone interpreter
** See Copyright Notice in lua.h
*/
@@ -134,9 +134,9 @@ static void print_usage (const char *badoption) {
luai_writestringerror(
"usage: %s [options] [script [args]]\n"
"Available options are:\n"
- " -e stat execute string " LUA_QL("stat") "\n"
- " -i enter interactive mode after executing " LUA_QL("script") "\n"
- " -l name require library " LUA_QL("name") "\n"
+ " -e stat execute string 'stat'\n"
+ " -i enter interactive mode after executing 'script'\n"
+ " -l name require library 'name'\n"
" -v show version information\n"
" -E ignore environment variables\n"
" -- stop handling options\n"
@@ -158,34 +158,34 @@ static void l_message (const char *pname, const char *msg) {
/*
** Check whether 'status' is not OK and, if so, prints the error
-** message on the top of the stack. Because this function can be called
-** unprotected, it only accepts actual strings as error messages. (A
-** coercion could raise a memory error.)
+** message on the top of the stack. It assumes that the error object
+** is a string, as it was either generated by Lua or by 'msghandler'.
*/
static int report (lua_State *L, int status) {
if (status != LUA_OK) {
- const char *msg = (lua_type(L, -1) == LUA_TSTRING) ? lua_tostring(L, -1)
- : NULL;
- if (msg == NULL) msg = "(error object is not a string)";
+ const char *msg = lua_tostring(L, -1);
l_message(progname, msg);
- lua_pop(L, 1);
+ lua_pop(L, 1); /* remove message */
}
return status;
}
/*
-** Message handler to be used to run all chunks
+** Message handler used to run all chunks
*/
static int msghandler (lua_State *L) {
const char *msg = lua_tostring(L, 1);
- if (msg) /* is error object a string? */
- luaL_traceback(L, L, msg, 1); /* use standard traceback */
- else if (!lua_isnoneornil(L, 1)) { /* non-string error object? */
- if (!luaL_callmeta(L, 1, "__tostring")) /* try its 'tostring' metamethod */
- lua_pushliteral(L, "(no error message)");
- } /* else no error object, does nothing */
- return 1;
+ if (msg == NULL) { /* is error object not a string? */
+ if (luaL_callmeta(L, 1, "__tostring") && /* does it have a metamethod */
+ lua_type(L, -1) == LUA_TSTRING) /* that produces a string? */
+ return 1; /* that is the message */
+ else
+ msg = lua_pushfstring(L, "(error object is a %s value)",
+ luaL_typename(L, 1));
+ }
+ luaL_traceback(L, L, msg, 1); /* append a standard traceback */
+ return 1; /* return the traceback */
}
@@ -389,9 +389,8 @@ static void l_print (lua_State *L) {
lua_getglobal(L, "print");
lua_insert(L, 1);
if (lua_pcall(L, n, 0, 0) != LUA_OK)
- l_message(progname, lua_pushfstring(L,
- "error calling " LUA_QL("print") " (%s)",
- lua_tostring(L, -1)));
+ l_message(progname, lua_pushfstring(L, "error calling 'print' (%s)",
+ lua_tostring(L, -1)));
}
}
diff --git a/src/lua.h b/src/lua.h
index 81aaaebf..c1de153d 100644
--- a/src/lua.h
+++ b/src/lua.h
@@ -1,5 +1,5 @@
/*
-** $Id: lua.h,v 1.312 2014/07/31 13:44:30 roberto Exp $
+** $Id: lua.h,v 1.319 2014/10/17 19:17:55 roberto Exp $
** Lua - A Scripting Language
** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
** See Copyright Notice at the end of this file
@@ -19,7 +19,7 @@
#define LUA_VERSION_MAJOR "5"
#define LUA_VERSION_MINOR "3"
#define LUA_VERSION_NUM 503
-#define LUA_VERSION_RELEASE "0 (alpha)"
+#define LUA_VERSION_RELEASE "0 (beta)"
#define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
#define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE
@@ -94,7 +94,7 @@ typedef LUA_INTEGER lua_Integer;
typedef LUA_UNSIGNED lua_Unsigned;
/* type for continuation-function contexts */
-typedef LUA_CTXT lua_Ctx;
+typedef LUA_KCONTEXT lua_KContext;
/*
@@ -105,7 +105,7 @@ typedef int (*lua_CFunction) (lua_State *L);
/*
** Type for continuation functions
*/
-typedef int (*lua_KFunction) (lua_State *L, int status, lua_Ctx ctx);
+typedef int (*lua_KFunction) (lua_State *L, int status, lua_KContext ctx);
/*
@@ -239,6 +239,7 @@ LUA_API int (lua_pushthread) (lua_State *L);
LUA_API int (lua_getglobal) (lua_State *L, const char *var);
LUA_API int (lua_gettable) (lua_State *L, int idx);
LUA_API int (lua_getfield) (lua_State *L, int idx, const char *k);
+LUA_API int (lua_geti) (lua_State *L, int idx, lua_Integer n);
LUA_API int (lua_rawget) (lua_State *L, int idx);
LUA_API int (lua_rawgeti) (lua_State *L, int idx, lua_Integer n);
LUA_API int (lua_rawgetp) (lua_State *L, int idx, const void *p);
@@ -255,6 +256,7 @@ LUA_API int (lua_getuservalue) (lua_State *L, int idx);
LUA_API void (lua_setglobal) (lua_State *L, const char *var);
LUA_API void (lua_settable) (lua_State *L, int idx);
LUA_API void (lua_setfield) (lua_State *L, int idx, const char *k);
+LUA_API void (lua_seti) (lua_State *L, int idx, lua_Integer n);
LUA_API void (lua_rawset) (lua_State *L, int idx);
LUA_API void (lua_rawseti) (lua_State *L, int idx, lua_Integer n);
LUA_API void (lua_rawsetp) (lua_State *L, int idx, const void *p);
@@ -265,12 +267,12 @@ LUA_API void (lua_setuservalue) (lua_State *L, int idx);
/*
** 'load' and 'call' functions (load and run Lua code)
*/
-LUA_API void (lua_callk) (lua_State *L, int nargs, int nresults, lua_Ctx ctx,
- lua_KFunction k);
+LUA_API void (lua_callk) (lua_State *L, int nargs, int nresults,
+ lua_KContext ctx, lua_KFunction k);
#define lua_call(L,n,r) lua_callk(L, (n), (r), 0, NULL)
LUA_API int (lua_pcallk) (lua_State *L, int nargs, int nresults, int errfunc,
- lua_Ctx ctx, lua_KFunction k);
+ lua_KContext ctx, lua_KFunction k);
#define lua_pcall(L,n,r,f) lua_pcallk(L, (n), (r), (f), 0, NULL)
LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt,
@@ -283,7 +285,7 @@ LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data, int strip);
/*
** coroutine functions
*/
-LUA_API int (lua_yieldk) (lua_State *L, int nresults, lua_Ctx ctx,
+LUA_API int (lua_yieldk) (lua_State *L, int nresults, lua_KContext ctx,
lua_KFunction k);
#define lua_yield(L,n) lua_yieldk(L, (n), 0, NULL)
LUA_API int (lua_resume) (lua_State *L, lua_State *from, int narg);
@@ -319,7 +321,7 @@ LUA_API int (lua_next) (lua_State *L, int idx);
LUA_API void (lua_concat) (lua_State *L, int n);
LUA_API void (lua_len) (lua_State *L, int idx);
-LUA_API size_t (lua_strtonum) (lua_State *L, const char *s);
+LUA_API size_t (lua_stringtonumber) (lua_State *L, const char *s);
LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud);
LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud);
@@ -377,7 +379,7 @@ LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud);
** compatibility macros for unsigned conversions
** ===============================================================
*/
-#if defined(LUA_COMPAT_APIUNSIGNED)
+#if defined(LUA_COMPAT_APIINTCASTS)
#define lua_pushunsigned(L,n) lua_pushinteger(L, (lua_Integer)(n))
#define lua_tounsignedx(L,i,is) ((lua_Integer)lua_tointegerx(L,i,is))
diff --git a/src/luaconf.h b/src/luaconf.h
index d3db9267..ae395769 100644
--- a/src/luaconf.h
+++ b/src/luaconf.h
@@ -1,5 +1,5 @@
/*
-** $Id: luaconf.h,v 1.212 2014/07/24 19:33:29 roberto Exp $
+** $Id: luaconf.h,v 1.220 2014/10/21 14:38:46 roberto Exp $
** Configuration file for Lua
** See Copyright Notice in lua.h
*/
@@ -8,9 +8,6 @@
#ifndef lconfig_h
#define lconfig_h
-#include <limits.h>
-#include <stddef.h>
-
/*
** ==================================================================
@@ -20,20 +17,42 @@
/*
-** ===================================================================
+** {==================================================================
@@ LUA_INT_INT / LUA_INT_LONG / LUA_INT_LONGLONG defines type for
-@@ Lua integers;
+@@ Lua integers; you must define one of them.
@@ LUA_REAL_FLOAT / LUA_REAL_DOUBLE / LUA_REAL_LONGDOUBLE defines
-@@ type for Lua floats.
+@@ type for Lua floats. You must define one of them.
+**
+** These definitions set the numeric types for Lua. Lua should work fine
+** with any mix of these previous options. The usual configurations
+** are 64-bit integers and floats (the default) and 32-bit integers and
+** floats (Small Lua, for restricted platforms).
**
-** These definitions set the numeric types for Lua. Lua should work
-** fine with any mix of these previous options.
-** The usual configurations are 64-bit integers and floats (the default)
-** and 32-bit integers and floats (Small Lua, for restricted hardware).
+** Note that C compilers not compliant with C99 may not have
+** support for 'long long'. In that case, you should not use option
+** 'LUA_INT_LONGLONG'; use instead option 'LUA_32BITS' for Small Lua
+** (see below), or LUA_INT_LONG plus LUA_REAL_DOUBLE for an interpreter
+** with 32-bit integers and double floating-point numbers.
** =====================================================================
*/
+
+/*
+** Just uncomment the next line for Small Lua; you can also define
+** LUA_32BITS in the make file, but changing here you ensure that
+** all software connected to Lua will be compiled with the same
+** configuration.
+*/
+/* #define LUA_32BITS */
+
+#if !defined(LUA_32BITS) && !defined(LUA_ANSI)
#define LUA_INT_LONGLONG
#define LUA_REAL_DOUBLE
+#else /* Lua 32 bits */
+#define LUA_INT_LONG
+#define LUA_REAL_FLOAT
+#endif
+
+/* }================================================================== */
/*
@@ -51,6 +70,7 @@
#endif
#if defined(LUA_WIN)
+#define _CRT_SECURE_NO_WARNINGS /* avoid warnings about ANSI C functions */
#define LUA_DL_DLL
#define LUA_USE_AFORMAT /* assume 'printf' handles 'aA' specifiers */
#endif
@@ -91,6 +111,9 @@
+#include <limits.h>
+#include <stddef.h>
+
/*
@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for
@@ Lua libraries.
@@ -220,7 +243,8 @@
/*
@@ LUA_QL describes how error messages quote program elements.
-** CHANGE it if you want a different appearance.
+** Lua does not use these macros anymore; they are here for
+** compatibility only.
*/
#define LUA_QL(x) "'" x "'"
#define LUA_QS LUA_QL("%s")
@@ -236,14 +260,10 @@
/*
@@ luai_writestring/luai_writeline define how 'print' prints its results.
-** They are only used in libraries and the stand-alone program. (The #if
-** avoids including 'stdio.h' everywhere.)
+** They are only used in libraries and the stand-alone program.
*/
-#if defined(LUA_LIB) || defined(lua_c)
-#include <stdio.h>
#define luai_writestring(s,l) fwrite((s), sizeof(char), (l), stdout)
#define luai_writeline() (luai_writestring("\n", 1), fflush(stdout))
-#endif
/*
@@ luai_writestringerror defines how to print error messages.
@@ -263,19 +283,20 @@
/*
-@@ LUA_CTXT is the type of the context ('ctx') for continuation functions.
-@@ It must be a numerical type; Lua will use 'intptr_t' if available.
+@@ LUA_KCONTEXT is the type of the context ('ctx') for continuation
+@@ functions. It must be a numerical type; Lua will use 'intptr_t' if
+@@ available.
*/
#if defined (LUA_USE_C99)
#include <stdint.h>
#if defined (INTPTR_MAX) /* even in C99 this type is optional */
-#define LUA_CTXT intptr_t
+#define LUA_KCONTEXT intptr_t
#endif
#endif
-#if !defined(LUA_CTXT)
+#if !defined(LUA_KCONTEXT)
/* default definition (the nearest thing to 'intptr_t' in C89) */
-#define LUA_CTXT ptrdiff_t
+#define LUA_KCONTEXT ptrdiff_t
#endif
@@ -305,15 +326,16 @@
#define LUA_COMPAT_BITLIB
/*
-@@ LUA_COMPAT_IPAIRS controls the effectivness of the __ipairs metamethod.
+@@ LUA_COMPAT_IPAIRS controls the effectiveness of the __ipairs metamethod.
*/
#define LUA_COMPAT_IPAIRS
/*
-@@ LUA_COMPAT_APIUNSIGNED controls the presence of macros for
-** manipulating unsigned integers (lua_pushunsigned, lua_tounsigned, etc.)
+@@ LUA_COMPAT_APIINTCASTS controls the presence of macros for
+** manipulating other integer types (lua_pushunsigned, lua_tounsigned,
+** luaL_checkint, luaL_checklong, etc.)
*/
-#define LUA_COMPAT_APIUNSIGNED
+#define LUA_COMPAT_APIINTCASTS
/*
@@ -525,16 +547,11 @@
#endif /* } */
-#if defined(LUA_ANSI)
-/* C89 does not support 'opf' variants for math functions */
+#if !defined(LUA_USE_C99)
+/* 'strtof' and 'opf' variants for math functions are C99 */
#undef l_mathop
-#define l_mathop(op) (lua_Number)op
-#endif
-
-
-#if defined(LUA_ANSI) || defined(_WIN32)
-/* C89 and Windows do not support 'strtof'... */
#undef lua_str2number
+#define l_mathop(op) (lua_Number)op
#define lua_str2number(s,p) ((lua_Number)strtod((s), (p)))
#endif
@@ -652,6 +669,10 @@
#else
+#if !defined(LLONG_MAX)
+#error "Compiler does not support 'long long'. See file 'luaconf.h' line 24"
+#endif
+
#define LUA_INTEGER long long
#define LUA_INTEGER_FRMLEN "ll"
diff --git a/src/lutf8lib.c b/src/lutf8lib.c
index 1e848def..de139296 100644
--- a/src/lutf8lib.c
+++ b/src/lutf8lib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lutf8lib.c,v 1.10 2014/07/16 13:56:14 roberto Exp $
+** $Id: lutf8lib.c,v 1.12 2014/10/15 14:31:10 roberto Exp $
** Standard library for UTF-8 manipulation
** See Copyright Notice in lua.h
*/
@@ -123,9 +123,9 @@ static int codepoint (lua_State *L) {
static void pushutfchar (lua_State *L, int arg) {
- int code = luaL_checkint(L, arg);
+ lua_Integer code = luaL_checkinteger(L, arg);
luaL_argcheck(L, 0 <= code && code <= MAXUNICODE, arg, "value out of range");
- lua_pushfstring(L, "%U", code);
+ lua_pushfstring(L, "%U", (long)code);
}
@@ -157,7 +157,7 @@ static int utfchar (lua_State *L) {
static int byteoffset (lua_State *L) {
size_t len;
const char *s = luaL_checklstring(L, 1, &len);
- int n = luaL_checkint(L, 2);
+ lua_Integer n = luaL_checkinteger(L, 2);
lua_Integer posi = (n >= 0) ? 1 : len + 1;
posi = u_posrelat(luaL_optinteger(L, 3, posi), len);
luaL_argcheck(L, 1 <= posi && --posi <= (lua_Integer)len, 3,
@@ -239,7 +239,7 @@ static struct luaL_Reg funcs[] = {
{"len", utflen},
{"codes", iter_codes},
/* placeholders */
- {"charpatt", NULL},
+ {"charpattern", NULL},
{NULL, NULL}
};
@@ -247,7 +247,7 @@ static struct luaL_Reg funcs[] = {
LUAMOD_API int luaopen_utf8 (lua_State *L) {
luaL_newlib(L, funcs);
lua_pushliteral(L, UTF8PATT);
- lua_setfield(L, -2, "charpatt");
+ lua_setfield(L, -2, "charpattern");
return 1;
}
diff --git a/src/lvm.c b/src/lvm.c
index 51f14292..c6c706db 100644
--- a/src/lvm.c
+++ b/src/lvm.c
@@ -1,5 +1,5 @@
/*
-** $Id: lvm.c,v 2.222 2014/07/30 14:42:44 roberto Exp $
+** $Id: lvm.c,v 2.224 2014/10/17 16:28:21 roberto Exp $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
@@ -1033,13 +1033,13 @@ void luaV_execute (lua_State *L) {
else { /* try making all values floats */
lua_Number ninit; lua_Number nlimit; lua_Number nstep;
if (!tonumber(plimit, &nlimit))
- luaG_runerror(L, LUA_QL("for") " limit must be a number");
+ luaG_runerror(L, "'for' limit must be a number");
setfltvalue(plimit, nlimit);
if (!tonumber(pstep, &nstep))
- luaG_runerror(L, LUA_QL("for") " step must be a number");
+ luaG_runerror(L, "'for' step must be a number");
setfltvalue(pstep, nstep);
if (!tonumber(init, &ninit))
- luaG_runerror(L, LUA_QL("for") " initial value must be a number");
+ luaG_runerror(L, "'for' initial value must be a number");
setfltvalue(init, luai_numsub(L, ninit, nstep));
}
ci->u.l.savedpc += GETARG_sBx(i);
@@ -1067,7 +1067,7 @@ void luaV_execute (lua_State *L) {
vmcase(OP_SETLIST,
int n = GETARG_B(i);
int c = GETARG_C(i);
- int last;
+ unsigned int last;
Table *h;
if (n == 0) n = cast_int(L->top - ra) - 1;
if (c == 0) {
diff --git a/src/lvm.h b/src/lvm.h
index 0f4667af..5c5e18c3 100644
--- a/src/lvm.h
+++ b/src/lvm.h
@@ -1,5 +1,5 @@
/*
-** $Id: lvm.h,v 2.33 2014/07/30 14:42:44 roberto Exp $
+** $Id: lvm.h,v 2.34 2014/08/01 17:24:02 roberto Exp $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
@@ -16,14 +16,14 @@
#if !defined(LUA_NOCVTN2S)
#define cvt2str(o) ttisnumber(o)
#else
-#define cvt2str(o) 0 /* no convertion from numbers to strings */
+#define cvt2str(o) 0 /* no conversion from numbers to strings */
#endif
#if !defined(LUA_NOCVTS2N)
#define cvt2num(o) ttisstring(o)
#else
-#define cvt2num(o) 0 /* no convertion from strings to numbers */
+#define cvt2num(o) 0 /* no conversion from strings to numbers */
#endif