diff options
Diffstat (limited to 'liolib.c')
| -rw-r--r-- | liolib.c | 72 |
1 files changed, 48 insertions, 24 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: liolib.c,v 2.84 2009/12/17 13:08:51 roberto Exp roberto $ | 2 | ** $Id: liolib.c,v 2.85 2009/12/17 16:20:01 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 | */ |
| @@ -271,35 +271,46 @@ static int io_output (lua_State *L) { | |||
| 271 | static int io_readline (lua_State *L); | 271 | static int io_readline (lua_State *L); |
| 272 | 272 | ||
| 273 | 273 | ||
| 274 | static void aux_lines (lua_State *L, int idx, int toclose) { | 274 | static void aux_lines (lua_State *L, int toclose) { |
| 275 | lua_pushvalue(L, idx); | 275 | int i; |
| 276 | int n = lua_gettop(L) - 1; /* number of arguments to read */ | ||
| 277 | /* ensure that arguments will fit here and into 'io_readline' stack */ | ||
| 278 | luaL_argcheck(L, n <= LUA_MINSTACK - 3, LUA_MINSTACK - 3, "too many options"); | ||
| 279 | lua_pushvalue(L, 1); /* file handle */ | ||
| 280 | lua_pushinteger(L, n); /* number of arguments to read */ | ||
| 276 | lua_pushboolean(L, toclose); /* close/not close file when finished */ | 281 | lua_pushboolean(L, toclose); /* close/not close file when finished */ |
| 277 | lua_pushcclosure(L, io_readline, 2); | 282 | for (i = 1; i <= n; i++) lua_pushvalue(L, i + 1); /* copy arguments */ |
| 283 | lua_pushcclosure(L, io_readline, 3 + n); | ||
| 278 | } | 284 | } |
| 279 | 285 | ||
| 280 | 286 | ||
| 281 | static int f_lines (lua_State *L) { | 287 | static int f_lines (lua_State *L) { |
| 282 | tofile(L); /* check that it's a valid file handle */ | 288 | tofile(L); /* check that it's a valid file handle */ |
| 283 | aux_lines(L, 1, 0); | 289 | aux_lines(L, 0); |
| 284 | return 1; | 290 | return 1; |
| 285 | } | 291 | } |
| 286 | 292 | ||
| 287 | 293 | ||
| 288 | static int io_lines (lua_State *L) { | 294 | static int io_lines (lua_State *L) { |
| 289 | if (lua_isnoneornil(L, 1)) { /* no arguments? */ | 295 | int toclose; |
| 290 | /* will iterate over default input */ | 296 | if (lua_isnone(L, 1)) lua_pushnil(L); /* at least one argument */ |
| 291 | lua_rawgeti(L, LUA_ENVIRONINDEX, IO_INPUT); | 297 | if (lua_isnil(L, 1)) { /* no file name? */ |
| 292 | return f_lines(L); | 298 | lua_rawgeti(L, LUA_ENVIRONINDEX, IO_INPUT); /* get default input */ |
| 299 | lua_replace(L, 1); /* put it at index 1 */ | ||
| 300 | tofile(L); /* check that it's a valid file handle */ | ||
| 301 | toclose = 0; /* do not close it after iteration */ | ||
| 293 | } | 302 | } |
| 294 | else { | 303 | else { /* open a new file */ |
| 295 | const char *filename = luaL_checkstring(L, 1); | 304 | const char *filename = luaL_checkstring(L, 1); |
| 296 | FILE **pf = newfile(L); | 305 | FILE **pf = newfile(L); |
| 297 | *pf = fopen(filename, "r"); | 306 | *pf = fopen(filename, "r"); |
| 298 | if (*pf == NULL) | 307 | if (*pf == NULL) |
| 299 | fileerror(L, 1, filename); | 308 | fileerror(L, 1, filename); |
| 300 | aux_lines(L, lua_gettop(L), 1); | 309 | lua_replace(L, 1); /* put file at index 1 */ |
| 301 | return 1; | 310 | toclose = 1; /* close it after iteration */ |
| 302 | } | 311 | } |
| 312 | aux_lines(L, toclose); | ||
| 313 | return 1; | ||
| 303 | } | 314 | } |
| 304 | 315 | ||
| 305 | 316 | ||
| @@ -316,7 +327,10 @@ static int read_number (lua_State *L, FILE *f) { | |||
| 316 | lua_pushnumber(L, d); | 327 | lua_pushnumber(L, d); |
| 317 | return 1; | 328 | return 1; |
| 318 | } | 329 | } |
| 319 | else return 0; /* read fails */ | 330 | else { |
| 331 | lua_pushnil(L); /* "result" to be removed */ | ||
| 332 | return 0; /* read fails */ | ||
| 333 | } | ||
| 320 | } | 334 | } |
| 321 | 335 | ||
| 322 | 336 | ||
| @@ -328,7 +342,7 @@ static int test_eof (lua_State *L, FILE *f) { | |||
| 328 | } | 342 | } |
| 329 | 343 | ||
| 330 | 344 | ||
| 331 | static int read_line (lua_State *L, FILE *f) { | 345 | static int read_line (lua_State *L, FILE *f, int chop) { |
| 332 | luaL_Buffer b; | 346 | luaL_Buffer b; |
| 333 | luaL_buffinit(L, &b); | 347 | luaL_buffinit(L, &b); |
| 334 | for (;;) { | 348 | for (;;) { |
| @@ -342,7 +356,7 @@ static int read_line (lua_State *L, FILE *f) { | |||
| 342 | if (l == 0 || p[l-1] != '\n') | 356 | if (l == 0 || p[l-1] != '\n') |
| 343 | luaL_addsize(&b, l); | 357 | luaL_addsize(&b, l); |
| 344 | else { | 358 | else { |
| 345 | luaL_addsize(&b, l - 1); /* do not include `eol' */ | 359 | luaL_addsize(&b, l - chop); /* chop 'eol' if needed */ |
| 346 | luaL_pushresult(&b); /* close buffer */ | 360 | luaL_pushresult(&b); /* close buffer */ |
| 347 | return 1; /* read at least an `eol' */ | 361 | return 1; /* read at least an `eol' */ |
| 348 | } | 362 | } |
| @@ -375,7 +389,7 @@ static int g_read (lua_State *L, FILE *f, int first) { | |||
| 375 | int n; | 389 | int n; |
| 376 | clearerr(f); | 390 | clearerr(f); |
| 377 | if (nargs == 0) { /* no arguments? */ | 391 | if (nargs == 0) { /* no arguments? */ |
| 378 | success = read_line(L, f); | 392 | success = read_line(L, f, 1); |
| 379 | n = first+1; /* to return 1 result */ | 393 | n = first+1; /* to return 1 result */ |
| 380 | } | 394 | } |
| 381 | else { /* ensure stack space for all results and for auxlib's buffer */ | 395 | else { /* ensure stack space for all results and for auxlib's buffer */ |
| @@ -394,7 +408,10 @@ static int g_read (lua_State *L, FILE *f, int first) { | |||
| 394 | success = read_number(L, f); | 408 | success = read_number(L, f); |
| 395 | break; | 409 | break; |
| 396 | case 'l': /* line */ | 410 | case 'l': /* line */ |
| 397 | success = read_line(L, f); | 411 | success = read_line(L, f, 1); |
| 412 | break; | ||
| 413 | case 'L': /* line with end-of-line */ | ||
| 414 | success = read_line(L, f, 0); | ||
| 398 | break; | 415 | break; |
| 399 | case 'a': /* file */ | 416 | case 'a': /* file */ |
| 400 | read_chars(L, f, ~((size_t)0)); /* read MAX_SIZE_T chars */ | 417 | read_chars(L, f, ~((size_t)0)); /* read MAX_SIZE_T chars */ |
| @@ -428,15 +445,22 @@ static int f_read (lua_State *L) { | |||
| 428 | 445 | ||
| 429 | static int io_readline (lua_State *L) { | 446 | static int io_readline (lua_State *L) { |
| 430 | FILE *f = *(FILE **)lua_touserdata(L, lua_upvalueindex(1)); | 447 | FILE *f = *(FILE **)lua_touserdata(L, lua_upvalueindex(1)); |
| 431 | int success; | 448 | int i; |
| 449 | int n = lua_tointeger(L, lua_upvalueindex(2)); | ||
| 432 | if (f == NULL) /* file is already closed? */ | 450 | if (f == NULL) /* file is already closed? */ |
| 433 | luaL_error(L, "file is already closed"); | 451 | luaL_error(L, "file is already closed"); |
| 434 | success = read_line(L, f); | 452 | lua_settop(L , 1); |
| 435 | if (ferror(f)) | 453 | for (i = 1; i <= n; i++) /* push arguments to 'g_read' */ |
| 436 | return luaL_error(L, "%s", strerror(errno)); | 454 | lua_pushvalue(L, lua_upvalueindex(3 + i)); |
| 437 | if (success) return 1; | 455 | n = g_read(L, f, 2); /* 'n' is number of results */ |
| 438 | else { /* EOF */ | 456 | lua_assert(n > 0); /* should return at least a nil */ |
| 439 | if (lua_toboolean(L, lua_upvalueindex(2))) { /* generator created file? */ | 457 | if (!lua_isnil(L, -n)) /* read at least one value? */ |
| 458 | return n; /* return them */ | ||
| 459 | else { /* first result is nil: EOF or error */ | ||
| 460 | if (!lua_isnil(L, -1)) /* is there error information? */ | ||
| 461 | return luaL_error(L, "%s", lua_tostring(L, -1)); /* error */ | ||
| 462 | /* else EOF */ | ||
| 463 | if (lua_toboolean(L, lua_upvalueindex(3))) { /* generator created file? */ | ||
| 440 | lua_settop(L, 0); | 464 | lua_settop(L, 0); |
| 441 | lua_pushvalue(L, lua_upvalueindex(1)); | 465 | lua_pushvalue(L, lua_upvalueindex(1)); |
| 442 | aux_close(L); /* close it */ | 466 | aux_close(L); /* close it */ |
