Skip to content

Instantly share code, notes, and snippets.

@starwing
Last active March 30, 2016 20:08
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save starwing/c6d2c3a2ec15dfc5da66 to your computer and use it in GitHub Desktop.
Save starwing/c6d2c3a2ec15dfc5da66 to your computer and use it in GitHub Desktop.
A Lua module loads symbol from global namespace
#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