--- lua-5.1.2/src/loadlib.c 2007年09月01日 20:48:07.656250000 -0400 +++ lua-5.1.2-mexec/src/loadlib.c 2007年09月01日 15:08:55.296875000 -0400 @@ -320,6 +320,38 @@ } } +static int ll_loadmodule (lua_State *L) { + int i; + const char *name = luaL_checkstring(L, 1); + /* iterate over available loaders */ + lua_getfield(L, LUA_ENVIRONINDEX, "loaders"); + if (!lua_istable(L, -1)) + luaL_error(L, LUA_QL("package.loaders") " must be a table"); + lua_pushliteral(L, ""); /* error message accumulator */ + for (i=1; ; i++) { + lua_rawgeti(L, -2, i); /* get a loader */ + if (lua_isnil(L, -1)) { + lua_pushfstring(L, "module " LUA_QS " not found:%s", + name, lua_tostring(L, -2)); + lua_remove(L, -3); + lua_remove(L, -3); + return 2; + } + lua_pushstring(L, name); + lua_call(L, 1, 1); /* call it */ + if (lua_isfunction(L, -1)) { /* did it find module? */ + lua_remove(L, -2); + lua_remove(L, -2); + return 1; /* module loaded successfully */ + } + else if (lua_isstring(L, -1)) /* loader returned error message? */ + lua_concat(L, 2); /* accumulate it */ + else + lua_pop(L, 1); + } + /* never reached */ + return 0; +} /* @@ -458,25 +490,10 @@ luaL_error(L, "loop or previous error loading module " LUA_QS, name); return 1; /* package is already loaded */ } - /* else must load it; iterate over available loaders */ - lua_getfield(L, LUA_ENVIRONINDEX, "loaders"); - if (!lua_istable(L, -1)) - luaL_error(L, LUA_QL("package.loaders") " must be a table"); - lua_pushliteral(L, ""); /* error message accumulator */ - for (i=1; ; i++) { - lua_rawgeti(L, -2, i); /* get a loader */ - if (lua_isnil(L, -1)) - luaL_error(L, "module " LUA_QS " not found:%s", - name, lua_tostring(L, -2)); - lua_pushstring(L, name); - lua_call(L, 1, 1); /* call it */ - if (lua_isfunction(L, -1)) /* did it find module? */ - break; /* module loaded successfully */ - else if (lua_isstring(L, -1)) /* loader returned error message? */ - lua_concat(L, 2); /* accumulate it */ - else - lua_pop(L, 1); - } + /* else must load it */ + lua_pushvalue(L, 1); + if (ll_loadmodule(L) == 2) /* note: or maybe lookup _G.loadmodule */ + lua_error(L); lua_pushlightuserdata(L, sentinel); lua_setfield(L, 2, name); /* _LOADED[name] = sentinel */ lua_pushstring(L, name); /* pass name as argument to module */ @@ -613,6 +630,7 @@ static const luaL_Reg ll_funcs[] = { {"module", ll_module}, {"require", ll_require}, + {"loadmodule", ll_loadmodule}, {NULL, NULL} }; diff -ur lua-5.1.2/src/lua.c lua-5.1.2-mexec/src/lua.c --- lua-5.1.2/src/lua.c 2007年09月01日 20:48:42.734375000 -0400 +++ lua-5.1.2-mexec/src/lua.c 2007年09月01日 14:34:57.203125000 -0400 @@ -44,6 +44,7 @@ "usage: %s [options] [script [args]].\n" "Available options are:\n" " -e stat execute string " LUA_QL("stat") "\n" + " -p name execute module as script and stop handling options\n" " -l name require library " LUA_QL("name") "\n" " -i enter interactive mode after executing " LUA_QL("script") "\n" " -v show version information\n" @@ -233,15 +234,31 @@ progname = oldprogname; } -static int handle_script (lua_State *L, char **argv, int n) { +static int handle_script (lua_State *L, char **argv, int has_p, int n) { int status; const char *fname; int narg = getargs(L, argv, n); /* collect arguments */ lua_setglobal(L, "arg"); fname = argv[n]; - if (strcmp(fname, "-") == 0 && strcmp(argv[n-1], "--") != 0) - fname = NULL; /* stdin */ - status = luaL_loadfile(L, fname); + if (has_p) { + if (has_p == 1) fname += 2; /* ignore "-p" */ + lua_getfield(L, LUA_GLOBALSINDEX, "loadmodule"); + lua_pushstring(L, fname); + lua_call(L, 1, 2); + if (lua_isnil(L, -2)) { + lua_remove(L, -2); + status = 1; + } + else { + lua_pop(L, 1); + status = 0; + } + } + else { + if (strcmp(fname, "-") == 0 && strcmp(argv[n-1], "--") != 0) + fname = NULL; /* stdin */ + status = luaL_loadfile(L, fname); + } lua_insert(L, -(narg+1)); if (status == 0) status = docall(L, narg, 0); @@ -255,7 +272,7 @@ #define notail(x) {if ((x)[2] != '0円') return -1;} -static int collectargs (char **argv, int *pi, int *pv, int *pe) { +static int collectargs (char **argv, int *pi, int *pv, int *pe, int *pp) { int i; for (i = 1; argv[i] != NULL; i++) { if (argv[i][0] != '-') /* not an option? */ @@ -281,6 +298,14 @@ if (argv[i] == NULL) return -1; } break; + case 'p': + if (argv[i][2] == '0円') { + i++; + *pp = 2; + if (argv[i] == NULL) return -1; + } + else *pp = 1; + return i; default: return -1; /* invalid option */ } } @@ -338,7 +363,7 @@ struct Smain *s = (struct Smain *)lua_touserdata(L, 1); char **argv = s->argv; int script; - int has_i = 0, has_v = 0, has_e = 0; + int has_i = 0, has_v = 0, has_e = 0, has_p = 0; globalL = L; if (argv[0] && argv[0][0]) progname = argv[0]; lua_gc(L, LUA_GCSTOP, 0); /* stop collector during initialization */ @@ -346,7 +371,7 @@ lua_gc(L, LUA_GCRESTART, 0); s->status = handle_luainit(L); if (s->status != 0) return 0; - script = collectargs(argv, &has_i, &has_v, &has_e); + script = collectargs(argv, &has_i, &has_v, &has_e, &has_p); if (script < 0) { /* invalid args? */ print_usage(); s->status = 1; @@ -356,7 +381,7 @@ s->status = runargs(L, argv, (script> 0) ? script : s->argc); if (s->status != 0) return 0; if (script) - s->status = handle_script(L, argv, script); + s->status = handle_script(L, argv, has_p, script); if (s->status != 0) return 0; if (has_i) dotty(L); diff -ur lua-5.1.2/src/lua.c~ lua-5.1.2-mexec/src/lua.c~ --- lua-5.1.2/src/lua.c~ 2006年06月02日 11:34:00.000000000 -0400 +++ lua-5.1.2-mexec/src/lua.c~ 2007年09月01日 10:33:46.359375000 -0400 @@ -44,6 +44,7 @@ "usage: %s [options] [script [args]].\n" "Available options are:\n" " -e stat execute string " LUA_QL("stat") "\n" + " -p name execute module as script and stop handling options\n" " -l name require library " LUA_QL("name") "\n" " -i enter interactive mode after executing " LUA_QL("script") "\n" " -v show version information\n" @@ -233,16 +234,54 @@ progname = oldprogname; } +/* based partly on loadlib.c ll_require and possibly should be merged */ +static int load_function (lua_State *L, const char * name) { + int i; + /* iterate over available loaders */ + lua_getfield(L, LUA_GLOBALSINDEX, "package"); + if (lua_istable(L, -1)) { + lua_getfield(L, -1, "loaders"); + lua_remove(L, -2); + } + if (!lua_istable(L, -1)) + luaL_error(L, LUA_QL("package.loaders") " must be a table"); + lua_pushliteral(L, ""); /* error message accumulator */ + for (i=1; ; i++) { + lua_rawgeti(L, -2, i); /* get a loader */ + if (lua_isnil(L, -1)) + luaL_error(L, "module " LUA_QS " not found:%s", + name, lua_tostring(L, -2)); + lua_pushstring(L, name); + lua_call(L, 1, 1); /* call it */ + if (lua_isfunction(L, -1)) { /* did it find module? */ + lua_remove(L, -2); + lua_remove(L, -2); + return 0; /* module loaded successfully */ + } + else if (lua_isstring(L, -1)) /* loader returned error message? */ + lua_concat(L, 2); /* accumulate it */ + else + lua_pop(L, 1); + } + lua_remove(L, -2); + return 1; +} -static int handle_script (lua_State *L, char **argv, int n) { +static int handle_script (lua_State *L, char **argv, int has_p, int n) { int status; const char *fname; int narg = getargs(L, argv, n); /* collect arguments */ lua_setglobal(L, "arg"); fname = argv[n]; - if (strcmp(fname, "-") == 0 && strcmp(argv[n-1], "--") != 0) - fname = NULL; /* stdin */ - status = luaL_loadfile(L, fname); + if (has_p) { + if (has_p == 1) fname += 2; /* ignore "-p" */ + status = load_function(L, fname); + } + else { + if (strcmp(fname, "-") == 0 && strcmp(argv[n-1], "--") != 0) + fname = NULL; /* stdin */ + status = luaL_loadfile(L, fname); + } lua_insert(L, -(narg+1)); if (status == 0) status = docall(L, narg, 0); @@ -256,7 +295,7 @@ #define notail(x) {if ((x)[2] != '0円') return -1;} -static int collectargs (char **argv, int *pi, int *pv, int *pe) { +static int collectargs (char **argv, int *pi, int *pv, int *pe, int *pp) { int i; for (i = 1; argv[i] != NULL; i++) { if (argv[i][0] != '-') /* not an option? */ @@ -282,6 +321,14 @@ if (argv[i] == NULL) return -1; } break; + case 'p': + if (argv[i][2] == '0円') { + i++; + *pp = 2; + if (argv[i] == NULL) return -1; + } + else *pp = 1; + return i; default: return -1; /* invalid option */ } } @@ -339,7 +386,7 @@ struct Smain *s = (struct Smain *)lua_touserdata(L, 1); char **argv = s->argv; int script; - int has_i = 0, has_v = 0, has_e = 0; + int has_i = 0, has_v = 0, has_e = 0, has_p = 0; globalL = L; if (argv[0] && argv[0][0]) progname = argv[0]; lua_gc(L, LUA_GCSTOP, 0); /* stop collector during initialization */ @@ -347,7 +394,7 @@ lua_gc(L, LUA_GCRESTART, 0); s->status = handle_luainit(L); if (s->status != 0) return 0; - script = collectargs(argv, &has_i, &has_v, &has_e); + script = collectargs(argv, &has_i, &has_v, &has_e, &has_p); if (script < 0) { /* invalid args? */ print_usage(); s->status = 1; @@ -357,7 +404,7 @@ s->status = runargs(L, argv, (script> 0) ? script : s->argc); if (s->status != 0) return 0; if (script) - s->status = handle_script(L, argv, script); + s->status = handle_script(L, argv, has_p, script); if (s->status != 0) return 0; if (has_i) dotty(L);