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 | ||