aboutsummaryrefslogtreecommitdiff
path: root/iolib.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1997-09-16 16:25:59 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1997-09-16 16:25:59 -0300
commit451124005b061157a6f5ac977c79ef49b4012335 (patch)
treef187e99fd7c25044eef0d163cc54d143a9c1699d /iolib.c
parent2f1fa3d427b783490c2f0efb7dfe0090e291692f (diff)
downloadlua-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.c338
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
14int lua_tagio;
15
16
17#ifdef POPEN
18FILE *popen();
19int pclose();
20#else
21#define popen(x,y) NULL /* that is, popen always fails */
22#define pclose(x) (-1)
23#endif
24
25
26static 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
38static 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
47static 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
56static void setfile (FILE *f, char *name)
57{
58 lua_pushusertag(f, lua_tagio);
59 lua_setglobal(name);
60}
61
62
63static void setreturn (FILE *f, char *name)
64{
65 setfile(f, name);
66 lua_pushusertag(f, lua_tagio);
67}
68
69
70static 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
92static 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
114static 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
127static 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
177static 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
189static void io_execute (void)
190{
191 lua_pushnumber(system(luaL_check_string(1)));
192}
193
194
195static void io_remove (void)
196{
197 pushresult(remove(luaL_check_string(1)) == 0);
198}
199
200
201static void io_rename (void)
202{
203 pushresult(rename(luaL_check_string(1),
204 luaL_check_string(2)) == 0);
205}
206
207
208static void io_tmpname (void)
209{
210 lua_pushstring(tmpnam(NULL));
211}
212
213
214
215static void io_getenv (void)
216{
217 lua_pushstring(getenv(luaL_check_string(1))); /* if NULL push nil */
218}
219
220
221static 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
235static 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
245static 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
252static 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
264static 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
301static void errorfb (void)
302{
303 fprintf(stderr, "lua: %s\n", lua_getstring(lua_getparam(1)));
304 lua_printstack(stderr);
305}
306
307
308
309static 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
327void 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}