From 82057d4e93a871979186d0f3c117def5aa300783 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Tue, 13 Aug 2024 14:43:29 +0100 Subject: [PATCH] [Project] Add more stuff to transparent UCL --- contrib/libucl/lua_ucl.c | 115 +++++++++++++++++++++++++++++---------- 1 file changed, 85 insertions(+), 30 deletions(-) diff --git a/contrib/libucl/lua_ucl.c b/contrib/libucl/lua_ucl.c index aaa57b24e..3e3a06605 100644 --- a/contrib/libucl/lua_ucl.c +++ b/contrib/libucl/lua_ucl.c @@ -1281,12 +1281,12 @@ lua_ucl_object_gc(lua_State *L) static int lua_ucl_iter_gc(lua_State *L) { - ucl_object_iter_t *pit; + ucl_object_iter_t it; - pit = lua_touserdata(L, 1); + it = *((ucl_object_iter_t *) lua_touserdata(L, 1)); - if (pit && *pit) { - ucl_object_iterate_free(*pit); + if (it) { + ucl_object_iterate_free(it); } return 0; @@ -1441,39 +1441,38 @@ lua_ucl_type(lua_State *L) static int lua_ucl_object_iter(lua_State *L) { - ucl_object_iter_t *pit; - ucl_object_t *obj; + ucl_object_iter_t it; const ucl_object_t *cur; - obj = lua_ucl_object_get(L, 1); - pit = lua_touserdata(L, 2); - - if (pit && *pit) { - cur = ucl_object_iterate_safe(obj, *pit); + it = *((ucl_object_iter_t *) lua_touserdata(L, 1)); + cur = ucl_object_iterate_safe(it, true); - if (cur) { - lua_pushvalue(L, 2); - if (ucl_object_key(cur)) { - size_t klen; - const char *k = ucl_object_keyl(cur, &klen); - lua_pushlstring(L, k, klen); + if (cur) { + if (ucl_object_key(cur)) { + size_t klen; + const char *k = ucl_object_keyl(cur, &klen); + lua_pushlstring(L, k, klen); + } + else { + if (lua_type(L, 2) == LUA_TNUMBER) { + lua_Integer idx = lua_tointeger(L, 2); + if (idx >= 0) { + lua_pushinteger(L, idx + 1); + } } else { - /* TODO: deal with arrays somehow */ - lua_pushnil(L); + lua_pushnumber(L, -1); } - lua_ucl_push_opaque(L, cur); - - return 3; } - else { - lua_pushnil(L); + lua_ucl_push_opaque(L, cur); - return 1; - } + return 2; } + else { + lua_pushnil(L); - return luaL_error(L, "invalid iterator"); + return 1; + } } static int @@ -1487,10 +1486,48 @@ lua_ucl_pairs(lua_State *L) if ((obj) && (t == UCL_ARRAY || t == UCL_OBJECT || obj->next != NULL)) { /* iter_func, ucl_object_t, iter */ lua_pushcfunction(L, lua_ucl_object_iter); - lua_pushvalue(L, 1); ucl_object_iter_t *pit = lua_newuserdata(L, sizeof(ucl_object_iter_t *)); + luaL_getmetatable(L, ITER_META); + lua_setmetatable(L, -2); ucl_object_iter_t it = ucl_object_iterate_new(obj); *pit = it; + lua_pushnumber(L, -1); + + return 3; + } + else { + return luaL_error(L, "invalid object type"); + } +} + +static int +lua_ucl_len(lua_State *L) +{ + ucl_object_t *obj; + + obj = lua_ucl_object_get(L, 1); + lua_pushinteger(L, obj->len); + + return 1; +} + +static int +lua_ucl_ipairs(lua_State *L) +{ + ucl_object_t *obj; + + obj = lua_ucl_object_get(L, 1); + int t = ucl_object_type(obj); + + if ((obj) && (t == UCL_ARRAY || obj->next != NULL)) { + /* iter_func, ucl_object_t, iter */ + lua_pushcfunction(L, lua_ucl_object_iter); + ucl_object_iter_t *pit = lua_newuserdata(L, sizeof(ucl_object_iter_t *)); + luaL_getmetatable(L, ITER_META); + lua_setmetatable(L, -2); + ucl_object_iter_t it = ucl_object_iterate_new(obj); + *pit = it; + lua_pushnumber(L, 0); return 3; } @@ -1542,9 +1579,13 @@ lua_ucl_object_mt(lua_State *L) { luaL_newmetatable(L, OBJECT_META); - lua_pushcfunction(L, lua_ucl_index); + lua_pushvalue(L, -1); lua_setfield(L, -2, "__index"); + /* Access UCL elements using `:at` method */ + lua_pushcfunction(L, lua_ucl_index); + lua_setfield(L, -2, "at"); + lua_pushcfunction(L, lua_ucl_newindex); lua_setfield(L, -2, "__newindex"); @@ -1558,6 +1599,20 @@ lua_ucl_object_mt(lua_State *L) lua_pushcfunction(L, lua_ucl_pairs); lua_setfield(L, -2, "__pairs"); + lua_pushcfunction(L, lua_ucl_ipairs); + lua_setfield(L, -2, "ipairs"); + + /* Usable merely with lua 5.2+ */ + lua_pushcfunction(L, lua_ucl_ipairs); + lua_setfield(L, -2, "__ipairs"); + + lua_pushcfunction(L, lua_ucl_len); + lua_setfield(L, -2, "len"); + + /* Usable merely with lua 5.2+ */ + lua_pushcfunction(L, lua_ucl_len); + lua_setfield(L, -2, "__len"); + lua_pushcfunction(L, lua_ucl_object_gc); lua_setfield(L, -2, "__gc"); @@ -1586,7 +1641,7 @@ lua_ucl_object_mt(lua_State *L) lua_setfield(L, -2, "__gc"); lua_pushstring(L, ITER_META); - lua_setfield(L, -2, "class"); + lua_setfield(L, -2, "__tostring"); lua_pop(L, 1); } -- 2.39.5