aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1995-11-10 15:55:48 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1995-11-10 15:55:48 -0200
commitf57afd6e32f3019ff11c8d0c284e78fa09790ca2 (patch)
tree71174326b37b2a0577cf1488a31eedc6a1030b26
parent5f664a45168803a12b27e9d96f74cad62869c562 (diff)
downloadlua-f57afd6e32f3019ff11c8d0c284e78fa09790ca2.tar.gz
lua-f57afd6e32f3019ff11c8d0c284e78fa09790ca2.tar.bz2
lua-f57afd6e32f3019ff11c8d0c284e78fa09790ca2.zip
re-implementation of functions "write" and "read"
-rw-r--r--iolib.c509
1 files changed, 256 insertions, 253 deletions
diff --git a/iolib.c b/iolib.c
index 31ebad9f..656c1b5b 100644
--- a/iolib.c
+++ b/iolib.c
@@ -3,7 +3,7 @@
3** Input/output library to LUA 3** Input/output library to LUA
4*/ 4*/
5 5
6char *rcs_iolib="$Id: iolib.c,v 1.26 1995/10/26 14:21:56 roberto Exp roberto $"; 6char *rcs_iolib="$Id: iolib.c,v 1.27 1995/11/03 15:43:50 roberto Exp roberto $";
7 7
8#include <stdio.h> 8#include <stdio.h>
9#include <ctype.h> 9#include <ctype.h>
@@ -20,26 +20,14 @@ char *rcs_iolib="$Id: iolib.c,v 1.26 1995/10/26 14:21:56 roberto Exp roberto $";
20static FILE *in=stdin, *out=stdout; 20static FILE *in=stdin, *out=stdout;
21 21
22 22
23#ifndef POPEN 23#ifdef POPEN
24FILE *popen();
25int pclose();
26#else
24#define popen(x,y) NULL /* that is, popen always fails */ 27#define popen(x,y) NULL /* that is, popen always fails */
25#define pclose(x) (-1) 28#define pclose(x) (-1)
26#endif 29#endif
27 30
28static void str_error(char *funcname)
29{
30 char buff[250];
31 sprintf(buff, "incorrect arguments to function `%s'", funcname);
32 lua_error(buff);
33}
34
35static char *check_and_get_string (int numArg, char *funcname)
36{
37 lua_Object o = lua_getparam(numArg);
38 if (!(lua_isstring(o) || lua_isnumber(o)))
39 str_error(funcname);
40 return lua_getstring(o);
41}
42
43 31
44static void closeread (void) 32static void closeread (void)
45{ 33{
@@ -67,7 +55,7 @@ static void closewrite (void)
67** status = readfrom (filename) 55** status = readfrom (filename)
68** where: 56** where:
69** status = 1 -> success 57** status = 1 -> success
70** status = 0 -> error 58** status = nil -> error
71*/ 59*/
72static void io_readfrom (void) 60static void io_readfrom (void)
73{ 61{
@@ -78,10 +66,10 @@ static void io_readfrom (void)
78 } 66 }
79 else 67 else
80 { 68 {
81 char *s = check_and_get_string(1, "readfrom"); 69 char *s = lua_check_string(1, "readfrom");
82 FILE *fp = (*s == '|') ? popen(s+1, "r") : fopen(s, "r"); 70 FILE *fp = (*s == '|') ? popen(s+1, "r") : fopen(s, "r");
83 if (fp == NULL) 71 if (fp == NULL)
84 lua_pushnumber (0); 72 lua_pushnil();
85 else 73 else
86 { 74 {
87 closeread(); 75 closeread();
@@ -98,7 +86,7 @@ static void io_readfrom (void)
98** status = writeto (filename) 86** status = writeto (filename)
99** where: 87** where:
100** status = 1 -> success 88** status = 1 -> success
101** status = 0 -> error 89** status = nil -> error
102*/ 90*/
103static void io_writeto (void) 91static void io_writeto (void)
104{ 92{
@@ -109,10 +97,10 @@ static void io_writeto (void)
109 } 97 }
110 else 98 else
111 { 99 {
112 char *s = check_and_get_string(1, "writeto"); 100 char *s = lua_check_string(1, "writeto");
113 FILE *fp = (*s == '|') ? popen(s+1,"w") : fopen(s,"w"); 101 FILE *fp = (*s == '|') ? popen(s+1,"w") : fopen(s,"w");
114 if (fp == NULL) 102 if (fp == NULL)
115 lua_pushnumber (0); 103 lua_pushnil();
116 else 104 else
117 { 105 {
118 closewrite(); 106 closewrite();
@@ -130,16 +118,16 @@ static void io_writeto (void)
130** where: 118** where:
131** status = 2 -> success (already exist) 119** status = 2 -> success (already exist)
132** status = 1 -> success (new file) 120** status = 1 -> success (new file)
133** status = 0 -> error 121** status = nil -> error
134*/ 122*/
135static void io_appendto (void) 123static void io_appendto (void)
136{ 124{
137 char *s = check_and_get_string(1, "appendto"); 125 char *s = lua_check_string(1, "appendto");
138 struct stat st; 126 struct stat st;
139 int r = (stat(s, &st) == -1) ? 1 : 2; 127 int r = (stat(s, &st) == -1) ? 1 : 2;
140 FILE *fp = fopen (s, "a"); 128 FILE *fp = fopen (s, "a");
141 if (fp == NULL) 129 if (fp == NULL)
142 lua_pushnumber (0); 130 lua_pushnil();
143 else 131 else
144 { 132 {
145 if (out != stdout) fclose (out); 133 if (out != stdout) fclose (out);
@@ -149,6 +137,72 @@ static void io_appendto (void)
149} 137}
150 138
151 139
140static char getformat (char *f, int *just, int *m, int *n)
141{
142 int t;
143 switch (*f++)
144 {
145 case 's': case 'S':
146 t = 's';
147 break;
148 case 'f': case 'F': case 'g': case 'G': case 'e': case 'E':
149 t = 'f';
150 break;
151 case 'i': case 'I':
152 t = 'i';
153 break;
154 default:
155 t = 0; /* to avoid compiler warnings */
156 lua_arg_error("read/write (format)");
157 }
158 *just = (*f == '<' || *f == '>' || *f == '|') ? *f++ : '>';
159 if (isdigit(*f))
160 {
161 *m = 0;
162 while (isdigit(*f))
163 *m = *m*10 + (*f++ - '0');
164 }
165 else
166 *m = -1;
167 if (*f == '.')
168 {
169 f++; /* skip point */
170 *n = 0;
171 while (isdigit(*f))
172 *n = *n*10 + (*f++ - '0');
173 }
174 else
175 *n = -1;
176 return t;
177}
178
179
180static char *add_char (int c)
181{
182 static char *buff = NULL;
183 static int max = 0;
184 static int n = 0;
185 if (n >= max)
186 {
187 if (max == 0)
188 {
189 max = 100;
190 buff = (char *)malloc(max);
191 }
192 else
193 {
194 max *= 2;
195 buff = (char *)realloc(buff, max);
196 }
197 if (buff == NULL)
198 lua_error("memory overflow");
199 }
200 buff[n++] = c;
201 if (c == 0)
202 n = 0; /* prepare for next string */
203 return buff;
204}
205
152/* 206/*
153** Read a variable. On error put nil on stack. 207** Read a variable. On error put nil on stack.
154** LUA interface: 208** LUA interface:
@@ -163,125 +217,100 @@ static void io_appendto (void)
163** Estes especificadores podem vir seguidos de numero que representa 217** Estes especificadores podem vir seguidos de numero que representa
164** o numero de campos a serem lidos. 218** o numero de campos a serem lidos.
165*/ 219*/
166static void io_read (void) 220
221static int read_until_char (int del)
222{
223 int c;
224 while((c = fgetc(in)) != EOF && c != del)
225 add_char(c);
226 return c;
227}
228
229static int read_until_blank (void)
230{
231 int c;
232 while((c = fgetc(in)) != EOF && !isspace(c))
233 add_char(c);
234 return c;
235}
236
237static void read_m (int m)
238{
239 int c;
240 while (m-- && (c = fgetc(in)) != EOF)
241 add_char(c);
242}
243
244
245static void read_free (void)
167{ 246{
168 lua_Object o = lua_getparam (1);
169 if (o == LUA_NOOBJECT) /* free format */
170 {
171 int c; 247 int c;
172 char s[256];
173 while (isspace(c=fgetc(in))) 248 while (isspace(c=fgetc(in)))
174 ; 249 ;
175 if (c == '\"' || c == '\'') 250 if (c == '\"' || c == '\'')
176 { 251 { /* string */
177 int del = c; 252 c = read_until_char(c);
178 int n=0;
179 while((c = fgetc(in)) != del)
180 {
181 if (c == EOF) 253 if (c == EOF)
182 { 254 {
183 lua_pushnil (); 255 add_char(0); /* to be ready for next time */
184 return; 256 lua_pushnil();
185 } 257 }
186 s[n++] = c; 258 else
187 } 259 lua_pushstring(add_char(0));
188 s[n] = 0;
189 } 260 }
190 else 261 else
191 { 262 {
192 double d; 263 double d;
193 ungetc (c, in); 264 char dummy;
194 if (fscanf (in, "%s", s) != 1) 265 char *s;
195 { 266 add_char(c);
196 lua_pushnil (); 267 read_until_blank();
197 return; 268 s = add_char(0);
198 } 269 if (sscanf(s, "%lf %c", &d, &dummy) == 1)
199 if (sscanf(s, "%lf %*c", &d) == 1) 270 lua_pushnumber(d);
200 { 271 else
201 lua_pushnumber (d); 272 lua_pushstring(s);
202 return;
203 }
204 } 273 }
205 lua_pushstring (s); 274}
206 return; 275
207 } 276static void io_read (void)
208 else /* formatted */ 277{
209 { 278 lua_Object o = lua_getparam (1);
210 char *e = check_and_get_string(1, "read"); 279 if (o == LUA_NOOBJECT) /* free format */
211 char t; 280 read_free();
212 int m=0; 281 else /* formatted */
213 while (isspace(*e)) e++;
214 t = *e++;
215 while (isdigit(*e))
216 m = m*10 + (*e++ - '0');
217
218 if (m > 0)
219 {
220 char f[80];
221 char s[256];
222 sprintf (f, "%%%ds", m);
223 if (fgets (s, m+1, in) == NULL)
224 {
225 lua_pushnil();
226 return;
227 }
228 else
229 {
230 if (s[strlen(s)-1] == '\n')
231 s[strlen(s)-1] = 0;
232 }
233 switch (tolower(t))
234 {
235 case 'i':
236 {
237 long int l;
238 sscanf (s, "%ld", &l);
239 lua_pushnumber(l);
240 }
241 break;
242 case 'f': case 'g': case 'e':
243 {
244 float fl;
245 sscanf (s, "%f", &fl);
246 lua_pushnumber(fl);
247 }
248 break;
249 default:
250 lua_pushstring(s);
251 break;
252 }
253 }
254 else
255 { 282 {
256 switch (tolower(t)) 283 int m, dummy1, dummy2;
257 { 284 switch (getformat(lua_check_string(1, "read"), &dummy1, &m, &dummy2))
258 case 'i':
259 {
260 long int l;
261 if (fscanf (in, "%ld", &l) == EOF)
262 lua_pushnil();
263 else lua_pushnumber(l);
264 }
265 break;
266 case 'f': case 'g': case 'e':
267 { 285 {
268 float f; 286 case 's':
269 if (fscanf (in, "%f", &f) == EOF) 287 if (m < 0)
270 lua_pushnil(); 288 read_until_blank();
271 else lua_pushnumber(f); 289 else
272 } 290 read_m(m);
273 break; 291 lua_pushstring(add_char(0));
274 default: 292 break;
275 { 293
276 char s[256]; 294 case 'i': /* can read as float, since it makes no difference to Lua */
277 if (fscanf (in, "%s", s) == EOF) 295 case 'f':
278 lua_pushnil(); 296 {
279 else lua_pushstring(s); 297 double d;
298 int result;
299 if (m < 0)
300 result = fscanf(in, "%lf", &d);
301 else
302 {
303 read_m(m);
304 result = sscanf(add_char(0), "%lf", &d);
305 }
306 if (result == 1)
307 lua_pushnumber(d);
308 else
309 lua_pushnil();
310 break;
311 }
280 } 312 }
281 break;
282 }
283 } 313 }
284 }
285} 314}
286 315
287 316
@@ -290,33 +319,13 @@ static void io_read (void)
290*/ 319*/
291static void io_readuntil (void) 320static void io_readuntil (void)
292{ 321{
293 int n=255,m=0; 322 int del = *lua_check_string(1, "readuntil");
294 int c,d; 323 int c = read_until_char(del);
295 char *s;
296 lua_Object lo = lua_getparam(1);
297 if (!lua_isstring(lo))
298 d = EOF;
299 else
300 d = *lua_getstring(lo);
301
302 s = (char *)malloc(n+1);
303 while((c = fgetc(in)) != EOF && c != d)
304 {
305 if (m==n)
306 {
307 n *= 2;
308 s = (char *)realloc(s, n+1);
309 }
310 s[m++] = c;
311 }
312 if (c != EOF) ungetc(c,in); 324 if (c != EOF) ungetc(c,in);
313 s[m] = 0; 325 lua_pushstring(add_char(0));
314 lua_pushstring(s);
315 free(s);
316} 326}
317 327
318 328
319
320/* 329/*
321** Write a variable. On error put 0 on stack, otherwise put 1. 330** Write a variable. On error put 0 on stack, otherwise put 1.
322** LUA interface: 331** LUA interface:
@@ -343,106 +352,100 @@ static void io_readuntil (void)
343** inteiros -> numero minimo de digitos 352** inteiros -> numero minimo de digitos
344** string -> nao se aplica 353** string -> nao se aplica
345*/ 354*/
346static char *buildformat (char *e, lua_Object o) 355
356static int write_fill (int n, int c)
347{ 357{
348 static char buffer[2048]; 358 while (n--)
349 static char f[80]; 359 if (fputc(c, out) == EOF)
350 char *string = &buffer[255]; 360 return 0;
351 char *fstart=e, *fspace, *send; 361 return 1;
352 char t, j='r';
353 int m=0, n=-1, l;
354 while (isspace(*e)) e++;
355 fspace = e;
356 t = *e++;
357 if (*e == '<' || *e == '|' || *e == '>') j = *e++;
358 while (isdigit(*e))
359 m = m*10 + (*e++ - '0');
360 if (*e == '.') e++; /* skip point */
361 while (isdigit(*e))
362 if (n < 0) n = (*e++ - '0');
363 else n = n*10 + (*e++ - '0');
364
365 sprintf(f,"%%");
366 if (j == '<' || j == '|') sprintf(strchr(f,0),"-");
367 if (m > 0) sprintf(strchr(f,0),"%d", m);
368 if (n >= 0) sprintf(strchr(f,0),".%d", n);
369 switch (t)
370 {
371 case 'i': case 'I': t = 'd';
372 sprintf(strchr(f,0), "%c", t);
373 sprintf (string, f, (long int)lua_getnumber(o));
374 break;
375 case 'f': case 'g': case 'e': case 'G': case 'E':
376 sprintf(strchr(f,0), "%c", t);
377 sprintf (string, f, (float)lua_getnumber(o));
378 break;
379 case 'F': t = 'f';
380 sprintf(strchr(f,0), "%c", t);
381 sprintf (string, f, (float)lua_getnumber(o));
382 break;
383 case 's': case 'S': t = 's';
384 sprintf(strchr(f,0), "%c", t);
385 sprintf (string, f, lua_getstring(o));
386 break;
387 default: return "";
388 }
389 l = strlen(string);
390 send = string+l;
391 if (m!=0 && l>m)
392 {
393 int i;
394 for (i=0; i<m; i++)
395 string[i] = '*';
396 string[i] = 0;
397 }
398 else if (m!=0 && j=='|')
399 {
400 int k;
401 int i=l-1;
402 while (isspace(string[i]) || string[i]==0) i--;
403 string -= (m-i)/2;
404 for(k=0; k<(m-i)/2; k++)
405 string[k] = ' ';
406 }
407 /* add space characteres */
408 while (fspace != fstart)
409 {
410 string--;
411 fspace--;
412 *string = *fspace;
413 }
414 while (isspace(*e)) *send++ = *e++;
415 *send = 0;
416 return string;
417} 362}
363
364static int write_string (char *s, int just, int m)
365{
366 int status;
367 int l = strlen(s);
368 int pre; /* number of blanks before string */
369 if (m < 0) m = l;
370 else if (l > m)
371 {
372 write_fill(m, '*');
373 return 0;
374 }
375 pre = (just == '<') ? 0 : (just == '>') ? m-l : (m-l)/2;
376 status = write_fill(pre, ' ');
377 status = status && fprintf(out, "%s", s) >= 0;
378 status = status && write_fill(m-(l+pre), ' ');
379 return status;
380}
381
382static int write_float (int just, int m, int n)
383{
384 char buffer[100];
385 lua_Object p = lua_getparam(1);
386 float number;
387 if (!lua_isnumber(p)) return 0;
388 number = lua_getnumber(p);
389 if (n >= 0)
390 sprintf(buffer, "%.*f", n, number);
391 else
392 sprintf(buffer, "%g", number);
393 return write_string(buffer, just, m);
394}
395
396
397static int write_int (int just, int m, int n)
398{
399 char buffer[100];
400 lua_Object p = lua_getparam(1);
401 int number;
402 if (!lua_isnumber(p)) return 0;
403 number = (int)lua_getnumber(p);
404 if (n >= 0)
405 sprintf(buffer, "%.*d", n, number);
406 else
407 sprintf(buffer, "%d", number);
408 return write_string(buffer, just, m);
409}
410
411
418static void io_write (void) 412static void io_write (void)
419{ 413{
420 lua_Object o1 = lua_getparam (1); 414 int status = 0;
421 lua_Object o2 = lua_getparam (2); 415 if (lua_getparam (2) == LUA_NOOBJECT) /* free format */
422 if (o1 == LUA_NOOBJECT) /* new line */ 416 {
423 { 417 lua_Object o1 = lua_getparam(1);
424 fprintf (out, "\n"); 418 if (lua_isnumber(o1))
425 lua_pushnumber(1); 419 status = fprintf (out, "%g", lua_getnumber(o1)) >= 0;
426 } 420 else if (lua_isstring(o1))
427 else if (o2 == LUA_NOOBJECT) /* free format */ 421 status = fprintf (out, "%s", lua_getstring(o1)) >= 0;
428 {
429 int status=0;
430 if (lua_isnumber(o1))
431 status = fprintf (out, "%g", lua_getnumber(o1));
432 else if (lua_isstring(o1))
433 status = fprintf (out, "%s", lua_getstring(o1));
434 lua_pushnumber(status);
435 }
436 else /* formated */
437 {
438 if (!lua_isstring(o2))
439 {
440 lua_error ("incorrect format to function `write'");
441 lua_pushnumber(0);
442 return;
443 } 422 }
444 lua_pushnumber(fprintf (out, "%s", buildformat(lua_getstring(o2),o1))); 423 else /* formated */
445 } 424 {
425 int just, m, n;
426 switch (getformat (lua_check_string(2, "write"), &just, &m, &n))
427 {
428 case 's':
429 {
430 lua_Object p = lua_getparam(1);
431 if (lua_isstring(p))
432 status = write_string(lua_getstring(p), just, m);
433 else
434 status = 0;
435 break;
436 }
437 case 'f':
438 status = write_float(just, m, n);
439 break;
440 case 'i':
441 status = write_int(just, m, n);
442 break;
443 }
444 }
445 if (status)
446 lua_pushnumber(status);
447 else
448 lua_pushnil();
446} 449}
447 450
448/* 451/*
@@ -451,19 +454,18 @@ static void io_write (void)
451*/ 454*/
452static void io_execute (void) 455static void io_execute (void)
453{ 456{
454 lua_pushnumber(system(check_and_get_string(1, "execute"))); 457 lua_pushnumber(system(lua_check_string(1, "execute")));
455} 458}
456 459
457/* 460/*
458** Remove a file. 461** Remove a file. On error return nil.
459** On error put 0 on stack, otherwise put 1.
460*/ 462*/
461static void io_remove (void) 463static void io_remove (void)
462{ 464{
463 if (remove(check_and_get_string(1, "remove")) == 0) 465 if (remove(lua_check_string(1, "remove")) == 0)
464 lua_pushnumber (1); 466 lua_pushnumber (1);
465 else 467 else
466 lua_pushnumber (0); 468 lua_pushnil();
467} 469}
468 470
469 471
@@ -472,7 +474,7 @@ static void io_remove (void)
472*/ 474*/
473static void io_getenv (void) 475static void io_getenv (void)
474{ 476{
475 char *env = getenv(check_and_get_string(1, "getenv")); 477 char *env = getenv(lua_check_string(1, "getenv"));
476 if (env == NULL) lua_pushnil(); 478 if (env == NULL) lua_pushnil();
477 else lua_pushstring(env); 479 else lua_pushstring(env);
478} 480}
@@ -612,3 +614,4 @@ void iolib_open (void)
612 lua_register ("print_stack", errorfb); 614 lua_register ("print_stack", errorfb);
613 lua_setfallback("error", errorfb); 615 lua_setfallback("error", errorfb);
614} 616}
617