Lua 5.1.4: loadlib.c
L0001
L0010
L0011
L0012 #include <stdlib.h>
L0013 #include <string.h>
L0014
L0015
L0016 #define loadlib_c
L0017 #define LUA_LIB
L0018
L0019 #include "lua.h"
L0020
L0021 #include "lauxlib.h"
L0022 #include "lualib.h"
L0023
L0024
L0025
L0026 #define LUA_POF "luaopen_"
L0027
L0028
L0029 #define LUA_OFSEP "_"
L0030
L0031
L0032 #define LIBPREFIX "LOADLIB: "
L0033
L0034 #define POF LUA_POF
L0035 #define LIB_FAIL "open"
L0036
L0037
L0038
L0039 #define ERRLIB 1
L0040 #define ERRFUNC 2
L0041
L0042 #define setprogdir(L) ((void)0)
L0043
L0044
L0045 static void ll_unloadlib (void *lib);
L0046 static void *ll_load (lua_State *L, const char *path);
L0047 static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym);
L0048
L0049
L0050
L0051 #if defined(LUA_DL_DLOPEN)
L0052
L0060
L0061 #include <dlfcn.h>
L0062
L0063 static void ll_unloadlib (void *lib) {
L0064 dlclose(lib);
L0065 }
L0066
L0067
L0068 static void *ll_load (lua_State *L, const char *path) {
L0069 void *lib = dlopen(path, RTLD_NOW);
L0070 if (lib == NULL) lua_pushstring(L, dlerror());
L0071 return lib;
L0072 }
L0073
L0074
L0075 static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
L0076 lua_CFunction f = (lua_CFunction)dlsym(lib, sym);
L0077 if (f == NULL) lua_pushstring(L, dlerror());
L0078 return f;
L0079 }
L0080
L0081
L0082
L0083
L0084
L0085 #elif defined(LUA_DL_DLL)
L0086
L0091
L0092 #include <windows.h>
L0093
L0094
L0095 #undef setprogdir
L0096
L0097 static void setprogdir (lua_State *L) {
L0098 char buff[MAX_PATH + 1];
L0099 char *lb;
L0100 DWORD nsize = sizeof(buff)/sizeof(char);
L0101 DWORD n = GetModuleFileNameA(NULL, buff, nsize);
L0102 if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL)
L0103 luaL_error(L, "unable to get ModuleFileName");
L0104 else {
L0105 *lb = '\0';
L0106 luaL_gsub(L, lua_tostring(L, -1), LUA_EXECDIR, buff);
L0107 lua_remove(L, -2); /* remove original string */
L0108 }
L0109 }
L0110
L0111
L0112 static void pusherror (lua_State *L) {
L0113 int error = GetLastError();
L0114 char buffer[128];
L0115 if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
L0116 NULL, error, 0, buffer, sizeof(buffer), NULL))
L0117 lua_pushstring(L, buffer);
L0118 else
L0119 lua_pushfstring(L, "system error %d\n", error);
L0120 }
L0121
L0122 static void ll_unloadlib (void *lib) {
L0123 FreeLibrary((HINSTANCE)lib);
L0124 }
L0125
L0126
L0127 static void *ll_load (lua_State *L, const char *path) {
L0128 HINSTANCE lib = LoadLibraryA(path);
L0129 if (lib == NULL) pusherror(L);
L0130 return lib;
L0131 }
L0132
L0133
L0134 static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
L0135 lua_CFunction f = (lua_CFunction)GetProcAddress((HINSTANCE)lib, sym);
L0136 if (f == NULL) pusherror(L);
L0137 return f;
L0138 }
L0139
L0140 /* }====================================================== */
L0141
L0142
L0143
L0144 #elif defined(LUA_DL_DYLD)
L0145 /*
L0146 ** {======================================================================
L0147 ** Native Mac OS X / Darwin Implementation
L0148 ** =======================================================================
L0149 */
L0150
L0151 #include <mach-o/dyld.h>
L0152
L0153
L0154 /* Mac appends a `_' before C function names */
L0155 #undef POF
L0156 #define POF "_" LUA_POF
L0157
L0158
L0159 static void pusherror (lua_State *L) {
L0160 const char *err_str;
L0161 const char *err_file;
L0162 NSLinkEditErrors err;
L0163 int err_num;
L0164 NSLinkEditError(&err, &err_num, &err_file, &err_str);
L0165 lua_pushstring(L, err_str);
L0166 }
L0167
L0168
L0169 static const char *errorfromcode (NSObjectFileImageReturnCode ret) {
L0170 switch (ret) {
L0171 case NSObjectFileImageInappropriateFile:
L0172 return "file is not a bundle";
L0173 case NSObjectFileImageArch:
L0174 return "library is for wrong CPU type";
L0175 case NSObjectFileImageFormat:
L0176 return "bad format";
L0177 case NSObjectFileImageAccess:
L0178 return "cannot access file";
L0179 case NSObjectFileImageFailure:
L0180 default:
L0181 return "unable to load library";
L0182 }
L0183 }
L0184
L0185
L0186 static void ll_unloadlib (void *lib) {
L0187 NSUnLinkModule((NSModule)lib, NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES);
L0188 }
L0189
L0190
L0191 static void *ll_load (lua_State *L, const char *path) {
L0192 NSObjectFileImage img;
L0193 NSObjectFileImageReturnCode ret;
L0194
L0195 if(!_dyld_present()) {
L0196 lua_pushliteral(L, "dyld not present");
L0197 return NULL;
L0198 }
L0199 ret = NSCreateObjectFileImageFromFile(path, &img);
L0200 if (ret == NSObjectFileImageSuccess) {
L0201 NSModule mod = NSLinkModule(img, path, NSLINKMODULE_OPTION_PRIVATE |
L0202 NSLINKMODULE_OPTION_RETURN_ON_ERROR);
L0203 NSDestroyObjectFileImage(img);
L0204 if (mod == NULL) pusherror(L);
L0205 return mod;
L0206 }
L0207 lua_pushstring(L, errorfromcode(ret));
L0208 return NULL;
L0209 }
L0210
L0211
L0212 static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
L0213 NSSymbol nss = NSLookupSymbolInModule((NSModule)lib, sym);
L0214 if (nss == NULL) {
L0215 lua_pushfstring(L, "symbol " LUA_QS " not found", sym);
L0216 return NULL;
L0217 }
L0218 return (lua_CFunction)NSAddressOfSymbol(nss);
L0219 }
L0220
L0221
L0222
L0223
L0224
L0225 #else
L0226
L0231
L0232 #undef LIB_FAIL
L0233 #define LIB_FAIL "absent"
L0234
L0235
L0236 #define DLMSG "dynamic libraries not enabled; check your Lua installation"
L0237
L0238
L0239 static void ll_unloadlib (void *lib) {
L0240 (void)lib;
L0241 }
L0242
L0243
L0244 static void *ll_load (lua_State *L, const char *path) {
L0245 (void)path;
L0246 lua_pushliteral(L, DLMSG);
L0247 return NULL;
L0248 }
L0249
L0250
L0251 static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
L0252 (void)lib; (void)sym;
L0253 lua_pushliteral(L, DLMSG);
L0254 return NULL;
L0255 }
L0256
L0257
L0258 #endif
L0259
L0260
L0261
L0262 static void **ll_register (lua_State *L, const char *path) {
L0263 void **plib;
L0264 lua_pushfstring(L, "%s%s", LIBPREFIX, path);
L0265 lua_gettable(L, LUA_REGISTRYINDEX);
L0266 if (!lua_isnil(L, -1))
L0267 plib = (void **)lua_touserdata(L, -1);
L0268 else {
L0269 lua_pop(L, 1);
L0270 plib = (void **)lua_newuserdata(L, sizeof(const void *));
L0271 *plib = NULL;
L0272 luaL_getmetatable(L, "_LOADLIB");
L0273 lua_setmetatable(L, -2);
L0274 lua_pushfstring(L, "%s%s", LIBPREFIX, path);
L0275 lua_pushvalue(L, -2);
L0276 lua_settable(L, LUA_REGISTRYINDEX);
L0277 }
L0278 return plib;
L0279 }
L0280
L0281
L0282
L0286 static int gctm (lua_State *L) {
L0287 void **lib = (void **)luaL_checkudata(L, 1, "_LOADLIB");
L0288 if (*lib) ll_unloadlib(*lib);
L0289 *lib = NULL;
L0290 return 0;
L0291 }
L0292
L0293
L0294 static int ll_loadfunc (lua_State *L, const char *path, const char *sym) {
L0295 void **reg = ll_register(L, path);
L0296 if (*reg == NULL) *reg = ll_load(L, path);
L0297 if (*reg == NULL)
L0298 return ERRLIB;
L0299 else {
L0300 lua_CFunction f = ll_sym(L, *reg, sym);
L0301 if (f == NULL)
L0302 return ERRFUNC;
L0303 lua_pushcfunction(L, f);
L0304 return 0;
L0305 }
L0306 }
L0307
L0308
L0309 static int ll_loadlib (lua_State *L) {
L0310 const char *path = luaL_checkstring(L, 1);
L0311 const char *init = luaL_checkstring(L, 2);
L0312 int stat = ll_loadfunc(L, path, init);
L0313 if (stat == 0)
L0314 return 1;
L0315 else {
L0316 lua_pushnil(L);
L0317 lua_insert(L, -2);
L0318 lua_pushstring(L, (stat == ERRLIB) ? LIB_FAIL : "init");
L0319 return 3;
L0320 }
L0321 }
L0322
L0323
L0324
L0325
L0330
L0331
L0332 static int readable (const char *filename) {
L0333 FILE *f = fopen(filename, "r");
L0334 if (f == NULL) return 0;
L0335 fclose(f);
L0336 return 1;
L0337 }
L0338
L0339
L0340 static const char *pushnexttemplate (lua_State *L, const char *path) {
L0341 const char *l;
L0342 while (*path == *LUA_PATHSEP) path++;
L0343 if (*path == '\0') return NULL;
L0344 l = strchr(path, *LUA_PATHSEP);
L0345 if (l == NULL) l = path + strlen(path);
L0346 lua_pushlstring(L, path, l - path);
L0347 return l;
L0348 }
L0349
L0350
L0351 static const char *findfile (lua_State *L, const char *name,
L0352 const char *pname) {
L0353 const char *path;
L0354 name = luaL_gsub(L, name, ".", LUA_DIRSEP);
L0355 lua_getfield(L, LUA_ENVIRONINDEX, pname);
L0356 path = lua_tostring(L, -1);
L0357 if (path == NULL)
L0358 luaL_error(L, LUA_QL("package.%s") " must be a string", pname);
L0359 lua_pushliteral(L, "");
L0360 while ((path = pushnexttemplate(L, path)) != NULL) {
L0361 const char *filename;
L0362 filename = luaL_gsub(L, lua_tostring(L, -1), LUA_PATH_MARK, name);
L0363 lua_remove(L, -2);
L0364 if (readable(filename))
L0365 return filename;
L0366 lua_pushfstring(L, "\n\tno file " LUA_QS, filename);
L0367 lua_remove(L, -2);
L0368 lua_concat(L, 2);
L0369 }
L0370 return NULL;
L0371 }
L0372
L0373
L0374 static void loaderror (lua_State *L, const char *filename) {
L0375 luaL_error(L, "error loading module " LUA_QS " from file " LUA_QS ":\n\t%s",
L0376 lua_tostring(L, 1), filename, lua_tostring(L, -1));
L0377 }
L0378
L0379
L0380 static int loader_Lua (lua_State *L) {
L0381 const char *filename;
L0382 const char *name = luaL_checkstring(L, 1);
L0383 filename = findfile(L, name, "path");
L0384 if (filename == NULL) return 1;
L0385 if (luaL_loadfile(L, filename) != 0)
L0386 loaderror(L, filename);
L0387 return 1;
L0388 }
L0389
L0390
L0391 static const char *mkfuncname (lua_State *L, const char *modname) {
L0392 const char *funcname;
L0393 const char *mark = strchr(modname, *LUA_IGMARK);
L0394 if (mark) modname = mark + 1;
L0395 funcname = luaL_gsub(L, modname, ".", LUA_OFSEP);
L0396 funcname = lua_pushfstring(L, POF"%s", funcname);
L0397 lua_remove(L, -2);
L0398 return funcname;
L0399 }
L0400
L0401
L0402 static int loader_C (lua_State *L) {
L0403 const char *funcname;
L0404 const char *name = luaL_checkstring(L, 1);
L0405 const char *filename = findfile(L, name, "cpath");
L0406 if (filename == NULL) return 1;
L0407 funcname = mkfuncname(L, name);
L0408 if (ll_loadfunc(L, filename, funcname) != 0)
L0409 loaderror(L, filename);
L0410 return 1;
L0411 }
L0412
L0413
L0414 static int loader_Croot (lua_State *L) {
L0415 const char *funcname;
L0416 const char *filename;
L0417 const char *name = luaL_checkstring(L, 1);
L0418 const char *p = strchr(name, '.');
L0419 int stat;
L0420 if (p == NULL) return 0;
L0421 lua_pushlstring(L, name, p - name);
L0422 filename = findfile(L, lua_tostring(L, -1), "cpath");
L0423 if (filename == NULL) return 1;
L0424 funcname = mkfuncname(L, name);
L0425 if ((stat = ll_loadfunc(L, filename, funcname)) != 0) {
L0426 if (stat != ERRFUNC) loaderror(L, filename);
L0427 lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS,
L0428 name, filename);
L0429 return 1;
L0430 }
L0431 return 1;
L0432 }
L0433
L0434
L0435 static int loader_preload (lua_State *L) {
L0436 const char *name = luaL_checkstring(L, 1);
L0437 lua_getfield(L, LUA_ENVIRONINDEX, "preload");
L0438 if (!lua_istable(L, -1))
L0439 luaL_error(L, LUA_QL("package.preload") " must be a table");
L0440 lua_getfield(L, -1, name);
L0441 if (lua_isnil(L, -1))
L0442 lua_pushfstring(L, "\n\tno field package.preload['%s']", name);
L0443 return 1;
L0444 }
L0445
L0446
L0447 static const int sentinel_ = 0;
L0448 #define sentinel ((void *)&sentinel_)
L0449
L0450
L0451 static int ll_require (lua_State *L) {
L0452 const char *name = luaL_checkstring(L, 1);
L0453 int i;
L0454 lua_settop(L, 1);
L0455 lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
L0456 lua_getfield(L, 2, name);
L0457 if (lua_toboolean(L, -1)) {
L0458 if (lua_touserdata(L, -1) == sentinel)
L0459 luaL_error(L, "loop or previous error loading module " LUA_QS, name);
L0460 return 1;
L0461 }
L0462
L0463 lua_getfield(L, LUA_ENVIRONINDEX, "loaders");
L0464 if (!lua_istable(L, -1))
L0465 luaL_error(L, LUA_QL("package.loaders") " must be a table");
L0466 lua_pushliteral(L, "");
L0467 for (i=1; ; i++) {
L0468 lua_rawgeti(L, -2, i);
L0469 if (lua_isnil(L, -1))
L0470 luaL_error(L, "module " LUA_QS " not found:%s",
L0471 name, lua_tostring(L, -2));
L0472 lua_pushstring(L, name);
L0473 lua_call(L, 1, 1);
L0474 if (lua_isfunction(L, -1))
L0475 break;
L0476 else if (lua_isstring(L, -1))
L0477 lua_concat(L, 2);
L0478 else
L0479 lua_pop(L, 1);
L0480 }
L0481 lua_pushlightuserdata(L, sentinel);
L0482 lua_setfield(L, 2, name);
L0483 lua_pushstring(L, name);
L0484 lua_call(L, 1, 1);
L0485 if (!lua_isnil(L, -1))
L0486 lua_setfield(L, 2, name);
L0487 lua_getfield(L, 2, name);
L0488 if (lua_touserdata(L, -1) == sentinel) {
L0489 lua_pushboolean(L, 1);
L0490 lua_pushvalue(L, -1);
L0491 lua_setfield(L, 2, name);
L0492 }
L0493 return 1;
L0494 }
L0495
L0496
L0497
L0498
L0499
L0500
L0505
L0506
L0507 static void setfenv (lua_State *L) {
L0508 lua_Debug ar;
L0509 if (lua_getstack(L, 1, &ar) == 0 ||
L0510 lua_getinfo(L, "f", &ar) == 0 ||
L0511 lua_iscfunction(L, -1))
L0512 luaL_error(L, LUA_QL("module") " not called from a Lua function");
L0513 lua_pushvalue(L, -2);
L0514 lua_setfenv(L, -2);
L0515 lua_pop(L, 1);
L0516 }
L0517
L0518
L0519 static void dooptions (lua_State *L, int n) {
L0520 int i;
L0521 for (i = 2; i <= n; i++) {
L0522 lua_pushvalue(L, i);
L0523 lua_pushvalue(L, -2);
L0524 lua_call(L, 1, 0);
L0525 }
L0526 }
L0527
L0528
L0529 static void modinit (lua_State *L, const char *modname) {
L0530 const char *dot;
L0531 lua_pushvalue(L, -1);
L0532 lua_setfield(L, -2, "_M");
L0533 lua_pushstring(L, modname);
L0534 lua_setfield(L, -2, "_NAME");
L0535 dot = strrchr(modname, '.');
L0536 if (dot == NULL) dot = modname;
L0537 else dot++;
L0538
L0539 lua_pushlstring(L, modname, dot - modname);
L0540 lua_setfield(L, -2, "_PACKAGE");
L0541 }
L0542
L0543
L0544 static int ll_module (lua_State *L) {
L0545 const char *modname = luaL_checkstring(L, 1);
L0546 int loaded = lua_gettop(L) + 1;
L0547 lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
L0548 lua_getfield(L, loaded, modname);
L0549 if (!lua_istable(L, -1)) {
L0550 lua_pop(L, 1);
L0551
L0552 if (luaL_findtable(L, LUA_GLOBALSINDEX, modname, 1) != NULL)
L0553 return luaL_error(L, "name conflict for module " LUA_QS, modname);
L0554 lua_pushvalue(L, -1);
L0555 lua_setfield(L, loaded, modname);
L0556 }
L0557
L0558 lua_getfield(L, -1, "_NAME");
L0559 if (!lua_isnil(L, -1))
L0560 lua_pop(L, 1);
L0561 else {
L0562 lua_pop(L, 1);
L0563 modinit(L, modname);
L0564 }
L0565 lua_pushvalue(L, -1);
L0566 setfenv(L);
L0567 dooptions(L, loaded - 1);
L0568 return 0;
L0569 }
L0570
L0571
L0572 static int ll_seeall (lua_State *L) {
L0573 luaL_checktype(L, 1, LUA_TTABLE);
L0574 if (!lua_getmetatable(L, 1)) {
L0575 lua_createtable(L, 0, 1);
L0576 lua_pushvalue(L, -1);
L0577 lua_setmetatable(L, 1);
L0578 }
L0579 lua_pushvalue(L, LUA_GLOBALSINDEX);
L0580 lua_setfield(L, -2, "__index");
L0581 return 0;
L0582 }
L0583
L0584
L0585
L0586
L0587
L0588
L0589
L0590 #define AUXMARK "\1"
L0591
L0592 static void setpath (lua_State *L, const char *fieldname, const char *envname,
L0593 const char *def) {
L0594 const char *path = getenv(envname);
L0595 if (path == NULL)
L0596 lua_pushstring(L, def);
L0597 else {
L0598
L0599 path = luaL_gsub(L, path, LUA_PATHSEP LUA_PATHSEP,
L0600 LUA_PATHSEP AUXMARK LUA_PATHSEP);
L0601 luaL_gsub(L, path, AUXMARK, def);
L0602 lua_remove(L, -2);
L0603 }
L0604 setprogdir(L);
L0605 lua_setfield(L, -2, fieldname);
L0606 }
L0607
L0608
L0609 static const luaL_Reg pk_funcs[] = {
L0610 {"loadlib", ll_loadlib},
L0611 {"seeall", ll_seeall},
L0612 {NULL, NULL}
L0613 };
L0614
L0615
L0616 static const luaL_Reg ll_funcs[] = {
L0617 {"module", ll_module},
L0618 {"require", ll_require},
L0619 {NULL, NULL}
L0620 };
L0621
L0622
L0623 static const lua_CFunction loaders[] =
L0624 {loader_preload, loader_Lua, loader_C, loader_Croot, NULL};
L0625
L0626
L0627 LUALIB_API int luaopen_package (lua_State *L) {
L0628 int i;
L0629
L0630 luaL_newmetatable(L, "_LOADLIB");
L0631 lua_pushcfunction(L, gctm);
L0632 lua_setfield(L, -2, "__gc");
L0633
L0634 luaL_register(L, LUA_LOADLIBNAME, pk_funcs);
L0635 #if defined(LUA_COMPAT_LOADLIB)
L0636 lua_getfield(L, -1, "loadlib");
L0637 lua_setfield(L, LUA_GLOBALSINDEX, "loadlib");
L0638 #endif
L0639 lua_pushvalue(L, -1);
L0640 lua_replace(L, LUA_ENVIRONINDEX);
L0641
L0642 lua_createtable(L, 0, sizeof(loaders)/sizeof(loaders[0]) - 1);
L0643
L0644 for (i=0; loaders[i] != NULL; i++) {
L0645 lua_pushcfunction(L, loaders[i]);
L0646 lua_rawseti(L, -2, i+1);
L0647 }
L0648 lua_setfield(L, -2, "loaders");
L0649 setpath(L, "path", LUA_PATH, LUA_PATH_DEFAULT);
L0650 setpath(L, "cpath", LUA_CPATH, LUA_CPATH_DEFAULT);
L0651
L0652 lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATHSEP "\n" LUA_PATH_MARK "\n"
L0653 LUA_EXECDIR "\n" LUA_IGMARK);
L0654 lua_setfield(L, -2, "config");
L0655
L0656 luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 2);
L0657 lua_setfield(L, -2, "loaded");
L0658
L0659 lua_newtable(L);
L0660 lua_setfield(L, -2, "preload");
L0661 lua_pushvalue(L, LUA_GLOBALSINDEX);
L0662 luaL_register(L, NULL, ll_funcs);
L0663 lua_pop(L, 1);
L0664 return 1;
L0665 }
L0666
Generated by pretty.lua