lua

A copy of the Lua development repository
Log | Files | Refs | README

commit d9340154accd593984fa0d2101fe5f3b63f4c3a2
parent e47baca75a3854c9f3065c554d6758bd23c5d73f
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date:   Mon, 25 Nov 2002 13:05:17 -0200

`__tostring' for files + small bug (could do invalid read inside
a userdata when it was not a file)

Diffstat:
Mliolib.c | 55+++++++++++++++++++++++++++++++++++--------------------
1 file changed, 35 insertions(+), 20 deletions(-)

diff --git a/liolib.c b/liolib.c @@ -1,5 +1,5 @@ /* -** $Id: liolib.c,v 2.23 2002/11/14 15:41:38 roberto Exp roberto $ +** $Id: liolib.c,v 2.24 2002/11/18 16:53:19 roberto Exp roberto $ ** Standard I/O (and system) library ** See Copyright Notice in lua.h */ @@ -54,23 +54,26 @@ static int pushresult (lua_State *L, int i, const char *filename) { } -static FILE *tofile (lua_State *L, int findex) { +static FILE **topfile (lua_State *L, int findex) { FILE **f = (FILE **)lua_touserdata(L, findex); - if (f && *f && lua_getmetatable(L, findex) && - lua_rawequal(L, -1, lua_upvalueindex(1))) { - lua_pop(L, 1); - return *f; - } - if (findex > 0) { - if (f && *f == NULL) - luaL_error(L, "attempt to use a closed file"); - else - luaL_argerror(L, findex, "bad file"); + if (f == NULL || !lua_getmetatable(L, findex) || + !lua_rawequal(L, -1, lua_upvalueindex(1))) { + luaL_argerror(L, findex, "bad file"); } - return NULL; + lua_pop(L, 1); + return f; +} + + +static FILE *tofile (lua_State *L, int findex) { + FILE **f = topfile(L, findex); + if (*f == NULL) + luaL_error(L, "attempt to use a closed file"); + return *f; } + /* ** When creating file handles, always creates a `closed' file handle ** before opening the actual file; so, if there is a memory error, the @@ -126,13 +129,25 @@ static int io_close (lua_State *L) { static int io_gc (lua_State *L) { - FILE **f = (FILE **)lua_touserdata(L, 1); - if (!(f && *f == NULL)) /* ignore closed files */ + FILE **f = topfile(L, 1); + if (*f != NULL) /* ignore closed files */ aux_close(L); return 0; } +static int io_tostring (lua_State *L) { + char buff[32]; + FILE **f = topfile(L, 1); + if (*f == NULL) + strcpy(buff, "closed"); + else + sprintf(buff, "%p", lua_touserdata(L, 1)); + lua_pushfstring(L, "file (%s)", buff); + return 1; +} + + static int io_open (lua_State *L) { const char *filename = luaL_checkstring(L, 1); const char *mode = luaL_optstring(L, 2, "r"); @@ -164,13 +179,9 @@ static int io_tmpfile (lua_State *L) { static FILE *getiofile (lua_State *L, const char *name) { - FILE *f; lua_pushstring(L, name); lua_rawget(L, lua_upvalueindex(1)); - f = tofile(L, -1); - if (f == NULL) - luaL_error(L, "%s is closed", name); - return f; + return tofile(L, -1); } @@ -478,6 +489,10 @@ static void createmeta (lua_State *L) { lua_pushvalue(L, -2); /* push metatable (will be upvalue for `gc' method) */ lua_pushcclosure(L, io_gc, 1); lua_rawset(L, -3); /* metatable.__gc = io_gc */ + lua_pushliteral(L, "__tostring"); + lua_pushvalue(L, -2); /* push metatable */ + lua_pushcclosure(L, io_tostring, 1); + lua_rawset(L, -3); /* file methods */ lua_pushliteral(L, "__index"); lua_pushvalue(L, -2); /* push metatable */