diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2010-03-03 15:48:57 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2010-03-03 15:48:57 -0300 |
commit | ae0a5e2142c943329a2e8d33f8d9964c9d090249 (patch) | |
tree | 5105d632c5d0069d0c1376b59b9131328044ce04 /liolib.c | |
parent | 347f0c33d1911cb36f310131e55ad85aee23d44c (diff) | |
download | lua-ae0a5e2142c943329a2e8d33f8d9964c9d090249.tar.gz lua-ae0a5e2142c943329a2e8d33f8d9964c9d090249.tar.bz2 lua-ae0a5e2142c943329a2e8d33f8d9964c9d090249.zip |
new option '*L' for io.read + options for io.lines
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 */ |