aboutsummaryrefslogtreecommitdiff
path: root/liolib.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2010-03-03 15:48:57 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2010-03-03 15:48:57 -0300
commitae0a5e2142c943329a2e8d33f8d9964c9d090249 (patch)
tree5105d632c5d0069d0c1376b59b9131328044ce04 /liolib.c
parent347f0c33d1911cb36f310131e55ad85aee23d44c (diff)
downloadlua-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.c72
1 files changed, 48 insertions, 24 deletions
diff --git a/liolib.c b/liolib.c
index 6282b5c4..7f22bd8b 100644
--- a/liolib.c
+++ b/liolib.c
@@ -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) {
271static int io_readline (lua_State *L); 271static int io_readline (lua_State *L);
272 272
273 273
274static void aux_lines (lua_State *L, int idx, int toclose) { 274static 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
281static int f_lines (lua_State *L) { 287static 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
288static int io_lines (lua_State *L) { 294static 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
331static int read_line (lua_State *L, FILE *f) { 345static 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
429static int io_readline (lua_State *L) { 446static 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 */