Add support for preloading lua modules. This is useful both when
authorJ. Ali Harlow <ali@juiblex.co.uk>
Wed, 29 Apr 2009 16:00:01 +0000 (17:00 +0100)
committerJ. Ali Harlow <ali@juiblex.co.uk>
Wed, 29 Apr 2009 16:00:01 +0000 (17:00 +0100)
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).

librazor/Makefile.am
librazor/lua.c
librazor/razor.h

index 1df2de0..1370909 100644 (file)
@@ -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
index 910a82f..97e08d7 100644 (file)
@@ -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)) {
index e7a0d25..b182629 100644 (file)
@@ -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_ */