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