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 | ||
