summaryrefslogtreecommitdiff
path: root/src/lauxlib.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lauxlib.c')
-rw-r--r--src/lauxlib.c41
1 files changed, 31 insertions, 10 deletions
diff --git a/src/lauxlib.c b/src/lauxlib.c
index b765cfdd..d61a8ef8 100644
--- a/src/lauxlib.c
+++ b/src/lauxlib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lauxlib.c,v 1.233 2011/06/16 14:11:04 roberto Exp $
+** $Id: lauxlib.c,v 1.236 2011/11/14 17:10:24 roberto Exp $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/
@@ -41,11 +41,10 @@
** return 1 + string at top if find a good name.
*/
static int findfield (lua_State *L, int objidx, int level) {
- int found = 0;
if (level == 0 || !lua_istable(L, -1))
return 0; /* not found */
lua_pushnil(L); /* start 'next' loop */
- while (!found && lua_next(L, -2)) { /* for each pair in table */
+ while (lua_next(L, -2)) { /* for each pair in table */
if (lua_type(L, -2) == LUA_TSTRING) { /* ignore non-string keys */
if (lua_rawequal(L, objidx, -1)) { /* found object? */
lua_pop(L, 1); /* remove value (but keep name) */
@@ -86,7 +85,7 @@ static void pushfuncname (lua_State *L, lua_Debug *ar) {
lua_pushfstring(L, "function " LUA_QS, ar->name);
else if (*ar->what == 'm') /* main? */
lua_pushfstring(L, "main chunk");
- else if (*ar->what == 'C' || *ar->what == 't') {
+ else if (*ar->what == 'C') {
if (pushglobalfuncname(L, ar)) {
lua_pushfstring(L, "function " LUA_QS, lua_tostring(L, -1));
lua_remove(L, -2); /* remove name */
@@ -331,7 +330,9 @@ 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) {
- if (!lua_checkstack(L, space)) {
+ /* keep some extra space to run error routines, if needed */
+ const int extra = LUA_MINSTACK;
+ if (!lua_checkstack(L, space + extra)) {
if (msg)
luaL_error(L, "stack overflow (%s)", msg);
else
@@ -591,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;
@@ -623,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;
@@ -639,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) {