From: J. Ali Harlow Date: Wed, 29 Apr 2009 16:00:01 +0000 (+0100) Subject: Add support for preloading lua modules. This is useful both when X-Git-Tag: 0.1~17 X-Git-Url: http://project.juiblex.co.uk/git/?a=commitdiff_plain;h=a5bc12ddeb09d7900749ac7966a80819be4fb840;p=razor.git Add support for preloading lua modules. This is useful both when providing lua bindings to applications based on librazor and when producing static binaries using librazor (where otherwise the lua POSIX library would need to be included as an additional dynamic object). --- diff --git a/librazor/Makefile.am b/librazor/Makefile.am index 1df2de0..1370909 100644 --- a/librazor/Makefile.am +++ b/librazor/Makefile.am @@ -49,7 +49,7 @@ TESTS = test-hashtable if HAVE_LUA test_lua_SOURCES = test-lua.c - test_lua_LDADD = lua.lo util.lo $(LUA_LIBS) ../gl/libgnu.la \ + test_lua_LDADD = lua.lo util.lo types.lo $(LUA_LIBS) ../gl/libgnu.la \ $(EXTRA_LIBS) TESTS += test-lua diff --git a/librazor/lua.c b/librazor/lua.c index 910a82f..97e08d7 100644 --- a/librazor/lua.c +++ b/librazor/lua.c @@ -289,6 +289,66 @@ static int proxy_handler(lua_State *L) return retval; } +struct razor_lua_loader { + uint32_t name; + lua_CFunction func; +}; + +static struct razor_preload { + int init; + struct hashtable modules; + struct array name_pool; + struct array loaders; +} razor_preload = {0}; + +RAZOR_EXPORT void razor_set_lua_loader(const char *modname, void (*loader)()) +{ + uint32_t name; + struct razor_lua_loader *ploader, *end; + + if (!razor_preload.init) { + razor_preload.init = 1; + array_init(&razor_preload.name_pool); + array_init(&razor_preload.loaders); + hashtable_init(&razor_preload.modules, + &razor_preload.name_pool); + } + + name = hashtable_tokenize(&razor_preload.modules, modname); + + end = razor_preload.loaders.data + razor_preload.loaders.size; + for(ploader = razor_preload.loaders.data; ploader < end; ploader++) + if (ploader->name == name) { + ploader->func = loader; + return; + } + + ploader = array_add(&razor_preload.loaders, sizeof(*ploader)); + ploader->name = name; + ploader->func = loader; +} + +static void razor_lua_preload(lua_State *L) +{ + struct razor_lua_loader *ploader, *end; + + if (!razor_preload.init) + return; + + lua_getfield(L, LUA_GLOBALSINDEX, "package"); + lua_getfield(L, -1, "preload"); + lua_remove(L, -2); + + end = razor_preload.loaders.data + razor_preload.loaders.size; + for(ploader = razor_preload.loaders.data; ploader < end; ploader++) { + lua_pushcfunction(L, ploader->func); + lua_setfield(L, -2, + razor_preload.name_pool.data + ploader->name); + } + + lua_pop(L, 1); +} + int run_lua_script(const char *root, const char *name, const char *body, ssize_t len) { @@ -303,6 +363,7 @@ int run_lua_script(const char *root, const char *name, const char *body, L = lua_newstate(alloc_lua, &rl); luaL_openlibs(L); + razor_lua_preload(L); lua_getglobal(L, "require"); lua_pushstring(L, "posix"); if (lua_pcall(L, 1, 1, 0)) { diff --git a/librazor/razor.h b/librazor/razor.h index e7a0d25..b182629 100644 --- a/librazor/razor.h +++ b/librazor/razor.h @@ -380,5 +380,7 @@ int razor_versioncmp(const char *s1, const char *s2); void razor_disable_root_name_checks(int disable); +void razor_set_lua_loader(const char *modname, void (*loader)()); + #endif /* _RAZOR_H_ */