diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-09-11 14:38:42 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-09-11 14:38:42 -0300 |
commit | 787a78f83e0484c9e9698189982e2f309808fae8 (patch) | |
tree | 0682eddf4ea5a49bf5078bac937a36f90057df57 /liolib.c | |
parent | 70c8a310925d6c41c3ef4f7feeae604a4c9a3a95 (diff) | |
download | lua-787a78f83e0484c9e9698189982e2f309808fae8.tar.gz lua-787a78f83e0484c9e9698189982e2f309808fae8.tar.bz2 lua-787a78f83e0484c9e9698189982e2f309808fae8.zip |
new scheme for buffers
Diffstat (limited to 'liolib.c')
-rw-r--r-- | liolib.c | 87 |
1 files changed, 53 insertions, 34 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: liolib.c,v 1.76 2000/08/31 20:23:40 roberto Exp roberto $ | 2 | ** $Id: liolib.c,v 1.77 2000/09/05 19:33:32 roberto Exp $ |
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 | */ |
@@ -263,7 +263,7 @@ static int read_pattern (lua_State *L, FILE *f, const char *p) { | |||
263 | if (c == NEED_OTHER) c = getc(f); | 263 | if (c == NEED_OTHER) c = getc(f); |
264 | m = (c==EOF) ? 0 : luaI_singlematch(c, p, ep); | 264 | m = (c==EOF) ? 0 : luaI_singlematch(c, p, ep); |
265 | if (m) { | 265 | if (m) { |
266 | if (!inskip) luaL_addchar(L, c); | 266 | if (!inskip) luaL_putchar(L, c); |
267 | c = NEED_OTHER; | 267 | c = NEED_OTHER; |
268 | } | 268 | } |
269 | switch (*ep) { | 269 | switch (*ep) { |
@@ -274,7 +274,7 @@ static int read_pattern (lua_State *L, FILE *f, const char *p) { | |||
274 | while (m) { /* reads the same item until it fails */ | 274 | while (m) { /* reads the same item until it fails */ |
275 | c = getc(f); | 275 | c = getc(f); |
276 | m = (c==EOF) ? 0 : luaI_singlematch(c, p, ep); | 276 | m = (c==EOF) ? 0 : luaI_singlematch(c, p, ep); |
277 | if (m && !inskip) luaL_addchar(L, c); | 277 | if (m && !inskip) luaL_putchar(L, c); |
278 | } | 278 | } |
279 | /* go through to continue reading the pattern */ | 279 | /* go through to continue reading the pattern */ |
280 | case '?': /* optional */ | 280 | case '?': /* optional */ |
@@ -308,53 +308,74 @@ static int read_number (lua_State *L, FILE *f) { | |||
308 | } | 308 | } |
309 | 309 | ||
310 | 310 | ||
311 | static void read_word (lua_State *L, FILE *f) { | 311 | static int read_word (lua_State *L, FILE *f) { |
312 | int c; | 312 | int c; |
313 | luaL_Buffer b; | ||
314 | luaL_buffinit(L, &b); | ||
313 | do { c = fgetc(f); } while (isspace(c)); /* skip spaces */ | 315 | do { c = fgetc(f); } while (isspace(c)); /* skip spaces */ |
314 | while (c != EOF && !isspace(c)) { | 316 | while (c != EOF && !isspace(c)) { |
315 | luaL_addchar(L, c); | 317 | luaL_putchar(&b, c); |
316 | c = fgetc(f); | 318 | c = fgetc(f); |
317 | } | 319 | } |
318 | ungetc(c, f); | 320 | ungetc(c, f); |
321 | luaL_pushresult(&b); /* close buffer */ | ||
322 | return (lua_strlen(L, 1) > 0); | ||
319 | } | 323 | } |
320 | 324 | ||
321 | 325 | ||
322 | #define HUNK_LINE 256 | ||
323 | #define HUNK_FILE BUFSIZ | ||
324 | |||
325 | static int read_line (lua_State *L, FILE *f) { | 326 | static int read_line (lua_State *L, FILE *f) { |
326 | int n; | 327 | int n = 0; |
327 | char *b; | 328 | luaL_Buffer b; |
329 | luaL_buffinit(L, &b); | ||
328 | for (;;) { | 330 | for (;;) { |
329 | b = luaL_openspace(L, HUNK_LINE); | 331 | char *p = luaL_prepbuffer(&b); |
330 | if (!fgets(b, HUNK_LINE, f)) return 0; /* read fails */ | 332 | if (!fgets(p, LUAL_BUFFERSIZE, f)) /* read fails? */ |
331 | n = strlen(b); | 333 | break; |
332 | if (b[n-1] != '\n') | 334 | n = strlen(p); |
333 | luaL_addsize(L, n); | 335 | if (p[n-1] != '\n') |
336 | luaL_addsize(&b, n); | ||
334 | else { | 337 | else { |
335 | luaL_addsize(L, n-1); /* do not add the `\n' */ | 338 | luaL_addsize(&b, n-1); /* do not add the `\n' */ |
336 | break; | 339 | break; |
337 | } | 340 | } |
338 | } | 341 | } |
339 | return 1; | 342 | luaL_pushresult(&b); /* close buffer */ |
343 | return (n > 0); /* read something? */ | ||
340 | } | 344 | } |
341 | 345 | ||
342 | 346 | ||
343 | static void read_file (lua_State *L, FILE *f) { | 347 | static void read_file (lua_State *L, FILE *f) { |
344 | size_t n; | 348 | size_t len = 0; |
345 | do { | 349 | size_t size = BUFSIZ; |
346 | char *b = luaL_openspace(L, HUNK_FILE); | 350 | char *buffer = NULL; |
347 | n = fread(b, sizeof(char), HUNK_FILE, f); | 351 | for (;;) { |
348 | luaL_addsize(L, n); | 352 | buffer = (char *)realloc(buffer, size); |
349 | } while (n==HUNK_FILE); | 353 | if (buffer == NULL) |
354 | lua_error(L, "not enough memory to read a file"); | ||
355 | len += fread(buffer+len, sizeof(char), size-len, f); | ||
356 | if (len < size) break; /* did not read all it could */ | ||
357 | size *= 2; | ||
358 | } | ||
359 | lua_pushlstring(L, buffer, len); | ||
360 | free(buffer); | ||
350 | } | 361 | } |
351 | 362 | ||
352 | 363 | ||
353 | static int read_chars (lua_State *L, FILE *f, size_t n) { | 364 | static int read_chars (lua_State *L, FILE *f, size_t n) { |
354 | char *b = luaL_openspace(L, n); | 365 | char *buffer; |
355 | size_t n1 = fread(b, sizeof(char), n, f); | 366 | size_t n1; |
356 | luaL_addsize(L, n1); | 367 | char statbuff[BUFSIZ]; |
357 | return (n == n1); | 368 | if (n <= BUFSIZ) |
369 | buffer = statbuff; | ||
370 | else { | ||
371 | buffer = (char *)malloc(n); | ||
372 | if (buffer == NULL) | ||
373 | lua_error(L, "not enough memory to read a file"); | ||
374 | } | ||
375 | n1 = fread(buffer, sizeof(char), n, f); | ||
376 | lua_pushlstring(L, buffer, n1); | ||
377 | if (buffer != statbuff) free(buffer); | ||
378 | return (n1 > 0 || n == 0); | ||
358 | } | 379 | } |
359 | 380 | ||
360 | 381 | ||
@@ -375,9 +396,7 @@ static int io_read (lua_State *L) { | |||
375 | else | 396 | else |
376 | luaL_checkstack(L, lastarg-firstarg+1, "too many arguments"); | 397 | luaL_checkstack(L, lastarg-firstarg+1, "too many arguments"); |
377 | for (n = firstarg; n<=lastarg; n++) { | 398 | for (n = firstarg; n<=lastarg; n++) { |
378 | size_t l; | ||
379 | int success; | 399 | int success; |
380 | luaL_resetbuffer(L); | ||
381 | if (lua_isnumber(L, n)) | 400 | if (lua_isnumber(L, n)) |
382 | success = read_chars(L, f, (size_t)lua_tonumber(L, n)); | 401 | success = read_chars(L, f, (size_t)lua_tonumber(L, n)); |
383 | else { | 402 | else { |
@@ -397,8 +416,7 @@ static int io_read (lua_State *L) { | |||
397 | success = 1; /* always success */ | 416 | success = 1; /* always success */ |
398 | break; | 417 | break; |
399 | case 'w': /* word */ | 418 | case 'w': /* word */ |
400 | read_word(L, f); | 419 | success = read_word(L, f); |
401 | success = 0; /* must read something to succeed */ | ||
402 | break; | 420 | break; |
403 | default: | 421 | default: |
404 | luaL_argerror(L, n, "invalid format"); | 422 | luaL_argerror(L, n, "invalid format"); |
@@ -406,9 +424,10 @@ static int io_read (lua_State *L) { | |||
406 | } | 424 | } |
407 | } | 425 | } |
408 | } | 426 | } |
409 | l = luaL_getsize(L); | 427 | if (!success) { |
410 | if (!success && l==0) break; /* read fails */ | 428 | lua_pop(L, 1); /* remove last result */ |
411 | lua_pushlstring(L, luaL_buffer(L), l); | 429 | break; /* read fails */ |
430 | } | ||
412 | } endloop: | 431 | } endloop: |
413 | return n - firstarg; | 432 | return n - firstarg; |
414 | } | 433 | } |