summaryrefslogtreecommitdiff
path: root/iolib.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1996-11-01 15:03:36 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1996-11-01 15:03:36 -0200
commit450465c4d4c765ef83e6b27d5e8d8591db55ef00 (patch)
treebd5a740fb9c021a544c4d13c1ce35fdb1b6a757e /iolib.c
parent2f44cc9f4d62cbdc6e752d5328408fc5123bedcc (diff)
downloadlua-450465c4d4c765ef83e6b27d5e8d8591db55ef00.tar.gz
lua-450465c4d4c765ef83e6b27d5e8d8591db55ef00.tar.bz2
lua-450465c4d4c765ef83e6b27d5e8d8591db55ef00.zip
new parameters for "read" and "write". BIG CHANGE.
Diffstat (limited to '')
-rw-r--r--iolib.c562
1 files changed, 124 insertions, 438 deletions
diff --git a/iolib.c b/iolib.c
index e689335d..eeeb43c4 100644
--- a/iolib.c
+++ b/iolib.c
@@ -1,10 +1,3 @@
1/*
2** iolib.c
3** Input/output library to LUA
4*/
5
6char *rcs_iolib="$Id: iolib.c,v 1.47 1996/08/01 14:55:33 roberto Exp roberto $";
7
8#include <stdio.h> 1#include <stdio.h>
9#include <ctype.h> 2#include <ctype.h>
10#include <string.h> 3#include <string.h>
@@ -16,7 +9,8 @@ char *rcs_iolib="$Id: iolib.c,v 1.47 1996/08/01 14:55:33 roberto Exp roberto $";
16#include "luadebug.h" 9#include "luadebug.h"
17#include "lualib.h" 10#include "lualib.h"
18 11
19static FILE *in, *out; 12
13FILE *lua_infile, *lua_outfile;
20 14
21 15
22#ifdef POPEN 16#ifdef POPEN
@@ -31,496 +25,194 @@ int pclose();
31static void pushresult (int i) 25static void pushresult (int i)
32{ 26{
33 if (i) 27 if (i)
34 lua_pushnumber (1); 28 lua_pushuserdata(NULL);
35} 29 else {
36 30 lua_pushnil();
37static void closeread (void) 31 lua_pushstring(strerror(errno));
38{
39 if (in != stdin)
40 {
41 if (pclose(in) == -1)
42 fclose(in);
43 in = stdin;
44 } 32 }
45} 33}
46 34
47static void closewrite (void) 35
36static void closefile (FILE *f)
48{ 37{
49 if (out != stdout) 38 if (f == stdin || f == stdout)
50 { 39 return;
51 if (pclose(out) == -1) 40 if (f == lua_infile)
52 fclose(out); 41 lua_infile = stdin;
53 out = stdout; 42 if (f == lua_outfile)
54 } 43 lua_outfile = stdout;
44 if (pclose(f) == -1)
45 fclose(f);
55} 46}
56 47
57/* 48
58** Open a file to read. 49
59** LUA interface:
60** status = readfrom (filename)
61** where:
62** status = 1 -> success
63** status = nil -> error
64*/
65static void io_readfrom (void) 50static void io_readfrom (void)
66{ 51{
67 if (lua_getparam (1) == LUA_NOOBJECT) 52 lua_Object f = lua_getparam(1);
68 { /* restore standart input */ 53 if (f == LUA_NOOBJECT)
69 closeread(); 54 closefile(lua_infile); /* restore standart input */
70 lua_pushnumber (1); 55 else if (lua_isuserdata(f))
71 } 56 lua_infile = lua_getuserdata(f);
72 else 57 else {
73 { 58 char *s = lua_check_string(1, "readfrom");
74 char *s = lua_check_string(1, "readfrom"); 59 FILE *fp = (*s == '|') ? popen(s+1, "r") : fopen(s, "r");
75 FILE *fp = (*s == '|') ? popen(s+1, "r") : fopen(s, "r"); 60 if (fp)
76 if (fp == NULL) 61 lua_infile = fp;
77 lua_pushnil(); 62 else {
78 else 63 pushresult(0);
79 { 64 return;
80 closeread(); 65 }
81 in = fp; 66 }
82 lua_pushnumber (1); 67 lua_pushuserdata(lua_infile);
83 }
84 }
85} 68}
86 69
87 70
88/*
89** Open a file to write.
90** LUA interface:
91** status = writeto (filename)
92** where:
93** status = 1 -> success
94** status = nil -> error
95*/
96static void io_writeto (void) 71static void io_writeto (void)
97{ 72{
98 if (lua_getparam (1) == LUA_NOOBJECT) /* restore standart output */ 73 lua_Object f = lua_getparam(1);
99 { 74 if (f == LUA_NOOBJECT)
100 closewrite(); 75 closefile(lua_outfile); /* restore standart output */
101 lua_pushnumber (1); 76 else if (lua_isuserdata(f))
102 } 77 lua_outfile = lua_getuserdata(f);
103 else 78 else {
104 { 79 char *s = lua_check_string(1, "writeto");
105 char *s = lua_check_string(1, "writeto"); 80 FILE *fp = (*s == '|') ? popen(s+1,"w") : fopen(s,"w");
106 FILE *fp = (*s == '|') ? popen(s+1,"w") : fopen(s,"w"); 81 if (fp)
107 if (fp) 82 lua_outfile = fp;
108 { 83 else {
109 closewrite(); 84 pushresult(0);
110 out = fp; 85 return;
111 lua_pushnumber (1); 86 }
112 } 87 }
113 } 88 lua_pushuserdata(lua_outfile);
114} 89}
115 90
116 91
117/*
118** Open a file to write appended.
119** LUA interface:
120** status = appendto (filename)
121** where:
122** status = 1 -> success
123** status = nil -> error
124*/
125static void io_appendto (void) 92static void io_appendto (void)
126{ 93{
127 char *s = lua_check_string(1, "appendto"); 94 char *s = lua_check_string(1, "appendto");
128 FILE *fp = fopen (s, "a"); 95 FILE *fp = fopen (s, "a");
129 if (fp) 96 if (fp != NULL) {
130 { 97 lua_outfile = fp;
131 if (out != stdout) fclose (out); 98 lua_pushuserdata(lua_outfile);
132 out = fp;
133 lua_pushnumber(1);
134 }
135}
136
137
138static char getformat (char *f, int *just, long *m, int *n)
139{
140 int t;
141 switch (*f++)
142 {
143 case 'q': case 'Q':
144 case 's': case 'S':
145 case 'i': case 'I':
146 t = tolower(*(f-1));
147 break;
148 case 'f': case 'F': case 'g': case 'G': case 'e': case 'E':
149 t = 'f';
150 break;
151 default:
152 t = 0; /* to avoid compiler warnings */
153 lua_arg_check(0, "read/write (format)");
154 }
155 *just = (*f == '<' || *f == '>' || *f == '|') ? *f++ : '>';
156 if (isdigit(*f))
157 {
158 *m = 0;
159 while (isdigit(*f))
160 *m = *m*10 + (*f++ - '0');
161 }
162 else
163 *m = -1;
164 if (*f == '.')
165 {
166 f++; /* skip point */
167 *n = 0;
168 while (isdigit(*f))
169 *n = *n*10 + (*f++ - '0');
170 } 99 }
171 else 100 else
172 *n = -1; 101 pushresult(0);
173 return t;
174} 102}
175 103
176 104
177/* 105#define NEED_OTHER (EOF-1) /* just some flag different from EOF */
178** Read a variable. On error put nil on stack.
179** LUA interface:
180** variable = read ([format])
181**
182** O formato pode ter um dos seguintes especificadores:
183**
184** s ou S -> para string
185** f ou F, g ou G, e ou E -> para reais
186** i ou I -> para inteiros
187**
188** Estes especificadores podem vir seguidos de numero que representa
189** o numero de campos a serem lidos.
190*/
191
192static int read_until_char (int del)
193{
194 int c;
195 while((c = fgetc(in)) != EOF && c != del)
196 luaI_addchar(c);
197 return c;
198}
199
200static void read_until_blank (void)
201{
202 int c;
203 while((c = fgetc(in)) != EOF && !isspace(c))
204 luaI_addchar(c);
205 if (c != EOF) ungetc(c,in);
206}
207
208static void read_m (size_t m)
209{
210 int c;
211 while (m-- && (c = fgetc(in)) != EOF)
212 luaI_addchar(c);
213}
214
215
216static void read_free (void)
217{
218 int c;
219 while (isspace(c=fgetc(in)))
220 ;
221 if (c == EOF)
222 return;
223 if (c == '\"' || c == '\'')
224 { /* string */
225 c = read_until_char(c);
226 if (c != EOF)
227 lua_pushstring(luaI_addchar(0));
228 }
229 else
230 {
231 double d;
232 char dummy;
233 char *s;
234 luaI_addchar(c);
235 read_until_blank();
236 s = luaI_addchar(0);
237 if (sscanf(s, "%lf %c", &d, &dummy) == 1)
238 lua_pushnumber(d);
239 else
240 lua_pushstring(s);
241 }
242}
243 106
244static void io_read (void) 107static void io_read (void)
245{ 108{
246 lua_Object o = lua_getparam (1); 109 char *buff;
247 luaI_addchar(0); /* initialize buffer */ 110 char *p = lua_opt_string(1, "[^\n]*{\n}", "read");
248 if (o == LUA_NOOBJECT) /* free format */ 111 int inskip = 0; /* to control {skips} */
249 read_free(); 112 int c = NEED_OTHER;
250 else /* formatted */ 113 luaI_addchar(0);
251 { 114 while (*p) {
252 long m; 115 if (*p == '{' || *p == '}') {
253 int dummy1, dummy2; 116 inskip = (*p == '{');
254 switch (getformat(lua_check_string(1, "read"), &dummy1, &m, &dummy2)) 117 p++;
255 { 118 }
256 case 's': 119 else {
257 { 120 char *ep = item_end(p); /* get what is next */
258 char *s; 121 int m;
259 if (m < 0) 122 if (c == NEED_OTHER) c = getc(lua_infile);
260 read_until_blank(); 123 if ((m = singlematch(c, p)) != 0) {
261 else 124 if (!inskip) luaI_addchar(c);
262 read_m(m); 125 c = NEED_OTHER;
263 s = luaI_addchar(0);
264 if ((m >= 0 && strlen(s) == m) || (m < 0 && strlen(s) > 0))
265 lua_pushstring(s);
266 break;
267 } 126 }
268 127 switch (*ep) {
269 case 'i': /* can read as float, since it makes no difference to Lua */ 128 case '*': /* repetition */
270 case 'f': 129 if (!m) p = ep+1; /* else stay in (repeat) the same item */
271 { 130 break;
272 double d; 131 case '?': /* optional */
273 int result; 132 p = ep+1; /* continues reading the pattern */
274 if (m < 0) 133 break;
275 result = fscanf(in, "%lf", &d); 134 default:
276 else 135 if (m) p = ep; /* continues reading the pattern */
277 { 136 else
278 read_m(m); 137 goto break_while; /* pattern fails */
279 result = sscanf(luaI_addchar(0), "%lf", &d);
280 }
281 if (result == 1)
282 lua_pushnumber(d);
283 break;
284 } 138 }
285 default:
286 lua_arg_check(0, "read (format)");
287 } 139 }
288 } 140 } break_while:
289} 141 if (c >= 0) /* not EOF nor NEED_OTHER? */
290 142 ungetc(c, lua_infile);
291 143 buff = luaI_addchar(0);
292/* 144 if (*buff != 0 || *p == 0) /* read something or did not fail? */
293** Read characters until a given one. The delimiter is not read. 145 lua_pushstring(buff);
294*/
295static void io_readuntil (void)
296{
297 int del, c;
298 lua_Object p = lua_getparam(1);
299 luaI_addchar(0); /* initialize buffer */
300 if (p == LUA_NOOBJECT || lua_isnil(p))
301 del = EOF;
302 else
303 del = *lua_check_string(1, "readuntil");
304 c = read_until_char(del);
305 if (c != EOF) ungetc(c,in);
306 lua_pushstring(luaI_addchar(0));
307}
308
309
310/*
311** Write a variable. On error put 0 on stack, otherwise put 1.
312** LUA interface:
313** status = write (variable [,format])
314**
315** O formato pode ter um dos seguintes especificadores:
316**
317** s ou S -> para string
318** f ou F, g ou G, e ou E -> para reais
319** i ou I -> para inteiros
320**
321** Estes especificadores podem vir seguidos de:
322**
323** [?][m][.n]
324**
325** onde:
326** ? -> indica justificacao
327** < = esquerda
328** | = centro
329** > = direita (default)
330** m -> numero maximo de campos (se exceder estoura)
331** n -> indica precisao para
332** reais -> numero de casas decimais
333** inteiros -> numero minimo de digitos
334** string -> nao se aplica
335*/
336
337static int write_fill (size_t n, int c)
338{
339 while (n--)
340 if (fputc(c, out) == EOF)
341 return 0;
342 return 1;
343}
344
345static int write_string (char *s, int just, long m)
346{
347 int status;
348 size_t l = strlen(s);
349 size_t pre; /* number of blanks before string */
350 if (m < 0) m = l;
351 else if (l > m)
352 {
353 write_fill(m, '*');
354 return 0;
355 }
356 pre = (just == '<') ? 0 : (just == '>') ? m-l : (m-l)/2;
357 status = write_fill(pre, ' ');
358 status = status && fprintf(out, "%s", s) >= 0;
359 status = status && write_fill(m-(l+pre), ' ');
360 return status;
361}
362
363static int write_quoted (int just, long m)
364{
365 luaI_addchar(0);
366 luaI_addquoted(lua_check_string(1, "write"));
367 return write_string(luaI_addchar(0), just, m);
368}
369
370static int write_float (int just, long m, int n)
371{
372 char buffer[100];
373 lua_Object p = lua_getparam(1);
374 float number;
375 if (!lua_isnumber(p)) return 0;
376 number = lua_getnumber(p);
377 if (n >= 0)
378 sprintf(buffer, "%.*f", n, number);
379 else
380 sprintf(buffer, "%g", number);
381 return write_string(buffer, just, m);
382}
383
384
385static int write_int (int just, long m, int n)
386{
387 char buffer[100];
388 lua_Object p = lua_getparam(1);
389 int number;
390 if (!lua_isnumber(p)) return 0;
391 number = (int)lua_getnumber(p);
392 if (n >= 0)
393 sprintf(buffer, "%.*d", n, number);
394 else
395 sprintf(buffer, "%d", number);
396 return write_string(buffer, just, m);
397} 146}
398 147
399 148
400static void io_write (void) 149static void io_write (void)
401{ 150{
402 int status = 0; 151 int arg = 1;
403 if (lua_getparam (2) == LUA_NOOBJECT) /* free format */ 152 int status = 1;
404 { 153 char *s;
405 lua_Object o1 = lua_getparam(1); 154 while ((s = lua_opt_string(arg++, NULL, "write")) != NULL)
406 int t = lua_type(o1); 155 status = status && (fputs(s, lua_outfile) != EOF);
407 if (t == LUA_T_NUMBER) 156 pushresult(status);
408 status = fprintf (out, "%g", lua_getnumber(o1)) >= 0;
409 else if (t == LUA_T_STRING)
410 status = fprintf (out, "%s", lua_getstring(o1)) >= 0;
411 }
412 else /* formated */
413 {
414 long m;
415 int just, n;
416 switch (getformat(lua_check_string(2, "write"), &just, &m, &n))
417 {
418 case 's':
419 {
420 lua_Object p = lua_getparam(1);
421 if (lua_isstring(p))
422 status = write_string(lua_getstring(p), just, m);
423 else
424 status = 0;
425 break;
426 }
427 case 'q':
428 status = write_quoted(just, m);
429 break;
430 case 'f':
431 status = write_float(just, m, n);
432 break;
433 case 'i':
434 status = write_int(just, m, n);
435 break;
436 }
437 }
438 if (status)
439 lua_pushnumber(status);
440} 157}
441 158
442/* 159
443** Execute a executable program using "system".
444** Return the result of execution.
445*/
446static void io_execute (void) 160static void io_execute (void)
447{ 161{
448 lua_pushnumber(system(lua_check_string(1, "execute"))); 162 lua_pushnumber(system(lua_check_string(1, "execute")));
449} 163}
450 164
451/* 165
452** Remove a file. On error return nil.
453*/
454static void io_remove (void) 166static void io_remove (void)
455{ 167{
456 pushresult(remove(lua_check_string(1, "remove")) == 0); 168 pushresult(remove(lua_check_string(1, "remove")) == 0);
457} 169}
458 170
171
459static void io_rename (void) 172static void io_rename (void)
460{ 173{
461 char *f1 = lua_check_string(1, "rename"); 174 pushresult(rename(lua_check_string(1, "rename"),
462 char *f2 = lua_check_string(2, "rename"); 175 lua_check_string(2, "rename")) == 0);
463 pushresult(rename(f1, f2) == 0);
464} 176}
465 177
178
466static void io_tmpname (void) 179static void io_tmpname (void)
467{ 180{
468 lua_pushstring(tmpnam(NULL)); 181 lua_pushstring(tmpnam(NULL));
469} 182}
470 183
471static void io_errorno (void)
472{
473/* lua_pushstring(strerror(errno));*/
474}
475 184
476 185
477/*
478** To get an environment variable
479*/
480static void io_getenv (void) 186static void io_getenv (void)
481{ 187{
482 char *env = getenv(lua_check_string(1, "getenv")); 188 lua_pushstring(getenv(lua_check_string(1, "getenv"))); /* if NULL push nil */
483 lua_pushstring(env); /* if NULL push nil */
484} 189}
485 190
486/* 191
487** Return user formatted time stamp
488*/
489static void io_date (void) 192static void io_date (void)
490{ 193{
491 time_t t; 194 time_t t;
492 struct tm *tm; 195 struct tm *tm;
493 char *s; 196 char *s = lua_opt_string(1, "%c", "date");
494 char b[BUFSIZ]; 197 char b[BUFSIZ];
495 if (lua_getparam(1) == LUA_NOOBJECT) 198 time(&t); tm = localtime(&t);
496 s = "%c"; 199 if (strftime(b,sizeof(b),s,tm))
497 else 200 lua_pushstring(b);
498 s = lua_check_string(1, "date"); 201 else
499 time(&t); tm = localtime(&t); 202 lua_error("invalid `date' format");
500 if (strftime(b,sizeof(b),s,tm))
501 lua_pushstring(b);
502 else
503 lua_error("invalid `date' format");
504} 203}
505 204
506/* 205
507** To exit
508*/
509static void io_exit (void) 206static void io_exit (void)
510{ 207{
511 lua_Object o = lua_getparam(1); 208 lua_Object o = lua_getparam(1);
512 int code = lua_isnumber(o) ? (int)lua_getnumber(o) : 1; 209 exit(lua_isnumber(o) ? (int)lua_getnumber(o) : 1);
513 exit(code);
514} 210}
515 211
516/* 212
517** To debug a lua program. Start a dialog with the user, interpreting
518 lua commands until an 'cont'.
519*/
520static void io_debug (void) 213static void io_debug (void)
521{ 214{
522 while (1) 215 while (1) {
523 {
524 char buffer[250]; 216 char buffer[250];
525 fprintf(stderr, "lua_debug> "); 217 fprintf(stderr, "lua_debug> ");
526 if (fgets(buffer, sizeof(buffer), stdin) == 0) return; 218 if (fgets(buffer, sizeof(buffer), stdin) == 0) return;
@@ -535,21 +227,18 @@ static void lua_printstack (FILE *f)
535 int level = 0; 227 int level = 0;
536 lua_Object func; 228 lua_Object func;
537 fprintf(f, "Active Stack:\n"); 229 fprintf(f, "Active Stack:\n");
538 while ((func = lua_stackedfunction(level++)) != LUA_NOOBJECT) 230 while ((func = lua_stackedfunction(level++)) != LUA_NOOBJECT) {
539 {
540 char *name; 231 char *name;
541 int currentline; 232 int currentline;
542 fprintf(f, "\t"); 233 fprintf(f, "\t");
543 switch (*lua_getobjname(func, &name)) 234 switch (*lua_getobjname(func, &name)) {
544 {
545 case 'g': 235 case 'g':
546 fprintf(f, "function %s", name); 236 fprintf(f, "function %s", name);
547 break; 237 break;
548 case 'f': 238 case 'f':
549 fprintf(f, "`%s' fallback", name); 239 fprintf(f, "`%s' fallback", name);
550 break; 240 break;
551 default: 241 default: {
552 {
553 char *filename; 242 char *filename;
554 int linedefined; 243 int linedefined;
555 lua_funcinfo(func, &filename, &linedefined); 244 lua_funcinfo(func, &filename, &linedefined);
@@ -570,8 +259,7 @@ static void lua_printstack (FILE *f)
570 259
571static void errorfb (void) 260static void errorfb (void)
572{ 261{
573 lua_Object o = lua_getparam(1); 262 char *s = lua_opt_string(1, "(no messsage)", NULL);
574 char *s = lua_isstring(o) ? lua_getstring(o) : "(no messsage)";
575 fprintf(stderr, "lua: %s\n", s); 263 fprintf(stderr, "lua: %s\n", s);
576 lua_printstack(stderr); 264 lua_printstack(stderr);
577} 265}
@@ -582,13 +270,11 @@ static struct lua_reg iolib[] = {
582{"writeto", io_writeto}, 270{"writeto", io_writeto},
583{"appendto", io_appendto}, 271{"appendto", io_appendto},
584{"read", io_read}, 272{"read", io_read},
585{"readuntil",io_readuntil},
586{"write", io_write}, 273{"write", io_write},
587{"execute", io_execute}, 274{"execute", io_execute},
588{"remove", io_remove}, 275{"remove", io_remove},
589{"rename", io_rename}, 276{"rename", io_rename},
590{"tmpname", io_tmpname}, 277{"tmpname", io_tmpname},
591{"ioerror", io_errorno},
592{"getenv", io_getenv}, 278{"getenv", io_getenv},
593{"date", io_date}, 279{"date", io_date},
594{"exit", io_exit}, 280{"exit", io_exit},
@@ -598,7 +284,7 @@ static struct lua_reg iolib[] = {
598 284
599void iolib_open (void) 285void iolib_open (void)
600{ 286{
601 in=stdin; out=stdout; 287 lua_infile=stdin; lua_outfile=stdout;
602 luaI_openlib(iolib, (sizeof(iolib)/sizeof(iolib[0]))); 288 luaI_openlib(iolib, (sizeof(iolib)/sizeof(iolib[0])));
603 lua_setfallback("error", errorfb); 289 lua_setfallback("error", errorfb);
604} 290}