diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2004-10-07 14:27:20 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2004-10-07 14:27:20 -0300 |
commit | 3bec76abe350ef610996b850a1b9c9bbdd46ee6b (patch) | |
tree | 8327be802e309b7e866ab8c2bef1f84a9a4bbfd7 | |
parent | 5cb6037d49cbbde936505a705e37d4962c91b28a (diff) | |
download | lua-3bec76abe350ef610996b850a1b9c9bbdd46ee6b.tar.gz lua-3bec76abe350ef610996b850a1b9c9bbdd46ee6b.tar.bz2 lua-3bec76abe350ef610996b850a1b9c9bbdd46ee6b.zip |
first version of loadlib for Mac OS X (not tested yet!!)
-rw-r--r-- | loadlib.c | 88 |
1 files changed, 66 insertions, 22 deletions
@@ -1,29 +1,28 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: loadlib.c,v 1.5 2003/05/14 21:01:53 roberto Exp roberto $ | 2 | ** $Id: loadlib.c,v 1.6 2004/04/30 20:13:38 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 | * |
6 | * This Lua library exports a single function, called loadlib, which is | 6 | * This Lua library exports a single function, called loadlib, which |
7 | * called from Lua as loadlib(lib,init), where lib is the full name of the | 7 | * is called from Lua as loadlib(lib,init), where lib is the full |
8 | * library to be loaded (including the complete path) and init is the name | 8 | * name of the library to be loaded (including the complete path) and |
9 | * of a function to be called after the library is loaded. Typically, this | 9 | * init is the name of a function to be called after the library is |
10 | * function will register other functions, thus making the complete library | 10 | * loaded. Typically, this function will register other functions, thus |
11 | * available to Lua. The init function is *not* automatically called by | 11 | * making the complete library available to Lua. The init function is |
12 | * loadlib. Instead, loadlib returns the init function as a Lua function | 12 | * *not* automatically called by loadlib. Instead, loadlib returns the |
13 | * that the client can call when it thinks is appropriate. In the case of | 13 | * init function as a Lua function that the client can call when it |
14 | * errors, loadlib returns nil and two strings describing the error. | 14 | * thinks is appropriate. In the case of errors, loadlib returns nil and |
15 | * The first string is supplied by the operating system; it should be | 15 | * two strings describing the error. The first string is supplied by |
16 | * informative and useful for error messages. The second string is "open", | 16 | * the operating system; it should be informative and useful for error |
17 | * "init", or "absent" to identify the error and is meant to be used for | 17 | * messages. The second string is "open", "init", or "absent" to identify |
18 | * making decisions without having to look into the first string (whose | 18 | * the error and is meant to be used for making decisions without having |
19 | * format is system-dependent). | 19 | * to look into the first string (whose format is system-dependent). |
20 | * | 20 | * This module contains an implementation of loadlib for Unix systems |
21 | * This module contains an implementation of loadlib for Unix systems that | 21 | * that have dlfcn, an implementation for Darwin (Mac OS X), an |
22 | * have dlfcn, an implementation for Windows, and a stub for other systems. | 22 | * implementation for Windows, and a stub for other systems. See |
23 | * See the list at the end of this file for some links to available | 23 | * the list at the end of this file for some links to available |
24 | * implementations of dlfcn and interfaces to other native dynamic loaders | 24 | * implementations of dlfcn and interfaces to other native dynamic |
25 | * on top of which loadlib could be implemented. | 25 | * loaders on top of which loadlib could be implemented. |
26 | * | ||
27 | */ | 26 | */ |
28 | 27 | ||
29 | #define loadlib_c | 28 | #define loadlib_c |
@@ -130,6 +129,51 @@ static int loadlib(lua_State *L) | |||
130 | 129 | ||
131 | #endif | 130 | #endif |
132 | 131 | ||
132 | /* Native Mac OS X / Darwin Implementation */ | ||
133 | #ifdef USE_DYLD | ||
134 | #define LOADLIB | ||
135 | |||
136 | #include <mach-o/dyld.h> | ||
137 | |||
138 | static int loadlib (lua_State *L) { | ||
139 | const char * err_str; | ||
140 | const char * err_file; | ||
141 | NSLinkEditErrors err; | ||
142 | int err_num; | ||
143 | const char *path=luaL_checkstring(L,1); | ||
144 | const char *init=luaL_checkstring(L,2); | ||
145 | const struct mach_header *lib; | ||
146 | /* this would be a rare case, but prevents crashing if it happens */ | ||
147 | if(!_dyld_present()) { | ||
148 | lua_pushnil(L); | ||
149 | lua_pushstring(L,"dyld not present."); | ||
150 | lua_pushstring(L,"absent"); | ||
151 | return 3; | ||
152 | } | ||
153 | |||
154 | lib = NSAddImage(path, NSADDIMAGE_OPTION_RETURN_ON_ERROR); | ||
155 | if(lib != NULL) { | ||
156 | NSSymbol init_sym = NSLookupSymbolInImage(lib, init, | ||
157 | NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | | ||
158 | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR); | ||
159 | if(init_sym != NULL) { | ||
160 | lua_CFunction f = (lua_CFunction)NSAddressOfSymbol(init_sym); | ||
161 | lua_pushlightuserdata(L,(void *)lib); | ||
162 | lua_pushcclosure(L,f,1); | ||
163 | return 1; | ||
164 | } | ||
165 | } | ||
166 | /* else an error ocurred */ | ||
167 | NSLinkEditError(&err, &err_num, &err_file, &err_str); | ||
168 | lua_pushnil(L); | ||
169 | lua_pushstring(L, err_str); | ||
170 | lua_pushstring(L, (lib != NULL) ? "init" : "open"); | ||
171 | /* Can't unload image */ | ||
172 | return 3; | ||
173 | } | ||
174 | |||
175 | #endif | ||
176 | |||
133 | 177 | ||
134 | 178 | ||
135 | #ifndef LOADLIB | 179 | #ifndef LOADLIB |