Imported from ../lua-3.0.tar.gz.
[lua.git] / src / inout.c
blob5d710610058dd8a21024afe8e3d129f9d96ec11b
1 /*
2 ** inout.c
3 ** Provide function to realise the input/output function and debugger
4 ** facilities.
5 ** Also provides some predefined lua functions.
6 */
8 char *rcs_inout="$Id: inout.c,v 2.69 1997/06/27 22:38:49 roberto Exp $";
10 #include <stdio.h>
11 #include <string.h>
13 #include "auxlib.h"
14 #include "fallback.h"
15 #include "hash.h"
16 #include "inout.h"
17 #include "lex.h"
18 #include "lua.h"
19 #include "luamem.h"
20 #include "luamem.h"
21 #include "opcode.h"
22 #include "table.h"
23 #include "tree.h"
24 #include "undump.h"
25 #include "zio.h"
28 /* Exported variables */
29 Word lua_linenumber;
30 char *lua_parsedfile;
33 char *luaI_typenames[] = { /* ORDER LUA_T */
34 "userdata", "line", "cmark", "mark", "function",
35 "function", "table", "string", "number", "nil",
36 NULL
41 void luaI_setparsedfile (char *name)
43 lua_parsedfile = luaI_createfixedstring(name)->str;
47 int lua_doFILE (FILE *f, int bin)
49 ZIO z;
50 luaZ_Fopen(&z, f);
51 if (bin)
52 return luaI_undump(&z);
53 else {
54 lua_setinput(&z);
55 return lua_domain();
60 int lua_dofile (char *filename)
62 int status;
63 int c;
64 FILE *f = (filename == NULL) ? stdin : fopen(filename, "r");
65 if (f == NULL)
66 return 2;
67 luaI_setparsedfile(filename?filename:"(stdin)");
68 c = fgetc(f);
69 ungetc(c, f);
70 if (c == ID_CHUNK) {
71 f = freopen(filename, "rb", f); /* set binary mode */
72 status = lua_doFILE(f, 1);
74 else {
75 if (c == '#')
76 while ((c=fgetc(f)) != '\n') /* skip first line */;
77 status = lua_doFILE(f, 0);
79 if (f != stdin)
80 fclose(f);
81 return status;
86 #define SIZE_PREF 20 /* size of string prefix to appear in error messages */
89 int lua_dobuffer (char *buff, int size)
91 int status;
92 ZIO z;
93 luaI_setparsedfile("(buffer)");
94 luaZ_mopen(&z, buff, size);
95 status = luaI_undump(&z);
96 return status;
100 int lua_dostring (char *str)
102 int status;
103 char buff[SIZE_PREF+25];
104 char *temp;
105 ZIO z;
106 if (str == NULL) return 1;
107 sprintf(buff, "(dostring) >> %.20s", str);
108 temp = strchr(buff, '\n');
109 if (temp) *temp = 0; /* end string after first line */
110 luaI_setparsedfile(buff);
111 luaZ_sopen(&z, str);
112 lua_setinput(&z);
113 status = lua_domain();
114 return status;
120 static int passresults (void)
122 int arg = 0;
123 lua_Object obj;
124 while ((obj = lua_getresult(++arg)) != LUA_NOOBJECT)
125 lua_pushobject(obj);
126 return arg-1;
130 static void packresults (void)
132 int arg = 0;
133 lua_Object obj;
134 lua_Object table = lua_createtable();
135 while ((obj = lua_getresult(++arg)) != LUA_NOOBJECT) {
136 lua_pushobject(table);
137 lua_pushnumber(arg);
138 lua_pushobject(obj);
139 lua_rawsettable();
141 lua_pushobject(table);
142 lua_pushstring("n");
143 lua_pushnumber(arg-1);
144 lua_rawsettable();
145 lua_pushobject(table); /* final result */
149 ** Internal function: do a string
151 static void lua_internaldostring (void)
153 lua_Object err = lua_getparam(2);
154 if (err != LUA_NOOBJECT) { /* set new error method */
155 luaL_arg_check(lua_isnil(err) || lua_isfunction(err), 2,
156 "must be a valid error handler");
157 lua_pushobject(err);
158 err = lua_seterrormethod();
160 if (lua_dostring(luaL_check_string(1)) == 0)
161 if (passresults() == 0)
162 lua_pushuserdata(NULL); /* at least one result to signal no errors */
163 if (err != LUA_NOOBJECT) { /* restore old error method */
164 lua_pushobject(err);
165 lua_seterrormethod();
170 ** Internal function: do a file
172 static void lua_internaldofile (void)
174 char *fname = luaL_opt_string(1, NULL);
175 if (lua_dofile(fname) == 0)
176 if (passresults() == 0)
177 lua_pushuserdata(NULL); /* at least one result to signal no errors */
181 static char *tostring (lua_Object obj)
183 TObject *o = luaI_Address(obj);
184 switch (ttype(o)) {
185 case LUA_T_NUMBER: case LUA_T_STRING:
186 return lua_getstring(obj);
187 case LUA_T_ARRAY: case LUA_T_FUNCTION:
188 case LUA_T_CFUNCTION: case LUA_T_NIL:
189 return luaI_typenames[-ttype(o)];
190 case LUA_T_USERDATA: {
191 char *buff = luaI_buffer(30);
192 sprintf(buff, "userdata: %p", o->value.ts->u.v);
193 return buff;
195 default: return "<unknown object>";
199 static void luaI_tostring (void)
201 lua_pushstring(tostring(lua_getparam(1)));
204 static void luaI_print (void)
206 int i = 1;
207 lua_Object obj;
208 while ((obj = lua_getparam(i++)) != LUA_NOOBJECT)
209 printf("%s\n", tostring(obj));
212 static void luaI_type (void)
214 lua_Object o = lua_getparam(1);
215 luaL_arg_check(o != LUA_NOOBJECT, 1, "no argument");
216 lua_pushstring(luaI_typenames[-ttype(luaI_Address(o))]);
217 lua_pushnumber(lua_tag(o));
221 ** Internal function: convert an object to a number
223 static void lua_obj2number (void)
225 lua_Object o = lua_getparam(1);
226 if (lua_isnumber(o))
227 lua_pushnumber(lua_getnumber(o));
231 static void luaI_error (void)
233 char *s = lua_getstring(lua_getparam(1));
234 if (s == NULL) s = "(no message)";
235 lua_error(s);
238 static void luaI_assert (void)
240 lua_Object p = lua_getparam(1);
241 if (p == LUA_NOOBJECT || lua_isnil(p))
242 lua_error("assertion failed!");
245 static void luaI_setglobal (void)
247 lua_Object value = lua_getparam(2);
248 luaL_arg_check(value != LUA_NOOBJECT, 2, NULL);
249 lua_pushobject(value);
250 lua_setglobal(luaL_check_string(1));
251 lua_pushobject(value); /* return given value */
254 static void luaI_rawsetglobal (void)
256 lua_Object value = lua_getparam(2);
257 luaL_arg_check(value != LUA_NOOBJECT, 2, NULL);
258 lua_pushobject(value);
259 lua_rawsetglobal(luaL_check_string(1));
260 lua_pushobject(value); /* return given value */
263 static void luaI_getglobal (void)
265 lua_pushobject(lua_getglobal(luaL_check_string(1)));
268 static void luaI_rawgetglobal (void)
270 lua_pushobject(lua_rawgetglobal(luaL_check_string(1)));
273 static void luatag (void)
275 lua_pushnumber(lua_tag(lua_getparam(1)));
279 static int getnarg (lua_Object table)
281 lua_Object temp;
282 /* temp = table.n */
283 lua_pushobject(table); lua_pushstring("n"); temp = lua_gettable();
284 return (lua_isnumber(temp) ? lua_getnumber(temp) : MAX_WORD);
287 static void luaI_call (void)
289 lua_Object f = lua_getparam(1);
290 lua_Object arg = lua_getparam(2);
291 int withtable = (strcmp(luaL_opt_string(3, ""), "pack") == 0);
292 int narg, i;
293 luaL_arg_check(lua_isfunction(f), 1, "function expected");
294 luaL_arg_check(lua_istable(arg), 2, "table expected");
295 narg = getnarg(arg);
296 /* push arg[1...n] */
297 for (i=0; i<narg; i++) {
298 lua_Object temp;
299 /* temp = arg[i+1] */
300 lua_pushobject(arg); lua_pushnumber(i+1); temp = lua_gettable();
301 if (narg == MAX_WORD && lua_isnil(temp))
302 break;
303 lua_pushobject(temp);
305 if (lua_callfunction(f))
306 lua_error(NULL);
307 else if (withtable)
308 packresults();
309 else
310 passresults();
313 static void luaIl_settag (void)
315 lua_Object o = lua_getparam(1);
316 luaL_arg_check(lua_istable(o), 1, "table expected");
317 lua_pushobject(o);
318 lua_settag(luaL_check_number(2));
321 static void luaIl_newtag (void)
323 lua_pushnumber(lua_newtag());
326 static void rawgettable (void)
328 lua_Object t = lua_getparam(1);
329 lua_Object i = lua_getparam(2);
330 luaL_arg_check(t != LUA_NOOBJECT, 1, NULL);
331 luaL_arg_check(i != LUA_NOOBJECT, 2, NULL);
332 lua_pushobject(t);
333 lua_pushobject(i);
334 lua_pushobject(lua_rawgettable());
337 static void rawsettable (void)
339 lua_Object t = lua_getparam(1);
340 lua_Object i = lua_getparam(2);
341 lua_Object v = lua_getparam(3);
342 luaL_arg_check(t != LUA_NOOBJECT && i != LUA_NOOBJECT && v != LUA_NOOBJECT,
343 0, NULL);
344 lua_pushobject(t);
345 lua_pushobject(i);
346 lua_pushobject(v);
347 lua_rawsettable();
351 static void luaI_collectgarbage (void)
353 lua_pushnumber(lua_collectgarbage(luaL_opt_number(1, 0)));
358 ** Internal functions
360 static struct {
361 char *name;
362 lua_CFunction func;
363 } int_funcs[] = {
364 {"assert", luaI_assert},
365 {"call", luaI_call},
366 {"collectgarbage", luaI_collectgarbage},
367 {"dofile", lua_internaldofile},
368 {"dostring", lua_internaldostring},
369 {"error", luaI_error},
370 {"getglobal", luaI_getglobal},
371 {"newtag", luaIl_newtag},
372 {"next", lua_next},
373 {"nextvar", luaI_nextvar},
374 {"print", luaI_print},
375 {"rawgetglobal", luaI_rawgetglobal},
376 {"rawgettable", rawgettable},
377 {"rawsetglobal", luaI_rawsetglobal},
378 {"rawsettable", rawsettable},
379 {"seterrormethod", luaI_seterrormethod},
380 #if LUA_COMPAT2_5
381 {"setfallback", luaI_setfallback},
382 #endif
383 {"setglobal", luaI_setglobal},
384 {"settagmethod", luaI_settagmethod},
385 {"gettagmethod", luaI_gettagmethod},
386 {"settag", luaIl_settag},
387 {"tonumber", lua_obj2number},
388 {"tostring", luaI_tostring},
389 {"tag", luatag},
390 {"type", luaI_type}
393 #define INTFUNCSIZE (sizeof(int_funcs)/sizeof(int_funcs[0]))
396 void luaI_predefine (void)
398 int i;
399 Word n;
400 for (i=0; i<INTFUNCSIZE; i++) {
401 n = luaI_findsymbolbyname(int_funcs[i].name);
402 s_ttype(n) = LUA_T_CFUNCTION; s_fvalue(n) = int_funcs[i].func;
404 n = luaI_findsymbolbyname("_VERSION");
405 s_ttype(n) = LUA_T_STRING; s_tsvalue(n) = lua_createstring(LUA_VERSION);