lua

A copy of the Lua development repository
Log | Files | Refs | README

commit 6cce5c060186c109d5fc87ac13b5d36d9d3997ea
parent eb70f58279e7bd8581ecf58c763d8065a8e2bfb0
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date:   Mon, 14 Nov 2011 15:10:00 -0200

new function 'luaL_loadfilex'

Diffstat:
Mlauxlib.c | 34+++++++++++++++++++++++++++-------
Mlauxlib.h | 14+++++++++-----
Mlbaselib.c | 21++++++++++++++-------
3 files changed, 50 insertions(+), 19 deletions(-)

diff --git a/lauxlib.c b/lauxlib.c @@ -1,5 +1,5 @@ /* -** $Id: lauxlib.c,v 1.234 2011/07/25 17:18:49 roberto Exp roberto $ +** $Id: lauxlib.c,v 1.235 2011/11/09 19:08:55 roberto Exp roberto $ ** Auxiliary functions for building Lua libraries ** See Copyright Notice in lua.h */ @@ -331,7 +331,7 @@ LUALIB_API int luaL_checkoption (lua_State *L, int narg, const char *def, LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *msg) { /* keep some extra space to run error routines, if needed */ - const int extra = 2 * LUA_MINSTACK; + const int extra = LUA_MINSTACK; if (!lua_checkstack(L, space + extra)) { if (msg) luaL_error(L, "stack overflow (%s)", msg); @@ -592,6 +592,16 @@ static int errfile (lua_State *L, const char *what, int fnameindex) { } +static int checkmode (lua_State *L, const char *mode, const char *x) { + if (mode && strchr(mode, x[0]) == NULL) { + lua_pushfstring(L, + "attempt to load a %s chunk (mode is " LUA_QS ")", x, mode); + return LUA_ERRFILE; + } + else return LUA_OK; +} + + static int skipBOM (LoadF *lf) { const char *p = "\xEF\xBB\xBF"; /* Utf8 BOM mark */ int c; @@ -624,7 +634,8 @@ static int skipcomment (LoadF *lf, int *cp) { } -LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) { +LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename, + const char *mode) { LoadF lf; int status, readstatus; int c; @@ -640,14 +651,23 @@ LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) { } if (skipcomment(&lf, &c)) /* read initial portion */ lf.buff[lf.n++] = '\n'; /* add line to correct line numbers */ - if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */ - lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */ - if (lf.f == NULL) return errfile(L, "reopen", fnameindex); - skipcomment(&lf, &c); /* re-read initial portion */ + if (c == LUA_SIGNATURE[0]) { /* binary file? */ + if ((status = checkmode(L, mode, "binary")) != LUA_OK) + goto closefile; + if (filename) { + lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */ + if (lf.f == NULL) return errfile(L, "reopen", fnameindex); + skipcomment(&lf, &c); /* re-read initial portion */ + } + } + else { /* text file */ + if ((status = checkmode(L, mode, "text")) != LUA_OK) + goto closefile; } if (c != EOF) lf.buff[lf.n++] = c; /* 'c' is the first character of the stream */ status = lua_load(L, getF, &lf, lua_tostring(L, -1)); + closefile: readstatus = ferror(lf.f); if (filename) fclose(lf.f); /* close file (even in case of errors) */ if (readstatus) { diff --git a/lauxlib.h b/lauxlib.h @@ -1,5 +1,5 @@ /* -** $Id: lauxlib.h,v 1.117 2011/06/16 14:10:12 roberto Exp roberto $ +** $Id: lauxlib.h,v 1.118 2011/11/11 19:59:17 roberto Exp roberto $ ** Auxiliary functions for building Lua libraries ** See Copyright Notice in lua.h */ @@ -72,7 +72,11 @@ LUALIB_API int (luaL_execresult) (lua_State *L, int stat); LUALIB_API int (luaL_ref) (lua_State *L, int t); LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref); -LUALIB_API int (luaL_loadfile) (lua_State *L, const char *filename); +LUALIB_API int (luaL_loadfilex) (lua_State *L, const char *filename, + const char *mode); + +#define luaL_loadfile(L,f) luaL_loadfilex(L,f,NULL) + LUALIB_API int (luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz, const char *name); 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); /* ** A file handle is a userdata with metatable 'LUA_FILEHANDLE' and -** initial structure 'luaIO_Stream' (it may contain other fields +** initial structure 'luaL_Stream' (it may contain other fields ** after that initial structure). */ #define LUA_FILEHANDLE "FILE*" -typedef struct luaIO_Stream { +typedef struct luaL_Stream { FILE *f; /* stream (NULL for incompletely created streams) */ lua_CFunction closef; /* to close stream (NULL for closed streams) */ -} luaIO_Stream; +} luaL_Stream; /* }====================================================== */ diff --git a/lbaselib.c b/lbaselib.c @@ -1,5 +1,5 @@ /* -** $Id: lbaselib.c,v 1.267 2011/11/09 19:28:27 roberto Exp roberto $ +** $Id: lbaselib.c,v 1.268 2011/11/09 19:38:00 roberto Exp roberto $ ** Basic library ** See Copyright Notice in lua.h */ @@ -255,7 +255,14 @@ static int load_aux (lua_State *L, int status) { static int luaB_loadfile (lua_State *L) { const char *fname = luaL_optstring(L, 1, NULL); - return load_aux(L, luaL_loadfile(L, fname)); + const char *mode = luaL_optstring(L, 2, NULL); + int env = !lua_isnone(L, 3); /* 'env' parameter? */ + int status = luaL_loadfilex(L, fname, mode); + if (status == LUA_OK && env) { /* 'env' parameter? */ + lua_pushvalue(L, 3); + lua_setupvalue(L, -2, 1); /* set it as 1st upvalue of loaded chunk */ + } + return load_aux(L, status); } @@ -277,11 +284,11 @@ typedef struct { ** pushed on the stack) in case of errors. */ static const char *checkrights (lua_State *L, const char *mode, const char *s) { - if (strchr(mode, 'b') == NULL && *s == LUA_SIGNATURE[0]) - return lua_pushstring(L, "attempt to load a binary chunk"); - if (strchr(mode, 't') == NULL && *s != LUA_SIGNATURE[0]) - return lua_pushstring(L, "attempt to load a text chunk"); - return NULL; /* chunk in allowed format */ + const char *x = (*s == LUA_SIGNATURE[0]) ? "binary" : "text"; + if (strchr(mode, x[0]) == NULL) + return lua_pushfstring(L, + "attempt to load a %s chunk (mode is " LUA_QS ")", x, mode); + else return NULL; }