diff options
| author | Lua Team <team@lua.org> | 2004-12-07 12:00:00 +0000 |
|---|---|---|
| committer | repogen <> | 2004-12-07 12:00:00 +0000 |
| commit | 226f7859b5392b6680b7e703f9cc7f7f101fd365 (patch) | |
| tree | 4345e84719d7f9ccf8d62fa007cbd386f235c58a /src/lib | |
| parent | d8fd22e11b391cf183068049bebbee9702c8f78f (diff) | |
| download | lua-github-5.1-work3.tar.gz | |
Lua 5.1-work35.1-work3
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/lauxlib.c | 78 | ||||
| -rw-r--r-- | src/lib/lbaselib.c | 76 | ||||
| -rw-r--r-- | src/lib/ldblib.c | 9 | ||||
| -rw-r--r-- | src/lib/loadlib.c | 397 | ||||
| -rw-r--r-- | src/lib/loslib.c | 8 | ||||
| -rw-r--r-- | src/lib/lstrlib.c | 50 |
6 files changed, 433 insertions, 185 deletions
diff --git a/src/lib/lauxlib.c b/src/lib/lauxlib.c index 7c14d001..615be8f2 100644 --- a/src/lib/lauxlib.c +++ b/src/lib/lauxlib.c @@ -1,5 +1,5 @@ /* -** $Id: lauxlib.c,v 1.124 2004/09/03 13:17:14 roberto Exp $ +** $Id: lauxlib.c,v 1.126 2004/09/29 21:03:14 roberto Exp $ ** Auxiliary functions for building Lua libraries ** See Copyright Notice in lua.h */ @@ -239,16 +239,22 @@ LUALIB_API void luaL_openlib (lua_State *L, const char *libname, const luaL_reg *l, int nup) { if (libname) { /* check whether lib already exists */ - lua_getglobal(L, libname); - if (lua_isnil(L, -1)) { /* no? */ - lua_pop(L, 1); + luaL_getfield(L, LUA_GLOBALSINDEX, libname); + if (lua_isnil(L, -1)) { /* not found? */ + lua_pop(L, 1); /* remove previous result */ lua_newtable(L); /* create it */ if (lua_getmetatable(L, LUA_GLOBALSINDEX)) lua_setmetatable(L, -2); /* share metatable with global table */ - lua_pushvalue(L, -1); /* register it with given name */ - lua_setglobal(L, libname); + lua_pushvalue(L, -1); + luaL_setfield(L, LUA_GLOBALSINDEX, libname); } + else if (!lua_istable(L, -1)) + luaL_error(L, "name conflict for library `%s'", libname); + lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); + lua_pushvalue(L, -2); + lua_setfield(L, -2, libname); /* _LOADED[modname] = new table */ + lua_pop(L, 1); /* remove _LOADED table */ lua_insert(L, -(nup+1)); /* move library table to below upvalues */ } for (; l->name; l++) { @@ -352,8 +358,8 @@ static const char *pushnexttemplate (lua_State *L, const char *path) { } -static const char *luaL_gsub (lua_State *L, const char *s, - const char *p, const char *r) { +LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, const char *p, + const char *r) { const char *wild; int l = strlen(p); luaL_Buffer b; @@ -381,16 +387,68 @@ LUALIB_API const char *luaL_searchpath (lua_State *L, const char *name, } fname = luaL_gsub(L, lua_tostring(L, -1), LUA_PATH_MARK, name); lua_remove(L, -2); /* remove path template */ - f = fopen(fname, "r"); /* try to read it */ + f = fopen(fname, "r"); /* try to open it */ if (f) { + int err; + getc(f); /* try to read file */ + err = ferror(f); fclose(f); - return fname; + if (err == 0) /* open and read sucessful? */ + return fname; /* return that file name */ } lua_pop(L, 1); /* remove file name */ } } +LUALIB_API const char *luaL_getfield (lua_State *L, int idx, + const char *fname) { + const char *e; + lua_pushvalue(L, idx); + while ((e = strchr(fname, '.')) != NULL) { + lua_pushlstring(L, fname, e - fname); + lua_rawget(L, -2); + lua_remove(L, -2); /* remove previous table */ + fname = e + 1; + if (!lua_istable(L, -1)) return fname; + } + lua_pushstring(L, fname); + lua_rawget(L, -2); /* get last field */ + lua_remove(L, -2); /* remove previous table */ + return NULL; +} + + +LUALIB_API const char *luaL_setfield (lua_State *L, int idx, + const char *fname) { + const char *e; + lua_pushvalue(L, idx); + while ((e = strchr(fname, '.')) != NULL) { + lua_pushlstring(L, fname, e - fname); + lua_rawget(L, -2); + if (lua_isnil(L, -1)) { /* no such field? */ + lua_pop(L, 1); /* remove this nil */ + lua_newtable(L); /* create a new table for field */ + lua_pushlstring(L, fname, e - fname); + lua_pushvalue(L, -2); + lua_settable(L, -4); /* set new table into field */ + } + lua_remove(L, -2); /* remove previous table */ + fname = e + 1; + if (!lua_istable(L, -1)) { + lua_pop(L, 2); /* remove table and value */ + return fname; + } + } + lua_pushstring(L, fname); + lua_pushvalue(L, -3); /* move value to the top */ + lua_rawset(L, -3); /* set last field */ + lua_pop(L, 2); /* remove value and table */ + return NULL; +} + + + /* ** {====================================================== ** Generic Buffer manipulation diff --git a/src/lib/lbaselib.c b/src/lib/lbaselib.c index 82a8f509..8c628097 100644 --- a/src/lib/lbaselib.c +++ b/src/lib/lbaselib.c @@ -1,5 +1,5 @@ /* -** $Id: lbaselib.c,v 1.158 2004/09/15 20:39:42 roberto Exp $ +** $Id: lbaselib.c,v 1.161 2004/12/06 17:53:42 roberto Exp $ ** Basic library ** See Copyright Notice in lua.h */ @@ -181,10 +181,10 @@ static int luaB_gcinfo (lua_State *L) { static int luaB_collectgarbage (lua_State *L) { - static const char *const opts[] = {"stop", "restart", "collect", "count", - "step", NULL}; - static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, - LUA_GCCOLLECT, LUA_GCCOUNT, LUA_GCSTEP}; + static const char *const opts[] = {"stop", "restart", "collect", + "count", "step", "setstepmul", "setincmode", NULL}; + static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT, + LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETSTEPMUL, LUA_GCSETINCMODE}; int o = luaL_findstring(luaL_optstring(L, 1, "collect"), opts); int ex = luaL_optint(L, 2, 0); luaL_argcheck(L, o >= 0, 1, "invalid option"); @@ -440,50 +440,6 @@ static int luaB_newproxy (lua_State *L) { } -/* -** {====================================================== -** `require' function -** ======================================================= -*/ - - -static const char *getpath (lua_State *L) { - /* try first `LUA_PATH' for compatibility */ - lua_getfield(L, LUA_GLOBALSINDEX, "LUA_PATH"); - if (!lua_isstring(L, -1)) { - lua_pop(L, 1); - lua_getfield(L, LUA_GLOBALSINDEX, "_PATH"); - } - if (!lua_isstring(L, -1)) - luaL_error(L, "global _PATH must be a string"); - return lua_tostring(L, -1); -} - - -static int luaB_require (lua_State *L) { - const char *name = luaL_checkstring(L, 1); - const char *fname; - lua_getfield(L, lua_upvalueindex(1), name); - if (lua_toboolean(L, -1)) /* is it there? */ - return 1; /* package is already loaded; return its result */ - /* else must load it; first mark it as loaded */ - lua_pushboolean(L, 1); - lua_setfield(L, lua_upvalueindex(1), name); /* _LOADED[name] = true */ - fname = luaL_searchpath(L, name, getpath(L)); - if (fname == NULL || luaL_loadfile(L, fname) != 0) - return luaL_error(L, "error loading package `%s' (%s)", name, - lua_tostring(L, -1)); - lua_pushvalue(L, 1); /* pass name as argument to module */ - lua_call(L, 1, 1); /* run loaded module */ - if (!lua_isnil(L, -1)) /* nil return? */ - lua_setfield(L, lua_upvalueindex(1), name); - lua_getfield(L, lua_upvalueindex(1), name); /* return _LOADED[name] */ - return 1; -} - -/* }====================================================== */ - - static const luaL_reg base_funcs[] = { {"error", luaB_error}, {"getmetatable", luaB_getmetatable}, @@ -656,11 +612,10 @@ static void auxopen (lua_State *L, const char *name, static void base_open (lua_State *L) { - const char *path; lua_pushvalue(L, LUA_GLOBALSINDEX); luaL_openlib(L, NULL, base_funcs, 0); /* open lib into global table */ lua_pushliteral(L, LUA_VERSION); - lua_setfield(L, LUA_GLOBALSINDEX, "_VERSION"); /* set global _VERSION */ + lua_setglobal(L, "_VERSION"); /* set global _VERSION */ /* `ipairs' and `pairs' need auxliliary functions as upvalues */ auxopen(L, "ipairs", luaB_ipairs, ipairsaux); auxopen(L, "pairs", luaB_pairs, luaB_next); @@ -671,21 +626,16 @@ static void base_open (lua_State *L) { lua_pushliteral(L, "kv"); lua_setfield(L, -2, "__mode"); /* metatable(w).__mode = "kv" */ lua_pushcclosure(L, luaB_newproxy, 1); - lua_setfield(L, LUA_GLOBALSINDEX, "newproxy"); /* set global `newproxy' */ - /* `require' needs a table to keep loaded chunks */ + lua_setglobal(L, "newproxy"); /* set global `newproxy' */ + /* create register._LOADED to track loaded modules */ + lua_newtable(L); + lua_setfield(L, LUA_REGISTRYINDEX, "_LOADED"); + /* create register._PRELOAD to allow pre-loaded modules */ lua_newtable(L); - lua_pushvalue(L, -1); - lua_setglobal(L, "_LOADED"); - lua_pushcclosure(L, luaB_require, 1); - lua_setfield(L, LUA_GLOBALSINDEX, "require"); + lua_setfield(L, LUA_REGISTRYINDEX, "_PRELOAD"); /* set global _G */ lua_pushvalue(L, LUA_GLOBALSINDEX); - lua_setfield(L, LUA_GLOBALSINDEX, "_G"); - /* set global _PATH */ - path = getenv(LUA_PATH); - if (path == NULL) path = LUA_PATH_DEFAULT; - lua_pushstring(L, path); - lua_setfield(L, LUA_GLOBALSINDEX, "_PATH"); + lua_setglobal(L, "_G"); } diff --git a/src/lib/ldblib.c b/src/lib/ldblib.c index 4ec5f393..36d647aa 100644 --- a/src/lib/ldblib.c +++ b/src/lib/ldblib.c @@ -1,5 +1,5 @@ /* -** $Id: ldblib.c,v 1.87 2004/08/13 18:02:36 roberto Exp $ +** $Id: ldblib.c,v 1.89 2004/11/17 12:02:41 roberto Exp $ ** Interface from Lua to its debug API ** See Copyright Notice in lua.h */ @@ -261,7 +261,7 @@ static int debug (lua_State *L) { if (fgets(buffer, sizeof(buffer), stdin) == 0 || strcmp(buffer, "cont\n") == 0) return 0; - if (luaL_loadbuffer(L, buffer, strlen(buffer), "=debug command") || + if (luaL_loadbuffer(L, buffer, strlen(buffer), "=(debug command)") || lua_pcall(L, 0, 0, 0)) { fputs(lua_tostring(L, -1), stderr); fputs("\n", stderr); @@ -275,14 +275,15 @@ static int debug (lua_State *L) { #define LEVELS2 10 /* size of the second part of the stack */ static int errorfb (lua_State *L) { - int level = 1; /* skip level 0 (it's this function) */ + int level = 0; int firstpart = 1; /* still before eventual `...' */ int arg; lua_State *L1 = getthread(L, &arg); lua_Debug ar; + if (L == L1) level++; /* skip level 0 (it's this function) */ if (lua_gettop(L) == arg) lua_pushliteral(L, ""); - else if (!lua_isstring(L, arg+1)) return 1; /* no string message */ + else if (!lua_isstring(L, arg+1)) return 1; /* message is not a string */ else lua_pushliteral(L, "\n"); lua_pushliteral(L, "stack traceback:"); while (lua_getstack(L1, level++, &ar)) { diff --git a/src/lib/loadlib.c b/src/lib/loadlib.c index 8b98a2bf..63bc0bcc 100644 --- a/src/lib/loadlib.c +++ b/src/lib/loadlib.c @@ -1,31 +1,35 @@ /* -** $Id: loadlib.c,v 1.6 2004/04/30 20:13:38 roberto Exp $ +** $Id: loadlib.c,v 1.11 2004/11/19 15:52:12 roberto Exp $ ** Dynamic library loader for Lua ** See Copyright Notice in lua.h * -* This Lua library exports a single function, called loadlib, which is -* called from Lua as loadlib(lib,init), where lib is the full name of the -* library to be loaded (including the complete path) and init is the name -* of a function to be called after the library is loaded. Typically, this -* function will register other functions, thus making the complete library -* available to Lua. The init function is *not* automatically called by -* loadlib. Instead, loadlib returns the init function as a Lua function -* that the client can call when it thinks is appropriate. In the case of -* errors, loadlib returns nil and two strings describing the error. -* The first string is supplied by the operating system; it should be -* informative and useful for error messages. The second string is "open", -* "init", or "absent" to identify the error and is meant to be used for -* making decisions without having to look into the first string (whose -* format is system-dependent). -* -* This module contains an implementation of loadlib for Unix systems that -* have dlfcn, an implementation for Windows, and a stub for other systems. -* See the list at the end of this file for some links to available -* implementations of dlfcn and interfaces to other native dynamic loaders -* on top of which loadlib could be implemented. -* +* This Lua library exports a single function, called loadlib, which +* is called from Lua as loadlib(lib,init), where lib is the full +* name of the library to be loaded (including the complete path) and +* init is the name of a function to be called after the library is +* loaded. Typically, this function will register other functions, thus +* making the complete library available to Lua. The init function is +* *not* automatically called by loadlib. Instead, loadlib returns the +* init function as a Lua function that the client can call when it +* thinks is appropriate. In the case of errors, loadlib returns nil and +* two strings describing the error. The first string is supplied by +* the operating system; it should be informative and useful for error +* messages. The second string is "open", "init", or "absent" to identify +* the error and is meant to be used for making decisions without having +* to look into the first string (whose format is system-dependent). +* This module contains an implementation of loadlib for Unix systems +* that have dlfcn, an implementation for Darwin (Mac OS X), an +* implementation for Windows, and a stub for other systems. See +* the list at the end of this file for some links to available +* implementations of dlfcn and interfaces to other native dynamic +* loaders on top of which loadlib could be implemented. */ + +#include <stdlib.h> +#include <string.h> + + #define loadlib_c #define LUA_LIB @@ -34,11 +38,14 @@ #include "lualib.h" -#undef LOADLIB +#define ERR_OPEN 1 +#define ERR_FUNCTION 2 + + +static void registerlib (lua_State *L, const void *lib); -#ifdef USE_DLOPEN -#define LOADLIB +#if defined(USE_DLOPEN) /* * This is an implementation of loadlib based on the dlfcn interface. * The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD, @@ -48,53 +55,41 @@ #include <dlfcn.h> -static int loadlib(lua_State *L) +#define freelib dlclose + +static int loadlib(lua_State *L, const char *path, const char *init) { - const char *path=luaL_checkstring(L,1); - const char *init=luaL_checkstring(L,2); void *lib=dlopen(path,RTLD_NOW); if (lib!=NULL) { lua_CFunction f=(lua_CFunction) dlsym(lib,init); if (f!=NULL) { - lua_pushlightuserdata(L,lib); - lua_pushcclosure(L,f,1); - return 1; + registerlib(L, lib); + lua_pushcfunction(L,f); + return 0; } } - /* else return appropriate error messages */ - lua_pushnil(L); + /* else return appropriate error message */ lua_pushstring(L,dlerror()); - lua_pushstring(L,(lib!=NULL) ? "init" : "open"); - if (lib!=NULL) dlclose(lib); - return 3; + if (lib!=NULL) { + dlclose(lib); + return ERR_FUNCTION; /* error loading function */ + } + else return ERR_OPEN; /* error loading library */ } -#endif - - - -/* -** In Windows, default is to use dll; otherwise, default is not to use dll -*/ -#ifndef USE_DLL -#ifdef _WIN32 -#define USE_DLL 1 -#else -#define USE_DLL 0 -#endif -#endif -#if USE_DLL -#define LOADLIB +#elif defined(USE_DLL) /* * This is an implementation of loadlib for Windows using native functions. */ #include <windows.h> +#define freelib(lib) FreeLibrary((HINSTANCE)lib) + static void pusherror(lua_State *L) { int error=GetLastError(); @@ -106,61 +101,310 @@ static void pusherror(lua_State *L) lua_pushfstring(L,"system error %d\n",error); } -static int loadlib(lua_State *L) +static int loadlib(lua_State *L, const char *path, const char *init) { - const char *path=luaL_checkstring(L,1); - const char *init=luaL_checkstring(L,2); HINSTANCE lib=LoadLibrary(path); if (lib!=NULL) { lua_CFunction f=(lua_CFunction) GetProcAddress(lib,init); if (f!=NULL) { - lua_pushlightuserdata(L,lib); - lua_pushcclosure(L,f,1); + registerlib(L, lib); + lua_pushcfunction(L,f); return 1; } } - lua_pushnil(L); pusherror(L); - lua_pushstring(L,(lib!=NULL) ? "init" : "open"); - if (lib!=NULL) FreeLibrary(lib); - return 3; + if (lib!=NULL) { + FreeLibrary(lib); + return ERR_OPEN; + } + else return ERR_FUNCTION; } -#endif +/* Native Mac OS X / Darwin Implementation */ +#elif defined(USE_DYLD) + +#include <mach-o/dyld.h> + + +/* Mach cannot unload images (?) */ +#define freelib(lib) ((void)lib) + +static void pusherror (lua_State *L) +{ + const char *err_str; + const char *err_file; + NSLinkEditErrors err; + int err_num; + NSLinkEditError(&err, &err_num, &err_file, &err_str); + lua_pushstring(L, err_str); +} + +static int loadlib (lua_State *L, const char *path, const char *init) { + const struct mach_header *lib; + /* this would be a rare case, but prevents crashing if it happens */ + if(!_dyld_present()) { + lua_pushstring(L,"dyld not present."); + return ERR_OPEN; + } + lib = NSAddImage(path, NSADDIMAGE_OPTION_RETURN_ON_ERROR); + if(lib != NULL) { + NSSymbol init_sym = NSLookupSymbolInImage(lib, init, + NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | + NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR); + if(init_sym != NULL) { + lua_CFunction f = (lua_CFunction)NSAddressOfSymbol(init_sym); + registerlib(L, lib); + lua_pushcfunction(L,f); + return 0; + } + } + /* else an error ocurred */ + pusherror(L); + /* Can't unload image */ + return (lib != NULL) ? ERR_FUNCTION : ERR_OPEN; +} + -#ifndef LOADLIB -/* Fallback for other systems */ -/* -** Those systems support dlopen, so they should have defined USE_DLOPEN. -** The default (no)implementation gives them a special error message. -*/ -#if defined(linux) || defined(sun) || defined(sgi) || defined(BSD) || defined(_WIN32) -#define LOADLIB "`loadlib' not installed (check your Lua configuration)" #else -#define LOADLIB "`loadlib' not supported" -#endif +/* Fallback for other systems */ + +#define freelib(lib) ((void)lib) static int loadlib(lua_State *L) { + registerlib(L, NULL); /* to avoid warnings */ lua_pushnil(L); - lua_pushliteral(L,LOADLIB); + lua_pushliteral(L,"`loadlib' not supported"); lua_pushliteral(L,"absent"); return 3; } + #endif -LUALIB_API int luaopen_loadlib (lua_State *L) + +/* +** common code for all implementations: put a library into the registry +** so that, when Lua closes its state, the library's __gc metamethod +** will be called to unload the library. +*/ +static void registerlib (lua_State *L, const void *lib) +{ + const void **plib = (const void **)lua_newuserdata(L, sizeof(const void *)); + *plib = lib; + luaL_getmetatable(L, "_LOADLIB"); + lua_setmetatable(L, -2); + lua_pushboolean(L, 1); + lua_settable(L, LUA_REGISTRYINDEX); /* registry[lib] = true */ +} + +/* +** __gc tag method: calls library's `freelib' function with the lib +** handle +*/ +static int gctm (lua_State *L) { - lua_register(L,"loadlib",loadlib); + void *lib = *(void **)luaL_checkudata(L, 1, "_LOADLIB"); + freelib(lib); return 0; } + +static int loadlib1 (lua_State *L) { + const char *path=luaL_checkstring(L,1); + const char *init=luaL_checkstring(L,2); + int res = loadlib(L,path,init); + if (res == 0) /* no error? */ + return 1; /* function is at stack top */ + else { /* error */ + lua_pushnil(L); + lua_insert(L,-2); /* insert nil before error message */ + lua_pushstring(L, (res==ERR_OPEN)?"open":"init"); + return 3; + } +} + + + +/* +** {====================================================== +** `require' and `module' functions +** ======================================================= +*/ + + +static const char *loadLua (lua_State *L, const char *fname, const char *name) { + const char *path; + /* try first `LUA_PATH' for compatibility */ + lua_getglobal(L, "LUA_PATH"); + path = lua_tostring(L, -1); + if (!path) { + lua_pop(L, 1); + luaL_getfield(L, LUA_GLOBALSINDEX, "package.path"); + path = lua_tostring(L, -1); + } + if (path == NULL) + luaL_error(L, "`package.path' must be a string"); + fname = luaL_searchpath(L, fname, path); + if (fname == NULL) return path; /* library not found in this path */ + if (luaL_loadfile(L, fname) != 0) + luaL_error(L, "error loading package `%s' (%s)", name, lua_tostring(L, -1)); + return NULL; /* library loaded successfully */ +} + + +static const char *loadC (lua_State *L, const char *fname, const char *name) { + const char *path; + const char *funcname; + luaL_getfield(L, LUA_GLOBALSINDEX, "package.cpath"); + path = lua_tostring(L, -1); + if (path == NULL) + luaL_error(L, "global _CPATH must be a string"); + fname = luaL_searchpath(L, fname, path); + if (fname == NULL) return path; /* library not found in this path */ + funcname = luaL_gsub(L, name, ".", ""); + funcname = lua_pushfstring(L, "%s%s", LUA_POF, funcname); + if (loadlib(L, fname, funcname) != 0) + luaL_error(L, "error loading package `%s' (%s)", name, lua_tostring(L, -1)); + return NULL; /* library loaded successfully */ +} + + +static int ll_require (lua_State *L) { + const char *name = luaL_checkstring(L, 1); + lua_settop(L, 1); + lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); + lua_getfield(L, 2, name); + if (lua_toboolean(L, -1)) /* is it there? */ + return 1; /* package is already loaded; return its result */ + /* else must load it; first mark it as loaded */ + lua_pushboolean(L, 1); + lua_setfield(L, 2, name); /* _LOADED[name] = true */ + /* check whether it is preloaded */ + lua_getfield(L, LUA_REGISTRYINDEX, "_PRELOAD"); + lua_getfield(L, -1, name); + if (lua_isnil(L, -1)) { /* no preload function for that module? */ + const char *fname = luaL_gsub(L, name, ".", LUA_DIRSEP); + const char *cpath = loadC(L, fname, name); /* try a C module */ + if (cpath) { /* not found? */ + const char *path = loadLua(L, fname, name); /* try a Lua module */ + if (path) { /* yet not found? */ + lua_pushnil(L); + lua_setfield(L, 2, name); /* unmark _LOADED[name] */ + return luaL_error(L, "package `%s' not found\n" + " cpath: %s\n path: %s", + name, cpath, path); + } + } + } + lua_pushvalue(L, 1); /* pass name as argument to module */ + lua_call(L, 1, 1); /* run loaded module */ + if (!lua_isnil(L, -1)) /* non-nil return? */ + lua_setfield(L, 2, name); /* update _LOADED[name] with returned value */ + lua_getfield(L, 2, name); /* return _LOADED[name] */ + return 1; +} + + +static void setfenv (lua_State *L) { + lua_Debug ar; + lua_getstack(L, 1, &ar); + lua_getinfo(L, "f", &ar); + lua_pushvalue(L, -2); + lua_setfenv(L, -2); +} + + +static int ll_module (lua_State *L) { + const char *modname = luaL_checkstring(L, 1); + const char *dot; + lua_settop(L, 1); + lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); + /* try to find given table */ + luaL_getfield(L, LUA_GLOBALSINDEX, modname); + if (lua_isnil(L, -1)) { /* not found? */ + lua_pop(L, 1); /* remove previous result */ + lua_newtable(L); /* create it */ + /* register it with given name */ + lua_pushvalue(L, -1); + luaL_setfield(L, LUA_GLOBALSINDEX, modname); + } + else if (!lua_istable(L, -1)) + return luaL_error(L, "name conflict for module `%s'", modname); + /* check whether table already has a _NAME field */ + lua_getfield(L, -1, "_NAME"); + if (!lua_isnil(L, -1)) /* is table an initialized module? */ + lua_pop(L, 1); + else { /* no; initialize it */ + lua_pop(L, 1); + lua_newtable(L); /* create new metatable */ + lua_pushvalue(L, LUA_GLOBALSINDEX); + lua_setfield(L, -2, "__index"); /* mt.__index = _G */ + lua_setmetatable(L, -2); + lua_pushstring(L, modname); + lua_setfield(L, -2, "_NAME"); + dot = strrchr(modname, '.'); /* look for last dot in module name */ + if (dot == NULL) dot = modname; + else dot++; + /* set _PACKAGE as package name (full module name minus last part) */ + lua_pushlstring(L, modname, dot - modname); + lua_setfield(L, -2, "_PACKAGE"); + } + lua_pushvalue(L, -1); + lua_setfield(L, 2, modname); /* _LOADED[modname] = new table */ + setfenv(L); + return 0; +} + + +/* }====================================================== */ + + +static const luaL_reg ll_funcs[] = { + {"loadlib", loadlib1}, + {"require", ll_require}, + {"module", ll_module}, + {NULL, NULL} +}; + + + +LUALIB_API int luaopen_loadlib (lua_State *L) { + const char *path; + /* create new type _LOADLIB */ + luaL_newmetatable(L, "_LOADLIB"); + lua_pushcfunction(L, gctm); + lua_setfield(L, -2, "__gc"); + /* create `package' table */ + lua_newtable(L); + lua_pushvalue(L, -1); + lua_setglobal(L, "package"); + /* set field `path' */ + path = getenv(LUA_PATH); + if (path == NULL) path = LUA_PATH_DEFAULT; + lua_pushstring(L, path); + lua_setfield(L, -2, "path"); + /* set field `cpath' */ + path = getenv(LUA_CPATH); + if (path == NULL) path = LUA_CPATH_DEFAULT; + lua_pushstring(L, path); + lua_setfield(L, -2, "cpath"); + /* set field `loaded' */ + lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); + lua_setfield(L, -2, "loaded"); + /* set field `preload' */ + lua_getfield(L, LUA_REGISTRYINDEX, "_PRELOAD"); + lua_setfield(L, -2, "preload"); + lua_pushvalue(L, LUA_GLOBALSINDEX); + luaL_openlib(L, NULL, ll_funcs, 0); /* open lib into global table */ + return 1; +} + /* * Here are some links to available implementations of dlfcn and * interfaces to other native dynamic loaders on top of which loadlib @@ -179,9 +423,6 @@ LUALIB_API int luaopen_loadlib (lua_State *L) * Macintosh, Windows * http://www.stat.umn.edu/~luke/xls/projects/dlbasics/dlbasics.html * -* Mac OS X/Darwin -* http://www.opendarwin.org/projects/dlcompat/ -* * GLIB has wrapper code for BeOS, OS2, Unix and Windows * http://cvs.gnome.org/lxr/source/glib/gmodule/ * diff --git a/src/lib/loslib.c b/src/lib/loslib.c index c5726cfe..4f1d2d03 100644 --- a/src/lib/loslib.c +++ b/src/lib/loslib.c @@ -1,5 +1,5 @@ /* -** $Id: loslib.c,v 1.2 2004/08/05 19:30:37 roberto Exp $ +** $Id: loslib.c,v 1.3 2004/10/08 18:57:16 roberto Exp $ ** Standard Operating System library ** See Copyright Notice in lua.h */ @@ -20,7 +20,7 @@ #include "lualib.h" -static int pushresult (lua_State *L, int i, const char *filename) { +static int os_pushresult (lua_State *L, int i, const char *filename) { if (i) { lua_pushboolean(L, 1); return 1; @@ -45,14 +45,14 @@ static int io_execute (lua_State *L) { static int io_remove (lua_State *L) { const char *filename = luaL_checkstring(L, 1); - return pushresult(L, remove(filename) == 0, filename); + return os_pushresult(L, remove(filename) == 0, filename); } static int io_rename (lua_State *L) { const char *fromname = luaL_checkstring(L, 1); const char *toname = luaL_checkstring(L, 2); - return pushresult(L, rename(fromname, toname) == 0, fromname); + return os_pushresult(L, rename(fromname, toname) == 0, fromname); } diff --git a/src/lib/lstrlib.c b/src/lib/lstrlib.c index 7fa205c0..a9c002fb 100644 --- a/src/lib/lstrlib.c +++ b/src/lib/lstrlib.c @@ -1,5 +1,5 @@ /* -** $Id: lstrlib.c,v 1.106 2004/08/09 13:30:33 roberto Exp $ +** $Id: lstrlib.c,v 1.109 2004/12/01 15:46:06 roberto Exp $ ** Standard library for string operations and pattern-matching ** See Copyright Notice in lua.h */ @@ -24,8 +24,6 @@ #define uchar(c) ((unsigned char)(c)) -typedef lua_Integer sint32; /* a signed version for size_t */ - static int str_len (lua_State *L) { size_t l; @@ -35,19 +33,19 @@ static int str_len (lua_State *L) { } -static sint32 posrelat (sint32 pos, size_t len) { +static ptrdiff_t posrelat (ptrdiff_t pos, size_t len) { /* relative string position: negative means back from end */ - return (pos>=0) ? pos : (sint32)len+pos+1; + return (pos>=0) ? pos : (ptrdiff_t)len+pos+1; } static int str_sub (lua_State *L) { size_t l; const char *s = luaL_checklstring(L, 1, &l); - sint32 start = posrelat(luaL_checkinteger(L, 2), l); - sint32 end = posrelat(luaL_optinteger(L, 3, -1), l); + ptrdiff_t start = posrelat(luaL_checkinteger(L, 2), l); + ptrdiff_t end = posrelat(luaL_optinteger(L, 3, -1), l); if (start < 1) start = 1; - if (end > (sint32)l) end = (sint32)l; + if (end > (ptrdiff_t)l) end = (ptrdiff_t)l; if (start <= end) lua_pushlstring(L, s+start-1, end-start+1); else lua_pushliteral(L, ""); @@ -107,8 +105,8 @@ static int str_rep (lua_State *L) { static int str_byte (lua_State *L) { size_t l; const char *s = luaL_checklstring(L, 1, &l); - sint32 posi = posrelat(luaL_optinteger(L, 2, 1), l); - sint32 pose = posrelat(luaL_optinteger(L, 3, posi), l); + ptrdiff_t posi = posrelat(luaL_optinteger(L, 2, 1), l); + ptrdiff_t pose = posrelat(luaL_optinteger(L, 3, posi), l); int n, i; if (posi <= 0) posi = 1; if ((size_t)pose > l) pose = l; @@ -173,7 +171,7 @@ typedef struct MatchState { int level; /* total number of captures (finished or unfinished) */ struct { const char *init; - sint32 len; + ptrdiff_t len; } capture[MAX_CAPTURES]; } MatchState; @@ -198,7 +196,7 @@ static int capture_to_close (MatchState *ms) { } -static const char *luaI_classend (MatchState *ms, const char *p) { +static const char *classend (MatchState *ms, const char *p) { switch (*p++) { case ESC: { if (*p == '\0') @@ -250,7 +248,7 @@ static int matchbracketclass (int c, const char *p, const char *ec) { while (++p < ec) { if (*p == ESC) { p++; - if (match_class(c, *p)) + if (match_class(c, uchar(*p))) return sig; } else if ((*(p+1) == '-') && (p+2 < ec)) { @@ -264,10 +262,10 @@ static int matchbracketclass (int c, const char *p, const char *ec) { } -static int luaI_singlematch (int c, const char *p, const char *ep) { +static int singlematch (int c, const char *p, const char *ep) { switch (*p) { case '.': return 1; /* matches any char */ - case ESC: return match_class(c, *(p+1)); + case ESC: return match_class(c, uchar(*(p+1))); case '[': return matchbracketclass(c, p, ep-1); default: return (uchar(*p) == c); } @@ -299,8 +297,8 @@ static const char *matchbalance (MatchState *ms, const char *s, static const char *max_expand (MatchState *ms, const char *s, const char *p, const char *ep) { - sint32 i = 0; /* counts maximum expand for item */ - while ((s+i)<ms->src_end && luaI_singlematch(uchar(*(s+i)), p, ep)) + ptrdiff_t i = 0; /* counts maximum expand for item */ + while ((s+i)<ms->src_end && singlematch(uchar(*(s+i)), p, ep)) i++; /* keeps trying to match with the maximum repetitions */ while (i>=0) { @@ -318,7 +316,7 @@ static const char *min_expand (MatchState *ms, const char *s, const char *res = match(ms, s, ep+1); if (res != NULL) return res; - else if (s<ms->src_end && luaI_singlematch(uchar(*s), p, ep)) + else if (s<ms->src_end && singlematch(uchar(*s), p, ep)) s++; /* try with one more repetition */ else return NULL; } @@ -385,7 +383,7 @@ static const char *match (MatchState *ms, const char *s, const char *p) { p += 2; if (*p != '[') luaL_error(ms->L, "missing `[' after `%%f' in pattern"); - ep = luaI_classend(ms, p); /* points to what is next */ + ep = classend(ms, p); /* points to what is next */ previous = (s == ms->src_init) ? '\0' : *(s-1); if (matchbracketclass(uchar(previous), p, ep-1) || !matchbracketclass(uchar(*s), p, ep-1)) return NULL; @@ -393,7 +391,7 @@ static const char *match (MatchState *ms, const char *s, const char *p) { } default: { if (isdigit(uchar(*(p+1)))) { /* capture results (%0-%9)? */ - s = match_capture(ms, s, *(p+1)); + s = match_capture(ms, s, uchar(*(p+1))); if (s == NULL) return NULL; p+=2; goto init; /* else return match(ms, s, p+2) */ } @@ -410,8 +408,8 @@ static const char *match (MatchState *ms, const char *s, const char *p) { else goto dflt; } default: dflt: { /* it is a pattern item */ - const char *ep = luaI_classend(ms, p); /* points to what is next */ - int m = s<ms->src_end && luaI_singlematch(uchar(*s), p, ep); + const char *ep = classend(ms, p); /* points to what is next */ + int m = s<ms->src_end && singlematch(uchar(*s), p, ep); switch (*ep) { case '?': { /* optional */ const char *res; @@ -490,9 +488,9 @@ static int str_find (lua_State *L) { size_t l1, l2; const char *s = luaL_checklstring(L, 1, &l1); const char *p = luaL_checklstring(L, 2, &l2); - sint32 init = posrelat(luaL_optinteger(L, 3, 1), l1) - 1; + ptrdiff_t init = posrelat(luaL_optinteger(L, 3, 1), l1) - 1; if (init < 0) init = 0; - else if ((size_t)(init) > l1) init = (sint32)l1; + else if ((size_t)(init) > l1) init = (ptrdiff_t)l1; if (lua_toboolean(L, 4) || /* explicit request? */ strpbrk(p, SPECIALS) == NULL) { /* or no special characters? */ /* do a plain search */ @@ -642,7 +640,7 @@ static int str_gsub (lua_State *L) { #define MAX_FORMAT 20 -static void luaI_addquoted (lua_State *L, luaL_Buffer *b, int arg) { +static void addquoted (lua_State *L, luaL_Buffer *b, int arg) { size_t l; const char *s = luaL_checklstring(L, arg, &l); luaL_putchar(b, '"'); @@ -726,7 +724,7 @@ static int str_format (lua_State *L) { break; } case 'q': { - luaI_addquoted(L, &b, arg); + addquoted(L, &b, arg); continue; /* skip the `addsize' at the end */ } case 's': { |
