]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
daemon/engine: syntactic sugar for module ‘get’, ‘set’ properties
authorMarek Vavruša <marek.vavrusa@nic.cz>
Sun, 19 Apr 2015 19:32:59 +0000 (21:32 +0200)
committerMarek Vavruša <marek.vavrusa@nic.cz>
Sun, 19 Apr 2015 19:32:59 +0000 (21:32 +0200)
if the module declares such properties, they can be accessed
by treating module as a table, e.g.

hints[‘localhost’] = ‘127.0.0.1’
hints.hostname = ‘192.168.1.1.
print(hints.localhost)

equals to:
hints.set(‘localhost 127.0.0.1’)
hints.set(‘hostname 192.168.1.1’)
print(hints.get(‘localhost’))

daemon/engine.c
daemon/lua/sandbox.lua
modules/README.rst

index 8b174a8096a37f398c0b20602493b0ad2515e89a..10ed169d0333a6f716f4132c80c49c3ed3ce59cb 100644 (file)
@@ -259,6 +259,30 @@ void engine_stop(struct engine *engine)
        uv_stop(uv_default_loop());
 }
 
+/** Register module properties in Lua environment */
+static int register_properties(struct engine *engine, struct kr_module *module)
+{
+       lua_newtable(engine->L);
+       if (module->config != NULL) {
+               REGISTER_MODULE_CALL(engine->L, module, module->config, "config");
+       }
+       for (struct kr_prop *p = module->props; p->name; ++p) {
+               if (p->cb != NULL && p->name != NULL) {
+                       REGISTER_MODULE_CALL(engine->L, module, p->cb, p->name);
+               }
+       }
+       lua_setglobal(engine->L, module->name);
+
+       /* Register module in Lua env */
+       lua_getglobal(engine->L, "modules_register");
+       lua_getglobal(engine->L, module->name);
+       if (l_sandboxcall(engine->L, 1) != 0) {
+               lua_pop(engine->L, 1);
+       }
+
+       return kr_ok();
+}
+
 int engine_register(struct engine *engine, const char *name)
 {
        if (engine == NULL || name == NULL) {
@@ -278,16 +302,7 @@ int engine_register(struct engine *engine, const char *name)
 
        /* Register properties */
        if (module->props) {
-               lua_newtable(engine->L);
-               if (module->config != NULL) {
-                       REGISTER_MODULE_CALL(engine->L, module, module->config, "config");
-               }
-               for (struct kr_prop *p = module->props; p->name; ++p) {
-                       if (p->cb != NULL && p->name != NULL) {
-                               REGISTER_MODULE_CALL(engine->L, module, p->cb, p->name);
-                       }
-               }
-               lua_setglobal(engine->L, module->name);
+               return register_properties(engine, module);
        }
 
        return kr_ok();
index e8e7fe0b671b3a7b2eb1803fe09b20afc42efc1b..9217796f0129320649c78a6c92317c2aa0403c3d 100644 (file)
@@ -35,6 +35,25 @@ setmetatable(modules, {
        end
 })
 
+-- Register module in Lua environment
+function modules_register(module)
+       -- Syntactic sugar for get() and set() properties
+       setmetatable(module, {
+               __index = function (t, k)
+                       local  v = rawget(t, k)
+                       if     v     then return v
+                       elseif t.get then return t.get(k)
+                       end
+               end,
+               __newindex = function (t, k, v)
+                       local  old_v = rawget(t, k)
+                       if not old_v and t.set then
+                               t.set(k..' '..v)
+                       end
+               end
+       })
+end
+
 -- Make sandboxed environment
 local function make_sandbox(defined)
        local __protected = { modules = true, cache = true, net = true }
index 594cef46e0cad1fed257acb011a068a837f50bde..e01236bf82de6bb6f6e37be3d066b79fee0f28a0 100644 (file)
@@ -247,6 +247,15 @@ Once you load the module, you can call the module property from the interactive
 
 *Note* |---| this relies on function pointers, so the same ``static inline`` trick as for the ``Layer()`` is required for C/Go.
 
+Special properties
+------------------
+
+If the module declares properties ``get`` or ``set``, they can be used in the Lua interpreter as
+regular tables.
+
+.. warning: This is not yet completely implemented, as the module I/O format may change to map_t a/o
+            embedded JSON tokenizer.
+
 .. _`not present in Go`: http://blog.golang.org/gos-declaration-syntax
 .. _CGO: http://golang.org/cmd/cgo/
 .. _GCCGO: https://golang.org/doc/install/gccgo