diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2011-11-14 15:10:24 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2011-11-14 15:10:24 -0200 |
| commit | 6cce5c060186c109d5fc87ac13b5d36d9d3997ea (patch) | |
| tree | b2215f8fec6effa7adc45e73614a0694b833016a | |
| parent | eb70f58279e7bd8581ecf58c763d8065a8e2bfb0 (diff) | |
| download | lua-6cce5c060186c109d5fc87ac13b5d36d9d3997ea.tar.gz lua-6cce5c060186c109d5fc87ac13b5d36d9d3997ea.tar.bz2 lua-6cce5c060186c109d5fc87ac13b5d36d9d3997ea.zip | |
new function 'luaL_loadfilex'
| -rw-r--r-- | lauxlib.c | 34 | ||||
| -rw-r--r-- | lauxlib.h | 14 | ||||
| -rw-r--r-- | lbaselib.c | 21 |
3 files changed, 50 insertions, 19 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lauxlib.c,v 1.234 2011/07/25 17:18:49 roberto Exp roberto $ | 2 | ** $Id: lauxlib.c,v 1.235 2011/11/09 19:08:55 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 | */ |
| @@ -331,7 +331,7 @@ LUALIB_API int luaL_checkoption (lua_State *L, int narg, const char *def, | |||
| 331 | 331 | ||
| 332 | LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *msg) { | 332 | LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *msg) { |
| 333 | /* keep some extra space to run error routines, if needed */ | 333 | /* keep some extra space to run error routines, if needed */ |
| 334 | const int extra = 2 * LUA_MINSTACK; | 334 | const int extra = LUA_MINSTACK; |
| 335 | if (!lua_checkstack(L, space + extra)) { | 335 | if (!lua_checkstack(L, space + extra)) { |
| 336 | if (msg) | 336 | if (msg) |
| 337 | luaL_error(L, "stack overflow (%s)", msg); | 337 | luaL_error(L, "stack overflow (%s)", msg); |
| @@ -592,6 +592,16 @@ static int errfile (lua_State *L, const char *what, int fnameindex) { | |||
| 592 | } | 592 | } |
| 593 | 593 | ||
| 594 | 594 | ||
| 595 | static int checkmode (lua_State *L, const char *mode, const char *x) { | ||
| 596 | if (mode && strchr(mode, x[0]) == NULL) { | ||
| 597 | lua_pushfstring(L, | ||
| 598 | "attempt to load a %s chunk (mode is " LUA_QS ")", x, mode); | ||
| 599 | return LUA_ERRFILE; | ||
| 600 | } | ||
| 601 | else return LUA_OK; | ||
| 602 | } | ||
| 603 | |||
| 604 | |||
| 595 | static int skipBOM (LoadF *lf) { | 605 | static int skipBOM (LoadF *lf) { |
| 596 | const char *p = "\xEF\xBB\xBF"; /* Utf8 BOM mark */ | 606 | const char *p = "\xEF\xBB\xBF"; /* Utf8 BOM mark */ |
| 597 | int c; | 607 | int c; |
| @@ -624,7 +634,8 @@ static int skipcomment (LoadF *lf, int *cp) { | |||
| 624 | } | 634 | } |
| 625 | 635 | ||
| 626 | 636 | ||
| 627 | LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) { | 637 | LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename, |
| 638 | const char *mode) { | ||
| 628 | LoadF lf; | 639 | LoadF lf; |
| 629 | int status, readstatus; | 640 | int status, readstatus; |
| 630 | int c; | 641 | int c; |
| @@ -640,14 +651,23 @@ LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) { | |||
| 640 | } | 651 | } |
| 641 | if (skipcomment(&lf, &c)) /* read initial portion */ | 652 | if (skipcomment(&lf, &c)) /* read initial portion */ |
| 642 | lf.buff[lf.n++] = '\n'; /* add line to correct line numbers */ | 653 | lf.buff[lf.n++] = '\n'; /* add line to correct line numbers */ |
| 643 | if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */ | 654 | if (c == LUA_SIGNATURE[0]) { /* binary file? */ |
| 644 | lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */ | 655 | if ((status = checkmode(L, mode, "binary")) != LUA_OK) |
| 645 | if (lf.f == NULL) return errfile(L, "reopen", fnameindex); | 656 | goto closefile; |
| 646 | skipcomment(&lf, &c); /* re-read initial portion */ | 657 | if (filename) { |
| 658 | lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */ | ||
| 659 | if (lf.f == NULL) return errfile(L, "reopen", fnameindex); | ||
| 660 | skipcomment(&lf, &c); /* re-read initial portion */ | ||
| 661 | } | ||
| 662 | } | ||
| 663 | else { /* text file */ | ||
| 664 | if ((status = checkmode(L, mode, "text")) != LUA_OK) | ||
| 665 | goto closefile; | ||
| 647 | } | 666 | } |
| 648 | if (c != EOF) | 667 | if (c != EOF) |
| 649 | lf.buff[lf.n++] = c; /* 'c' is the first character of the stream */ | 668 | lf.buff[lf.n++] = c; /* 'c' is the first character of the stream */ |
| 650 | status = lua_load(L, getF, &lf, lua_tostring(L, -1)); | 669 | status = lua_load(L, getF, &lf, lua_tostring(L, -1)); |
| 670 | closefile: | ||
| 651 | readstatus = ferror(lf.f); | 671 | readstatus = ferror(lf.f); |
| 652 | if (filename) fclose(lf.f); /* close file (even in case of errors) */ | 672 | if (filename) fclose(lf.f); /* close file (even in case of errors) */ |
| 653 | if (readstatus) { | 673 | if (readstatus) { |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lauxlib.h,v 1.117 2011/06/16 14:10:12 roberto Exp roberto $ | 2 | ** $Id: lauxlib.h,v 1.118 2011/11/11 19:59:17 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 | */ |
| @@ -72,7 +72,11 @@ LUALIB_API int (luaL_execresult) (lua_State *L, int stat); | |||
| 72 | LUALIB_API int (luaL_ref) (lua_State *L, int t); | 72 | LUALIB_API int (luaL_ref) (lua_State *L, int t); |
| 73 | LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref); | 73 | LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref); |
| 74 | 74 | ||
| 75 | LUALIB_API int (luaL_loadfile) (lua_State *L, const char *filename); | 75 | LUALIB_API int (luaL_loadfilex) (lua_State *L, const char *filename, |
| 76 | const char *mode); | ||
| 77 | |||
| 78 | #define luaL_loadfile(L,f) luaL_loadfilex(L,f,NULL) | ||
| 79 | |||
| 76 | LUALIB_API int (luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz, | 80 | LUALIB_API int (luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz, |
| 77 | const char *name); | 81 | const char *name); |
| 78 | LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s); | 82 | LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s); |
| @@ -172,17 +176,17 @@ LUALIB_API char *(luaL_buffinitsize) (lua_State *L, luaL_Buffer *B, size_t sz); | |||
| 172 | 176 | ||
| 173 | /* | 177 | /* |
| 174 | ** A file handle is a userdata with metatable 'LUA_FILEHANDLE' and | 178 | ** A file handle is a userdata with metatable 'LUA_FILEHANDLE' and |
| 175 | ** initial structure 'luaIO_Stream' (it may contain other fields | 179 | ** initial structure 'luaL_Stream' (it may contain other fields |
| 176 | ** after that initial structure). | 180 | ** after that initial structure). |
| 177 | */ | 181 | */ |
| 178 | 182 | ||
| 179 | #define LUA_FILEHANDLE "FILE*" | 183 | #define LUA_FILEHANDLE "FILE*" |
| 180 | 184 | ||
| 181 | 185 | ||
| 182 | typedef struct luaIO_Stream { | 186 | typedef struct luaL_Stream { |
| 183 | FILE *f; /* stream (NULL for incompletely created streams) */ | 187 | FILE *f; /* stream (NULL for incompletely created streams) */ |
| 184 | lua_CFunction closef; /* to close stream (NULL for closed streams) */ | 188 | lua_CFunction closef; /* to close stream (NULL for closed streams) */ |
| 185 | } luaIO_Stream; | 189 | } luaL_Stream; |
| 186 | 190 | ||
| 187 | /* }====================================================== */ | 191 | /* }====================================================== */ |
| 188 | 192 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lbaselib.c,v 1.267 2011/11/09 19:28:27 roberto Exp roberto $ | 2 | ** $Id: lbaselib.c,v 1.268 2011/11/09 19:38:00 roberto Exp roberto $ |
| 3 | ** Basic library | 3 | ** Basic library |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -255,7 +255,14 @@ static int load_aux (lua_State *L, int status) { | |||
| 255 | 255 | ||
| 256 | static int luaB_loadfile (lua_State *L) { | 256 | static int luaB_loadfile (lua_State *L) { |
| 257 | const char *fname = luaL_optstring(L, 1, NULL); | 257 | const char *fname = luaL_optstring(L, 1, NULL); |
| 258 | return load_aux(L, luaL_loadfile(L, fname)); | 258 | const char *mode = luaL_optstring(L, 2, NULL); |
| 259 | int env = !lua_isnone(L, 3); /* 'env' parameter? */ | ||
| 260 | int status = luaL_loadfilex(L, fname, mode); | ||
| 261 | if (status == LUA_OK && env) { /* 'env' parameter? */ | ||
| 262 | lua_pushvalue(L, 3); | ||
| 263 | lua_setupvalue(L, -2, 1); /* set it as 1st upvalue of loaded chunk */ | ||
| 264 | } | ||
| 265 | return load_aux(L, status); | ||
| 259 | } | 266 | } |
| 260 | 267 | ||
| 261 | 268 | ||
| @@ -277,11 +284,11 @@ typedef struct { | |||
| 277 | ** pushed on the stack) in case of errors. | 284 | ** pushed on the stack) in case of errors. |
| 278 | */ | 285 | */ |
| 279 | static const char *checkrights (lua_State *L, const char *mode, const char *s) { | 286 | static const char *checkrights (lua_State *L, const char *mode, const char *s) { |
| 280 | if (strchr(mode, 'b') == NULL && *s == LUA_SIGNATURE[0]) | 287 | const char *x = (*s == LUA_SIGNATURE[0]) ? "binary" : "text"; |
| 281 | return lua_pushstring(L, "attempt to load a binary chunk"); | 288 | if (strchr(mode, x[0]) == NULL) |
| 282 | if (strchr(mode, 't') == NULL && *s != LUA_SIGNATURE[0]) | 289 | return lua_pushfstring(L, |
| 283 | return lua_pushstring(L, "attempt to load a text chunk"); | 290 | "attempt to load a %s chunk (mode is " LUA_QS ")", x, mode); |
| 284 | return NULL; /* chunk in allowed format */ | 291 | else return NULL; |
| 285 | } | 292 | } |
| 286 | 293 | ||
| 287 | 294 | ||
