2 ** $Id: liolib.c,v 1.21 1998/06/18 17:04:28 roberto Exp $
3 ** Standard I/O (and system) library
4 ** See Copyright Notice in lua.h
23 #define setlocale(a,b) 0
30 #define strerror(e) "(no error message provided by operating system)"
37 #define FIRSTARG 3 /* 1st and 2nd are upvalues */
39 #define FINPUT "_INPUT"
40 #define FOUTPUT "_OUTPUT"
47 #define popen(x,y) NULL /* that is, popen always fails */
48 #define pclose(x) (-1)
52 static int gettag (int i
)
54 return lua_getnumber(lua_getparam(i
));
58 static void pushresult (int i
)
61 lua_pushuserdata(NULL
);
64 lua_pushstring(strerror(errno
));
69 static int ishandler (lua_Object f
)
71 if (lua_isuserdata(f
)) {
72 if (lua_tag(f
) == gettag(CLOSEDTAG
))
73 lua_error("cannot access a closed file");
74 return lua_tag(f
) == gettag(IOTAG
);
79 static FILE *getfile (char *name
)
81 lua_Object f
= lua_getglobal(name
);
83 luaL_verror("global variable `%.50s' is not a file handle", name
);
84 return lua_getuserdata(f
);
88 static FILE *getfileparam (char *name
, int *arg
)
90 lua_Object f
= lua_getparam(*arg
);
93 return lua_getuserdata(f
);
100 static void closefile (char *name
)
102 FILE *f
= getfile(name
);
103 if (f
== stdin
|| f
== stdout
) return;
106 lua_pushobject(lua_getglobal(name
));
107 lua_settag(gettag(CLOSEDTAG
));
111 static void setfile (FILE *f
, char *name
, int tag
)
113 lua_pushusertag(f
, tag
);
118 static void setreturn (FILE *f
, char *name
)
120 int tag
= gettag(IOTAG
);
121 setfile(f
, name
, tag
);
122 lua_pushusertag(f
, tag
);
126 static void io_readfrom (void)
129 lua_Object f
= lua_getparam(FIRSTARG
);
130 if (f
== LUA_NOOBJECT
) {
134 else if (lua_tag(f
) == gettag(IOTAG
))
135 current
= lua_getuserdata(f
);
137 char *s
= luaL_check_string(FIRSTARG
);
138 current
= (*s
== '|') ? popen(s
+1, "r") : fopen(s
, "r");
139 if (current
== NULL
) {
144 setreturn(current
, FINPUT
);
148 static void io_writeto (void)
151 lua_Object f
= lua_getparam(FIRSTARG
);
152 if (f
== LUA_NOOBJECT
) {
156 else if (lua_tag(f
) == gettag(IOTAG
))
157 current
= lua_getuserdata(f
);
159 char *s
= luaL_check_string(FIRSTARG
);
160 current
= (*s
== '|') ? popen(s
+1,"w") : fopen(s
,"w");
161 if (current
== NULL
) {
166 setreturn(current
, FOUTPUT
);
170 static void io_appendto (void)
172 char *s
= luaL_check_string(FIRSTARG
);
173 FILE *fp
= fopen (s
, "a");
175 setreturn(fp
, FOUTPUT
);
181 #define NEED_OTHER (EOF-1) /* just some flag different from EOF */
184 static void read_until (FILE *f
, int lim
) {
187 for (c
= getc(f
); c
!= EOF
&& c
!= lim
; c
= getc(f
)) {
191 if (l
> 0 || c
== lim
) /* read anything? */
192 lua_pushlstring(luaL_buffer(), l
);
195 static void io_read (void) {
197 FILE *f
= getfileparam(FINPUT
, &arg
);
198 char *p
= luaL_opt_string(arg
, NULL
);
200 if (p
== NULL
) /* default: read a line */
202 else if (p
[0] == '.' && p
[1] == '*' && p
[2] == 0) /* p = ".*" */
205 int l
= 0; /* number of chars read in buffer */
206 int inskip
= 0; /* to control {skips} */
216 lua_error("unbalanced braces in read pattern");
221 char *ep
; /* get what is next */
222 int m
; /* match result */
223 if (c
== NEED_OTHER
) c
= getc(f
);
225 luaI_singlematch(0, p
, &ep
); /* to set "ep" */
229 m
= luaI_singlematch(c
, p
, &ep
);
239 case '*': /* repetition */
240 if (!m
) p
= ep
+1; /* else stay in (repeat) the same item */
242 case '?': /* optional */
243 p
= ep
+1; /* continues reading the pattern */
246 if (m
) p
= ep
; /* continues reading the pattern */
248 goto break_while
; /* pattern fails */
253 if (c
>= 0) /* not EOF nor NEED_OTHER? */
255 if (l
> 0 || *p
== 0) /* read something or did not fail? */
256 lua_pushlstring(luaL_buffer(), l
);
261 static void io_write (void)
264 FILE *f
= getfileparam(FOUTPUT
, &arg
);
268 while ((s
= luaL_opt_lstr(arg
++, NULL
, &l
)) != NULL
)
269 status
= status
&& (fwrite(s
, 1, l
, f
) == l
);
274 static void io_execute (void)
276 lua_pushnumber(system(luaL_check_string(1)));
280 static void io_remove (void)
282 pushresult(remove(luaL_check_string(1)) == 0);
286 static void io_rename (void)
288 pushresult(rename(luaL_check_string(1),
289 luaL_check_string(2)) == 0);
293 static void io_tmpname (void)
295 lua_pushstring(tmpnam(NULL
));
300 static void io_getenv (void)
302 lua_pushstring(getenv(luaL_check_string(1))); /* if NULL push nil */
306 static void io_clock (void) {
307 lua_pushnumber(((double)clock())/CLOCKS_PER_SEC
);
311 static void io_date (void)
315 char *s
= luaL_opt_string(1, "%c");
317 time(&t
); tm
= localtime(&t
);
318 if (strftime(b
,sizeof(b
),s
,tm
))
321 lua_error("invalid `date' format");
325 static void setloc (void)
327 static int cat
[] = {LC_ALL
, LC_COLLATE
, LC_CTYPE
, LC_MONETARY
, LC_NUMERIC
,
329 static char *catnames
[] = {"all", "collate", "ctype", "monetary",
330 "numeric", "time", NULL
};
331 int op
= luaL_findstring(luaL_opt_string(2, "all"), catnames
);
332 luaL_arg_check(op
!= -1, 2, "invalid option");
333 lua_pushstring(setlocale(cat
[op
], luaL_check_string(1)));
337 static void io_exit (void)
339 lua_Object o
= lua_getparam(1);
340 exit(lua_isnumber(o
) ? (int)lua_getnumber(o
) : 1);
344 static void io_debug (void)
348 fprintf(stderr
, "lua_debug> ");
349 if (fgets(buffer
, sizeof(buffer
), stdin
) == 0) return;
350 if (strcmp(buffer
, "cont\n") == 0) return;
351 lua_dostring(buffer
);
356 static void lua_printstack (FILE *f
)
358 int level
= 1; /* skip level 0 (it's this function) */
360 while ((func
= lua_stackedfunction(level
++)) != LUA_NOOBJECT
) {
365 lua_funcinfo(func
, &filename
, &linedefined
);
366 fprintf(f
, (level
==2) ? "Active Stack:\n\t" : "\t");
367 switch (*lua_getobjname(func
, &name
)) {
369 fprintf(f
, "function %s", name
);
372 fprintf(f
, "`%s' tag method", name
);
375 if (linedefined
== 0)
376 fprintf(f
, "main of %s", filename
);
377 else if (linedefined
< 0)
378 fprintf(f
, "%s", filename
);
380 fprintf(f
, "function (%s:%d)", filename
, linedefined
);
384 if ((currentline
= lua_currentline(func
)) > 0)
385 fprintf(f
, " at line %d", currentline
);
387 fprintf(f
, " [in file %s]", filename
);
393 static void errorfb (void)
395 fprintf(stderr
, "lua: %s\n", lua_getstring(lua_getparam(1)));
396 lua_printstack(stderr
);
401 static struct luaL_reg iolib
[] = {
402 {"setlocale", setloc
},
403 {"execute", io_execute
},
404 {"remove", io_remove
},
405 {"rename", io_rename
},
406 {"tmpname", io_tmpname
},
407 {"getenv", io_getenv
},
412 {"print_stack", errorfb
}
415 static struct luaL_reg iolibtag
[] = {
416 {"readfrom", io_readfrom
},
417 {"writeto", io_writeto
},
418 {"appendto", io_appendto
},
423 static void openwithtags (void)
425 int iotag
= lua_newtag();
426 int closedtag
= lua_newtag();
428 for (i
=0; i
<sizeof(iolibtag
)/sizeof(iolibtag
[0]); i
++) {
429 /* put both tags as upvalues for these functions */
430 lua_pushnumber(iotag
);
431 lua_pushnumber(closedtag
);
432 lua_pushcclosure(iolibtag
[i
].func
, 2);
433 lua_setglobal(iolibtag
[i
].name
);
435 setfile(stdin
, FINPUT
, iotag
);
436 setfile(stdout
, FOUTPUT
, iotag
);
437 setfile(stdin
, "_STDIN", iotag
);
438 setfile(stdout
, "_STDOUT", iotag
);
439 setfile(stderr
, "_STDERR", iotag
);
442 void lua_iolibopen (void)
444 luaL_openlib(iolib
, (sizeof(iolib
)/sizeof(iolib
[0])));
446 lua_pushcfunction(errorfb
);
447 lua_seterrormethod();