xref: /freebsd/contrib/libucl/include/ucl.h (revision a0409676120c1e558d0ade943019934e0f15118d)
139ee7a7aSBaptiste Daroussin /* Copyright (c) 2013-2015, Vsevolod Stakhov
2c99fb5f9SBaptiste Daroussin  * All rights reserved.
3c99fb5f9SBaptiste Daroussin  *
4c99fb5f9SBaptiste Daroussin  * Redistribution and use in source and binary forms, with or without
5c99fb5f9SBaptiste Daroussin  * modification, are permitted provided that the following conditions are met:
6c99fb5f9SBaptiste Daroussin  *       * Redistributions of source code must retain the above copyright
7c99fb5f9SBaptiste Daroussin  *         notice, this list of conditions and the following disclaimer.
8c99fb5f9SBaptiste Daroussin  *       * Redistributions in binary form must reproduce the above copyright
9c99fb5f9SBaptiste Daroussin  *         notice, this list of conditions and the following disclaimer in the
10c99fb5f9SBaptiste Daroussin  *         documentation and/or other materials provided with the distribution.
11c99fb5f9SBaptiste Daroussin  *
12c99fb5f9SBaptiste Daroussin  * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY
13c99fb5f9SBaptiste Daroussin  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
14c99fb5f9SBaptiste Daroussin  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
15c99fb5f9SBaptiste Daroussin  * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY
16c99fb5f9SBaptiste Daroussin  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
17c99fb5f9SBaptiste Daroussin  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
18c99fb5f9SBaptiste Daroussin  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
19c99fb5f9SBaptiste Daroussin  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
20c99fb5f9SBaptiste Daroussin  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21c99fb5f9SBaptiste Daroussin  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22c99fb5f9SBaptiste Daroussin  */
23c99fb5f9SBaptiste Daroussin 
24c99fb5f9SBaptiste Daroussin #ifndef UCL_H_
25c99fb5f9SBaptiste Daroussin #define UCL_H_
26c99fb5f9SBaptiste Daroussin 
27c99fb5f9SBaptiste Daroussin #include <string.h>
28c99fb5f9SBaptiste Daroussin #include <stddef.h>
29c99fb5f9SBaptiste Daroussin #include <stdlib.h>
30c99fb5f9SBaptiste Daroussin #include <stdint.h>
31c99fb5f9SBaptiste Daroussin #include <stdbool.h>
32c99fb5f9SBaptiste Daroussin #include <stdarg.h>
33c99fb5f9SBaptiste Daroussin #include <stdio.h>
34c99fb5f9SBaptiste Daroussin 
3536c53d67SBaptiste Daroussin #ifdef _WIN32
3636c53d67SBaptiste Daroussin # define UCL_EXTERN __declspec(dllexport)
3736c53d67SBaptiste Daroussin #else
3836c53d67SBaptiste Daroussin # define UCL_EXTERN
3936c53d67SBaptiste Daroussin #endif
4036c53d67SBaptiste Daroussin 
41c99fb5f9SBaptiste Daroussin /**
42c99fb5f9SBaptiste Daroussin  * @mainpage
43c99fb5f9SBaptiste Daroussin  * This is a reference manual for UCL API. You may find the description of UCL format by following this
44c99fb5f9SBaptiste Daroussin  * [github repository](https://github.com/vstakhov/libucl).
45c99fb5f9SBaptiste Daroussin  *
46c99fb5f9SBaptiste Daroussin  * This manual has several main sections:
47c99fb5f9SBaptiste Daroussin  *  - @ref structures
48c99fb5f9SBaptiste Daroussin  *  - @ref utils
49c99fb5f9SBaptiste Daroussin  *  - @ref parser
50c99fb5f9SBaptiste Daroussin  *  - @ref emitter
51c99fb5f9SBaptiste Daroussin  */
52c99fb5f9SBaptiste Daroussin 
53c99fb5f9SBaptiste Daroussin /**
54c99fb5f9SBaptiste Daroussin  * @file ucl.h
55c99fb5f9SBaptiste Daroussin  * @brief UCL parsing and emitting functions
56c99fb5f9SBaptiste Daroussin  *
57c99fb5f9SBaptiste Daroussin  * UCL is universal configuration language, which is a form of
58c99fb5f9SBaptiste Daroussin  * JSON with less strict rules that make it more comfortable for
59c99fb5f9SBaptiste Daroussin  * using as a configuration language
60c99fb5f9SBaptiste Daroussin  */
61c99fb5f9SBaptiste Daroussin #ifdef  __cplusplus
62c99fb5f9SBaptiste Daroussin extern "C" {
63c99fb5f9SBaptiste Daroussin #endif
64c99fb5f9SBaptiste Daroussin /*
65c99fb5f9SBaptiste Daroussin  * Memory allocation utilities
66c99fb5f9SBaptiste Daroussin  * UCL_ALLOC(size) - allocate memory for UCL
67c99fb5f9SBaptiste Daroussin  * UCL_FREE(size, ptr) - free memory of specified size at ptr
68c99fb5f9SBaptiste Daroussin  * Default: malloc and free
69c99fb5f9SBaptiste Daroussin  */
70c99fb5f9SBaptiste Daroussin #ifndef UCL_ALLOC
71c99fb5f9SBaptiste Daroussin #define UCL_ALLOC(size) malloc(size)
72c99fb5f9SBaptiste Daroussin #endif
73c99fb5f9SBaptiste Daroussin #ifndef UCL_FREE
74c99fb5f9SBaptiste Daroussin #define UCL_FREE(size, ptr) free(ptr)
75c99fb5f9SBaptiste Daroussin #endif
76c99fb5f9SBaptiste Daroussin 
77c99fb5f9SBaptiste Daroussin #if    __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
78c99fb5f9SBaptiste Daroussin #define UCL_WARN_UNUSED_RESULT               \
79c99fb5f9SBaptiste Daroussin   __attribute__((warn_unused_result))
80c99fb5f9SBaptiste Daroussin #else
81c99fb5f9SBaptiste Daroussin #define UCL_WARN_UNUSED_RESULT
82c99fb5f9SBaptiste Daroussin #endif
83c99fb5f9SBaptiste Daroussin 
84b04a7a0bSBaptiste Daroussin #ifdef __GNUC__
85b04a7a0bSBaptiste Daroussin #define UCL_DEPRECATED(func) func __attribute__ ((deprecated))
86b04a7a0bSBaptiste Daroussin #elif defined(_MSC_VER)
87b04a7a0bSBaptiste Daroussin #define UCL_DEPRECATED(func) __declspec(deprecated) func
88b04a7a0bSBaptiste Daroussin #else
89b04a7a0bSBaptiste Daroussin #define UCL_DEPRECATED(func) func
90b04a7a0bSBaptiste Daroussin #endif
91b04a7a0bSBaptiste Daroussin 
92c99fb5f9SBaptiste Daroussin /**
93c99fb5f9SBaptiste Daroussin  * @defgroup structures Structures and types
94c99fb5f9SBaptiste Daroussin  * UCL defines several enumeration types used for error reporting or specifying flags and attributes.
95c99fb5f9SBaptiste Daroussin  *
96c99fb5f9SBaptiste Daroussin  * @{
97c99fb5f9SBaptiste Daroussin  */
98c99fb5f9SBaptiste Daroussin 
99c99fb5f9SBaptiste Daroussin /**
100c99fb5f9SBaptiste Daroussin  * The common error codes returned by ucl parser
101c99fb5f9SBaptiste Daroussin  */
102c99fb5f9SBaptiste Daroussin typedef enum ucl_error {
103c99fb5f9SBaptiste Daroussin 	UCL_EOK = 0, /**< No error */
104c99fb5f9SBaptiste Daroussin 	UCL_ESYNTAX, /**< Syntax error occurred during parsing */
105c99fb5f9SBaptiste Daroussin 	UCL_EIO, /**< IO error occurred during parsing */
106c99fb5f9SBaptiste Daroussin 	UCL_ESTATE, /**< Invalid state machine state */
107c99fb5f9SBaptiste Daroussin 	UCL_ENESTED, /**< Input has too many recursion levels */
108*a0409676SBaptiste Daroussin 	UCL_EUNPAIRED, /**< Input has too many recursion levels */
109c99fb5f9SBaptiste Daroussin 	UCL_EMACRO, /**< Error processing a macro */
110c99fb5f9SBaptiste Daroussin 	UCL_EINTERNAL, /**< Internal unclassified error */
111d9f0ce31SBaptiste Daroussin 	UCL_ESSL, /**< SSL error */
112*a0409676SBaptiste Daroussin 	UCL_EMERGE /**< A merge error occurred */
113c99fb5f9SBaptiste Daroussin } ucl_error_t;
114c99fb5f9SBaptiste Daroussin 
115c99fb5f9SBaptiste Daroussin /**
116c99fb5f9SBaptiste Daroussin  * #ucl_object_t may have one of specified types, some types are compatible with each other and some are not.
117c99fb5f9SBaptiste Daroussin  * For example, you can always convert #UCL_TIME to #UCL_FLOAT. Also you can convert #UCL_FLOAT to #UCL_INTEGER
118c99fb5f9SBaptiste Daroussin  * by loosing floating point. Every object may be converted to a string by #ucl_object_tostring_forced() function.
119c99fb5f9SBaptiste Daroussin  *
120c99fb5f9SBaptiste Daroussin  */
121c99fb5f9SBaptiste Daroussin typedef enum ucl_type {
122c99fb5f9SBaptiste Daroussin 	UCL_OBJECT = 0, /**< UCL object - key/value pairs */
123c99fb5f9SBaptiste Daroussin 	UCL_ARRAY, /**< UCL array */
124c99fb5f9SBaptiste Daroussin 	UCL_INT, /**< Integer number */
125c99fb5f9SBaptiste Daroussin 	UCL_FLOAT, /**< Floating point number */
126c99fb5f9SBaptiste Daroussin 	UCL_STRING, /**< Null terminated string */
127c99fb5f9SBaptiste Daroussin 	UCL_BOOLEAN, /**< Boolean value */
128c99fb5f9SBaptiste Daroussin 	UCL_TIME, /**< Time value (floating point number of seconds) */
129c99fb5f9SBaptiste Daroussin 	UCL_USERDATA, /**< Opaque userdata pointer (may be used in macros) */
130c99fb5f9SBaptiste Daroussin 	UCL_NULL /**< Null value */
131c99fb5f9SBaptiste Daroussin } ucl_type_t;
132c99fb5f9SBaptiste Daroussin 
133c99fb5f9SBaptiste Daroussin /**
134c99fb5f9SBaptiste Daroussin  * You can use one of these types to serialise #ucl_object_t by using ucl_object_emit().
135c99fb5f9SBaptiste Daroussin  */
136c99fb5f9SBaptiste Daroussin typedef enum ucl_emitter {
137c99fb5f9SBaptiste Daroussin 	UCL_EMIT_JSON = 0, /**< Emit fine formatted JSON */
138c99fb5f9SBaptiste Daroussin 	UCL_EMIT_JSON_COMPACT, /**< Emit compacted JSON */
139c99fb5f9SBaptiste Daroussin 	UCL_EMIT_CONFIG, /**< Emit human readable config format */
14039ee7a7aSBaptiste Daroussin 	UCL_EMIT_YAML, /**< Emit embedded YAML format */
14139ee7a7aSBaptiste Daroussin 	UCL_EMIT_MSGPACK, /**< Emit msgpack output */
14239ee7a7aSBaptiste Daroussin 	UCL_EMIT_MAX /**< Unsupported emitter type */
143c99fb5f9SBaptiste Daroussin } ucl_emitter_t;
144c99fb5f9SBaptiste Daroussin 
145c99fb5f9SBaptiste Daroussin /**
146c99fb5f9SBaptiste Daroussin  * These flags defines parser behaviour. If you specify #UCL_PARSER_ZEROCOPY you must ensure
147c99fb5f9SBaptiste Daroussin  * that the input memory is not freed if an object is in use. Moreover, if you want to use
148c99fb5f9SBaptiste Daroussin  * zero-terminated keys and string values then you should not use zero-copy mode, as in this case
149c99fb5f9SBaptiste Daroussin  * UCL still has to perform copying implicitly.
150c99fb5f9SBaptiste Daroussin  */
151c99fb5f9SBaptiste Daroussin typedef enum ucl_parser_flags {
152d9f0ce31SBaptiste Daroussin 	UCL_PARSER_DEFAULT = 0,       /**< No special flags */
153d9f0ce31SBaptiste Daroussin 	UCL_PARSER_KEY_LOWERCASE = (1 << 0), /**< Convert all keys to lower case */
154d9f0ce31SBaptiste Daroussin 	UCL_PARSER_ZEROCOPY = (1 << 1), /**< Parse input in zero-copy mode if possible */
155d9f0ce31SBaptiste Daroussin 	UCL_PARSER_NO_TIME = (1 << 2), /**< Do not parse time and treat time values as strings */
156d9f0ce31SBaptiste Daroussin 	UCL_PARSER_NO_IMPLICIT_ARRAYS = (1 << 3), /** Create explicit arrays instead of implicit ones */
157d9f0ce31SBaptiste Daroussin 	UCL_PARSER_SAVE_COMMENTS = (1 << 4), /** Save comments in the parser context */
15811dd9ed6SBaptiste Daroussin 	UCL_PARSER_DISABLE_MACRO = (1 << 5), /** Treat macros as comments */
15911dd9ed6SBaptiste Daroussin 	UCL_PARSER_NO_FILEVARS = (1 << 6) /** Do not set file vars */
160c99fb5f9SBaptiste Daroussin } ucl_parser_flags_t;
161c99fb5f9SBaptiste Daroussin 
162c99fb5f9SBaptiste Daroussin /**
163c99fb5f9SBaptiste Daroussin  * String conversion flags, that are used in #ucl_object_fromstring_common function.
164c99fb5f9SBaptiste Daroussin  */
165c99fb5f9SBaptiste Daroussin typedef enum ucl_string_flags {
16639ee7a7aSBaptiste Daroussin 	UCL_STRING_RAW = 0x0,     /**< Treat string as is */
167d9f0ce31SBaptiste Daroussin 	UCL_STRING_ESCAPE = (1 << 0),  /**< Perform JSON escape */
168d9f0ce31SBaptiste Daroussin 	UCL_STRING_TRIM = (1 << 1),    /**< Trim leading and trailing whitespaces */
169d9f0ce31SBaptiste Daroussin 	UCL_STRING_PARSE_BOOLEAN = (1 << 2),    /**< Parse passed string and detect boolean */
170d9f0ce31SBaptiste Daroussin 	UCL_STRING_PARSE_INT = (1 << 3),    /**< Parse passed string and detect integer number */
171d9f0ce31SBaptiste Daroussin 	UCL_STRING_PARSE_DOUBLE = (1 << 4),    /**< Parse passed string and detect integer or float number */
172d9f0ce31SBaptiste Daroussin 	UCL_STRING_PARSE_TIME = (1 << 5), /**< Parse time strings */
17397bd480fSBaptiste Daroussin 	UCL_STRING_PARSE_NUMBER =  UCL_STRING_PARSE_INT|UCL_STRING_PARSE_DOUBLE|UCL_STRING_PARSE_TIME,  /**<
174c99fb5f9SBaptiste Daroussin 									Parse passed string and detect number */
175c99fb5f9SBaptiste Daroussin 	UCL_STRING_PARSE =  UCL_STRING_PARSE_BOOLEAN|UCL_STRING_PARSE_NUMBER,   /**<
176c99fb5f9SBaptiste Daroussin 									Parse passed string (and detect booleans and numbers) */
177d9f0ce31SBaptiste Daroussin 	UCL_STRING_PARSE_BYTES = (1 << 6)  /**< Treat numbers as bytes */
178c99fb5f9SBaptiste Daroussin } ucl_string_flags_t;
179c99fb5f9SBaptiste Daroussin 
180c99fb5f9SBaptiste Daroussin /**
181*a0409676SBaptiste Daroussin  * Basic flags for an object (can use up to 12 bits as higher 4 bits are used
182*a0409676SBaptiste Daroussin  * for priorities)
183c99fb5f9SBaptiste Daroussin  */
184c99fb5f9SBaptiste Daroussin typedef enum ucl_object_flags {
18539ee7a7aSBaptiste Daroussin 	UCL_OBJECT_ALLOCATED_KEY = (1 << 0), /**< An object has key allocated internally */
18639ee7a7aSBaptiste Daroussin 	UCL_OBJECT_ALLOCATED_VALUE = (1 << 1), /**< An object has a string value allocated internally */
18739ee7a7aSBaptiste Daroussin 	UCL_OBJECT_NEED_KEY_ESCAPE = (1 << 2), /**< The key of an object need to be escaped on output */
18839ee7a7aSBaptiste Daroussin 	UCL_OBJECT_EPHEMERAL = (1 << 3), /**< Temporary object that does not need to be freed really */
18939ee7a7aSBaptiste Daroussin 	UCL_OBJECT_MULTILINE = (1 << 4), /**< String should be displayed as multiline string */
19039ee7a7aSBaptiste Daroussin 	UCL_OBJECT_MULTIVALUE = (1 << 5), /**< Object is a key with multiple values */
19139ee7a7aSBaptiste Daroussin 	UCL_OBJECT_INHERITED = (1 << 6), /**< Object has been inherited from another */
192*a0409676SBaptiste Daroussin 	UCL_OBJECT_BINARY = (1 << 7), /**< Object contains raw binary data */
193*a0409676SBaptiste Daroussin 	UCL_OBJECT_SQUOTED = (1 << 8) /**< Object has been enclosed in single quotes */
194c99fb5f9SBaptiste Daroussin } ucl_object_flags_t;
195c99fb5f9SBaptiste Daroussin 
196c99fb5f9SBaptiste Daroussin /**
19739ee7a7aSBaptiste Daroussin  * Duplicate policy types
19839ee7a7aSBaptiste Daroussin  */
19939ee7a7aSBaptiste Daroussin enum ucl_duplicate_strategy {
20039ee7a7aSBaptiste Daroussin 	UCL_DUPLICATE_APPEND = 0, /**< Default policy to merge based on priorities */
20139ee7a7aSBaptiste Daroussin 	UCL_DUPLICATE_MERGE,     /**< Merge new object with old one */
20239ee7a7aSBaptiste Daroussin 	UCL_DUPLICATE_REWRITE,   /**< Rewrite old keys */
20339ee7a7aSBaptiste Daroussin 	UCL_DUPLICATE_ERROR      /**< Stop parsing on duplicate found */
20439ee7a7aSBaptiste Daroussin };
20539ee7a7aSBaptiste Daroussin 
20639ee7a7aSBaptiste Daroussin /**
20739ee7a7aSBaptiste Daroussin  * Input format type
20839ee7a7aSBaptiste Daroussin  */
20939ee7a7aSBaptiste Daroussin enum ucl_parse_type {
21039ee7a7aSBaptiste Daroussin 	UCL_PARSE_UCL = 0, /**< Default ucl format */
21139ee7a7aSBaptiste Daroussin 	UCL_PARSE_MSGPACK, /**< Message pack input format */
21211dd9ed6SBaptiste Daroussin 	UCL_PARSE_CSEXP, /**< Canonical S-expressions */
21311dd9ed6SBaptiste Daroussin 	UCL_PARSE_AUTO /**< Try to detect parse type */
21439ee7a7aSBaptiste Daroussin };
21539ee7a7aSBaptiste Daroussin 
21639ee7a7aSBaptiste Daroussin /**
217c99fb5f9SBaptiste Daroussin  * UCL object structure. Please mention that the most of fields should not be touched by
218c99fb5f9SBaptiste Daroussin  * UCL users. In future, this structure may be converted to private one.
219c99fb5f9SBaptiste Daroussin  */
220c99fb5f9SBaptiste Daroussin typedef struct ucl_object_s {
221c99fb5f9SBaptiste Daroussin 	/**
222c99fb5f9SBaptiste Daroussin 	 * Variant value type
223c99fb5f9SBaptiste Daroussin 	 */
224c99fb5f9SBaptiste Daroussin 	union {
225c99fb5f9SBaptiste Daroussin 		int64_t iv;							/**< Int value of an object */
226c99fb5f9SBaptiste Daroussin 		const char *sv;						/**< String value of an object */
227c99fb5f9SBaptiste Daroussin 		double dv;							/**< Double value of an object */
2288e3b1ab2SBaptiste Daroussin 		void *av;							/**< Array					*/
229c99fb5f9SBaptiste Daroussin 		void *ov;							/**< Object					*/
230c99fb5f9SBaptiste Daroussin 		void* ud;							/**< Opaque user data		*/
231c99fb5f9SBaptiste Daroussin 	} value;
232c99fb5f9SBaptiste Daroussin 	const char *key;						/**< Key of an object		*/
233c99fb5f9SBaptiste Daroussin 	struct ucl_object_s *next;				/**< Array handle			*/
234c99fb5f9SBaptiste Daroussin 	struct ucl_object_s *prev;				/**< Array handle			*/
23511dd9ed6SBaptiste Daroussin 	uint32_t keylen;						/**< Length of a key		*/
2364bf54857SBaptiste Daroussin 	uint32_t len;							/**< Size of an object		*/
2374bf54857SBaptiste Daroussin 	uint32_t ref;							/**< Reference count		*/
238c99fb5f9SBaptiste Daroussin 	uint16_t flags;							/**< Object flags			*/
2394bf54857SBaptiste Daroussin 	uint16_t type;							/**< Real type				*/
2404bf54857SBaptiste Daroussin 	unsigned char* trash_stack[2];			/**< Pointer to allocated chunks */
241c99fb5f9SBaptiste Daroussin } ucl_object_t;
242c99fb5f9SBaptiste Daroussin 
2434bf54857SBaptiste Daroussin /**
2444bf54857SBaptiste Daroussin  * Destructor type for userdata objects
2454bf54857SBaptiste Daroussin  * @param ud user specified data pointer
2464bf54857SBaptiste Daroussin  */
2474bf54857SBaptiste Daroussin typedef void (*ucl_userdata_dtor)(void *ud);
2484bf54857SBaptiste Daroussin typedef const char* (*ucl_userdata_emitter)(void *ud);
2494bf54857SBaptiste Daroussin 
250c99fb5f9SBaptiste Daroussin /** @} */
251c99fb5f9SBaptiste Daroussin 
252c99fb5f9SBaptiste Daroussin /**
253c99fb5f9SBaptiste Daroussin  * @defgroup utils Utility functions
254c99fb5f9SBaptiste Daroussin  * A number of utility functions simplify handling of UCL objects
255c99fb5f9SBaptiste Daroussin  *
256c99fb5f9SBaptiste Daroussin  * @{
257c99fb5f9SBaptiste Daroussin  */
258c99fb5f9SBaptiste Daroussin /**
259c99fb5f9SBaptiste Daroussin  * Copy and return a key of an object, returned key is zero-terminated
260c99fb5f9SBaptiste Daroussin  * @param obj CL object
261c99fb5f9SBaptiste Daroussin  * @return zero terminated key
262c99fb5f9SBaptiste Daroussin  */
263b04a7a0bSBaptiste Daroussin UCL_EXTERN char* ucl_copy_key_trash (const ucl_object_t *obj);
264c99fb5f9SBaptiste Daroussin 
265c99fb5f9SBaptiste Daroussin /**
266c99fb5f9SBaptiste Daroussin  * Copy and return a string value of an object, returned key is zero-terminated
267c99fb5f9SBaptiste Daroussin  * @param obj CL object
268c99fb5f9SBaptiste Daroussin  * @return zero terminated string representation of object value
269c99fb5f9SBaptiste Daroussin  */
270b04a7a0bSBaptiste Daroussin UCL_EXTERN char* ucl_copy_value_trash (const ucl_object_t *obj);
271c99fb5f9SBaptiste Daroussin 
272c99fb5f9SBaptiste Daroussin /**
273c99fb5f9SBaptiste Daroussin  * Creates a new object
274c99fb5f9SBaptiste Daroussin  * @return new object
275c99fb5f9SBaptiste Daroussin  */
27697bd480fSBaptiste Daroussin UCL_EXTERN ucl_object_t* ucl_object_new (void) UCL_WARN_UNUSED_RESULT;
277c99fb5f9SBaptiste Daroussin 
278c99fb5f9SBaptiste Daroussin /**
279c99fb5f9SBaptiste Daroussin  * Create new object with type specified
280c99fb5f9SBaptiste Daroussin  * @param type type of a new object
281c99fb5f9SBaptiste Daroussin  * @return new object
282c99fb5f9SBaptiste Daroussin  */
2832e8ed2b8SBaptiste Daroussin UCL_EXTERN ucl_object_t* ucl_object_typed_new (ucl_type_t type) UCL_WARN_UNUSED_RESULT;
2842e8ed2b8SBaptiste Daroussin 
2852e8ed2b8SBaptiste Daroussin /**
2864bf54857SBaptiste Daroussin  * Create new object with type and priority specified
2874bf54857SBaptiste Daroussin  * @param type type of a new object
2884bf54857SBaptiste Daroussin  * @param priority priority of an object
2894bf54857SBaptiste Daroussin  * @return new object
2904bf54857SBaptiste Daroussin  */
2914bf54857SBaptiste Daroussin UCL_EXTERN ucl_object_t* ucl_object_new_full (ucl_type_t type, unsigned priority)
2924bf54857SBaptiste Daroussin 	UCL_WARN_UNUSED_RESULT;
2934bf54857SBaptiste Daroussin 
2944bf54857SBaptiste Daroussin /**
2954bf54857SBaptiste Daroussin  * Create new object with userdata dtor
2964bf54857SBaptiste Daroussin  * @param dtor destructor function
297d9f0ce31SBaptiste Daroussin  * @param emitter emitter for userdata
298d9f0ce31SBaptiste Daroussin  * @param ptr opaque pointer
2994bf54857SBaptiste Daroussin  * @return new object
3004bf54857SBaptiste Daroussin  */
3014bf54857SBaptiste Daroussin UCL_EXTERN ucl_object_t* ucl_object_new_userdata (ucl_userdata_dtor dtor,
302d9f0ce31SBaptiste Daroussin 		ucl_userdata_emitter emitter, void *ptr) UCL_WARN_UNUSED_RESULT;
3034bf54857SBaptiste Daroussin 
3044bf54857SBaptiste Daroussin /**
3054bf54857SBaptiste Daroussin  * Perform deep copy of an object copying everything
3064bf54857SBaptiste Daroussin  * @param other object to copy
3074bf54857SBaptiste Daroussin  * @return new object with refcount equal to 1
3084bf54857SBaptiste Daroussin  */
3094bf54857SBaptiste Daroussin UCL_EXTERN ucl_object_t * ucl_object_copy (const ucl_object_t *other)
3104bf54857SBaptiste Daroussin 	UCL_WARN_UNUSED_RESULT;
3114bf54857SBaptiste Daroussin 
3124bf54857SBaptiste Daroussin /**
3132e8ed2b8SBaptiste Daroussin  * Return the type of an object
3142e8ed2b8SBaptiste Daroussin  * @return the object type
3152e8ed2b8SBaptiste Daroussin  */
3162e8ed2b8SBaptiste Daroussin UCL_EXTERN ucl_type_t ucl_object_type (const ucl_object_t *obj);
317c99fb5f9SBaptiste Daroussin 
318c99fb5f9SBaptiste Daroussin /**
319d9f0ce31SBaptiste Daroussin  * Converts ucl object type to its string representation
320d9f0ce31SBaptiste Daroussin  * @param type type of object
321d9f0ce31SBaptiste Daroussin  * @return constant string describing type
322d9f0ce31SBaptiste Daroussin  */
323d9f0ce31SBaptiste Daroussin UCL_EXTERN const char * ucl_object_type_to_string (ucl_type_t type);
324d9f0ce31SBaptiste Daroussin 
325d9f0ce31SBaptiste Daroussin /**
326d9f0ce31SBaptiste Daroussin  * Converts string that represents ucl type to real ucl type enum
327d9f0ce31SBaptiste Daroussin  * @param input C string with name of type
328d9f0ce31SBaptiste Daroussin  * @param res resulting target
329d9f0ce31SBaptiste Daroussin  * @return true if `input` is a name of type stored in `res`
330d9f0ce31SBaptiste Daroussin  */
331d9f0ce31SBaptiste Daroussin UCL_EXTERN bool ucl_object_string_to_type (const char *input, ucl_type_t *res);
332d9f0ce31SBaptiste Daroussin 
333d9f0ce31SBaptiste Daroussin /**
334c99fb5f9SBaptiste Daroussin  * Convert any string to an ucl object making the specified transformations
335c99fb5f9SBaptiste Daroussin  * @param str fixed size or NULL terminated string
336c99fb5f9SBaptiste Daroussin  * @param len length (if len is zero, than str is treated as NULL terminated)
337c99fb5f9SBaptiste Daroussin  * @param flags conversion flags
338c99fb5f9SBaptiste Daroussin  * @return new object
339c99fb5f9SBaptiste Daroussin  */
34036c53d67SBaptiste Daroussin UCL_EXTERN ucl_object_t * ucl_object_fromstring_common (const char *str, size_t len,
341c99fb5f9SBaptiste Daroussin 		enum ucl_string_flags flags) UCL_WARN_UNUSED_RESULT;
342c99fb5f9SBaptiste Daroussin 
343c99fb5f9SBaptiste Daroussin /**
344c99fb5f9SBaptiste Daroussin  * Create a UCL object from the specified string
345c99fb5f9SBaptiste Daroussin  * @param str NULL terminated string, will be json escaped
346c99fb5f9SBaptiste Daroussin  * @return new object
347c99fb5f9SBaptiste Daroussin  */
348b04a7a0bSBaptiste Daroussin UCL_EXTERN ucl_object_t *ucl_object_fromstring (const char *str) UCL_WARN_UNUSED_RESULT;
349c99fb5f9SBaptiste Daroussin 
350c99fb5f9SBaptiste Daroussin /**
351c99fb5f9SBaptiste Daroussin  * Create a UCL object from the specified string
352c99fb5f9SBaptiste Daroussin  * @param str fixed size string, will be json escaped
353c99fb5f9SBaptiste Daroussin  * @param len length of a string
354c99fb5f9SBaptiste Daroussin  * @return new object
355c99fb5f9SBaptiste Daroussin  */
356b04a7a0bSBaptiste Daroussin UCL_EXTERN ucl_object_t *ucl_object_fromlstring (const char *str,
357b04a7a0bSBaptiste Daroussin 		size_t len) UCL_WARN_UNUSED_RESULT;
358c99fb5f9SBaptiste Daroussin 
359c99fb5f9SBaptiste Daroussin /**
360c99fb5f9SBaptiste Daroussin  * Create an object from an integer number
361c99fb5f9SBaptiste Daroussin  * @param iv number
362c99fb5f9SBaptiste Daroussin  * @return new object
363c99fb5f9SBaptiste Daroussin  */
364b04a7a0bSBaptiste Daroussin UCL_EXTERN ucl_object_t* ucl_object_fromint (int64_t iv) UCL_WARN_UNUSED_RESULT;
365c99fb5f9SBaptiste Daroussin 
366c99fb5f9SBaptiste Daroussin /**
367c99fb5f9SBaptiste Daroussin  * Create an object from a float number
368c99fb5f9SBaptiste Daroussin  * @param dv number
369c99fb5f9SBaptiste Daroussin  * @return new object
370c99fb5f9SBaptiste Daroussin  */
371b04a7a0bSBaptiste Daroussin UCL_EXTERN ucl_object_t* ucl_object_fromdouble (double dv) UCL_WARN_UNUSED_RESULT;
372c99fb5f9SBaptiste Daroussin 
373c99fb5f9SBaptiste Daroussin /**
374c99fb5f9SBaptiste Daroussin  * Create an object from a boolean
375c99fb5f9SBaptiste Daroussin  * @param bv bool value
376c99fb5f9SBaptiste Daroussin  * @return new object
377c99fb5f9SBaptiste Daroussin  */
378b04a7a0bSBaptiste Daroussin UCL_EXTERN ucl_object_t* ucl_object_frombool (bool bv) UCL_WARN_UNUSED_RESULT;
379c99fb5f9SBaptiste Daroussin 
380c99fb5f9SBaptiste Daroussin /**
381c99fb5f9SBaptiste Daroussin  * Insert a object 'elt' to the hash 'top' and associate it with key 'key'
3824bf54857SBaptiste Daroussin  * @param top destination object (must be of type UCL_OBJECT)
383c99fb5f9SBaptiste Daroussin  * @param elt element to insert (must NOT be NULL)
384c99fb5f9SBaptiste Daroussin  * @param key key to associate with this object (either const or preallocated)
385c99fb5f9SBaptiste Daroussin  * @param keylen length of the key (or 0 for NULL terminated keys)
386c99fb5f9SBaptiste Daroussin  * @param copy_key make an internal copy of key
387b04a7a0bSBaptiste Daroussin  * @return true if key has been inserted
388c99fb5f9SBaptiste Daroussin  */
389b04a7a0bSBaptiste Daroussin UCL_EXTERN bool ucl_object_insert_key (ucl_object_t *top, ucl_object_t *elt,
390b04a7a0bSBaptiste Daroussin 		const char *key, size_t keylen, bool copy_key);
391c99fb5f9SBaptiste Daroussin 
392c99fb5f9SBaptiste Daroussin /**
393c99fb5f9SBaptiste Daroussin  * Replace a object 'elt' to the hash 'top' and associate it with key 'key', old object will be unrefed,
394c99fb5f9SBaptiste Daroussin  * if no object has been found this function works like ucl_object_insert_key()
3954bf54857SBaptiste Daroussin  * @param top destination object (must be of type UCL_OBJECT)
396c99fb5f9SBaptiste Daroussin  * @param elt element to insert (must NOT be NULL)
397c99fb5f9SBaptiste Daroussin  * @param key key to associate with this object (either const or preallocated)
398c99fb5f9SBaptiste Daroussin  * @param keylen length of the key (or 0 for NULL terminated keys)
399c99fb5f9SBaptiste Daroussin  * @param copy_key make an internal copy of key
400b04a7a0bSBaptiste Daroussin  * @return true if key has been inserted
401c99fb5f9SBaptiste Daroussin  */
402b04a7a0bSBaptiste Daroussin UCL_EXTERN bool ucl_object_replace_key (ucl_object_t *top, ucl_object_t *elt,
403b04a7a0bSBaptiste Daroussin 		const char *key, size_t keylen, bool copy_key);
404c99fb5f9SBaptiste Daroussin 
405c99fb5f9SBaptiste Daroussin /**
4064bf54857SBaptiste Daroussin  * Merge the keys from one object to another object. Overwrite on conflict
4074bf54857SBaptiste Daroussin  * @param top destination object (must be of type UCL_OBJECT)
4084bf54857SBaptiste Daroussin  * @param elt element to insert (must be of type UCL_OBJECT)
4094bf54857SBaptiste Daroussin  * @param copy copy rather than reference the elements
4104bf54857SBaptiste Daroussin  * @return true if all keys have been merged
4114bf54857SBaptiste Daroussin  */
4124bf54857SBaptiste Daroussin UCL_EXTERN bool ucl_object_merge (ucl_object_t *top, ucl_object_t *elt, bool copy);
4134bf54857SBaptiste Daroussin 
4144bf54857SBaptiste Daroussin /**
41536c53d67SBaptiste Daroussin  * Delete a object associated with key 'key', old object will be unrefered,
41636c53d67SBaptiste Daroussin  * @param top object
41736c53d67SBaptiste Daroussin  * @param key key associated to the object to remove
41836c53d67SBaptiste Daroussin  * @param keylen length of the key (or 0 for NULL terminated keys)
41936c53d67SBaptiste Daroussin  */
420b04a7a0bSBaptiste Daroussin UCL_EXTERN bool ucl_object_delete_keyl (ucl_object_t *top,
421b04a7a0bSBaptiste Daroussin 		const char *key, size_t keylen);
42236c53d67SBaptiste Daroussin 
42336c53d67SBaptiste Daroussin /**
42436c53d67SBaptiste Daroussin  * Delete a object associated with key 'key', old object will be unrefered,
42536c53d67SBaptiste Daroussin  * @param top object
42636c53d67SBaptiste Daroussin  * @param key key associated to the object to remove
42736c53d67SBaptiste Daroussin  */
428b04a7a0bSBaptiste Daroussin UCL_EXTERN bool ucl_object_delete_key (ucl_object_t *top,
429b04a7a0bSBaptiste Daroussin 		const char *key);
43036c53d67SBaptiste Daroussin 
43197bd480fSBaptiste Daroussin 
43297bd480fSBaptiste Daroussin /**
4334bf54857SBaptiste Daroussin  * Removes `key` from `top` object, returning the object that was removed. This
4344bf54857SBaptiste Daroussin  * object is not released, caller must unref the returned object when it is no
4354bf54857SBaptiste Daroussin  * longer needed.
43697bd480fSBaptiste Daroussin  * @param top object
43797bd480fSBaptiste Daroussin  * @param key key to remove
43897bd480fSBaptiste Daroussin  * @param keylen length of the key (or 0 for NULL terminated keys)
43997bd480fSBaptiste Daroussin  * @return removed object or NULL if object has not been found
44097bd480fSBaptiste Daroussin  */
44197bd480fSBaptiste Daroussin UCL_EXTERN ucl_object_t* ucl_object_pop_keyl (ucl_object_t *top, const char *key,
44297bd480fSBaptiste Daroussin 		size_t keylen) UCL_WARN_UNUSED_RESULT;
44397bd480fSBaptiste Daroussin 
44497bd480fSBaptiste Daroussin /**
4454bf54857SBaptiste Daroussin  * Removes `key` from `top` object returning the object that was removed. This
4464bf54857SBaptiste Daroussin  * object is not released, caller must unref the returned object when it is no
4474bf54857SBaptiste Daroussin  * longer needed.
44897bd480fSBaptiste Daroussin  * @param top object
44997bd480fSBaptiste Daroussin  * @param key key to remove
45097bd480fSBaptiste Daroussin  * @return removed object or NULL if object has not been found
45197bd480fSBaptiste Daroussin  */
45297bd480fSBaptiste Daroussin UCL_EXTERN ucl_object_t* ucl_object_pop_key (ucl_object_t *top, const char *key)
45397bd480fSBaptiste Daroussin 	UCL_WARN_UNUSED_RESULT;
45497bd480fSBaptiste Daroussin 
45536c53d67SBaptiste Daroussin /**
4564bf54857SBaptiste Daroussin  * Insert a object 'elt' to the hash 'top' and associate it with key 'key', if
4574bf54857SBaptiste Daroussin  * the specified key exist, try to merge its content
4584bf54857SBaptiste Daroussin  * @param top destination object (must be of type UCL_OBJECT)
459c99fb5f9SBaptiste Daroussin  * @param elt element to insert (must NOT be NULL)
460c99fb5f9SBaptiste Daroussin  * @param key key to associate with this object (either const or preallocated)
461c99fb5f9SBaptiste Daroussin  * @param keylen length of the key (or 0 for NULL terminated keys)
462c99fb5f9SBaptiste Daroussin  * @param copy_key make an internal copy of key
463b04a7a0bSBaptiste Daroussin  * @return true if key has been inserted
464c99fb5f9SBaptiste Daroussin  */
465b04a7a0bSBaptiste Daroussin UCL_EXTERN bool ucl_object_insert_key_merged (ucl_object_t *top, ucl_object_t *elt,
466b04a7a0bSBaptiste Daroussin 		const char *key, size_t keylen, bool copy_key);
467c99fb5f9SBaptiste Daroussin 
468c99fb5f9SBaptiste Daroussin /**
469*a0409676SBaptiste Daroussin  * Reserve space in ucl array or object for `elt` elements
470*a0409676SBaptiste Daroussin  * @param obj object to reserve
471*a0409676SBaptiste Daroussin  * @param reserved size to reserve in an object
472*a0409676SBaptiste Daroussin  * @return 0 on success, -1 on failure (i.e. ENOMEM)
473*a0409676SBaptiste Daroussin  */
474*a0409676SBaptiste Daroussin UCL_EXTERN bool ucl_object_reserve (ucl_object_t *obj, size_t reserved);
475*a0409676SBaptiste Daroussin 
476*a0409676SBaptiste Daroussin /**
4774bf54857SBaptiste Daroussin  * Append an element to the end of array object
4784bf54857SBaptiste Daroussin  * @param top destination object (must NOT be NULL)
479c99fb5f9SBaptiste Daroussin  * @param elt element to append (must NOT be NULL)
480b04a7a0bSBaptiste Daroussin  * @return true if value has been inserted
481c99fb5f9SBaptiste Daroussin  */
482b04a7a0bSBaptiste Daroussin UCL_EXTERN bool ucl_array_append (ucl_object_t *top,
483b04a7a0bSBaptiste Daroussin 		ucl_object_t *elt);
484c99fb5f9SBaptiste Daroussin 
485c99fb5f9SBaptiste Daroussin /**
486c99fb5f9SBaptiste Daroussin  * Append an element to the start of array object
4874bf54857SBaptiste Daroussin  * @param top destination object (must NOT be NULL)
488c99fb5f9SBaptiste Daroussin  * @param elt element to append (must NOT be NULL)
489b04a7a0bSBaptiste Daroussin  * @return true if value has been inserted
490c99fb5f9SBaptiste Daroussin  */
491b04a7a0bSBaptiste Daroussin UCL_EXTERN bool ucl_array_prepend (ucl_object_t *top,
492b04a7a0bSBaptiste Daroussin 		ucl_object_t *elt);
493c99fb5f9SBaptiste Daroussin 
494c99fb5f9SBaptiste Daroussin /**
4954bf54857SBaptiste Daroussin  * Merge all elements of second array into the first array
4964bf54857SBaptiste Daroussin  * @param top destination array (must be of type UCL_ARRAY)
4974bf54857SBaptiste Daroussin  * @param elt array to copy elements from (must be of type UCL_ARRAY)
4984bf54857SBaptiste Daroussin  * @param copy copy elements instead of referencing them
4994bf54857SBaptiste Daroussin  * @return true if arrays were merged
5004bf54857SBaptiste Daroussin  */
5014bf54857SBaptiste Daroussin UCL_EXTERN bool ucl_array_merge (ucl_object_t *top, ucl_object_t *elt,
5024bf54857SBaptiste Daroussin 		bool copy);
5034bf54857SBaptiste Daroussin 
5044bf54857SBaptiste Daroussin /**
5054bf54857SBaptiste Daroussin  * Removes an element `elt` from the array `top`, returning the object that was
5064bf54857SBaptiste Daroussin  * removed. This object is not released, caller must unref the returned object
5074bf54857SBaptiste Daroussin  * when it is no longer needed.
508c99fb5f9SBaptiste Daroussin  * @param top array ucl object
509c99fb5f9SBaptiste Daroussin  * @param elt element to remove
510c99fb5f9SBaptiste Daroussin  * @return removed element or NULL if `top` is NULL or not an array
511c99fb5f9SBaptiste Daroussin  */
512b04a7a0bSBaptiste Daroussin UCL_EXTERN ucl_object_t* ucl_array_delete (ucl_object_t *top,
513b04a7a0bSBaptiste Daroussin 		ucl_object_t *elt);
514c99fb5f9SBaptiste Daroussin 
515c99fb5f9SBaptiste Daroussin /**
516c99fb5f9SBaptiste Daroussin  * Returns the first element of the array `top`
517c99fb5f9SBaptiste Daroussin  * @param top array ucl object
518c99fb5f9SBaptiste Daroussin  * @return element or NULL if `top` is NULL or not an array
519c99fb5f9SBaptiste Daroussin  */
520b04a7a0bSBaptiste Daroussin UCL_EXTERN const ucl_object_t* ucl_array_head (const ucl_object_t *top);
521c99fb5f9SBaptiste Daroussin 
522c99fb5f9SBaptiste Daroussin /**
523c99fb5f9SBaptiste Daroussin  * Returns the last element of the array `top`
524c99fb5f9SBaptiste Daroussin  * @param top array ucl object
525c99fb5f9SBaptiste Daroussin  * @return element or NULL if `top` is NULL or not an array
526c99fb5f9SBaptiste Daroussin  */
527b04a7a0bSBaptiste Daroussin UCL_EXTERN const ucl_object_t* ucl_array_tail (const ucl_object_t *top);
528c99fb5f9SBaptiste Daroussin 
529c99fb5f9SBaptiste Daroussin /**
5304bf54857SBaptiste Daroussin  * Removes the last element from the array `top`, returning the object that was
5314bf54857SBaptiste Daroussin  * removed. This object is not released, caller must unref the returned object
5324bf54857SBaptiste Daroussin  * when it is no longer needed.
533c99fb5f9SBaptiste Daroussin  * @param top array ucl object
534c99fb5f9SBaptiste Daroussin  * @return removed element or NULL if `top` is NULL or not an array
535c99fb5f9SBaptiste Daroussin  */
53697bd480fSBaptiste Daroussin UCL_EXTERN ucl_object_t* ucl_array_pop_last (ucl_object_t *top);
537c99fb5f9SBaptiste Daroussin 
538c99fb5f9SBaptiste Daroussin /**
5394bf54857SBaptiste Daroussin  * Removes the first element from the array `top`, returning the object that was
5404bf54857SBaptiste Daroussin  * removed. This object is not released, caller must unref the returned object
5414bf54857SBaptiste Daroussin  * when it is no longer needed.
542c99fb5f9SBaptiste Daroussin  * @param top array ucl object
543c99fb5f9SBaptiste Daroussin  * @return removed element or NULL if `top` is NULL or not an array
544c99fb5f9SBaptiste Daroussin  */
54597bd480fSBaptiste Daroussin UCL_EXTERN ucl_object_t* ucl_array_pop_first (ucl_object_t *top);
546c99fb5f9SBaptiste Daroussin 
547c99fb5f9SBaptiste Daroussin /**
548*a0409676SBaptiste Daroussin  * Return size of the array `top`
549*a0409676SBaptiste Daroussin  * @param top object to get size from (must be of type UCL_ARRAY)
550*a0409676SBaptiste Daroussin  * @return size of the array
551*a0409676SBaptiste Daroussin  */
552*a0409676SBaptiste Daroussin UCL_EXTERN unsigned int ucl_array_size (const ucl_object_t *top);
553*a0409676SBaptiste Daroussin 
554*a0409676SBaptiste Daroussin /**
5554bf54857SBaptiste Daroussin  * Return object identified by index of the array `top`
5564bf54857SBaptiste Daroussin  * @param top object to get a key from (must be of type UCL_ARRAY)
5574bf54857SBaptiste Daroussin  * @param index array index to return
5584bf54857SBaptiste Daroussin  * @return object at the specified index or NULL if index is not found
5594bf54857SBaptiste Daroussin  */
5604bf54857SBaptiste Daroussin UCL_EXTERN const ucl_object_t* ucl_array_find_index (const ucl_object_t *top,
5614bf54857SBaptiste Daroussin 		unsigned int index);
5624bf54857SBaptiste Daroussin 
5634bf54857SBaptiste Daroussin /**
56439ee7a7aSBaptiste Daroussin  * Return the index of `elt` in the array `top`
56539ee7a7aSBaptiste Daroussin  * @param top object to get a key from (must be of type UCL_ARRAY)
56639ee7a7aSBaptiste Daroussin  * @param elt element to find index of (must NOT be NULL)
56739ee7a7aSBaptiste Daroussin  * @return index of `elt` in the array `top or (unsigned int)-1 if `elt` is not found
56839ee7a7aSBaptiste Daroussin  */
56939ee7a7aSBaptiste Daroussin UCL_EXTERN unsigned int ucl_array_index_of (ucl_object_t *top,
57039ee7a7aSBaptiste Daroussin 		ucl_object_t *elt);
57139ee7a7aSBaptiste Daroussin 
57239ee7a7aSBaptiste Daroussin /**
5734bf54857SBaptiste Daroussin  * Replace an element in an array with a different element, returning the object
5744bf54857SBaptiste Daroussin  * that was replaced. This object is not released, caller must unref the
5754bf54857SBaptiste Daroussin  * returned object when it is no longer needed.
5764bf54857SBaptiste Daroussin  * @param top destination object (must be of type UCL_ARRAY)
5774bf54857SBaptiste Daroussin  * @param elt element to append (must NOT be NULL)
5784bf54857SBaptiste Daroussin  * @param index array index in destination to overwrite with elt
5794bf54857SBaptiste Daroussin  * @return object that was replaced or NULL if index is not found
5804bf54857SBaptiste Daroussin  */
5814bf54857SBaptiste Daroussin ucl_object_t *
5824bf54857SBaptiste Daroussin ucl_array_replace_index (ucl_object_t *top, ucl_object_t *elt,
5834bf54857SBaptiste Daroussin 	unsigned int index);
5844bf54857SBaptiste Daroussin 
5854bf54857SBaptiste Daroussin /**
586c99fb5f9SBaptiste Daroussin  * Append a element to another element forming an implicit array
587c99fb5f9SBaptiste Daroussin  * @param head head to append (may be NULL)
588c99fb5f9SBaptiste Daroussin  * @param elt new element
5894bf54857SBaptiste Daroussin  * @return the new implicit array
590c99fb5f9SBaptiste Daroussin  */
59197bd480fSBaptiste Daroussin UCL_EXTERN ucl_object_t * ucl_elt_append (ucl_object_t *head,
592b04a7a0bSBaptiste Daroussin 		ucl_object_t *elt);
593c99fb5f9SBaptiste Daroussin 
594c99fb5f9SBaptiste Daroussin /**
595c99fb5f9SBaptiste Daroussin  * Converts an object to double value
596c99fb5f9SBaptiste Daroussin  * @param obj CL object
597c99fb5f9SBaptiste Daroussin  * @param target target double variable
598c99fb5f9SBaptiste Daroussin  * @return true if conversion was successful
599c99fb5f9SBaptiste Daroussin  */
600b04a7a0bSBaptiste Daroussin UCL_EXTERN bool ucl_object_todouble_safe (const ucl_object_t *obj, double *target);
601c99fb5f9SBaptiste Daroussin 
602c99fb5f9SBaptiste Daroussin /**
603c99fb5f9SBaptiste Daroussin  * Unsafe version of \ref ucl_obj_todouble_safe
604c99fb5f9SBaptiste Daroussin  * @param obj CL object
605c99fb5f9SBaptiste Daroussin  * @return double value
606c99fb5f9SBaptiste Daroussin  */
607b04a7a0bSBaptiste Daroussin UCL_EXTERN double ucl_object_todouble (const ucl_object_t *obj);
608c99fb5f9SBaptiste Daroussin 
609c99fb5f9SBaptiste Daroussin /**
610c99fb5f9SBaptiste Daroussin  * Converts an object to integer value
611c99fb5f9SBaptiste Daroussin  * @param obj CL object
612c99fb5f9SBaptiste Daroussin  * @param target target integer variable
613c99fb5f9SBaptiste Daroussin  * @return true if conversion was successful
614c99fb5f9SBaptiste Daroussin  */
615b04a7a0bSBaptiste Daroussin UCL_EXTERN bool ucl_object_toint_safe (const ucl_object_t *obj, int64_t *target);
616c99fb5f9SBaptiste Daroussin 
617c99fb5f9SBaptiste Daroussin /**
618c99fb5f9SBaptiste Daroussin  * Unsafe version of \ref ucl_obj_toint_safe
619c99fb5f9SBaptiste Daroussin  * @param obj CL object
620c99fb5f9SBaptiste Daroussin  * @return int value
621c99fb5f9SBaptiste Daroussin  */
622b04a7a0bSBaptiste Daroussin UCL_EXTERN int64_t ucl_object_toint (const ucl_object_t *obj);
623c99fb5f9SBaptiste Daroussin 
624c99fb5f9SBaptiste Daroussin /**
625c99fb5f9SBaptiste Daroussin  * Converts an object to boolean value
626c99fb5f9SBaptiste Daroussin  * @param obj CL object
627c99fb5f9SBaptiste Daroussin  * @param target target boolean variable
628c99fb5f9SBaptiste Daroussin  * @return true if conversion was successful
629c99fb5f9SBaptiste Daroussin  */
630b04a7a0bSBaptiste Daroussin UCL_EXTERN bool ucl_object_toboolean_safe (const ucl_object_t *obj, bool *target);
631c99fb5f9SBaptiste Daroussin 
632c99fb5f9SBaptiste Daroussin /**
633c99fb5f9SBaptiste Daroussin  * Unsafe version of \ref ucl_obj_toboolean_safe
634c99fb5f9SBaptiste Daroussin  * @param obj CL object
635c99fb5f9SBaptiste Daroussin  * @return boolean value
636c99fb5f9SBaptiste Daroussin  */
637b04a7a0bSBaptiste Daroussin UCL_EXTERN bool ucl_object_toboolean (const ucl_object_t *obj);
638c99fb5f9SBaptiste Daroussin 
639c99fb5f9SBaptiste Daroussin /**
640c99fb5f9SBaptiste Daroussin  * Converts an object to string value
641c99fb5f9SBaptiste Daroussin  * @param obj CL object
642c99fb5f9SBaptiste Daroussin  * @param target target string variable, no need to free value
643c99fb5f9SBaptiste Daroussin  * @return true if conversion was successful
644c99fb5f9SBaptiste Daroussin  */
645b04a7a0bSBaptiste Daroussin UCL_EXTERN bool ucl_object_tostring_safe (const ucl_object_t *obj, const char **target);
646c99fb5f9SBaptiste Daroussin 
647c99fb5f9SBaptiste Daroussin /**
648c99fb5f9SBaptiste Daroussin  * Unsafe version of \ref ucl_obj_tostring_safe
649c99fb5f9SBaptiste Daroussin  * @param obj CL object
650c99fb5f9SBaptiste Daroussin  * @return string value
651c99fb5f9SBaptiste Daroussin  */
652b04a7a0bSBaptiste Daroussin UCL_EXTERN const char* ucl_object_tostring (const ucl_object_t *obj);
653c99fb5f9SBaptiste Daroussin 
654c99fb5f9SBaptiste Daroussin /**
655c99fb5f9SBaptiste Daroussin  * Convert any object to a string in JSON notation if needed
656c99fb5f9SBaptiste Daroussin  * @param obj CL object
657c99fb5f9SBaptiste Daroussin  * @return string value
658c99fb5f9SBaptiste Daroussin  */
659b04a7a0bSBaptiste Daroussin UCL_EXTERN const char* ucl_object_tostring_forced (const ucl_object_t *obj);
660c99fb5f9SBaptiste Daroussin 
661c99fb5f9SBaptiste Daroussin /**
662c99fb5f9SBaptiste Daroussin  * Return string as char * and len, string may be not zero terminated, more efficient that \ref ucl_obj_tostring as it
663c99fb5f9SBaptiste Daroussin  * allows zero-copy (if #UCL_PARSER_ZEROCOPY has been used during parsing)
664c99fb5f9SBaptiste Daroussin  * @param obj CL object
665c99fb5f9SBaptiste Daroussin  * @param target target string variable, no need to free value
666c99fb5f9SBaptiste Daroussin  * @param tlen target length
667c99fb5f9SBaptiste Daroussin  * @return true if conversion was successful
668c99fb5f9SBaptiste Daroussin  */
669b04a7a0bSBaptiste Daroussin UCL_EXTERN bool ucl_object_tolstring_safe (const ucl_object_t *obj,
67097bd480fSBaptiste Daroussin 		const char **target, size_t *tlen);
671c99fb5f9SBaptiste Daroussin 
672c99fb5f9SBaptiste Daroussin /**
673c99fb5f9SBaptiste Daroussin  * Unsafe version of \ref ucl_obj_tolstring_safe
674c99fb5f9SBaptiste Daroussin  * @param obj CL object
675c99fb5f9SBaptiste Daroussin  * @return string value
676c99fb5f9SBaptiste Daroussin  */
677b04a7a0bSBaptiste Daroussin UCL_EXTERN const char* ucl_object_tolstring (const ucl_object_t *obj, size_t *tlen);
678c99fb5f9SBaptiste Daroussin 
679c99fb5f9SBaptiste Daroussin /**
680c99fb5f9SBaptiste Daroussin  * Return object identified by a key in the specified object
681c99fb5f9SBaptiste Daroussin  * @param obj object to get a key from (must be of type UCL_OBJECT)
682c99fb5f9SBaptiste Daroussin  * @param key key to search
6834bf54857SBaptiste Daroussin  * @return object matching the specified key or NULL if key was not found
684c99fb5f9SBaptiste Daroussin  */
685d9f0ce31SBaptiste Daroussin UCL_EXTERN const ucl_object_t* ucl_object_lookup (const ucl_object_t *obj,
686b04a7a0bSBaptiste Daroussin 		const char *key);
687d9f0ce31SBaptiste Daroussin #define ucl_object_find_key ucl_object_lookup
688c99fb5f9SBaptiste Daroussin 
689c99fb5f9SBaptiste Daroussin /**
69039ee7a7aSBaptiste Daroussin  * Return object identified by a key in the specified object, if the first key is
69139ee7a7aSBaptiste Daroussin  * not found then look for the next one. This process is repeated unless
69239ee7a7aSBaptiste Daroussin  * the next argument in the list is not NULL. So, `ucl_object_find_any_key(obj, key, NULL)`
69339ee7a7aSBaptiste Daroussin  * is equal to `ucl_object_find_key(obj, key)`
69439ee7a7aSBaptiste Daroussin  * @param obj object to get a key from (must be of type UCL_OBJECT)
69539ee7a7aSBaptiste Daroussin  * @param key key to search
69639ee7a7aSBaptiste Daroussin  * @param ... list of alternative keys to search (NULL terminated)
69739ee7a7aSBaptiste Daroussin  * @return object matching the specified key or NULL if key was not found
69839ee7a7aSBaptiste Daroussin  */
699d9f0ce31SBaptiste Daroussin UCL_EXTERN const ucl_object_t* ucl_object_lookup_any (const ucl_object_t *obj,
70039ee7a7aSBaptiste Daroussin 		const char *key, ...);
701d9f0ce31SBaptiste Daroussin #define ucl_object_find_any_key ucl_object_lookup_any
70239ee7a7aSBaptiste Daroussin 
70339ee7a7aSBaptiste Daroussin /**
704c99fb5f9SBaptiste Daroussin  * Return object identified by a fixed size key in the specified object
705c99fb5f9SBaptiste Daroussin  * @param obj object to get a key from (must be of type UCL_OBJECT)
706c99fb5f9SBaptiste Daroussin  * @param key key to search
707c99fb5f9SBaptiste Daroussin  * @param klen length of a key
7084bf54857SBaptiste Daroussin  * @return object matching the specified key or NULL if key was not found
709c99fb5f9SBaptiste Daroussin  */
710d9f0ce31SBaptiste Daroussin UCL_EXTERN const ucl_object_t* ucl_object_lookup_len (const ucl_object_t *obj,
711b04a7a0bSBaptiste Daroussin 		const char *key, size_t klen);
712d9f0ce31SBaptiste Daroussin #define ucl_object_find_keyl ucl_object_lookup_len
713c99fb5f9SBaptiste Daroussin 
714c99fb5f9SBaptiste Daroussin /**
7152e8ed2b8SBaptiste Daroussin  * Return object identified by dot notation string
7162e8ed2b8SBaptiste Daroussin  * @param obj object to search in
7172e8ed2b8SBaptiste Daroussin  * @param path dot.notation.path to the path to lookup. May use numeric .index on arrays
7182e8ed2b8SBaptiste Daroussin  * @return object matched the specified path or NULL if path is not found
7192e8ed2b8SBaptiste Daroussin  */
720d9f0ce31SBaptiste Daroussin UCL_EXTERN const ucl_object_t *ucl_object_lookup_path (const ucl_object_t *obj,
7212e8ed2b8SBaptiste Daroussin 		const char *path);
722d9f0ce31SBaptiste Daroussin #define ucl_lookup_path ucl_object_lookup_path
7232e8ed2b8SBaptiste Daroussin 
7242e8ed2b8SBaptiste Daroussin /**
72539ee7a7aSBaptiste Daroussin  * Return object identified by object notation string using arbitrary delimiter
72639ee7a7aSBaptiste Daroussin  * @param obj object to search in
72739ee7a7aSBaptiste Daroussin  * @param path dot.notation.path to the path to lookup. May use numeric .index on arrays
72839ee7a7aSBaptiste Daroussin  * @param sep the sepatorator to use in place of . (incase keys have . in them)
72939ee7a7aSBaptiste Daroussin  * @return object matched the specified path or NULL if path is not found
73039ee7a7aSBaptiste Daroussin  */
731d9f0ce31SBaptiste Daroussin UCL_EXTERN const ucl_object_t *ucl_object_lookup_path_char (const ucl_object_t *obj,
73239ee7a7aSBaptiste Daroussin 		const char *path, char sep);
733d9f0ce31SBaptiste Daroussin #define ucl_lookup_path_char ucl_object_lookup_path_char
73439ee7a7aSBaptiste Daroussin 
73539ee7a7aSBaptiste Daroussin /**
736c99fb5f9SBaptiste Daroussin  * Returns a key of an object as a NULL terminated string
737c99fb5f9SBaptiste Daroussin  * @param obj CL object
738c99fb5f9SBaptiste Daroussin  * @return key or NULL if there is no key
739c99fb5f9SBaptiste Daroussin  */
740b04a7a0bSBaptiste Daroussin UCL_EXTERN const char* ucl_object_key (const ucl_object_t *obj);
741c99fb5f9SBaptiste Daroussin 
742c99fb5f9SBaptiste Daroussin /**
743c99fb5f9SBaptiste Daroussin  * Returns a key of an object as a fixed size string (may be more efficient)
744c99fb5f9SBaptiste Daroussin  * @param obj CL object
745c99fb5f9SBaptiste Daroussin  * @param len target key length
746c99fb5f9SBaptiste Daroussin  * @return key pointer
747c99fb5f9SBaptiste Daroussin  */
748b04a7a0bSBaptiste Daroussin UCL_EXTERN const char* ucl_object_keyl (const ucl_object_t *obj, size_t *len);
749c99fb5f9SBaptiste Daroussin 
750c99fb5f9SBaptiste Daroussin /**
751c99fb5f9SBaptiste Daroussin  * Increase reference count for an object
752c99fb5f9SBaptiste Daroussin  * @param obj object to ref
7534bf54857SBaptiste Daroussin  * @return the referenced object
754c99fb5f9SBaptiste Daroussin  */
755b04a7a0bSBaptiste Daroussin UCL_EXTERN ucl_object_t* ucl_object_ref (const ucl_object_t *obj);
756b04a7a0bSBaptiste Daroussin 
757b04a7a0bSBaptiste Daroussin /**
758b04a7a0bSBaptiste Daroussin  * Free ucl object
759b04a7a0bSBaptiste Daroussin  * @param obj ucl object to free
760b04a7a0bSBaptiste Daroussin  */
761b04a7a0bSBaptiste Daroussin UCL_DEPRECATED(UCL_EXTERN void ucl_object_free (ucl_object_t *obj));
762c99fb5f9SBaptiste Daroussin 
763c99fb5f9SBaptiste Daroussin /**
764c99fb5f9SBaptiste Daroussin  * Decrease reference count for an object
765c99fb5f9SBaptiste Daroussin  * @param obj object to unref
766c99fb5f9SBaptiste Daroussin  */
76797bd480fSBaptiste Daroussin UCL_EXTERN void ucl_object_unref (ucl_object_t *obj);
76897bd480fSBaptiste Daroussin 
76997bd480fSBaptiste Daroussin /**
77097bd480fSBaptiste Daroussin  * Compare objects `o1` and `o2`
77197bd480fSBaptiste Daroussin  * @param o1 the first object
77297bd480fSBaptiste Daroussin  * @param o2 the second object
77397bd480fSBaptiste Daroussin  * @return values >0, 0 and <0 if `o1` is more than, equal and less than `o2`.
77497bd480fSBaptiste Daroussin  * The order of comparison:
77597bd480fSBaptiste Daroussin  * 1) Type of objects
77697bd480fSBaptiste Daroussin  * 2) Size of objects
77797bd480fSBaptiste Daroussin  * 3) Content of objects
77897bd480fSBaptiste Daroussin  */
779b04a7a0bSBaptiste Daroussin UCL_EXTERN int ucl_object_compare (const ucl_object_t *o1,
780b04a7a0bSBaptiste Daroussin 		const ucl_object_t *o2);
78197bd480fSBaptiste Daroussin 
78297bd480fSBaptiste Daroussin /**
783d9f0ce31SBaptiste Daroussin  * Compare objects `o1` and `o2` useful for sorting
784d9f0ce31SBaptiste Daroussin  * @param o1 the first object
785d9f0ce31SBaptiste Daroussin  * @param o2 the second object
786d9f0ce31SBaptiste Daroussin  * @return values >0, 0 and <0 if `o1` is more than, equal and less than `o2`.
787d9f0ce31SBaptiste Daroussin  * The order of comparison:
788d9f0ce31SBaptiste Daroussin  * 1) Type of objects
789d9f0ce31SBaptiste Daroussin  * 2) Size of objects
790d9f0ce31SBaptiste Daroussin  * 3) Content of objects
791d9f0ce31SBaptiste Daroussin  */
792d9f0ce31SBaptiste Daroussin UCL_EXTERN int ucl_object_compare_qsort (const ucl_object_t **o1,
793d9f0ce31SBaptiste Daroussin 		const ucl_object_t **o2);
794d9f0ce31SBaptiste Daroussin 
795d9f0ce31SBaptiste Daroussin /**
79697bd480fSBaptiste Daroussin  * Sort UCL array using `cmp` compare function
79797bd480fSBaptiste Daroussin  * @param ar
79897bd480fSBaptiste Daroussin  * @param cmp
79997bd480fSBaptiste Daroussin  */
80097bd480fSBaptiste Daroussin UCL_EXTERN void ucl_object_array_sort (ucl_object_t *ar,
80139ee7a7aSBaptiste Daroussin 		int (*cmp)(const ucl_object_t **o1, const ucl_object_t **o2));
80297bd480fSBaptiste Daroussin 
803*a0409676SBaptiste Daroussin enum ucl_object_keys_sort_flags {
804*a0409676SBaptiste Daroussin 	UCL_SORT_KEYS_DEFAULT = 0,
805*a0409676SBaptiste Daroussin 	UCL_SORT_KEYS_ICASE = (1u << 0u),
806*a0409676SBaptiste Daroussin 	UCL_SORT_KEYS_RECURSIVE = (1u << 1u),
807*a0409676SBaptiste Daroussin };
808*a0409676SBaptiste Daroussin /***
809*a0409676SBaptiste Daroussin  * Sorts keys in object in place
810*a0409676SBaptiste Daroussin  * @param obj
811*a0409676SBaptiste Daroussin  * @param how
812*a0409676SBaptiste Daroussin  */
813*a0409676SBaptiste Daroussin UCL_EXTERN void ucl_object_sort_keys (ucl_object_t *obj,
814*a0409676SBaptiste Daroussin 		enum ucl_object_keys_sort_flags how);
815*a0409676SBaptiste Daroussin 
816c99fb5f9SBaptiste Daroussin /**
8174bf54857SBaptiste Daroussin  * Get the priority for specific UCL object
8184bf54857SBaptiste Daroussin  * @param obj any ucl object
8194bf54857SBaptiste Daroussin  * @return priority of an object
8204bf54857SBaptiste Daroussin  */
8214bf54857SBaptiste Daroussin UCL_EXTERN unsigned int ucl_object_get_priority (const ucl_object_t *obj);
8224bf54857SBaptiste Daroussin 
8234bf54857SBaptiste Daroussin /**
8244bf54857SBaptiste Daroussin  * Set explicit priority of an object.
8254bf54857SBaptiste Daroussin  * @param obj any ucl object
8264bf54857SBaptiste Daroussin  * @param priority new priroity value (only 4 least significant bits are considred)
8274bf54857SBaptiste Daroussin  */
8284bf54857SBaptiste Daroussin UCL_EXTERN void ucl_object_set_priority (ucl_object_t *obj,
8294bf54857SBaptiste Daroussin 		unsigned int priority);
8304bf54857SBaptiste Daroussin 
8314bf54857SBaptiste Daroussin /**
832c99fb5f9SBaptiste Daroussin  * Opaque iterator object
833c99fb5f9SBaptiste Daroussin  */
834c99fb5f9SBaptiste Daroussin typedef void* ucl_object_iter_t;
835c99fb5f9SBaptiste Daroussin 
836c99fb5f9SBaptiste Daroussin /**
837c99fb5f9SBaptiste Daroussin  * Get next key from an object
838c99fb5f9SBaptiste Daroussin  * @param obj object to iterate
839c99fb5f9SBaptiste Daroussin  * @param iter opaque iterator, must be set to NULL on the first call:
840c99fb5f9SBaptiste Daroussin  * ucl_object_iter_t it = NULL;
841c99fb5f9SBaptiste Daroussin  * while ((cur = ucl_iterate_object (obj, &it)) != NULL) ...
842*a0409676SBaptiste Daroussin  * @param ep pointer record exception (such as ENOMEM), could be NULL
843c99fb5f9SBaptiste Daroussin  * @return the next object or NULL
844c99fb5f9SBaptiste Daroussin  */
845*a0409676SBaptiste Daroussin UCL_EXTERN const ucl_object_t* ucl_object_iterate_with_error (const ucl_object_t *obj,
846*a0409676SBaptiste Daroussin 		ucl_object_iter_t *iter, bool expand_values, int *ep);
847*a0409676SBaptiste Daroussin 
848d9f0ce31SBaptiste Daroussin #define ucl_iterate_object ucl_object_iterate
849*a0409676SBaptiste Daroussin #define ucl_object_iterate(ob, it, ev) ucl_object_iterate_with_error((ob), (it), (ev), NULL)
8508e3b1ab2SBaptiste Daroussin 
8518e3b1ab2SBaptiste Daroussin /**
8528e3b1ab2SBaptiste Daroussin  * Create new safe iterator for the specified object
8538e3b1ab2SBaptiste Daroussin  * @param obj object to iterate
8548e3b1ab2SBaptiste Daroussin  * @return new iterator object that should be used with safe iterators API only
8558e3b1ab2SBaptiste Daroussin  */
8568e3b1ab2SBaptiste Daroussin UCL_EXTERN ucl_object_iter_t ucl_object_iterate_new (const ucl_object_t *obj)
8578e3b1ab2SBaptiste Daroussin 	UCL_WARN_UNUSED_RESULT;
8588e3b1ab2SBaptiste Daroussin /**
859*a0409676SBaptiste Daroussin  * Check safe iterator object after performing some operations on it
860*a0409676SBaptiste Daroussin  * (such as ucl_object_iterate_safe()) to see if operation has encountered
861*a0409676SBaptiste Daroussin  * fatal exception while performing that operation (e.g. ENOMEM).
862*a0409676SBaptiste Daroussin  * @param iter opaque iterator
863*a0409676SBaptiste Daroussin  * @return true if exception has occured, false otherwise
864*a0409676SBaptiste Daroussin  */
865*a0409676SBaptiste Daroussin UCL_EXTERN bool ucl_object_iter_chk_excpn(ucl_object_iter_t *it);
866*a0409676SBaptiste Daroussin 
867*a0409676SBaptiste Daroussin /**
8688e3b1ab2SBaptiste Daroussin  * Reset initialized iterator to a new object
8698e3b1ab2SBaptiste Daroussin  * @param obj new object to iterate
8708e3b1ab2SBaptiste Daroussin  * @return modified iterator object
8718e3b1ab2SBaptiste Daroussin  */
8728e3b1ab2SBaptiste Daroussin UCL_EXTERN ucl_object_iter_t ucl_object_iterate_reset (ucl_object_iter_t it,
8738e3b1ab2SBaptiste Daroussin 		const ucl_object_t *obj);
8748e3b1ab2SBaptiste Daroussin 
8758e3b1ab2SBaptiste Daroussin /**
876*a0409676SBaptiste Daroussin  * Get the next object from the `obj`. This function iterates over arrays, objects
8778e3b1ab2SBaptiste Daroussin  * and implicit arrays
8788e3b1ab2SBaptiste Daroussin  * @param iter safe iterator
87911dd9ed6SBaptiste Daroussin  * @param expand_values expand explicit arrays and objects
8808e3b1ab2SBaptiste Daroussin  * @return the next object in sequence
8818e3b1ab2SBaptiste Daroussin  */
8828e3b1ab2SBaptiste Daroussin UCL_EXTERN const ucl_object_t* ucl_object_iterate_safe (ucl_object_iter_t iter,
8838e3b1ab2SBaptiste Daroussin 		bool expand_values);
88411dd9ed6SBaptiste Daroussin /**
88511dd9ed6SBaptiste Daroussin  * Iteration type enumerator
88611dd9ed6SBaptiste Daroussin  */
88711dd9ed6SBaptiste Daroussin enum ucl_iterate_type {
88811dd9ed6SBaptiste Daroussin 	UCL_ITERATE_EXPLICIT = 1 << 0, /**< Iterate just explicit arrays and objects */
88911dd9ed6SBaptiste Daroussin 	UCL_ITERATE_IMPLICIT = 1 << 1,  /**< Iterate just implicit arrays */
89011dd9ed6SBaptiste Daroussin 	UCL_ITERATE_BOTH = (1 << 0) | (1 << 1),   /**< Iterate both explicit and implicit arrays*/
89111dd9ed6SBaptiste Daroussin };
89211dd9ed6SBaptiste Daroussin 
89311dd9ed6SBaptiste Daroussin /**
894*a0409676SBaptiste Daroussin  * Get the next object from the `obj`. This function iterates over arrays, objects
89511dd9ed6SBaptiste Daroussin  * and implicit arrays if needed
89611dd9ed6SBaptiste Daroussin  * @param iter safe iterator
89711dd9ed6SBaptiste Daroussin  * @param
89811dd9ed6SBaptiste Daroussin  * @return the next object in sequence
89911dd9ed6SBaptiste Daroussin  */
90011dd9ed6SBaptiste Daroussin UCL_EXTERN const ucl_object_t* ucl_object_iterate_full (ucl_object_iter_t iter,
90111dd9ed6SBaptiste Daroussin 		enum ucl_iterate_type type);
9028e3b1ab2SBaptiste Daroussin 
9038e3b1ab2SBaptiste Daroussin /**
9048e3b1ab2SBaptiste Daroussin  * Free memory associated with the safe iterator
9058e3b1ab2SBaptiste Daroussin  * @param it safe iterator object
9068e3b1ab2SBaptiste Daroussin  */
9078e3b1ab2SBaptiste Daroussin UCL_EXTERN void ucl_object_iterate_free (ucl_object_iter_t it);
9088e3b1ab2SBaptiste Daroussin 
909c99fb5f9SBaptiste Daroussin /** @} */
910c99fb5f9SBaptiste Daroussin 
911c99fb5f9SBaptiste Daroussin 
912c99fb5f9SBaptiste Daroussin /**
913c99fb5f9SBaptiste Daroussin  * @defgroup parser Parsing functions
914c99fb5f9SBaptiste Daroussin  * These functions are used to parse UCL objects
915c99fb5f9SBaptiste Daroussin  *
916c99fb5f9SBaptiste Daroussin  * @{
917c99fb5f9SBaptiste Daroussin  */
918c99fb5f9SBaptiste Daroussin 
919c99fb5f9SBaptiste Daroussin /**
920c99fb5f9SBaptiste Daroussin  * Macro handler for a parser
921c99fb5f9SBaptiste Daroussin  * @param data the content of macro
922c99fb5f9SBaptiste Daroussin  * @param len the length of content
9234bf54857SBaptiste Daroussin  * @param arguments arguments object
924c99fb5f9SBaptiste Daroussin  * @param ud opaque user data
925c99fb5f9SBaptiste Daroussin  * @param err error pointer
926c99fb5f9SBaptiste Daroussin  * @return true if macro has been parsed
927c99fb5f9SBaptiste Daroussin  */
9284bf54857SBaptiste Daroussin typedef bool (*ucl_macro_handler) (const unsigned char *data, size_t len,
9294bf54857SBaptiste Daroussin 		const ucl_object_t *arguments,
9304bf54857SBaptiste Daroussin 		void* ud);
931c99fb5f9SBaptiste Daroussin 
93239ee7a7aSBaptiste Daroussin /**
93339ee7a7aSBaptiste Daroussin  * Context dependent macro handler for a parser
93439ee7a7aSBaptiste Daroussin  * @param data the content of macro
93539ee7a7aSBaptiste Daroussin  * @param len the length of content
93639ee7a7aSBaptiste Daroussin  * @param arguments arguments object
93739ee7a7aSBaptiste Daroussin  * @param context previously parsed context
93839ee7a7aSBaptiste Daroussin  * @param ud opaque user data
93939ee7a7aSBaptiste Daroussin  * @param err error pointer
94039ee7a7aSBaptiste Daroussin  * @return true if macro has been parsed
94139ee7a7aSBaptiste Daroussin  */
94239ee7a7aSBaptiste Daroussin typedef bool (*ucl_context_macro_handler) (const unsigned char *data, size_t len,
94339ee7a7aSBaptiste Daroussin 		const ucl_object_t *arguments,
94439ee7a7aSBaptiste Daroussin 		const ucl_object_t *context,
94539ee7a7aSBaptiste Daroussin 		void* ud);
94639ee7a7aSBaptiste Daroussin 
947c99fb5f9SBaptiste Daroussin /* Opaque parser */
948c99fb5f9SBaptiste Daroussin struct ucl_parser;
949c99fb5f9SBaptiste Daroussin 
950c99fb5f9SBaptiste Daroussin /**
951c99fb5f9SBaptiste Daroussin  * Creates new parser object
952c99fb5f9SBaptiste Daroussin  * @param pool pool to allocate memory from
953c99fb5f9SBaptiste Daroussin  * @return new parser object
954c99fb5f9SBaptiste Daroussin  */
95536c53d67SBaptiste Daroussin UCL_EXTERN struct ucl_parser* ucl_parser_new (int flags);
956c99fb5f9SBaptiste Daroussin 
957c99fb5f9SBaptiste Daroussin /**
958*a0409676SBaptiste Daroussin  * Sets the default priority for the parser applied to chunks that do not
95939ee7a7aSBaptiste Daroussin  * specify priority explicitly
96039ee7a7aSBaptiste Daroussin  * @param parser parser object
96139ee7a7aSBaptiste Daroussin  * @param prio default priority (0 .. 16)
96239ee7a7aSBaptiste Daroussin  * @return true if parser's default priority was set
96339ee7a7aSBaptiste Daroussin  */
96439ee7a7aSBaptiste Daroussin UCL_EXTERN bool ucl_parser_set_default_priority (struct ucl_parser *parser,
96539ee7a7aSBaptiste Daroussin 		unsigned prio);
96639ee7a7aSBaptiste Daroussin /**
967*a0409676SBaptiste Daroussin  * Gets the default priority for the parser applied to chunks that do not
968*a0409676SBaptiste Daroussin  * specify priority explicitly
969*a0409676SBaptiste Daroussin  * @param parser parser object
970*a0409676SBaptiste Daroussin  * @return true default priority (0 .. 16), -1 for failure
971*a0409676SBaptiste Daroussin  */
972*a0409676SBaptiste Daroussin UCL_EXTERN int ucl_parser_get_default_priority (struct ucl_parser *parser);
973*a0409676SBaptiste Daroussin 
974*a0409676SBaptiste Daroussin /**
975c99fb5f9SBaptiste Daroussin  * Register new handler for a macro
976c99fb5f9SBaptiste Daroussin  * @param parser parser object
977c99fb5f9SBaptiste Daroussin  * @param macro macro name (without leading dot)
978c99fb5f9SBaptiste Daroussin  * @param handler handler (it is called immediately after macro is parsed)
979c99fb5f9SBaptiste Daroussin  * @param ud opaque user data for a handler
980*a0409676SBaptiste Daroussin  * @return true on success, false on failure (i.e. ENOMEM)
981c99fb5f9SBaptiste Daroussin  */
982*a0409676SBaptiste Daroussin UCL_EXTERN bool ucl_parser_register_macro (struct ucl_parser *parser,
98339ee7a7aSBaptiste Daroussin 		const char *macro,
984c99fb5f9SBaptiste Daroussin 		ucl_macro_handler handler, void* ud);
985c99fb5f9SBaptiste Daroussin 
986c99fb5f9SBaptiste Daroussin /**
98739ee7a7aSBaptiste Daroussin  * Register new context dependent handler for a macro
98839ee7a7aSBaptiste Daroussin  * @param parser parser object
98939ee7a7aSBaptiste Daroussin  * @param macro macro name (without leading dot)
99039ee7a7aSBaptiste Daroussin  * @param handler handler (it is called immediately after macro is parsed)
99139ee7a7aSBaptiste Daroussin  * @param ud opaque user data for a handler
992*a0409676SBaptiste Daroussin  * @return true on success, false on failure (i.e. ENOMEM)
99339ee7a7aSBaptiste Daroussin  */
994*a0409676SBaptiste Daroussin UCL_EXTERN bool ucl_parser_register_context_macro (struct ucl_parser *parser,
99539ee7a7aSBaptiste Daroussin 		const char *macro,
99639ee7a7aSBaptiste Daroussin 		ucl_context_macro_handler handler,
99739ee7a7aSBaptiste Daroussin 		void* ud);
99839ee7a7aSBaptiste Daroussin 
99939ee7a7aSBaptiste Daroussin /**
10002e8ed2b8SBaptiste Daroussin  * Handler to detect unregistered variables
10012e8ed2b8SBaptiste Daroussin  * @param data variable data
10022e8ed2b8SBaptiste Daroussin  * @param len length of variable
10032e8ed2b8SBaptiste Daroussin  * @param replace (out) replace value for variable
10042e8ed2b8SBaptiste Daroussin  * @param replace_len (out) replace length for variable
10052e8ed2b8SBaptiste Daroussin  * @param need_free (out) UCL will free `dest` after usage
10062e8ed2b8SBaptiste Daroussin  * @param ud opaque userdata
10072e8ed2b8SBaptiste Daroussin  * @return true if variable
10082e8ed2b8SBaptiste Daroussin  */
10092e8ed2b8SBaptiste Daroussin typedef bool (*ucl_variable_handler) (const unsigned char *data, size_t len,
10102e8ed2b8SBaptiste Daroussin 		unsigned char **replace, size_t *replace_len, bool *need_free, void* ud);
10112e8ed2b8SBaptiste Daroussin 
10122e8ed2b8SBaptiste Daroussin /**
1013c99fb5f9SBaptiste Daroussin  * Register new parser variable
1014c99fb5f9SBaptiste Daroussin  * @param parser parser object
1015c99fb5f9SBaptiste Daroussin  * @param var variable name
1016c99fb5f9SBaptiste Daroussin  * @param value variable value
1017c99fb5f9SBaptiste Daroussin  */
101836c53d67SBaptiste Daroussin UCL_EXTERN void ucl_parser_register_variable (struct ucl_parser *parser, const char *var,
1019c99fb5f9SBaptiste Daroussin 		const char *value);
1020c99fb5f9SBaptiste Daroussin 
1021c99fb5f9SBaptiste Daroussin /**
10222e8ed2b8SBaptiste Daroussin  * Set handler for unknown variables
10232e8ed2b8SBaptiste Daroussin  * @param parser parser structure
10242e8ed2b8SBaptiste Daroussin  * @param handler desired handler
10252e8ed2b8SBaptiste Daroussin  * @param ud opaque data for the handler
10262e8ed2b8SBaptiste Daroussin  */
10272e8ed2b8SBaptiste Daroussin UCL_EXTERN void ucl_parser_set_variables_handler (struct ucl_parser *parser,
10282e8ed2b8SBaptiste Daroussin 		ucl_variable_handler handler, void *ud);
10292e8ed2b8SBaptiste Daroussin 
10302e8ed2b8SBaptiste Daroussin /**
1031c99fb5f9SBaptiste Daroussin  * Load new chunk to a parser
1032c99fb5f9SBaptiste Daroussin  * @param parser parser structure
1033c99fb5f9SBaptiste Daroussin  * @param data the pointer to the beginning of a chunk
1034c99fb5f9SBaptiste Daroussin  * @param len the length of a chunk
1035c99fb5f9SBaptiste Daroussin  * @return true if chunk has been added and false in case of error
1036c99fb5f9SBaptiste Daroussin  */
103797bd480fSBaptiste Daroussin UCL_EXTERN bool ucl_parser_add_chunk (struct ucl_parser *parser,
103897bd480fSBaptiste Daroussin 		const unsigned char *data, size_t len);
103997bd480fSBaptiste Daroussin 
104097bd480fSBaptiste Daroussin /**
10414bf54857SBaptiste Daroussin  * Load new chunk to a parser with the specified priority
10424bf54857SBaptiste Daroussin  * @param parser parser structure
10434bf54857SBaptiste Daroussin  * @param data the pointer to the beginning of a chunk
10444bf54857SBaptiste Daroussin  * @param len the length of a chunk
10454bf54857SBaptiste Daroussin  * @param priority the desired priority of a chunk (only 4 least significant bits
10464bf54857SBaptiste Daroussin  * are considered for this parameter)
10474bf54857SBaptiste Daroussin  * @return true if chunk has been added and false in case of error
10484bf54857SBaptiste Daroussin  */
10494bf54857SBaptiste Daroussin UCL_EXTERN bool ucl_parser_add_chunk_priority (struct ucl_parser *parser,
10504bf54857SBaptiste Daroussin 		const unsigned char *data, size_t len, unsigned priority);
10514bf54857SBaptiste Daroussin 
10524bf54857SBaptiste Daroussin /**
1053*a0409676SBaptiste Daroussin  * Insert new chunk to a parser (must have previously processed data with an existing top object)
1054*a0409676SBaptiste Daroussin  * @param parser parser structure
1055*a0409676SBaptiste Daroussin  * @param data the pointer to the beginning of a chunk
1056*a0409676SBaptiste Daroussin  * @param len the length of a chunk
1057*a0409676SBaptiste Daroussin  * @return true if chunk has been added and false in case of error
1058*a0409676SBaptiste Daroussin  */
1059*a0409676SBaptiste Daroussin UCL_EXTERN bool ucl_parser_insert_chunk (struct ucl_parser *parser,
1060*a0409676SBaptiste Daroussin 		const unsigned char *data, size_t len);
1061*a0409676SBaptiste Daroussin 
1062*a0409676SBaptiste Daroussin /**
106339ee7a7aSBaptiste Daroussin  * Full version of ucl_add_chunk with priority and duplicate strategy
106439ee7a7aSBaptiste Daroussin  * @param parser parser structure
106539ee7a7aSBaptiste Daroussin  * @param data the pointer to the beginning of a chunk
106639ee7a7aSBaptiste Daroussin  * @param len the length of a chunk
106739ee7a7aSBaptiste Daroussin  * @param priority the desired priority of a chunk (only 4 least significant bits
106839ee7a7aSBaptiste Daroussin  * are considered for this parameter)
106939ee7a7aSBaptiste Daroussin  * @param strat duplicates merging strategy
107039ee7a7aSBaptiste Daroussin  * @param parse_type input format
107139ee7a7aSBaptiste Daroussin  * @return true if chunk has been added and false in case of error
107239ee7a7aSBaptiste Daroussin  */
107339ee7a7aSBaptiste Daroussin UCL_EXTERN bool ucl_parser_add_chunk_full (struct ucl_parser *parser,
107439ee7a7aSBaptiste Daroussin 		const unsigned char *data, size_t len, unsigned priority,
107539ee7a7aSBaptiste Daroussin 		enum ucl_duplicate_strategy strat, enum ucl_parse_type parse_type);
107639ee7a7aSBaptiste Daroussin 
107739ee7a7aSBaptiste Daroussin /**
107897bd480fSBaptiste Daroussin  * Load ucl object from a string
107997bd480fSBaptiste Daroussin  * @param parser parser structure
108097bd480fSBaptiste Daroussin  * @param data the pointer to the string
108197bd480fSBaptiste Daroussin  * @param len the length of the string, if `len` is 0 then `data` must be zero-terminated string
108297bd480fSBaptiste Daroussin  * @return true if string has been added and false in case of error
108397bd480fSBaptiste Daroussin  */
108497bd480fSBaptiste Daroussin UCL_EXTERN bool ucl_parser_add_string (struct ucl_parser *parser,
108597bd480fSBaptiste Daroussin 		const char *data, size_t len);
1086c99fb5f9SBaptiste Daroussin 
1087c99fb5f9SBaptiste Daroussin /**
108839ee7a7aSBaptiste Daroussin  * Load ucl object from a string
108939ee7a7aSBaptiste Daroussin  * @param parser parser structure
109039ee7a7aSBaptiste Daroussin  * @param data the pointer to the string
109139ee7a7aSBaptiste Daroussin  * @param len the length of the string, if `len` is 0 then `data` must be zero-terminated string
109239ee7a7aSBaptiste Daroussin  * @param priority the desired priority of a chunk (only 4 least significant bits
109339ee7a7aSBaptiste Daroussin  * are considered for this parameter)
109439ee7a7aSBaptiste Daroussin  * @return true if string has been added and false in case of error
109539ee7a7aSBaptiste Daroussin  */
109639ee7a7aSBaptiste Daroussin UCL_EXTERN bool ucl_parser_add_string_priority (struct ucl_parser *parser,
109739ee7a7aSBaptiste Daroussin 		const char *data, size_t len, unsigned priority);
109839ee7a7aSBaptiste Daroussin 
109939ee7a7aSBaptiste Daroussin /**
1100c99fb5f9SBaptiste Daroussin  * Load and add data from a file
1101c99fb5f9SBaptiste Daroussin  * @param parser parser structure
1102c99fb5f9SBaptiste Daroussin  * @param filename the name of file
110311dd9ed6SBaptiste Daroussin  * @param err if *err is NULL it is set to parser error
1104c99fb5f9SBaptiste Daroussin  * @return true if chunk has been added and false in case of error
1105c99fb5f9SBaptiste Daroussin  */
1106b04a7a0bSBaptiste Daroussin UCL_EXTERN bool ucl_parser_add_file (struct ucl_parser *parser,
1107b04a7a0bSBaptiste Daroussin 		const char *filename);
1108c99fb5f9SBaptiste Daroussin 
1109c99fb5f9SBaptiste Daroussin /**
111039ee7a7aSBaptiste Daroussin  * Load and add data from a file
111139ee7a7aSBaptiste Daroussin  * @param parser parser structure
111239ee7a7aSBaptiste Daroussin  * @param filename the name of file
111311dd9ed6SBaptiste Daroussin  * @param err if *err is NULL it is set to parser error
111439ee7a7aSBaptiste Daroussin  * @param priority the desired priority of a chunk (only 4 least significant bits
111539ee7a7aSBaptiste Daroussin  * are considered for this parameter)
111639ee7a7aSBaptiste Daroussin  * @return true if chunk has been added and false in case of error
111739ee7a7aSBaptiste Daroussin  */
111839ee7a7aSBaptiste Daroussin UCL_EXTERN bool ucl_parser_add_file_priority (struct ucl_parser *parser,
111939ee7a7aSBaptiste Daroussin 		const char *filename, unsigned priority);
112039ee7a7aSBaptiste Daroussin 
112139ee7a7aSBaptiste Daroussin /**
1122273c26a3SBaptiste Daroussin  * Load and add data from a file
1123273c26a3SBaptiste Daroussin  * @param parser parser structure
1124273c26a3SBaptiste Daroussin  * @param filename the name of file
1125273c26a3SBaptiste Daroussin  * @param priority the desired priority of a chunk (only 4 least significant bits
1126273c26a3SBaptiste Daroussin  * are considered for this parameter)
1127273c26a3SBaptiste Daroussin  * @param strat Merge strategy to use while parsing this file
1128273c26a3SBaptiste Daroussin  * @param parse_type Parser type to use while parsing this file
1129273c26a3SBaptiste Daroussin  * @return true if chunk has been added and false in case of error
1130273c26a3SBaptiste Daroussin  */
1131273c26a3SBaptiste Daroussin UCL_EXTERN bool ucl_parser_add_file_full (struct ucl_parser *parser, const char *filename,
1132273c26a3SBaptiste Daroussin 		unsigned priority, enum ucl_duplicate_strategy strat,
1133273c26a3SBaptiste Daroussin 		enum ucl_parse_type parse_type);
1134273c26a3SBaptiste Daroussin 
1135273c26a3SBaptiste Daroussin /**
1136b04a7a0bSBaptiste Daroussin  * Load and add data from a file descriptor
1137b04a7a0bSBaptiste Daroussin  * @param parser parser structure
1138b04a7a0bSBaptiste Daroussin  * @param filename the name of file
1139b04a7a0bSBaptiste Daroussin  * @param err if *err is NULL it is set to parser error
1140b04a7a0bSBaptiste Daroussin  * @return true if chunk has been added and false in case of error
1141b04a7a0bSBaptiste Daroussin  */
1142b04a7a0bSBaptiste Daroussin UCL_EXTERN bool ucl_parser_add_fd (struct ucl_parser *parser,
1143b04a7a0bSBaptiste Daroussin 		int fd);
1144b04a7a0bSBaptiste Daroussin 
1145b04a7a0bSBaptiste Daroussin /**
114639ee7a7aSBaptiste Daroussin  * Load and add data from a file descriptor
114739ee7a7aSBaptiste Daroussin  * @param parser parser structure
114839ee7a7aSBaptiste Daroussin  * @param filename the name of file
114939ee7a7aSBaptiste Daroussin  * @param err if *err is NULL it is set to parser error
115039ee7a7aSBaptiste Daroussin  * @param priority the desired priority of a chunk (only 4 least significant bits
115139ee7a7aSBaptiste Daroussin  * are considered for this parameter)
115239ee7a7aSBaptiste Daroussin  * @return true if chunk has been added and false in case of error
115339ee7a7aSBaptiste Daroussin  */
115439ee7a7aSBaptiste Daroussin UCL_EXTERN bool ucl_parser_add_fd_priority (struct ucl_parser *parser,
115539ee7a7aSBaptiste Daroussin 		int fd, unsigned priority);
115639ee7a7aSBaptiste Daroussin 
115739ee7a7aSBaptiste Daroussin /**
115811dd9ed6SBaptiste Daroussin  * Load and add data from a file descriptor
115911dd9ed6SBaptiste Daroussin  * @param parser parser structure
116011dd9ed6SBaptiste Daroussin  * @param filename the name of file
116111dd9ed6SBaptiste Daroussin  * @param err if *err is NULL it is set to parser error
116211dd9ed6SBaptiste Daroussin  * @param priority the desired priority of a chunk (only 4 least significant bits
116311dd9ed6SBaptiste Daroussin  * are considered for this parameter)
116411dd9ed6SBaptiste Daroussin  * @param strat Merge strategy to use while parsing this file
116511dd9ed6SBaptiste Daroussin  * @param parse_type Parser type to use while parsing this file
116611dd9ed6SBaptiste Daroussin  * @return true if chunk has been added and false in case of error
116711dd9ed6SBaptiste Daroussin  */
116811dd9ed6SBaptiste Daroussin UCL_EXTERN bool ucl_parser_add_fd_full (struct ucl_parser *parser, int fd,
116911dd9ed6SBaptiste Daroussin 		unsigned priority, enum ucl_duplicate_strategy strat,
117011dd9ed6SBaptiste Daroussin 		enum ucl_parse_type parse_type);
117111dd9ed6SBaptiste Daroussin 
117211dd9ed6SBaptiste Daroussin /**
117339ee7a7aSBaptiste Daroussin  * Provide a UCL_ARRAY of paths to search for include files. The object is
117439ee7a7aSBaptiste Daroussin  * copied so caller must unref the object.
117539ee7a7aSBaptiste Daroussin  * @param parser parser structure
117639ee7a7aSBaptiste Daroussin  * @param paths UCL_ARRAY of paths to search
117739ee7a7aSBaptiste Daroussin  * @return true if the path search array was replaced in the parser
117839ee7a7aSBaptiste Daroussin  */
117939ee7a7aSBaptiste Daroussin UCL_EXTERN bool ucl_set_include_path (struct ucl_parser *parser,
118039ee7a7aSBaptiste Daroussin 		ucl_object_t *paths);
118139ee7a7aSBaptiste Daroussin 
118239ee7a7aSBaptiste Daroussin /**
1183b04a7a0bSBaptiste Daroussin  * Get a top object for a parser (refcount is increased)
1184c99fb5f9SBaptiste Daroussin  * @param parser parser structure
1185c99fb5f9SBaptiste Daroussin  * @param err if *err is NULL it is set to parser error
1186c99fb5f9SBaptiste Daroussin  * @return top parser object or NULL
1187c99fb5f9SBaptiste Daroussin  */
118836c53d67SBaptiste Daroussin UCL_EXTERN ucl_object_t* ucl_parser_get_object (struct ucl_parser *parser);
1189c99fb5f9SBaptiste Daroussin 
1190c99fb5f9SBaptiste Daroussin /**
1191*a0409676SBaptiste Daroussin  * Get the current stack object as stack accessor function for use in macro
1192*a0409676SBaptiste Daroussin  * functions (refcount is increased)
1193*a0409676SBaptiste Daroussin  * @param parser parser object
1194*a0409676SBaptiste Daroussin  * @param depth depth of stack to retrieve (top is 0)
1195*a0409676SBaptiste Daroussin  * @return current stack object or NULL
1196*a0409676SBaptiste Daroussin  */
1197*a0409676SBaptiste Daroussin UCL_EXTERN ucl_object_t* ucl_parser_get_current_stack_object (struct ucl_parser *parser, unsigned int depth);
1198*a0409676SBaptiste Daroussin 
1199*a0409676SBaptiste Daroussin /**
1200*a0409676SBaptiste Daroussin  * Peek at the character at the current chunk position
1201*a0409676SBaptiste Daroussin  * @param parser parser structure
1202*a0409676SBaptiste Daroussin  * @return current chunk position character
1203*a0409676SBaptiste Daroussin  */
1204*a0409676SBaptiste Daroussin UCL_EXTERN unsigned char ucl_parser_chunk_peek (struct ucl_parser *parser);
1205*a0409676SBaptiste Daroussin 
1206*a0409676SBaptiste Daroussin /**
1207*a0409676SBaptiste Daroussin  * Skip the character at the current chunk position
1208*a0409676SBaptiste Daroussin  * @param parser parser structure
1209*a0409676SBaptiste Daroussin  * @return success boolean
1210*a0409676SBaptiste Daroussin  */
1211*a0409676SBaptiste Daroussin UCL_EXTERN bool ucl_parser_chunk_skip (struct ucl_parser *parser);
1212*a0409676SBaptiste Daroussin 
1213*a0409676SBaptiste Daroussin /**
121439ee7a7aSBaptiste Daroussin  * Get the error string if parsing has been failed
1215c99fb5f9SBaptiste Daroussin  * @param parser parser object
121639ee7a7aSBaptiste Daroussin  * @return error description
1217c99fb5f9SBaptiste Daroussin  */
121836c53d67SBaptiste Daroussin UCL_EXTERN const char *ucl_parser_get_error (struct ucl_parser *parser);
12198e3b1ab2SBaptiste Daroussin 
12208e3b1ab2SBaptiste Daroussin /**
122139ee7a7aSBaptiste Daroussin  * Get the code of the last error
122239ee7a7aSBaptiste Daroussin  * @param parser parser object
122339ee7a7aSBaptiste Daroussin  * @return error code
122439ee7a7aSBaptiste Daroussin  */
122539ee7a7aSBaptiste Daroussin UCL_EXTERN int ucl_parser_get_error_code (struct ucl_parser *parser);
122639ee7a7aSBaptiste Daroussin 
122739ee7a7aSBaptiste Daroussin /**
122839ee7a7aSBaptiste Daroussin  * Get the current column number within parser
122939ee7a7aSBaptiste Daroussin  * @param parser parser object
123039ee7a7aSBaptiste Daroussin  * @return current column number
123139ee7a7aSBaptiste Daroussin  */
123239ee7a7aSBaptiste Daroussin UCL_EXTERN unsigned ucl_parser_get_column (struct ucl_parser *parser);
123339ee7a7aSBaptiste Daroussin 
123439ee7a7aSBaptiste Daroussin /**
123539ee7a7aSBaptiste Daroussin  * Get the current line number within parser
123639ee7a7aSBaptiste Daroussin  * @param parser parser object
123739ee7a7aSBaptiste Daroussin  * @return current line number
123839ee7a7aSBaptiste Daroussin  */
123939ee7a7aSBaptiste Daroussin UCL_EXTERN unsigned ucl_parser_get_linenum (struct ucl_parser *parser);
124039ee7a7aSBaptiste Daroussin 
124139ee7a7aSBaptiste Daroussin /**
12428e3b1ab2SBaptiste Daroussin  * Clear the error in the parser
12438e3b1ab2SBaptiste Daroussin  * @param parser parser object
12448e3b1ab2SBaptiste Daroussin  */
12458e3b1ab2SBaptiste Daroussin UCL_EXTERN void ucl_parser_clear_error (struct ucl_parser *parser);
12468e3b1ab2SBaptiste Daroussin 
1247c99fb5f9SBaptiste Daroussin /**
1248c99fb5f9SBaptiste Daroussin  * Free ucl parser object
1249c99fb5f9SBaptiste Daroussin  * @param parser parser object
1250c99fb5f9SBaptiste Daroussin  */
125136c53d67SBaptiste Daroussin UCL_EXTERN void ucl_parser_free (struct ucl_parser *parser);
1252c99fb5f9SBaptiste Daroussin 
1253c99fb5f9SBaptiste Daroussin /**
1254d9f0ce31SBaptiste Daroussin  * Get constant opaque pointer to comments structure for this parser. Increase
1255d9f0ce31SBaptiste Daroussin  * refcount to prevent this object to be destroyed on parser's destruction
1256d9f0ce31SBaptiste Daroussin  * @param parser parser structure
1257d9f0ce31SBaptiste Daroussin  * @return ucl comments pointer or NULL
1258d9f0ce31SBaptiste Daroussin  */
1259d9f0ce31SBaptiste Daroussin UCL_EXTERN const ucl_object_t * ucl_parser_get_comments (struct ucl_parser *parser);
1260d9f0ce31SBaptiste Daroussin 
1261d9f0ce31SBaptiste Daroussin /**
1262d9f0ce31SBaptiste Daroussin  * Utility function to find a comment object for the specified object in the input
1263d9f0ce31SBaptiste Daroussin  * @param comments comments object
1264d9f0ce31SBaptiste Daroussin  * @param srch search object
1265d9f0ce31SBaptiste Daroussin  * @return string comment enclosed in ucl_object_t
1266d9f0ce31SBaptiste Daroussin  */
1267d9f0ce31SBaptiste Daroussin UCL_EXTERN const ucl_object_t * ucl_comments_find (const ucl_object_t *comments,
1268d9f0ce31SBaptiste Daroussin 		const ucl_object_t *srch);
1269d9f0ce31SBaptiste Daroussin 
1270d9f0ce31SBaptiste Daroussin /**
1271d9f0ce31SBaptiste Daroussin  * Move comment from `from` object to `to` object
1272d9f0ce31SBaptiste Daroussin  * @param comments comments object
1273d9f0ce31SBaptiste Daroussin  * @param what source object
1274*a0409676SBaptiste Daroussin  * @param with destination object
1275d9f0ce31SBaptiste Daroussin  * @return `true` if `from` has comment and it has been moved to `to`
1276d9f0ce31SBaptiste Daroussin  */
1277d9f0ce31SBaptiste Daroussin UCL_EXTERN bool ucl_comments_move (ucl_object_t *comments,
1278d9f0ce31SBaptiste Daroussin 		const ucl_object_t *from, const ucl_object_t *to);
1279d9f0ce31SBaptiste Daroussin 
1280d9f0ce31SBaptiste Daroussin /**
1281d9f0ce31SBaptiste Daroussin  * Adds a new comment for an object
1282d9f0ce31SBaptiste Daroussin  * @param comments comments object
1283d9f0ce31SBaptiste Daroussin  * @param obj object to add comment to
1284d9f0ce31SBaptiste Daroussin  * @param comment string representation of a comment
1285d9f0ce31SBaptiste Daroussin  */
1286d9f0ce31SBaptiste Daroussin UCL_EXTERN void ucl_comments_add (ucl_object_t *comments,
1287d9f0ce31SBaptiste Daroussin 		const ucl_object_t *obj, const char *comment);
1288d9f0ce31SBaptiste Daroussin 
1289d9f0ce31SBaptiste Daroussin /**
1290c99fb5f9SBaptiste Daroussin  * Add new public key to parser for signatures check
1291c99fb5f9SBaptiste Daroussin  * @param parser parser object
1292c99fb5f9SBaptiste Daroussin  * @param key PEM representation of a key
1293c99fb5f9SBaptiste Daroussin  * @param len length of the key
1294c99fb5f9SBaptiste Daroussin  * @param err if *err is NULL it is set to parser error
1295c99fb5f9SBaptiste Daroussin  * @return true if a key has been successfully added
1296c99fb5f9SBaptiste Daroussin  */
1297d9f0ce31SBaptiste Daroussin UCL_EXTERN bool ucl_parser_pubkey_add (struct ucl_parser *parser,
1298d9f0ce31SBaptiste Daroussin 		const unsigned char *key, size_t len);
1299c99fb5f9SBaptiste Daroussin 
1300c99fb5f9SBaptiste Daroussin /**
1301c99fb5f9SBaptiste Daroussin  * Set FILENAME and CURDIR variables in parser
1302c99fb5f9SBaptiste Daroussin  * @param parser parser object
1303c99fb5f9SBaptiste Daroussin  * @param filename filename to set or NULL to set FILENAME to "undef" and CURDIR to getcwd()
1304c99fb5f9SBaptiste Daroussin  * @param need_expand perform realpath() if this variable is true and filename is not NULL
1305c99fb5f9SBaptiste Daroussin  * @return true if variables has been set
1306c99fb5f9SBaptiste Daroussin  */
130736c53d67SBaptiste Daroussin UCL_EXTERN bool ucl_parser_set_filevars (struct ucl_parser *parser, const char *filename,
1308c99fb5f9SBaptiste Daroussin 		bool need_expand);
1309c99fb5f9SBaptiste Daroussin 
1310*a0409676SBaptiste Daroussin /**
1311*a0409676SBaptiste Daroussin  * Returns current file for the parser
1312*a0409676SBaptiste Daroussin  * @param parser parser object
1313*a0409676SBaptiste Daroussin  * @return current file or NULL if parsing memory
1314*a0409676SBaptiste Daroussin  */
1315*a0409676SBaptiste Daroussin UCL_EXTERN const char *ucl_parser_get_cur_file (struct ucl_parser *parser);
1316*a0409676SBaptiste Daroussin 
1317*a0409676SBaptiste Daroussin /**
1318*a0409676SBaptiste Daroussin  * Defines special handler for certain types of data (identified by magic)
1319*a0409676SBaptiste Daroussin  */
1320*a0409676SBaptiste Daroussin typedef bool (*ucl_parser_special_handler_t) (struct ucl_parser *parser,
1321*a0409676SBaptiste Daroussin 		const unsigned char *source, size_t source_len,
1322*a0409676SBaptiste Daroussin 		unsigned char **destination, size_t *dest_len,
1323*a0409676SBaptiste Daroussin 		void *user_data);
1324*a0409676SBaptiste Daroussin 
1325*a0409676SBaptiste Daroussin /**
1326*a0409676SBaptiste Daroussin  * Special handler flags
1327*a0409676SBaptiste Daroussin  */
1328*a0409676SBaptiste Daroussin enum ucl_special_handler_flags {
1329*a0409676SBaptiste Daroussin 	UCL_SPECIAL_HANDLER_DEFAULT = 0,
1330*a0409676SBaptiste Daroussin 	UCL_SPECIAL_HANDLER_PREPROCESS_ALL = (1u << 0),
1331*a0409676SBaptiste Daroussin };
1332*a0409676SBaptiste Daroussin 
1333*a0409676SBaptiste Daroussin /**
1334*a0409676SBaptiste Daroussin  * Special handler structure
1335*a0409676SBaptiste Daroussin  */
1336*a0409676SBaptiste Daroussin struct ucl_parser_special_handler {
1337*a0409676SBaptiste Daroussin 	const unsigned char *magic;
1338*a0409676SBaptiste Daroussin 	size_t magic_len;
1339*a0409676SBaptiste Daroussin 	enum ucl_special_handler_flags flags;
1340*a0409676SBaptiste Daroussin 	ucl_parser_special_handler_t handler;
1341*a0409676SBaptiste Daroussin 	void (*free_function) (unsigned char *data, size_t len, void *user_data);
1342*a0409676SBaptiste Daroussin 	void *user_data;
1343*a0409676SBaptiste Daroussin 	struct ucl_parser_special_handler *next; /* Used internally */
1344*a0409676SBaptiste Daroussin };
1345*a0409676SBaptiste Daroussin 
1346*a0409676SBaptiste Daroussin /**
1347*a0409676SBaptiste Daroussin  * Add special handler for a parser, handles special sequences identified by magic
1348*a0409676SBaptiste Daroussin  * @param parser parser structure
1349*a0409676SBaptiste Daroussin  * @param handler handler structure
1350*a0409676SBaptiste Daroussin  */
1351*a0409676SBaptiste Daroussin UCL_EXTERN void ucl_parser_add_special_handler (struct ucl_parser *parser,
1352*a0409676SBaptiste Daroussin 		struct ucl_parser_special_handler *handler);
1353*a0409676SBaptiste Daroussin 
1354*a0409676SBaptiste Daroussin /**
1355*a0409676SBaptiste Daroussin  * Handler for include traces:
1356*a0409676SBaptiste Daroussin  * @param parser parser object
1357*a0409676SBaptiste Daroussin  * @param parent where include is done from
1358*a0409676SBaptiste Daroussin  * @param args arguments to an include
1359*a0409676SBaptiste Daroussin  * @param path path of the include
1360*a0409676SBaptiste Daroussin  * @param pathlen length of the path
1361*a0409676SBaptiste Daroussin  * @param user_data opaque userdata
1362*a0409676SBaptiste Daroussin  */
1363*a0409676SBaptiste Daroussin typedef void (ucl_include_trace_func_t) (struct ucl_parser *parser,
1364*a0409676SBaptiste Daroussin 		const ucl_object_t *parent,
1365*a0409676SBaptiste Daroussin 		const ucl_object_t *args,
1366*a0409676SBaptiste Daroussin 		const char *path,
1367*a0409676SBaptiste Daroussin 		size_t pathlen,
1368*a0409676SBaptiste Daroussin 		void *user_data);
1369*a0409676SBaptiste Daroussin 
1370*a0409676SBaptiste Daroussin /**
1371*a0409676SBaptiste Daroussin  * Register trace function for an include handler
1372*a0409676SBaptiste Daroussin  * @param parser parser object
1373*a0409676SBaptiste Daroussin  * @param func function to trace includes
1374*a0409676SBaptiste Daroussin  * @param user_data opaque data
1375*a0409676SBaptiste Daroussin  */
1376*a0409676SBaptiste Daroussin UCL_EXTERN void ucl_parser_set_include_tracer (struct ucl_parser *parser,
1377*a0409676SBaptiste Daroussin 											   ucl_include_trace_func_t func,
1378*a0409676SBaptiste Daroussin 											   void *user_data);
1379*a0409676SBaptiste Daroussin 
1380c99fb5f9SBaptiste Daroussin /** @} */
1381c99fb5f9SBaptiste Daroussin 
1382c99fb5f9SBaptiste Daroussin /**
1383c99fb5f9SBaptiste Daroussin  * @defgroup emitter Emitting functions
1384c99fb5f9SBaptiste Daroussin  * These functions are used to serialise UCL objects to some string representation.
1385c99fb5f9SBaptiste Daroussin  *
1386c99fb5f9SBaptiste Daroussin  * @{
1387c99fb5f9SBaptiste Daroussin  */
1388c99fb5f9SBaptiste Daroussin 
13893dcf5eb7SBaptiste Daroussin struct ucl_emitter_context;
1390c99fb5f9SBaptiste Daroussin /**
1391c99fb5f9SBaptiste Daroussin  * Structure using for emitter callbacks
1392c99fb5f9SBaptiste Daroussin  */
1393c99fb5f9SBaptiste Daroussin struct ucl_emitter_functions {
1394c99fb5f9SBaptiste Daroussin 	/** Append a single character */
1395c99fb5f9SBaptiste Daroussin 	int (*ucl_emitter_append_character) (unsigned char c, size_t nchars, void *ud);
1396c99fb5f9SBaptiste Daroussin 	/** Append a string of a specified length */
1397c99fb5f9SBaptiste Daroussin 	int (*ucl_emitter_append_len) (unsigned const char *str, size_t len, void *ud);
1398c99fb5f9SBaptiste Daroussin 	/** Append a 64 bit integer */
1399c99fb5f9SBaptiste Daroussin 	int (*ucl_emitter_append_int) (int64_t elt, void *ud);
1400c99fb5f9SBaptiste Daroussin 	/** Append floating point element */
1401c99fb5f9SBaptiste Daroussin 	int (*ucl_emitter_append_double) (double elt, void *ud);
14023dcf5eb7SBaptiste Daroussin 	/** Free userdata */
14033dcf5eb7SBaptiste Daroussin 	void (*ucl_emitter_free_func)(void *ud);
1404c99fb5f9SBaptiste Daroussin 	/** Opaque userdata pointer */
1405c99fb5f9SBaptiste Daroussin 	void *ud;
1406c99fb5f9SBaptiste Daroussin };
1407c99fb5f9SBaptiste Daroussin 
14083dcf5eb7SBaptiste Daroussin struct ucl_emitter_operations {
14093dcf5eb7SBaptiste Daroussin 	/** Write a primitive element */
14103dcf5eb7SBaptiste Daroussin 	void (*ucl_emitter_write_elt) (struct ucl_emitter_context *ctx,
14113dcf5eb7SBaptiste Daroussin 		const ucl_object_t *obj, bool first, bool print_key);
14123dcf5eb7SBaptiste Daroussin 	/** Start ucl object */
14133dcf5eb7SBaptiste Daroussin 	void (*ucl_emitter_start_object) (struct ucl_emitter_context *ctx,
14143dcf5eb7SBaptiste Daroussin 		const ucl_object_t *obj, bool print_key);
14153dcf5eb7SBaptiste Daroussin 	/** End ucl object */
14163dcf5eb7SBaptiste Daroussin 	void (*ucl_emitter_end_object) (struct ucl_emitter_context *ctx,
14173dcf5eb7SBaptiste Daroussin 		const ucl_object_t *obj);
14183dcf5eb7SBaptiste Daroussin 	/** Start ucl array */
14193dcf5eb7SBaptiste Daroussin 	void (*ucl_emitter_start_array) (struct ucl_emitter_context *ctx,
14203dcf5eb7SBaptiste Daroussin 		const ucl_object_t *obj, bool print_key);
14213dcf5eb7SBaptiste Daroussin 	void (*ucl_emitter_end_array) (struct ucl_emitter_context *ctx,
14223dcf5eb7SBaptiste Daroussin 		const ucl_object_t *obj);
14233dcf5eb7SBaptiste Daroussin };
14243dcf5eb7SBaptiste Daroussin 
14253dcf5eb7SBaptiste Daroussin /**
14263dcf5eb7SBaptiste Daroussin  * Structure that defines emitter functions
14273dcf5eb7SBaptiste Daroussin  */
14283dcf5eb7SBaptiste Daroussin struct ucl_emitter_context {
14293dcf5eb7SBaptiste Daroussin 	/** Name of emitter (e.g. json, compact_json) */
14303dcf5eb7SBaptiste Daroussin 	const char *name;
14313dcf5eb7SBaptiste Daroussin 	/** Unique id (e.g. UCL_EMIT_JSON for standard emitters */
14323dcf5eb7SBaptiste Daroussin 	int id;
14333dcf5eb7SBaptiste Daroussin 	/** A set of output functions */
14343dcf5eb7SBaptiste Daroussin 	const struct ucl_emitter_functions *func;
14353dcf5eb7SBaptiste Daroussin 	/** A set of output operations */
14363dcf5eb7SBaptiste Daroussin 	const struct ucl_emitter_operations *ops;
14373dcf5eb7SBaptiste Daroussin 	/** Current amount of indent tabs */
14384bf54857SBaptiste Daroussin 	unsigned int indent;
14393dcf5eb7SBaptiste Daroussin 	/** Top level object */
14403dcf5eb7SBaptiste Daroussin 	const ucl_object_t *top;
1441d9f0ce31SBaptiste Daroussin 	/** Optional comments */
1442d9f0ce31SBaptiste Daroussin 	const ucl_object_t *comments;
14433dcf5eb7SBaptiste Daroussin };
14443dcf5eb7SBaptiste Daroussin 
1445c99fb5f9SBaptiste Daroussin /**
1446c99fb5f9SBaptiste Daroussin  * Emit object to a string
1447c99fb5f9SBaptiste Daroussin  * @param obj object
1448c99fb5f9SBaptiste Daroussin  * @param emit_type if type is #UCL_EMIT_JSON then emit json, if type is
1449c99fb5f9SBaptiste Daroussin  * #UCL_EMIT_CONFIG then emit config like object
1450c99fb5f9SBaptiste Daroussin  * @return dump of an object (must be freed after using) or NULL in case of error
1451c99fb5f9SBaptiste Daroussin  */
1452b04a7a0bSBaptiste Daroussin UCL_EXTERN unsigned char *ucl_object_emit (const ucl_object_t *obj,
1453b04a7a0bSBaptiste Daroussin 		enum ucl_emitter emit_type);
1454c99fb5f9SBaptiste Daroussin 
1455c99fb5f9SBaptiste Daroussin /**
145639ee7a7aSBaptiste Daroussin  * Emit object to a string that can contain `\0` inside
145739ee7a7aSBaptiste Daroussin  * @param obj object
145839ee7a7aSBaptiste Daroussin  * @param emit_type if type is #UCL_EMIT_JSON then emit json, if type is
145939ee7a7aSBaptiste Daroussin  * #UCL_EMIT_CONFIG then emit config like object
146039ee7a7aSBaptiste Daroussin  * @param len the resulting length
146139ee7a7aSBaptiste Daroussin  * @return dump of an object (must be freed after using) or NULL in case of error
146239ee7a7aSBaptiste Daroussin  */
146339ee7a7aSBaptiste Daroussin UCL_EXTERN unsigned char *ucl_object_emit_len (const ucl_object_t *obj,
146439ee7a7aSBaptiste Daroussin 		enum ucl_emitter emit_type, size_t *len);
146539ee7a7aSBaptiste Daroussin 
146639ee7a7aSBaptiste Daroussin /**
1467c99fb5f9SBaptiste Daroussin  * Emit object to a string
1468c99fb5f9SBaptiste Daroussin  * @param obj object
1469c99fb5f9SBaptiste Daroussin  * @param emit_type if type is #UCL_EMIT_JSON then emit json, if type is
1470c99fb5f9SBaptiste Daroussin  * #UCL_EMIT_CONFIG then emit config like object
14713dcf5eb7SBaptiste Daroussin  * @param emitter a set of emitter functions
1472d9f0ce31SBaptiste Daroussin  * @param comments optional comments for the parser
1473c99fb5f9SBaptiste Daroussin  * @return dump of an object (must be freed after using) or NULL in case of error
1474c99fb5f9SBaptiste Daroussin  */
1475b04a7a0bSBaptiste Daroussin UCL_EXTERN bool ucl_object_emit_full (const ucl_object_t *obj,
1476b04a7a0bSBaptiste Daroussin 		enum ucl_emitter emit_type,
1477d9f0ce31SBaptiste Daroussin 		struct ucl_emitter_functions *emitter,
1478d9f0ce31SBaptiste Daroussin 		const ucl_object_t *comments);
14793dcf5eb7SBaptiste Daroussin 
14803dcf5eb7SBaptiste Daroussin /**
14813dcf5eb7SBaptiste Daroussin  * Start streamlined UCL object emitter
14823dcf5eb7SBaptiste Daroussin  * @param obj top UCL object
14833dcf5eb7SBaptiste Daroussin  * @param emit_type emit type
14843dcf5eb7SBaptiste Daroussin  * @param emitter a set of emitter functions
14853dcf5eb7SBaptiste Daroussin  * @return new streamlined context that should be freed by
14863dcf5eb7SBaptiste Daroussin  * `ucl_object_emit_streamline_finish`
14873dcf5eb7SBaptiste Daroussin  */
14883dcf5eb7SBaptiste Daroussin UCL_EXTERN struct ucl_emitter_context* ucl_object_emit_streamline_new (
14893dcf5eb7SBaptiste Daroussin 		const ucl_object_t *obj, enum ucl_emitter emit_type,
14903dcf5eb7SBaptiste Daroussin 		struct ucl_emitter_functions *emitter);
14913dcf5eb7SBaptiste Daroussin 
14923dcf5eb7SBaptiste Daroussin /**
14933dcf5eb7SBaptiste Daroussin  * Start object or array container for the streamlined output
14943dcf5eb7SBaptiste Daroussin  * @param ctx streamlined context
14953dcf5eb7SBaptiste Daroussin  * @param obj container object
14963dcf5eb7SBaptiste Daroussin  */
14973dcf5eb7SBaptiste Daroussin UCL_EXTERN void ucl_object_emit_streamline_start_container (
14983dcf5eb7SBaptiste Daroussin 		struct ucl_emitter_context *ctx, const ucl_object_t *obj);
14993dcf5eb7SBaptiste Daroussin /**
15003dcf5eb7SBaptiste Daroussin  * Add a complete UCL object to streamlined output
15013dcf5eb7SBaptiste Daroussin  * @param ctx streamlined context
15023dcf5eb7SBaptiste Daroussin  * @param obj object to output
15033dcf5eb7SBaptiste Daroussin  */
15043dcf5eb7SBaptiste Daroussin UCL_EXTERN void ucl_object_emit_streamline_add_object (
15053dcf5eb7SBaptiste Daroussin 		struct ucl_emitter_context *ctx, const ucl_object_t *obj);
15063dcf5eb7SBaptiste Daroussin /**
15073dcf5eb7SBaptiste Daroussin  * End previously added container
15083dcf5eb7SBaptiste Daroussin  * @param ctx streamlined context
15093dcf5eb7SBaptiste Daroussin  */
15103dcf5eb7SBaptiste Daroussin UCL_EXTERN void ucl_object_emit_streamline_end_container (
15113dcf5eb7SBaptiste Daroussin 		struct ucl_emitter_context *ctx);
15123dcf5eb7SBaptiste Daroussin /**
15133dcf5eb7SBaptiste Daroussin  * Terminate streamlined container finishing all containers in it
15143dcf5eb7SBaptiste Daroussin  * @param ctx streamlined context
15153dcf5eb7SBaptiste Daroussin  */
15163dcf5eb7SBaptiste Daroussin UCL_EXTERN void ucl_object_emit_streamline_finish (
15173dcf5eb7SBaptiste Daroussin 		struct ucl_emitter_context *ctx);
15183dcf5eb7SBaptiste Daroussin 
15193dcf5eb7SBaptiste Daroussin /**
15203dcf5eb7SBaptiste Daroussin  * Returns functions to emit object to memory
15213dcf5eb7SBaptiste Daroussin  * @param pmem target pointer (should be freed by caller)
15223dcf5eb7SBaptiste Daroussin  * @return emitter functions structure
15233dcf5eb7SBaptiste Daroussin  */
15243dcf5eb7SBaptiste Daroussin UCL_EXTERN struct ucl_emitter_functions* ucl_object_emit_memory_funcs (
15253dcf5eb7SBaptiste Daroussin 		void **pmem);
15263dcf5eb7SBaptiste Daroussin 
15273dcf5eb7SBaptiste Daroussin /**
15283dcf5eb7SBaptiste Daroussin  * Returns functions to emit object to FILE *
15293dcf5eb7SBaptiste Daroussin  * @param fp FILE * object
15303dcf5eb7SBaptiste Daroussin  * @return emitter functions structure
15313dcf5eb7SBaptiste Daroussin  */
15323dcf5eb7SBaptiste Daroussin UCL_EXTERN struct ucl_emitter_functions* ucl_object_emit_file_funcs (
15333dcf5eb7SBaptiste Daroussin 		FILE *fp);
15343dcf5eb7SBaptiste Daroussin /**
15353dcf5eb7SBaptiste Daroussin  * Returns functions to emit object to a file descriptor
15363dcf5eb7SBaptiste Daroussin  * @param fd file descriptor
15373dcf5eb7SBaptiste Daroussin  * @return emitter functions structure
15383dcf5eb7SBaptiste Daroussin  */
15393dcf5eb7SBaptiste Daroussin UCL_EXTERN struct ucl_emitter_functions* ucl_object_emit_fd_funcs (
15403dcf5eb7SBaptiste Daroussin 		int fd);
15413dcf5eb7SBaptiste Daroussin 
15423dcf5eb7SBaptiste Daroussin /**
15433dcf5eb7SBaptiste Daroussin  * Free emitter functions
15443dcf5eb7SBaptiste Daroussin  * @param f pointer to functions
15453dcf5eb7SBaptiste Daroussin  */
15463dcf5eb7SBaptiste Daroussin UCL_EXTERN void ucl_object_emit_funcs_free (struct ucl_emitter_functions *f);
15473dcf5eb7SBaptiste Daroussin 
1548c99fb5f9SBaptiste Daroussin /** @} */
1549c99fb5f9SBaptiste Daroussin 
155097bd480fSBaptiste Daroussin /**
155197bd480fSBaptiste Daroussin  * @defgroup schema Schema functions
155297bd480fSBaptiste Daroussin  * These functions are used to validate UCL objects using json schema format
155397bd480fSBaptiste Daroussin  *
155497bd480fSBaptiste Daroussin  * @{
155597bd480fSBaptiste Daroussin  */
155697bd480fSBaptiste Daroussin 
155797bd480fSBaptiste Daroussin /**
155897bd480fSBaptiste Daroussin  * Used to define UCL schema error
155997bd480fSBaptiste Daroussin  */
156097bd480fSBaptiste Daroussin enum ucl_schema_error_code {
156197bd480fSBaptiste Daroussin 	UCL_SCHEMA_OK = 0,          /**< no error */
156297bd480fSBaptiste Daroussin 	UCL_SCHEMA_TYPE_MISMATCH,   /**< type of object is incorrect */
156397bd480fSBaptiste Daroussin 	UCL_SCHEMA_INVALID_SCHEMA,  /**< schema is invalid */
156497bd480fSBaptiste Daroussin 	UCL_SCHEMA_MISSING_PROPERTY,/**< one or more missing properties */
156597bd480fSBaptiste Daroussin 	UCL_SCHEMA_CONSTRAINT,      /**< constraint found */
156697bd480fSBaptiste Daroussin 	UCL_SCHEMA_MISSING_DEPENDENCY, /**< missing dependency */
1567d9f0ce31SBaptiste Daroussin 	UCL_SCHEMA_EXTERNAL_REF_MISSING, /**< cannot fetch external ref */
1568d9f0ce31SBaptiste Daroussin 	UCL_SCHEMA_EXTERNAL_REF_INVALID, /**< invalid external ref */
1569d9f0ce31SBaptiste Daroussin 	UCL_SCHEMA_INTERNAL_ERROR, /**< something bad happened */
157097bd480fSBaptiste Daroussin 	UCL_SCHEMA_UNKNOWN          /**< generic error */
157197bd480fSBaptiste Daroussin };
157297bd480fSBaptiste Daroussin 
157397bd480fSBaptiste Daroussin /**
157497bd480fSBaptiste Daroussin  * Generic ucl schema error
157597bd480fSBaptiste Daroussin  */
157697bd480fSBaptiste Daroussin struct ucl_schema_error {
157797bd480fSBaptiste Daroussin 	enum ucl_schema_error_code code;	/**< error code */
157897bd480fSBaptiste Daroussin 	char msg[128];						/**< error message */
1579*a0409676SBaptiste Daroussin 	const ucl_object_t *obj;			/**< object where error occurred */
158097bd480fSBaptiste Daroussin };
158197bd480fSBaptiste Daroussin 
158297bd480fSBaptiste Daroussin /**
158397bd480fSBaptiste Daroussin  * Validate object `obj` using schema object `schema`.
158497bd480fSBaptiste Daroussin  * @param schema schema object
158597bd480fSBaptiste Daroussin  * @param obj object to validate
158697bd480fSBaptiste Daroussin  * @param err error pointer, if this parameter is not NULL and error has been
1587*a0409676SBaptiste Daroussin  * occurred, then `err` is filled with the exact error definition.
158897bd480fSBaptiste Daroussin  * @return true if `obj` is valid using `schema`
158997bd480fSBaptiste Daroussin  */
1590b04a7a0bSBaptiste Daroussin UCL_EXTERN bool ucl_object_validate (const ucl_object_t *schema,
1591b04a7a0bSBaptiste Daroussin 		const ucl_object_t *obj, struct ucl_schema_error *err);
159297bd480fSBaptiste Daroussin 
1593d9f0ce31SBaptiste Daroussin /**
1594d9f0ce31SBaptiste Daroussin  * Validate object `obj` using schema object `schema` and root schema at `root`.
1595d9f0ce31SBaptiste Daroussin  * @param schema schema object
1596d9f0ce31SBaptiste Daroussin  * @param obj object to validate
1597d9f0ce31SBaptiste Daroussin  * @param root root schema object
1598d9f0ce31SBaptiste Daroussin  * @param err error pointer, if this parameter is not NULL and error has been
1599*a0409676SBaptiste Daroussin  * occurred, then `err` is filled with the exact error definition.
1600d9f0ce31SBaptiste Daroussin  * @return true if `obj` is valid using `schema`
1601d9f0ce31SBaptiste Daroussin  */
1602d9f0ce31SBaptiste Daroussin UCL_EXTERN bool ucl_object_validate_root (const ucl_object_t *schema,
1603d9f0ce31SBaptiste Daroussin 		const ucl_object_t *obj,
1604d9f0ce31SBaptiste Daroussin 		const ucl_object_t *root,
1605d9f0ce31SBaptiste Daroussin 		struct ucl_schema_error *err);
1606d9f0ce31SBaptiste Daroussin 
1607d9f0ce31SBaptiste Daroussin /**
1608d9f0ce31SBaptiste Daroussin  * Validate object `obj` using schema object `schema` and root schema at `root`
1609d9f0ce31SBaptiste Daroussin  * using some external references provided.
1610d9f0ce31SBaptiste Daroussin  * @param schema schema object
1611d9f0ce31SBaptiste Daroussin  * @param obj object to validate
1612d9f0ce31SBaptiste Daroussin  * @param root root schema object
1613d9f0ce31SBaptiste Daroussin  * @param ext_refs external references (might be modified during validation)
1614d9f0ce31SBaptiste Daroussin  * @param err error pointer, if this parameter is not NULL and error has been
1615*a0409676SBaptiste Daroussin  * occurred, then `err` is filled with the exact error definition.
1616d9f0ce31SBaptiste Daroussin  * @return true if `obj` is valid using `schema`
1617d9f0ce31SBaptiste Daroussin  */
1618d9f0ce31SBaptiste Daroussin UCL_EXTERN bool ucl_object_validate_root_ext (const ucl_object_t *schema,
1619d9f0ce31SBaptiste Daroussin 		const ucl_object_t *obj,
1620d9f0ce31SBaptiste Daroussin 		const ucl_object_t *root,
1621d9f0ce31SBaptiste Daroussin 		ucl_object_t *ext_refs,
1622d9f0ce31SBaptiste Daroussin 		struct ucl_schema_error *err);
1623d9f0ce31SBaptiste Daroussin 
162497bd480fSBaptiste Daroussin /** @} */
162597bd480fSBaptiste Daroussin 
1626c99fb5f9SBaptiste Daroussin #ifdef  __cplusplus
1627c99fb5f9SBaptiste Daroussin }
1628c99fb5f9SBaptiste Daroussin #endif
1629c99fb5f9SBaptiste Daroussin /*
1630c99fb5f9SBaptiste Daroussin  * XXX: Poorly named API functions, need to replace them with the appropriate
1631c99fb5f9SBaptiste Daroussin  * named function. All API functions *must* use naming ucl_object_*. Usage of
1632c99fb5f9SBaptiste Daroussin  * ucl_obj* should be avoided.
1633c99fb5f9SBaptiste Daroussin  */
1634c99fb5f9SBaptiste Daroussin #define ucl_obj_todouble_safe ucl_object_todouble_safe
1635c99fb5f9SBaptiste Daroussin #define ucl_obj_todouble ucl_object_todouble
1636c99fb5f9SBaptiste Daroussin #define ucl_obj_tostring ucl_object_tostring
1637c99fb5f9SBaptiste Daroussin #define ucl_obj_tostring_safe ucl_object_tostring_safe
1638c99fb5f9SBaptiste Daroussin #define ucl_obj_tolstring ucl_object_tolstring
1639c99fb5f9SBaptiste Daroussin #define ucl_obj_tolstring_safe ucl_object_tolstring_safe
1640c99fb5f9SBaptiste Daroussin #define ucl_obj_toint ucl_object_toint
1641c99fb5f9SBaptiste Daroussin #define ucl_obj_toint_safe ucl_object_toint_safe
1642c99fb5f9SBaptiste Daroussin #define ucl_obj_toboolean ucl_object_toboolean
1643c99fb5f9SBaptiste Daroussin #define ucl_obj_toboolean_safe ucl_object_toboolean_safe
1644c99fb5f9SBaptiste Daroussin #define ucl_obj_get_key ucl_object_find_key
1645c99fb5f9SBaptiste Daroussin #define ucl_obj_get_keyl ucl_object_find_keyl
1646c99fb5f9SBaptiste Daroussin #define ucl_obj_unref ucl_object_unref
1647c99fb5f9SBaptiste Daroussin #define ucl_obj_ref ucl_object_ref
1648c99fb5f9SBaptiste Daroussin #define ucl_obj_free ucl_object_free
1649c99fb5f9SBaptiste Daroussin 
1650*a0409676SBaptiste Daroussin #define UCL_PRIORITY_MIN 0
1651*a0409676SBaptiste Daroussin #define UCL_PRIORITY_MAX 15
1652*a0409676SBaptiste Daroussin 
1653c99fb5f9SBaptiste Daroussin #endif /* UCL_H_ */
1654