diff options
Diffstat (limited to 'src/lib_io.c')
-rw-r--r-- | src/lib_io.c | 59 |
1 files changed, 35 insertions, 24 deletions
diff --git a/src/lib_io.c b/src/lib_io.c index e0762297..8911958f 100644 --- a/src/lib_io.c +++ b/src/lib_io.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include "lj_obj.h" | 19 | #include "lj_obj.h" |
20 | #include "lj_err.h" | 20 | #include "lj_err.h" |
21 | #include "lj_str.h" | 21 | #include "lj_str.h" |
22 | #include "lj_state.h" | ||
22 | #include "lj_ff.h" | 23 | #include "lj_ff.h" |
23 | #include "lj_lib.h" | 24 | #include "lj_lib.h" |
24 | 25 | ||
@@ -253,6 +254,31 @@ static int io_file_write(lua_State *L, FILE *fp, int start) | |||
253 | return luaL_fileresult(L, status, NULL); | 254 | return luaL_fileresult(L, status, NULL); |
254 | } | 255 | } |
255 | 256 | ||
257 | static int io_file_iter(lua_State *L) | ||
258 | { | ||
259 | GCfunc *fn = curr_func(L); | ||
260 | IOFileUD *iof = uddata(udataV(&fn->c.upvalue[0])); | ||
261 | int n = fn->c.nupvalues - 1; | ||
262 | if (iof->fp == NULL) | ||
263 | lj_err_caller(L, LJ_ERR_IOCLFL); | ||
264 | L->top = L->base; | ||
265 | if (n) { /* Copy upvalues with options to stack. */ | ||
266 | if (n > LUAI_MAXCSTACK) | ||
267 | lj_err_caller(L, LJ_ERR_STKOV); | ||
268 | lj_state_checkstack(L, (MSize)n); | ||
269 | memcpy(L->top, &fn->c.upvalue[1], n*sizeof(TValue)); | ||
270 | L->top += n; | ||
271 | } | ||
272 | n = io_file_read(L, iof->fp, 0); | ||
273 | if (ferror(iof->fp)) | ||
274 | lj_err_callermsg(L, strVdata(L->top-2)); | ||
275 | if (tvisnil(L->base) && (iof->type & IOFILE_FLAG_CLOSE)) { | ||
276 | io_file_close(L, iof); /* Return values are ignored. */ | ||
277 | return 0; | ||
278 | } | ||
279 | return n; | ||
280 | } | ||
281 | |||
256 | /* -- I/O file methods ---------------------------------------------------- */ | 282 | /* -- I/O file methods ---------------------------------------------------- */ |
257 | 283 | ||
258 | #define LJLIB_MODULE_io_method | 284 | #define LJLIB_MODULE_io_method |
@@ -333,14 +359,11 @@ LJLIB_CF(io_method_setvbuf) | |||
333 | return luaL_fileresult(L, setvbuf(fp, NULL, opt, sz) == 0, NULL); | 359 | return luaL_fileresult(L, setvbuf(fp, NULL, opt, sz) == 0, NULL); |
334 | } | 360 | } |
335 | 361 | ||
336 | LJLIB_PUSH(top-2) /* io_lines_iter */ | ||
337 | LJLIB_CF(io_method_lines) | 362 | LJLIB_CF(io_method_lines) |
338 | { | 363 | { |
339 | io_tofile(L); | 364 | io_tofile(L); |
340 | setfuncV(L, L->top, funcV(lj_lib_upvalue(L, 1))); | 365 | lua_pushcclosure(L, io_file_iter, (int)(L->top - L->base)); |
341 | setudataV(L, L->top+1, udataV(L->base)); | 366 | return 1; |
342 | L->top += 2; | ||
343 | return 2; | ||
344 | } | 367 | } |
345 | 368 | ||
346 | LJLIB_CF(io_method___gc) | 369 | LJLIB_CF(io_method___gc) |
@@ -459,30 +482,19 @@ LJLIB_CF(io_output) | |||
459 | return io_std_getset(L, GCROOT_IO_OUTPUT, "w"); | 482 | return io_std_getset(L, GCROOT_IO_OUTPUT, "w"); |
460 | } | 483 | } |
461 | 484 | ||
462 | LJLIB_NOREG LJLIB_CF(io_lines_iter) | ||
463 | { | ||
464 | IOFileUD *iof = io_tofile(L); | ||
465 | int ok = io_file_readline(L, iof->fp, 1); | ||
466 | if (ferror(iof->fp)) | ||
467 | lj_err_callermsg(L, strerror(errno)); | ||
468 | if (!ok && (iof->type & IOFILE_FLAG_CLOSE)) | ||
469 | io_file_close(L, iof); /* Return values are ignored (ok is 0). */ | ||
470 | return ok; | ||
471 | } | ||
472 | |||
473 | LJLIB_PUSH(top-3) /* io_lines_iter */ | ||
474 | LJLIB_CF(io_lines) | 485 | LJLIB_CF(io_lines) |
475 | { | 486 | { |
476 | if (L->base < L->top && !tvisnil(L->base)) { /* io.lines(fname) */ | 487 | if (L->base == L->top) setnilV(L->top++); |
488 | if (!tvisnil(L->base)) { /* io.lines(fname) */ | ||
477 | IOFileUD *iof = io_file_open(L, "r"); | 489 | IOFileUD *iof = io_file_open(L, "r"); |
478 | iof->type = IOFILE_TYPE_FILE|IOFILE_FLAG_CLOSE; | 490 | iof->type = IOFILE_TYPE_FILE|IOFILE_FLAG_CLOSE; |
479 | setfuncV(L, L->top-2, funcV(lj_lib_upvalue(L, 1))); | 491 | L->top--; |
492 | setudataV(L, L->base, udataV(L->top)); | ||
480 | } else { /* io.lines() iterates over stdin. */ | 493 | } else { /* io.lines() iterates over stdin. */ |
481 | setfuncV(L, L->top, funcV(lj_lib_upvalue(L, 1))); | 494 | setudataV(L, L->base, IOSTDF_UD(L, GCROOT_IO_INPUT)); |
482 | setudataV(L, L->top+1, IOSTDF_UD(L, GCROOT_IO_INPUT)); | ||
483 | L->top += 2; | ||
484 | } | 495 | } |
485 | return 2; | 496 | lua_pushcclosure(L, io_file_iter, (int)(L->top - L->base)); |
497 | return 1; | ||
486 | } | 498 | } |
487 | 499 | ||
488 | LJLIB_CF(io_type) | 500 | LJLIB_CF(io_type) |
@@ -516,7 +528,6 @@ static GCobj *io_std_new(lua_State *L, FILE *fp, const char *name) | |||
516 | 528 | ||
517 | LUALIB_API int luaopen_io(lua_State *L) | 529 | LUALIB_API int luaopen_io(lua_State *L) |
518 | { | 530 | { |
519 | lj_lib_pushcf(L, lj_cf_io_lines_iter, FF_io_lines_iter); | ||
520 | LJ_LIB_REG(L, NULL, io_method); | 531 | LJ_LIB_REG(L, NULL, io_method); |
521 | copyTV(L, L->top, L->top-1); L->top++; | 532 | copyTV(L, L->top, L->top-1); L->top++; |
522 | lua_setfield(L, LUA_REGISTRYINDEX, LUA_FILEHANDLE); | 533 | lua_setfield(L, LUA_REGISTRYINDEX, LUA_FILEHANDLE); |