diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1999-04-05 16:47:05 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1999-04-05 16:47:05 -0300 |
commit | de04533dc020553a94ecb16480e55e51b1368dbf (patch) | |
tree | fc4bf9799f25a7a33405fba850ee8f8eca3557a9 /liolib.c | |
parent | 7c9aee64c250e6f56b5788479d62ff9cbc6ad634 (diff) | |
download | lua-de04533dc020553a94ecb16480e55e51b1368dbf.tar.gz lua-de04533dc020553a94ecb16480e55e51b1368dbf.tar.bz2 lua-de04533dc020553a94ecb16480e55e51b1368dbf.zip |
better the old way, using upvalues to keep iotag.
Diffstat (limited to 'liolib.c')
-rw-r--r-- | liolib.c | 97 |
1 files changed, 52 insertions, 45 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: liolib.c,v 1.35 1999/03/16 20:07:54 roberto Exp roberto $ | 2 | ** $Id: liolib.c,v 1.36 1999/03/26 13:48:26 roberto Exp roberto $ |
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 | */ |
@@ -32,21 +32,25 @@ | |||
32 | #endif | 32 | #endif |
33 | 33 | ||
34 | 34 | ||
35 | #define CLOSEDTAG(tag) ((tag)-1) | 35 | #define IOTAG 1 |
36 | |||
37 | #define FIRSTARG 2 /* 1st is upvalue */ | ||
38 | |||
39 | #define CLOSEDTAG(tag) ((tag)-1) /* assume that CLOSEDTAG = iotag-1 */ | ||
36 | 40 | ||
37 | 41 | ||
38 | #define FINPUT "_INPUT" | 42 | #define FINPUT "_INPUT" |
39 | #define FOUTPUT "_OUTPUT" | 43 | #define FOUTPUT "_OUTPUT" |
40 | 44 | ||
41 | #define MODESIZE 3 /* string for file mode */ | ||
42 | 45 | ||
43 | #ifdef POPEN | 46 | #ifdef POPEN |
44 | FILE *popen(); | 47 | FILE *popen(); |
45 | int pclose(); | 48 | int pclose(); |
49 | #define CLOSEFILE(f) {if (pclose(f) == -1) fclose(f);} | ||
46 | #else | 50 | #else |
47 | /* no support for popen */ | 51 | /* no support for popen */ |
48 | #define popen(x,y) NULL /* that is, popen always fails */ | 52 | #define popen(x,y) NULL /* that is, popen always fails */ |
49 | #define pclose(x) (-1) | 53 | #define CLOSEFILE(f) {fclose(f);} |
50 | #endif | 54 | #endif |
51 | 55 | ||
52 | 56 | ||
@@ -69,8 +73,7 @@ static void pushresult (int i) { | |||
69 | */ | 73 | */ |
70 | 74 | ||
71 | static int gettag (void) { | 75 | static int gettag (void) { |
72 | lua_pushusertag(stdin, LUA_ANYTAG); | 76 | return (int)lua_getnumber(lua_getparam(IOTAG)); |
73 | return lua_tag(lua_pop()); /* get the tag of stdin */ | ||
74 | } | 77 | } |
75 | 78 | ||
76 | 79 | ||
@@ -117,17 +120,10 @@ static FILE *getfileparam (char *name, int *arg) { | |||
117 | } | 120 | } |
118 | 121 | ||
119 | 122 | ||
120 | static void rawclose (FILE *f) { | ||
121 | if (f != stdin && f != stdout) { | ||
122 | if (pclose(f) == -1) fclose(f); | ||
123 | } | ||
124 | } | ||
125 | |||
126 | |||
127 | static void closefile (FILE *f) { | 123 | static void closefile (FILE *f) { |
128 | if (f != stdin && f != stdout) { | 124 | if (f != stdin && f != stdout) { |
129 | int tag = gettag(); | 125 | int tag = gettag(); |
130 | rawclose(f); | 126 | CLOSEFILE(f); |
131 | lua_pushusertag(f, tag); | 127 | lua_pushusertag(f, tag); |
132 | lua_settag(CLOSEDTAG(tag)); | 128 | lua_settag(CLOSEDTAG(tag)); |
133 | } | 129 | } |
@@ -135,22 +131,20 @@ static void closefile (FILE *f) { | |||
135 | 131 | ||
136 | 132 | ||
137 | static void io_close (void) { | 133 | static void io_close (void) { |
138 | closefile(getnonullfile(1)); | 134 | closefile(getnonullfile(FIRSTARG)); |
139 | } | 135 | } |
140 | 136 | ||
141 | 137 | ||
142 | static void gc_close (void) { | 138 | static void gc_close (void) { |
143 | int tag = luaL_check_int(1); | 139 | FILE *f = getnonullfile(FIRSTARG); |
144 | lua_Object fh = lua_getparam(2); | 140 | if (f != stdin && f != stdout && f != stderr) { |
145 | FILE *f = lua_getuserdata(fh); | 141 | CLOSEFILE(f); |
146 | luaL_arg_check(lua_isuserdata(fh) && lua_tag(fh) == tag, 2, | 142 | } |
147 | "invalid file handle for GC"); | ||
148 | rawclose(f); | ||
149 | } | 143 | } |
150 | 144 | ||
151 | 145 | ||
152 | static void io_open (void) { | 146 | static void io_open (void) { |
153 | FILE *f = fopen(luaL_check_string(1), luaL_check_string(2)); | 147 | FILE *f = fopen(luaL_check_string(FIRSTARG), luaL_check_string(FIRSTARG+1)); |
154 | if (f) lua_pushusertag(f, gettag()); | 148 | if (f) lua_pushusertag(f, gettag()); |
155 | else pushresult(0); | 149 | else pushresult(0); |
156 | } | 150 | } |
@@ -171,7 +165,7 @@ static void setreturn (FILE *f, char *name) { | |||
171 | 165 | ||
172 | static void io_readfrom (void) { | 166 | static void io_readfrom (void) { |
173 | FILE *current; | 167 | FILE *current; |
174 | lua_Object f = lua_getparam(1); | 168 | lua_Object f = lua_getparam(FIRSTARG); |
175 | if (f == LUA_NOOBJECT) { | 169 | if (f == LUA_NOOBJECT) { |
176 | closefile(getfilebyname(FINPUT)); | 170 | closefile(getfilebyname(FINPUT)); |
177 | current = stdin; | 171 | current = stdin; |
@@ -179,7 +173,7 @@ static void io_readfrom (void) { | |||
179 | else if (lua_tag(f) == gettag()) /* deprecated option */ | 173 | else if (lua_tag(f) == gettag()) /* deprecated option */ |
180 | current = lua_getuserdata(f); | 174 | current = lua_getuserdata(f); |
181 | else { | 175 | else { |
182 | char *s = luaL_check_string(1); | 176 | char *s = luaL_check_string(FIRSTARG); |
183 | current = (*s == '|') ? popen(s+1, "r") : fopen(s, "r"); | 177 | current = (*s == '|') ? popen(s+1, "r") : fopen(s, "r"); |
184 | if (current == NULL) { | 178 | if (current == NULL) { |
185 | pushresult(0); | 179 | pushresult(0); |
@@ -192,7 +186,7 @@ static void io_readfrom (void) { | |||
192 | 186 | ||
193 | static void io_writeto (void) { | 187 | static void io_writeto (void) { |
194 | FILE *current; | 188 | FILE *current; |
195 | lua_Object f = lua_getparam(1); | 189 | lua_Object f = lua_getparam(FIRSTARG); |
196 | if (f == LUA_NOOBJECT) { | 190 | if (f == LUA_NOOBJECT) { |
197 | closefile(getfilebyname(FOUTPUT)); | 191 | closefile(getfilebyname(FOUTPUT)); |
198 | current = stdout; | 192 | current = stdout; |
@@ -200,7 +194,7 @@ static void io_writeto (void) { | |||
200 | else if (lua_tag(f) == gettag()) /* deprecated option */ | 194 | else if (lua_tag(f) == gettag()) /* deprecated option */ |
201 | current = lua_getuserdata(f); | 195 | current = lua_getuserdata(f); |
202 | else { | 196 | else { |
203 | char *s = luaL_check_string(1); | 197 | char *s = luaL_check_string(FIRSTARG); |
204 | current = (*s == '|') ? popen(s+1,"w") : fopen(s, "w"); | 198 | current = (*s == '|') ? popen(s+1,"w") : fopen(s, "w"); |
205 | if (current == NULL) { | 199 | if (current == NULL) { |
206 | pushresult(0); | 200 | pushresult(0); |
@@ -212,7 +206,7 @@ static void io_writeto (void) { | |||
212 | 206 | ||
213 | 207 | ||
214 | static void io_appendto (void) { | 208 | static void io_appendto (void) { |
215 | FILE *fp = fopen(luaL_check_string(1), "a"); | 209 | FILE *fp = fopen(luaL_check_string(FIRSTARG), "a"); |
216 | if (fp != NULL) | 210 | if (fp != NULL) |
217 | setreturn(fp, FOUTPUT); | 211 | setreturn(fp, FOUTPUT); |
218 | else | 212 | else |
@@ -317,7 +311,7 @@ static void read_file (FILE *f) { | |||
317 | 311 | ||
318 | static void io_read (void) { | 312 | static void io_read (void) { |
319 | static char *options[] = {"*n", "*l", "*a", ".*", "*w", NULL}; | 313 | static char *options[] = {"*n", "*l", "*a", ".*", "*w", NULL}; |
320 | int arg = 1; | 314 | int arg = FIRSTARG; |
321 | FILE *f = getfileparam(FINPUT, &arg); | 315 | FILE *f = getfileparam(FINPUT, &arg); |
322 | char *p = luaL_opt_string(arg++, "*l"); | 316 | char *p = luaL_opt_string(arg++, "*l"); |
323 | do { /* repeat for each part */ | 317 | do { /* repeat for each part */ |
@@ -351,7 +345,7 @@ static void io_read (void) { | |||
351 | 345 | ||
352 | 346 | ||
353 | static void io_write (void) { | 347 | static void io_write (void) { |
354 | int arg = 1; | 348 | int arg = FIRSTARG; |
355 | FILE *f = getfileparam(FOUTPUT, &arg); | 349 | FILE *f = getfileparam(FOUTPUT, &arg); |
356 | int status = 1; | 350 | int status = 1; |
357 | char *s; | 351 | char *s; |
@@ -365,10 +359,10 @@ static void io_write (void) { | |||
365 | static void io_seek (void) { | 359 | static void io_seek (void) { |
366 | static int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END}; | 360 | static int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END}; |
367 | static char *modenames[] = {"set", "cur", "end", NULL}; | 361 | static char *modenames[] = {"set", "cur", "end", NULL}; |
368 | FILE *f = getnonullfile(1); | 362 | FILE *f = getnonullfile(FIRSTARG); |
369 | int op = luaL_findstring(luaL_opt_string(2, "cur"), modenames); | 363 | int op = luaL_findstring(luaL_opt_string(FIRSTARG+1, "cur"), modenames); |
370 | long offset = luaL_opt_long(3, 0); | 364 | long offset = luaL_opt_long(FIRSTARG+2, 0); |
371 | luaL_arg_check(op != -1, 2, "invalid mode"); | 365 | luaL_arg_check(op != -1, FIRSTARG+1, "invalid mode"); |
372 | op = fseek(f, offset, mode[op]); | 366 | op = fseek(f, offset, mode[op]); |
373 | if (op) | 367 | if (op) |
374 | pushresult(0); /* error */ | 368 | pushresult(0); /* error */ |
@@ -378,8 +372,8 @@ static void io_seek (void) { | |||
378 | 372 | ||
379 | 373 | ||
380 | static void io_flush (void) { | 374 | static void io_flush (void) { |
381 | FILE *f = getfile(1); | 375 | FILE *f = getfile(FIRSTARG); |
382 | luaL_arg_check(f || lua_getparam(1) == LUA_NOOBJECT, 1, | 376 | luaL_arg_check(f || lua_getparam(FIRSTARG) == LUA_NOOBJECT, FIRSTARG, |
383 | "invalid file handle"); | 377 | "invalid file handle"); |
384 | pushresult(fflush(f) == 0); | 378 | pushresult(fflush(f) == 0); |
385 | } | 379 | } |
@@ -532,44 +526,57 @@ static void errorfb (void) { | |||
532 | 526 | ||
533 | static struct luaL_reg iolib[] = { | 527 | static struct luaL_reg iolib[] = { |
534 | {"_ERRORMESSAGE", errorfb}, | 528 | {"_ERRORMESSAGE", errorfb}, |
535 | {"appendto", io_appendto}, | ||
536 | {"clock", io_clock}, | 529 | {"clock", io_clock}, |
537 | {"closefile", io_close}, | ||
538 | {"date", io_date}, | 530 | {"date", io_date}, |
539 | {"debug", io_debug}, | 531 | {"debug", io_debug}, |
540 | {"execute", io_execute}, | 532 | {"execute", io_execute}, |
541 | {"exit", io_exit}, | 533 | {"exit", io_exit}, |
542 | {"flush", io_flush}, | ||
543 | {"getenv", io_getenv}, | 534 | {"getenv", io_getenv}, |
535 | {"remove", io_remove}, | ||
536 | {"rename", io_rename}, | ||
537 | {"setlocale", setloc}, | ||
538 | {"tmpname", io_tmpname} | ||
539 | }; | ||
540 | |||
541 | |||
542 | static struct luaL_reg iolibtag[] = { | ||
543 | {"appendto", io_appendto}, | ||
544 | {"closefile", io_close}, | ||
545 | {"flush", io_flush}, | ||
544 | {"openfile", io_open}, | 546 | {"openfile", io_open}, |
545 | {"read", io_read}, | 547 | {"read", io_read}, |
546 | {"readfrom", io_readfrom}, | 548 | {"readfrom", io_readfrom}, |
547 | {"remove", io_remove}, | ||
548 | {"rename", io_rename}, | ||
549 | {"seek", io_seek}, | 549 | {"seek", io_seek}, |
550 | {"setlocale", setloc}, | ||
551 | {"tmpname", io_tmpname}, | ||
552 | {"write", io_write}, | 550 | {"write", io_write}, |
553 | {"writeto", io_writeto} | 551 | {"writeto", io_writeto} |
554 | }; | 552 | }; |
555 | 553 | ||
556 | 554 | ||
557 | void lua_iolibopen (void) { | 555 | static void openwithtags (void) { |
556 | int i; | ||
558 | int iotag = lua_newtag(); | 557 | int iotag = lua_newtag(); |
559 | lua_newtag(); /* alloc CLOSEDTAG: assume that CLOSEDTAG = iotag-1 */ | 558 | lua_newtag(); /* alloc CLOSEDTAG: assume that CLOSEDTAG = iotag-1 */ |
559 | for (i=0; i<sizeof(iolibtag)/sizeof(iolibtag[0]); i++) { | ||
560 | /* put iotag as upvalue for these functions */ | ||
561 | lua_pushnumber(iotag); | ||
562 | lua_pushcclosure(iolibtag[i].func, 1); | ||
563 | lua_setglobal(iolibtag[i].name); | ||
564 | } | ||
560 | /* predefined file handles */ | 565 | /* predefined file handles */ |
561 | setfile(stdin, FINPUT, iotag); | 566 | setfile(stdin, FINPUT, iotag); |
562 | setfile(stdout, FOUTPUT, iotag); | 567 | setfile(stdout, FOUTPUT, iotag); |
563 | setfile(stdin, "_STDIN", iotag); | 568 | setfile(stdin, "_STDIN", iotag); |
564 | setfile(stdout, "_STDOUT", iotag); | 569 | setfile(stdout, "_STDOUT", iotag); |
565 | setfile(stderr, "_STDERR", iotag); | 570 | setfile(stderr, "_STDERR", iotag); |
566 | /* make sure stdin (with its tag) won't be collected */ | ||
567 | lua_pushusertag(stdin, iotag); lua_ref(1); | ||
568 | /* close file when collected */ | 571 | /* close file when collected */ |
569 | lua_pushnumber(iotag); | 572 | lua_pushnumber(iotag); |
570 | lua_pushcclosure(gc_close, 1); | 573 | lua_pushcclosure(gc_close, 1); |
571 | lua_settagmethod(iotag, "gc"); | 574 | lua_settagmethod(iotag, "gc"); |
575 | } | ||
576 | |||
577 | void lua_iolibopen (void) { | ||
572 | /* register lib functions */ | 578 | /* register lib functions */ |
573 | luaL_openlib(iolib, (sizeof(iolib)/sizeof(iolib[0]))); | 579 | luaL_openlib(iolib, (sizeof(iolib)/sizeof(iolib[0]))); |
580 | openwithtags(); | ||
574 | } | 581 | } |
575 | 582 | ||