summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1998-12-27 18:21:28 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1998-12-27 18:21:28 -0200
commit63166c0ca0ccd06ffdc8796120ea14614456a1e9 (patch)
tree535a5194a65e076d45bb2edb8624fa0c9a4f6f1e
parenta881abfd1e2097ea23b586a93c6164f0f4c2cdcd (diff)
downloadlua-63166c0ca0ccd06ffdc8796120ea14614456a1e9.tar.gz
lua-63166c0ca0ccd06ffdc8796120ea14614456a1e9.tar.bz2
lua-63166c0ca0ccd06ffdc8796120ea14614456a1e9.zip
new implementation of function "read", with predifined options.
-rw-r--r--liolib.c266
1 files changed, 147 insertions, 119 deletions
diff --git a/liolib.c b/liolib.c
index 83a57d48..764dd883 100644
--- a/liolib.c
+++ b/liolib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: liolib.c,v 1.25 1998/09/07 18:59:59 roberto Exp roberto $ 2** $Id: liolib.c,v 1.26 1998/11/20 15:41:43 roberto Exp roberto $
3** Standard I/O (and system) library 3** Standard I/O (and system) library
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -20,6 +20,7 @@
20#ifndef OLD_ANSI 20#ifndef OLD_ANSI
21#include <locale.h> 21#include <locale.h>
22#else 22#else
23/* no support for locale and for strerror: fake them */
23#define setlocale(a,b) 0 24#define setlocale(a,b) 0
24#define LC_ALL 0 25#define LC_ALL 0
25#define LC_COLLATE 0 26#define LC_COLLATE 0
@@ -44,19 +45,19 @@
44FILE *popen(); 45FILE *popen();
45int pclose(); 46int pclose();
46#else 47#else
48/* no support for popen */
47#define popen(x,y) NULL /* that is, popen always fails */ 49#define popen(x,y) NULL /* that is, popen always fails */
48#define pclose(x) (-1) 50#define pclose(x) (-1)
49#endif 51#endif
50 52
51 53
52static int gettag (int i) 54
53{ 55static int gettag (int i) {
54 return lua_getnumber(lua_getparam(i)); 56 return (int)lua_getnumber(lua_getparam(i));
55} 57}
56 58
57 59
58static void pushresult (int i) 60static void pushresult (int i) {
59{
60 if (i) 61 if (i)
61 lua_pushuserdata(NULL); 62 lua_pushuserdata(NULL);
62 else { 63 else {
@@ -67,8 +68,7 @@ static void pushresult (int i)
67} 68}
68 69
69 70
70static int ishandler (lua_Object f) 71static int ishandler (lua_Object f) {
71{
72 if (lua_isuserdata(f)) { 72 if (lua_isuserdata(f)) {
73 if (lua_tag(f) == gettag(CLOSEDTAG)) 73 if (lua_tag(f) == gettag(CLOSEDTAG))
74 lua_error("cannot access a closed file"); 74 lua_error("cannot access a closed file");
@@ -77,8 +77,7 @@ static int ishandler (lua_Object f)
77 else return 0; 77 else return 0;
78} 78}
79 79
80static FILE *getfilebyname (char *name) 80static FILE *getfilebyname (char *name) {
81{
82 lua_Object f = lua_getglobal(name); 81 lua_Object f = lua_getglobal(name);
83 if (!ishandler(f)) 82 if (!ishandler(f))
84 luaL_verror("global variable `%.50s' is not a file handle", name); 83 luaL_verror("global variable `%.50s' is not a file handle", name);
@@ -112,8 +111,7 @@ static char *getmode (char mode) {
112} 111}
113 112
114 113
115static void closefile (char *name) 114static void closefile (char *name) {
116{
117 FILE *f = getfilebyname(name); 115 FILE *f = getfilebyname(name);
118 if (f == stdin || f == stdout) return; 116 if (f == stdin || f == stdout) return;
119 if (pclose(f) == -1) 117 if (pclose(f) == -1)
@@ -123,23 +121,20 @@ static void closefile (char *name)
123} 121}
124 122
125 123
126static void setfile (FILE *f, char *name, int tag) 124static void setfile (FILE *f, char *name, int tag) {
127{
128 lua_pushusertag(f, tag); 125 lua_pushusertag(f, tag);
129 lua_setglobal(name); 126 lua_setglobal(name);
130} 127}
131 128
132 129
133static void setreturn (FILE *f, char *name) 130static void setreturn (FILE *f, char *name) {
134{
135 int tag = gettag(IOTAG); 131 int tag = gettag(IOTAG);
136 setfile(f, name, tag); 132 setfile(f, name, tag);
137 lua_pushusertag(f, tag); 133 lua_pushusertag(f, tag);
138} 134}
139 135
140 136
141static void io_readfrom (void) 137static void io_readfrom (void) {
142{
143 FILE *current; 138 FILE *current;
144 lua_Object f = lua_getparam(FIRSTARG); 139 lua_Object f = lua_getparam(FIRSTARG);
145 if (f == LUA_NOOBJECT) { 140 if (f == LUA_NOOBJECT) {
@@ -160,8 +155,7 @@ static void io_readfrom (void)
160} 155}
161 156
162 157
163static void io_writeto (void) 158static void io_writeto (void) {
164{
165 FILE *current; 159 FILE *current;
166 lua_Object f = lua_getparam(FIRSTARG); 160 lua_Object f = lua_getparam(FIRSTARG);
167 if (f == LUA_NOOBJECT) { 161 if (f == LUA_NOOBJECT) {
@@ -182,8 +176,7 @@ static void io_writeto (void)
182} 176}
183 177
184 178
185static void io_appendto (void) 179static void io_appendto (void) {
186{
187 char *s = luaL_check_string(FIRSTARG); 180 char *s = luaL_check_string(FIRSTARG);
188 FILE *fp = fopen (s, getmode('a')); 181 FILE *fp = fopen (s, getmode('a'));
189 if (fp != NULL) 182 if (fp != NULL)
@@ -193,90 +186,133 @@ static void io_appendto (void)
193} 186}
194 187
195 188
196#define NEED_OTHER (EOF-1) /* just some flag different from EOF */
197 189
190/*====================================================
191** READ
192**===================================================*/
193
194static int read_pattern (FILE *f, char *p) {
195 int inskip = 0; /* {skip} level */
196 int c = getc(f);
197 while (*p != '\0') {
198 switch (*p) {
199 case '{':
200 inskip++;
201 p++;
202 continue;
203 case '}':
204 if (!inskip) lua_error("unbalanced braces in read pattern");
205 inskip--;
206 p++;
207 continue;
208 default: {
209 char *ep; /* get what is next */
210 int m; /* match result */
211 if (c != EOF)
212 m = luaI_singlematch(c, p, &ep);
213 else {
214 luaI_singlematch(0, p, &ep); /* to set "ep" */
215 m = 0; /* EOF matches no pattern */
216 }
217 if (m) {
218 if (!inskip) luaL_addchar(c);
219 c = getc(f);
220 }
221 switch (*ep) {
222 case '*': /* repetition */
223 if (!m) p = ep+1; /* else stay in (repeat) the same item */
224 continue;
225 case '?': /* optional */
226 p = ep+1; /* continues reading the pattern */
227 continue;
228 default:
229 if (!m) { /* pattern fails? */
230 ungetc(c, f);
231 return 0;
232 }
233 p = ep; /* continues reading the pattern */
234 }
235 }
236 }
237 }
238 ungetc(c, f);
239 return 1;
240}
198 241
199static void read_until (FILE *f, int lim) { 242
200 int l = 0; 243static int read_number (FILE *f) {
201 int c; 244 double d;
202 for (c = getc(f); c != EOF && c != lim; c = getc(f)) { 245 if (fscanf(f, "%lf", &d) == 1) {
203 luaL_addchar(c); 246 lua_pushnumber(d);
204 l++; 247 return 1;
205 } 248 }
206 if (l > 0 || c == lim) /* read anything? */ 249 else return 0; /* read fails */
207 lua_pushlstring(luaL_buffer(), l);
208 else
209 lua_pushnil();
210} 250}
211 251
252
253#define HUNK_LINE 1024
254#define HUNK_FILE BUFSIZ
255
256static int read_line (FILE *f) {
257 /* equivalent to: return read_pattern(f, "[^\n]*{\n}"); */
258 int n;
259 char *b;
260 do {
261 b = luaL_openspace(HUNK_LINE);
262 if (!fgets(b, HUNK_LINE, f)) return 0; /* read fails */
263 n = strlen(b);
264 luaL_addsize(n);
265 } while (b[n-1] != '\n');
266 luaL_addsize(-1); /* remove '\n' */
267 return 1;
268}
269
270
271static void read_file (FILE *f) {
272 /* equivalent to: return read_pattern(f, ".*"); */
273 int n;
274 do {
275 char *b = luaL_openspace(HUNK_FILE);
276 n = fread(b, sizeof(char), HUNK_FILE, f);
277 luaL_addsize(n);
278 } while (n==HUNK_FILE);
279}
280
281
212static void io_read (void) { 282static void io_read (void) {
283 static char *options[] = {"*n", "*l", "*a", ".*", "*w", NULL};
213 int arg = FIRSTARG; 284 int arg = FIRSTARG;
214 FILE *f = getfileparam(FINPUT, &arg); 285 FILE *f = getfileparam(FINPUT, &arg);
215 char *p = luaL_opt_string(arg, NULL); 286 char *p = luaL_opt_string(arg++, "*l");
216 luaL_resetbuffer(); 287 do { /* repeat for each part */
217 if (p == NULL) /* default: read a line */ 288 long l;
218 read_until(f, '\n'); 289 int success;
219 else if (strcmp(p, ".*") == 0) 290 luaL_resetbuffer();
220 read_until(f, EOF); 291 switch (luaL_findstring(p, options)) {
221 else { 292 case 0: /* number */
222 int l = 0; /* number of chars read in buffer */ 293 if (!read_number(f)) return; /* read fails */
223 int inskip = 0; /* to control {skips} */ 294 continue; /* number is already pushed; avoid the "pushstring" */
224 int c = NEED_OTHER; 295 case 1: /* line */
225 while (*p) { 296 success = read_line(f);
226 switch (*p) { 297 break;
227 case '{': 298 case 2: case 3: /* file */
228 inskip++; 299 read_file(f);
229 p++; 300 success = 1; /* always success */
230 continue; 301 break;
231 case '}': 302 case 4: /* word */
232 if (inskip == 0) 303 success = read_pattern(f, "{%s*}%S%S*");
233 lua_error("unbalanced braces in read pattern"); 304 break;
234 inskip--; 305 default:
235 p++; 306 success = read_pattern(f, p);
236 continue; 307 }
237 default: { 308 l = luaL_getsize();
238 char *ep; /* get what is next */ 309 if (!success && l==0) return; /* read fails */
239 int m; /* match result */ 310 lua_pushlstring(luaL_buffer(), l);
240 if (c == NEED_OTHER) c = getc(f); 311 } while ((p = luaL_opt_string(arg++, NULL)));
241 if (c == EOF) {
242 luaI_singlematch(0, p, &ep); /* to set "ep" */
243 m = 0;
244 }
245 else {
246 m = luaI_singlematch(c, p, &ep);
247 if (m) {
248 if (inskip == 0) {
249 luaL_addchar(c);
250 l++;
251 }
252 c = NEED_OTHER;
253 }
254 }
255 switch (*ep) {
256 case '*': /* repetition */
257 if (!m) p = ep+1; /* else stay in (repeat) the same item */
258 continue;
259 case '?': /* optional */
260 p = ep+1; /* continues reading the pattern */
261 continue;
262 default:
263 if (m) p = ep; /* continues reading the pattern */
264 else
265 goto break_while; /* pattern fails */
266 }
267 }
268 }
269 } break_while:
270 if (c >= 0) /* not EOF nor NEED_OTHER? */
271 ungetc(c, f);
272 if (l > 0 || *p == 0) /* read something or did not fail? */
273 lua_pushlstring(luaL_buffer(), l);
274 }
275} 312}
276 313
277 314
278static void io_write (void) 315static void io_write (void) {
279{
280 int arg = FIRSTARG; 316 int arg = FIRSTARG;
281 FILE *f = getfileparam(FOUTPUT, &arg); 317 FILE *f = getfileparam(FOUTPUT, &arg);
282 int status = 1; 318 int status = 1;
@@ -312,34 +348,29 @@ static void io_flush (void) {
312} 348}
313 349
314 350
315static void io_execute (void) 351static void io_execute (void) {
316{
317 lua_pushnumber(system(luaL_check_string(1))); 352 lua_pushnumber(system(luaL_check_string(1)));
318} 353}
319 354
320 355
321static void io_remove (void) 356static void io_remove (void) {
322{
323 pushresult(remove(luaL_check_string(1)) == 0); 357 pushresult(remove(luaL_check_string(1)) == 0);
324} 358}
325 359
326 360
327static void io_rename (void) 361static void io_rename (void) {
328{
329 pushresult(rename(luaL_check_string(1), 362 pushresult(rename(luaL_check_string(1),
330 luaL_check_string(2)) == 0); 363 luaL_check_string(2)) == 0);
331} 364}
332 365
333 366
334static void io_tmpname (void) 367static void io_tmpname (void) {
335{
336 lua_pushstring(tmpnam(NULL)); 368 lua_pushstring(tmpnam(NULL));
337} 369}
338 370
339 371
340 372
341static void io_getenv (void) 373static void io_getenv (void) {
342{
343 lua_pushstring(getenv(luaL_check_string(1))); /* if NULL push nil */ 374 lua_pushstring(getenv(luaL_check_string(1))); /* if NULL push nil */
344} 375}
345 376
@@ -349,12 +380,11 @@ static void io_clock (void) {
349} 380}
350 381
351 382
352static void io_date (void) 383static void io_date (void) {
353{ 384 char b[256];
354 time_t t;
355 struct tm *tm;
356 char *s = luaL_opt_string(1, "%c"); 385 char *s = luaL_opt_string(1, "%c");
357 char b[BUFSIZ]; 386 struct tm *tm;
387 time_t t;
358 time(&t); tm = localtime(&t); 388 time(&t); tm = localtime(&t);
359 if (strftime(b,sizeof(b),s,tm)) 389 if (strftime(b,sizeof(b),s,tm))
360 lua_pushstring(b); 390 lua_pushstring(b);
@@ -363,8 +393,7 @@ static void io_date (void)
363} 393}
364 394
365 395
366static void setloc (void) 396static void setloc (void) {
367{
368 static int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC, 397 static int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC,
369 LC_TIME}; 398 LC_TIME};
370 static char *catnames[] = {"all", "collate", "ctype", "monetary", 399 static char *catnames[] = {"all", "collate", "ctype", "monetary",
@@ -375,16 +404,14 @@ static void setloc (void)
375} 404}
376 405
377 406
378static void io_exit (void) 407static void io_exit (void) {
379{
380 lua_Object o = lua_getparam(1); 408 lua_Object o = lua_getparam(1);
381 exit(lua_isnumber(o) ? (int)lua_getnumber(o) : 1); 409 exit(lua_isnumber(o) ? (int)lua_getnumber(o) : 1);
382} 410}
383 411
384 412
385static void io_debug (void) 413static void io_debug (void) {
386{ 414 for (;;) {
387 while (1) {
388 char buffer[250]; 415 char buffer[250];
389 fprintf(stderr, "lua_debug> "); 416 fprintf(stderr, "lua_debug> ");
390 if (fgets(buffer, sizeof(buffer), stdin) == 0) return; 417 if (fgets(buffer, sizeof(buffer), stdin) == 0) return;
@@ -394,6 +421,7 @@ static void io_debug (void)
394} 421}
395 422
396 423
424
397#define MESSAGESIZE 150 425#define MESSAGESIZE 150
398#define MAXMESSAGE (MESSAGESIZE*10) 426#define MAXMESSAGE (MESSAGESIZE*10)
399 427
@@ -467,8 +495,7 @@ static struct luaL_reg iolibtag[] = {
467 {"write", io_write} 495 {"write", io_write}
468}; 496};
469 497
470static void openwithtags (void) 498static void openwithtags (void) {
471{
472 int iotag = lua_newtag(); 499 int iotag = lua_newtag();
473 int closedtag = lua_newtag(); 500 int closedtag = lua_newtag();
474 int i; 501 int i;
@@ -490,3 +517,4 @@ void lua_iolibopen (void) {
490 luaL_openlib(iolib, (sizeof(iolib)/sizeof(iolib[0]))); 517 luaL_openlib(iolib, (sizeof(iolib)/sizeof(iolib[0])));
491 openwithtags(); 518 openwithtags();
492} 519}
520