aboutsummaryrefslogtreecommitdiff
path: root/src/lua/liolib.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/lua/liolib.c (renamed from src/lua-5.3/liolib.c)112
1 files changed, 75 insertions, 37 deletions
diff --git a/src/lua-5.3/liolib.c b/src/lua/liolib.c
index 8a9e75c..7ac3444 100644
--- a/src/lua-5.3/liolib.c
+++ b/src/lua/liolib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: liolib.c,v 2.151.1.1 2017/04/19 17:29:57 roberto Exp $ 2** $Id: liolib.c $
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*/
@@ -39,7 +39,7 @@
39/* Check whether 'mode' matches '[rwa]%+?[L_MODEEXT]*' */ 39/* Check whether 'mode' matches '[rwa]%+?[L_MODEEXT]*' */
40static int l_checkmode (const char *mode) { 40static int l_checkmode (const char *mode) {
41 return (*mode != '\0' && strchr("rwa", *(mode++)) != NULL && 41 return (*mode != '\0' && strchr("rwa", *(mode++)) != NULL &&
42 (*mode != '+' || (++mode, 1)) && /* skip if char is '+' */ 42 (*mode != '+' || ((void)(++mode), 1)) && /* skip if char is '+' */
43 (strspn(mode, L_MODEEXT) == strlen(mode))); /* check extensions */ 43 (strspn(mode, L_MODEEXT) == strlen(mode))); /* check extensions */
44} 44}
45 45
@@ -68,7 +68,7 @@ static int l_checkmode (const char *mode) {
68 68
69/* ISO C definitions */ 69/* ISO C definitions */
70#define l_popen(L,c,m) \ 70#define l_popen(L,c,m) \
71 ((void)((void)c, m), \ 71 ((void)c, (void)m, \
72 luaL_error(L, "'popen' not supported"), \ 72 luaL_error(L, "'popen' not supported"), \
73 (FILE*)0) 73 (FILE*)0)
74#define l_pclose(L,file) ((void)L, (void)file, -1) 74#define l_pclose(L,file) ((void)L, (void)file, -1)
@@ -133,6 +133,7 @@ static int l_checkmode (const char *mode) {
133/* }====================================================== */ 133/* }====================================================== */
134 134
135 135
136
136#define IO_PREFIX "_IO_" 137#define IO_PREFIX "_IO_"
137#define IOPREF_LEN (sizeof(IO_PREFIX)/sizeof(char) - 1) 138#define IOPREF_LEN (sizeof(IO_PREFIX)/sizeof(char) - 1)
138#define IO_INPUT (IO_PREFIX "input") 139#define IO_INPUT (IO_PREFIX "input")
@@ -152,7 +153,7 @@ static int io_type (lua_State *L) {
152 luaL_checkany(L, 1); 153 luaL_checkany(L, 1);
153 p = (LStream *)luaL_testudata(L, 1, LUA_FILEHANDLE); 154 p = (LStream *)luaL_testudata(L, 1, LUA_FILEHANDLE);
154 if (p == NULL) 155 if (p == NULL)
155 lua_pushnil(L); /* not a file */ 156 luaL_pushfail(L); /* not a file */
156 else if (isclosed(p)) 157 else if (isclosed(p))
157 lua_pushliteral(L, "closed file"); 158 lua_pushliteral(L, "closed file");
158 else 159 else
@@ -186,7 +187,7 @@ static FILE *tofile (lua_State *L) {
186** handle is in a consistent state. 187** handle is in a consistent state.
187*/ 188*/
188static LStream *newprefile (lua_State *L) { 189static LStream *newprefile (lua_State *L) {
189 LStream *p = (LStream *)lua_newuserdata(L, sizeof(LStream)); 190 LStream *p = (LStream *)lua_newuserdatauv(L, sizeof(LStream), 0);
190 p->closef = NULL; /* mark file handle as 'closed' */ 191 p->closef = NULL; /* mark file handle as 'closed' */
191 luaL_setmetatable(L, LUA_FILEHANDLE); 192 luaL_setmetatable(L, LUA_FILEHANDLE);
192 return p; 193 return p;
@@ -214,7 +215,7 @@ static int f_close (lua_State *L) {
214 215
215static int io_close (lua_State *L) { 216static int io_close (lua_State *L) {
216 if (lua_isnone(L, 1)) /* no argument? */ 217 if (lua_isnone(L, 1)) /* no argument? */
217 lua_getfield(L, LUA_REGISTRYINDEX, IO_OUTPUT); /* use standard output */ 218 lua_getfield(L, LUA_REGISTRYINDEX, IO_OUTPUT); /* use default output */
218 return f_close(L); 219 return f_close(L);
219} 220}
220 221
@@ -269,6 +270,7 @@ static int io_open (lua_State *L) {
269*/ 270*/
270static int io_pclose (lua_State *L) { 271static int io_pclose (lua_State *L) {
271 LStream *p = tolstream(L); 272 LStream *p = tolstream(L);
273 errno = 0;
272 return luaL_execresult(L, l_pclose(L, p->f)); 274 return luaL_execresult(L, l_pclose(L, p->f));
273} 275}
274 276
@@ -295,7 +297,7 @@ static FILE *getiofile (lua_State *L, const char *findex) {
295 lua_getfield(L, LUA_REGISTRYINDEX, findex); 297 lua_getfield(L, LUA_REGISTRYINDEX, findex);
296 p = (LStream *)lua_touserdata(L, -1); 298 p = (LStream *)lua_touserdata(L, -1);
297 if (isclosed(p)) 299 if (isclosed(p))
298 luaL_error(L, "standard %s file is closed", findex + IOPREF_LEN); 300 luaL_error(L, "default %s file is closed", findex + IOPREF_LEN);
299 return p->f; 301 return p->f;
300} 302}
301 303
@@ -336,12 +338,22 @@ static int io_readline (lua_State *L);
336*/ 338*/
337#define MAXARGLINE 250 339#define MAXARGLINE 250
338 340
341/*
342** Auxiliary function to create the iteration function for 'lines'.
343** The iteration function is a closure over 'io_readline', with
344** the following upvalues:
345** 1) The file being read (first value in the stack)
346** 2) the number of arguments to read
347** 3) a boolean, true iff file has to be closed when finished ('toclose')
348** *) a variable number of format arguments (rest of the stack)
349*/
339static void aux_lines (lua_State *L, int toclose) { 350static void aux_lines (lua_State *L, int toclose) {
340 int n = lua_gettop(L) - 1; /* number of arguments to read */ 351 int n = lua_gettop(L) - 1; /* number of arguments to read */
341 luaL_argcheck(L, n <= MAXARGLINE, MAXARGLINE + 2, "too many arguments"); 352 luaL_argcheck(L, n <= MAXARGLINE, MAXARGLINE + 2, "too many arguments");
353 lua_pushvalue(L, 1); /* file */
342 lua_pushinteger(L, n); /* number of arguments to read */ 354 lua_pushinteger(L, n); /* number of arguments to read */
343 lua_pushboolean(L, toclose); /* close/not close file when finished */ 355 lua_pushboolean(L, toclose); /* close/not close file when finished */
344 lua_rotate(L, 2, 2); /* move 'n' and 'toclose' to their positions */ 356 lua_rotate(L, 2, 3); /* move the three values to their positions */
345 lua_pushcclosure(L, io_readline, 3 + n); 357 lua_pushcclosure(L, io_readline, 3 + n);
346} 358}
347 359
@@ -353,6 +365,11 @@ static int f_lines (lua_State *L) {
353} 365}
354 366
355 367
368/*
369** Return an iteration function for 'io.lines'. If file has to be
370** closed, also returns the file itself as a second result (to be
371** closed as the state at the exit of a generic for).
372*/
356static int io_lines (lua_State *L) { 373static int io_lines (lua_State *L) {
357 int toclose; 374 int toclose;
358 if (lua_isnone(L, 1)) lua_pushnil(L); /* at least one argument */ 375 if (lua_isnone(L, 1)) lua_pushnil(L); /* at least one argument */
@@ -368,8 +385,15 @@ static int io_lines (lua_State *L) {
368 lua_replace(L, 1); /* put file at index 1 */ 385 lua_replace(L, 1); /* put file at index 1 */
369 toclose = 1; /* close it after iteration */ 386 toclose = 1; /* close it after iteration */
370 } 387 }
371 aux_lines(L, toclose); 388 aux_lines(L, toclose); /* push iteration function */
372 return 1; 389 if (toclose) {
390 lua_pushnil(L); /* state */
391 lua_pushnil(L); /* control */
392 lua_pushvalue(L, 1); /* file is the to-be-closed variable (4th result) */
393 return 4;
394 }
395 else
396 return 1;
373} 397}
374 398
375 399
@@ -435,7 +459,7 @@ static int readdigits (RN *rn, int hex) {
435/* 459/*
436** Read a number: first reads a valid prefix of a numeral into a buffer. 460** Read a number: first reads a valid prefix of a numeral into a buffer.
437** Then it calls 'lua_stringtonumber' to check whether the format is 461** Then it calls 'lua_stringtonumber' to check whether the format is
438** correct and to convert it to a Lua number 462** correct and to convert it to a Lua number.
439*/ 463*/
440static int read_number (lua_State *L, FILE *f) { 464static int read_number (lua_State *L, FILE *f) {
441 RN rn; 465 RN rn;
@@ -447,7 +471,7 @@ static int read_number (lua_State *L, FILE *f) {
447 decp[1] = '.'; /* always accept a dot */ 471 decp[1] = '.'; /* always accept a dot */
448 l_lockfile(rn.f); 472 l_lockfile(rn.f);
449 do { rn.c = l_getc(rn.f); } while (isspace(rn.c)); /* skip spaces */ 473 do { rn.c = l_getc(rn.f); } while (isspace(rn.c)); /* skip spaces */
450 test2(&rn, "-+"); /* optional signal */ 474 test2(&rn, "-+"); /* optional sign */
451 if (test2(&rn, "00")) { 475 if (test2(&rn, "00")) {
452 if (test2(&rn, "xX")) hex = 1; /* numeral is hexadecimal */ 476 if (test2(&rn, "xX")) hex = 1; /* numeral is hexadecimal */
453 else count = 1; /* count initial '0' as a valid digit */ 477 else count = 1; /* count initial '0' as a valid digit */
@@ -456,7 +480,7 @@ static int read_number (lua_State *L, FILE *f) {
456 if (test2(&rn, decp)) /* decimal point? */ 480 if (test2(&rn, decp)) /* decimal point? */
457 count += readdigits(&rn, hex); /* fractional part */ 481 count += readdigits(&rn, hex); /* fractional part */
458 if (count > 0 && test2(&rn, (hex ? "pP" : "eE"))) { /* exponent mark? */ 482 if (count > 0 && test2(&rn, (hex ? "pP" : "eE"))) { /* exponent mark? */
459 test2(&rn, "-+"); /* exponent signal */ 483 test2(&rn, "-+"); /* exponent sign */
460 readdigits(&rn, 0); /* exponent digits */ 484 readdigits(&rn, 0); /* exponent digits */
461 } 485 }
462 ungetc(rn.c, rn.f); /* unread look-ahead char */ 486 ungetc(rn.c, rn.f); /* unread look-ahead char */
@@ -481,17 +505,17 @@ static int test_eof (lua_State *L, FILE *f) {
481 505
482static int read_line (lua_State *L, FILE *f, int chop) { 506static int read_line (lua_State *L, FILE *f, int chop) {
483 luaL_Buffer b; 507 luaL_Buffer b;
484 int c = '\0'; 508 int c;
485 luaL_buffinit(L, &b); 509 luaL_buffinit(L, &b);
486 while (c != EOF && c != '\n') { /* repeat until end of line */ 510 do { /* may need to read several chunks to get whole line */
487 char *buff = luaL_prepbuffer(&b); /* preallocate buffer */ 511 char *buff = luaL_prepbuffer(&b); /* preallocate buffer space */
488 int i = 0; 512 int i = 0;
489 l_lockfile(f); /* no memory errors can happen inside the lock */ 513 l_lockfile(f); /* no memory errors can happen inside the lock */
490 while (i < LUAL_BUFFERSIZE && (c = l_getc(f)) != EOF && c != '\n') 514 while (i < LUAL_BUFFERSIZE && (c = l_getc(f)) != EOF && c != '\n')
491 buff[i++] = c; 515 buff[i++] = c; /* read up to end of line or buffer limit */
492 l_unlockfile(f); 516 l_unlockfile(f);
493 luaL_addsize(&b, i); 517 luaL_addsize(&b, i);
494 } 518 } while (c != EOF && c != '\n'); /* repeat until end of line */
495 if (!chop && c == '\n') /* want a newline and have one? */ 519 if (!chop && c == '\n') /* want a newline and have one? */
496 luaL_addchar(&b, c); /* add ending newline to result */ 520 luaL_addchar(&b, c); /* add ending newline to result */
497 luaL_pushresult(&b); /* close buffer */ 521 luaL_pushresult(&b); /* close buffer */
@@ -528,14 +552,14 @@ static int read_chars (lua_State *L, FILE *f, size_t n) {
528 552
529static int g_read (lua_State *L, FILE *f, int first) { 553static int g_read (lua_State *L, FILE *f, int first) {
530 int nargs = lua_gettop(L) - 1; 554 int nargs = lua_gettop(L) - 1;
531 int success; 555 int n, success;
532 int n;
533 clearerr(f); 556 clearerr(f);
534 if (nargs == 0) { /* no arguments? */ 557 if (nargs == 0) { /* no arguments? */
535 success = read_line(L, f, 1); 558 success = read_line(L, f, 1);
536 n = first+1; /* to return 1 result */ 559 n = first + 1; /* to return 1 result */
537 } 560 }
538 else { /* ensure stack space for all results and for auxlib's buffer */ 561 else {
562 /* ensure stack space for all results and for auxlib's buffer */
539 luaL_checkstack(L, nargs+LUA_MINSTACK, "too many arguments"); 563 luaL_checkstack(L, nargs+LUA_MINSTACK, "too many arguments");
540 success = 1; 564 success = 1;
541 for (n = first; nargs-- && success; n++) { 565 for (n = first; nargs-- && success; n++) {
@@ -570,7 +594,7 @@ static int g_read (lua_State *L, FILE *f, int first) {
570 return luaL_fileresult(L, 0, NULL); 594 return luaL_fileresult(L, 0, NULL);
571 if (!success) { 595 if (!success) {
572 lua_pop(L, 1); /* remove last result */ 596 lua_pop(L, 1); /* remove last result */
573 lua_pushnil(L); /* push nil instead */ 597 luaL_pushfail(L); /* push nil instead */
574 } 598 }
575 return n - first; 599 return n - first;
576} 600}
@@ -586,6 +610,9 @@ static int f_read (lua_State *L) {
586} 610}
587 611
588 612
613/*
614** Iteration function for 'lines'.
615*/
589static int io_readline (lua_State *L) { 616static int io_readline (lua_State *L) {
590 LStream *p = (LStream *)lua_touserdata(L, lua_upvalueindex(1)); 617 LStream *p = (LStream *)lua_touserdata(L, lua_upvalueindex(1));
591 int i; 618 int i;
@@ -600,14 +627,14 @@ static int io_readline (lua_State *L) {
600 lua_assert(n > 0); /* should return at least a nil */ 627 lua_assert(n > 0); /* should return at least a nil */
601 if (lua_toboolean(L, -n)) /* read at least one value? */ 628 if (lua_toboolean(L, -n)) /* read at least one value? */
602 return n; /* return them */ 629 return n; /* return them */
603 else { /* first result is nil: EOF or error */ 630 else { /* first result is false: EOF or error */
604 if (n > 1) { /* is there error information? */ 631 if (n > 1) { /* is there error information? */
605 /* 2nd result is error message */ 632 /* 2nd result is error message */
606 return luaL_error(L, "%s", lua_tostring(L, -n + 1)); 633 return luaL_error(L, "%s", lua_tostring(L, -n + 1));
607 } 634 }
608 if (lua_toboolean(L, lua_upvalueindex(3))) { /* generator created file? */ 635 if (lua_toboolean(L, lua_upvalueindex(3))) { /* generator created file? */
609 lua_settop(L, 0); 636 lua_settop(L, 0); /* clear stack */
610 lua_pushvalue(L, lua_upvalueindex(1)); 637 lua_pushvalue(L, lua_upvalueindex(1)); /* push file at index 1 */
611 aux_close(L); /* close it */ 638 aux_close(L); /* close it */
612 } 639 }
613 return 0; 640 return 0;
@@ -716,26 +743,37 @@ static const luaL_Reg iolib[] = {
716/* 743/*
717** methods for file handles 744** methods for file handles
718*/ 745*/
719static const luaL_Reg flib[] = { 746static const luaL_Reg meth[] = {
720 {"close", f_close},
721 {"flush", f_flush},
722 {"lines", f_lines},
723 {"read", f_read}, 747 {"read", f_read},
748 {"write", f_write},
749 {"lines", f_lines},
750 {"flush", f_flush},
724 {"seek", f_seek}, 751 {"seek", f_seek},
752 {"close", f_close},
725 {"setvbuf", f_setvbuf}, 753 {"setvbuf", f_setvbuf},
726 {"write", f_write}, 754 {NULL, NULL}
755};
756
757
758/*
759** metamethods for file handles
760*/
761static const luaL_Reg metameth[] = {
762 {"__index", NULL}, /* place holder */
727 {"__gc", f_gc}, 763 {"__gc", f_gc},
764 {"__close", f_gc},
728 {"__tostring", f_tostring}, 765 {"__tostring", f_tostring},
729 {NULL, NULL} 766 {NULL, NULL}
730}; 767};
731 768
732 769
733static void createmeta (lua_State *L) { 770static void createmeta (lua_State *L) {
734 luaL_newmetatable(L, LUA_FILEHANDLE); /* create metatable for file handles */ 771 luaL_newmetatable(L, LUA_FILEHANDLE); /* metatable for file handles */
735 lua_pushvalue(L, -1); /* push metatable */ 772 luaL_setfuncs(L, metameth, 0); /* add metamethods to new metatable */
736 lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */ 773 luaL_newlibtable(L, meth); /* create method table */
737 luaL_setfuncs(L, flib, 0); /* add file methods to new metatable */ 774 luaL_setfuncs(L, meth, 0); /* add file methods to method table */
738 lua_pop(L, 1); /* pop new metatable */ 775 lua_setfield(L, -2, "__index"); /* metatable.__index = method table */
776 lua_pop(L, 1); /* pop metatable */
739} 777}
740 778
741 779
@@ -745,7 +783,7 @@ static void createmeta (lua_State *L) {
745static int io_noclose (lua_State *L) { 783static int io_noclose (lua_State *L) {
746 LStream *p = tolstream(L); 784 LStream *p = tolstream(L);
747 p->closef = &io_noclose; /* keep file opened */ 785 p->closef = &io_noclose; /* keep file opened */
748 lua_pushnil(L); 786 luaL_pushfail(L);
749 lua_pushliteral(L, "cannot close standard file"); 787 lua_pushliteral(L, "cannot close standard file");
750 return 2; 788 return 2;
751} 789}