diff options
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]*' */ |
| 40 | static int l_checkmode (const char *mode) { | 40 | static 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 | */ |
| 188 | static LStream *newprefile (lua_State *L) { | 189 | static 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 | ||
| 215 | static int io_close (lua_State *L) { | 216 | static 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 | */ |
| 270 | static int io_pclose (lua_State *L) { | 271 | static 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 | */ | ||
| 339 | static void aux_lines (lua_State *L, int toclose) { | 350 | static 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 | */ | ||
| 356 | static int io_lines (lua_State *L) { | 373 | static 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 | */ |
| 440 | static int read_number (lua_State *L, FILE *f) { | 464 | static 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 | ||
| 482 | static int read_line (lua_State *L, FILE *f, int chop) { | 506 | static 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 | ||
| 529 | static int g_read (lua_State *L, FILE *f, int first) { | 553 | static 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 | */ | ||
| 589 | static int io_readline (lua_State *L) { | 616 | static 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 | */ |
| 719 | static const luaL_Reg flib[] = { | 746 | static 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 | */ | ||
| 761 | static 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 | ||
| 733 | static void createmeta (lua_State *L) { | 770 | static 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) { | |||
| 745 | static int io_noclose (lua_State *L) { | 783 | static 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 | } |
