aboutsummaryrefslogtreecommitdiff
path: root/liolib.c
diff options
context:
space:
mode:
Diffstat (limited to 'liolib.c')
-rw-r--r--liolib.c94
1 files changed, 49 insertions, 45 deletions
diff --git a/liolib.c b/liolib.c
index fa9830bf..dda79529 100644
--- a/liolib.c
+++ b/liolib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: liolib.c,v 1.111 2001/03/26 14:31:49 roberto Exp roberto $ 2** $Id: liolib.c,v 1.112 2001/04/23 16:35:45 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*/
@@ -48,15 +48,17 @@ int pclose(); */
48#define OUTFILE 1 48#define OUTFILE 1
49#define NOFILE 2 49#define NOFILE 2
50 50
51#define FILEHANDLE l_s("FileHandle") 51#define FILEHANDLE l_s("FileHandle")
52#define CLOSEDFILEHANDLE l_s("ClosedFileHandle")
52 53
53 54
54static const l_char *const filenames[] = {l_s("_INPUT"), l_s("_OUTPUT")}; 55static const l_char *const filenames[] = {l_s("_INPUT"), l_s("_OUTPUT")};
56static const l_char *const basicfiles[] = {l_s("_STDIN"), l_s("_STDOUT")};
55 57
56 58
57static int pushresult (lua_State *L, int i) { 59static int pushresult (lua_State *L, int i) {
58 if (i) { 60 if (i) {
59 lua_pushuserdata(L, NULL); 61 lua_newuserdatabox(L, NULL);
60 return 1; 62 return 1;
61 } 63 }
62 else { 64 else {
@@ -81,16 +83,15 @@ static int pushresult (lua_State *L, int i) {
81static FILE *getopthandle (lua_State *L, int inout) { 83static FILE *getopthandle (lua_State *L, int inout) {
82 FILE *p = (FILE *)lua_touserdata(L, 1); 84 FILE *p = (FILE *)lua_touserdata(L, 1);
83 if (p != NULL) { /* is it a userdata ? */ 85 if (p != NULL) { /* is it a userdata ? */
84 if (!checkfile(L, 1)) { 86 if (!checkfile(L, 1)) { /* not a valid file handle? */
85 if (strcmp(lua_xtypename(L, 1), l_s("ClosedFileHandle")) == 0) 87 if (strcmp(lua_xtypename(L, 1), CLOSEDFILEHANDLE) == 0)
86 luaL_argerror(L, 1, l_s("file is closed")); 88 luaL_argerror(L, 1, l_s("file is closed"));
87 else 89 else
88 luaL_argerror(L, 1, l_s("(invalid value)")); 90 luaL_argerror(L, 1, l_s("(invalid value)"));
89 } 91 }
90 /* move it to stack top */ 92 lua_pushvalue(L, 1); lua_remove(L, 1); /* move it to stack top */
91 lua_pushvalue(L, 1); lua_remove(L, 1);
92 } 93 }
93 else if (inout != NOFILE) { /* try global value */ 94 else { /* try global value */
94 lua_getglobal(L, filenames[inout]); 95 lua_getglobal(L, filenames[inout]);
95 if (!checkfile(L,-1)) 96 if (!checkfile(L,-1))
96 luaL_verror(L, l_s("global variable `%.10s' is not a valid file handle"), 97 luaL_verror(L, l_s("global variable `%.10s' is not a valid file handle"),
@@ -101,46 +102,50 @@ static FILE *getopthandle (lua_State *L, int inout) {
101} 102}
102 103
103 104
104static void pushfile (lua_State *L, FILE *f) { 105static void newfile (lua_State *L, FILE *f) {
105 lua_pushusertag(L, f, lua_name2tag(L, FILEHANDLE)); 106 lua_newuserdatabox(L, f);
107 lua_settag(L, lua_name2tag(L, FILEHANDLE));
106} 108}
107 109
108 110
109static void setfilebyname (lua_State *L, FILE *f, const l_char *name) { 111static void newfilewithname (lua_State *L, FILE *f, const l_char *name) {
110 pushfile(L, f); 112 newfile(L, f);
111 lua_setglobal(L, name); 113 lua_setglobal(L, name);
112} 114}
113 115
114 116
115#define setfile(L,f,inout) (setfilebyname(L,f,filenames[inout])) 117static int setnewfile (lua_State *L, FILE *f, int inout) {
116
117
118static int setreturn (lua_State *L, FILE *f, int inout) {
119 if (f == NULL) 118 if (f == NULL)
120 return pushresult(L, 0); 119 return pushresult(L, 0);
121 else { 120 else {
122 if (inout != NOFILE) 121 newfile(L, f);
123 setfile(L, f, inout); 122 if (inout != NOFILE) {
124 pushfile(L, f); 123 lua_pushvalue(L, -1);
124 lua_setglobal(L, filenames[inout]);
125 }
125 return 1; 126 return 1;
126 } 127 }
127} 128}
128 129
129 130
130static int closefile (lua_State *L, FILE *f) { 131static void resetfile (lua_State *L, int inout) {
131 if (f == stdin || f == stdout || f == stderr) 132 lua_getglobal(L, basicfiles[inout]);
132 return 1; 133 lua_setglobal(L, filenames[inout]);
133 else {
134 lua_pushuserdata(L, f);
135 lua_settag(L, lua_name2tag(L, l_s("ClosedFileHandle")));
136 return (CLOSEFILE(L, f) == 0);
137 }
138} 134}
139 135
140 136
141static int io_close (lua_State *L) { 137static int io_close (lua_State *L) {
142 FILE *f = (FILE *)luaL_check_userdata(L, 1, FILEHANDLE); 138 FILE *f;
143 return pushresult(L, closefile(L, f)); 139 int status;
140 lua_settop(L, 1);
141 f = luaL_check_userdata(L, 1, FILEHANDLE);
142 if (f == stdin || f == stdout || f == stderr)
143 status = 1;
144 else {
145 lua_settag(L, lua_name2tag(L, CLOSEDFILEHANDLE));
146 status = (CLOSEFILE(L, f) == 0);
147 }
148 return pushresult(L, status);
144} 149}
145 150
146 151
@@ -154,12 +159,12 @@ static int file_collect (lua_State *L) {
154 159
155static int io_open (lua_State *L) { 160static int io_open (lua_State *L) {
156 FILE *f = fopen(luaL_check_string(L, 1), luaL_check_string(L, 2)); 161 FILE *f = fopen(luaL_check_string(L, 1), luaL_check_string(L, 2));
157 return setreturn(L, f, NOFILE); 162 return setnewfile(L, f, NOFILE);
158} 163}
159 164
160 165
161static int io_tmpfile (lua_State *L) { 166static int io_tmpfile (lua_State *L) {
162 return setreturn(L, tmpfile(), NOFILE); 167 return setnewfile(L, tmpfile(), NOFILE);
163} 168}
164 169
165 170
@@ -167,16 +172,15 @@ static int io_tmpfile (lua_State *L) {
167static int io_fromto (lua_State *L, int inout, const l_char *mode) { 172static int io_fromto (lua_State *L, int inout, const l_char *mode) {
168 FILE *current; 173 FILE *current;
169 if (lua_isnull(L, 1)) { 174 if (lua_isnull(L, 1)) {
170 closefile(L, getopthandle(L, inout)); 175 getopthandle(L, inout);
171 current = (inout == 0) ? stdin : stdout; 176 resetfile(L, inout);
177 return io_close(L);
172 } 178 }
173 else if (checkfile(L, 1)) /* deprecated option */
174 current = (FILE *)lua_touserdata(L, 1);
175 else { 179 else {
176 const l_char *s = luaL_check_string(L, 1); 180 const l_char *s = luaL_check_string(L, 1);
177 current = (*s == l_c('|')) ? popen(s+1, mode) : fopen(s, mode); 181 current = (*s == l_c('|')) ? popen(s+1, mode) : fopen(s, mode);
182 return setnewfile(L, current, inout);
178 } 183 }
179 return setreturn(L, current, inout);
180} 184}
181 185
182 186
@@ -192,7 +196,7 @@ static int io_writeto (lua_State *L) {
192 196
193static int io_appendto (lua_State *L) { 197static int io_appendto (lua_State *L) {
194 FILE *current = fopen(luaL_check_string(L, 1), l_s("a")); 198 FILE *current = fopen(luaL_check_string(L, 1), l_s("a"));
195 return setreturn(L, current, OUTFILE); 199 return setnewfile(L, current, OUTFILE);
196} 200}
197 201
198 202
@@ -388,8 +392,8 @@ static int io_seek (lua_State *L) {
388 392
389 393
390static int io_flush (lua_State *L) { 394static int io_flush (lua_State *L) {
391 FILE *f = getopthandle(L, NOFILE); 395 FILE *f = (lua_isnull(L, 1)) ? (FILE *)NULL :
392 luaL_arg_check(L, f || lua_isnull(L, 1), 1, l_s("invalid file handle")); 396 (FILE *)luaL_check_userdata(L, 1, FILEHANDLE);
393 return pushresult(L, fflush(f) == 0); 397 return pushresult(L, fflush(f) == 0);
394} 398}
395 399
@@ -679,14 +683,14 @@ static const luaL_reg iolib[] = {
679 683
680LUALIB_API int lua_iolibopen (lua_State *L) { 684LUALIB_API int lua_iolibopen (lua_State *L) {
681 int iotag = lua_newxtype(L, FILEHANDLE, LUA_TUSERDATA); 685 int iotag = lua_newxtype(L, FILEHANDLE, LUA_TUSERDATA);
682 lua_newxtype(L, l_s("ClosedFileHandle"), LUA_TUSERDATA); 686 lua_newxtype(L, CLOSEDFILEHANDLE, LUA_TUSERDATA);
683 luaL_openl(L, iolib); 687 luaL_openl(L, iolib);
684 /* predefined file handles */ 688 /* predefined file handles */
685 setfile(L, stdin, INFILE); 689 newfilewithname(L, stdin, basicfiles[INFILE]);
686 setfile(L, stdout, OUTFILE); 690 newfilewithname(L, stdout, basicfiles[OUTFILE]);
687 setfilebyname(L, stdin, l_s("_STDIN")); 691 newfilewithname(L, stderr, l_s("_STDERR"));
688 setfilebyname(L, stdout, l_s("_STDOUT")); 692 resetfile(L, INFILE);
689 setfilebyname(L, stderr, l_s("_STDERR")); 693 resetfile(L, OUTFILE);
690 /* close files when collected */ 694 /* close files when collected */
691 lua_pushcfunction(L, file_collect); 695 lua_pushcfunction(L, file_collect);
692 lua_settagmethod(L, iotag, l_s("gc")); 696 lua_settagmethod(L, iotag, l_s("gc"));