diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1997-09-16 16:25:59 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1997-09-16 16:25:59 -0300 |
commit | 451124005b061157a6f5ac977c79ef49b4012335 (patch) | |
tree | f187e99fd7c25044eef0d163cc54d143a9c1699d /iolib.c | |
parent | 2f1fa3d427b783490c2f0efb7dfe0090e291692f (diff) | |
download | lua-451124005b061157a6f5ac977c79ef49b4012335.tar.gz lua-451124005b061157a6f5ac977c79ef49b4012335.tar.bz2 lua-451124005b061157a6f5ac977c79ef49b4012335.zip |
Standard I/O (and system) library
Diffstat (limited to 'iolib.c')
-rw-r--r-- | iolib.c | 338 |
1 files changed, 0 insertions, 338 deletions
diff --git a/iolib.c b/iolib.c deleted file mode 100644 index 9945d6b4..00000000 --- a/iolib.c +++ /dev/null | |||
@@ -1,338 +0,0 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <string.h> | ||
3 | #include <time.h> | ||
4 | #include <stdlib.h> | ||
5 | #include <errno.h> | ||
6 | |||
7 | #include "lualoc.h" | ||
8 | #include "lua.h" | ||
9 | #include "auxlib.h" | ||
10 | #include "luadebug.h" | ||
11 | #include "lualib.h" | ||
12 | |||
13 | |||
14 | int lua_tagio; | ||
15 | |||
16 | |||
17 | #ifdef POPEN | ||
18 | FILE *popen(); | ||
19 | int pclose(); | ||
20 | #else | ||
21 | #define popen(x,y) NULL /* that is, popen always fails */ | ||
22 | #define pclose(x) (-1) | ||
23 | #endif | ||
24 | |||
25 | |||
26 | static void pushresult (int i) | ||
27 | { | ||
28 | if (i) | ||
29 | lua_pushuserdata(NULL); | ||
30 | else { | ||
31 | lua_pushnil(); | ||
32 | lua_pushstring(strerror(errno)); | ||
33 | } | ||
34 | } | ||
35 | |||
36 | |||
37 | |||
38 | static FILE *getfile (char *name) | ||
39 | { | ||
40 | lua_Object f = lua_getglobal(name); | ||
41 | if (!lua_isuserdata(f) || lua_tag(f) != lua_tagio) | ||
42 | luaL_verror("global variable %s is not a file handle", name); | ||
43 | return lua_getuserdata(f); | ||
44 | } | ||
45 | |||
46 | |||
47 | static void closefile (char *name) | ||
48 | { | ||
49 | FILE *f = getfile(name); | ||
50 | if (f == stdin || f == stdout) return; | ||
51 | if (pclose(f) == -1) | ||
52 | fclose(f); | ||
53 | } | ||
54 | |||
55 | |||
56 | static void setfile (FILE *f, char *name) | ||
57 | { | ||
58 | lua_pushusertag(f, lua_tagio); | ||
59 | lua_setglobal(name); | ||
60 | } | ||
61 | |||
62 | |||
63 | static void setreturn (FILE *f, char *name) | ||
64 | { | ||
65 | setfile(f, name); | ||
66 | lua_pushusertag(f, lua_tagio); | ||
67 | } | ||
68 | |||
69 | |||
70 | static void io_readfrom (void) | ||
71 | { | ||
72 | FILE *current; | ||
73 | lua_Object f = lua_getparam(1); | ||
74 | if (f == LUA_NOOBJECT) { | ||
75 | closefile("_INPUT"); | ||
76 | current = stdin; | ||
77 | } | ||
78 | else if (lua_tag(f) == lua_tagio) | ||
79 | current = lua_getuserdata(f); | ||
80 | else { | ||
81 | char *s = luaL_check_string(1); | ||
82 | current = (*s == '|') ? popen(s+1, "r") : fopen(s, "r"); | ||
83 | if (current == NULL) { | ||
84 | pushresult(0); | ||
85 | return; | ||
86 | } | ||
87 | } | ||
88 | setreturn(current, "_INPUT"); | ||
89 | } | ||
90 | |||
91 | |||
92 | static void io_writeto (void) | ||
93 | { | ||
94 | FILE *current; | ||
95 | lua_Object f = lua_getparam(1); | ||
96 | if (f == LUA_NOOBJECT) { | ||
97 | closefile("_OUTPUT"); | ||
98 | current = stdout; | ||
99 | } | ||
100 | else if (lua_tag(f) == lua_tagio) | ||
101 | current = lua_getuserdata(f); | ||
102 | else { | ||
103 | char *s = luaL_check_string(1); | ||
104 | current = (*s == '|') ? popen(s+1,"w") : fopen(s,"w"); | ||
105 | if (current == NULL) { | ||
106 | pushresult(0); | ||
107 | return; | ||
108 | } | ||
109 | } | ||
110 | setreturn(current, "_OUTPUT"); | ||
111 | } | ||
112 | |||
113 | |||
114 | static void io_appendto (void) | ||
115 | { | ||
116 | char *s = luaL_check_string(1); | ||
117 | FILE *fp = fopen (s, "a"); | ||
118 | if (fp != NULL) | ||
119 | setreturn(fp, "_OUTPUT"); | ||
120 | else | ||
121 | pushresult(0); | ||
122 | } | ||
123 | |||
124 | |||
125 | #define NEED_OTHER (EOF-1) /* just some flag different from EOF */ | ||
126 | |||
127 | static void io_read (void) | ||
128 | { | ||
129 | FILE *f = getfile("_INPUT"); | ||
130 | char *buff; | ||
131 | char *p = luaL_opt_string(1, "[^\n]*{\n}"); | ||
132 | int inskip = 0; /* to control {skips} */ | ||
133 | int c = NEED_OTHER; | ||
134 | luaI_emptybuff(); | ||
135 | while (*p) { | ||
136 | if (*p == '{') { | ||
137 | inskip++; | ||
138 | p++; | ||
139 | } | ||
140 | else if (*p == '}') { | ||
141 | if (inskip == 0) | ||
142 | lua_error("unbalanced braces in read pattern"); | ||
143 | inskip--; | ||
144 | p++; | ||
145 | } | ||
146 | else { | ||
147 | char *ep = luaL_item_end(p); /* get what is next */ | ||
148 | int m; /* match result */ | ||
149 | if (c == NEED_OTHER) c = getc(f); | ||
150 | m = (c == EOF) ? 0 : luaL_singlematch((char)c, p); | ||
151 | if (m) { | ||
152 | if (inskip == 0) luaI_addchar(c); | ||
153 | c = NEED_OTHER; | ||
154 | } | ||
155 | switch (*ep) { | ||
156 | case '*': /* repetition */ | ||
157 | if (!m) p = ep+1; /* else stay in (repeat) the same item */ | ||
158 | break; | ||
159 | case '?': /* optional */ | ||
160 | p = ep+1; /* continues reading the pattern */ | ||
161 | break; | ||
162 | default: | ||
163 | if (m) p = ep; /* continues reading the pattern */ | ||
164 | else | ||
165 | goto break_while; /* pattern fails */ | ||
166 | } | ||
167 | } | ||
168 | } break_while: | ||
169 | if (c >= 0) /* not EOF nor NEED_OTHER? */ | ||
170 | ungetc(c, f); | ||
171 | buff = luaI_addchar(0); | ||
172 | if (*buff != 0 || *p == 0) /* read something or did not fail? */ | ||
173 | lua_pushstring(buff); | ||
174 | } | ||
175 | |||
176 | |||
177 | static void io_write (void) | ||
178 | { | ||
179 | FILE *f = getfile("_OUTPUT"); | ||
180 | int arg = 1; | ||
181 | int status = 1; | ||
182 | char *s; | ||
183 | while ((s = luaL_opt_string(arg++, NULL)) != NULL) | ||
184 | status = status && (fputs(s, f) != EOF); | ||
185 | pushresult(status); | ||
186 | } | ||
187 | |||
188 | |||
189 | static void io_execute (void) | ||
190 | { | ||
191 | lua_pushnumber(system(luaL_check_string(1))); | ||
192 | } | ||
193 | |||
194 | |||
195 | static void io_remove (void) | ||
196 | { | ||
197 | pushresult(remove(luaL_check_string(1)) == 0); | ||
198 | } | ||
199 | |||
200 | |||
201 | static void io_rename (void) | ||
202 | { | ||
203 | pushresult(rename(luaL_check_string(1), | ||
204 | luaL_check_string(2)) == 0); | ||
205 | } | ||
206 | |||
207 | |||
208 | static void io_tmpname (void) | ||
209 | { | ||
210 | lua_pushstring(tmpnam(NULL)); | ||
211 | } | ||
212 | |||
213 | |||
214 | |||
215 | static void io_getenv (void) | ||
216 | { | ||
217 | lua_pushstring(getenv(luaL_check_string(1))); /* if NULL push nil */ | ||
218 | } | ||
219 | |||
220 | |||
221 | static void io_date (void) | ||
222 | { | ||
223 | time_t t; | ||
224 | struct tm *tm; | ||
225 | char *s = luaL_opt_string(1, "%c"); | ||
226 | char b[BUFSIZ]; | ||
227 | time(&t); tm = localtime(&t); | ||
228 | if (strftime(b,sizeof(b),s,tm)) | ||
229 | lua_pushstring(b); | ||
230 | else | ||
231 | lua_error("invalid `date' format"); | ||
232 | } | ||
233 | |||
234 | |||
235 | static void setloc (void) | ||
236 | { | ||
237 | static int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC, | ||
238 | LC_TIME}; | ||
239 | int op = (int)luaL_opt_number(2, 0); | ||
240 | luaL_arg_check(0 <= op && op <= 5, 2, "invalid option"); | ||
241 | lua_pushstring(setlocale(cat[op], luaL_check_string(1))); | ||
242 | } | ||
243 | |||
244 | |||
245 | static void io_exit (void) | ||
246 | { | ||
247 | lua_Object o = lua_getparam(1); | ||
248 | exit(lua_isnumber(o) ? (int)lua_getnumber(o) : 1); | ||
249 | } | ||
250 | |||
251 | |||
252 | static void io_debug (void) | ||
253 | { | ||
254 | while (1) { | ||
255 | char buffer[250]; | ||
256 | fprintf(stderr, "lua_debug> "); | ||
257 | if (fgets(buffer, sizeof(buffer), stdin) == 0) return; | ||
258 | if (strcmp(buffer, "cont\n") == 0) return; | ||
259 | lua_dostring(buffer); | ||
260 | } | ||
261 | } | ||
262 | |||
263 | |||
264 | static void lua_printstack (FILE *f) | ||
265 | { | ||
266 | int level = 1; /* skip level 0 (it's this function) */ | ||
267 | lua_Object func; | ||
268 | while ((func = lua_stackedfunction(level++)) != LUA_NOOBJECT) { | ||
269 | char *name; | ||
270 | int currentline; | ||
271 | char *filename; | ||
272 | int linedefined; | ||
273 | lua_funcinfo(func, &filename, &linedefined); | ||
274 | fprintf(f, (level==2) ? "Active Stack:\n\t" : "\t"); | ||
275 | switch (*lua_getobjname(func, &name)) { | ||
276 | case 'g': | ||
277 | fprintf(f, "function %s", name); | ||
278 | break; | ||
279 | case 't': | ||
280 | fprintf(f, "`%s' tag method", name); | ||
281 | break; | ||
282 | default: { | ||
283 | if (linedefined == 0) | ||
284 | fprintf(f, "main of %s", filename); | ||
285 | else if (linedefined < 0) | ||
286 | fprintf(f, "%s", filename); | ||
287 | else | ||
288 | fprintf(f, "function (%s:%d)", filename, linedefined); | ||
289 | filename = NULL; | ||
290 | } | ||
291 | } | ||
292 | if ((currentline = lua_currentline(func)) > 0) | ||
293 | fprintf(f, " at line %d", currentline); | ||
294 | if (filename) | ||
295 | fprintf(f, " [in file %s]", filename); | ||
296 | fprintf(f, "\n"); | ||
297 | } | ||
298 | } | ||
299 | |||
300 | |||
301 | static void errorfb (void) | ||
302 | { | ||
303 | fprintf(stderr, "lua: %s\n", lua_getstring(lua_getparam(1))); | ||
304 | lua_printstack(stderr); | ||
305 | } | ||
306 | |||
307 | |||
308 | |||
309 | static struct luaL_reg iolib[] = { | ||
310 | {"setlocale", setloc}, | ||
311 | {"readfrom", io_readfrom}, | ||
312 | {"writeto", io_writeto}, | ||
313 | {"appendto", io_appendto}, | ||
314 | {"read", io_read}, | ||
315 | {"write", io_write}, | ||
316 | {"execute", io_execute}, | ||
317 | {"remove", io_remove}, | ||
318 | {"rename", io_rename}, | ||
319 | {"tmpname", io_tmpname}, | ||
320 | {"getenv", io_getenv}, | ||
321 | {"date", io_date}, | ||
322 | {"exit", io_exit}, | ||
323 | {"debug", io_debug}, | ||
324 | {"print_stack", errorfb} | ||
325 | }; | ||
326 | |||
327 | void iolib_open (void) | ||
328 | { | ||
329 | lua_tagio = lua_newtag(); | ||
330 | setfile(stdin, "_INPUT"); | ||
331 | setfile(stdout, "_OUTPUT"); | ||
332 | setfile(stdin, "_STDIN"); | ||
333 | setfile(stdout, "_STDOUT"); | ||
334 | setfile(stderr, "_STDERR"); | ||
335 | luaL_openlib(iolib, (sizeof(iolib)/sizeof(iolib[0]))); | ||
336 | lua_pushcfunction(errorfb); | ||
337 | lua_seterrormethod(); | ||
338 | } | ||