summaryrefslogtreecommitdiff
path: root/liolib.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1999-04-05 16:47:05 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1999-04-05 16:47:05 -0300
commitde04533dc020553a94ecb16480e55e51b1368dbf (patch)
treefc4bf9799f25a7a33405fba850ee8f8eca3557a9 /liolib.c
parent7c9aee64c250e6f56b5788479d62ff9cbc6ad634 (diff)
downloadlua-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.c97
1 files changed, 52 insertions, 45 deletions
diff --git a/liolib.c b/liolib.c
index df6d8c91..85efea5e 100644
--- a/liolib.c
+++ b/liolib.c
@@ -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
44FILE *popen(); 47FILE *popen();
45int pclose(); 48int 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
71static int gettag (void) { 75static 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
120static void rawclose (FILE *f) {
121 if (f != stdin && f != stdout) {
122 if (pclose(f) == -1) fclose(f);
123 }
124}
125
126
127static void closefile (FILE *f) { 123static 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
137static void io_close (void) { 133static void io_close (void) {
138 closefile(getnonullfile(1)); 134 closefile(getnonullfile(FIRSTARG));
139} 135}
140 136
141 137
142static void gc_close (void) { 138static 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
152static void io_open (void) { 146static 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
172static void io_readfrom (void) { 166static 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
193static void io_writeto (void) { 187static 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
214static void io_appendto (void) { 208static 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
318static void io_read (void) { 312static 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
353static void io_write (void) { 347static 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) {
365static void io_seek (void) { 359static 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
380static void io_flush (void) { 374static 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
533static struct luaL_reg iolib[] = { 527static 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
542static 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
557void lua_iolibopen (void) { 555static 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
577void 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