aboutsummaryrefslogtreecommitdiff
path: root/liolib.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2018-10-31 14:54:45 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2018-10-31 14:54:45 -0300
commit947a372f5860a76fcafb4a2845abc322e440d6fc (patch)
treee35840847207c850af5262f93f863f583d2af76d /liolib.c
parente073cbc2e538369e0611abfc9948f301aea6aef3 (diff)
downloadlua-947a372f5860a76fcafb4a2845abc322e440d6fc.tar.gz
lua-947a372f5860a76fcafb4a2845abc322e440d6fc.tar.bz2
lua-947a372f5860a76fcafb4a2845abc322e440d6fc.zip
State in generic 'for' acts as a to-be-closed variable
The implicit variable 'state' in a generic 'for' is marked as a to-be-closed variable, so that the state will be closed as soon as the loop ends, no matter how. Taking advantage of this new facility, the call 'io.lines(filename)' now returns the open file as a second result. Therefore, an iteraction like 'for l in io.lines(name)...' will close the file even when the loop ends with a break or an error.
Diffstat (limited to 'liolib.c')
-rw-r--r--liolib.c35
1 files changed, 29 insertions, 6 deletions
diff --git a/liolib.c b/liolib.c
index 3dc509bd..5881b029 100644
--- a/liolib.c
+++ b/liolib.c
@@ -354,12 +354,22 @@ static int io_readline (lua_State *L);
354*/ 354*/
355#define MAXARGLINE 250 355#define MAXARGLINE 250
356 356
357/*
358** Auxiliar function to create the iteration function for 'lines'.
359** The iteration function is a closure over 'io_readline', with
360** the following upvalues:
361** 1) The file being read (first value in the stack)
362** 2) the number of arguments to read
363** 3) a boolean, true iff file has to be closed when finished ('toclose')
364** *) a variable number of format arguments (rest of the stack)
365*/
357static void aux_lines (lua_State *L, int toclose) { 366static void aux_lines (lua_State *L, int toclose) {
358 int n = lua_gettop(L) - 1; /* number of arguments to read */ 367 int n = lua_gettop(L) - 1; /* number of arguments to read */
359 luaL_argcheck(L, n <= MAXARGLINE, MAXARGLINE + 2, "too many arguments"); 368 luaL_argcheck(L, n <= MAXARGLINE, MAXARGLINE + 2, "too many arguments");
369 lua_pushvalue(L, 1); /* file */
360 lua_pushinteger(L, n); /* number of arguments to read */ 370 lua_pushinteger(L, n); /* number of arguments to read */
361 lua_pushboolean(L, toclose); /* close/not close file when finished */ 371 lua_pushboolean(L, toclose); /* close/not close file when finished */
362 lua_rotate(L, 2, 2); /* move 'n' and 'toclose' to their positions */ 372 lua_rotate(L, 2, 3); /* move the three values to their positions */
363 lua_pushcclosure(L, io_readline, 3 + n); 373 lua_pushcclosure(L, io_readline, 3 + n);
364} 374}
365 375
@@ -371,6 +381,11 @@ static int f_lines (lua_State *L) {
371} 381}
372 382
373 383
384/*
385** Return an iteration function for 'io.lines'. If file has to be
386** closed, also returns the file itself as a second result (to be
387** closed as the state at the exit of a generic for).
388*/
374static int io_lines (lua_State *L) { 389static int io_lines (lua_State *L) {
375 int toclose; 390 int toclose;
376 if (lua_isnone(L, 1)) lua_pushnil(L); /* at least one argument */ 391 if (lua_isnone(L, 1)) lua_pushnil(L); /* at least one argument */
@@ -386,8 +401,13 @@ static int io_lines (lua_State *L) {
386 lua_replace(L, 1); /* put file at index 1 */ 401 lua_replace(L, 1); /* put file at index 1 */
387 toclose = 1; /* close it after iteration */ 402 toclose = 1; /* close it after iteration */
388 } 403 }
389 aux_lines(L, toclose); 404 aux_lines(L, toclose); /* push iteration function */
390 return 1; 405 if (toclose) {
406 lua_pushvalue(L, 1); /* file will be second result */
407 return 2;
408 }
409 else
410 return 1;
391} 411}
392 412
393 413
@@ -453,7 +473,7 @@ static int readdigits (RN *rn, int hex) {
453/* 473/*
454** Read a number: first reads a valid prefix of a numeral into a buffer. 474** Read a number: first reads a valid prefix of a numeral into a buffer.
455** Then it calls 'lua_stringtonumber' to check whether the format is 475** Then it calls 'lua_stringtonumber' to check whether the format is
456** correct and to convert it to a Lua number 476** correct and to convert it to a Lua number.
457*/ 477*/
458static int read_number (lua_State *L, FILE *f) { 478static int read_number (lua_State *L, FILE *f) {
459 RN rn; 479 RN rn;
@@ -604,6 +624,9 @@ static int f_read (lua_State *L) {
604} 624}
605 625
606 626
627/*
628** Iteration function for 'lines'.
629*/
607static int io_readline (lua_State *L) { 630static int io_readline (lua_State *L) {
608 LStream *p = (LStream *)lua_touserdata(L, lua_upvalueindex(1)); 631 LStream *p = (LStream *)lua_touserdata(L, lua_upvalueindex(1));
609 int i; 632 int i;
@@ -624,8 +647,8 @@ static int io_readline (lua_State *L) {
624 return luaL_error(L, "%s", lua_tostring(L, -n + 1)); 647 return luaL_error(L, "%s", lua_tostring(L, -n + 1));
625 } 648 }
626 if (lua_toboolean(L, lua_upvalueindex(3))) { /* generator created file? */ 649 if (lua_toboolean(L, lua_upvalueindex(3))) { /* generator created file? */
627 lua_settop(L, 0); 650 lua_settop(L, 0); /* clear stack */
628 lua_pushvalue(L, lua_upvalueindex(1)); 651 lua_pushvalue(L, lua_upvalueindex(1)); /* push file at index 1 */
629 aux_close(L); /* close it */ 652 aux_close(L); /* close it */
630 } 653 }
631 return 0; 654 return 0;