diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2020-03-11 14:31:38 +0000 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2020-03-11 14:31:38 +0000 |
commit | f595d3331b4f8a94e1ceefca228b1fd5104d4f82 (patch) | |
tree | 4ca8fd7f65c69dea9df45c8cd49901a31547829a /contrib/libucl | |
parent | a7108fde8fa77c6cb6e66186e6a490951747899d (diff) | |
download | rspamd-f595d3331b4f8a94e1ceefca228b1fd5104d4f82.tar.gz rspamd-f595d3331b4f8a94e1ceefca228b1fd5104d4f82.zip |
[Minor] Allow to push objects to lua replacing UCL_NULL
Diffstat (limited to 'contrib/libucl')
-rw-r--r-- | contrib/libucl/lua_ucl.c | 73 | ||||
-rw-r--r-- | contrib/libucl/lua_ucl.h | 12 |
2 files changed, 60 insertions, 25 deletions
diff --git a/contrib/libucl/lua_ucl.c b/contrib/libucl/lua_ucl.c index 8edea5868..a9f1d8924 100644 --- a/contrib/libucl/lua_ucl.c +++ b/contrib/libucl/lua_ucl.c @@ -74,8 +74,9 @@ func = "huh"; #define UCL_ARRAY_TYPE_META "ucl.type.array" #define UCL_IMPL_ARRAY_TYPE_META "ucl.type.impl_array" -static int ucl_object_lua_push_array (lua_State *L, const ucl_object_t *obj); -static int ucl_object_lua_push_scalar (lua_State *L, const ucl_object_t *obj, bool allow_array); +static int ucl_object_lua_push_array (lua_State *L, const ucl_object_t *obj, int flags); +static int ucl_object_lua_push_scalar (lua_State *L, const ucl_object_t *obj, int flags); +static int ucl_object_push_lua_common (lua_State *L, const ucl_object_t *obj, int flags); static ucl_object_t* ucl_object_lua_fromtable (lua_State *L, int idx, ucl_string_flags_t flags); static ucl_object_t* ucl_object_lua_fromelt (lua_State *L, int idx, ucl_string_flags_t flags); @@ -89,10 +90,10 @@ static void *ucl_null; */ static void ucl_object_lua_push_element (lua_State *L, const char *key, - const ucl_object_t *obj) + const ucl_object_t *obj, int flags) { lua_pushstring (L, key); - ucl_object_push_lua (L, obj, true); + ucl_object_push_lua_common (L, obj, flags); lua_settable (L, -3); } @@ -132,6 +133,12 @@ lua_ucl_userdata_emitter (void *ud) return fd->ret; } +enum lua_ucl_push_flags { + LUA_UCL_DEFAULT_FLAGS = 0, + LUA_UCL_ALLOW_ARRAY = (1u << 0u), + LUA_UCL_CONVERT_NIL = (1u << 1u), +}; + /** * Push a single object to lua * @param L @@ -140,21 +147,21 @@ lua_ucl_userdata_emitter (void *ud) */ static int ucl_object_lua_push_object (lua_State *L, const ucl_object_t *obj, - bool allow_array) + int flags) { const ucl_object_t *cur; ucl_object_iter_t it = NULL; - if (allow_array && obj->next != NULL) { + if ((flags & LUA_UCL_ALLOW_ARRAY) && obj->next != NULL) { /* Actually we need to push this as an array */ - return ucl_object_lua_push_array (L, obj); + return ucl_object_lua_push_array (L, obj, flags); } lua_createtable (L, 0, obj->len); it = NULL; while ((cur = ucl_object_iterate (obj, &it, true)) != NULL) { - ucl_object_lua_push_element (L, ucl_object_key (cur), cur); + ucl_object_lua_push_element (L, ucl_object_key (cur), cur, flags); } luaL_getmetatable (L, UCL_OBJECT_TYPE_META); @@ -170,7 +177,7 @@ ucl_object_lua_push_object (lua_State *L, const ucl_object_t *obj, * @return */ static int -ucl_object_lua_push_array (lua_State *L, const ucl_object_t *obj) +ucl_object_lua_push_array (lua_State *L, const ucl_object_t *obj, int flags) { const ucl_object_t *cur; ucl_object_iter_t it; @@ -182,7 +189,7 @@ ucl_object_lua_push_array (lua_State *L, const ucl_object_t *obj) lua_createtable (L, nelt, 0); while ((cur = ucl_object_iterate_safe (it, true))) { - ucl_object_push_lua (L, cur, false); + ucl_object_push_lua (L, cur, (flags & ~LUA_UCL_ALLOW_ARRAY)); lua_rawseti (L, -2, i); i ++; } @@ -201,7 +208,7 @@ ucl_object_lua_push_array (lua_State *L, const ucl_object_t *obj) lua_createtable (L, nelt, 0); LL_FOREACH (obj, cur) { - ucl_object_push_lua (L, cur, false); + ucl_object_push_lua (L, cur, (flags & ~LUA_UCL_ALLOW_ARRAY)); lua_rawseti (L, -2, i); i ++; } @@ -218,13 +225,13 @@ ucl_object_lua_push_array (lua_State *L, const ucl_object_t *obj) */ static int ucl_object_lua_push_scalar (lua_State *L, const ucl_object_t *obj, - bool allow_array) + int flags) { struct ucl_lua_funcdata *fd; - if (allow_array && obj->next != NULL) { + if ((flags & LUA_UCL_ALLOW_ARRAY) && obj->next != NULL) { /* Actually we need to push this as an array */ - return ucl_object_lua_push_array (L, obj); + return ucl_object_lua_push_array (L, obj, flags); } switch (obj->type) { @@ -246,7 +253,12 @@ ucl_object_lua_push_scalar (lua_State *L, const ucl_object_t *obj, lua_pushnumber (L, ucl_obj_todouble (obj)); break; case UCL_NULL: - lua_getfield (L, LUA_REGISTRYINDEX, "ucl.null"); + if (flags & LUA_UCL_CONVERT_NIL) { + lua_pushboolean (L, false); + } + else { + lua_getfield (L, LUA_REGISTRYINDEX, "ucl.null"); + } break; case UCL_USERDATA: fd = (struct ucl_lua_funcdata *)obj->value.ud; @@ -260,6 +272,19 @@ ucl_object_lua_push_scalar (lua_State *L, const ucl_object_t *obj, return 1; } +static int +ucl_object_push_lua_common (lua_State *L, const ucl_object_t *obj, int flags) +{ + switch (obj->type) { + case UCL_OBJECT: + return ucl_object_lua_push_object (L, obj, flags); + case UCL_ARRAY: + return ucl_object_lua_push_array (L, obj, flags); + default: + return ucl_object_lua_push_scalar (L, obj, flags); + } +} + /*** * @function ucl_object_push_lua(L, obj, allow_array) * This is a `C` function to push `UCL` object as lua variable. This function @@ -278,14 +303,16 @@ ucl_object_lua_push_scalar (lua_State *L, const ucl_object_t *obj, int ucl_object_push_lua (lua_State *L, const ucl_object_t *obj, bool allow_array) { - switch (obj->type) { - case UCL_OBJECT: - return ucl_object_lua_push_object (L, obj, allow_array); - case UCL_ARRAY: - return ucl_object_lua_push_array (L, obj); - default: - return ucl_object_lua_push_scalar (L, obj, allow_array); - } + return ucl_object_push_lua_common (L, obj, + allow_array ? LUA_UCL_ALLOW_ARRAY : LUA_UCL_DEFAULT_FLAGS); +} + +int +ucl_object_push_lua_filter_nil (lua_State *L, const ucl_object_t *obj, bool allow_array) +{ + return ucl_object_push_lua_common (L, obj, + allow_array ? (LUA_UCL_ALLOW_ARRAY|LUA_UCL_CONVERT_NIL) : + (LUA_UCL_DEFAULT_FLAGS|LUA_UCL_CONVERT_NIL)); } /** diff --git a/contrib/libucl/lua_ucl.h b/contrib/libucl/lua_ucl.h index da7e014b9..5b7f88e03 100644 --- a/contrib/libucl/lua_ucl.h +++ b/contrib/libucl/lua_ucl.h @@ -70,8 +70,16 @@ UCL_EXTERN ucl_object_t* ucl_object_lua_import_escape (lua_State *L, int idx); */ UCL_EXTERN int ucl_object_push_lua (lua_State *L, const ucl_object_t *obj, bool allow_array); +/** + * Push an object to lua replacing all ucl.null with `false` + * @param L lua state + * @param obj object to push + * @param allow_array traverse over implicit arrays + */ +UCL_EXTERN int ucl_object_push_lua_filter_nil (lua_State *L, + const ucl_object_t *obj, + bool allow_array); -UCL_EXTERN struct ucl_lua_funcdata* ucl_object_toclosure ( - const ucl_object_t *obj); +UCL_EXTERN struct ucl_lua_funcdata* ucl_object_toclosure (const ucl_object_t *obj); #endif /* LUA_UCL_H_ */ |