diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1998-12-27 18:21:28 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1998-12-27 18:21:28 -0200 |
commit | 63166c0ca0ccd06ffdc8796120ea14614456a1e9 (patch) | |
tree | 535a5194a65e076d45bb2edb8624fa0c9a4f6f1e /liolib.c | |
parent | a881abfd1e2097ea23b586a93c6164f0f4c2cdcd (diff) | |
download | lua-63166c0ca0ccd06ffdc8796120ea14614456a1e9.tar.gz lua-63166c0ca0ccd06ffdc8796120ea14614456a1e9.tar.bz2 lua-63166c0ca0ccd06ffdc8796120ea14614456a1e9.zip |
new implementation of function "read", with predifined options.
Diffstat (limited to 'liolib.c')
-rw-r--r-- | liolib.c | 266 |
1 files changed, 147 insertions, 119 deletions
@@ -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 @@ | |||
44 | FILE *popen(); | 45 | FILE *popen(); |
45 | int pclose(); | 46 | int 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 | ||
52 | static int gettag (int i) | 54 | |
53 | { | 55 | static 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 | ||
58 | static void pushresult (int i) | 60 | static 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 | ||
70 | static int ishandler (lua_Object f) | 71 | static 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 | ||
80 | static FILE *getfilebyname (char *name) | 80 | static 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 | ||
115 | static void closefile (char *name) | 114 | static 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 | ||
126 | static void setfile (FILE *f, char *name, int tag) | 124 | static 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 | ||
133 | static void setreturn (FILE *f, char *name) | 130 | static 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 | ||
141 | static void io_readfrom (void) | 137 | static 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 | ||
163 | static void io_writeto (void) | 158 | static 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 | ||
185 | static void io_appendto (void) | 179 | static 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 | |||
194 | static 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 | ||
199 | static void read_until (FILE *f, int lim) { | 242 | |
200 | int l = 0; | 243 | static 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 | |||
256 | static 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 | |||
271 | static 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 | |||
212 | static void io_read (void) { | 282 | static 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 | ||
278 | static void io_write (void) | 315 | static 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 | ||
315 | static void io_execute (void) | 351 | static 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 | ||
321 | static void io_remove (void) | 356 | static 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 | ||
327 | static void io_rename (void) | 361 | static 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 | ||
334 | static void io_tmpname (void) | 367 | static void io_tmpname (void) { |
335 | { | ||
336 | lua_pushstring(tmpnam(NULL)); | 368 | lua_pushstring(tmpnam(NULL)); |
337 | } | 369 | } |
338 | 370 | ||
339 | 371 | ||
340 | 372 | ||
341 | static void io_getenv (void) | 373 | static 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 | ||
352 | static void io_date (void) | 383 | static 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 | ||
366 | static void setloc (void) | 396 | static 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 | ||
378 | static void io_exit (void) | 407 | static 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 | ||
385 | static void io_debug (void) | 413 | static 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 | ||
470 | static void openwithtags (void) | 498 | static 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 | |||