diff options
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 | } |
