Browse Source

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.
Matthias Schiffer 6 years ago
parent
commit
0b80f1b5ce

+ 6 - 1
package/gluon-core/Makefile

@@ -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

+ 0 - 44
package/gluon-core/luasrc/usr/lib/lua/gluon/site.lua

@@ -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)

+ 12 - 0
package/gluon-core/src/CMakeLists.txt

@@ -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
+)

+ 113 - 0
package/gluon-core/src/site.c

@@ -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;
+}