Last active
March 30, 2016 20:08
-
-
Save starwing/c6d2c3a2ec15dfc5da66 to your computer and use it in GitHub Desktop.
A Lua module loads symbol from global namespace
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define LUA_LIB | |
#include <lua.h> | |
#include <lauxlib.h> | |
#include <string.h> | |
#define LUA_OFSEP "_" | |
#define LUA_IGMARK "-" | |
#define LUA_POF "luaopen_" | |
#ifdef _WIN32 | |
#include <Windows.h> | |
static void pusherror (lua_State *L) { | |
int error = GetLastError(); | |
char buffer[128]; | |
if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, | |
NULL, error, 0, buffer, sizeof(buffer)/sizeof(char), NULL)) | |
lua_pushstring(L, buffer); | |
else | |
lua_pushfstring(L, "system error %d\n", error); | |
} | |
static lua_CFunction lsys_sym (lua_State *L, const char *sym) { | |
HMODULE lib = GetModuleHandle(NULL); | |
lua_CFunction f = (lua_CFunction)GetProcAddress(lib, sym); | |
if (f == NULL) pusherror(L); | |
return f; | |
} | |
#else | |
#include <dlfcn.h> | |
static lua_CFunction lsys_sym (lua_State *L, const char *sym) { | |
void *lib = dlopen(NULL, RTLD_NOW|RTLD_GLOBAL); | |
lua_CFunction f = (lua_CFunction)dlsym(lib, sym); | |
dlclose(lib); | |
if (f == NULL) lua_pushstring(L, dlerror()); | |
return f; | |
} | |
#endif | |
static int lookforfunc (lua_State *L, const char *sym) { | |
lua_CFunction f = lsys_sym(L, sym); | |
if (f == NULL) return 0; | |
lua_pushcfunction(L, f); | |
return 1; | |
} | |
static int loadfunc (lua_State *L, const char *modname) { | |
const char *openfunc; | |
const char *mark; | |
modname = luaL_gsub(L, modname, ".", LUA_OFSEP); | |
mark = strchr(modname, *LUA_IGMARK); | |
if (mark) { | |
int stat; | |
openfunc = lua_pushlstring(L, modname, mark - modname); | |
openfunc = lua_pushfstring(L, LUA_POF"%s", openfunc); | |
stat = lookforfunc(L, openfunc); | |
if (!stat) return stat; | |
modname = mark + 1; /* else go ahead and try old-style name */ | |
} | |
openfunc = lua_pushfstring(L, LUA_POF"%s", modname); | |
return lookforfunc(L, openfunc); | |
} | |
static int searcher_Cbuiltin (lua_State *L) { | |
const char *name = luaL_checkstring(L, 1); | |
if (loadfunc(L, name)) { | |
lua_pushstring(L, "(builtin)"); | |
return 2; | |
} | |
lua_pushfstring(L, "\n\tno module '%s' in (builtin)", | |
lua_tostring(L, 1)); | |
return 1; | |
} | |
LUALIB_API int luaopen_builtin(lua_State *L) { | |
lua_getglobal(L, "package"); | |
if (lua_isnil(L, -1)) | |
return luaL_error(L, "can not find global 'package' module"); | |
lua_getfield(L, -1, "searchers"); | |
if (lua_isnil(L, -1)) { | |
lua_getfield(L, -1, "loaders"); | |
if (lua_isnil(L, -1)) | |
return luaL_error(L, "can not find 'searchers' or 'loaders' in 'package'"); | |
} | |
lua_pushcfunction(L, searcher_Cbuiltin); | |
lua_rawseti(L, -2, lua_rawlen(L, -2) + 1); | |
return 0; | |
} | |
/* win32cc: flags+='-s -O3 -mdll -DLUA_BUILD_AS_DLL' | |
* win32cc: output='builtin.dll' libs+='-llua53' | |
* unixcc: flags+='-s -O3 -shared -fPIC' output='builtin.so' */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment