Author: bapt
Date: Sun Feb 19 17:37:16 2017
New Revision: 313953
URL: https://svnweb.freebsd.org/changeset/base/313953

Log:
  Import libucl 20170219
  
  MFC after:    3 days

Modified:
  head/contrib/libucl/ChangeLog.md
  head/contrib/libucl/README.md
  head/contrib/libucl/configure.ac
  head/contrib/libucl/include/ucl.h
  head/contrib/libucl/lua/lua_ucl.c
  head/contrib/libucl/src/ucl_emitter_utils.c
  head/contrib/libucl/src/ucl_internal.h
  head/contrib/libucl/src/ucl_parser.c
  head/contrib/libucl/src/ucl_util.c
Directory Properties:
  head/contrib/libucl/   (props changed)

Modified: head/contrib/libucl/ChangeLog.md
==============================================================================
--- head/contrib/libucl/ChangeLog.md    Sun Feb 19 17:35:14 2017        
(r313952)
+++ head/contrib/libucl/ChangeLog.md    Sun Feb 19 17:37:16 2017        
(r313953)
@@ -35,7 +35,7 @@
 
 ### Libucl 0.7.3
 
-- Fixed a bug with macroes that come after an empty object
+- Fixed a bug with macros that come after an empty object
 - Fixed a bug in include processing when an incorrect variable has been 
destroyed (use-after-free)
 
 ### Libucl 0.8.0

Modified: head/contrib/libucl/README.md
==============================================================================
--- head/contrib/libucl/README.md       Sun Feb 19 17:35:14 2017        
(r313952)
+++ head/contrib/libucl/README.md       Sun Feb 19 17:37:16 2017        
(r313953)
@@ -1,6 +1,8 @@
 # LIBUCL
 
