From d5b83ead90fba27faa344c72406d85987d2460a4 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Wed, 6 Jun 2001 15:00:19 -0300 Subject: new implementation for userdatas, without `keys' --- liolib.c | 94 +++++++++++++++++++++++++++++++++------------------------------- 1 file changed, 49 insertions(+), 45 deletions(-) (limited to 'liolib.c') diff --git a/liolib.c b/liolib.c index fa9830bf..dda79529 100644 --- a/liolib.c +++ b/liolib.c @@ -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")); -- cgit v1.2.3-55-g6feb