aboutsummaryrefslogtreecommitdiff
path: root/liolib.c
diff options
context:
space:
mode:
Diffstat (limited to 'liolib.c')
-rw-r--r--liolib.c58
1 files changed, 43 insertions, 15 deletions
diff --git a/liolib.c b/liolib.c
index 16adf983..a4f6eed5 100644
--- a/liolib.c
+++ b/liolib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: liolib.c,v 1.124 2001/10/26 17:33:30 roberto Exp $ 2** $Id: liolib.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
3** Standard I/O (and system) library 3** Standard I/O (and system) library
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -61,6 +61,7 @@ static int pushresult (lua_State *L, int i) {
61} 61}
62 62
63 63
64
64/* 65/*
65** {====================================================== 66** {======================================================
66** FILE Operations 67** FILE Operations
@@ -68,14 +69,30 @@ static int pushresult (lua_State *L, int i) {
68*/ 69*/
69 70
70 71
71#define checkfile(L,f) (strcmp(lua_type(L,(f)), FILEHANDLE) == 0) 72
73static int checkfile (lua_State *L, int findex, const char *tname) {
74 int res;
75 lua_geteventtable(L, findex);
76 lua_pushstring(L, tname);
77 lua_gettable(L, LUA_REGISTRYINDEX);
78 res = lua_equal(L, -1, -2);
79 lua_pop(L, 2);
80 return res;
81}
82
83
84/* temporary?? should be in auxlib... */
85static void *luaL_check_userdata (lua_State *L, int findex, const char *tn) {
86 luaL_arg_check(L, checkfile(L, findex, tn), findex, "bad file");
87 return lua_touserdata(L, findex);
88}
72 89
73 90
74static FILE *getopthandle (lua_State *L, int inout) { 91static FILE *getopthandle (lua_State *L, int inout) {
75 FILE *p = (FILE *)(lua_touserdata(L, 1)); 92 FILE *p = (FILE *)(lua_touserdata(L, 1));
76 if (p != NULL) { /* is it a userdata ? */ 93 if (p != NULL) { /* is it a userdata ? */
77 if (!checkfile(L, 1)) { /* not a valid file handle? */ 94 if (!checkfile(L, 1, FILEHANDLE)) { /* not a valid file handle? */
78 if (strcmp(lua_type(L, 1), CLOSEDFILEHANDLE) == 0) 95 if (checkfile(L, 1, CLOSEDFILEHANDLE))
79 luaL_argerror(L, 1, "file is closed"); 96 luaL_argerror(L, 1, "file is closed");
80 else 97 else
81 luaL_argerror(L, 1, "(invalid value)"); 98 luaL_argerror(L, 1, "(invalid value)");
@@ -84,7 +101,7 @@ static FILE *getopthandle (lua_State *L, int inout) {
84 } 101 }
85 else { /* try global value */ 102 else { /* try global value */
86 lua_getglobal(L, filenames[inout]); 103 lua_getglobal(L, filenames[inout]);
87 if (!checkfile(L,-1)) 104 if (!checkfile(L, -1, FILEHANDLE))
88 luaL_verror(L, "global variable `%.10s' is not a valid file handle", 105 luaL_verror(L, "global variable `%.10s' is not a valid file handle",
89 filenames[inout]); 106 filenames[inout]);
90 p = (FILE *)(lua_touserdata(L, -1)); 107 p = (FILE *)(lua_touserdata(L, -1));
@@ -95,7 +112,9 @@ static FILE *getopthandle (lua_State *L, int inout) {
95 112
96static void newfile (lua_State *L, FILE *f) { 113static void newfile (lua_State *L, FILE *f) {
97 lua_newuserdatabox(L, f); 114 lua_newuserdatabox(L, f);
98 lua_settag(L, lua_name2tag(L, FILEHANDLE)); 115 lua_pushliteral(L, FILEHANDLE);
116 lua_gettable(L, LUA_REGISTRYINDEX);
117 lua_seteventtable(L, -2);
99} 118}
100 119
101 120
@@ -130,7 +149,9 @@ static int io_close (lua_State *L) {
130 int status = 1; 149 int status = 1;
131 if (f != stdin && f != stdout && f != stderr) { 150 if (f != stdin && f != stdout && f != stderr) {
132 lua_settop(L, 1); /* make sure file is on top */ 151 lua_settop(L, 1); /* make sure file is on top */
133 lua_settag(L, lua_name2tag(L, CLOSEDFILEHANDLE)); 152 lua_pushliteral(L, CLOSEDFILEHANDLE);
153 lua_gettable(L, LUA_REGISTRYINDEX);
154 lua_seteventtable(L, 1);
134 status = (CLOSEFILE(L, f) == 0); 155 status = (CLOSEFILE(L, f) == 0);
135 } 156 }
136 return pushresult(L, status); 157 return pushresult(L, status);
@@ -301,7 +322,7 @@ static int io_read (lua_State *L) {
301 luaL_check_stack(L, nargs+LUA_MINSTACK, "too many arguments"); 322 luaL_check_stack(L, nargs+LUA_MINSTACK, "too many arguments");
302 success = 1; 323 success = 1;
303 for (n = 1; n<=nargs && success; n++) { 324 for (n = 1; n<=nargs && success; n++) {
304 if (lua_rawtag(L, n) == LUA_TNUMBER) { 325 if (lua_type(L, n) == LUA_TNUMBER) {
305 size_t l = (size_t)lua_tonumber(L, n); 326 size_t l = (size_t)lua_tonumber(L, n);
306 success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l); 327 success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l);
307 } 328 }
@@ -353,7 +374,7 @@ static int io_write (lua_State *L) {
353 int arg; 374 int arg;
354 int status = 1; 375 int status = 1;
355 for (arg=1; arg<=nargs; arg++) { 376 for (arg=1; arg<=nargs; arg++) {
356 if (lua_rawtag(L, arg) == LUA_TNUMBER) { 377 if (lua_type(L, arg) == LUA_TNUMBER) {
357 /* optimization: could be done exactly as for strings */ 378 /* optimization: could be done exactly as for strings */
358 status = status && 379 status = status &&
359 fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0; 380 fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0;
@@ -514,7 +535,7 @@ static int io_time (lua_State *L) {
514 else { 535 else {
515 time_t t; 536 time_t t;
516 struct tm ts; 537 struct tm ts;
517 luaL_check_rawtype(L, 1, LUA_TTABLE); 538 luaL_check_type(L, 1, LUA_TTABLE);
518 lua_settop(L, 1); /* make sure table is at the top */ 539 lua_settop(L, 1); /* make sure table is at the top */
519 ts.tm_sec = getfield(L, "sec", 0); 540 ts.tm_sec = getfield(L, "sec", 0);
520 ts.tm_min = getfield(L, "min", 0); 541 ts.tm_min = getfield(L, "min", 0);
@@ -677,8 +698,18 @@ static const luaL_reg iolib[] = {
677 698
678 699
679LUALIB_API int lua_iolibopen (lua_State *L) { 700LUALIB_API int lua_iolibopen (lua_State *L) {
680 int iotag = lua_newtype(L, FILEHANDLE, LUA_TUSERDATA); 701 lua_pushliteral(L, FILEHANDLE);
681 lua_newtype(L, CLOSEDFILEHANDLE, LUA_TUSERDATA); 702 lua_newtable(L); /* event table for FILEHANDLE */
703 /* close files when collected */
704 lua_pushliteral(L, "gc");
705 lua_pushcfunction(L, file_collect);
706 lua_settable(L, -3);
707 /* put new eventtable into registry */
708 lua_settable(L, LUA_REGISTRYINDEX); /* registry.FILEHANDLE = eventtable */
709 lua_pushliteral(L, CLOSEDFILEHANDLE);
710 /* event table for CLOSEDFILEHANDLE */
711 lua_newtable(L);
712 lua_settable(L, LUA_REGISTRYINDEX);
682 luaL_openl(L, iolib); 713 luaL_openl(L, iolib);
683 /* predefined file handles */ 714 /* predefined file handles */
684 newfilewithname(L, stdin, basicfiles[INFILE]); 715 newfilewithname(L, stdin, basicfiles[INFILE]);
@@ -686,9 +717,6 @@ LUALIB_API int lua_iolibopen (lua_State *L) {
686 newfilewithname(L, stderr, "_STDERR"); 717 newfilewithname(L, stderr, "_STDERR");
687 resetfile(L, INFILE); 718 resetfile(L, INFILE);
688 resetfile(L, OUTFILE); 719 resetfile(L, OUTFILE);
689 /* close files when collected */
690 lua_pushcfunction(L, file_collect);
691 lua_settagmethod(L, iotag, "gc");
692 return 0; 720 return 0;
693} 721}
694 722