tag system replaced by event tables

This commit is contained in:
Roberto Ierusalimschy
2001-12-05 18:15:18 -02:00
parent 413fc7334b
commit 592a309177
24 changed files with 417 additions and 711 deletions

View File

@@ -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;
}