diff options
Diffstat (limited to 'liolib.c')
-rw-r--r-- | liolib.c | 58 |
1 files changed, 43 insertions, 15 deletions
@@ -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 | |
73 | static 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... */ | ||
85 | static 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 | ||
74 | static FILE *getopthandle (lua_State *L, int inout) { | 91 | static 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 | ||
96 | static void newfile (lua_State *L, FILE *f) { | 113 | static 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 | ||
679 | LUALIB_API int lua_iolibopen (lua_State *L) { | 700 | LUALIB_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 | ||