#include "libgluonutil.h" #include "lua-jsonc.h" #include #include #include #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; }