site.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. #include "libgluonutil.h"
  2. #include "lua-jsonc.h"
  3. #include <limits.h>
  4. #include <lualib.h>
  5. #include <lauxlib.h>
  6. #define UDATA "gluon.site"
  7. static struct json_object * gluon_site_udata(lua_State *L, int narg) {
  8. return *(struct json_object **)luaL_checkudata(L, narg, UDATA);
  9. }
  10. static void gluon_site_push_none(lua_State *L) {
  11. lua_pushlightuserdata(L, gluon_site_push_none);
  12. lua_rawget(L, LUA_REGISTRYINDEX);
  13. }
  14. static void gluon_site_do_wrap(lua_State *L, struct json_object *obj) {
  15. struct json_object **objp = lua_newuserdata(L, sizeof(struct json_object *));
  16. *objp = json_object_get(obj);
  17. luaL_getmetatable(L, UDATA);
  18. lua_setmetatable(L, -2);
  19. }
  20. static void gluon_site_wrap(lua_State *L, struct json_object *obj) {
  21. if (obj)
  22. gluon_site_do_wrap(L, obj);
  23. else
  24. gluon_site_push_none(L);
  25. }
  26. static int gluon_site_index(lua_State *L) {
  27. struct json_object *obj = gluon_site_udata(L, 1);
  28. const char *key;
  29. lua_Number lua_index;
  30. size_t index;
  31. struct json_object *v = NULL;
  32. switch (json_object_get_type(obj)) {
  33. case json_type_object:
  34. key = lua_tostring(L, 2);
  35. if (key)
  36. json_object_object_get_ex(obj, key, &v);
  37. break;
  38. case json_type_array:
  39. index = lua_index = lua_tonumber(L, 2);
  40. if (lua_index == (lua_Number)index && index >= 1)
  41. v = json_object_array_get_idx(obj, index-1);
  42. break;
  43. case json_type_string:
  44. case json_type_null:
  45. break;
  46. case json_type_boolean:
  47. case json_type_int:
  48. case json_type_double:
  49. luaL_error(L, "attempt to index a number or boolean value");
  50. __builtin_unreachable();
  51. }
  52. gluon_site_wrap(L, v);
  53. return 1;
  54. }
  55. static int gluon_site_call(lua_State *L) {
  56. struct json_object *obj = gluon_site_udata(L, 1);
  57. if (obj) {
  58. lua_jsonc_push_json(L, obj);
  59. } else {
  60. if (lua_isnone(L, 2))
  61. lua_pushnil(L);
  62. else
  63. lua_pushvalue(L, 2);
  64. }
  65. return 1;
  66. }
  67. static int gluon_site_gc(lua_State *L) {
  68. json_object_put(gluon_site_udata(L, 1));
  69. return 0;
  70. }
  71. static const luaL_reg R[] = {
  72. { "__index", gluon_site_index },
  73. { "__call", gluon_site_call },
  74. { "__gc", gluon_site_gc },
  75. {}
  76. };
  77. int luaopen_gluon_site(lua_State *L) {
  78. luaL_newmetatable(L, UDATA);
  79. luaL_register(L, NULL, R);
  80. lua_pop(L, 1);
  81. /* Create "none" object */
  82. lua_pushlightuserdata(L, gluon_site_push_none);
  83. gluon_site_do_wrap(L, NULL);
  84. lua_rawset(L, LUA_REGISTRYINDEX);
  85. struct json_object *site = gluonutil_load_site_config();
  86. gluon_site_wrap(L, site);
  87. json_object_put(site);
  88. return 1;
  89. }