diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2004-11-11 13:42:57 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2004-11-11 13:42:57 -0200 |
| commit | 2ed07ea8c1912a6e2c44924764934fe30f6b9db2 (patch) | |
| tree | 59c1b3f8932e3af8c2681d526b6cb9fe245b5a69 | |
| parent | cfd7bc478f21494c254a8ed514271dbe655721b0 (diff) | |
| download | lua-2ed07ea8c1912a6e2c44924764934fe30f6b9db2.tar.gz lua-2ed07ea8c1912a6e2c44924764934fe30f6b9db2.tar.bz2 lua-2ed07ea8c1912a6e2c44924764934fe30f6b9db2.zip | |
towards "requiring" C libraries
| -rw-r--r-- | loadlib.c | 67 |
1 files changed, 39 insertions, 28 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: loadlib.c,v 1.7 2004/10/07 17:27:20 roberto Exp roberto $ | 2 | ** $Id: loadlib.c,v 1.8 2004/10/18 18:07:31 roberto Exp roberto $ |
| 3 | ** Dynamic library loader for Lua | 3 | ** Dynamic library loader for Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | * | 5 | * |
| @@ -33,6 +33,10 @@ | |||
| 33 | #include "lualib.h" | 33 | #include "lualib.h" |
| 34 | 34 | ||
| 35 | 35 | ||
| 36 | #define ERR_OPEN 1 | ||
| 37 | #define ERR_FUNCTION 2 | ||
| 38 | |||
| 39 | |||
| 36 | static void registerlib (lua_State *L, const void *lib); | 40 | static void registerlib (lua_State *L, const void *lib); |
| 37 | 41 | ||
| 38 | 42 | ||
| @@ -48,10 +52,8 @@ static void registerlib (lua_State *L, const void *lib); | |||
| 48 | 52 | ||
| 49 | #define freelib dlclose | 53 | #define freelib dlclose |
| 50 | 54 | ||
| 51 | static int loadlib(lua_State *L) | 55 | static int loadlib(lua_State *L, const char *path, const char *init) |
| 52 | { | 56 | { |
| 53 | const char *path=luaL_checkstring(L,1); | ||
| 54 | const char *init=luaL_checkstring(L,2); | ||
| 55 | void *lib=dlopen(path,RTLD_NOW); | 57 | void *lib=dlopen(path,RTLD_NOW); |
| 56 | if (lib!=NULL) | 58 | if (lib!=NULL) |
| 57 | { | 59 | { |
| @@ -60,15 +62,16 @@ static int loadlib(lua_State *L) | |||
| 60 | { | 62 | { |
| 61 | registerlib(L, lib); | 63 | registerlib(L, lib); |
| 62 | lua_pushcfunction(L,f); | 64 | lua_pushcfunction(L,f); |
| 63 | return 1; | 65 | return 0; |
| 64 | } | 66 | } |
| 65 | } | 67 | } |
| 66 | /* else return appropriate error messages */ | 68 | /* else return appropriate error message */ |
| 67 | lua_pushnil(L); | ||
| 68 | lua_pushstring(L,dlerror()); | 69 | lua_pushstring(L,dlerror()); |
| 69 | lua_pushstring(L,(lib!=NULL) ? "init" : "open"); | 70 | if (lib!=NULL) { |
| 70 | if (lib!=NULL) dlclose(lib); | 71 | dlclose(lib); |
| 71 | return 3; | 72 | return ERR_FUNCTION; /* error loading function */ |
| 73 | } | ||
| 74 | else return ERR_OPEN; /* error loading library */ | ||
| 72 | } | 75 | } |
| 73 | 76 | ||
| 74 | 77 | ||
| @@ -93,10 +96,8 @@ static void pusherror(lua_State *L) | |||
| 93 | lua_pushfstring(L,"system error %d\n",error); | 96 | lua_pushfstring(L,"system error %d\n",error); |
| 94 | } | 97 | } |
| 95 | 98 | ||
| 96 | static int loadlib(lua_State *L) | 99 | static int loadlib(lua_State *L, const char *path, const char *init) |
| 97 | { | 100 | { |
| 98 | const char *path=luaL_checkstring(L,1); | ||
| 99 | const char *init=luaL_checkstring(L,2); | ||
| 100 | HINSTANCE lib=LoadLibrary(path); | 101 | HINSTANCE lib=LoadLibrary(path); |
| 101 | if (lib!=NULL) | 102 | if (lib!=NULL) |
| 102 | { | 103 | { |
| @@ -108,11 +109,12 @@ static int loadlib(lua_State *L) | |||
| 108 | return 1; | 109 | return 1; |
| 109 | } | 110 | } |
| 110 | } | 111 | } |
| 111 | lua_pushnil(L); | ||
| 112 | pusherror(L); | 112 | pusherror(L); |
| 113 | lua_pushstring(L,(lib!=NULL) ? "init" : "open"); | 113 | if (lib!=NULL) { |
| 114 | if (lib!=NULL) FreeLibrary(lib); | 114 | FreeLibrary(lib); |
| 115 | return 3; | 115 | return ERR_OPEN; |
| 116 | } | ||
| 117 | else return ERR_FUNCTION; | ||
| 116 | } | 118 | } |
| 117 | 119 | ||
| 118 | 120 | ||
| @@ -136,16 +138,12 @@ static void pusherror (lua_State *L) | |||
| 136 | lua_pushstring(L, err_str); | 138 | lua_pushstring(L, err_str); |
| 137 | } | 139 | } |
| 138 | 140 | ||
| 139 | static int loadlib (lua_State *L) { | 141 | static int loadlib (lua_State *L, const char *path, const char *init) { |
| 140 | const char *path=luaL_checkstring(L,1); | ||
| 141 | const char *init=luaL_checkstring(L,2); | ||
| 142 | const struct mach_header *lib; | 142 | const struct mach_header *lib; |
| 143 | /* this would be a rare case, but prevents crashing if it happens */ | 143 | /* this would be a rare case, but prevents crashing if it happens */ |
| 144 | if(!_dyld_present()) { | 144 | if(!_dyld_present()) { |
| 145 | lua_pushnil(L); | ||
| 146 | lua_pushstring(L,"dyld not present."); | 145 | lua_pushstring(L,"dyld not present."); |
| 147 | lua_pushstring(L,"absent"); | 146 | return ERR_OPEN; |
| 148 | return 3; | ||
| 149 | } | 147 | } |
| 150 | lib = NSAddImage(path, NSADDIMAGE_OPTION_RETURN_ON_ERROR); | 148 | lib = NSAddImage(path, NSADDIMAGE_OPTION_RETURN_ON_ERROR); |
| 151 | if(lib != NULL) { | 149 | if(lib != NULL) { |
| @@ -156,15 +154,13 @@ static int loadlib (lua_State *L) { | |||
| 156 | lua_CFunction f = (lua_CFunction)NSAddressOfSymbol(init_sym); | 154 | lua_CFunction f = (lua_CFunction)NSAddressOfSymbol(init_sym); |
| 157 | registerlib(L, lib); | 155 | registerlib(L, lib); |
| 158 | lua_pushcfunction(L,f); | 156 | lua_pushcfunction(L,f); |
| 159 | return 1; | 157 | return 0; |
| 160 | } | 158 | } |
| 161 | } | 159 | } |
| 162 | /* else an error ocurred */ | 160 | /* else an error ocurred */ |
| 163 | lua_pushnil(L); | ||
| 164 | pusherror(L); | 161 | pusherror(L); |
| 165 | lua_pushstring(L, (lib != NULL) ? "init" : "open"); | ||
| 166 | /* Can't unload image */ | 162 | /* Can't unload image */ |
| 167 | return 3; | 163 | return (lib != NULL) ? ERR_FUNCTION : ERR_OPEN; |
| 168 | } | 164 | } |
| 169 | 165 | ||
| 170 | 166 | ||
| @@ -213,12 +209,27 @@ static int gctm (lua_State *L) | |||
| 213 | return 0; | 209 | return 0; |
| 214 | } | 210 | } |
| 215 | 211 | ||
| 212 | |||
| 213 | static int loadlib1 (lua_State *L) { | ||
| 214 | const char *path=luaL_checkstring(L,1); | ||
| 215 | const char *init=luaL_checkstring(L,2); | ||
| 216 | int res = loadlib(L,path,init); | ||
| 217 | if (res == 0) /* no error? */ | ||
| 218 | return 1; /* function is at stack top */ | ||
| 219 | else { /* error */ | ||
| 220 | lua_pushnil(L); | ||
| 221 | lua_insert(L,-2); /* insert nil before error message */ | ||
| 222 | lua_pushstring(L, (res==ERR_OPEN)?"open":"init"); | ||
| 223 | return 3; | ||
| 224 | } | ||
| 225 | } | ||
| 226 | |||
| 216 | LUALIB_API int luaopen_loadlib (lua_State *L) | 227 | LUALIB_API int luaopen_loadlib (lua_State *L) |
| 217 | { | 228 | { |
| 218 | luaL_newmetatable(L, "_LOADLIB"); | 229 | luaL_newmetatable(L, "_LOADLIB"); |
| 219 | lua_pushcfunction(L, gctm); | 230 | lua_pushcfunction(L, gctm); |
| 220 | lua_setfield(L, -2, "__gc"); | 231 | lua_setfield(L, -2, "__gc"); |
| 221 | lua_register(L,"loadlib",loadlib); | 232 | lua_register(L,"loadlib",loadlib1); |
| 222 | return 0; | 233 | return 0; |
| 223 | } | 234 | } |
| 224 | 235 | ||
