From 592a309177edc52847b1196969ad6d49ba21f4fb Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Wed, 5 Dec 2001 18:15:18 -0200 Subject: tag system replaced by event tables --- liolib.c | 58 +++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 43 insertions(+), 15 deletions(-) (limited to 'liolib.c') diff --git a/liolib.c b/liolib.c index 16adf983..a4f6eed5 100644 --- a/liolib.c +++ b/liolib.c @@ -1,5 +1,5 @@ /* -** $Id: liolib.c,v 1.124 2001/10/26 17:33:30 roberto Exp $ +** $Id: liolib.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $ ** Standard I/O (and system) library ** See Copyright Notice in lua.h */ @@ -61,6 +61,7 @@ static int pushresult (lua_State *L, int i) { } + /* ** {====================================================== ** FILE Operations @@ -68,14 +69,30 @@ static int pushresult (lua_State *L, int i) { */ -#define checkfile(L,f) (strcmp(lua_type(L,(f)), FILEHANDLE) == 0) + +static int checkfile (lua_State *L, int findex, const char *tname) { + int res; + lua_geteventtable(L, findex); + lua_pushstring(L, tname); + lua_gettable(L, LUA_REGISTRYINDEX); + res = lua_equal(L, -1, -2); + lua_pop(L, 2); + return res; +} + + +/* temporary?? should be in auxlib... */ +static void *luaL_check_userdata (lua_State *L, int findex, const char *tn) { + luaL_arg_check(L, checkfile(L, findex, tn), findex, "bad file"); + return lua_touserdata(L, findex); +} 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)) { /* not a valid file handle? */ - if (strcmp(lua_type(L, 1), CLOSEDFILEHANDLE) == 0) + if (!checkfile(L, 1, FILEHANDLE)) { /* not a valid file handle? */ + if (checkfile(L, 1, CLOSEDFILEHANDLE)) luaL_argerror(L, 1, "file is closed"); else luaL_argerror(L, 1, "(invalid value)"); @@ -84,7 +101,7 @@ static FILE *getopthandle (lua_State *L, int inout) { } else { /* try global value */ lua_getglobal(L, filenames[inout]); - if (!checkfile(L,-1)) + if (!checkfile(L, -1, FILEHANDLE)) luaL_verror(L, "global variable `%.10s' is not a valid file handle", filenames[inout]); p = (FILE *)(lua_touserdata(L, -1)); @@ -95,7 +112,9 @@ static FILE *getopthandle (lua_State *L, int inout) { static void newfile (lua_State *L, FILE *f) { lua_newuserdatabox(L, f); - lua_settag(L, lua_name2tag(L, FILEHANDLE)); + lua_pushliteral(L, FILEHANDLE); + lua_gettable(L, LUA_REGISTRYINDEX); + lua_seteventtable(L, -2); } @@ -130,7 +149,9 @@ static int io_close (lua_State *L) { int status = 1; if (f != stdin && f != stdout && f != stderr) { lua_settop(L, 1); /* make sure file is on top */ - lua_settag(L, lua_name2tag(L, CLOSEDFILEHANDLE)); + lua_pushliteral(L, CLOSEDFILEHANDLE); + lua_gettable(L, LUA_REGISTRYINDEX); + lua_seteventtable(L, 1); status = (CLOSEFILE(L, f) == 0); } return pushresult(L, status); @@ -301,7 +322,7 @@ static int io_read (lua_State *L) { luaL_check_stack(L, nargs+LUA_MINSTACK, "too many arguments"); success = 1; for (n = 1; n<=nargs && success; n++) { - if (lua_rawtag(L, n) == LUA_TNUMBER) { + if (lua_type(L, n) == LUA_TNUMBER) { size_t l = (size_t)lua_tonumber(L, n); success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l); } @@ -353,7 +374,7 @@ static int io_write (lua_State *L) { int arg; int status = 1; for (arg=1; arg<=nargs; arg++) { - if (lua_rawtag(L, arg) == LUA_TNUMBER) { + if (lua_type(L, arg) == LUA_TNUMBER) { /* optimization: could be done exactly as for strings */ status = status && fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0; @@ -514,7 +535,7 @@ static int io_time (lua_State *L) { else { time_t t; struct tm ts; - luaL_check_rawtype(L, 1, LUA_TTABLE); + luaL_check_type(L, 1, LUA_TTABLE); lua_settop(L, 1); /* make sure table is at the top */ ts.tm_sec = getfield(L, "sec", 0); ts.tm_min = getfield(L, "min", 0); @@ -677,8 +698,18 @@ static const luaL_reg iolib[] = { LUALIB_API int lua_iolibopen (lua_State *L) { - int iotag = lua_newtype(L, FILEHANDLE, LUA_TUSERDATA); - lua_newtype(L, CLOSEDFILEHANDLE, LUA_TUSERDATA); + lua_pushliteral(L, FILEHANDLE); + lua_newtable(L); /* event table for FILEHANDLE */ + /* close files when collected */ + lua_pushliteral(L, "gc"); + lua_pushcfunction(L, file_collect); + lua_settable(L, -3); + /* put new eventtable into registry */ + lua_settable(L, LUA_REGISTRYINDEX); /* registry.FILEHANDLE = eventtable */ + lua_pushliteral(L, CLOSEDFILEHANDLE); + /* event table for CLOSEDFILEHANDLE */ + lua_newtable(L); + lua_settable(L, LUA_REGISTRYINDEX); luaL_openl(L, iolib); /* predefined file handles */ newfilewithname(L, stdin, basicfiles[INFILE]); @@ -686,9 +717,6 @@ LUALIB_API int lua_iolibopen (lua_State *L) { newfilewithname(L, stderr, "_STDERR"); resetfile(L, INFILE); resetfile(L, OUTFILE); - /* close files when collected */ - lua_pushcfunction(L, file_collect); - lua_settagmethod(L, iotag, "gc"); return 0; } -- cgit v1.2.3-55-g6feb