diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2004-12-22 15:43:27 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2004-12-22 15:43:27 -0200 |
commit | 96727c61b87d199b51a3ebb707255e79d5ed1b84 (patch) | |
tree | c99da1452411280bb649910908ac58a32df93197 /loadlib.c | |
parent | d5ebc3ff6de4b5f7019bb887e917e00cb3a0a899 (diff) | |
download | lua-96727c61b87d199b51a3ebb707255e79d5ed1b84.tar.gz lua-96727c61b87d199b51a3ebb707255e79d5ed1b84.tar.bz2 lua-96727c61b87d199b51a3ebb707255e79d5ed1b84.zip |
several improvements/corrections
Diffstat (limited to 'loadlib.c')
-rw-r--r-- | loadlib.c | 173 |
1 files changed, 84 insertions, 89 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: loadlib.c,v 1.11 2004/11/19 15:52:12 roberto Exp roberto $ | 2 | ** $Id: loadlib.c,v 1.12 2004/12/13 12:14:21 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 | * |
@@ -58,26 +58,23 @@ static void registerlib (lua_State *L, const void *lib); | |||
58 | 58 | ||
59 | #define freelib dlclose | 59 | #define freelib dlclose |
60 | 60 | ||
61 | static int loadlib(lua_State *L, const char *path, const char *init) | 61 | static int loadlib(lua_State *L, const char *path, const char *init) { |
62 | { | 62 | void *lib=dlopen(path,RTLD_NOW); |
63 | void *lib=dlopen(path,RTLD_NOW); | 63 | if (lib != NULL) { |
64 | if (lib!=NULL) | 64 | lua_CFunction f=(lua_CFunction) dlsym(lib,init); |
65 | { | 65 | if (f != NULL) { |
66 | lua_CFunction f=(lua_CFunction) dlsym(lib,init); | 66 | registerlib(L, lib); |
67 | if (f!=NULL) | 67 | lua_pushcfunction(L,f); |
68 | { | 68 | return 0; |
69 | registerlib(L, lib); | 69 | } |
70 | lua_pushcfunction(L,f); | 70 | } |
71 | return 0; | 71 | /* else return appropriate error message */ |
72 | } | 72 | lua_pushstring(L,dlerror()); |
73 | } | 73 | if (lib != NULL) { |
74 | /* else return appropriate error message */ | 74 | dlclose(lib); |
75 | lua_pushstring(L,dlerror()); | 75 | return ERR_FUNCTION; /* error loading function */ |
76 | if (lib!=NULL) { | 76 | } |
77 | dlclose(lib); | 77 | else return ERR_OPEN; /* error loading library */ |
78 | return ERR_FUNCTION; /* error loading function */ | ||
79 | } | ||
80 | else return ERR_OPEN; /* error loading library */ | ||
81 | } | 78 | } |
82 | 79 | ||
83 | 80 | ||
@@ -91,36 +88,34 @@ static int loadlib(lua_State *L, const char *path, const char *init) | |||
91 | 88 | ||
92 | #define freelib(lib) FreeLibrary((HINSTANCE)lib) | 89 | #define freelib(lib) FreeLibrary((HINSTANCE)lib) |
93 | 90 | ||
94 | static void pusherror(lua_State *L) | 91 | |
95 | { | 92 | static void pusherror(lua_State *L) { |
96 | int error=GetLastError(); | 93 | int error = GetLastError(); |
97 | char buffer[128]; | 94 | char buffer[128]; |
98 | if (FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, | 95 | if (FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, |
99 | 0, error, 0, buffer, sizeof(buffer), 0)) | 96 | 0, error, 0, buffer, sizeof(buffer), 0)) |
100 | lua_pushstring(L,buffer); | 97 | lua_pushstring(L,buffer); |
101 | else | 98 | else |
102 | lua_pushfstring(L,"system error %d\n",error); | 99 | lua_pushfstring(L, "system error %d\n", error); |
103 | } | 100 | } |
104 | 101 | ||
105 | static int loadlib(lua_State *L, const char *path, const char *init) | 102 | |
106 | { | 103 | static int loadlib (lua_State *L, const char *path, const char *init) { |
107 | HINSTANCE lib=LoadLibrary(path); | 104 | HINSTANCE lib = LoadLibrary(path); |
108 | if (lib!=NULL) | 105 | if (lib != NULL) { |
109 | { | 106 | lua_CFunction f = (lua_CFunction)GetProcAddress(lib, init); |
110 | lua_CFunction f=(lua_CFunction) GetProcAddress(lib,init); | 107 | if (f != NULL) { |
111 | if (f!=NULL) | 108 | registerlib(L, lib); |
112 | { | 109 | lua_pushcfunction(L, f); |
113 | registerlib(L, lib); | 110 | return 0; |
114 | lua_pushcfunction(L,f); | 111 | } |
115 | return 1; | ||
116 | } | 112 | } |
117 | } | 113 | pusherror(L); |
118 | pusherror(L); | 114 | if (lib != NULL) { |
119 | if (lib!=NULL) { | 115 | FreeLibrary(lib); |
120 | FreeLibrary(lib); | 116 | return ERR_OPEN; |
121 | return ERR_OPEN; | 117 | } |
122 | } | 118 | else return ERR_FUNCTION; |
123 | else return ERR_FUNCTION; | ||
124 | } | 119 | } |
125 | 120 | ||
126 | 121 | ||
@@ -134,21 +129,22 @@ static int loadlib(lua_State *L, const char *path, const char *init) | |||
134 | /* Mach cannot unload images (?) */ | 129 | /* Mach cannot unload images (?) */ |
135 | #define freelib(lib) ((void)lib) | 130 | #define freelib(lib) ((void)lib) |
136 | 131 | ||
137 | static void pusherror (lua_State *L) | 132 | |
138 | { | 133 | static void pusherror (lua_State *L) { |
139 | const char *err_str; | 134 | const char *err_str; |
140 | const char *err_file; | 135 | const char *err_file; |
141 | NSLinkEditErrors err; | 136 | NSLinkEditErrors err; |
142 | int err_num; | 137 | int err_num; |
143 | NSLinkEditError(&err, &err_num, &err_file, &err_str); | 138 | NSLinkEditError(&err, &err_num, &err_file, &err_str); |
144 | lua_pushstring(L, err_str); | 139 | lua_pushstring(L, err_str); |
145 | } | 140 | } |
146 | 141 | ||
142 | |||
147 | static int loadlib (lua_State *L, const char *path, const char *init) { | 143 | static int loadlib (lua_State *L, const char *path, const char *init) { |
148 | const struct mach_header *lib; | 144 | const struct mach_header *lib; |
149 | /* this would be a rare case, but prevents crashing if it happens */ | 145 | /* this would be a rare case, but prevents crashing if it happens */ |
150 | if(!_dyld_present()) { | 146 | if(!_dyld_present()) { |
151 | lua_pushstring(L,"dyld not present."); | 147 | lua_pushstring(L, "dyld not present."); |
152 | return ERR_OPEN; | 148 | return ERR_OPEN; |
153 | } | 149 | } |
154 | lib = NSAddImage(path, NSADDIMAGE_OPTION_RETURN_ON_ERROR); | 150 | lib = NSAddImage(path, NSADDIMAGE_OPTION_RETURN_ON_ERROR); |
@@ -159,7 +155,7 @@ static int loadlib (lua_State *L, const char *path, const char *init) { | |||
159 | if(init_sym != NULL) { | 155 | if(init_sym != NULL) { |
160 | lua_CFunction f = (lua_CFunction)NSAddressOfSymbol(init_sym); | 156 | lua_CFunction f = (lua_CFunction)NSAddressOfSymbol(init_sym); |
161 | registerlib(L, lib); | 157 | registerlib(L, lib); |
162 | lua_pushcfunction(L,f); | 158 | lua_pushcfunction(L, f); |
163 | return 0; | 159 | return 0; |
164 | } | 160 | } |
165 | } | 161 | } |
@@ -177,11 +173,10 @@ static int loadlib (lua_State *L, const char *path, const char *init) { | |||
177 | 173 | ||
178 | #define freelib(lib) ((void)lib) | 174 | #define freelib(lib) ((void)lib) |
179 | 175 | ||
180 | static int loadlib(lua_State *L, const char *path, const char *init) | 176 | static int loadlib (lua_State *L, const char *path, const char *init) { |
181 | { | 177 | (void)path; (void)init; (void)®isterlib; /* to avoid warnings */ |
182 | (void)path; (void)init; (void)®isterlib; /* to avoid warnings */ | 178 | lua_pushliteral(L,"`loadlib' not supported"); |
183 | lua_pushliteral(L,"`loadlib' not supported"); | 179 | return ERR_ABSENT; |
184 | return ERR_ABSENT; | ||
185 | } | 180 | } |
186 | 181 | ||
187 | #endif | 182 | #endif |
@@ -192,41 +187,39 @@ static int loadlib(lua_State *L, const char *path, const char *init) | |||
192 | ** so that, when Lua closes its state, the library's __gc metamethod | 187 | ** so that, when Lua closes its state, the library's __gc metamethod |
193 | ** will be called to unload the library. | 188 | ** will be called to unload the library. |
194 | */ | 189 | */ |
195 | static void registerlib (lua_State *L, const void *lib) | 190 | static void registerlib (lua_State *L, const void *lib) { |
196 | { | 191 | const void **plib = (const void **)lua_newuserdata(L, sizeof(const void *)); |
197 | const void **plib = (const void **)lua_newuserdata(L, sizeof(const void *)); | 192 | *plib = lib; |
198 | *plib = lib; | 193 | luaL_getmetatable(L, "_LOADLIB"); |
199 | luaL_getmetatable(L, "_LOADLIB"); | 194 | lua_setmetatable(L, -2); |
200 | lua_setmetatable(L, -2); | 195 | lua_pushboolean(L, 1); |
201 | lua_pushboolean(L, 1); | 196 | lua_settable(L, LUA_REGISTRYINDEX); /* registry[lib] = true */ |
202 | lua_settable(L, LUA_REGISTRYINDEX); /* registry[lib] = true */ | ||
203 | } | 197 | } |
204 | 198 | ||
205 | /* | 199 | /* |
206 | ** __gc tag method: calls library's `freelib' function with the lib | 200 | ** __gc tag method: calls library's `freelib' function with the lib |
207 | ** handle | 201 | ** handle |
208 | */ | 202 | */ |
209 | static int gctm (lua_State *L) | 203 | static int gctm (lua_State *L) { |
210 | { | 204 | void *lib = *(void **)luaL_checkudata(L, 1, "_LOADLIB"); |
211 | void *lib = *(void **)luaL_checkudata(L, 1, "_LOADLIB"); | 205 | freelib(lib); |
212 | freelib(lib); | 206 | return 0; |
213 | return 0; | ||
214 | } | 207 | } |
215 | 208 | ||
216 | 209 | ||
217 | static int ll_loadlib (lua_State *L) { | 210 | static int ll_loadlib (lua_State *L) { |
218 | static const char *const errcodes[] = {NULL, "open", "init", "absent"}; | 211 | static const char *const errcodes[] = {NULL, "open", "init", "absent"}; |
219 | const char *path=luaL_checkstring(L,1); | 212 | const char *path = luaL_checkstring(L, 1); |
220 | const char *init=luaL_checkstring(L,2); | 213 | const char *init = luaL_checkstring(L, 2); |
221 | int res = loadlib(L,path,init); | 214 | int res = loadlib(L,path,init); |
222 | if (res == 0) /* no error? */ | 215 | if (res == 0) /* no error? */ |
223 | return 1; /* function is at stack top */ | 216 | return 1; /* function is at stack top */ |
224 | else { /* error */ | 217 | else { /* error */ |
225 | lua_pushnil(L); | 218 | lua_pushnil(L); |
226 | lua_insert(L,-2); /* insert nil before error message */ | 219 | lua_insert(L, -2); /* insert nil before error message */ |
227 | lua_pushstring(L, errcodes[res]); | 220 | lua_pushstring(L, errcodes[res]); |
228 | return 3; | 221 | return 3; |
229 | } | 222 | } |
230 | } | 223 | } |
231 | 224 | ||
232 | 225 | ||
@@ -264,7 +257,7 @@ static const char *loadC (lua_State *L, const char *fname, const char *name) { | |||
264 | luaL_getfield(L, LUA_GLOBALSINDEX, "package.cpath"); | 257 | luaL_getfield(L, LUA_GLOBALSINDEX, "package.cpath"); |
265 | path = lua_tostring(L, -1); | 258 | path = lua_tostring(L, -1); |
266 | if (path == NULL) | 259 | if (path == NULL) |
267 | luaL_error(L, "global _CPATH must be a string"); | 260 | luaL_error(L, "`package.cpath' must be a string"); |
268 | fname = luaL_searchpath(L, fname, path); | 261 | fname = luaL_searchpath(L, fname, path); |
269 | if (fname == NULL) return path; /* library not found in this path */ | 262 | if (fname == NULL) return path; /* library not found in this path */ |
270 | funcname = luaL_gsub(L, name, ".", LUA_OFSEP); | 263 | funcname = luaL_gsub(L, name, ".", LUA_OFSEP); |
@@ -346,6 +339,8 @@ static int ll_module (lua_State *L) { | |||
346 | lua_pushvalue(L, LUA_GLOBALSINDEX); | 339 | lua_pushvalue(L, LUA_GLOBALSINDEX); |
347 | lua_setfield(L, -2, "__index"); /* mt.__index = _G */ | 340 | lua_setfield(L, -2, "__index"); /* mt.__index = _G */ |
348 | lua_setmetatable(L, -2); | 341 | lua_setmetatable(L, -2); |
342 | lua_pushvalue(L, -1); | ||
343 | lua_setfield(L, -2, "_M"); /* module._M = module */ | ||
349 | lua_pushstring(L, modname); | 344 | lua_pushstring(L, modname); |
350 | lua_setfield(L, -2, "_NAME"); | 345 | lua_setfield(L, -2, "_NAME"); |
351 | dot = strrchr(modname, '.'); /* look for last dot in module name */ | 346 | dot = strrchr(modname, '.'); /* look for last dot in module name */ |