diff options
Diffstat (limited to 'fixed/iolib.c')
-rw-r--r-- | fixed/iolib.c | 402 |
1 files changed, 402 insertions, 0 deletions
diff --git a/fixed/iolib.c b/fixed/iolib.c new file mode 100644 index 00000000..dce91f9d --- /dev/null +++ b/fixed/iolib.c | |||
@@ -0,0 +1,402 @@ | |||
1 | /* | ||
2 | ** iolib.c | ||
3 | ** Input/output library to LUA | ||
4 | ** | ||
5 | ** Waldemar Celes Filho | ||
6 | ** TeCGraf - PUC-Rio | ||
7 | ** 19 May 93 | ||
8 | */ | ||
9 | |||
10 | #include <stdlib.h> | ||
11 | #include <string.h> | ||
12 | #include <stdio.h> | ||
13 | #include <ctype.h> | ||
14 | #ifdef __GNUC__ | ||
15 | #include <floatingpoint.h> | ||
16 | #endif | ||
17 | |||
18 | #include "lua.h" | ||
19 | |||
20 | static FILE *in=NULL, *out=NULL; | ||
21 | |||
22 | /* | ||
23 | ** Open a file to read. | ||
24 | ** LUA interface: | ||
25 | ** status = readfrom (filename) | ||
26 | ** where: | ||
27 | ** status = 1 -> success | ||
28 | ** status = 0 -> error | ||
29 | */ | ||
30 | static void io_readfrom (void) | ||
31 | { | ||
32 | lua_Object o = lua_getparam (1); | ||
33 | if (o == NULL) /* restore standart input */ | ||
34 | { | ||
35 | if (in != stdin) | ||
36 | { | ||
37 | fclose (in); | ||
38 | in = stdin; | ||
39 | } | ||
40 | lua_pushnumber (1); | ||
41 | } | ||
42 | else | ||
43 | { | ||
44 | if (!lua_isstring (o)) | ||
45 | { | ||
46 | lua_error ("incorrect argument to function 'readfrom`"); | ||
47 | lua_pushnumber (0); | ||
48 | } | ||
49 | else | ||
50 | { | ||
51 | FILE *fp = fopen (lua_getstring(o),"r"); | ||
52 | if (fp == NULL) | ||
53 | { | ||
54 | lua_pushnumber (0); | ||
55 | } | ||
56 | else | ||
57 | { | ||
58 | if (in != stdin) fclose (in); | ||
59 | in = fp; | ||
60 | lua_pushnumber (1); | ||
61 | } | ||
62 | } | ||
63 | } | ||
64 | } | ||
65 | |||
66 | |||
67 | /* | ||
68 | ** Open a file to write. | ||
69 | ** LUA interface: | ||
70 | ** status = writeto (filename) | ||
71 | ** where: | ||
72 | ** status = 1 -> success | ||
73 | ** status = 0 -> error | ||
74 | */ | ||
75 | static void io_writeto (void) | ||
76 | { | ||
77 | lua_Object o = lua_getparam (1); | ||
78 | if (o == NULL) /* restore standart output */ | ||
79 | { | ||
80 | if (out != stdout) | ||
81 | { | ||
82 | fclose (out); | ||
83 | out = stdout; | ||
84 | } | ||
85 | lua_pushnumber (1); | ||
86 | } | ||
87 | else | ||
88 | { | ||
89 | if (!lua_isstring (o)) | ||
90 | { | ||
91 | lua_error ("incorrect argument to function 'writeto`"); | ||
92 | lua_pushnumber (0); | ||
93 | } | ||
94 | else | ||
95 | { | ||
96 | FILE *fp = fopen (lua_getstring(o),"w"); | ||
97 | if (fp == NULL) | ||
98 | { | ||
99 | lua_pushnumber (0); | ||
100 | } | ||
101 | else | ||
102 | { | ||
103 | if (out != stdout) fclose (out); | ||
104 | out = fp; | ||
105 | lua_pushnumber (1); | ||
106 | } | ||
107 | } | ||
108 | } | ||
109 | } | ||
110 | |||
111 | |||
112 | /* | ||
113 | ** Read a variable. On error put nil on stack. | ||
114 | ** LUA interface: | ||
115 | ** variable = read ([format]) | ||
116 | ** | ||
117 | ** O formato pode ter um dos seguintes especificadores: | ||
118 | ** | ||
119 | ** s ou S -> para string | ||
120 | ** f ou F, g ou G, e ou E -> para reais | ||
121 | ** i ou I -> para inteiros | ||
122 | ** | ||
123 | ** Estes especificadores podem vir seguidos de numero que representa | ||
124 | ** o numero de campos a serem lidos. | ||
125 | */ | ||
126 | static void io_read (void) | ||
127 | { | ||
128 | lua_Object o = lua_getparam (1); | ||
129 | if (o == NULL) /* free format */ | ||
130 | { | ||
131 | int c; | ||
132 | char s[256]; | ||
133 | while (isspace(c=fgetc(in))) | ||
134 | ; | ||
135 | if (c == '\"') | ||
136 | { | ||
137 | if (fscanf (in, "%[^\"]\"", s) != 1) | ||
138 | { | ||
139 | lua_pushnil (); | ||
140 | return; | ||
141 | } | ||
142 | } | ||
143 | else if (c == '\'') | ||
144 | { | ||
145 | if (fscanf (in, "%[^\']\'", s) != 1) | ||
146 | { | ||
147 | lua_pushnil (); | ||
148 | return; | ||
149 | } | ||
150 | } | ||
151 | else | ||
152 | { | ||
153 | char *ptr; | ||
154 | double d; | ||
155 | ungetc (c, in); | ||
156 | if (fscanf (in, "%s", s) != 1) | ||
157 | { | ||
158 | lua_pushnil (); | ||
159 | return; | ||
160 | } | ||
161 | d = strtod (s, &ptr); | ||
162 | if (!(*ptr)) | ||
163 | { | ||
164 | lua_pushnumber (d); | ||
165 | return; | ||
166 | } | ||
167 | } | ||
168 | lua_pushstring (s); | ||
169 | return; | ||
170 | } | ||
171 | else /* formatted */ | ||
172 | { | ||
173 | char *e = lua_getstring(o); | ||
174 | char t; | ||
175 | int m=0; | ||
176 | while (isspace(*e)) e++; | ||
177 | t = *e++; | ||
178 | while (isdigit(*e)) | ||
179 | m = m*10 + (*e++ - '0'); | ||
180 | |||
181 | if (m > 0) | ||
182 | { | ||
183 | char f[80]; | ||
184 | char s[256]; | ||
185 | sprintf (f, "%%%ds", m); | ||
186 | fscanf (in, f, s); | ||
187 | switch (tolower(t)) | ||
188 | { | ||
189 | case 'i': | ||
190 | { | ||
191 | long int l; | ||
192 | sscanf (s, "%ld", &l); | ||
193 | lua_pushnumber(l); | ||
194 | } | ||
195 | break; | ||
196 | case 'f': case 'g': case 'e': | ||
197 | { | ||
198 | float f; | ||
199 | sscanf (s, "%f", &f); | ||
200 | lua_pushnumber(f); | ||
201 | } | ||
202 | break; | ||
203 | default: | ||
204 | lua_pushstring(s); | ||
205 | break; | ||
206 | } | ||
207 | } | ||
208 | else | ||
209 | { | ||
210 | switch (tolower(t)) | ||
211 | { | ||
212 | case 'i': | ||
213 | { | ||
214 | long int l; | ||
215 | fscanf (in, "%ld", &l); | ||
216 | lua_pushnumber(l); | ||
217 | } | ||
218 | break; | ||
219 | case 'f': case 'g': case 'e': | ||
220 | { | ||
221 | float f; | ||
222 | fscanf (in, "%f", &f); | ||
223 | lua_pushnumber(f); | ||
224 | } | ||
225 | break; | ||
226 | default: | ||
227 | { | ||
228 | char s[256]; | ||
229 | fscanf (in, "%s", s); | ||
230 | lua_pushstring(s); | ||
231 | } | ||
232 | break; | ||
233 | } | ||
234 | } | ||
235 | } | ||
236 | } | ||
237 | |||
238 | |||
239 | /* | ||
240 | ** Write a variable. On error put 0 on stack, otherwise put 1. | ||
241 | ** LUA interface: | ||
242 | ** status = write (variable [,format]) | ||
243 | ** | ||
244 | ** O formato pode ter um dos seguintes especificadores: | ||
245 | ** | ||
246 | ** s ou S -> para string | ||
247 | ** f ou F, g ou G, e ou E -> para reais | ||
248 | ** i ou I -> para inteiros | ||
249 | ** | ||
250 | ** Estes especificadores podem vir seguidos de: | ||
251 | ** | ||
252 | ** [?][m][.n] | ||
253 | ** | ||
254 | ** onde: | ||
255 | ** ? -> indica justificacao | ||
256 | ** < = esquerda | ||
257 | ** | = centro | ||
258 | ** > = direita (default) | ||
259 | ** m -> numero maximo de campos (se exceder estoura) | ||
260 | ** n -> indica precisao para | ||
261 | ** reais -> numero de casas decimais | ||
262 | ** inteiros -> numero minimo de digitos | ||
263 | ** string -> nao se aplica | ||
264 | */ | ||
265 | static char *buildformat (char *e, lua_Object o) | ||
266 | { | ||
267 | static char buffer[512]; | ||
268 | static char f[80]; | ||
269 | char *string = &buffer[255]; | ||
270 | char t, j='r'; | ||
271 | int m=0, n=0, l; | ||
272 | while (isspace(*e)) e++; | ||
273 | t = *e++; | ||
274 | if (*e == '<' || *e == '|' || *e == '>') j = *e++; | ||
275 | while (isdigit(*e)) | ||
276 | m = m*10 + (*e++ - '0'); | ||
277 | e++; /* skip point */ | ||
278 | while (isdigit(*e)) | ||
279 | n = n*10 + (*e++ - '0'); | ||
280 | |||
281 | sprintf(f,"%%"); | ||
282 | if (j == '<' || j == '|') sprintf(strchr(f,0),"-"); | ||
283 | if (m != 0) sprintf(strchr(f,0),"%d", m); | ||
284 | if (n != 0) sprintf(strchr(f,0),".%d", n); | ||
285 | sprintf(strchr(f,0), "%c", t); | ||
286 | switch (tolower(t)) | ||
287 | { | ||
288 | case 'i': t = 'i'; | ||
289 | sprintf (string, f, (long int)lua_getnumber(o)); | ||
290 | break; | ||
291 | case 'f': case 'g': case 'e': t = 'f'; | ||
292 | sprintf (string, f, (float)lua_getnumber(o)); | ||
293 | break; | ||
294 | case 's': t = 's'; | ||
295 | sprintf (string, f, lua_getstring(o)); | ||
296 | break; | ||
297 | default: return ""; | ||
298 | } | ||
299 | l = strlen(string); | ||
300 | if (m!=0 && l>m) | ||
301 | { | ||
302 | int i; | ||
303 | for (i=0; i<m; i++) | ||
304 | string[i] = '*'; | ||
305 | string[i] = 0; | ||
306 | } | ||
307 | else if (m!=0 && j=='|') | ||
308 | { | ||
309 | int i=l-1; | ||
310 | while (isspace(string[i])) i--; | ||
311 | string -= (m-i) / 2; | ||
312 | i=0; | ||
313 | while (string[i]==0) string[i++] = ' '; | ||
314 | string[l] = 0; | ||
315 | } | ||
316 | return string; | ||
317 | } | ||
318 | static void io_write (void) | ||
319 | { | ||
320 | lua_Object o1 = lua_getparam (1); | ||
321 | lua_Object o2 = lua_getparam (2); | ||
322 | if (o1 == NULL) /* new line */ | ||
323 | { | ||
324 | fprintf (out, "\n"); | ||
325 | lua_pushnumber(1); | ||
326 | } | ||
327 | else if (o2 == NULL) /* free format */ | ||
328 | { | ||
329 | int status=0; | ||
330 | if (lua_isnumber(o1)) | ||
331 | status = fprintf (out, "%g", lua_getnumber(o1)); | ||
332 | else if (lua_isstring(o1)) | ||
333 | status = fprintf (out, "%s", lua_getstring(o1)); | ||
334 | lua_pushnumber(status); | ||
335 | } | ||
336 | else /* formated */ | ||
337 | { | ||
338 | if (!lua_isstring(o2)) | ||
339 | { | ||
340 | lua_error ("incorrect format to function `write'"); | ||
341 | lua_pushnumber(0); | ||
342 | return; | ||
343 | } | ||
344 | lua_pushnumber(fprintf (out, "%s", buildformat(lua_getstring(o2),o1))); | ||
345 | } | ||
346 | } | ||
347 | |||
348 | /* | ||
349 | ** Execute a executable program using "sustem". | ||
350 | ** On error put 0 on stack, otherwise put 1. | ||
351 | */ | ||
352 | void io_execute (void) | ||
353 | { | ||
354 | lua_Object o = lua_getparam (1); | ||
355 | if (o == NULL || !lua_isstring (o)) | ||
356 | { | ||
357 | lua_error ("incorrect argument to function 'execute`"); | ||
358 | lua_pushnumber (0); | ||
359 | } | ||
360 | else | ||
361 | { | ||
362 | system(lua_getstring(o)); | ||
363 | lua_pushnumber (1); | ||
364 | } | ||
365 | return; | ||
366 | } | ||
367 | |||
368 | /* | ||
369 | ** Remove a file. | ||
370 | ** On error put 0 on stack, otherwise put 1. | ||
371 | */ | ||
372 | void io_remove (void) | ||
373 | { | ||
374 | lua_Object o = lua_getparam (1); | ||
375 | if (o == NULL || !lua_isstring (o)) | ||
376 | { | ||
377 | lua_error ("incorrect argument to function 'execute`"); | ||
378 | lua_pushnumber (0); | ||
379 | } | ||
380 | else | ||
381 | { | ||
382 | if (remove(lua_getstring(o)) == 0) | ||
383 | lua_pushnumber (1); | ||
384 | else | ||
385 | lua_pushnumber (0); | ||
386 | } | ||
387 | return; | ||
388 | } | ||
389 | |||
390 | /* | ||
391 | ** Open io library | ||
392 | */ | ||
393 | void iolib_open (void) | ||
394 | { | ||
395 | in=stdin; out=stdout; | ||
396 | lua_register ("readfrom", io_readfrom); | ||
397 | lua_register ("writeto", io_writeto); | ||
398 | lua_register ("read", io_read); | ||
399 | lua_register ("write", io_write); | ||
400 | lua_register ("execute", io_execute); | ||
401 | lua_register ("remove", io_remove); | ||
402 | } | ||