diff options
Diffstat (limited to 'liolib.c')
-rw-r--r-- | liolib.c | 160 |
1 files changed, 40 insertions, 120 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: liolib.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $ | 2 | ** $Id: liolib.c,v 1.131 2002/02/08 22:39:56 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 | */ |
@@ -20,6 +20,12 @@ | |||
20 | 20 | ||
21 | 21 | ||
22 | 22 | ||
23 | /* | ||
24 | ** {====================================================== | ||
25 | ** FILE Operations | ||
26 | ** ======================================================= | ||
27 | */ | ||
28 | |||
23 | 29 | ||
24 | #ifdef POPEN | 30 | #ifdef POPEN |
25 | /* FILE *popen(); | 31 | /* FILE *popen(); |
@@ -41,7 +47,7 @@ int pclose(); */ | |||
41 | 47 | ||
42 | 48 | ||
43 | static const char *const filenames[] = {"_INPUT", "_OUTPUT"}; | 49 | static const char *const filenames[] = {"_INPUT", "_OUTPUT"}; |
44 | static const char *const basicfiles[] = {"_STDIN", "_STDOUT"}; | 50 | static const char *const basicfiles[] = {"stdin", "stdout"}; |
45 | 51 | ||
46 | 52 | ||
47 | static int pushresult (lua_State *L, int i) { | 53 | static int pushresult (lua_State *L, int i) { |
@@ -58,15 +64,6 @@ static int pushresult (lua_State *L, int i) { | |||
58 | } | 64 | } |
59 | 65 | ||
60 | 66 | ||
61 | |||
62 | /* | ||
63 | ** {====================================================== | ||
64 | ** FILE Operations | ||
65 | ** ======================================================= | ||
66 | */ | ||
67 | |||
68 | |||
69 | |||
70 | static int checkfile (lua_State *L, int findex, const char *tname) { | 67 | static int checkfile (lua_State *L, int findex, const char *tname) { |
71 | int res; | 68 | int res; |
72 | lua_getmetatable(L, findex); | 69 | lua_getmetatable(L, findex); |
@@ -116,8 +113,9 @@ static void newfile (lua_State *L, FILE *f) { | |||
116 | 113 | ||
117 | 114 | ||
118 | static void newfilewithname (lua_State *L, FILE *f, const char *name) { | 115 | static void newfilewithname (lua_State *L, FILE *f, const char *name) { |
116 | lua_pushstring(L, name); | ||
119 | newfile(L, f); | 117 | newfile(L, f); |
120 | lua_setglobal(L, name); | 118 | lua_settable(L, -3); |
121 | } | 119 | } |
122 | 120 | ||
123 | 121 | ||
@@ -136,8 +134,11 @@ static int setnewfile (lua_State *L, FILE *f, int inout) { | |||
136 | 134 | ||
137 | 135 | ||
138 | static void resetfile (lua_State *L, int inout) { | 136 | static void resetfile (lua_State *L, int inout) { |
139 | lua_getglobal(L, basicfiles[inout]); | 137 | lua_getglobal(L, "io"); |
138 | lua_pushstring(L, basicfiles[inout]); | ||
139 | lua_gettable(L, -2); | ||
140 | lua_setglobal(L, filenames[inout]); | 140 | lua_setglobal(L, filenames[inout]); |
141 | lua_pop(L, 1); | ||
141 | } | 142 | } |
142 | 143 | ||
143 | 144 | ||
@@ -410,6 +411,20 @@ static int io_flush (lua_State *L) { | |||
410 | return pushresult(L, fflush(f) == 0); | 411 | return pushresult(L, fflush(f) == 0); |
411 | } | 412 | } |
412 | 413 | ||
414 | static const luaL_reg iolib[] = { | ||
415 | {"appendto", io_appendto}, | ||
416 | {"close", io_close}, | ||
417 | {"flush", io_flush}, | ||
418 | {"open", io_open}, | ||
419 | {"read", io_read}, | ||
420 | {"readfrom", io_readfrom}, | ||
421 | {"seek", io_seek}, | ||
422 | {"tmpfile", io_tmpfile}, | ||
423 | {"write", io_write}, | ||
424 | {"writeto", io_writeto}, | ||
425 | {NULL, NULL} | ||
426 | }; | ||
427 | |||
413 | /* }====================================================== */ | 428 | /* }====================================================== */ |
414 | 429 | ||
415 | 430 | ||
@@ -445,7 +460,6 @@ static int io_tmpname (lua_State *L) { | |||
445 | } | 460 | } |
446 | 461 | ||
447 | 462 | ||
448 | |||
449 | static int io_getenv (lua_State *L) { | 463 | static int io_getenv (lua_State *L) { |
450 | lua_pushstring(L, getenv(luaL_check_string(L, 1))); /* if NULL push nil */ | 464 | lua_pushstring(L, getenv(luaL_check_string(L, 1))); /* if NULL push nil */ |
451 | return 1; | 465 | return 1; |
@@ -580,128 +594,30 @@ static int io_exit (lua_State *L) { | |||
580 | return 0; /* to avoid warnings */ | 594 | return 0; /* to avoid warnings */ |
581 | } | 595 | } |
582 | 596 | ||
583 | /* }====================================================== */ | 597 | static const luaL_reg syslib[] = { |
584 | |||
585 | |||
586 | |||
587 | static int io_debug (lua_State *L) { | ||
588 | for (;;) { | ||
589 | char buffer[250]; | ||
590 | fprintf(stderr, "lua_debug> "); | ||
591 | if (fgets(buffer, sizeof(buffer), stdin) == 0 || | ||
592 | strcmp(buffer, "cont\n") == 0) | ||
593 | return 0; | ||
594 | lua_dostring(L, buffer); | ||
595 | lua_settop(L, 0); /* remove eventual returns */ | ||
596 | } | ||
597 | } | ||
598 | |||
599 | |||
600 | #define LEVELS1 12 /* size of the first part of the stack */ | ||
601 | #define LEVELS2 10 /* size of the second part of the stack */ | ||
602 | |||
603 | static int errorfb (lua_State *L) { | ||
604 | int level = 1; /* skip level 0 (it's this function) */ | ||
605 | int firstpart = 1; /* still before eventual `...' */ | ||
606 | lua_Debug ar; | ||
607 | luaL_Buffer b; | ||
608 | luaL_buffinit(L, &b); | ||
609 | luaL_addstring(&b, "error: "); | ||
610 | luaL_addstring(&b, luaL_check_string(L, 1)); | ||
611 | luaL_addstring(&b, "\n"); | ||
612 | while (lua_getstack(L, level++, &ar)) { | ||
613 | char buff[120]; /* enough to fit following `sprintf's */ | ||
614 | if (level == 2) | ||
615 | luaL_addstring(&b, "stack traceback:\n"); | ||
616 | else if (level > LEVELS1 && firstpart) { | ||
617 | /* no more than `LEVELS2' more levels? */ | ||
618 | if (!lua_getstack(L, level+LEVELS2, &ar)) | ||
619 | level--; /* keep going */ | ||
620 | else { | ||
621 | luaL_addstring(&b, " ...\n"); /* too many levels */ | ||
622 | while (lua_getstack(L, level+LEVELS2, &ar)) /* find last levels */ | ||
623 | level++; | ||
624 | } | ||
625 | firstpart = 0; | ||
626 | continue; | ||
627 | } | ||
628 | sprintf(buff, "%4d: ", level-1); | ||
629 | luaL_addstring(&b, buff); | ||
630 | lua_getinfo(L, "Snl", &ar); | ||
631 | switch (*ar.namewhat) { | ||
632 | case 'g': case 'l': /* global, local */ | ||
633 | sprintf(buff, "function `%.50s'", ar.name); | ||
634 | break; | ||
635 | case 'f': /* field */ | ||
636 | sprintf(buff, "method `%.50s'", ar.name); | ||
637 | break; | ||
638 | case 't': /* tag method */ | ||
639 | sprintf(buff, "`%.50s' tag method", ar.name); | ||
640 | break; | ||
641 | default: { | ||
642 | if (*ar.what == 'm') /* main? */ | ||
643 | sprintf(buff, "main of %.70s", ar.short_src); | ||
644 | else if (*ar.what == 'C') /* C function? */ | ||
645 | sprintf(buff, "%.70s", ar.short_src); | ||
646 | else | ||
647 | sprintf(buff, "function <%d:%.70s>", ar.linedefined, ar.short_src); | ||
648 | ar.source = NULL; /* do not print source again */ | ||
649 | } | ||
650 | } | ||
651 | luaL_addstring(&b, buff); | ||
652 | if (ar.currentline > 0) { | ||
653 | sprintf(buff, " at line %d", ar.currentline); | ||
654 | luaL_addstring(&b, buff); | ||
655 | } | ||
656 | if (ar.source) { | ||
657 | sprintf(buff, " [%.70s]", ar.short_src); | ||
658 | luaL_addstring(&b, buff); | ||
659 | } | ||
660 | luaL_addstring(&b, "\n"); | ||
661 | } | ||
662 | luaL_pushresult(&b); | ||
663 | lua_getglobal(L, LUA_ALERT); | ||
664 | if (lua_isfunction(L, -1)) { /* avoid loop if _ALERT is not defined */ | ||
665 | lua_pushvalue(L, -2); /* error message */ | ||
666 | lua_rawcall(L, 1, 0); | ||
667 | } | ||
668 | return 0; | ||
669 | } | ||
670 | |||
671 | |||
672 | |||
673 | static const luaL_reg iolib[] = { | ||
674 | {"appendto", io_appendto}, | ||
675 | {"clock", io_clock}, | 598 | {"clock", io_clock}, |
676 | {"closefile", io_close}, | ||
677 | {"date", io_date}, | 599 | {"date", io_date}, |
678 | {"debug", io_debug}, | ||
679 | {"difftime", io_difftime}, | 600 | {"difftime", io_difftime}, |
680 | {"execute", io_execute}, | 601 | {"execute", io_execute}, |
681 | {"exit", io_exit}, | 602 | {"exit", io_exit}, |
682 | {"flush", io_flush}, | ||
683 | {"getenv", io_getenv}, | 603 | {"getenv", io_getenv}, |
684 | {"openfile", io_open}, | ||
685 | {"read", io_read}, | ||
686 | {"readfrom", io_readfrom}, | ||
687 | {"remove", io_remove}, | 604 | {"remove", io_remove}, |
688 | {"rename", io_rename}, | 605 | {"rename", io_rename}, |
689 | {"seek", io_seek}, | ||
690 | {"setlocale", io_setloc}, | 606 | {"setlocale", io_setloc}, |
691 | {"time", io_time}, | 607 | {"time", io_time}, |
692 | {"tmpfile", io_tmpfile}, | ||
693 | {"tmpname", io_tmpname}, | 608 | {"tmpname", io_tmpname}, |
694 | {"write", io_write}, | 609 | {NULL, NULL} |
695 | {"writeto", io_writeto}, | ||
696 | {LUA_ERRORMESSAGE, errorfb} | ||
697 | }; | 610 | }; |
698 | 611 | ||
612 | /* }====================================================== */ | ||
613 | |||
614 | |||
699 | 615 | ||
700 | LUALIB_API int lua_iolibopen (lua_State *L) { | 616 | LUALIB_API int lua_iolibopen (lua_State *L) { |
701 | lua_pushliteral(L, FILEHANDLE); | 617 | lua_pushliteral(L, FILEHANDLE); |
702 | lua_newtable(L); /* meta table for FILEHANDLE */ | 618 | lua_newtable(L); /* meta table for FILEHANDLE */ |
703 | /* close files when collected */ | 619 | /* close files when collected */ |
704 | lua_pushliteral(L, "gc"); | 620 | lua_pushliteral(L, "__gc"); |
705 | lua_pushcfunction(L, file_collect); | 621 | lua_pushcfunction(L, file_collect); |
706 | lua_rawset(L, -3); | 622 | lua_rawset(L, -3); |
707 | /* put new metatable into registry */ | 623 | /* put new metatable into registry */ |
@@ -710,11 +626,15 @@ LUALIB_API int lua_iolibopen (lua_State *L) { | |||
710 | lua_pushliteral(L, CLOSEDFILEHANDLE); | 626 | lua_pushliteral(L, CLOSEDFILEHANDLE); |
711 | lua_newtable(L); | 627 | lua_newtable(L); |
712 | lua_rawset(L, LUA_REGISTRYINDEX); | 628 | lua_rawset(L, LUA_REGISTRYINDEX); |
713 | luaL_openl(L, iolib); | 629 | luaL_opennamedlib(L, "os", syslib); |
630 | lua_pushliteral(L, "io"); | ||
631 | lua_newtable(L); | ||
632 | luaL_openlib(L, iolib); | ||
714 | /* predefined file handles */ | 633 | /* predefined file handles */ |
715 | newfilewithname(L, stdin, basicfiles[INFILE]); | 634 | newfilewithname(L, stdin, basicfiles[INFILE]); |
716 | newfilewithname(L, stdout, basicfiles[OUTFILE]); | 635 | newfilewithname(L, stdout, basicfiles[OUTFILE]); |
717 | newfilewithname(L, stderr, "_STDERR"); | 636 | newfilewithname(L, stderr, "stderr"); |
637 | lua_settable(L, LUA_GLOBALSINDEX); | ||
718 | resetfile(L, INFILE); | 638 | resetfile(L, INFILE); |
719 | resetfile(L, OUTFILE); | 639 | resetfile(L, OUTFILE); |
720 | return 0; | 640 | return 0; |