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