diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-08-29 11:33:31 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-08-29 11:33:31 -0300 |
commit | ac12f4db4b2f715b1556722b6ed65804cfd6348a (patch) | |
tree | 4c15a7988e19c766ed9e88451db92140200fd041 /liolib.c | |
parent | b691d4344bb67a1a09203466812877595b3bd744 (diff) | |
download | lua-ac12f4db4b2f715b1556722b6ed65804cfd6348a.tar.gz lua-ac12f4db4b2f715b1556722b6ed65804cfd6348a.tar.bz2 lua-ac12f4db4b2f715b1556722b6ed65804cfd6348a.zip |
C upvalues are the last arguments to a function
Diffstat (limited to 'liolib.c')
-rw-r--r-- | liolib.c | 100 |
1 files changed, 58 insertions, 42 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: liolib.c,v 1.71 2000/08/22 17:47:17 roberto Exp roberto $ | 2 | ** $Id: liolib.c,v 1.72 2000/08/28 17:57:04 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 | */ |
@@ -109,7 +109,6 @@ static FILE *getfilebyref (lua_State *L, IOCtrl *ctrl, int inout) { | |||
109 | lua_getref(L, ctrl->ref[inout]); | 109 | lua_getref(L, ctrl->ref[inout]); |
110 | lua_rawget(L); | 110 | lua_rawget(L); |
111 | f = gethandle(L, ctrl, -1); | 111 | f = gethandle(L, ctrl, -1); |
112 | lua_settop(L, -1); /* remove global */ | ||
113 | if (f == NULL) | 112 | if (f == NULL) |
114 | luaL_verror(L, "global variable `%.10s' is not a file handle", | 113 | luaL_verror(L, "global variable `%.10s' is not a file handle", |
115 | filenames[inout]); | 114 | filenames[inout]); |
@@ -150,21 +149,23 @@ static int closefile (lua_State *L, IOCtrl *ctrl, FILE *f) { | |||
150 | 149 | ||
151 | 150 | ||
152 | static int io_close (lua_State *L) { | 151 | static int io_close (lua_State *L) { |
153 | IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, 1); | 152 | IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1); |
154 | return pushresult(L, closefile(L, ctrl, getnonullfile(L, ctrl, 2))); | 153 | lua_settop(L, -1); /* remove upvalue */ |
154 | return pushresult(L, closefile(L, ctrl, getnonullfile(L, ctrl, 1))); | ||
155 | } | 155 | } |
156 | 156 | ||
157 | 157 | ||
158 | static int file_collect (lua_State *L) { | 158 | static int file_collect (lua_State *L) { |
159 | IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, 1); | 159 | IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1); |
160 | if (ctrl == (IOCtrl *)lua_touserdata(L, 2)) { | 160 | lua_settop(L, -1); /* remove upvalue */ |
161 | if (ctrl == (IOCtrl *)lua_touserdata(L, 1)) { | ||
161 | /* collectig `ctrl' itself */ | 162 | /* collectig `ctrl' itself */ |
162 | lua_unref(L, ctrl->ref[INFILE]); | 163 | lua_unref(L, ctrl->ref[INFILE]); |
163 | lua_unref(L, ctrl->ref[OUTFILE]); | 164 | lua_unref(L, ctrl->ref[OUTFILE]); |
164 | free(ctrl); | 165 | free(ctrl); |
165 | } | 166 | } |
166 | else { /* collecting a file: Close it */ | 167 | else { /* collecting a file: Close it */ |
167 | FILE *f = getnonullfile(L, ctrl, 2); | 168 | FILE *f = getnonullfile(L, ctrl, 1); |
168 | if (f != stdin && f != stdout && f != stderr) | 169 | if (f != stdin && f != stdout && f != stderr) |
169 | CLOSEFILE(L, f); | 170 | CLOSEFILE(L, f); |
170 | } | 171 | } |
@@ -173,8 +174,10 @@ static int file_collect (lua_State *L) { | |||
173 | 174 | ||
174 | 175 | ||
175 | static int io_open (lua_State *L) { | 176 | static int io_open (lua_State *L) { |
176 | IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, 1); | 177 | IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1); |
177 | FILE *f = fopen(luaL_check_string(L, 2), luaL_check_string(L, 3)); | 178 | FILE *f; |
179 | lua_settop(L, -1); /* remove upvalue */ | ||
180 | f = fopen(luaL_check_string(L, 1), luaL_check_string(L, 2)); | ||
178 | if (f) { | 181 | if (f) { |
179 | lua_pushusertag(L, f, ctrl->iotag); | 182 | lua_pushusertag(L, f, ctrl->iotag); |
180 | return 1; | 183 | return 1; |
@@ -186,16 +189,17 @@ static int io_open (lua_State *L) { | |||
186 | 189 | ||
187 | 190 | ||
188 | static int io_fromto (lua_State *L, int inout, const char *mode) { | 191 | static int io_fromto (lua_State *L, int inout, const char *mode) { |
189 | IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, 1); | 192 | IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1); |
190 | FILE *current; | 193 | FILE *current; |
191 | if (lua_isnull(L, 2)) { | 194 | lua_settop(L, -1); /* remove upvalue */ |
195 | if (lua_isnull(L, 1)) { | ||
192 | closefile(L, ctrl, getfilebyref(L, ctrl, inout)); | 196 | closefile(L, ctrl, getfilebyref(L, ctrl, inout)); |
193 | current = (inout == 0) ? stdin : stdout; | 197 | current = (inout == 0) ? stdin : stdout; |
194 | } | 198 | } |
195 | else if (lua_tag(L, 2) == ctrl->iotag) /* deprecated option */ | 199 | else if (lua_tag(L, 1) == ctrl->iotag) /* deprecated option */ |
196 | current = (FILE *)lua_touserdata(L, 2); | 200 | current = (FILE *)lua_touserdata(L, 1); |
197 | else { | 201 | else { |
198 | const char *s = luaL_check_string(L, 2); | 202 | const char *s = luaL_check_string(L, 1); |
199 | current = (*s == '|') ? popen(s+1, mode) : fopen(s, mode); | 203 | current = (*s == '|') ? popen(s+1, mode) : fopen(s, mode); |
200 | } | 204 | } |
201 | return setreturn(L, ctrl, current, inout); | 205 | return setreturn(L, ctrl, current, inout); |
@@ -213,8 +217,10 @@ static int io_writeto (lua_State *L) { | |||
213 | 217 | ||
214 | 218 | ||
215 | static int io_appendto (lua_State *L) { | 219 | static int io_appendto (lua_State *L) { |
216 | IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, 1); | 220 | IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1); |
217 | FILE *current = fopen(luaL_check_string(L, 2), "a"); | 221 | FILE *current; |
222 | lua_settop(L, -1); /* remove upvalue */ | ||
223 | current = fopen(luaL_check_string(L, 1), "a"); | ||
218 | return setreturn(L, ctrl, current, OUTFILE); | 224 | return setreturn(L, ctrl, current, OUTFILE); |
219 | } | 225 | } |
220 | 226 | ||
@@ -353,28 +359,33 @@ static int read_chars (lua_State *L, FILE *f, size_t n) { | |||
353 | 359 | ||
354 | 360 | ||
355 | static int io_read (lua_State *L) { | 361 | static int io_read (lua_State *L) { |
356 | IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, 1); | 362 | IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1); |
357 | int lastarg = lua_gettop(L); | 363 | int lastarg = lua_gettop(L) - 1; |
358 | int firstarg = 2; | 364 | int firstarg = 1; |
359 | FILE *f = gethandle(L, ctrl, firstarg); | 365 | FILE *f = gethandle(L, ctrl, firstarg); |
360 | int n = 0; | 366 | int n; |
361 | if (f) firstarg++; | 367 | if (f) firstarg++; |
362 | else f = getfilebyref(L, ctrl, INFILE); /* get _INPUT */ | 368 | else f = getfilebyref(L, ctrl, INFILE); /* get _INPUT */ |
363 | do { /* repeat for each part */ | 369 | lua_settop(L, -1); |
370 | if (firstarg > lastarg) { /* no arguments? */ | ||
371 | lua_settop(L, 0); /* erase upvalue and other eventual garbage */ | ||
372 | firstarg = lastarg = 1; /* correct indices */ | ||
373 | lua_pushstring(L, "*l"); /* push default argument */ | ||
374 | } | ||
375 | for (n = firstarg; n<=lastarg; n++) { | ||
364 | size_t l; | 376 | size_t l; |
365 | int success; | 377 | int success; |
366 | luaL_resetbuffer(L); | 378 | luaL_resetbuffer(L); |
367 | if (lua_isnumber(L, firstarg+n)) | 379 | if (lua_isnumber(L, n)) |
368 | success = read_chars(L, f, (size_t)lua_tonumber(L, firstarg+n)); | 380 | success = read_chars(L, f, (size_t)lua_tonumber(L, n)); |
369 | else { | 381 | else { |
370 | const char *p = luaL_opt_string(L, firstarg+n, "*l"); | 382 | const char *p = luaL_check_string(L, n); |
371 | if (p[0] != '*') | 383 | if (p[0] != '*') |
372 | success = read_pattern(L, f, p); /* deprecated! */ | 384 | success = read_pattern(L, f, p); /* deprecated! */ |
373 | else { | 385 | else { |
374 | switch (p[1]) { | 386 | switch (p[1]) { |
375 | case 'n': /* number */ | 387 | case 'n': /* number */ |
376 | if (!read_number(L, f)) return n; /* read fails */ | 388 | if (!read_number(L, f)) goto endloop; /* read fails */ |
377 | n++; | ||
378 | continue; /* number is already pushed; avoid the "pushstring" */ | 389 | continue; /* number is already pushed; avoid the "pushstring" */ |
379 | case 'l': /* line */ | 390 | case 'l': /* line */ |
380 | success = read_line(L, f); | 391 | success = read_line(L, f); |
@@ -388,26 +399,25 @@ static int io_read (lua_State *L) { | |||
388 | success = 0; /* must read something to succeed */ | 399 | success = 0; /* must read something to succeed */ |
389 | break; | 400 | break; |
390 | default: | 401 | default: |
391 | luaL_argerror(L, firstarg+n, "invalid format"); | 402 | luaL_argerror(L, n, "invalid format"); |
392 | success = 0; /* to avoid warnings */ | 403 | success = 0; /* to avoid warnings */ |
393 | } | 404 | } |
394 | } | 405 | } |
395 | } | 406 | } |
396 | l = luaL_getsize(L); | 407 | l = luaL_getsize(L); |
397 | if (!success && l==0) return n; /* read fails */ | 408 | if (!success && l==0) break; /* read fails */ |
398 | lua_pushlstring(L, luaL_buffer(L), l); | 409 | lua_pushlstring(L, luaL_buffer(L), l); |
399 | n++; | 410 | } endloop: |
400 | } while (firstarg+n <= lastarg); | 411 | return n - firstarg; |
401 | return n; | ||
402 | } | 412 | } |
403 | 413 | ||
404 | /* }====================================================== */ | 414 | /* }====================================================== */ |
405 | 415 | ||
406 | 416 | ||
407 | static int io_write (lua_State *L) { | 417 | static int io_write (lua_State *L) { |
408 | int lastarg = lua_gettop(L); | 418 | int lastarg = lua_gettop(L) - 1; |
409 | IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, 1); | 419 | IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1); |
410 | int arg = 2; | 420 | int arg = 1; |
411 | int status = 1; | 421 | int status = 1; |
412 | FILE *f = gethandle(L, ctrl, arg); | 422 | FILE *f = gethandle(L, ctrl, arg); |
413 | if (f) arg++; | 423 | if (f) arg++; |
@@ -431,11 +441,15 @@ static int io_write (lua_State *L) { | |||
431 | static int io_seek (lua_State *L) { | 441 | static int io_seek (lua_State *L) { |
432 | static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END}; | 442 | static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END}; |
433 | static const char *const modenames[] = {"set", "cur", "end", NULL}; | 443 | static const char *const modenames[] = {"set", "cur", "end", NULL}; |
434 | IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, 1); | 444 | IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1); |
435 | FILE *f = getnonullfile(L, ctrl, 2); | 445 | FILE *f; |
436 | int op = luaL_findstring(luaL_opt_string(L, 3, "cur"), modenames); | 446 | int op; |
437 | long offset = luaL_opt_long(L, 4, 0); | 447 | long offset; |
438 | luaL_arg_check(L, op != -1, 3, "invalid mode"); | 448 | lua_settop(L, -1); /* remove upvalue */ |
449 | f = getnonullfile(L, ctrl, 1); | ||
450 | op = luaL_findstring(luaL_opt_string(L, 2, "cur"), modenames); | ||
451 | offset = luaL_opt_long(L, 3, 0); | ||
452 | luaL_arg_check(L, op != -1, 2, "invalid mode"); | ||
439 | op = fseek(f, offset, mode[op]); | 453 | op = fseek(f, offset, mode[op]); |
440 | if (op) | 454 | if (op) |
441 | return pushresult(L, 0); /* error */ | 455 | return pushresult(L, 0); /* error */ |
@@ -447,9 +461,11 @@ static int io_seek (lua_State *L) { | |||
447 | 461 | ||
448 | 462 | ||
449 | static int io_flush (lua_State *L) { | 463 | static int io_flush (lua_State *L) { |
450 | IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, 1); | 464 | IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1); |
451 | FILE *f = gethandle(L, ctrl, 2); | 465 | FILE *f; |
452 | luaL_arg_check(L, f || lua_isnull(L, 2), 2, "invalid file handle"); | 466 | lua_settop(L, -1); /* remove upvalue */ |
467 | f = gethandle(L, ctrl, 1); | ||
468 | luaL_arg_check(L, f || lua_isnull(L, 1), 1, "invalid file handle"); | ||
453 | return pushresult(L, fflush(f) == 0); | 469 | return pushresult(L, fflush(f) == 0); |
454 | } | 470 | } |
455 | 471 | ||