From cb846eabcdd306de3ff54c77ad0184f08850dead Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Tue, 10 Jan 2017 12:35:55 +0000 Subject: [Feature] Add ucl_object_iterate_full function --- contrib/libucl/ucl.h | 19 +++++++++++++++++++ contrib/libucl/ucl_util.c | 15 +++++++++++---- 2 files changed, 30 insertions(+), 4 deletions(-) (limited to 'contrib/libucl') diff --git a/contrib/libucl/ucl.h b/contrib/libucl/ucl.h index 024f5dd8f..ec93bd7e1 100644 --- a/contrib/libucl/ucl.h +++ b/contrib/libucl/ucl.h @@ -831,10 +831,29 @@ UCL_EXTERN ucl_object_iter_t ucl_object_iterate_reset (ucl_object_iter_t it, * Get the next object from the `obj`. This fucntion iterates over arrays, objects * and implicit arrays * @param iter safe iterator + * @param expand_values expand explicit arrays and objects * @return the next object in sequence */ UCL_EXTERN const ucl_object_t* ucl_object_iterate_safe (ucl_object_iter_t iter, bool expand_values); +/** + * Iteration type enumerator + */ +enum ucl_iterate_type { + UCL_ITERATE_EXPLICIT = 1 << 0, /**< Iterate just explicit arrays and objects */ + UCL_ITERATE_IMPLICIT = 1 << 1, /**< Iterate just implicit arrays */ + UCL_ITERATE_BOTH = (1 << 0) | (1 << 1), /**< Iterate both explicit and implicit arrays*/ +}; + +/** + * Get the next object from the `obj`. This fucntion iterates over arrays, objects + * and implicit arrays if needed + * @param iter safe iterator + * @param + * @return the next object in sequence + */ +UCL_EXTERN const ucl_object_t* ucl_object_iterate_full (ucl_object_iter_t iter, + enum ucl_iterate_type type); /** * Free memory associated with the safe iterator diff --git a/contrib/libucl/ucl_util.c b/contrib/libucl/ucl_util.c index 1adb8c3b6..6691c8546 100644 --- a/contrib/libucl/ucl_util.c +++ b/contrib/libucl/ucl_util.c @@ -2478,6 +2478,13 @@ ucl_object_iterate_reset (ucl_object_iter_t it, const ucl_object_t *obj) const ucl_object_t* ucl_object_iterate_safe (ucl_object_iter_t it, bool expand_values) +{ + return ucl_object_iterate_full (it, expand_values ? UCL_ITERATE_BOTH : + UCL_ITERATE_IMPLICIT); +} + +const ucl_object_t* +ucl_object_iterate_full (ucl_object_iter_t it, enum ucl_iterate_type type) { struct ucl_object_safe_iter *rit = UCL_SAFE_ITER (it); const ucl_object_t *ret = NULL; @@ -2491,21 +2498,21 @@ ucl_object_iterate_safe (ucl_object_iter_t it, bool expand_values) if (rit->impl_it->type == UCL_OBJECT || rit->impl_it->type == UCL_ARRAY) { ret = ucl_object_iterate (rit->impl_it, &rit->expl_it, true); - if (ret == NULL) { + if (ret == NULL && (type & UCL_ITERATE_IMPLICIT)) { /* Need to switch to another implicit object in chain */ rit->impl_it = rit->impl_it->next; rit->expl_it = NULL; - return ucl_object_iterate_safe (it, expand_values); + return ucl_object_iterate_safe (it, type); } } else { /* Just iterate over the implicit array */ ret = rit->impl_it; rit->impl_it = rit->impl_it->next; - if (expand_values) { + if (type & UCL_ITERATE_EXPLICIT) { /* We flatten objects if need to expand values */ if (ret->type == UCL_OBJECT || ret->type == UCL_ARRAY) { - return ucl_object_iterate_safe (it, expand_values); + return ucl_object_iterate_safe (it, type); } } } -- cgit v1.2.3