diff options
| -rw-r--r-- | lauxlib.c | 43 |
1 files changed, 30 insertions, 13 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lauxlib.c,v 1.213 2010/05/18 17:32:19 roberto Exp roberto $ | 2 | ** $Id: lauxlib.c,v 1.214 2010/05/31 16:34:19 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 | */ |
| @@ -476,7 +476,7 @@ LUALIB_API void luaL_unref (lua_State *L, int t, int ref) { | |||
| 476 | */ | 476 | */ |
| 477 | 477 | ||
| 478 | typedef struct LoadF { | 478 | typedef struct LoadF { |
| 479 | int first; /* pre-read character */ | 479 | int n; /* number of pre-read characters */ |
| 480 | FILE *f; /* file being read */ | 480 | FILE *f; /* file being read */ |
| 481 | char buff[LUAL_BUFFERSIZE]; /* area for reading file */ | 481 | char buff[LUAL_BUFFERSIZE]; /* area for reading file */ |
| 482 | } LoadF; | 482 | } LoadF; |
| @@ -485,10 +485,9 @@ typedef struct LoadF { | |||
| 485 | static const char *getF (lua_State *L, void *ud, size_t *size) { | 485 | static const char *getF (lua_State *L, void *ud, size_t *size) { |
| 486 | LoadF *lf = (LoadF *)ud; | 486 | LoadF *lf = (LoadF *)ud; |
| 487 | (void)L; | 487 | (void)L; |
| 488 | if (lf->first != EOF) { /* first character not read yet? */ | 488 | if (lf->n > 0) { /* are there pre-read characters to be read? */ |
| 489 | lf->buff[0] = (char)lf->first; /* return it */ | 489 | *size = lf->n; /* return them (chars already in buffer) */ |
| 490 | *size = 1; | 490 | lf->n = 0; /* no more pre-read characters */ |
| 491 | lf->first = EOF; /* now it has been read */ | ||
| 492 | } | 491 | } |
| 493 | else { /* read a block from file */ | 492 | else { /* read a block from file */ |
| 494 | /* 'fread' can return > 0 *and* set the EOF flag. If next call to | 493 | /* 'fread' can return > 0 *and* set the EOF flag. If next call to |
| @@ -510,6 +509,23 @@ static int errfile (lua_State *L, const char *what, int fnameindex) { | |||
| 510 | } | 509 | } |
| 511 | 510 | ||
| 512 | 511 | ||
| 512 | /* | ||
| 513 | ** reads the first character of file 'f' and skips its first line | ||
| 514 | ** if it starts with '#'. Returns true if it skipped the first line. | ||
| 515 | ** In any case, '*cp' has the first "valid" character of the file | ||
| 516 | ** (after the optional first-line comment). | ||
| 517 | */ | ||
| 518 | static int skipcomment (FILE *f, int *cp) { | ||
| 519 | int c = *cp = getc(f); | ||
| 520 | if (c == '#') { /* first line is a comment (Unix exec. file)? */ | ||
| 521 | while ((c = getc(f)) != EOF && c != '\n') ; /* skip first line */ | ||
| 522 | *cp = getc(f); /* skip end-of-line */ | ||
| 523 | return 1; /* there was a comment */ | ||
| 524 | } | ||
| 525 | else return 0; /* no comment */ | ||
| 526 | } | ||
| 527 | |||
| 528 | |||
| 513 | LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) { | 529 | LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) { |
| 514 | LoadF lf; | 530 | LoadF lf; |
| 515 | int status, readstatus; | 531 | int status, readstatus; |
| @@ -524,16 +540,17 @@ LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) { | |||
| 524 | lf.f = fopen(filename, "r"); | 540 | lf.f = fopen(filename, "r"); |
| 525 | if (lf.f == NULL) return errfile(L, "open", fnameindex); | 541 | if (lf.f == NULL) return errfile(L, "open", fnameindex); |
| 526 | } | 542 | } |
| 527 | c = getc(lf.f); | 543 | lf.n = 0; |
| 528 | if (c == '#') { /* Unix exec. file? */ | 544 | if (skipcomment(lf.f, &c)) /* read initial portion */ |
| 529 | while ((c = getc(lf.f)) != EOF && c != '\n') ; /* skip first line */ | 545 | lf.buff[lf.n++] = '\n'; /* add line to correct line numbers */ |
| 530 | } | 546 | if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */ |
| 531 | else if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */ | ||
| 532 | lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */ | 547 | lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */ |
| 533 | if (lf.f == NULL) return errfile(L, "reopen", fnameindex); | 548 | if (lf.f == NULL) return errfile(L, "reopen", fnameindex); |
| 534 | c = getc(lf.f); /* re-read first character */ | 549 | lf.n = 0; |
| 550 | skipcomment(lf.f, &c); /* re-read initial portion */ | ||
| 535 | } | 551 | } |
| 536 | lf.first = c; /* 'c' is the first character of the stream */ | 552 | if (c != EOF) |
| 553 | lf.buff[lf.n++] = c; /* 'c' is the first character of the stream */ | ||
| 537 | status = lua_load(L, getF, &lf, lua_tostring(L, -1)); | 554 | status = lua_load(L, getF, &lf, lua_tostring(L, -1)); |
| 538 | readstatus = ferror(lf.f); | 555 | readstatus = ferror(lf.f); |
| 539 | if (filename) fclose(lf.f); /* close file (even in case of errors) */ | 556 | if (filename) fclose(lf.f); /* close file (even in case of errors) */ |
