diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2010-02-18 17:32:41 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2010-02-18 17:32:41 -0200 |
commit | 64a7ec987cae3c59353600bf76bf635d0906b0cf (patch) | |
tree | 967f08d9414cf4a5f80479b7ba5cd23147f96aa8 /lauxlib.c | |
parent | 4274738e81ad12923c2ae5c769b3350c36cf1505 (diff) | |
download | lua-64a7ec987cae3c59353600bf76bf635d0906b0cf.tar.gz lua-64a7ec987cae3c59353600bf76bf635d0906b0cf.tar.bz2 lua-64a7ec987cae3c59353600bf76bf635d0906b0cf.zip |
avoid using 'ungetc' in loadfile
Diffstat (limited to 'lauxlib.c')
-rw-r--r-- | lauxlib.c | 22 |
1 files changed, 15 insertions, 7 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lauxlib.c,v 1.198 2010/02/11 15:52:50 roberto Exp roberto $ | 2 | ** $Id: lauxlib.c,v 1.199 2010/02/18 19:18:41 roberto Exp roberto $ |
3 | ** Auxiliary functions for building Lua libraries | 3 | ** Auxiliary functions for building Lua libraries |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -495,6 +495,7 @@ LUALIB_API void luaL_unref (lua_State *L, int t, int ref) { | |||
495 | */ | 495 | */ |
496 | 496 | ||
497 | typedef struct LoadF { | 497 | typedef struct LoadF { |
498 | int first; | ||
498 | FILE *f; | 499 | FILE *f; |
499 | char buff[LUAL_BUFFERSIZE]; | 500 | char buff[LUAL_BUFFERSIZE]; |
500 | } LoadF; | 501 | } LoadF; |
@@ -503,11 +504,18 @@ typedef struct LoadF { | |||
503 | static const char *getF (lua_State *L, void *ud, size_t *size) { | 504 | static const char *getF (lua_State *L, void *ud, size_t *size) { |
504 | LoadF *lf = (LoadF *)ud; | 505 | LoadF *lf = (LoadF *)ud; |
505 | (void)L; | 506 | (void)L; |
506 | /* 'fread' can return > 0 *and* set the EOF flag. If next call to | 507 | if (lf->first != EOF) { |
507 | 'getF' calls 'fread', terminal may still wait for user input. | 508 | *size = 1; |
508 | The next check avoids this problem. */ | 509 | lf->buff[0] = (char)lf->first; |
509 | if (feof(lf->f)) return NULL; | 510 | lf->first = EOF; |
510 | *size = fread(lf->buff, 1, sizeof(lf->buff), lf->f); | 511 | } |
512 | else { | ||
513 | /* 'fread' can return > 0 *and* set the EOF flag. If next call to | ||
514 | 'getF' called 'fread', it might still wait for user input. | ||
515 | The next check avoids this problem. */ | ||
516 | if (feof(lf->f)) return NULL; | ||
517 | *size = fread(lf->buff, 1, sizeof(lf->buff), lf->f); | ||
518 | } | ||
511 | return (*size > 0) ? lf->buff : NULL; | 519 | return (*size > 0) ? lf->buff : NULL; |
512 | } | 520 | } |
513 | 521 | ||
@@ -543,7 +551,7 @@ LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) { | |||
543 | lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */ | 551 | lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */ |
544 | if (lf.f == NULL) return errfile(L, "reopen", fnameindex); | 552 | if (lf.f == NULL) return errfile(L, "reopen", fnameindex); |
545 | } | 553 | } |
546 | ungetc(c, lf.f); | 554 | lf.first = c; /* 'c' is the first character of the stream */ |
547 | status = lua_load(L, getF, &lf, lua_tostring(L, -1)); | 555 | status = lua_load(L, getF, &lf, lua_tostring(L, -1)); |
548 | readstatus = ferror(lf.f); | 556 | readstatus = ferror(lf.f); |
549 | if (filename) fclose(lf.f); /* close file (even in case of errors) */ | 557 | if (filename) fclose(lf.f); /* close file (even in case of errors) */ |