gluon-core: reimplement gluon.site module in C

By basing the Lua gluon.site module on gluonutil_load_site_config(), the
config load implementation needs to changed only in a single place for
multi-domain support.
This commit is contained in:
Matthias Schiffer 2018-01-18 16:23:10 +01:00
parent 6cf88c3b03
commit 0b80f1b5ce
No known key found for this signature in database
GPG Key ID: 16EF3F64CB201D9C
4 changed files with 131 additions and 45 deletions

View File

@ -9,6 +9,7 @@ PKG_VERSION:=$(if $(DUMP),x,$(GLUON_VERSION))
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
include ../gluon.mk
include $(INCLUDE_DIR)/cmake.mk
define Package/gluon-core
@ -24,16 +25,20 @@ define Package/gluon-core/description
Gluon community wifi mesh firmware framework: core
endef
define Build/Configure
define Build/Prepare
mkdir -p $(PKG_BUILD_DIR)
$(CP) ./src/* $(PKG_BUILD_DIR)/
endef
define Build/Compile
$(call Build/Compile/Default,all)
$(call GluonSrcDiet,./luasrc,$(PKG_BUILD_DIR)/luadest/)
endef
define Package/gluon-core/install
$(CP) ./files/* $(1)/
$(CP) $(PKG_BUILD_DIR)/luadest/* $(1)/
$(CP) $(PKG_INSTALL_DIR)/* $(1)/
$(INSTALL_DIR) $(1)/lib/gluon
echo '$(GLUON_VERSION)' > $(1)/lib/gluon/gluon-version

View File

@ -1,44 +0,0 @@
local json = require 'jsonc'
local site = assert(json.load('/lib/gluon/site.json'))
local wrap
local function index(t, k)
local v = getmetatable(t).value
if v == nil then return wrap(nil) end
return wrap(v[k])
end
local function newindex()
error('attempted to modify site config')
end
local function call(t, def)
local v = getmetatable(t).value
if v == nil then return def end
return v
end
local function _wrap(v, t)
return setmetatable(t or {}, {
__index = index,
__newindex = newindex,
__call = call,
value = v,
})
end
local none = _wrap(nil)
function wrap(v, t)
if v == nil then return none end
return _wrap(v, t)
end
module 'gluon.site'
return wrap(site, _M)

View File

@ -0,0 +1,12 @@
cmake_minimum_required(VERSION 3.0)
project(gluon-core C)
add_library(site MODULE site.c)
set_property(TARGET site PROPERTY PREFIX "")
set_property(TARGET site PROPERTY COMPILE_FLAGS "-Wall -std=c99")
target_link_libraries(site gluonutil lua lua-jsonc)
install(TARGETS site
LIBRARY DESTINATION lib/lua/gluon
)

View File

@ -0,0 +1,113 @@
#include "libgluonutil.h"
#include "lua-jsonc.h"
#include <limits.h>
#include <lualib.h>
#include <lauxlib.h>
#define UDATA "gluon.site"
static struct json_object * gluon_site_udata(lua_State *L, int narg) {
return *(struct json_object **)luaL_checkudata(L, narg, UDATA);
}
static void gluon_site_push_none(lua_State *L) {
lua_pushlightuserdata(L, gluon_site_push_none);
lua_rawget(L, LUA_REGISTRYINDEX);
}
static void gluon_site_do_wrap(lua_State *L, struct json_object *obj) {
struct json_object **objp = lua_newuserdata(L, sizeof(struct json_object *));
*objp = json_object_get(obj);
luaL_getmetatable(L, UDATA);
lua_setmetatable(L, -2);
}
static void gluon_site_wrap(lua_State *L, struct json_object *obj) {
if (obj)
gluon_site_do_wrap(L, obj);
else
gluon_site_push_none(L);
}
static int gluon_site_index(lua_State *L) {
struct json_object *obj = gluon_site_udata(L, 1);
const char *key;
lua_Number lua_index;
size_t index;
struct json_object *v = NULL;
switch (json_object_get_type(obj)) {
case json_type_object:
key = lua_tostring(L, 2);
if (key)
json_object_object_get_ex(obj, key, &v);
break;
case json_type_array:
index = lua_index = lua_tonumber(L, 2);
if (lua_index == (lua_Number)index && index >= 1)
v = json_object_array_get_idx(obj, index-1);
break;
case json_type_string:
case json_type_null:
break;
case json_type_boolean:
case json_type_int:
case json_type_double:
luaL_error(L, "attempt to index a number or boolean value");
__builtin_unreachable();
}
gluon_site_wrap(L, v);
return 1;
}
static int gluon_site_call(lua_State *L) {
struct json_object *obj = gluon_site_udata(L, 1);
if (obj) {
lua_jsonc_push_json(L, obj);
} else {
if (lua_isnone(L, 2))
lua_pushnil(L);
else
lua_pushvalue(L, 2);
}
return 1;
}
static int gluon_site_gc(lua_State *L) {
json_object_put(gluon_site_udata(L, 1));
return 0;
}
static const luaL_reg R[] = {
{ "__index", gluon_site_index },
{ "__call", gluon_site_call },
{ "__gc", gluon_site_gc },
{}
};
int luaopen_gluon_site(lua_State *L) {
luaL_newmetatable(L, UDATA);
luaL_register(L, NULL, R);
lua_pop(L, 1);
/* Create "none" object */
lua_pushlightuserdata(L, gluon_site_push_none);
gluon_site_do_wrap(L, NULL);
lua_rawset(L, LUA_REGISTRYINDEX);
struct json_object *site = gluonutil_load_site_config();
gluon_site_wrap(L, site);
json_object_put(site);
return 1;
}