summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLua Team <team@lua.org>2011-06-21 12:00:00 +0000
committerrepogen <>2011-06-21 12:00:00 +0000
commit16559ecd52698cfead11eca834903b686bf62d65 (patch)
treeadbd9d16fce451ea32713ab4ec21396abcd595f5 /src
parentd60cd73117443e4a9be4a58463850bd34088acf3 (diff)
downloadlua-github-16559ecd52698cfead11eca834903b686bf62d65.tar.gz
Lua 5.2.0-beta-rc25.2.0-beta-rc2
Diffstat (limited to 'src')
-rw-r--r--src/Makefile48
-rw-r--r--src/lauxlib.c13
-rw-r--r--src/lauxlib.h5
-rw-r--r--src/lbaselib.c21
-rw-r--r--src/lbitlib.c4
-rw-r--r--src/lctype.c45
-rw-r--r--src/lctype.h50
-rw-r--r--src/ldo.c27
-rw-r--r--src/liolib.c267
-rw-r--r--src/llex.c102
-rw-r--r--src/llex.h4
-rw-r--r--src/lobject.c22
-rw-r--r--src/loslib.c4
-rw-r--r--src/lparser.c47
-rw-r--r--src/lparser.h5
-rw-r--r--src/lstrlib.c4
-rw-r--r--src/ltable.c4
-rw-r--r--src/lua.c4
-rw-r--r--src/luac.c6
-rw-r--r--src/lundump.c4
20 files changed, 306 insertions, 380 deletions
diff --git a/src/Makefile b/src/Makefile
index 9d3d97c8..ba25b206 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -7,13 +7,18 @@
PLAT= none
CC= gcc
-CFLAGS= -O2 -Wall -DLUA_COMPAT_ALL $(MYCFLAGS)
-LIBS= -lm $(MYLIBS)
+CFLAGS= -O2 -Wall -DLUA_COMPAT_ALL $(SYSCFLAGS) $(MYCFLAGS)
+LDFLAGS= $(SYSLDFLAGS) $(MYLDFLAGS)
+LIBS= -lm $(SYSLIBS) $(MYLIBS)
AR= ar rcu
RANLIB= ranlib
RM= rm -f
+SYSCFLAGS=
+SYSLDFLAGS=
+SYSLIBS=
+
MYCFLAGS=
MYLDFLAGS=
MYLIBS=
@@ -23,7 +28,7 @@ MYLIBS=
PLATS= aix ansi bsd freebsd generic linux macosx mingw posix solaris
LUA_A= liblua.a
-CORE_O= lapi.o lcode.o lctype.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o \
+CORE_O= lapi.o lcode.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o \
lmem.o lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o \
ltm.o lundump.o lvm.o lzio.o
LIB_O= lauxlib.o lbaselib.o lbitlib.o lcorolib.o ldblib.o liolib.o \
@@ -53,10 +58,10 @@ $(LUA_A): $(CORE_O) $(LIB_O)
$(RANLIB) $@
$(LUA_T): $(LUA_O) $(LUA_A)
- $(CC) -o $@ $(MYLDFLAGS) $(LUA_O) $(LUA_A) $(LIBS)
+ $(CC) -o $@ $(LDFLAGS) $(LUA_O) $(LUA_A) $(LIBS)
$(LUAC_T): $(LUAC_O) $(LUA_A)
- $(CC) -o $@ $(MYLDFLAGS) $(LUAC_O) $(LUA_A) $(LIBS)
+ $(CC) -o $@ $(LDFLAGS) $(LUAC_O) $(LUA_A) $(LIBS)
clean:
$(RM) $(ALL_T) $(ALL_O)
@@ -68,12 +73,11 @@ echo:
@echo "PLAT= $(PLAT)"
@echo "CC= $(CC)"
@echo "CFLAGS= $(CFLAGS)"
+ @echo "LDFLAGS= $(SYSLDFLAGS)"
+ @echo "LIBS= $(LIBS)"
@echo "AR= $(AR)"
@echo "RANLIB= $(RANLIB)"
@echo "RM= $(RM)"
- @echo "MYCFLAGS= $(MYCFLAGS)"
- @echo "MYLDFLAGS= $(MYLDFLAGS)"
- @echo "MYLIBS= $(MYLIBS)"
# Convenience targets for popular platforms
ALL= all
@@ -83,35 +87,35 @@ none:
@echo " $(PLATS)"
aix:
- $(MAKE) $(ALL) CC="xlc" CFLAGS="-O2 -DLUA_USE_POSIX -DLUA_USE_DLOPEN" MYLIBS="-ldl" MYLDFLAGS="-brtl -bexpall"
+ $(MAKE) $(ALL) CC="xlc" CFLAGS="-O2 -DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-ldl" SYSLDFLAGS="-brtl -bexpall"
ansi:
- $(MAKE) $(ALL) MYCFLAGS="-DLUA_ANSI"
+ $(MAKE) $(ALL) SYSCFLAGS="-DLUA_ANSI"
bsd:
- $(MAKE) $(ALL) MYCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" MYLIBS="-Wl,-E"
+ $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-Wl,-E"
freebsd:
- $(MAKE) $(ALL) MYCFLAGS="-DLUA_USE_LINUX" MYLIBS="-Wl,-E -lreadline"
+ $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -lreadline"
generic: $(ALL)
linux:
- $(MAKE) $(ALL) MYCFLAGS="-DLUA_USE_LINUX" MYLIBS="-Wl,-E -ldl -lreadline"
+ $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -ldl -lreadline -lncurses"
macosx:
- $(MAKE) $(ALL) MYCFLAGS="-DLUA_USE_MACOSX" MYLIBS="-lreadline"
+ $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_MACOSX" SYSLIBS="-lreadline"
mingw:
$(MAKE) "LUA_A=lua52.dll" "LUA_T=lua.exe" \
"AR=$(CC) -shared -o" "RANLIB=strip --strip-unneeded" \
- "MYCFLAGS=-DLUA_BUILD_AS_DLL" "MYLIBS=" "MYLDFLAGS=-s" lua.exe
+ "SYSCFLAGS=-DLUA_BUILD_AS_DLL" "SYSLIBS=" "SYSLDFLAGS=-s" lua.exe
posix:
- $(MAKE) $(ALL) MYCFLAGS="-DLUA_USE_POSIX"
+ $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX"
solaris:
- $(MAKE) $(ALL) MYCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" MYLIBS="-ldl"
+ $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-ldl"
# list targets that do not create files (but not all makes understand .PHONY)
.PHONY: all $(PLATS) default o a clean depend echo none
@@ -128,7 +132,6 @@ lcode.o: lcode.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \
lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h lgc.h \
lstring.h ltable.h lvm.h
lcorolib.o: lcorolib.c lua.h luaconf.h lauxlib.h lualib.h
-lctype.o: lctype.c lctype.h lua.h luaconf.h llimits.h
ldblib.o: ldblib.c lua.h luaconf.h lauxlib.h lualib.h
ldebug.o: ldebug.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h \
ltm.h lzio.h lmem.h lcode.h llex.h lopcodes.h lparser.h ldebug.h ldo.h \
@@ -144,14 +147,14 @@ lgc.o: lgc.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \
lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h
linit.o: linit.c lua.h luaconf.h lualib.h lauxlib.h
liolib.o: liolib.c lua.h luaconf.h lauxlib.h lualib.h
-llex.o: llex.c lua.h luaconf.h lctype.h llimits.h ldo.h lobject.h \
- lstate.h ltm.h lzio.h lmem.h llex.h lparser.h lstring.h lgc.h ltable.h
+llex.o: llex.c lua.h luaconf.h ldo.h lobject.h llimits.h lstate.h ltm.h \
+ lzio.h lmem.h llex.h lparser.h lstring.h lgc.h ltable.h
lmathlib.o: lmathlib.c lua.h luaconf.h lauxlib.h lualib.h
lmem.o: lmem.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \
ltm.h lzio.h lmem.h ldo.h lgc.h
loadlib.o: loadlib.c lua.h luaconf.h lauxlib.h lualib.h
-lobject.o: lobject.c lua.h luaconf.h lctype.h llimits.h ldebug.h lstate.h \
- lobject.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h lvm.h
+lobject.o: lobject.c lua.h luaconf.h ldebug.h lstate.h lobject.h \
+ llimits.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h lvm.h
lopcodes.o: lopcodes.c lopcodes.h llimits.h lua.h luaconf.h
loslib.o: loslib.c lua.h luaconf.h lauxlib.h lualib.h
lparser.o: lparser.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \
@@ -178,4 +181,3 @@ lvm.o: lvm.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \
lzio.o: lzio.c lua.h luaconf.h llimits.h lmem.h lstate.h lobject.h ltm.h \
lzio.h
-# (end of Makefile)
diff --git a/src/lauxlib.c b/src/lauxlib.c
index fc080230..b765cfdd 100644
--- a/src/lauxlib.c
+++ b/src/lauxlib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lauxlib.c,v 1.232 2011/05/03 16:01:57 roberto Exp $
+** $Id: lauxlib.c,v 1.233 2011/06/16 14:11:04 roberto Exp $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/
@@ -251,13 +251,12 @@ LUALIB_API int luaL_execresult (lua_State *L, int stat) {
else {
inspectstat(stat, what); /* interpret result */
if (*what == 'e' && stat == 0) /* successful termination? */
- return luaL_fileresult(L, 1, NULL);
- else { /* return nil,what,code */
+ lua_pushboolean(L, 1);
+ else
lua_pushnil(L);
- lua_pushstring(L, what);
- lua_pushinteger(L, stat);
- return 3;
- }
+ lua_pushstring(L, what);
+ lua_pushinteger(L, stat);
+ return 3; /* return true/nil,what,code */
}
}
diff --git a/src/lauxlib.h b/src/lauxlib.h
index 8b85ebe5..a7aa0d76 100644
--- a/src/lauxlib.h
+++ b/src/lauxlib.h
@@ -1,5 +1,5 @@
/*
-** $Id: lauxlib.h,v 1.116 2011/04/08 19:17:36 roberto Exp $
+** $Id: lauxlib.h,v 1.117 2011/06/16 14:10:12 roberto Exp $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/
@@ -164,6 +164,7 @@ LUALIB_API char *(luaL_buffinitsize) (lua_State *L, luaL_Buffer *B, size_t sz);
/* compatibility with old module system */
+#if defined(LUA_COMPAT_MODULE)
LUALIB_API void (luaL_pushmodule) (lua_State *L, const char *modname,
int sizehint);
@@ -172,6 +173,8 @@ LUALIB_API void (luaL_openlib) (lua_State *L, const char *libname,
#define luaL_register(L,n,l) (luaL_openlib(L,(n),(l),0))
+#endif
+
#endif
diff --git a/src/lbaselib.c b/src/lbaselib.c
index 82c8c1fe..91c21e31 100644
--- a/src/lbaselib.c
+++ b/src/lbaselib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lbaselib.c,v 1.261 2011/05/26 16:09:40 roberto Exp $
+** $Id: lbaselib.c,v 1.262 2011/06/16 14:12:24 roberto Exp $
** Basic library
** See Copyright Notice in lua.h
*/
@@ -268,6 +268,13 @@ static int luaB_loadfile (lua_State *L) {
** =======================================================
*/
+
+typedef struct {
+char c;
+ const char *mode;
+} loaddata;
+
+
/*
** check whether a chunk (prefix in 's') satisfies given 'mode'
** ('t' for text, 'b' for binary). Returns error message (also
@@ -298,7 +305,7 @@ static const char *checkrights (lua_State *L, const char *mode, const char *s) {
*/
static const char *generic_reader (lua_State *L, void *ud, size_t *size) {
const char *s;
- const char **mode = (const char **)ud;
+ loaddata *ld = (loaddata *)ud;
luaL_checkstack(L, 2, "too many nested functions");
lua_pushvalue(L, 1); /* get function */
lua_call(L, 0, 1); /* call it */
@@ -307,9 +314,9 @@ static const char *generic_reader (lua_State *L, void *ud, size_t *size) {
return NULL;
}
else if ((s = lua_tostring(L, -1)) != NULL) {
- if (*mode != NULL) { /* first time? */
- s = checkrights(L, *mode, s); /* check mode */
- *mode = NULL; /* to avoid further checks */
+ if (ld->mode != NULL) { /* first time? */
+ s = checkrights(L, ld->mode, s); /* check mode */
+ ld->mode = NULL; /* to avoid further checks */
if (s) luaL_error(L, s);
}
lua_replace(L, RESERVEDSLOT); /* save string in reserved slot */
@@ -335,9 +342,11 @@ static int luaB_load (lua_State *L) {
}
else { /* loading from a reader function */
const char *chunkname = luaL_optstring(L, 2, "=(load)");
+ loaddata ld;
+ ld.mode = mode;
luaL_checktype(L, 1, LUA_TFUNCTION);
lua_settop(L, RESERVEDSLOT); /* create reserved slot */
- status = lua_load(L, generic_reader, &mode, chunkname);
+ status = lua_load(L, generic_reader, &ld, chunkname);
}
if (status == LUA_OK && top >= 4) { /* is there an 'env' argument */
lua_pushvalue(L, 4); /* environment for loaded function */
diff --git a/src/lbitlib.c b/src/lbitlib.c
index dcc0ac16..7533b85c 100644
--- a/src/lbitlib.c
+++ b/src/lbitlib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lbitlib.c,v 1.15 2010/12/17 13:26:38 roberto Exp $
+** $Id: lbitlib.c,v 1.16 2011/06/20 16:35:23 roberto Exp $
** Standard library for bitwise operations
** See Copyright Notice in lua.h
*/
@@ -152,7 +152,7 @@ static int b_rrot (lua_State *L) {
static int fieldargs (lua_State *L, int farg, int *width) {
int f = luaL_checkint(L, farg);
int w = luaL_optint(L, farg + 1, 1);
- luaL_argcheck(L, 0 <= f, farg, "field cannot be netative");
+ 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");
diff --git a/src/lctype.c b/src/lctype.c
deleted file mode 100644
index b3627f99..00000000
--- a/src/lctype.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
-** $Id: lctype.c,v 1.8 2009/11/19 19:06:52 roberto Exp $
-** 'ctype' functions for Lua
-** See Copyright Notice in lua.h
-*/
-
-#include <limits.h>
-
-#include "lctype.h"
-
-LUAI_DDEF const lu_byte luai_ctype_[UCHAR_MAX + 2] = {
- 0x00, /* EOZ */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x0c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16,
- 0x16, 0x16, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x25,
- 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
- 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
- 0x25, 0x25, 0x25, 0x04, 0x04, 0x04, 0x04, 0x05,
- 0x04, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x05,
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
- 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-};
diff --git a/src/lctype.h b/src/lctype.h
deleted file mode 100644
index b43baa79..00000000
--- a/src/lctype.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
-** $Id: lctype.h,v 1.8 2009/11/19 19:06:52 roberto Exp $
-** 'ctype' functions for Lua
-** See Copyright Notice in lua.h
-*/
-
-#ifndef lctype_h
-#define lctype_h
-
-
-#include <limits.h>
-
-#include "lua.h"
-
-#include "llimits.h"
-
-
-#define ALPHABIT 0
-#define DIGITBIT 1
-#define PRINTBIT 2
-#define SPACEBIT 3
-#define XDIGITBIT 4
-#define UPPERBIT 5
-
-
-#define MASK(B) (1 << (B))
-
-
-/*
-** add 1 to char to allow index -1 (EOZ)
-*/
-#define testprop(c,p) (luai_ctype_[(c)+1] & (p))
-
-/*
-** 'lalpha' (Lua alphabetic) and 'lalnum' (Lua alphanumeric) both include '_'
-*/
-#define lislalpha(c) testprop(c, MASK(ALPHABIT))
-#define lislalnum(c) testprop(c, (MASK(ALPHABIT) | MASK(DIGITBIT)))
-#define lisupper(c) testprop(c, MASK(UPPERBIT))
-#define lisdigit(c) testprop(c, MASK(DIGITBIT))
-#define lisspace(c) testprop(c, MASK(SPACEBIT))
-#define lisprint(c) testprop(c, MASK(PRINTBIT))
-#define lisxdigit(c) testprop(c, MASK(XDIGITBIT))
-
-
-/* one more entry for 0 and one more for -1 (EOZ) */
-LUAI_DDEC const lu_byte luai_ctype_[UCHAR_MAX + 2];
-
-#endif
-
diff --git a/src/ldo.c b/src/ldo.c
index c3d86aff..99868aee 100644
--- a/src/ldo.c
+++ b/src/ldo.c
@@ -1,10 +1,11 @@
/*
-** $Id: ldo.c,v 2.95 2011/06/02 19:31:40 roberto Exp $
+** $Id: ldo.c,v 2.97 2011/06/20 16:36:03 roberto Exp $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
+#include <locale.h>
#include <setjmp.h>
#include <stdlib.h>
#include <string.h>
@@ -612,8 +613,22 @@ struct SParser { /* data to `f_parser' */
Mbuffer buff; /* dynamic structure used by the scanner */
Dyndata dyd; /* dynamic structures used by the parser */
const char *name;
+ TString *savedlocale;
};
+
+/*
+** save current locale and set locale to "C" for calling the parser
+*/
+static Proto *callparser (lua_State *L, struct SParser *p, int c) {
+ const char *oldloc = setlocale(LC_ALL, NULL); /* get current locale */
+ p->savedlocale = luaS_new(L, oldloc); /* make a copy */
+ setsvalue2s(L, L->top - 1, p->savedlocale); /* anchor it */
+ (void)setlocale(LC_ALL, "C"); /* standard locale for parsing Lua files */
+ return luaY_parser(L, p->z, &p->buff, &p->dyd, p->name, c);
+}
+
+
static void f_parser (lua_State *L, void *ud) {
int i;
Proto *tf;
@@ -621,8 +636,7 @@ static void f_parser (lua_State *L, void *ud) {
struct SParser *p = cast(struct SParser *, ud);
int c = zgetc(p->z); /* read first character */
tf = (c == LUA_SIGNATURE[0])
- ? luaU_undump(L, p->z, &p->buff, p->name)
- : luaY_parser(L, p->z, &p->buff, &p->dyd, p->name, c);
+ ? luaU_undump(L, p->z, &p->buff, p->name) : callparser(L, p, c);
setptvalue2s(L, L->top, tf);
incr_top(L);
cl = luaF_newLclosure(L, tf);
@@ -635,8 +649,9 @@ static void f_parser (lua_State *L, void *ud) {
int luaD_protectedparser (lua_State *L, ZIO *z, const char *name) {
struct SParser p;
int status;
+ setnilvalue(L->top++); /* reserve space for anchoring locale */
L->nny++; /* cannot yield during parsing */
- p.z = z; p.name = name;
+ p.z = z; p.name = name; p.savedlocale = NULL;
p.dyd.actvar.arr = NULL; p.dyd.actvar.size = 0;
p.dyd.gt.arr = NULL; p.dyd.gt.size = 0;
p.dyd.label.arr = NULL; p.dyd.label.size = 0;
@@ -647,6 +662,10 @@ int luaD_protectedparser (lua_State *L, ZIO *z, const char *name) {
luaM_freearray(L, p.dyd.gt.arr, p.dyd.gt.size);
luaM_freearray(L, p.dyd.label.arr, p.dyd.label.size);
L->nny--;
+ if (p.savedlocale) /* locale was changed? */
+ (void)setlocale(LC_ALL, getstr(p.savedlocale)); /* restore old locale */
+ setobjs2s(L, L->top - 2, L->top - 1); /* remove reserved space */
+ --L->top;
return status;
}
diff --git a/src/liolib.c b/src/liolib.c
index ab1f1311..a29a53ec 100644
--- a/src/liolib.c
+++ b/src/liolib.c
@@ -1,5 +1,5 @@
/*
-** $Id: liolib.c,v 2.99 2011/03/03 16:34:46 roberto Exp $
+** $Id: liolib.c,v 2.100 2011/06/21 13:43:48 roberto Exp $
** Standard I/O (and system) library
** See Copyright Notice in lua.h
*/
@@ -19,8 +19,6 @@
#include "lualib.h"
-#define MAX_SIZE_T (~(size_t)0)
-
/*
** lua_popen spawns a new process connected to the current one through
@@ -51,11 +49,15 @@
#endif /* } */
-#define IO_INPUT 1
-#define IO_OUTPUT 2
+#define IO_PREFIX "lua_io_"
+#define IO_INPUT (IO_PREFIX "input")
+#define IO_OUTPUT (IO_PREFIX "output")
-static const char *const fnames[] = {"input", "output"};
+typedef struct LStream {
+ FILE *f; /* stream */
+ lua_CFunction closef; /* to close stream (NULL for closed streams) */
+} LStream;
static void fileerror (lua_State *L, int arg, const char *filename) {
@@ -64,16 +66,18 @@ static void fileerror (lua_State *L, int arg, const char *filename) {
}
-#define tofilep(L) ((FILE **)luaL_checkudata(L, 1, LUA_FILEHANDLE))
+#define tolstream(L) ((LStream *)luaL_checkudata(L, 1, LUA_FILEHANDLE))
+
+#define isclosed(p) ((p)->closef == NULL)
static int io_type (lua_State *L) {
- void *ud;
+ LStream *p;
luaL_checkany(L, 1);
- ud = luaL_testudata(L, 1, LUA_FILEHANDLE);
- if (ud == NULL)
+ p = (LStream *)luaL_testudata(L, 1, LUA_FILEHANDLE);
+ if (p == NULL)
lua_pushnil(L); /* not a file */
- else if (*((FILE **)ud) == NULL)
+ else if (isclosed(p))
lua_pushliteral(L, "closed file");
else
lua_pushliteral(L, "file");
@@ -81,11 +85,22 @@ static int io_type (lua_State *L) {
}
+static int f_tostring (lua_State *L) {
+ LStream *p = tolstream(L);
+ if (isclosed(p))
+ lua_pushliteral(L, "file (closed)");
+ else
+ lua_pushfstring(L, "file (%p)", p->f);
+ return 1;
+}
+
+
static FILE *tofile (lua_State *L) {
- FILE **f = tofilep(L);
- if (*f == NULL)
+ LStream *p = tolstream(L);
+ if (isclosed(p))
luaL_error(L, "attempt to use a closed file");
- return *f;
+ lua_assert(p->f);
+ return p->f;
}
@@ -94,40 +109,35 @@ static FILE *tofile (lua_State *L) {
** before opening the actual file; so, if there is a memory error, the
** file is not left opened.
*/
-static FILE **newprefile (lua_State *L) {
- FILE **pf = (FILE **)lua_newuserdata(L, sizeof(FILE *));
- *pf = NULL; /* file handle is currently `closed' */
+static LStream *newprefile (lua_State *L) {
+ LStream *p = (LStream *)lua_newuserdata(L, sizeof(LStream));
+ p->closef = NULL; /* mark file handle as 'closed' */
luaL_setmetatable(L, LUA_FILEHANDLE);
- return pf;
+ return p;
}
-static FILE **newfile (lua_State *L) {
- FILE **pf = newprefile(L);
- lua_pushvalue(L, lua_upvalueindex(1)); /* set upvalue... */
- lua_setuservalue(L, -2); /* ... as environment for new file */
- return pf;
+static int aux_close (lua_State *L) {
+ LStream *p = tolstream(L);
+ lua_CFunction cf = p->closef;
+ p->closef = NULL; /* mark stream as closed */
+ return (*cf)(L); /* close it */
}
-/*
-** function to (not) close the standard files stdin, stdout, and stderr
-*/
-static int io_noclose (lua_State *L) {
- lua_pushnil(L);
- lua_pushliteral(L, "cannot close standard file");
- return 2;
+static int io_close (lua_State *L) {
+ if (lua_isnone(L, 1)) /* no argument? */
+ lua_getfield(L, LUA_REGISTRYINDEX, IO_OUTPUT); /* use standard output */
+ tofile(L); /* make sure argument is an open stream */
+ return aux_close(L);
}
-/*
-** function to close 'popen' files
-*/
-static int io_pclose (lua_State *L) {
- FILE **p = tofilep(L);
- int stat = lua_pclose(L, *p);
- *p = NULL; /* mark stream as closed (for GC) */
- return luaL_execresult(L, stat);
+static int f_gc (lua_State *L) {
+ LStream *p = tolstream(L);
+ if (!isclosed(p) && p->f != NULL)
+ aux_close(L); /* ignore closed and incompletely open files */
+ return 0;
}
@@ -135,111 +145,90 @@ static int io_pclose (lua_State *L) {
** function to close regular files
*/
static int io_fclose (lua_State *L) {
- FILE **p = tofilep(L);
- int ok = (fclose(*p) == 0);
- *p = NULL; /* mark stream as closed (for GC) */
- return luaL_fileresult(L, ok, NULL);
+ LStream *p = tolstream(L);
+ int res = fclose(p->f);
+ return luaL_fileresult(L, (res == 0), NULL);
}
-static int aux_close (lua_State *L) {
- lua_getuservalue(L, 1);
- lua_getfield(L, -1, "__close");
- return (lua_tocfunction(L, -1))(L);
-}
-
-
-static int io_close (lua_State *L) {
- if (lua_isnone(L, 1))
- lua_rawgeti(L, lua_upvalueindex(1), IO_OUTPUT);
- tofile(L); /* make sure argument is a file */
- return aux_close(L);
-}
-
-
-static int io_gc (lua_State *L) {
- FILE *f = *tofilep(L);
- if (f != NULL) /* ignore closed files */
- aux_close(L);
- return 0;
-}
-
-
-static int io_tostring (lua_State *L) {
- FILE *f = *tofilep(L);
- if (f == NULL)
- lua_pushliteral(L, "file (closed)");
- else
- lua_pushfstring(L, "file (%p)", f);
- return 1;
+static LStream *newfile (lua_State *L) {
+ LStream *p = newprefile(L);
+ p->f = NULL;
+ p->closef = &io_fclose;
+ return p;
}
static int io_open (lua_State *L) {
const char *filename = luaL_checkstring(L, 1);
const char *mode = luaL_optstring(L, 2, "r");
- FILE **pf;
+ LStream *p = newfile(L);
int i = 0;
/* check whether 'mode' matches '[rwa]%+?b?' */
if (!(mode[i] != '\0' && strchr("rwa", mode[i++]) != NULL &&
(mode[i] != '+' || ++i) && /* skip if char is '+' */
(mode[i] != 'b' || ++i) && /* skip if char is 'b' */
(mode[i] == '\0')))
- luaL_error(L, "invalid mode " LUA_QL("%s")
- " (should match " LUA_QL("[rwa]%%+?b?") ")", mode);
- pf = newfile(L);
- *pf = fopen(filename, mode);
- return (*pf == NULL) ? luaL_fileresult(L, 0, filename) : 1;
+ return luaL_error(L, "invalid mode " LUA_QL("%s")
+ " (should match " LUA_QL("[rwa]%%+?b?") ")", mode);
+ p->f = fopen(filename, mode);
+ return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1;
}
/*
-** this function has a separated environment, which defines the
-** correct __close for 'popen' files
+** function to close 'popen' files
*/
+static int io_pclose (lua_State *L) {
+ LStream *p = tolstream(L);
+ return luaL_execresult(L, lua_pclose(L, p->f));
+}
+
+
static int io_popen (lua_State *L) {
const char *filename = luaL_checkstring(L, 1);
const char *mode = luaL_optstring(L, 2, "r");
- FILE **pf = newfile(L);
- *pf = lua_popen(L, filename, mode);
- return (*pf == NULL) ? luaL_fileresult(L, 0, filename) : 1;
+ LStream *p = newprefile(L);
+ p->f = lua_popen(L, filename, mode);
+ p->closef = &io_pclose;
+ return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1;
}
static int io_tmpfile (lua_State *L) {
- FILE **pf = newfile(L);
- *pf = tmpfile();
- return (*pf == NULL) ? luaL_fileresult(L, 0, NULL) : 1;
+ LStream *p = newfile(L);
+ p->f = tmpfile();
+ return (p->f == NULL) ? luaL_fileresult(L, 0, NULL) : 1;
}
-static FILE *getiofile (lua_State *L, int findex) {
- FILE *f;
- lua_rawgeti(L, lua_upvalueindex(1), findex);
- f = *(FILE **)lua_touserdata(L, -1);
- if (f == NULL)
- luaL_error(L, "standard %s file is closed", fnames[findex - 1]);
- return f;
+static FILE *getiofile (lua_State *L, const char *findex) {
+ LStream *p;
+ 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));
+ return p->f;
}
-static int g_iofile (lua_State *L, int f, const char *mode) {
+static int g_iofile (lua_State *L, const char *f, const char *mode) {
if (!lua_isnoneornil(L, 1)) {
const char *filename = lua_tostring(L, 1);
if (filename) {
- FILE **pf = newfile(L);
- *pf = fopen(filename, mode);
- if (*pf == NULL)
+ LStream *p = newfile(L);
+ p->f = fopen(filename, mode);
+ if (p->f == NULL)
fileerror(L, 1, filename);
}
else {
tofile(L); /* check that it's a valid file handle */
lua_pushvalue(L, 1);
}
- lua_rawseti(L, lua_upvalueindex(1), f);
+ lua_setfield(L, LUA_REGISTRYINDEX, f);
}
/* return current value */
- lua_rawgeti(L, lua_upvalueindex(1), f);
+ lua_getfield(L, LUA_REGISTRYINDEX, f);
return 1;
}
@@ -281,16 +270,16 @@ static int io_lines (lua_State *L) {
int toclose;
if (lua_isnone(L, 1)) lua_pushnil(L); /* at least one argument */
if (lua_isnil(L, 1)) { /* no file name? */
- lua_rawgeti(L, lua_upvalueindex(1), IO_INPUT); /* get default input */
+ lua_getfield(L, LUA_REGISTRYINDEX, IO_INPUT); /* get default input */
lua_replace(L, 1); /* put it at index 1 */
tofile(L); /* check that it's a valid file handle */
toclose = 0; /* do not close it after iteration */
}
else { /* open a new file */
const char *filename = luaL_checkstring(L, 1);
- FILE **pf = newfile(L);
- *pf = fopen(filename, "r");
- if (*pf == NULL)
+ LStream *p = newfile(L);
+ p->f = fopen(filename, "r");
+ if (p->f == NULL)
fileerror(L, 1, filename);
lua_replace(L, 1); /* put file at index 1 */
toclose = 1; /* close it after iteration */
@@ -350,6 +339,8 @@ static int read_line (lua_State *L, FILE *f, int chop) {
}
+#define MAX_SIZE_T (~(size_t)0)
+
static void read_all (lua_State *L, FILE *f) {
size_t rlen = LUAL_BUFFERSIZE; /* how much to read in each cycle */
luaL_Buffer b;
@@ -440,15 +431,15 @@ static int f_read (lua_State *L) {
static int io_readline (lua_State *L) {
- FILE *f = *(FILE **)lua_touserdata(L, lua_upvalueindex(1));
+ LStream *p = (LStream *)lua_touserdata(L, lua_upvalueindex(1));
int i;
int n = (int)lua_tointeger(L, lua_upvalueindex(2));
- if (f == NULL) /* file is already closed? */
- luaL_error(L, "file is already closed");
+ if (isclosed(p)) /* file is already closed? */
+ return luaL_error(L, "file is already closed");
lua_settop(L , 1);
for (i = 1; i <= n; i++) /* push arguments to 'g_read' */
lua_pushvalue(L, lua_upvalueindex(3 + i));
- n = g_read(L, f, 2); /* 'n' is number of results */
+ 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? */
return n; /* return them */
@@ -494,7 +485,7 @@ static int io_write (lua_State *L) {
static int f_write (lua_State *L) {
- FILE * f = tofile(L);
+ FILE *f = tofile(L);
lua_pushvalue(L, 1); /* push file at the stack top (to be returned) */
return g_write(L, f, 2);
}
@@ -538,6 +529,9 @@ static int f_flush (lua_State *L) {
}
+/*
+** functions for 'io' library
+*/
static const luaL_Reg iolib[] = {
{"close", io_close},
{"flush", io_flush},
@@ -554,6 +548,9 @@ static const luaL_Reg iolib[] = {
};
+/*
+** methods for file handles
+*/
static const luaL_Reg flib[] = {
{"close", io_close},
{"flush", f_flush},
@@ -562,8 +559,8 @@ static const luaL_Reg flib[] = {
{"seek", f_seek},
{"setvbuf", f_setvbuf},
{"write", f_write},
- {"__gc", io_gc},
- {"__tostring", io_tostring},
+ {"__gc", f_gc},
+ {"__tostring", f_tostring},
{NULL, NULL}
};
@@ -577,46 +574,38 @@ static void createmeta (lua_State *L) {
}
-static void createstdfile (lua_State *L, FILE *f, int k, const char *fname) {
- *newprefile(L) = f;
- if (k > 0) {
- lua_pushvalue(L, -1); /* copy new file */
- lua_rawseti(L, 1, k); /* add it to common upvalue */
- }
- lua_pushvalue(L, 3); /* get environment for default files */
- lua_setuservalue(L, -2); /* set it as environment for file */
- lua_setfield(L, 2, fname); /* add file to module */
+/*
+** function to (not) close the standard files stdin, stdout, and stderr
+*/
+static int io_noclose (lua_State *L) {
+ LStream *p = tolstream(L);
+ p->closef = &io_noclose; /* keep file opened */
+ lua_pushnil(L);
+ lua_pushliteral(L, "cannot close standard file");
+ return 2;
}
-/*
-** pushes a new table with {__close = cls}
-*/
-static void newenv (lua_State *L, lua_CFunction cls) {
- lua_createtable(L, 0, 1);
- lua_pushcfunction(L, cls);
- lua_setfield(L, -2, "__close");
+static void createstdfile (lua_State *L, FILE *f, const char *k,
+ const char *fname) {
+ LStream *p = newprefile(L);
+ p->f = f;
+ p->closef = &io_noclose;
+ if (k != NULL) {
+ lua_pushvalue(L, -1);
+ lua_setfield(L, LUA_REGISTRYINDEX, k); /* add file to registry */
+ }
+ lua_setfield(L, -2, fname); /* add file to module */
}
LUAMOD_API int luaopen_io (lua_State *L) {
- lua_settop(L, 0);
+ luaL_newlib(L, iolib); /* new module */
createmeta(L);
- /* create (private) environment (with fields IO_INPUT, IO_OUTPUT, __close) */
- newenv(L, io_fclose); /* upvalue for all io functions at index 1 */
- luaL_newlibtable(L, iolib); /* new module at index 2 */
- lua_pushvalue(L, 1); /* copy of env to be consumed by 'setfuncs' */
- luaL_setfuncs(L, iolib, 1);
/* create (and set) default files */
- newenv(L, io_noclose); /* environment for default files at index 3 */
createstdfile(L, stdin, IO_INPUT, "stdin");
createstdfile(L, stdout, IO_OUTPUT, "stdout");
- createstdfile(L, stderr, 0, "stderr");
- lua_pop(L, 1); /* pop environment for default files */
- lua_getfield(L, 2, "popen");
- newenv(L, io_pclose); /* create environment for 'popen' streams */
- lua_setupvalue(L, -2, 1); /* set it as upvalue for 'popen' */
- lua_pop(L, 1); /* pop 'popen' */
+ createstdfile(L, stderr, NULL, "stderr");
return 1;
}
diff --git a/src/llex.c b/src/llex.c
index 7d034b0a..80592f19 100644
--- a/src/llex.c
+++ b/src/llex.c
@@ -1,11 +1,11 @@
/*
-** $Id: llex.c,v 2.47 2011/05/03 15:51:16 roberto Exp $
+** $Id: llex.c,v 2.50 2011/06/20 16:52:48 roberto Exp $
** Lexical Analyzer
** See Copyright Notice in lua.h
*/
-#include <locale.h>
+#include <ctype.h>
#include <string.h>
#define llex_c
@@ -13,7 +13,6 @@
#include "lua.h"
-#include "lctype.h"
#include "ldo.h"
#include "llex.h"
#include "lobject.h"
@@ -38,7 +37,7 @@ static const char *const luaX_tokens [] = {
"end", "false", "for", "function", "goto", "if",
"in", "local", "nil", "not", "or", "repeat",
"return", "then", "true", "until", "while",
- "..", "...", "==", ">=", "<=", "~=", "<eof>",
+ "..", "...", "==", ">=", "<=", "~=", "::", "<eof>",
"<number>", "<name>", "<string>"
};
@@ -75,7 +74,7 @@ void luaX_init (lua_State *L) {
const char *luaX_token2str (LexState *ls, int token) {
if (token < FIRST_RESERVED) {
lua_assert(token == cast(unsigned char, token));
- return (lisprint(token)) ? luaO_pushfstring(ls->L, LUA_QL("%c"), token) :
+ return (isprint(token)) ? luaO_pushfstring(ls->L, LUA_QL("%c"), token) :
luaO_pushfstring(ls->L, "char(%d)", token);
}
else {
@@ -185,52 +184,24 @@ static int check_next (LexState *ls, const char *set) {
}
-/*
-** change all characters 'from' in buffer to 'to'
-*/
-static void buffreplace (LexState *ls, char from, char to) {
- size_t n = luaZ_bufflen(ls->buff);
- char *p = luaZ_buffer(ls->buff);
- while (n--)
- if (p[n] == from) p[n] = to;
-}
-
-
-#if !defined(getlocaledecpoint)
-#define getlocaledecpoint() (localeconv()->decimal_point[0])
-#endif
-
#define buff2d(b,e) luaO_str2d(luaZ_buffer(b), luaZ_bufflen(b) - 1, e)
-/*
-** in case of format error, try to change decimal point separator to
-** the one defined in the current locale and check again
-*/
-static void trydecpoint (LexState *ls, SemInfo *seminfo) {
- char old = ls->decpoint;
- ls->decpoint = getlocaledecpoint();
- buffreplace(ls, old, ls->decpoint); /* try new decimal separator */
- if (!buff2d(ls->buff, &seminfo->r)) {
- /* format error with correct decimal point: no more options */
- buffreplace(ls, ls->decpoint, '.'); /* undo change (for error message) */
- lexerror(ls, "malformed number", TK_NUMBER);
- }
-}
-
/* LUA_NUMBER */
static void read_numeral (LexState *ls, SemInfo *seminfo) {
- lua_assert(lisdigit(ls->current));
+ lua_assert(isdigit(ls->current));
do {
save_and_next(ls);
if (check_next(ls, "EePp")) /* exponent part? */
check_next(ls, "+-"); /* optional exponent sign */
- } while (lislalnum(ls->current) || ls->current == '.');
+ } while (isalnum(ls->current) || ls->current == '.');
save(ls, '\0');
- buffreplace(ls, '.', ls->decpoint); /* follow locale for decimal point */
- if (!buff2d(ls->buff, &seminfo->r)) /* format error? */
- trydecpoint(ls, seminfo); /* try to update decimal point separator */
+ if (!luaO_str2d(luaZ_buffer(ls->buff),
+ luaZ_bufflen(ls->buff) - 1,
+ &seminfo->r)) /* format error? */
+ lexerror(ls, "malformed number", TK_NUMBER);
+
}
@@ -287,25 +258,32 @@ static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) {
static int readhexaesc (LexState *ls) {
- int c1, c2 = EOZ;
- if (!lisxdigit(c1 = next(ls)) || !lisxdigit(c2 = next(ls))) {
- luaZ_resetbuffer(ls->buff); /* prepare error message */
- save(ls, '\\'); save(ls, 'x');
- if (c1 != EOZ) save(ls, c1);
- if (c2 != EOZ) save(ls, c2);
- lexerror(ls, "hexadecimal digit expected", TK_STRING);
+ int c1 = next(ls);
+ int c2 = EOZ;
+ if (isxdigit(c1)) {
+ c2 = next(ls);
+ if (isxdigit(c2))
+ return (luaO_hexavalue(c1) << 4) + luaO_hexavalue(c2);
+ /* else go through to error */
}
- return (luaO_hexavalue(c1) << 4) + luaO_hexavalue(c2);
+ luaZ_resetbuffer(ls->buff); /* prepare error message */
+ save(ls, '\\'); save(ls, 'x');
+ if (c1 != EOZ) save(ls, c1);
+ if (c2 != EOZ) save(ls, c2);
+ lexerror(ls, "hexadecimal digit expected", TK_STRING);
+ return 0; /* to avoid warnings */
}
static int readdecesc (LexState *ls) {
- int c1 = ls->current, c2, c3;
- int c = c1 - '0';
- if (lisdigit(c2 = next(ls))) {
- c = 10*c + c2 - '0';
- if (lisdigit(c3 = next(ls))) {
- c = 10*c + c3 - '0';
+ int c1 = ls->current; /* first char must be a digit */
+ int c2 = next(ls); /* read second char */
+ int c = c1 - '0'; /* partial result */
+ if (isdigit(c2)) {
+ int c3 = next(ls); /* read third char */
+ c = 10*c + c2 - '0'; /* update result */
+ if (isdigit(c3)) {
+ c = 10*c + c3 - '0'; /* update result */
if (c > UCHAR_MAX) {
luaZ_resetbuffer(ls->buff); /* prepare error message */
save(ls, '\\');
@@ -349,14 +327,14 @@ static void read_string (LexState *ls, int del, SemInfo *seminfo) {
case EOZ: continue; /* will raise an error next loop */
case '*': { /* skip following span of spaces */
next(ls); /* skip the '*' */
- while (lisspace(ls->current)) {
+ while (isspace(ls->current)) {
if (currIsNewline(ls)) inclinenumber(ls);
else next(ls);
}
continue; /* do not save 'c' */
}
default: {
- if (!lisdigit(ls->current))
+ if (!isdigit(ls->current))
c = ls->current; /* handles \\, \", \', and \? */
else /* digital escape \ddd */
c = readdecesc(ls);
@@ -437,6 +415,11 @@ static int llex (LexState *ls, SemInfo *seminfo) {
if (ls->current != '=') return '~';
else { next(ls); return TK_NE; }
}
+ case ':': {
+ next(ls);
+ if (ls->current != ':') return ':';
+ else { next(ls); return TK_DBCOLON; }
+ }
case '"': case '\'': { /* short literal strings */
read_string(ls, ls->current, seminfo);
return TK_STRING;
@@ -448,7 +431,7 @@ static int llex (LexState *ls, SemInfo *seminfo) {
return TK_DOTS; /* '...' */
else return TK_CONCAT; /* '..' */
}
- else if (!lisdigit(ls->current)) return '.';
+ else if (!isdigit(ls->current)) return '.';
/* else go through */
}
case '0': case '1': case '2': case '3': case '4':
@@ -460,11 +443,12 @@ static int llex (LexState *ls, SemInfo *seminfo) {
return TK_EOS;
}
default: {
- if (lislalpha(ls->current)) { /* identifier or reserved word? */
+ if (isalpha(ls->current) || ls->current == '_') {
+ /* identifier or reserved word */
TString *ts;
do {
save_and_next(ls);
- } while (lislalnum(ls->current));
+ } while (isalnum(ls->current) || ls->current == '_');
ts = luaX_newstring(ls, luaZ_buffer(ls->buff),
luaZ_bufflen(ls->buff));
seminfo->ts = ts;
diff --git a/src/llex.h b/src/llex.h
index 5edbbc1d..ce0bad40 100644
--- a/src/llex.h
+++ b/src/llex.h
@@ -1,5 +1,5 @@
/*
-** $Id: llex.h,v 1.70 2011/05/03 15:51:16 roberto Exp $
+** $Id: llex.h,v 1.71 2011/06/20 16:52:48 roberto Exp $
** Lexical Analyzer
** See Copyright Notice in lua.h
*/
@@ -26,7 +26,7 @@ enum RESERVED {
TK_GOTO, TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT,
TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE,
/* other terminal symbols */
- TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_EOS,
+ TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_DBCOLON, TK_EOS,
TK_NUMBER, TK_NAME, TK_STRING
};
diff --git a/src/lobject.c b/src/lobject.c
index dcc487ca..fecd88ed 100644
--- a/src/lobject.c
+++ b/src/lobject.c
@@ -1,9 +1,10 @@
/*
-** $Id: lobject.c,v 2.49 2011/05/31 18:24:36 roberto Exp $
+** $Id: lobject.c,v 2.51 2011/06/18 17:25:15 roberto Exp $
** Some generic functions over Lua objects
** See Copyright Notice in lua.h
*/
+#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
@@ -14,7 +15,6 @@
#include "lua.h"
-#include "lctype.h"
#include "ldebug.h"
#include "ldo.h"
#include "lmem.h"
@@ -85,9 +85,9 @@ lua_Number luaO_arith (int op, lua_Number v1, lua_Number v2) {
int luaO_hexavalue (int c) {
- if (lisdigit(c)) return c - '0';
- else if (lisupper(c)) return c - 'A' + 10;
- else return c - 'a' + 10;
+ lua_assert(isxdigit(c));
+ if (isdigit(c)) return c - '0';
+ else return toupper(c) - 'A' + 10;
}
@@ -104,8 +104,8 @@ static int isneg (const char **s) {
static lua_Number readhexa (const char **s, lua_Number r, int *count) {
- while (lisxdigit(cast_uchar(**s))) { /* read integer part */
- r = (r * 16.0) + (double)luaO_hexavalue(*(*s)++);
+ while (isxdigit(cast_uchar(**s))) { /* read integer part */
+ r = (r * 16.0) + cast_num(luaO_hexavalue(cast_uchar(*(*s)++)));
(*count)++;
}
return r;
@@ -121,7 +121,7 @@ static lua_Number lua_strx2number (const char *s, char **endptr) {
int e = 0, i = 0;
int neg = 0; /* 1 if number is negative */
*endptr = cast(char *, s); /* nothing is valid yet */
- while (lisspace(cast_uchar(*s))) s++; /* skip initial spaces */
+ while (isspace(cast_uchar(*s))) s++; /* skip initial spaces */
neg = isneg(&s); /* check signal */
if (!(*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X'))) /* check '0x' */
return 0.0; /* invalid format (no '0x') */
@@ -140,9 +140,9 @@ static lua_Number lua_strx2number (const char *s, char **endptr) {
int neg1;
s++; /* skip 'p' */
neg1 = isneg(&s); /* signal */
- if (!lisdigit(cast_uchar(*s)))
+ if (!isdigit(cast_uchar(*s)))
goto ret; /* must have at least one digit */
- while (lisdigit(cast_uchar(*s))) /* read exponent */
+ while (isdigit(cast_uchar(*s))) /* read exponent */
exp1 = exp1 * 10 + *(s++) - '0';
if (neg1) exp1 = -exp1;
e += exp1;
@@ -163,7 +163,7 @@ int luaO_str2d (const char *s, size_t len, lua_Number *result) {
else
*result = lua_str2number(s, &endptr);
if (endptr == s) return 0; /* nothing recognized */
- while (lisspace(cast_uchar(*endptr))) endptr++;
+ while (isspace(cast_uchar(*endptr))) endptr++;
return (endptr == s + len); /* OK if no trailing characters */
}
diff --git a/src/loslib.c b/src/loslib.c
index 2ce9902f..585ba781 100644
--- a/src/loslib.c
+++ b/src/loslib.c
@@ -1,5 +1,5 @@
/*
-** $Id: loslib.c,v 1.34 2011/03/03 16:34:46 roberto Exp $
+** $Id: loslib.c,v 1.35 2011/06/20 16:50:59 roberto Exp $
** Standard Operating System library
** See Copyright Notice in lua.h
*/
@@ -21,7 +21,7 @@
/*
-** list of valid conversion specifiers @* for the 'strftime' function
+** list of valid conversion specifiers for the 'strftime' function
*/
#if !defined(LUA_STRFTIMEOPTIONS)
diff --git a/src/lparser.c b/src/lparser.c
index 225e022e..0d4382a4 100644
--- a/src/lparser.c
+++ b/src/lparser.c
@@ -1,5 +1,5 @@
/*
-** $Id: lparser.c,v 2.109 2011/05/02 17:33:01 roberto Exp $
+** $Id: lparser.c,v 2.111 2011/06/20 16:52:48 roberto Exp $
** Lua Parser
** See Copyright Notice in lua.h
*/
@@ -367,7 +367,7 @@ static int findlabel (LexState *ls, int g) {
/* check labels in current block for a match */
for (i = bl->firstlabel; i < dyd->label.n; i++) {
Labeldesc *lb = &dyd->label.arr[i];
- if (eqstr(lb->name, gt->name)) { /* correct label? */
+ if (eqstr(lb->name, gt->name) && lb->pc != -1) { /* correct label? */
if (gt->nactvar > lb->nactvar &&
(bl->upval || dyd->label.n > bl->firstlabel))
luaK_patchclose(ls->fs, gt->pc, lb->nactvar);
@@ -411,7 +411,7 @@ static void findgotos (LexState *ls, Labeldesc *lb) {
/*
** "export" pending gotos to outer level, to check them against
** outer labels; if the block being exited has upvalues, and
-** the goto exists the scope of any variable (which can be the
+** the goto exits the scope of any variable (which can be the
** upvalue), close those variables being exited.
*/
static void movegotosout (FuncState *fs, BlockCnt *bl) {
@@ -460,12 +460,18 @@ static void breaklabel (LexState *ls) {
static void undefgoto (LexState *ls, Labeldesc *gt) {
const char *msg = (gt->name->tsv.reserved > 0)
? "<%s> at line %d not inside a loop"
- : "label " LUA_QS " (<goto> at line %d) undefined";
+ : "no visible label " LUA_QS " for <goto> at line %d";
msg = luaO_pushfstring(ls->L, msg, getstr(gt->name), gt->line);
semerror(ls, msg);
}
+static void invalidatelabels (Labellist *ll, int level) {
+ for (; level < ll->n; level++)
+ ll->arr[level].pc = -1; /* mark label as out of scope */
+}
+
+
static void leaveblock (FuncState *fs) {
BlockCnt *bl = fs->bl;
LexState *ls = fs->ls;
@@ -481,7 +487,7 @@ static void leaveblock (FuncState *fs) {
removevars(fs, bl->nactvar);
lua_assert(bl->nactvar == fs->nactvar);
fs->freereg = fs->nactvar; /* free registers */
- ls->dyd->label.n = bl->firstlabel; /* remove local labels */
+ invalidatelabels(&ls->dyd->label, bl->firstlabel); /* remove local labels */
if (bl->previous) /* inner block? */
movegotosout(fs, bl); /* update pending gotos to outer block */
else if (bl->firstgoto < ls->dyd->gt.n) /* pending gotos in outer block? */
@@ -526,6 +532,7 @@ static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) {
fs->nlocvars = 0;
fs->nactvar = 0;
fs->firstlocal = ls->dyd->actvar.n;
+ fs->firstlabel = ls->dyd->label.n;
fs->bl = NULL;
f = luaF_newproto(L);
fs->f = f;
@@ -548,6 +555,7 @@ static void close_func (LexState *ls) {
Proto *f = fs->f;
luaK_ret(fs, 0, 0); /* final return */
leaveblock(fs);
+ ls->dyd->label.n = fs->firstlabel; /* remove labels */
luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction);
f->sizecode = fs->pc;
luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int);
@@ -1185,13 +1193,11 @@ static void gotostat (LexState *ls, TString *label, int line) {
}
-static void labelstat (LexState *ls, TString *label, int line) {
- /* label -> '@' NAME ':' */
- FuncState *fs = ls->fs;
- Labellist *ll = &ls->dyd->label;
- int l, i; /* index of new label being created */
- /* check for repeated labels on the same block */
- for (i = ls->fs->bl->firstlabel; i < ll->n; i++) {
+/* check for repeated labels on the same function */
+static void checkrepeated (LexState *ls, FuncState *fs, Labellist *ll,
+ TString *label) {
+ int i;
+ for (i = fs->firstlabel; i < ll->n; i++) {
if (eqstr(label, ll->arr[i].name)) {
const char *msg = luaO_pushfstring(ls->L,
"label " LUA_QS " already defined on line %d",
@@ -1199,11 +1205,20 @@ static void labelstat (LexState *ls, TString *label, int line) {
semerror(ls, msg);
}
}
- checknext(ls, ':'); /* skip colon */
+}
+
+
+static void labelstat (LexState *ls, TString *label, int line) {
+ /* label -> '::' NAME '::' */
+ FuncState *fs = ls->fs;
+ Labellist *ll = &ls->dyd->label;
+ int l; /* index of new label being created */
+ checkrepeated(ls, fs, ll, label); /* check for repeated labels */
+ checknext(ls, TK_DBCOLON); /* skip double colon */
/* create new entry for this label */
l = newlabelentry(ls, ll, label, line, fs->pc);
/* skip other no-op statements */
- while (ls->t.token == ';' || ls->t.token == '@')
+ while (ls->t.token == ';' || ls->t.token == TK_DBCOLON)
statement(ls);
if (block_follow(ls, 0)) { /* label is last no-op statement in the block? */
/* assume that locals are already out of scope */
@@ -1537,8 +1552,8 @@ static void statement (LexState *ls) {
localstat(ls);
break;
}
- case '@': { /* stat -> label */
- luaX_next(ls); /* skip '@' */
+ case TK_DBCOLON: { /* stat -> label */
+ luaX_next(ls); /* skip double colon */
labelstat(ls, str_checkname(ls), line);
break;
}
diff --git a/src/lparser.h b/src/lparser.h
index 4e7e06fc..47bbf12d 100644
--- a/src/lparser.h
+++ b/src/lparser.h
@@ -1,5 +1,5 @@
/*
-** $Id: lparser.h,v 1.68 2011/02/23 13:13:10 roberto Exp $
+** $Id: lparser.h,v 1.69 2011/06/16 16:36:39 roberto Exp $
** Lua Parser
** See Copyright Notice in lua.h
*/
@@ -62,7 +62,7 @@ typedef struct Vardesc {
/* description of pending goto statements and label statements */
typedef struct Labeldesc {
TString *name; /* label identifier */
- int pc; /* position in code */
+ int pc; /* position in code (for labels, -1 means out of scope) */
int line; /* line where it appeared */
lu_byte nactvar; /* local level where it appears in current block */
} Labeldesc;
@@ -107,6 +107,7 @@ typedef struct FuncState {
int nk; /* number of elements in `k' */
int np; /* number of elements in `p' */
int firstlocal; /* index of first local var of this function */
+ int firstlabel; /* index of first label of this function */
short nlocvars; /* number of elements in `locvars' */
lu_byte nactvar; /* number of active local variables */
lu_byte nups; /* number of upvalues */
diff --git a/src/lstrlib.c b/src/lstrlib.c
index 369054fd..465f9ff4 100644
--- a/src/lstrlib.c
+++ b/src/lstrlib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lstrlib.c,v 1.168 2011/06/09 18:22:47 roberto Exp $
+** $Id: lstrlib.c,v 1.169 2011/06/16 14:14:05 roberto Exp $
** Standard library for string operations and pattern-matching
** See Copyright Notice in lua.h
*/
@@ -45,7 +45,7 @@ static int str_len (lua_State *L) {
/* translate a relative string position: negative means back from end */
static size_t posrelat (ptrdiff_t pos, size_t len) {
if (pos >= 0) return (size_t)pos;
- else if (-(size_t)pos > len) return 0;
+ else if (0u - (size_t)pos > len) return 0;
else return len - ((size_t)-pos) + 1;
}
diff --git a/src/ltable.c b/src/ltable.c
index 155c2716..a9379596 100644
--- a/src/ltable.c
+++ b/src/ltable.c
@@ -1,5 +1,5 @@
/*
-** $Id: ltable.c,v 2.59 2011/06/09 18:23:27 roberto Exp $
+** $Id: ltable.c,v 2.60 2011/06/16 14:14:31 roberto Exp $
** Lua tables (hash)
** See Copyright Notice in lua.h
*/
@@ -88,7 +88,7 @@ static Node *hashnum (const Table *t, lua_Number n) {
int i;
luai_hashnum(i, n);
if (i < 0) {
- if ((unsigned int)i == -(unsigned int)i)
+ if (cast(unsigned int, i) == 0u - i) /* use unsigned to avoid overflows */
i = 0; /* handle INT_MIN */
i = -i; /* must be a positive value */
}
diff --git a/src/lua.c b/src/lua.c
index 4d098b97..8b317c6a 100644
--- a/src/lua.c
+++ b/src/lua.c
@@ -1,5 +1,5 @@
/*
-** $Id: lua.c,v 1.199 2011/05/26 16:09:40 roberto Exp $
+** $Id: lua.c,v 1.200 2011/06/16 14:30:58 roberto Exp $
** Lua stand-alone interpreter
** See Copyright Notice in lua.h
*/
@@ -183,7 +183,7 @@ static int docall (lua_State *L, int narg, int nres) {
static void print_version (void) {
- luai_writestring(LUA_COPYRIGHT, sizeof(LUA_COPYRIGHT));
+ luai_writestring(LUA_COPYRIGHT, strlen(LUA_COPYRIGHT));
luai_writeline();
}
diff --git a/src/luac.c b/src/luac.c
index 1b28c799..62ff9cc5 100644
--- a/src/luac.c
+++ b/src/luac.c
@@ -1,5 +1,5 @@
/*
-** $Id: luac.c,v 1.66 2011/05/10 01:08:57 lhf Exp $
+** $Id: luac.c,v 1.67 2011/06/21 12:29:00 lhf Exp $
** Lua compiler (saves bytecodes to files; also list bytecodes)
** See Copyright Notice in lua.h
*/
@@ -162,7 +162,7 @@ static int writer(lua_State* L, const void* p, size_t size, void* u)
static int pmain(lua_State* L)
{
int argc=(int)lua_tointeger(L,1);
- char** argv=lua_touserdata(L,2);
+ char** argv=(char**)lua_touserdata(L,2);
const Proto* f;
int i;
if (!lua_checkstack(L,argc)) fatal("too many input files");
@@ -193,7 +193,7 @@ int main(int argc, char* argv[])
argc-=i; argv+=i;
if (argc<=0) usage("no input files given");
L=luaL_newstate();
- if (L==NULL) fatal("not enough memory for state");
+ if (L==NULL) fatal("cannot create state: not enough memory");
lua_pushcfunction(L,&pmain);
lua_pushinteger(L,argc);
lua_pushlightuserdata(L,argv);
diff --git a/src/lundump.c b/src/lundump.c
index ba1a3dc3..d7b0ab3b 100644
--- a/src/lundump.c
+++ b/src/lundump.c
@@ -1,5 +1,5 @@
/*
-** $Id: lundump.c,v 1.69 2011/05/06 13:35:17 lhf Exp $
+** $Id: lundump.c,v 1.70 2011/06/21 12:29:00 lhf Exp $
** load precompiled Lua chunks
** See Copyright Notice in lua.h
*/
@@ -44,7 +44,7 @@ static void error(LoadState* S, const char* why)
static void LoadBlock(LoadState* S, void* b, size_t size)
{
- if (luaZ_read(S->Z,b,size)!=0) error(S,"corrupted");
+ if (luaZ_read(S->Z,b,size)!=0) error(S,"truncated");
}
static int LoadChar(LoadState* S)