|
|
@ -1,5 +1,5 @@ |
|
|
|
/*
|
|
|
|
** $Id: liolib.c,v 1.111 2001/03/26 14:31:49 roberto Exp roberto $ |
|
|
|
** $Id: liolib.c,v 1.112 2001/04/23 16:35:45 roberto Exp roberto $ |
|
|
|
** Standard I/O (and system) library |
|
|
|
** See Copyright Notice in lua.h |
|
|
|
*/ |
|
|
@ -48,15 +48,17 @@ int pclose(); */ |
|
|
|
#define OUTFILE 1 |
|
|
|
#define NOFILE 2 |
|
|
|
|
|
|
|
#define FILEHANDLE l_s("FileHandle") |
|
|
|
#define FILEHANDLE l_s("FileHandle") |
|
|
|
#define CLOSEDFILEHANDLE l_s("ClosedFileHandle") |
|
|
|
|
|
|
|
|
|
|
|
static const l_char *const filenames[] = {l_s("_INPUT"), l_s("_OUTPUT")}; |
|
|
|
static const l_char *const basicfiles[] = {l_s("_STDIN"), l_s("_STDOUT")}; |
|
|
|
|
|
|
|
|
|
|
|
static int pushresult (lua_State *L, int i) { |
|
|
|
if (i) { |
|
|
|
lua_pushuserdata(L, NULL); |
|
|
|
lua_newuserdatabox(L, NULL); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
else { |
|
|
@ -81,16 +83,15 @@ static int pushresult (lua_State *L, int i) { |
|
|
|
static FILE *getopthandle (lua_State *L, int inout) { |
|
|
|
FILE *p = (FILE *)lua_touserdata(L, 1); |
|
|
|
if (p != NULL) { /* is it a userdata ? */ |
|
|
|
if (!checkfile(L, 1)) { |
|
|
|
if (strcmp(lua_xtypename(L, 1), l_s("ClosedFileHandle")) == 0) |
|
|
|
if (!checkfile(L, 1)) { /* not a valid file handle? */ |
|
|
|
if (strcmp(lua_xtypename(L, 1), CLOSEDFILEHANDLE) == 0) |
|
|
|
luaL_argerror(L, 1, l_s("file is closed")); |
|
|
|
else |
|
|
|
luaL_argerror(L, 1, l_s("(invalid value)")); |
|
|
|
} |
|
|
|
/* move it to stack top */ |
|
|
|
lua_pushvalue(L, 1); lua_remove(L, 1); |
|
|
|
lua_pushvalue(L, 1); lua_remove(L, 1); /* move it to stack top */ |
|
|
|
} |
|
|
|
else if (inout != NOFILE) { /* try global value */ |
|
|
|
else { /* try global value */ |
|
|
|
lua_getglobal(L, filenames[inout]); |
|
|
|
if (!checkfile(L,-1)) |
|
|
|
luaL_verror(L, l_s("global variable `%.10s' is not a valid file handle"), |
|
|
@ -101,46 +102,50 @@ static FILE *getopthandle (lua_State *L, int inout) { |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void pushfile (lua_State *L, FILE *f) { |
|
|
|
lua_pushusertag(L, f, lua_name2tag(L, FILEHANDLE)); |
|
|
|
static void newfile (lua_State *L, FILE *f) { |
|
|
|
lua_newuserdatabox(L, f); |
|
|
|
lua_settag(L, lua_name2tag(L, FILEHANDLE)); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void setfilebyname (lua_State *L, FILE *f, const l_char *name) { |
|
|
|
pushfile(L, f); |
|
|
|
static void newfilewithname (lua_State *L, FILE *f, const l_char *name) { |
|
|
|
newfile(L, f); |
|
|
|
lua_setglobal(L, name); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#define setfile(L,f,inout) (setfilebyname(L,f,filenames[inout])) |
|
|
|
|
|
|
|
|
|
|
|
static int setreturn (lua_State *L, FILE *f, int inout) { |
|
|
|
static int setnewfile (lua_State *L, FILE *f, int inout) { |
|
|
|
if (f == NULL) |
|
|
|
return pushresult(L, 0); |
|
|
|
else { |
|
|
|
if (inout != NOFILE) |
|
|
|
setfile(L, f, inout); |
|
|
|
pushfile(L, f); |
|
|
|
newfile(L, f); |
|
|
|
if (inout != NOFILE) { |
|
|
|
lua_pushvalue(L, -1); |
|
|
|
lua_setglobal(L, filenames[inout]); |
|
|
|
} |
|
|
|
return 1; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static int closefile (lua_State *L, FILE *f) { |
|
|
|
if (f == stdin || f == stdout || f == stderr) |
|
|
|
return 1; |
|
|
|
else { |
|
|
|
lua_pushuserdata(L, f); |
|
|
|
lua_settag(L, lua_name2tag(L, l_s("ClosedFileHandle"))); |
|
|
|
return (CLOSEFILE(L, f) == 0); |
|
|
|
} |
|
|
|
static void resetfile (lua_State *L, int inout) { |
|
|
|
lua_getglobal(L, basicfiles[inout]); |
|
|
|
lua_setglobal(L, filenames[inout]); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static int io_close (lua_State *L) { |
|
|
|
FILE *f = (FILE *)luaL_check_userdata(L, 1, FILEHANDLE); |
|
|
|
return pushresult(L, closefile(L, f)); |
|
|
|
FILE *f; |
|
|
|
int status; |
|
|
|
lua_settop(L, 1); |
|
|
|
f = luaL_check_userdata(L, 1, FILEHANDLE); |
|
|
|
if (f == stdin || f == stdout || f == stderr) |
|
|
|
status = 1; |
|
|
|
else { |
|
|
|
lua_settag(L, lua_name2tag(L, CLOSEDFILEHANDLE)); |
|
|
|
status = (CLOSEFILE(L, f) == 0); |
|
|
|
} |
|
|
|
return pushresult(L, status); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -154,12 +159,12 @@ static int file_collect (lua_State *L) { |
|
|
|
|
|
|
|
static int io_open (lua_State *L) { |
|
|
|
FILE *f = fopen(luaL_check_string(L, 1), luaL_check_string(L, 2)); |
|
|
|
return setreturn(L, f, NOFILE); |
|
|
|
return setnewfile(L, f, NOFILE); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static int io_tmpfile (lua_State *L) { |
|
|
|
return setreturn(L, tmpfile(), NOFILE); |
|
|
|
return setnewfile(L, tmpfile(), NOFILE); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -167,16 +172,15 @@ static int io_tmpfile (lua_State *L) { |
|
|
|
static int io_fromto (lua_State *L, int inout, const l_char *mode) { |
|
|
|
FILE *current; |
|
|
|
if (lua_isnull(L, 1)) { |
|
|
|
closefile(L, getopthandle(L, inout)); |
|
|
|
current = (inout == 0) ? stdin : stdout; |
|
|
|
getopthandle(L, inout); |
|
|
|
resetfile(L, inout); |
|
|
|
return io_close(L); |
|
|
|
} |
|
|
|
else if (checkfile(L, 1)) /* deprecated option */ |
|
|
|
current = (FILE *)lua_touserdata(L, 1); |
|
|
|
else { |
|
|
|
const l_char *s = luaL_check_string(L, 1); |
|
|
|
current = (*s == l_c('|')) ? popen(s+1, mode) : fopen(s, mode); |
|
|
|
return setnewfile(L, current, inout); |
|
|
|
} |
|
|
|
return setreturn(L, current, inout); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -192,7 +196,7 @@ static int io_writeto (lua_State *L) { |
|
|
|
|
|
|
|
static int io_appendto (lua_State *L) { |
|
|
|
FILE *current = fopen(luaL_check_string(L, 1), l_s("a")); |
|
|
|
return setreturn(L, current, OUTFILE); |
|
|
|
return setnewfile(L, current, OUTFILE); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -388,8 +392,8 @@ static int io_seek (lua_State *L) { |
|
|
|
|
|
|
|
|
|
|
|
static int io_flush (lua_State *L) { |
|
|
|
FILE *f = getopthandle(L, NOFILE); |
|
|
|
luaL_arg_check(L, f || lua_isnull(L, 1), 1, l_s("invalid file handle")); |
|
|
|
FILE *f = (lua_isnull(L, 1)) ? (FILE *)NULL : |
|
|
|
(FILE *)luaL_check_userdata(L, 1, FILEHANDLE); |
|
|
|
return pushresult(L, fflush(f) == 0); |
|
|
|
} |
|
|
|
|
|
|
@ -679,14 +683,14 @@ static const luaL_reg iolib[] = { |
|
|
|
|
|
|
|
LUALIB_API int lua_iolibopen (lua_State *L) { |
|
|
|
int iotag = lua_newxtype(L, FILEHANDLE, LUA_TUSERDATA); |
|
|
|
lua_newxtype(L, l_s("ClosedFileHandle"), LUA_TUSERDATA); |
|
|
|
lua_newxtype(L, CLOSEDFILEHANDLE, LUA_TUSERDATA); |
|
|
|
luaL_openl(L, iolib); |
|
|
|
/* predefined file handles */ |
|
|
|
setfile(L, stdin, INFILE); |
|
|
|
setfile(L, stdout, OUTFILE); |
|
|
|
setfilebyname(L, stdin, l_s("_STDIN")); |
|
|
|
setfilebyname(L, stdout, l_s("_STDOUT")); |
|
|
|
setfilebyname(L, stderr, l_s("_STDERR")); |
|
|
|
newfilewithname(L, stdin, basicfiles[INFILE]); |
|
|
|
newfilewithname(L, stdout, basicfiles[OUTFILE]); |
|
|
|
newfilewithname(L, stderr, l_s("_STDERR")); |
|
|
|
resetfile(L, INFILE); |
|
|
|
resetfile(L, OUTFILE); |
|
|
|
/* close files when collected */ |
|
|
|
lua_pushcfunction(L, file_collect); |
|
|
|
lua_settagmethod(L, iotag, l_s("gc")); |
|
|
|