From: Marek Vavruša Date: Sun, 19 Apr 2015 19:32:59 +0000 (+0200) Subject: daemon/engine: syntactic sugar for module ‘get’, ‘set’ properties X-Git-Tag: v1.0.0-beta1~236^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ae7b572dc19b3136562cc64cda67d30316e3be6f;p=thirdparty%2Fknot-resolver.git daemon/engine: syntactic sugar for module ‘get’, ‘set’ properties 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’)) --- diff --git a/daemon/engine.c b/daemon/engine.c index 8b174a809..10ed169d0 100644 --- a/daemon/engine.c +++ b/daemon/engine.c @@ -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(); diff --git a/daemon/lua/sandbox.lua b/daemon/lua/sandbox.lua index e8e7fe0b6..9217796f0 100644 --- a/daemon/lua/sandbox.lua +++ b/daemon/lua/sandbox.lua @@ -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 } diff --git a/modules/README.rst b/modules/README.rst index 594cef46e..e01236bf8 100644 --- a/modules/README.rst +++ b/modules/README.rst @@ -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