-[![Build 
Status](https://travis-ci.org/vstakhov/libucl.svg?branch=master)](https://travis-ci.org/vstakhov/libucl)[![Coverity](https://scan.coverity.com/projects/4138/badge.svg)](https://scan.coverity.com/projects/4138)[![Coverage
 
Status](https://coveralls.io/repos/github/vstakhov/libucl/badge.svg?branch=master)](https://coveralls.io/github/vstakhov/libucl?branch=master)
+[![Build 
Status](https://travis-ci.org/vstakhov/libucl.svg?branch=master)](https://travis-ci.org/vstakhov/libucl)
+[![Coverity](https://scan.coverity.com/projects/4138/badge.svg)](https://scan.coverity.com/projects/4138)
+[![Coverage 
Status](https://coveralls.io/repos/github/vstakhov/libucl/badge.svg?branch=master)](https://coveralls.io/github/vstakhov/libucl?branch=master)
 
 **Table of Contents**  *generated with [DocToc](http://doctoc.herokuapp.com/)*
 
@@ -217,8 +219,8 @@ Multiline comments may be nested:
 
 UCL supports external macros both multiline and single line ones:
 ```nginx
-.macro "sometext";
-.macro {
+.macro_name "sometext";
+.macro_name {
     Some long text
     ....
 };
@@ -229,12 +231,12 @@ arguments themselves are the UCL object 
 options:
 
 ```nginx
-.macro(param=value) "something";
-.macro(param={key=value}) "something";
-.macro(.include "params.conf") "something";
-.macro(#this is multiline macro
+.macro_name(param=value) "something";
+.macro_name(param={key=value}) "something";
+.macro_name(.include "params.conf") "something";
+.macro_name(#this is multiline macro
 param = [value1, value2]) "something";
-.macro(key="()") "something";
+.macro_name(key="()") "something";
 ```
 
 UCL also provide a convenient `include` macro to load content from another 
files

Modified: head/contrib/libucl/configure.ac
==============================================================================
--- head/contrib/libucl/configure.ac    Sun Feb 19 17:35:14 2017        
(r313952)
+++ head/contrib/libucl/configure.ac    Sun Feb 19 17:37:16 2017        
(r313953)
@@ -39,6 +39,7 @@ AC_CHECK_HEADERS_ONCE([stdarg.h])
 AC_CHECK_HEADERS_ONCE([stdbool.h])
 AC_CHECK_HEADERS_ONCE([stdint.h])
 AC_CHECK_HEADERS_ONCE([string.h])
+AC_CHECK_HEADERS_ONCE([strings.h])
 AC_CHECK_HEADERS_ONCE([unistd.h])
 AC_CHECK_HEADERS_ONCE([ctype.h])
 AC_CHECK_HEADERS_ONCE([errno.h])

Modified: head/contrib/libucl/include/ucl.h
==============================================================================
--- head/contrib/libucl/include/ucl.h   Sun Feb 19 17:35:14 2017        
(r313952)
+++ head/contrib/libucl/include/ucl.h   Sun Feb 19 17:37:16 2017        
(r313953)
@@ -154,7 +154,8 @@ typedef enum ucl_parser_flags {
        UCL_PARSER_NO_TIME = (1 << 2), /**< Do not parse time and treat time 
values as strings */
        UCL_PARSER_NO_IMPLICIT_ARRAYS = (1 << 3), /** Create explicit arrays 
instead of implicit ones */
        UCL_PARSER_SAVE_COMMENTS = (1 << 4), /** Save comments in the parser 
context */
-       UCL_PARSER_DISABLE_MACRO = (1 << 5) /** Treat macros as comments */
+       UCL_PARSER_DISABLE_MACRO = (1 << 5), /** Treat macros as comments */
+       UCL_PARSER_NO_FILEVARS = (1 << 6) /** Do not set file vars */
 } ucl_parser_flags_t;
 
 /**
@@ -205,7 +206,8 @@ enum ucl_duplicate_strategy {
 enum ucl_parse_type {
        UCL_PARSE_UCL = 0, /**< Default ucl format */
        UCL_PARSE_MSGPACK, /**< Message pack input format */
-       UCL_PARSE_CSEXP /**< Canonical S-expressions */
+       UCL_PARSE_CSEXP, /**< Canonical S-expressions */
+       UCL_PARSE_AUTO /**< Try to detect parse type */
 };
 
 /**
@@ -227,7 +229,7 @@ typedef struct ucl_object_s {
        const char *key;                                                /**< 
Key of an object           */
        struct ucl_object_s *next;                              /**< Array 
handle                       */
        struct ucl_object_s *prev;                              /**< Array 
handle                       */
-       uint32_t keylen;                                                /**< 
Lenght of a key            */
+       uint32_t keylen;                                                /**< 
Length of a key            */
        uint32_t len;                                                   /**< 
Size of an object          */
        uint32_t ref;                                                   /**< 
Reference count            */
        uint16_t flags;                                                 /**< 
Object flags                       */
@@ -831,10 +833,29 @@ UCL_EXTERN ucl_object_iter_t ucl_object_
  * 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
@@ -1016,6 +1037,7 @@ UCL_EXTERN bool ucl_parser_add_string_pr
  * Load and add data from a file
  * @param parser parser structure
  * @param filename the name of file
+ * @param err if *err is NULL it is set to parser error
  * @return true if chunk has been added and false in case of error
  */
 UCL_EXTERN bool ucl_parser_add_file (struct ucl_parser *parser,
@@ -1025,6 +1047,7 @@ UCL_EXTERN bool ucl_parser_add_file (str
  * Load and add data from a file
  * @param parser parser structure
  * @param filename the name of file
+ * @param err if *err is NULL it is set to parser error
  * @param priority the desired priority of a chunk (only 4 least significant 
bits
  * are considered for this parameter)
  * @return true if chunk has been added and false in case of error
@@ -1069,6 +1092,21 @@ UCL_EXTERN bool ucl_parser_add_fd_priori
                int fd, unsigned priority);
 
 /**
+ * Load and add data from a file descriptor
+ * @param parser parser structure
+ * @param filename the name of file
+ * @param err if *err is NULL it is set to parser error
+ * @param priority the desired priority of a chunk (only 4 least significant 
bits
+ * are considered for this parameter)
+ * @param strat Merge strategy to use while parsing this file
+ * @param parse_type Parser type to use while parsing this file
+ * @return true if chunk has been added and false in case of error
+ */
+UCL_EXTERN bool ucl_parser_add_fd_full (struct ucl_parser *parser, int fd,
+               unsigned priority, enum ucl_duplicate_strategy strat,
+               enum ucl_parse_type parse_type);
+
+/**
  * Provide a UCL_ARRAY of paths to search for include files. The object is
  * copied so caller must unref the object.
  * @param parser parser structure

Modified: head/contrib/libucl/lua/lua_ucl.c
==============================================================================
--- head/contrib/libucl/lua/lua_ucl.c   Sun Feb 19 17:35:14 2017        
(r313952)
+++ head/contrib/libucl/lua/lua_ucl.c   Sun Feb 19 17:37:16 2017        
(r313953)
@@ -29,7 +29,6 @@
 #include "ucl_internal.h"
 #include "lua_ucl.h"
 #include <strings.h>
-#include <zconf.h>
 
 /***
  * @module ucl
@@ -187,6 +186,8 @@ ucl_object_lua_push_array (lua_State *L,
                        lua_rawseti (L, -2, i);
                        i ++;
                }
+
+               ucl_object_iterate_free (it);
        }
        else {
                /* Optimize allocation by preallocation of table */
@@ -482,7 +483,7 @@ static int
 lua_ucl_parser_init (lua_State *L)
 {
        struct ucl_parser *parser, **pparser;
-       int flags = 0;
+       int flags = UCL_PARSER_NO_FILEVARS;
 
        if (lua_gettop (L) >= 1) {
                flags = lua_tonumber (L, 1);
@@ -524,6 +525,27 @@ lua_ucl_push_opaque (lua_State *L, ucl_o
        lua_setmetatable (L, -2);
 }
 
+static inline enum ucl_parse_type
+lua_ucl_str_to_parse_type (const char *str)
+{
+       enum ucl_parse_type type = UCL_PARSE_UCL;
+
+       if (str != NULL) {
+               if (strcasecmp (str, "msgpack") == 0) {
+                       type = UCL_PARSE_MSGPACK;
+               }
+               else if (strcasecmp (str, "sexp") == 0 ||
+                               strcasecmp (str, "csexp") == 0) {
+                       type = UCL_PARSE_CSEXP;
+               }
+               else if (strcasecmp (str, "auto") == 0) {
+                       type = UCL_PARSE_AUTO;
+               }
+       }
+
+       return type;
+}
+
 /***
  * @method parser:parse_file(name)
  * Parse UCL object from file.
@@ -579,13 +601,19 @@ lua_ucl_parser_parse_string (lua_State *
        struct ucl_parser *parser;
        const char *string;
        size_t llen;
+       enum ucl_parse_type type = UCL_PARSE_UCL;
        int ret = 2;
 
        parser = lua_ucl_parser_get (L, 1);
        string = luaL_checklstring (L, 2, &llen);
 
+       if (lua_type (L, 3) == LUA_TSTRING) {
+               type = lua_ucl_str_to_parse_type (lua_tostring (L, 3));
+       }
+
        if (parser != NULL && string != NULL) {
-               if (ucl_parser_add_chunk (parser, (const unsigned char 
*)string, llen)) {
+               if (ucl_parser_add_chunk_full (parser, (const unsigned char 
*)string,
+                               llen, 0, UCL_DUPLICATE_APPEND, type)) {
                        lua_pushboolean (L, true);
                        ret = 1;
                }
@@ -761,6 +789,28 @@ lua_ucl_object_unwrap (lua_State *L)
        return 1;
 }
 
+static inline enum ucl_emitter
+lua_ucl_str_to_emit_type (const char *strtype)
+{
+       enum ucl_emitter format = UCL_EMIT_JSON_COMPACT;
+
+       if (strcasecmp (strtype, "json") == 0) {
+               format = UCL_EMIT_JSON;
+       }
+       else if (strcasecmp (strtype, "json-compact") == 0) {
+               format = UCL_EMIT_JSON_COMPACT;
+       }
+       else if (strcasecmp (strtype, "yaml") == 0) {
+               format = UCL_EMIT_YAML;
+       }
+       else if (strcasecmp (strtype, "config") == 0 ||
+                       strcasecmp (strtype, "ucl") == 0) {
+               format = UCL_EMIT_CONFIG;
+       }
+
+       return format;
+}
+
 /***
  * @method object:tostring(type)
  * Unwraps opaque ucl object to string (json by default). Optionally you can
@@ -787,19 +837,7 @@ lua_ucl_object_tostring (lua_State *L)
                        if (lua_type (L, 2) == LUA_TSTRING) {
                                const char *strtype = lua_tostring (L, 2);
 
-                               if (strcasecmp (strtype, "json") == 0) {
-                                       format = UCL_EMIT_JSON;
-                               }
-                               else if (strcasecmp (strtype, "json-compact") 
== 0) {
-                                       format = UCL_EMIT_JSON_COMPACT;
-                               }
-                               else if (strcasecmp (strtype, "yaml") == 0) {
-                                       format = UCL_EMIT_YAML;
-                               }
-                               else if (strcasecmp (strtype, "config") == 0 ||
-                                               strcasecmp (strtype, "ucl") == 
0) {
-                                       format = UCL_EMIT_CONFIG;
-                               }
+                               format = lua_ucl_str_to_emit_type (strtype);
                        }
                }
 
@@ -1088,6 +1126,9 @@ lua_ucl_to_format (lua_State *L)
                                strcasecmp (strtype, "ucl") == 0) {
                                format = UCL_EMIT_CONFIG;
                        }
+                       else if (strcasecmp (strtype, "msgpack") == 0) {
+                               format = UCL_EMIT_MSGPACK;
+                       }
                }
        }
 

Modified: head/contrib/libucl/src/ucl_emitter_utils.c
==============================================================================
--- head/contrib/libucl/src/ucl_emitter_utils.c Sun Feb 19 17:35:14 2017        
(r313952)
+++ head/contrib/libucl/src/ucl_emitter_utils.c Sun Feb 19 17:37:16 2017        
(r313953)
@@ -102,7 +102,7 @@ ucl_elt_string_write_json (const char *s
        func->ucl_emitter_append_character ('"', 1, func->ud);
 
        while (size) {
-               if (ucl_test_character (*p, UCL_CHARACTER_JSON_UNSAFE)) {
+               if (ucl_test_character (*p, 
UCL_CHARACTER_JSON_UNSAFE|UCL_CHARACTER_DENIED)) {
                        if (len > 0) {
                                func->ucl_emitter_append_len (c, len, func->ud);
                        }
@@ -128,6 +128,10 @@ ucl_elt_string_write_json (const char *s
                        case '"':
                                func->ucl_emitter_append_len ("\\\"", 2, 
func->ud);
                                break;
+                       default:
+                               /* Emit unicode unknown character */
+                               func->ucl_emitter_append_len ("\\uFFFD", 5, 
func->ud);
+                               break;
                        }
                        len = 0;
                        c = ++p;
@@ -138,9 +142,11 @@ ucl_elt_string_write_json (const char *s
                }
                size --;
        }
+
        if (len > 0) {
                func->ucl_emitter_append_len (c, len, func->ud);
        }
+
        func->ucl_emitter_append_character ('"', 1, func->ud);
 }
 

Modified: head/contrib/libucl/src/ucl_internal.h
==============================================================================
--- head/contrib/libucl/src/ucl_internal.h      Sun Feb 19 17:35:14 2017        
(r313952)
+++ head/contrib/libucl/src/ucl_internal.h      Sun Feb 19 17:37:16 2017        
(r313953)
@@ -87,6 +87,9 @@
 #ifdef HAVE_STRING_H
 #include <string.h>
 #endif
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
 
 #include "utlist.h"
 #include "utstring.h"
@@ -127,19 +130,19 @@ enum ucl_parser_state {
 };
 
 enum ucl_character_type {
-       UCL_CHARACTER_DENIED = 0,
-       UCL_CHARACTER_KEY = 1,
-       UCL_CHARACTER_KEY_START = 1 << 1,
-       UCL_CHARACTER_WHITESPACE = 1 << 2,
-       UCL_CHARACTER_WHITESPACE_UNSAFE = 1 << 3,
-       UCL_CHARACTER_VALUE_END = 1 << 4,
-       UCL_CHARACTER_VALUE_STR = 1 << 5,
-       UCL_CHARACTER_VALUE_DIGIT = 1 << 6,
-       UCL_CHARACTER_VALUE_DIGIT_START = 1 << 7,
-       UCL_CHARACTER_ESCAPE = 1 << 8,
-       UCL_CHARACTER_KEY_SEP = 1 << 9,
-       UCL_CHARACTER_JSON_UNSAFE = 1 << 10,
-       UCL_CHARACTER_UCL_UNSAFE = 1 << 11
+       UCL_CHARACTER_DENIED = (1 << 0),
+       UCL_CHARACTER_KEY = (1 << 1),
+       UCL_CHARACTER_KEY_START = (1 << 2),
+       UCL_CHARACTER_WHITESPACE = (1 << 3),
+       UCL_CHARACTER_WHITESPACE_UNSAFE = (1 << 4),
+       UCL_CHARACTER_VALUE_END = (1 << 5),
+       UCL_CHARACTER_VALUE_STR = (1 << 6),
+       UCL_CHARACTER_VALUE_DIGIT = (1 << 7),
+       UCL_CHARACTER_VALUE_DIGIT_START = (1 << 8),
+       UCL_CHARACTER_ESCAPE = (1 << 9),
+       UCL_CHARACTER_KEY_SEP = (1 << 10),
+       UCL_CHARACTER_JSON_UNSAFE = (1 << 11),
+       UCL_CHARACTER_UCL_UNSAFE = (1 << 12)
 };
 
 struct ucl_macro {
@@ -568,4 +571,6 @@ bool ucl_parser_process_object_element (
  */
 bool ucl_parse_msgpack (struct ucl_parser *parser);
 
+bool ucl_parse_csexp (struct ucl_parser *parser);
+
 #endif /* UCL_INTERNAL_H_ */

Modified: head/contrib/libucl/src/ucl_parser.c
==============================================================================
--- head/contrib/libucl/src/ucl_parser.c        Sun Feb 19 17:35:14 2017        
(r313952)
+++ head/contrib/libucl/src/ucl_parser.c        Sun Feb 19 17:37:16 2017        
(r313953)
@@ -2469,8 +2469,10 @@ ucl_parser_new (int flags)
                parser->comments = ucl_object_typed_new (UCL_OBJECT);
        }
 
-       /* Initial assumption about filevars */
-       ucl_parser_set_filevars (parser, NULL, false);
+       if (!(flags & UCL_PARSER_NO_FILEVARS)) {
+               /* Initial assumption about filevars */
+               ucl_parser_set_filevars (parser, NULL, false);
+       }
 
        return parser;
 }
@@ -2617,6 +2619,19 @@ ucl_parser_add_chunk_full (struct ucl_pa
                        return false;
                }
 
+               if (parse_type == UCL_PARSE_AUTO && len > 0) {
+                       /* We need to detect parse type by the first symbol */
+                       if ((*data & 0x80) == 0x80 && (*data >= 0xdc && *data 
<= 0xdf)) {
+                               parse_type = UCL_PARSE_MSGPACK;
+                       }
+                       else if (*data == '(') {
+                               parse_type = UCL_PARSE_CSEXP;
+                       }
+                       else {
+                               parse_type = UCL_PARSE_UCL;
+                       }
+               }
+
                chunk->begin = data;
                chunk->remain = len;
                chunk->pos = chunk->begin;
@@ -2643,6 +2658,8 @@ ucl_parser_add_chunk_full (struct ucl_pa
                                return ucl_state_machine (parser);
                        case UCL_PARSE_MSGPACK:
                                return ucl_parse_msgpack (parser);
+                       case UCL_PARSE_CSEXP:
+                               return ucl_parse_csexp (parser);
                        }
                }
                else {

Modified: head/contrib/libucl/src/ucl_util.c
==============================================================================
--- head/contrib/libucl/src/ucl_util.c  Sun Feb 19 17:35:14 2017        
(r313952)
+++ head/contrib/libucl/src/ucl_util.c  Sun Feb 19 17:37:16 2017        
(r313953)
@@ -26,11 +26,17 @@
 #include "ucl_internal.h"
 #include "ucl_chartable.h"
 #include "kvec.h"
+#include <limits.h>
 #include <stdarg.h>
 #include <stdio.h> /* for snprintf */
 
 #ifndef _WIN32
 #include <glob.h>
+#include <sys/param.h>
+#else
+#ifndef NBBY
+#define NBBY 8
+#endif
 #endif
 
 #ifdef HAVE_LIBGEN_H
@@ -81,11 +87,6 @@ typedef kvec_t(ucl_object_t *) ucl_array
 #define MAP_FAILED      ((void *) -1)
 #endif
 
-#ifdef _WIN32
-#include <limits.h>
-#define NBBY CHAR_BIT
-#endif
-
 static void *ucl_mmap(char *addr, size_t length, int prot, int access, int fd, 
off_t offset)
 {
        void *map = NULL;
@@ -1854,9 +1855,11 @@ ucl_parser_add_file (struct ucl_parser *
                        UCL_PARSE_UCL);
 }
 
+
 bool
-ucl_parser_add_fd_priority (struct ucl_parser *parser, int fd,
-               unsigned priority)
+ucl_parser_add_fd_full (struct ucl_parser *parser, int fd,
+               unsigned priority, enum ucl_duplicate_strategy strat,
+               enum ucl_parse_type parse_type)
 {
        unsigned char *buf;
        size_t len;
@@ -1882,7 +1885,8 @@ ucl_parser_add_fd_priority (struct ucl_p
        }
        parser->cur_file = NULL;
        len = st.st_size;
-       ret = ucl_parser_add_chunk_priority (parser, buf, len, priority);
+       ret = ucl_parser_add_chunk_full (parser, buf, len, priority, strat,
+                       parse_type);
 
        if (len > 0) {
                ucl_munmap (buf, len);
@@ -1892,6 +1896,18 @@ ucl_parser_add_fd_priority (struct ucl_p
 }
 
 bool
+ucl_parser_add_fd_priority (struct ucl_parser *parser, int fd,
+               unsigned priority)
+{
+       if (parser == NULL) {
+               return false;
+       }
+
+       return ucl_parser_add_fd_full(parser, fd, parser->default_priority,
+                       UCL_DUPLICATE_APPEND, UCL_PARSE_UCL);
+}
+
+bool
 ucl_parser_add_fd (struct ucl_parser *parser, int fd)
 {
        if (parser == NULL) {
@@ -2488,6 +2504,10 @@ ucl_object_iterate_reset (ucl_object_ite
 
        UCL_SAFE_ITER_CHECK (rit);
 
+       if (rit->expl_it != NULL) {
+               UCL_FREE (sizeof (*rit->expl_it), rit->expl_it);
+       }
+
        rit->impl_it = obj;
        rit->expl_it = NULL;
 
@@ -2497,6 +2517,13 @@ ucl_object_iterate_reset (ucl_object_ite
 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;
 
@@ -2509,21 +2536,23 @@ ucl_object_iterate_safe (ucl_object_iter
        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);
                        }
                }
        }
@@ -2538,6 +2567,10 @@ ucl_object_iterate_free (ucl_object_iter
 
        UCL_SAFE_ITER_CHECK (rit);
 
+       if (rit->expl_it != NULL) {
+               UCL_FREE (sizeof (*rit->expl_it), rit->expl_it);
+       }
+
        UCL_FREE (sizeof (*rit), it);
 }
 
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to