xref: /freebsd/contrib/libucl/include/ucl.h (revision 4bf5485791b743cece52e2defa8c8efdf389b57a)
1c99fb5f9SBaptiste Daroussin /* Copyright (c) 2013, 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 */
108c99fb5f9SBaptiste Daroussin 	UCL_EMACRO, /**< Error processing a macro */
109c99fb5f9SBaptiste Daroussin 	UCL_EINTERNAL, /**< Internal unclassified error */
110c99fb5f9SBaptiste Daroussin 	UCL_ESSL /**< SSL error */
111c99fb5f9SBaptiste Daroussin } ucl_error_t;
112c99fb5f9SBaptiste Daroussin 
113c99fb5f9SBaptiste Daroussin /**
114c99fb5f9SBaptiste Daroussin  * #ucl_object_t may have one of specified types, some types are compatible with each other and some are not.
115c99fb5f9SBaptiste Daroussin  * For example, you can always convert #UCL_TIME to #UCL_FLOAT. Also you can convert #UCL_FLOAT to #UCL_INTEGER
116c99fb5f9SBaptiste Daroussin  * by loosing floating point. Every object may be converted to a string by #ucl_object_tostring_forced() function.
117c99fb5f9SBaptiste Daroussin  *
118c99fb5f9SBaptiste Daroussin  */
119c99fb5f9SBaptiste Daroussin typedef enum ucl_type {
120c99fb5f9SBaptiste Daroussin 	UCL_OBJECT = 0, /**< UCL object - key/value pairs */
121c99fb5f9SBaptiste Daroussin 	UCL_ARRAY, /**< UCL array */
122c99fb5f9SBaptiste Daroussin 	UCL_INT, /**< Integer number */
123c99fb5f9SBaptiste Daroussin 	UCL_FLOAT, /**< Floating point number */
124c99fb5f9SBaptiste Daroussin 	UCL_STRING, /**< Null terminated string */
125c99fb5f9SBaptiste Daroussin 	UCL_BOOLEAN, /**< Boolean value */
126c99fb5f9SBaptiste Daroussin 	UCL_TIME, /**< Time value (floating point number of seconds) */
127c99fb5f9SBaptiste Daroussin 	UCL_USERDATA, /**< Opaque userdata pointer (may be used in macros) */
128c99fb5f9SBaptiste Daroussin 	UCL_NULL /**< Null value */
129c99fb5f9SBaptiste Daroussin } ucl_type_t;
130c99fb5f9SBaptiste Daroussin 
131c99fb5f9SBaptiste Daroussin /**
132c99fb5f9SBaptiste Daroussin  * You can use one of these types to serialise #ucl_object_t by using ucl_object_emit().
133c99fb5f9SBaptiste Daroussin  */
134c99fb5f9SBaptiste Daroussin typedef enum ucl_emitter {
135c99fb5f9SBaptiste Daroussin 	UCL_EMIT_JSON = 0, /**< Emit fine formatted JSON */
136c99fb5f9SBaptiste Daroussin 	UCL_EMIT_JSON_COMPACT, /**< Emit compacted JSON */
137c99fb5f9SBaptiste Daroussin 	UCL_EMIT_CONFIG, /**< Emit human readable config format */
138c99fb5f9SBaptiste Daroussin 	UCL_EMIT_YAML /**< Emit embedded YAML format */
139c99fb5f9SBaptiste Daroussin } ucl_emitter_t;
140c99fb5f9SBaptiste Daroussin 
141c99fb5f9SBaptiste Daroussin /**
142c99fb5f9SBaptiste Daroussin  * These flags defines parser behaviour. If you specify #UCL_PARSER_ZEROCOPY you must ensure
143c99fb5f9SBaptiste Daroussin  * that the input memory is not freed if an object is in use. Moreover, if you want to use
144c99fb5f9SBaptiste Daroussin  * zero-terminated keys and string values then you should not use zero-copy mode, as in this case
145c99fb5f9SBaptiste Daroussin  * UCL still has to perform copying implicitly.
146c99fb5f9SBaptiste Daroussin  */
147c99fb5f9SBaptiste Daroussin typedef enum ucl_parser_flags {
148c99fb5f9SBaptiste Daroussin 	UCL_PARSER_KEY_LOWERCASE = 0x1, /**< Convert all keys to lower case */
14997bd480fSBaptiste Daroussin 	UCL_PARSER_ZEROCOPY = 0x2, /**< Parse input in zero-copy mode if possible */
150*4bf54857SBaptiste Daroussin 	UCL_PARSER_NO_TIME = 0x4, /**< Do not parse time and treat time values as strings */
151*4bf54857SBaptiste Daroussin 	UCL_PARSER_NO_IMPLICIT_ARRAYS = 0x8 /** Create explicit arrays instead of implicit ones */
152c99fb5f9SBaptiste Daroussin } ucl_parser_flags_t;
153c99fb5f9SBaptiste Daroussin 
154c99fb5f9SBaptiste Daroussin /**
155c99fb5f9SBaptiste Daroussin  * String conversion flags, that are used in #ucl_object_fromstring_common function.
156c99fb5f9SBaptiste Daroussin  */
157c99fb5f9SBaptiste Daroussin typedef enum ucl_string_flags {
158c99fb5f9SBaptiste Daroussin 	UCL_STRING_ESCAPE = 0x1,  /**< Perform JSON escape */
159c99fb5f9SBaptiste Daroussin 	UCL_STRING_TRIM = 0x2,    /**< Trim leading and trailing whitespaces */
160c99fb5f9SBaptiste Daroussin 	UCL_STRING_PARSE_BOOLEAN = 0x4,    /**< Parse passed string and detect boolean */
161c99fb5f9SBaptiste Daroussin 	UCL_STRING_PARSE_INT = 0x8,    /**< Parse passed string and detect integer number */
162c99fb5f9SBaptiste Daroussin 	UCL_STRING_PARSE_DOUBLE = 0x10,    /**< Parse passed string and detect integer or float number */
16397bd480fSBaptiste Daroussin 	UCL_STRING_PARSE_TIME = 0x20, /**< Parse time strings */
16497bd480fSBaptiste Daroussin 	UCL_STRING_PARSE_NUMBER =  UCL_STRING_PARSE_INT|UCL_STRING_PARSE_DOUBLE|UCL_STRING_PARSE_TIME,  /**<
165c99fb5f9SBaptiste Daroussin 									Parse passed string and detect number */
166c99fb5f9SBaptiste Daroussin 	UCL_STRING_PARSE =  UCL_STRING_PARSE_BOOLEAN|UCL_STRING_PARSE_NUMBER,   /**<
167c99fb5f9SBaptiste Daroussin 									Parse passed string (and detect booleans and numbers) */
16897bd480fSBaptiste Daroussin 	UCL_STRING_PARSE_BYTES = 0x40  /**< Treat numbers as bytes */
169c99fb5f9SBaptiste Daroussin } ucl_string_flags_t;
170c99fb5f9SBaptiste Daroussin 
171c99fb5f9SBaptiste Daroussin /**
172c99fb5f9SBaptiste Daroussin  * Basic flags for an object
173c99fb5f9SBaptiste Daroussin  */
174c99fb5f9SBaptiste Daroussin typedef enum ucl_object_flags {
175*4bf54857SBaptiste Daroussin 	UCL_OBJECT_ALLOCATED_KEY = 0x1, /**< An object has key allocated internally */
176*4bf54857SBaptiste Daroussin 	UCL_OBJECT_ALLOCATED_VALUE = 0x2, /**< An object has a string value allocated internally */
177*4bf54857SBaptiste Daroussin 	UCL_OBJECT_NEED_KEY_ESCAPE = 0x4, /**< The key of an object need to be escaped on output */
178*4bf54857SBaptiste Daroussin 	UCL_OBJECT_EPHEMERAL = 0x8, /**< Temporary object that does not need to be freed really */
179*4bf54857SBaptiste Daroussin 	UCL_OBJECT_MULTILINE = 0x10, /**< String should be displayed as multiline string */
180*4bf54857SBaptiste Daroussin 	UCL_OBJECT_MULTIVALUE = 0x20 /**< Object is a key with multiple values */
181c99fb5f9SBaptiste Daroussin } ucl_object_flags_t;
182c99fb5f9SBaptiste Daroussin 
183c99fb5f9SBaptiste Daroussin /**
184c99fb5f9SBaptiste Daroussin  * UCL object structure. Please mention that the most of fields should not be touched by
185c99fb5f9SBaptiste Daroussin  * UCL users. In future, this structure may be converted to private one.
186c99fb5f9SBaptiste Daroussin  */
187c99fb5f9SBaptiste Daroussin typedef struct ucl_object_s {
188c99fb5f9SBaptiste Daroussin 	/**
189c99fb5f9SBaptiste Daroussin 	 * Variant value type
190c99fb5f9SBaptiste Daroussin 	 */
191c99fb5f9SBaptiste Daroussin 	union {
192c99fb5f9SBaptiste Daroussin 		int64_t iv;							/**< Int value of an object */
193c99fb5f9SBaptiste Daroussin 		const char *sv;					/**< String value of an object */
194c99fb5f9SBaptiste Daroussin 		double dv;							/**< Double value of an object */
195c99fb5f9SBaptiste Daroussin 		struct ucl_object_s *av;			/**< Array					*/
196c99fb5f9SBaptiste Daroussin 		void *ov;							/**< Object					*/
197c99fb5f9SBaptiste Daroussin 		void* ud;							/**< Opaque user data		*/
198c99fb5f9SBaptiste Daroussin 	} value;
199c99fb5f9SBaptiste Daroussin 	const char *key;						/**< Key of an object		*/
200c99fb5f9SBaptiste Daroussin 	struct ucl_object_s *next;				/**< Array handle			*/
201c99fb5f9SBaptiste Daroussin 	struct ucl_object_s *prev;				/**< Array handle			*/
202*4bf54857SBaptiste Daroussin 	uint32_t keylen;						/**< Lenght of a key		*/
203*4bf54857SBaptiste Daroussin 	uint32_t len;							/**< Size of an object		*/
204*4bf54857SBaptiste Daroussin 	uint32_t ref;							/**< Reference count		*/
205c99fb5f9SBaptiste Daroussin 	uint16_t flags;							/**< Object flags			*/
206*4bf54857SBaptiste Daroussin 	uint16_t type;							/**< Real type				*/
207*4bf54857SBaptiste Daroussin 	unsigned char* trash_stack[2];			/**< Pointer to allocated chunks */
208c99fb5f9SBaptiste Daroussin } ucl_object_t;
209c99fb5f9SBaptiste Daroussin 
210*4bf54857SBaptiste Daroussin /**
211*4bf54857SBaptiste Daroussin  * Destructor type for userdata objects
212*4bf54857SBaptiste Daroussin  * @param ud user specified data pointer
213*4bf54857SBaptiste Daroussin  */
214*4bf54857SBaptiste Daroussin typedef void (*ucl_userdata_dtor)(void *ud);
215*4bf54857SBaptiste Daroussin typedef const char* (*ucl_userdata_emitter)(void *ud);
216*4bf54857SBaptiste Daroussin 
217c99fb5f9SBaptiste Daroussin /** @} */
218c99fb5f9SBaptiste Daroussin 
219c99fb5f9SBaptiste Daroussin /**
220c99fb5f9SBaptiste Daroussin  * @defgroup utils Utility functions
221c99fb5f9SBaptiste Daroussin  * A number of utility functions simplify handling of UCL objects
222c99fb5f9SBaptiste Daroussin  *
223c99fb5f9SBaptiste Daroussin  * @{
224c99fb5f9SBaptiste Daroussin  */
225c99fb5f9SBaptiste Daroussin /**
226c99fb5f9SBaptiste Daroussin  * Copy and return a key of an object, returned key is zero-terminated
227c99fb5f9SBaptiste Daroussin  * @param obj CL object
228c99fb5f9SBaptiste Daroussin  * @return zero terminated key
229c99fb5f9SBaptiste Daroussin  */
230b04a7a0bSBaptiste Daroussin UCL_EXTERN char* ucl_copy_key_trash (const ucl_object_t *obj);
231c99fb5f9SBaptiste Daroussin 
232c99fb5f9SBaptiste Daroussin /**
233c99fb5f9SBaptiste Daroussin  * Copy and return a string value of an object, returned key is zero-terminated
234c99fb5f9SBaptiste Daroussin  * @param obj CL object
235c99fb5f9SBaptiste Daroussin  * @return zero terminated string representation of object value
236c99fb5f9SBaptiste Daroussin  */
237b04a7a0bSBaptiste Daroussin UCL_EXTERN char* ucl_copy_value_trash (const ucl_object_t *obj);
238c99fb5f9SBaptiste Daroussin 
239c99fb5f9SBaptiste Daroussin /**
240c99fb5f9SBaptiste Daroussin  * Creates a new object
241c99fb5f9SBaptiste Daroussin  * @return new object
242c99fb5f9SBaptiste Daroussin  */
24397bd480fSBaptiste Daroussin UCL_EXTERN ucl_object_t* ucl_object_new (void) UCL_WARN_UNUSED_RESULT;
244c99fb5f9SBaptiste Daroussin 
245c99fb5f9SBaptiste Daroussin /**
246c99fb5f9SBaptiste Daroussin  * Create new object with type specified
247c99fb5f9SBaptiste Daroussin  * @param type type of a new object
248c99fb5f9SBaptiste Daroussin  * @return new object
249c99fb5f9SBaptiste Daroussin  */
2502e8ed2b8SBaptiste Daroussin UCL_EXTERN ucl_object_t* ucl_object_typed_new (ucl_type_t type) UCL_WARN_UNUSED_RESULT;
2512e8ed2b8SBaptiste Daroussin 
2522e8ed2b8SBaptiste Daroussin /**
253*4bf54857SBaptiste Daroussin  * Create new object with type and priority specified
254*4bf54857SBaptiste Daroussin  * @param type type of a new object
255*4bf54857SBaptiste Daroussin  * @param priority priority of an object
256*4bf54857SBaptiste Daroussin  * @return new object
257*4bf54857SBaptiste Daroussin  */
258*4bf54857SBaptiste Daroussin UCL_EXTERN ucl_object_t* ucl_object_new_full (ucl_type_t type, unsigned priority)
259*4bf54857SBaptiste Daroussin 	UCL_WARN_UNUSED_RESULT;
260*4bf54857SBaptiste Daroussin 
261*4bf54857SBaptiste Daroussin /**
262*4bf54857SBaptiste Daroussin  * Create new object with userdata dtor
263*4bf54857SBaptiste Daroussin  * @param dtor destructor function
264*4bf54857SBaptiste Daroussin  * @return new object
265*4bf54857SBaptiste Daroussin  */
266*4bf54857SBaptiste Daroussin UCL_EXTERN ucl_object_t* ucl_object_new_userdata (ucl_userdata_dtor dtor,
267*4bf54857SBaptiste Daroussin 		ucl_userdata_emitter emitter) UCL_WARN_UNUSED_RESULT;
268*4bf54857SBaptiste Daroussin 
269*4bf54857SBaptiste Daroussin /**
270*4bf54857SBaptiste Daroussin  * Perform deep copy of an object copying everything
271*4bf54857SBaptiste Daroussin  * @param other object to copy
272*4bf54857SBaptiste Daroussin  * @return new object with refcount equal to 1
273*4bf54857SBaptiste Daroussin  */
274*4bf54857SBaptiste Daroussin UCL_EXTERN ucl_object_t * ucl_object_copy (const ucl_object_t *other)
275*4bf54857SBaptiste Daroussin 	UCL_WARN_UNUSED_RESULT;
276*4bf54857SBaptiste Daroussin 
277*4bf54857SBaptiste Daroussin /**
2782e8ed2b8SBaptiste Daroussin  * Return the type of an object
2792e8ed2b8SBaptiste Daroussin  * @return the object type
2802e8ed2b8SBaptiste Daroussin  */
2812e8ed2b8SBaptiste Daroussin UCL_EXTERN ucl_type_t ucl_object_type (const ucl_object_t *obj);
282c99fb5f9SBaptiste Daroussin 
283c99fb5f9SBaptiste Daroussin /**
284c99fb5f9SBaptiste Daroussin  * Convert any string to an ucl object making the specified transformations
285c99fb5f9SBaptiste Daroussin  * @param str fixed size or NULL terminated string
286c99fb5f9SBaptiste Daroussin  * @param len length (if len is zero, than str is treated as NULL terminated)
287c99fb5f9SBaptiste Daroussin  * @param flags conversion flags
288c99fb5f9SBaptiste Daroussin  * @return new object
289c99fb5f9SBaptiste Daroussin  */
29036c53d67SBaptiste Daroussin UCL_EXTERN ucl_object_t * ucl_object_fromstring_common (const char *str, size_t len,
291c99fb5f9SBaptiste Daroussin 		enum ucl_string_flags flags) UCL_WARN_UNUSED_RESULT;
292c99fb5f9SBaptiste Daroussin 
293c99fb5f9SBaptiste Daroussin /**
294c99fb5f9SBaptiste Daroussin  * Create a UCL object from the specified string
295c99fb5f9SBaptiste Daroussin  * @param str NULL terminated string, will be json escaped
296c99fb5f9SBaptiste Daroussin  * @return new object
297c99fb5f9SBaptiste Daroussin  */
298b04a7a0bSBaptiste Daroussin UCL_EXTERN ucl_object_t *ucl_object_fromstring (const char *str) UCL_WARN_UNUSED_RESULT;
299c99fb5f9SBaptiste Daroussin 
300c99fb5f9SBaptiste Daroussin /**
301c99fb5f9SBaptiste Daroussin  * Create a UCL object from the specified string
302c99fb5f9SBaptiste Daroussin  * @param str fixed size string, will be json escaped
303c99fb5f9SBaptiste Daroussin  * @param len length of a string
304c99fb5f9SBaptiste Daroussin  * @return new object
305c99fb5f9SBaptiste Daroussin  */
306b04a7a0bSBaptiste Daroussin UCL_EXTERN ucl_object_t *ucl_object_fromlstring (const char *str,
307b04a7a0bSBaptiste Daroussin 		size_t len) UCL_WARN_UNUSED_RESULT;
308c99fb5f9SBaptiste Daroussin 
309c99fb5f9SBaptiste Daroussin /**
310c99fb5f9SBaptiste Daroussin  * Create an object from an integer number
311c99fb5f9SBaptiste Daroussin  * @param iv number
312c99fb5f9SBaptiste Daroussin  * @return new object
313c99fb5f9SBaptiste Daroussin  */
314b04a7a0bSBaptiste Daroussin UCL_EXTERN ucl_object_t* ucl_object_fromint (int64_t iv) UCL_WARN_UNUSED_RESULT;
315c99fb5f9SBaptiste Daroussin 
316c99fb5f9SBaptiste Daroussin /**
317c99fb5f9SBaptiste Daroussin  * Create an object from a float number
318c99fb5f9SBaptiste Daroussin  * @param dv number
319c99fb5f9SBaptiste Daroussin  * @return new object
320c99fb5f9SBaptiste Daroussin  */
321b04a7a0bSBaptiste Daroussin UCL_EXTERN ucl_object_t* ucl_object_fromdouble (double dv) UCL_WARN_UNUSED_RESULT;
322c99fb5f9SBaptiste Daroussin 
323c99fb5f9SBaptiste Daroussin /**
324c99fb5f9SBaptiste Daroussin  * Create an object from a boolean
325c99fb5f9SBaptiste Daroussin  * @param bv bool value
326c99fb5f9SBaptiste Daroussin  * @return new object
327c99fb5f9SBaptiste Daroussin  */
328b04a7a0bSBaptiste Daroussin UCL_EXTERN ucl_object_t* ucl_object_frombool (bool bv) UCL_WARN_UNUSED_RESULT;
329c99fb5f9SBaptiste Daroussin 
330c99fb5f9SBaptiste Daroussin /**
331c99fb5f9SBaptiste Daroussin  * Insert a object 'elt' to the hash 'top' and associate it with key 'key'
332*4bf54857SBaptiste Daroussin  * @param top destination object (must be of type UCL_OBJECT)
333c99fb5f9SBaptiste Daroussin  * @param elt element to insert (must NOT be NULL)
334c99fb5f9SBaptiste Daroussin  * @param key key to associate with this object (either const or preallocated)
335c99fb5f9SBaptiste Daroussin  * @param keylen length of the key (or 0 for NULL terminated keys)
336c99fb5f9SBaptiste Daroussin  * @param copy_key make an internal copy of key
337b04a7a0bSBaptiste Daroussin  * @return true if key has been inserted
338c99fb5f9SBaptiste Daroussin  */
339b04a7a0bSBaptiste Daroussin UCL_EXTERN bool ucl_object_insert_key (ucl_object_t *top, ucl_object_t *elt,
340b04a7a0bSBaptiste Daroussin 		const char *key, size_t keylen, bool copy_key);
341c99fb5f9SBaptiste Daroussin 
342c99fb5f9SBaptiste Daroussin /**
343c99fb5f9SBaptiste Daroussin  * Replace a object 'elt' to the hash 'top' and associate it with key 'key', old object will be unrefed,
344c99fb5f9SBaptiste Daroussin  * if no object has been found this function works like ucl_object_insert_key()
345*4bf54857SBaptiste Daroussin  * @param top destination object (must be of type UCL_OBJECT)
346c99fb5f9SBaptiste Daroussin  * @param elt element to insert (must NOT be NULL)
347c99fb5f9SBaptiste Daroussin  * @param key key to associate with this object (either const or preallocated)
348c99fb5f9SBaptiste Daroussin  * @param keylen length of the key (or 0 for NULL terminated keys)
349c99fb5f9SBaptiste Daroussin  * @param copy_key make an internal copy of key
350b04a7a0bSBaptiste Daroussin  * @return true if key has been inserted
351c99fb5f9SBaptiste Daroussin  */
352b04a7a0bSBaptiste Daroussin UCL_EXTERN bool ucl_object_replace_key (ucl_object_t *top, ucl_object_t *elt,
353b04a7a0bSBaptiste Daroussin 		const char *key, size_t keylen, bool copy_key);
354c99fb5f9SBaptiste Daroussin 
355c99fb5f9SBaptiste Daroussin /**
356*4bf54857SBaptiste Daroussin  * Merge the keys from one object to another object. Overwrite on conflict
357*4bf54857SBaptiste Daroussin  * @param top destination object (must be of type UCL_OBJECT)
358*4bf54857SBaptiste Daroussin  * @param elt element to insert (must be of type UCL_OBJECT)
359*4bf54857SBaptiste Daroussin  * @param copy copy rather than reference the elements
360*4bf54857SBaptiste Daroussin  * @return true if all keys have been merged
361*4bf54857SBaptiste Daroussin  */
362*4bf54857SBaptiste Daroussin UCL_EXTERN bool ucl_object_merge (ucl_object_t *top, ucl_object_t *elt, bool copy);
363*4bf54857SBaptiste Daroussin 
364*4bf54857SBaptiste Daroussin /**
36536c53d67SBaptiste Daroussin  * Delete a object associated with key 'key', old object will be unrefered,
36636c53d67SBaptiste Daroussin  * @param top object
36736c53d67SBaptiste Daroussin  * @param key key associated to the object to remove
36836c53d67SBaptiste Daroussin  * @param keylen length of the key (or 0 for NULL terminated keys)
36936c53d67SBaptiste Daroussin  */
370b04a7a0bSBaptiste Daroussin UCL_EXTERN bool ucl_object_delete_keyl (ucl_object_t *top,
371b04a7a0bSBaptiste Daroussin 		const char *key, size_t keylen);
37236c53d67SBaptiste Daroussin 
37336c53d67SBaptiste Daroussin /**
37436c53d67SBaptiste Daroussin  * Delete a object associated with key 'key', old object will be unrefered,
37536c53d67SBaptiste Daroussin  * @param top object
37636c53d67SBaptiste Daroussin  * @param key key associated to the object to remove
37736c53d67SBaptiste Daroussin  */
378b04a7a0bSBaptiste Daroussin UCL_EXTERN bool ucl_object_delete_key (ucl_object_t *top,
379b04a7a0bSBaptiste Daroussin 		const char *key);
38036c53d67SBaptiste Daroussin 
38197bd480fSBaptiste Daroussin 
38297bd480fSBaptiste Daroussin /**
383*4bf54857SBaptiste Daroussin  * Removes `key` from `top` object, returning the object that was removed. This
384*4bf54857SBaptiste Daroussin  * object is not released, caller must unref the returned object when it is no
385*4bf54857SBaptiste Daroussin  * longer needed.
38697bd480fSBaptiste Daroussin  * @param top object
38797bd480fSBaptiste Daroussin  * @param key key to remove
38897bd480fSBaptiste Daroussin  * @param keylen length of the key (or 0 for NULL terminated keys)
38997bd480fSBaptiste Daroussin  * @return removed object or NULL if object has not been found
39097bd480fSBaptiste Daroussin  */
39197bd480fSBaptiste Daroussin UCL_EXTERN ucl_object_t* ucl_object_pop_keyl (ucl_object_t *top, const char *key,
39297bd480fSBaptiste Daroussin 		size_t keylen) UCL_WARN_UNUSED_RESULT;
39397bd480fSBaptiste Daroussin 
39497bd480fSBaptiste Daroussin /**
395*4bf54857SBaptiste Daroussin  * Removes `key` from `top` object returning the object that was removed. This
396*4bf54857SBaptiste Daroussin  * object is not released, caller must unref the returned object when it is no
397*4bf54857SBaptiste Daroussin  * longer needed.
39897bd480fSBaptiste Daroussin  * @param top object
39997bd480fSBaptiste Daroussin  * @param key key to remove
40097bd480fSBaptiste Daroussin  * @return removed object or NULL if object has not been found
40197bd480fSBaptiste Daroussin  */
40297bd480fSBaptiste Daroussin UCL_EXTERN ucl_object_t* ucl_object_pop_key (ucl_object_t *top, const char *key)
40397bd480fSBaptiste Daroussin 	UCL_WARN_UNUSED_RESULT;
40497bd480fSBaptiste Daroussin 
40536c53d67SBaptiste Daroussin /**
406*4bf54857SBaptiste Daroussin  * Insert a object 'elt' to the hash 'top' and associate it with key 'key', if
407*4bf54857SBaptiste Daroussin  * the specified key exist, try to merge its content
408*4bf54857SBaptiste Daroussin  * @param top destination object (must be of type UCL_OBJECT)
409c99fb5f9SBaptiste Daroussin  * @param elt element to insert (must NOT be NULL)
410c99fb5f9SBaptiste Daroussin  * @param key key to associate with this object (either const or preallocated)
411c99fb5f9SBaptiste Daroussin  * @param keylen length of the key (or 0 for NULL terminated keys)
412c99fb5f9SBaptiste Daroussin  * @param copy_key make an internal copy of key
413b04a7a0bSBaptiste Daroussin  * @return true if key has been inserted
414c99fb5f9SBaptiste Daroussin  */
415b04a7a0bSBaptiste Daroussin UCL_EXTERN bool ucl_object_insert_key_merged (ucl_object_t *top, ucl_object_t *elt,
416b04a7a0bSBaptiste Daroussin 		const char *key, size_t keylen, bool copy_key);
417c99fb5f9SBaptiste Daroussin 
418c99fb5f9SBaptiste Daroussin /**
419*4bf54857SBaptiste Daroussin  * Append an element to the end of array object
420*4bf54857SBaptiste Daroussin  * @param top destination object (must NOT be NULL)
421c99fb5f9SBaptiste Daroussin  * @param elt element to append (must NOT be NULL)
422b04a7a0bSBaptiste Daroussin  * @return true if value has been inserted
423c99fb5f9SBaptiste Daroussin  */
424b04a7a0bSBaptiste Daroussin UCL_EXTERN bool ucl_array_append (ucl_object_t *top,
425b04a7a0bSBaptiste Daroussin 		ucl_object_t *elt);
426c99fb5f9SBaptiste Daroussin 
427c99fb5f9SBaptiste Daroussin /**
428c99fb5f9SBaptiste Daroussin  * Append an element to the start of array object
429*4bf54857SBaptiste Daroussin  * @param top destination object (must NOT be NULL)
430c99fb5f9SBaptiste Daroussin  * @param elt element to append (must NOT be NULL)
431b04a7a0bSBaptiste Daroussin  * @return true if value has been inserted
432c99fb5f9SBaptiste Daroussin  */
433b04a7a0bSBaptiste Daroussin UCL_EXTERN bool ucl_array_prepend (ucl_object_t *top,
434b04a7a0bSBaptiste Daroussin 		ucl_object_t *elt);
435c99fb5f9SBaptiste Daroussin 
436c99fb5f9SBaptiste Daroussin /**
437*4bf54857SBaptiste Daroussin  * Merge all elements of second array into the first array
438*4bf54857SBaptiste Daroussin  * @param top destination array (must be of type UCL_ARRAY)
439*4bf54857SBaptiste Daroussin  * @param elt array to copy elements from (must be of type UCL_ARRAY)
440*4bf54857SBaptiste Daroussin  * @param copy copy elements instead of referencing them
441*4bf54857SBaptiste Daroussin  * @return true if arrays were merged
442*4bf54857SBaptiste Daroussin  */
443*4bf54857SBaptiste Daroussin UCL_EXTERN bool ucl_array_merge (ucl_object_t *top, ucl_object_t *elt,
444*4bf54857SBaptiste Daroussin 		bool copy);
445*4bf54857SBaptiste Daroussin 
446*4bf54857SBaptiste Daroussin /**
447*4bf54857SBaptiste Daroussin  * Removes an element `elt` from the array `top`, returning the object that was
448*4bf54857SBaptiste Daroussin  * removed. This object is not released, caller must unref the returned object
449*4bf54857SBaptiste Daroussin  * when it is no longer needed.
450c99fb5f9SBaptiste Daroussin  * @param top array ucl object
451c99fb5f9SBaptiste Daroussin  * @param elt element to remove
452c99fb5f9SBaptiste Daroussin  * @return removed element or NULL if `top` is NULL or not an array
453c99fb5f9SBaptiste Daroussin  */
454b04a7a0bSBaptiste Daroussin UCL_EXTERN ucl_object_t* ucl_array_delete (ucl_object_t *top,
455b04a7a0bSBaptiste Daroussin 		ucl_object_t *elt);
456c99fb5f9SBaptiste Daroussin 
457c99fb5f9SBaptiste Daroussin /**
458c99fb5f9SBaptiste Daroussin  * Returns the first element of the array `top`
459c99fb5f9SBaptiste Daroussin  * @param top array ucl object
460c99fb5f9SBaptiste Daroussin  * @return element or NULL if `top` is NULL or not an array
461c99fb5f9SBaptiste Daroussin  */
462b04a7a0bSBaptiste Daroussin UCL_EXTERN const ucl_object_t* ucl_array_head (const ucl_object_t *top);
463c99fb5f9SBaptiste Daroussin 
464c99fb5f9SBaptiste Daroussin /**
465c99fb5f9SBaptiste Daroussin  * Returns the last element of the array `top`
466c99fb5f9SBaptiste Daroussin  * @param top array ucl object
467c99fb5f9SBaptiste Daroussin  * @return element or NULL if `top` is NULL or not an array
468c99fb5f9SBaptiste Daroussin  */
469b04a7a0bSBaptiste Daroussin UCL_EXTERN const ucl_object_t* ucl_array_tail (const ucl_object_t *top);
470c99fb5f9SBaptiste Daroussin 
471c99fb5f9SBaptiste Daroussin /**
472*4bf54857SBaptiste Daroussin  * Removes the last element from the array `top`, returning the object that was
473*4bf54857SBaptiste Daroussin  * removed. This object is not released, caller must unref the returned object
474*4bf54857SBaptiste Daroussin  * when it is no longer needed.
475c99fb5f9SBaptiste Daroussin  * @param top array ucl object
476c99fb5f9SBaptiste Daroussin  * @return removed element or NULL if `top` is NULL or not an array
477c99fb5f9SBaptiste Daroussin  */
47897bd480fSBaptiste Daroussin UCL_EXTERN ucl_object_t* ucl_array_pop_last (ucl_object_t *top);
479c99fb5f9SBaptiste Daroussin 
480c99fb5f9SBaptiste Daroussin /**
481*4bf54857SBaptiste Daroussin  * Removes the first element from the array `top`, returning the object that was
482*4bf54857SBaptiste Daroussin  * removed. This object is not released, caller must unref the returned object
483*4bf54857SBaptiste Daroussin  * when it is no longer needed.
484c99fb5f9SBaptiste Daroussin  * @param top array ucl object
485c99fb5f9SBaptiste Daroussin  * @return removed element or NULL if `top` is NULL or not an array
486c99fb5f9SBaptiste Daroussin  */
48797bd480fSBaptiste Daroussin UCL_EXTERN ucl_object_t* ucl_array_pop_first (ucl_object_t *top);
488c99fb5f9SBaptiste Daroussin 
489c99fb5f9SBaptiste Daroussin /**
490*4bf54857SBaptiste Daroussin  * Return object identified by index of the array `top`
491*4bf54857SBaptiste Daroussin  * @param top object to get a key from (must be of type UCL_ARRAY)
492*4bf54857SBaptiste Daroussin  * @param index array index to return
493*4bf54857SBaptiste Daroussin  * @return object at the specified index or NULL if index is not found
494*4bf54857SBaptiste Daroussin  */
495*4bf54857SBaptiste Daroussin UCL_EXTERN const ucl_object_t* ucl_array_find_index (const ucl_object_t *top,
496*4bf54857SBaptiste Daroussin 		unsigned int index);
497*4bf54857SBaptiste Daroussin 
498*4bf54857SBaptiste Daroussin /**
499*4bf54857SBaptiste Daroussin  * Replace an element in an array with a different element, returning the object
500*4bf54857SBaptiste Daroussin  * that was replaced. This object is not released, caller must unref the
501*4bf54857SBaptiste Daroussin  * returned object when it is no longer needed.
502*4bf54857SBaptiste Daroussin  * @param top destination object (must be of type UCL_ARRAY)
503*4bf54857SBaptiste Daroussin  * @param elt element to append (must NOT be NULL)
504*4bf54857SBaptiste Daroussin  * @param index array index in destination to overwrite with elt
505*4bf54857SBaptiste Daroussin  * @return object that was replaced or NULL if index is not found
506*4bf54857SBaptiste Daroussin  */
507*4bf54857SBaptiste Daroussin ucl_object_t *
508*4bf54857SBaptiste Daroussin ucl_array_replace_index (ucl_object_t *top, ucl_object_t *elt,
509*4bf54857SBaptiste Daroussin 	unsigned int index);
510*4bf54857SBaptiste Daroussin 
511*4bf54857SBaptiste Daroussin /**
512c99fb5f9SBaptiste Daroussin  * Append a element to another element forming an implicit array
513c99fb5f9SBaptiste Daroussin  * @param head head to append (may be NULL)
514c99fb5f9SBaptiste Daroussin  * @param elt new element
515*4bf54857SBaptiste Daroussin  * @return the new implicit array
516c99fb5f9SBaptiste Daroussin  */
51797bd480fSBaptiste Daroussin UCL_EXTERN ucl_object_t * ucl_elt_append (ucl_object_t *head,
518b04a7a0bSBaptiste Daroussin 		ucl_object_t *elt);
519c99fb5f9SBaptiste Daroussin 
520c99fb5f9SBaptiste Daroussin /**
521c99fb5f9SBaptiste Daroussin  * Converts an object to double value
522c99fb5f9SBaptiste Daroussin  * @param obj CL object
523c99fb5f9SBaptiste Daroussin  * @param target target double variable
524c99fb5f9SBaptiste Daroussin  * @return true if conversion was successful
525c99fb5f9SBaptiste Daroussin  */
526b04a7a0bSBaptiste Daroussin UCL_EXTERN bool ucl_object_todouble_safe (const ucl_object_t *obj, double *target);
527c99fb5f9SBaptiste Daroussin 
528c99fb5f9SBaptiste Daroussin /**
529c99fb5f9SBaptiste Daroussin  * Unsafe version of \ref ucl_obj_todouble_safe
530c99fb5f9SBaptiste Daroussin  * @param obj CL object
531c99fb5f9SBaptiste Daroussin  * @return double value
532c99fb5f9SBaptiste Daroussin  */
533b04a7a0bSBaptiste Daroussin UCL_EXTERN double ucl_object_todouble (const ucl_object_t *obj);
534c99fb5f9SBaptiste Daroussin 
535c99fb5f9SBaptiste Daroussin /**
536c99fb5f9SBaptiste Daroussin  * Converts an object to integer value
537c99fb5f9SBaptiste Daroussin  * @param obj CL object
538c99fb5f9SBaptiste Daroussin  * @param target target integer variable
539c99fb5f9SBaptiste Daroussin  * @return true if conversion was successful
540c99fb5f9SBaptiste Daroussin  */
541b04a7a0bSBaptiste Daroussin UCL_EXTERN bool ucl_object_toint_safe (const ucl_object_t *obj, int64_t *target);
542c99fb5f9SBaptiste Daroussin 
543c99fb5f9SBaptiste Daroussin /**
544c99fb5f9SBaptiste Daroussin  * Unsafe version of \ref ucl_obj_toint_safe
545c99fb5f9SBaptiste Daroussin  * @param obj CL object
546c99fb5f9SBaptiste Daroussin  * @return int value
547c99fb5f9SBaptiste Daroussin  */
548b04a7a0bSBaptiste Daroussin UCL_EXTERN int64_t ucl_object_toint (const ucl_object_t *obj);
549c99fb5f9SBaptiste Daroussin 
550c99fb5f9SBaptiste Daroussin /**
551c99fb5f9SBaptiste Daroussin  * Converts an object to boolean value
552c99fb5f9SBaptiste Daroussin  * @param obj CL object
553c99fb5f9SBaptiste Daroussin  * @param target target boolean variable
554c99fb5f9SBaptiste Daroussin  * @return true if conversion was successful
555c99fb5f9SBaptiste Daroussin  */
556b04a7a0bSBaptiste Daroussin UCL_EXTERN bool ucl_object_toboolean_safe (const ucl_object_t *obj, bool *target);
557c99fb5f9SBaptiste Daroussin 
558c99fb5f9SBaptiste Daroussin /**
559c99fb5f9SBaptiste Daroussin  * Unsafe version of \ref ucl_obj_toboolean_safe
560c99fb5f9SBaptiste Daroussin  * @param obj CL object
561c99fb5f9SBaptiste Daroussin  * @return boolean value
562c99fb5f9SBaptiste Daroussin  */
563b04a7a0bSBaptiste Daroussin UCL_EXTERN bool ucl_object_toboolean (const ucl_object_t *obj);
564c99fb5f9SBaptiste Daroussin 
565c99fb5f9SBaptiste Daroussin /**
566c99fb5f9SBaptiste Daroussin  * Converts an object to string value
567c99fb5f9SBaptiste Daroussin  * @param obj CL object
568c99fb5f9SBaptiste Daroussin  * @param target target string variable, no need to free value
569c99fb5f9SBaptiste Daroussin  * @return true if conversion was successful
570c99fb5f9SBaptiste Daroussin  */
571b04a7a0bSBaptiste Daroussin UCL_EXTERN bool ucl_object_tostring_safe (const ucl_object_t *obj, const char **target);
572c99fb5f9SBaptiste Daroussin 
573c99fb5f9SBaptiste Daroussin /**
574c99fb5f9SBaptiste Daroussin  * Unsafe version of \ref ucl_obj_tostring_safe
575c99fb5f9SBaptiste Daroussin  * @param obj CL object
576c99fb5f9SBaptiste Daroussin  * @return string value
577c99fb5f9SBaptiste Daroussin  */
578b04a7a0bSBaptiste Daroussin UCL_EXTERN const char* ucl_object_tostring (const ucl_object_t *obj);
579c99fb5f9SBaptiste Daroussin 
580c99fb5f9SBaptiste Daroussin /**
581c99fb5f9SBaptiste Daroussin  * Convert any object to a string in JSON notation if needed
582c99fb5f9SBaptiste Daroussin  * @param obj CL object
583c99fb5f9SBaptiste Daroussin  * @return string value
584c99fb5f9SBaptiste Daroussin  */
585b04a7a0bSBaptiste Daroussin UCL_EXTERN const char* ucl_object_tostring_forced (const ucl_object_t *obj);
586c99fb5f9SBaptiste Daroussin 
587c99fb5f9SBaptiste Daroussin /**
588c99fb5f9SBaptiste Daroussin  * Return string as char * and len, string may be not zero terminated, more efficient that \ref ucl_obj_tostring as it
589c99fb5f9SBaptiste Daroussin  * allows zero-copy (if #UCL_PARSER_ZEROCOPY has been used during parsing)
590c99fb5f9SBaptiste Daroussin  * @param obj CL object
591c99fb5f9SBaptiste Daroussin  * @param target target string variable, no need to free value
592c99fb5f9SBaptiste Daroussin  * @param tlen target length
593c99fb5f9SBaptiste Daroussin  * @return true if conversion was successful
594c99fb5f9SBaptiste Daroussin  */
595b04a7a0bSBaptiste Daroussin UCL_EXTERN bool ucl_object_tolstring_safe (const ucl_object_t *obj,
59697bd480fSBaptiste Daroussin 		const char **target, size_t *tlen);
597c99fb5f9SBaptiste Daroussin 
598c99fb5f9SBaptiste Daroussin /**
599c99fb5f9SBaptiste Daroussin  * Unsafe version of \ref ucl_obj_tolstring_safe
600c99fb5f9SBaptiste Daroussin  * @param obj CL object
601c99fb5f9SBaptiste Daroussin  * @return string value
602c99fb5f9SBaptiste Daroussin  */
603b04a7a0bSBaptiste Daroussin UCL_EXTERN const char* ucl_object_tolstring (const ucl_object_t *obj, size_t *tlen);
604c99fb5f9SBaptiste Daroussin 
605c99fb5f9SBaptiste Daroussin /**
606c99fb5f9SBaptiste Daroussin  * Return object identified by a key in the specified object
607c99fb5f9SBaptiste Daroussin  * @param obj object to get a key from (must be of type UCL_OBJECT)
608c99fb5f9SBaptiste Daroussin  * @param key key to search
609*4bf54857SBaptiste Daroussin  * @return object matching the specified key or NULL if key was not found
610c99fb5f9SBaptiste Daroussin  */
611b04a7a0bSBaptiste Daroussin UCL_EXTERN const ucl_object_t* ucl_object_find_key (const ucl_object_t *obj,
612b04a7a0bSBaptiste Daroussin 		const char *key);
613c99fb5f9SBaptiste Daroussin 
614c99fb5f9SBaptiste Daroussin /**
615c99fb5f9SBaptiste Daroussin  * Return object identified by a fixed size key in the specified object
616c99fb5f9SBaptiste Daroussin  * @param obj object to get a key from (must be of type UCL_OBJECT)
617c99fb5f9SBaptiste Daroussin  * @param key key to search
618c99fb5f9SBaptiste Daroussin  * @param klen length of a key
619*4bf54857SBaptiste Daroussin  * @return object matching the specified key or NULL if key was not found
620c99fb5f9SBaptiste Daroussin  */
621b04a7a0bSBaptiste Daroussin UCL_EXTERN const ucl_object_t* ucl_object_find_keyl (const ucl_object_t *obj,
622b04a7a0bSBaptiste Daroussin 		const char *key, size_t klen);
623c99fb5f9SBaptiste Daroussin 
624c99fb5f9SBaptiste Daroussin /**
6252e8ed2b8SBaptiste Daroussin  * Return object identified by dot notation string
6262e8ed2b8SBaptiste Daroussin  * @param obj object to search in
6272e8ed2b8SBaptiste Daroussin  * @param path dot.notation.path to the path to lookup. May use numeric .index on arrays
6282e8ed2b8SBaptiste Daroussin  * @return object matched the specified path or NULL if path is not found
6292e8ed2b8SBaptiste Daroussin  */
6302e8ed2b8SBaptiste Daroussin UCL_EXTERN const ucl_object_t *ucl_lookup_path (const ucl_object_t *obj,
6312e8ed2b8SBaptiste Daroussin 		const char *path);
6322e8ed2b8SBaptiste Daroussin 
6332e8ed2b8SBaptiste Daroussin /**
634c99fb5f9SBaptiste Daroussin  * Returns a key of an object as a NULL terminated string
635c99fb5f9SBaptiste Daroussin  * @param obj CL object
636c99fb5f9SBaptiste Daroussin  * @return key or NULL if there is no key
637c99fb5f9SBaptiste Daroussin  */
638b04a7a0bSBaptiste Daroussin UCL_EXTERN const char* ucl_object_key (const ucl_object_t *obj);
639c99fb5f9SBaptiste Daroussin 
640c99fb5f9SBaptiste Daroussin /**
641c99fb5f9SBaptiste Daroussin  * Returns a key of an object as a fixed size string (may be more efficient)
642c99fb5f9SBaptiste Daroussin  * @param obj CL object
643c99fb5f9SBaptiste Daroussin  * @param len target key length
644c99fb5f9SBaptiste Daroussin  * @return key pointer
645c99fb5f9SBaptiste Daroussin  */
646b04a7a0bSBaptiste Daroussin UCL_EXTERN const char* ucl_object_keyl (const ucl_object_t *obj, size_t *len);
647c99fb5f9SBaptiste Daroussin 
648c99fb5f9SBaptiste Daroussin /**
649c99fb5f9SBaptiste Daroussin  * Increase reference count for an object
650c99fb5f9SBaptiste Daroussin  * @param obj object to ref
651*4bf54857SBaptiste Daroussin  * @return the referenced object
652c99fb5f9SBaptiste Daroussin  */
653b04a7a0bSBaptiste Daroussin UCL_EXTERN ucl_object_t* ucl_object_ref (const ucl_object_t *obj);
654b04a7a0bSBaptiste Daroussin 
655b04a7a0bSBaptiste Daroussin /**
656b04a7a0bSBaptiste Daroussin  * Free ucl object
657b04a7a0bSBaptiste Daroussin  * @param obj ucl object to free
658b04a7a0bSBaptiste Daroussin  */
659b04a7a0bSBaptiste Daroussin UCL_DEPRECATED(UCL_EXTERN void ucl_object_free (ucl_object_t *obj));
660c99fb5f9SBaptiste Daroussin 
661c99fb5f9SBaptiste Daroussin /**
662c99fb5f9SBaptiste Daroussin  * Decrease reference count for an object
663c99fb5f9SBaptiste Daroussin  * @param obj object to unref
664c99fb5f9SBaptiste Daroussin  */
66597bd480fSBaptiste Daroussin UCL_EXTERN void ucl_object_unref (ucl_object_t *obj);
66697bd480fSBaptiste Daroussin 
66797bd480fSBaptiste Daroussin /**
66897bd480fSBaptiste Daroussin  * Compare objects `o1` and `o2`
66997bd480fSBaptiste Daroussin  * @param o1 the first object
67097bd480fSBaptiste Daroussin  * @param o2 the second object
67197bd480fSBaptiste Daroussin  * @return values >0, 0 and <0 if `o1` is more than, equal and less than `o2`.
67297bd480fSBaptiste Daroussin  * The order of comparison:
67397bd480fSBaptiste Daroussin  * 1) Type of objects
67497bd480fSBaptiste Daroussin  * 2) Size of objects
67597bd480fSBaptiste Daroussin  * 3) Content of objects
67697bd480fSBaptiste Daroussin  */
677b04a7a0bSBaptiste Daroussin UCL_EXTERN int ucl_object_compare (const ucl_object_t *o1,
678b04a7a0bSBaptiste Daroussin 		const ucl_object_t *o2);
67997bd480fSBaptiste Daroussin 
68097bd480fSBaptiste Daroussin /**
68197bd480fSBaptiste Daroussin  * Sort UCL array using `cmp` compare function
68297bd480fSBaptiste Daroussin  * @param ar
68397bd480fSBaptiste Daroussin  * @param cmp
68497bd480fSBaptiste Daroussin  */
68597bd480fSBaptiste Daroussin UCL_EXTERN void ucl_object_array_sort (ucl_object_t *ar,
686b04a7a0bSBaptiste Daroussin 		int (*cmp)(const ucl_object_t *o1, const ucl_object_t *o2));
68797bd480fSBaptiste Daroussin 
688c99fb5f9SBaptiste Daroussin /**
689*4bf54857SBaptiste Daroussin  * Get the priority for specific UCL object
690*4bf54857SBaptiste Daroussin  * @param obj any ucl object
691*4bf54857SBaptiste Daroussin  * @return priority of an object
692*4bf54857SBaptiste Daroussin  */
693*4bf54857SBaptiste Daroussin UCL_EXTERN unsigned int ucl_object_get_priority (const ucl_object_t *obj);
694*4bf54857SBaptiste Daroussin 
695*4bf54857SBaptiste Daroussin /**
696*4bf54857SBaptiste Daroussin  * Set explicit priority of an object.
697*4bf54857SBaptiste Daroussin  * @param obj any ucl object
698*4bf54857SBaptiste Daroussin  * @param priority new priroity value (only 4 least significant bits are considred)
699*4bf54857SBaptiste Daroussin  */
700*4bf54857SBaptiste Daroussin UCL_EXTERN void ucl_object_set_priority (ucl_object_t *obj,
701*4bf54857SBaptiste Daroussin 		unsigned int priority);
702*4bf54857SBaptiste Daroussin 
703*4bf54857SBaptiste Daroussin /**
704c99fb5f9SBaptiste Daroussin  * Opaque iterator object
705c99fb5f9SBaptiste Daroussin  */
706c99fb5f9SBaptiste Daroussin typedef void* ucl_object_iter_t;
707c99fb5f9SBaptiste Daroussin 
708c99fb5f9SBaptiste Daroussin /**
709c99fb5f9SBaptiste Daroussin  * Get next key from an object
710c99fb5f9SBaptiste Daroussin  * @param obj object to iterate
711c99fb5f9SBaptiste Daroussin  * @param iter opaque iterator, must be set to NULL on the first call:
712c99fb5f9SBaptiste Daroussin  * ucl_object_iter_t it = NULL;
713c99fb5f9SBaptiste Daroussin  * while ((cur = ucl_iterate_object (obj, &it)) != NULL) ...
714c99fb5f9SBaptiste Daroussin  * @return the next object or NULL
715c99fb5f9SBaptiste Daroussin  */
716b04a7a0bSBaptiste Daroussin UCL_EXTERN const ucl_object_t* ucl_iterate_object (const ucl_object_t *obj,
717b04a7a0bSBaptiste Daroussin 		ucl_object_iter_t *iter, bool expand_values);
718c99fb5f9SBaptiste Daroussin /** @} */
719c99fb5f9SBaptiste Daroussin 
720c99fb5f9SBaptiste Daroussin 
721c99fb5f9SBaptiste Daroussin /**
722c99fb5f9SBaptiste Daroussin  * @defgroup parser Parsing functions
723c99fb5f9SBaptiste Daroussin  * These functions are used to parse UCL objects
724c99fb5f9SBaptiste Daroussin  *
725c99fb5f9SBaptiste Daroussin  * @{
726c99fb5f9SBaptiste Daroussin  */
727c99fb5f9SBaptiste Daroussin 
728c99fb5f9SBaptiste Daroussin /**
729c99fb5f9SBaptiste Daroussin  * Macro handler for a parser
730c99fb5f9SBaptiste Daroussin  * @param data the content of macro
731c99fb5f9SBaptiste Daroussin  * @param len the length of content
732*4bf54857SBaptiste Daroussin  * @param arguments arguments object
733c99fb5f9SBaptiste Daroussin  * @param ud opaque user data
734c99fb5f9SBaptiste Daroussin  * @param err error pointer
735c99fb5f9SBaptiste Daroussin  * @return true if macro has been parsed
736c99fb5f9SBaptiste Daroussin  */
737*4bf54857SBaptiste Daroussin typedef bool (*ucl_macro_handler) (const unsigned char *data, size_t len,
738*4bf54857SBaptiste Daroussin 		const ucl_object_t *arguments,
739*4bf54857SBaptiste Daroussin 		void* ud);
740c99fb5f9SBaptiste Daroussin 
741c99fb5f9SBaptiste Daroussin /* Opaque parser */
742c99fb5f9SBaptiste Daroussin struct ucl_parser;
743c99fb5f9SBaptiste Daroussin 
744c99fb5f9SBaptiste Daroussin /**
745c99fb5f9SBaptiste Daroussin  * Creates new parser object
746c99fb5f9SBaptiste Daroussin  * @param pool pool to allocate memory from
747c99fb5f9SBaptiste Daroussin  * @return new parser object
748c99fb5f9SBaptiste Daroussin  */
74936c53d67SBaptiste Daroussin UCL_EXTERN struct ucl_parser* ucl_parser_new (int flags);
750c99fb5f9SBaptiste Daroussin 
751c99fb5f9SBaptiste Daroussin /**
752c99fb5f9SBaptiste Daroussin  * Register new handler for a macro
753c99fb5f9SBaptiste Daroussin  * @param parser parser object
754c99fb5f9SBaptiste Daroussin  * @param macro macro name (without leading dot)
755c99fb5f9SBaptiste Daroussin  * @param handler handler (it is called immediately after macro is parsed)
756c99fb5f9SBaptiste Daroussin  * @param ud opaque user data for a handler
757c99fb5f9SBaptiste Daroussin  */
75836c53d67SBaptiste Daroussin UCL_EXTERN void ucl_parser_register_macro (struct ucl_parser *parser, const char *macro,
759c99fb5f9SBaptiste Daroussin 		ucl_macro_handler handler, void* ud);
760c99fb5f9SBaptiste Daroussin 
761c99fb5f9SBaptiste Daroussin /**
7622e8ed2b8SBaptiste Daroussin  * Handler to detect unregistered variables
7632e8ed2b8SBaptiste Daroussin  * @param data variable data
7642e8ed2b8SBaptiste Daroussin  * @param len length of variable
7652e8ed2b8SBaptiste Daroussin  * @param replace (out) replace value for variable
7662e8ed2b8SBaptiste Daroussin  * @param replace_len (out) replace length for variable
7672e8ed2b8SBaptiste Daroussin  * @param need_free (out) UCL will free `dest` after usage
7682e8ed2b8SBaptiste Daroussin  * @param ud opaque userdata
7692e8ed2b8SBaptiste Daroussin  * @return true if variable
7702e8ed2b8SBaptiste Daroussin  */
7712e8ed2b8SBaptiste Daroussin typedef bool (*ucl_variable_handler) (const unsigned char *data, size_t len,
7722e8ed2b8SBaptiste Daroussin 		unsigned char **replace, size_t *replace_len, bool *need_free, void* ud);
7732e8ed2b8SBaptiste Daroussin 
7742e8ed2b8SBaptiste Daroussin /**
775c99fb5f9SBaptiste Daroussin  * Register new parser variable
776c99fb5f9SBaptiste Daroussin  * @param parser parser object
777c99fb5f9SBaptiste Daroussin  * @param var variable name
778c99fb5f9SBaptiste Daroussin  * @param value variable value
779c99fb5f9SBaptiste Daroussin  */
78036c53d67SBaptiste Daroussin UCL_EXTERN void ucl_parser_register_variable (struct ucl_parser *parser, const char *var,
781c99fb5f9SBaptiste Daroussin 		const char *value);
782c99fb5f9SBaptiste Daroussin 
783c99fb5f9SBaptiste Daroussin /**
7842e8ed2b8SBaptiste Daroussin  * Set handler for unknown variables
7852e8ed2b8SBaptiste Daroussin  * @param parser parser structure
7862e8ed2b8SBaptiste Daroussin  * @param handler desired handler
7872e8ed2b8SBaptiste Daroussin  * @param ud opaque data for the handler
7882e8ed2b8SBaptiste Daroussin  */
7892e8ed2b8SBaptiste Daroussin UCL_EXTERN void ucl_parser_set_variables_handler (struct ucl_parser *parser,
7902e8ed2b8SBaptiste Daroussin 		ucl_variable_handler handler, void *ud);
7912e8ed2b8SBaptiste Daroussin 
7922e8ed2b8SBaptiste Daroussin /**
793c99fb5f9SBaptiste Daroussin  * Load new chunk to a parser
794c99fb5f9SBaptiste Daroussin  * @param parser parser structure
795c99fb5f9SBaptiste Daroussin  * @param data the pointer to the beginning of a chunk
796c99fb5f9SBaptiste Daroussin  * @param len the length of a chunk
797c99fb5f9SBaptiste Daroussin  * @return true if chunk has been added and false in case of error
798c99fb5f9SBaptiste Daroussin  */
79997bd480fSBaptiste Daroussin UCL_EXTERN bool ucl_parser_add_chunk (struct ucl_parser *parser,
80097bd480fSBaptiste Daroussin 		const unsigned char *data, size_t len);
80197bd480fSBaptiste Daroussin 
80297bd480fSBaptiste Daroussin /**
803*4bf54857SBaptiste Daroussin  * Load new chunk to a parser with the specified priority
804*4bf54857SBaptiste Daroussin  * @param parser parser structure
805*4bf54857SBaptiste Daroussin  * @param data the pointer to the beginning of a chunk
806*4bf54857SBaptiste Daroussin  * @param len the length of a chunk
807*4bf54857SBaptiste Daroussin  * @param priority the desired priority of a chunk (only 4 least significant bits
808*4bf54857SBaptiste Daroussin  * are considered for this parameter)
809*4bf54857SBaptiste Daroussin  * @return true if chunk has been added and false in case of error
810*4bf54857SBaptiste Daroussin  */
811*4bf54857SBaptiste Daroussin UCL_EXTERN bool ucl_parser_add_chunk_priority (struct ucl_parser *parser,
812*4bf54857SBaptiste Daroussin 		const unsigned char *data, size_t len, unsigned priority);
813*4bf54857SBaptiste Daroussin 
814*4bf54857SBaptiste Daroussin /**
81597bd480fSBaptiste Daroussin  * Load ucl object from a string
81697bd480fSBaptiste Daroussin  * @param parser parser structure
81797bd480fSBaptiste Daroussin  * @param data the pointer to the string
81897bd480fSBaptiste Daroussin  * @param len the length of the string, if `len` is 0 then `data` must be zero-terminated string
81997bd480fSBaptiste Daroussin  * @return true if string has been added and false in case of error
82097bd480fSBaptiste Daroussin  */
82197bd480fSBaptiste Daroussin UCL_EXTERN bool ucl_parser_add_string (struct ucl_parser *parser,
82297bd480fSBaptiste Daroussin 		const char *data,size_t len);
823c99fb5f9SBaptiste Daroussin 
824c99fb5f9SBaptiste Daroussin /**
825c99fb5f9SBaptiste Daroussin  * Load and add data from a file
826c99fb5f9SBaptiste Daroussin  * @param parser parser structure
827c99fb5f9SBaptiste Daroussin  * @param filename the name of file
828c99fb5f9SBaptiste Daroussin  * @param err if *err is NULL it is set to parser error
829c99fb5f9SBaptiste Daroussin  * @return true if chunk has been added and false in case of error
830c99fb5f9SBaptiste Daroussin  */
831b04a7a0bSBaptiste Daroussin UCL_EXTERN bool ucl_parser_add_file (struct ucl_parser *parser,
832b04a7a0bSBaptiste Daroussin 		const char *filename);
833c99fb5f9SBaptiste Daroussin 
834c99fb5f9SBaptiste Daroussin /**
835b04a7a0bSBaptiste Daroussin  * Load and add data from a file descriptor
836b04a7a0bSBaptiste Daroussin  * @param parser parser structure
837b04a7a0bSBaptiste Daroussin  * @param filename the name of file
838b04a7a0bSBaptiste Daroussin  * @param err if *err is NULL it is set to parser error
839b04a7a0bSBaptiste Daroussin  * @return true if chunk has been added and false in case of error
840b04a7a0bSBaptiste Daroussin  */
841b04a7a0bSBaptiste Daroussin UCL_EXTERN bool ucl_parser_add_fd (struct ucl_parser *parser,
842b04a7a0bSBaptiste Daroussin 		int fd);
843b04a7a0bSBaptiste Daroussin 
844b04a7a0bSBaptiste Daroussin /**
845b04a7a0bSBaptiste Daroussin  * Get a top object for a parser (refcount is increased)
846c99fb5f9SBaptiste Daroussin  * @param parser parser structure
847c99fb5f9SBaptiste Daroussin  * @param err if *err is NULL it is set to parser error
848c99fb5f9SBaptiste Daroussin  * @return top parser object or NULL
849c99fb5f9SBaptiste Daroussin  */
85036c53d67SBaptiste Daroussin UCL_EXTERN ucl_object_t* ucl_parser_get_object (struct ucl_parser *parser);
851c99fb5f9SBaptiste Daroussin 
852c99fb5f9SBaptiste Daroussin /**
853c99fb5f9SBaptiste Daroussin  * Get the error string if failing
854c99fb5f9SBaptiste Daroussin  * @param parser parser object
855c99fb5f9SBaptiste Daroussin  */
85636c53d67SBaptiste Daroussin UCL_EXTERN const char *ucl_parser_get_error(struct ucl_parser *parser);
857c99fb5f9SBaptiste Daroussin /**
858c99fb5f9SBaptiste Daroussin  * Free ucl parser object
859c99fb5f9SBaptiste Daroussin  * @param parser parser object
860c99fb5f9SBaptiste Daroussin  */
86136c53d67SBaptiste Daroussin UCL_EXTERN void ucl_parser_free (struct ucl_parser *parser);
862c99fb5f9SBaptiste Daroussin 
863c99fb5f9SBaptiste Daroussin /**
864c99fb5f9SBaptiste Daroussin  * Add new public key to parser for signatures check
865c99fb5f9SBaptiste Daroussin  * @param parser parser object
866c99fb5f9SBaptiste Daroussin  * @param key PEM representation of a key
867c99fb5f9SBaptiste Daroussin  * @param len length of the key
868c99fb5f9SBaptiste Daroussin  * @param err if *err is NULL it is set to parser error
869c99fb5f9SBaptiste Daroussin  * @return true if a key has been successfully added
870c99fb5f9SBaptiste Daroussin  */
87136c53d67SBaptiste Daroussin UCL_EXTERN bool ucl_pubkey_add (struct ucl_parser *parser, const unsigned char *key, size_t len);
872c99fb5f9SBaptiste Daroussin 
873c99fb5f9SBaptiste Daroussin /**
874c99fb5f9SBaptiste Daroussin  * Set FILENAME and CURDIR variables in parser
875c99fb5f9SBaptiste Daroussin  * @param parser parser object
876c99fb5f9SBaptiste Daroussin  * @param filename filename to set or NULL to set FILENAME to "undef" and CURDIR to getcwd()
877c99fb5f9SBaptiste Daroussin  * @param need_expand perform realpath() if this variable is true and filename is not NULL
878c99fb5f9SBaptiste Daroussin  * @return true if variables has been set
879c99fb5f9SBaptiste Daroussin  */
88036c53d67SBaptiste Daroussin UCL_EXTERN bool ucl_parser_set_filevars (struct ucl_parser *parser, const char *filename,
881c99fb5f9SBaptiste Daroussin 		bool need_expand);
882c99fb5f9SBaptiste Daroussin 
883c99fb5f9SBaptiste Daroussin /** @} */
884c99fb5f9SBaptiste Daroussin 
885c99fb5f9SBaptiste Daroussin /**
886c99fb5f9SBaptiste Daroussin  * @defgroup emitter Emitting functions
887c99fb5f9SBaptiste Daroussin  * These functions are used to serialise UCL objects to some string representation.
888c99fb5f9SBaptiste Daroussin  *
889c99fb5f9SBaptiste Daroussin  * @{
890c99fb5f9SBaptiste Daroussin  */
891c99fb5f9SBaptiste Daroussin 
8923dcf5eb7SBaptiste Daroussin struct ucl_emitter_context;
893c99fb5f9SBaptiste Daroussin /**
894c99fb5f9SBaptiste Daroussin  * Structure using for emitter callbacks
895c99fb5f9SBaptiste Daroussin  */
896c99fb5f9SBaptiste Daroussin struct ucl_emitter_functions {
897c99fb5f9SBaptiste Daroussin 	/** Append a single character */
898c99fb5f9SBaptiste Daroussin 	int (*ucl_emitter_append_character) (unsigned char c, size_t nchars, void *ud);
899c99fb5f9SBaptiste Daroussin 	/** Append a string of a specified length */
900c99fb5f9SBaptiste Daroussin 	int (*ucl_emitter_append_len) (unsigned const char *str, size_t len, void *ud);
901c99fb5f9SBaptiste Daroussin 	/** Append a 64 bit integer */
902c99fb5f9SBaptiste Daroussin 	int (*ucl_emitter_append_int) (int64_t elt, void *ud);
903c99fb5f9SBaptiste Daroussin 	/** Append floating point element */
904c99fb5f9SBaptiste Daroussin 	int (*ucl_emitter_append_double) (double elt, void *ud);
9053dcf5eb7SBaptiste Daroussin 	/** Free userdata */
9063dcf5eb7SBaptiste Daroussin 	void (*ucl_emitter_free_func)(void *ud);
907c99fb5f9SBaptiste Daroussin 	/** Opaque userdata pointer */
908c99fb5f9SBaptiste Daroussin 	void *ud;
909c99fb5f9SBaptiste Daroussin };
910c99fb5f9SBaptiste Daroussin 
9113dcf5eb7SBaptiste Daroussin struct ucl_emitter_operations {
9123dcf5eb7SBaptiste Daroussin 	/** Write a primitive element */
9133dcf5eb7SBaptiste Daroussin 	void (*ucl_emitter_write_elt) (struct ucl_emitter_context *ctx,
9143dcf5eb7SBaptiste Daroussin 		const ucl_object_t *obj, bool first, bool print_key);
9153dcf5eb7SBaptiste Daroussin 	/** Start ucl object */
9163dcf5eb7SBaptiste Daroussin 	void (*ucl_emitter_start_object) (struct ucl_emitter_context *ctx,
9173dcf5eb7SBaptiste Daroussin 		const ucl_object_t *obj, bool print_key);
9183dcf5eb7SBaptiste Daroussin 	/** End ucl object */
9193dcf5eb7SBaptiste Daroussin 	void (*ucl_emitter_end_object) (struct ucl_emitter_context *ctx,
9203dcf5eb7SBaptiste Daroussin 		const ucl_object_t *obj);
9213dcf5eb7SBaptiste Daroussin 	/** Start ucl array */
9223dcf5eb7SBaptiste Daroussin 	void (*ucl_emitter_start_array) (struct ucl_emitter_context *ctx,
9233dcf5eb7SBaptiste Daroussin 		const ucl_object_t *obj, bool print_key);
9243dcf5eb7SBaptiste Daroussin 	void (*ucl_emitter_end_array) (struct ucl_emitter_context *ctx,
9253dcf5eb7SBaptiste Daroussin 		const ucl_object_t *obj);
9263dcf5eb7SBaptiste Daroussin };
9273dcf5eb7SBaptiste Daroussin 
9283dcf5eb7SBaptiste Daroussin /**
9293dcf5eb7SBaptiste Daroussin  * Structure that defines emitter functions
9303dcf5eb7SBaptiste Daroussin  */
9313dcf5eb7SBaptiste Daroussin struct ucl_emitter_context {
9323dcf5eb7SBaptiste Daroussin 	/** Name of emitter (e.g. json, compact_json) */
9333dcf5eb7SBaptiste Daroussin 	const char *name;
9343dcf5eb7SBaptiste Daroussin 	/** Unique id (e.g. UCL_EMIT_JSON for standard emitters */
9353dcf5eb7SBaptiste Daroussin 	int id;
9363dcf5eb7SBaptiste Daroussin 	/** A set of output functions */
9373dcf5eb7SBaptiste Daroussin 	const struct ucl_emitter_functions *func;
9383dcf5eb7SBaptiste Daroussin 	/** A set of output operations */
9393dcf5eb7SBaptiste Daroussin 	const struct ucl_emitter_operations *ops;
9403dcf5eb7SBaptiste Daroussin 	/** Current amount of indent tabs */
941*4bf54857SBaptiste Daroussin 	unsigned int indent;
9423dcf5eb7SBaptiste Daroussin 	/** Top level object */
9433dcf5eb7SBaptiste Daroussin 	const ucl_object_t *top;
9443dcf5eb7SBaptiste Daroussin 	/** The rest of context */
9453dcf5eb7SBaptiste Daroussin 	unsigned char data[1];
9463dcf5eb7SBaptiste Daroussin };
9473dcf5eb7SBaptiste Daroussin 
948c99fb5f9SBaptiste Daroussin /**
949c99fb5f9SBaptiste Daroussin  * Emit object to a string
950c99fb5f9SBaptiste Daroussin  * @param obj object
951c99fb5f9SBaptiste Daroussin  * @param emit_type if type is #UCL_EMIT_JSON then emit json, if type is
952c99fb5f9SBaptiste Daroussin  * #UCL_EMIT_CONFIG then emit config like object
953c99fb5f9SBaptiste Daroussin  * @return dump of an object (must be freed after using) or NULL in case of error
954c99fb5f9SBaptiste Daroussin  */
955b04a7a0bSBaptiste Daroussin UCL_EXTERN unsigned char *ucl_object_emit (const ucl_object_t *obj,
956b04a7a0bSBaptiste Daroussin 		enum ucl_emitter emit_type);
957c99fb5f9SBaptiste Daroussin 
958c99fb5f9SBaptiste Daroussin /**
959c99fb5f9SBaptiste Daroussin  * Emit object to a string
960c99fb5f9SBaptiste Daroussin  * @param obj object
961c99fb5f9SBaptiste Daroussin  * @param emit_type if type is #UCL_EMIT_JSON then emit json, if type is
962c99fb5f9SBaptiste Daroussin  * #UCL_EMIT_CONFIG then emit config like object
9633dcf5eb7SBaptiste Daroussin  * @param emitter a set of emitter functions
964c99fb5f9SBaptiste Daroussin  * @return dump of an object (must be freed after using) or NULL in case of error
965c99fb5f9SBaptiste Daroussin  */
966b04a7a0bSBaptiste Daroussin UCL_EXTERN bool ucl_object_emit_full (const ucl_object_t *obj,
967b04a7a0bSBaptiste Daroussin 		enum ucl_emitter emit_type,
968c99fb5f9SBaptiste Daroussin 		struct ucl_emitter_functions *emitter);
9693dcf5eb7SBaptiste Daroussin 
9703dcf5eb7SBaptiste Daroussin /**
9713dcf5eb7SBaptiste Daroussin  * Start streamlined UCL object emitter
9723dcf5eb7SBaptiste Daroussin  * @param obj top UCL object
9733dcf5eb7SBaptiste Daroussin  * @param emit_type emit type
9743dcf5eb7SBaptiste Daroussin  * @param emitter a set of emitter functions
9753dcf5eb7SBaptiste Daroussin  * @return new streamlined context that should be freed by
9763dcf5eb7SBaptiste Daroussin  * `ucl_object_emit_streamline_finish`
9773dcf5eb7SBaptiste Daroussin  */
9783dcf5eb7SBaptiste Daroussin UCL_EXTERN struct ucl_emitter_context* ucl_object_emit_streamline_new (
9793dcf5eb7SBaptiste Daroussin 		const ucl_object_t *obj, enum ucl_emitter emit_type,
9803dcf5eb7SBaptiste Daroussin 		struct ucl_emitter_functions *emitter);
9813dcf5eb7SBaptiste Daroussin 
9823dcf5eb7SBaptiste Daroussin /**
9833dcf5eb7SBaptiste Daroussin  * Start object or array container for the streamlined output
9843dcf5eb7SBaptiste Daroussin  * @param ctx streamlined context
9853dcf5eb7SBaptiste Daroussin  * @param obj container object
9863dcf5eb7SBaptiste Daroussin  */
9873dcf5eb7SBaptiste Daroussin UCL_EXTERN void ucl_object_emit_streamline_start_container (
9883dcf5eb7SBaptiste Daroussin 		struct ucl_emitter_context *ctx, const ucl_object_t *obj);
9893dcf5eb7SBaptiste Daroussin /**
9903dcf5eb7SBaptiste Daroussin  * Add a complete UCL object to streamlined output
9913dcf5eb7SBaptiste Daroussin  * @param ctx streamlined context
9923dcf5eb7SBaptiste Daroussin  * @param obj object to output
9933dcf5eb7SBaptiste Daroussin  */
9943dcf5eb7SBaptiste Daroussin UCL_EXTERN void ucl_object_emit_streamline_add_object (
9953dcf5eb7SBaptiste Daroussin 		struct ucl_emitter_context *ctx, const ucl_object_t *obj);
9963dcf5eb7SBaptiste Daroussin /**
9973dcf5eb7SBaptiste Daroussin  * End previously added container
9983dcf5eb7SBaptiste Daroussin  * @param ctx streamlined context
9993dcf5eb7SBaptiste Daroussin  */
10003dcf5eb7SBaptiste Daroussin UCL_EXTERN void ucl_object_emit_streamline_end_container (
10013dcf5eb7SBaptiste Daroussin 		struct ucl_emitter_context *ctx);
10023dcf5eb7SBaptiste Daroussin /**
10033dcf5eb7SBaptiste Daroussin  * Terminate streamlined container finishing all containers in it
10043dcf5eb7SBaptiste Daroussin  * @param ctx streamlined context
10053dcf5eb7SBaptiste Daroussin  */
10063dcf5eb7SBaptiste Daroussin UCL_EXTERN void ucl_object_emit_streamline_finish (
10073dcf5eb7SBaptiste Daroussin 		struct ucl_emitter_context *ctx);
10083dcf5eb7SBaptiste Daroussin 
10093dcf5eb7SBaptiste Daroussin /**
10103dcf5eb7SBaptiste Daroussin  * Returns functions to emit object to memory
10113dcf5eb7SBaptiste Daroussin  * @param pmem target pointer (should be freed by caller)
10123dcf5eb7SBaptiste Daroussin  * @return emitter functions structure
10133dcf5eb7SBaptiste Daroussin  */
10143dcf5eb7SBaptiste Daroussin UCL_EXTERN struct ucl_emitter_functions* ucl_object_emit_memory_funcs (
10153dcf5eb7SBaptiste Daroussin 		void **pmem);
10163dcf5eb7SBaptiste Daroussin 
10173dcf5eb7SBaptiste Daroussin /**
10183dcf5eb7SBaptiste Daroussin  * Returns functions to emit object to FILE *
10193dcf5eb7SBaptiste Daroussin  * @param fp FILE * object
10203dcf5eb7SBaptiste Daroussin  * @return emitter functions structure
10213dcf5eb7SBaptiste Daroussin  */
10223dcf5eb7SBaptiste Daroussin UCL_EXTERN struct ucl_emitter_functions* ucl_object_emit_file_funcs (
10233dcf5eb7SBaptiste Daroussin 		FILE *fp);
10243dcf5eb7SBaptiste Daroussin /**
10253dcf5eb7SBaptiste Daroussin  * Returns functions to emit object to a file descriptor
10263dcf5eb7SBaptiste Daroussin  * @param fd file descriptor
10273dcf5eb7SBaptiste Daroussin  * @return emitter functions structure
10283dcf5eb7SBaptiste Daroussin  */
10293dcf5eb7SBaptiste Daroussin UCL_EXTERN struct ucl_emitter_functions* ucl_object_emit_fd_funcs (
10303dcf5eb7SBaptiste Daroussin 		int fd);
10313dcf5eb7SBaptiste Daroussin 
10323dcf5eb7SBaptiste Daroussin /**
10333dcf5eb7SBaptiste Daroussin  * Free emitter functions
10343dcf5eb7SBaptiste Daroussin  * @param f pointer to functions
10353dcf5eb7SBaptiste Daroussin  */
10363dcf5eb7SBaptiste Daroussin UCL_EXTERN void ucl_object_emit_funcs_free (struct ucl_emitter_functions *f);
10373dcf5eb7SBaptiste Daroussin 
1038c99fb5f9SBaptiste Daroussin /** @} */
1039c99fb5f9SBaptiste Daroussin 
104097bd480fSBaptiste Daroussin /**
104197bd480fSBaptiste Daroussin  * @defgroup schema Schema functions
104297bd480fSBaptiste Daroussin  * These functions are used to validate UCL objects using json schema format
104397bd480fSBaptiste Daroussin  *
104497bd480fSBaptiste Daroussin  * @{
104597bd480fSBaptiste Daroussin  */
104697bd480fSBaptiste Daroussin 
104797bd480fSBaptiste Daroussin /**
104897bd480fSBaptiste Daroussin  * Used to define UCL schema error
104997bd480fSBaptiste Daroussin  */
105097bd480fSBaptiste Daroussin enum ucl_schema_error_code {
105197bd480fSBaptiste Daroussin 	UCL_SCHEMA_OK = 0,          /**< no error */
105297bd480fSBaptiste Daroussin 	UCL_SCHEMA_TYPE_MISMATCH,   /**< type of object is incorrect */
105397bd480fSBaptiste Daroussin 	UCL_SCHEMA_INVALID_SCHEMA,  /**< schema is invalid */
105497bd480fSBaptiste Daroussin 	UCL_SCHEMA_MISSING_PROPERTY,/**< one or more missing properties */
105597bd480fSBaptiste Daroussin 	UCL_SCHEMA_CONSTRAINT,      /**< constraint found */
105697bd480fSBaptiste Daroussin 	UCL_SCHEMA_MISSING_DEPENDENCY, /**< missing dependency */
105797bd480fSBaptiste Daroussin 	UCL_SCHEMA_UNKNOWN          /**< generic error */
105897bd480fSBaptiste Daroussin };
105997bd480fSBaptiste Daroussin 
106097bd480fSBaptiste Daroussin /**
106197bd480fSBaptiste Daroussin  * Generic ucl schema error
106297bd480fSBaptiste Daroussin  */
106397bd480fSBaptiste Daroussin struct ucl_schema_error {
106497bd480fSBaptiste Daroussin 	enum ucl_schema_error_code code;	/**< error code */
106597bd480fSBaptiste Daroussin 	char msg[128];						/**< error message */
1066b04a7a0bSBaptiste Daroussin 	const ucl_object_t *obj;			/**< object where error occured */
106797bd480fSBaptiste Daroussin };
106897bd480fSBaptiste Daroussin 
106997bd480fSBaptiste Daroussin /**
107097bd480fSBaptiste Daroussin  * Validate object `obj` using schema object `schema`.
107197bd480fSBaptiste Daroussin  * @param schema schema object
107297bd480fSBaptiste Daroussin  * @param obj object to validate
107397bd480fSBaptiste Daroussin  * @param err error pointer, if this parameter is not NULL and error has been
107497bd480fSBaptiste Daroussin  * occured, then `err` is filled with the exact error definition.
107597bd480fSBaptiste Daroussin  * @return true if `obj` is valid using `schema`
107697bd480fSBaptiste Daroussin  */
1077b04a7a0bSBaptiste Daroussin UCL_EXTERN bool ucl_object_validate (const ucl_object_t *schema,
1078b04a7a0bSBaptiste Daroussin 		const ucl_object_t *obj, struct ucl_schema_error *err);
107997bd480fSBaptiste Daroussin 
108097bd480fSBaptiste Daroussin /** @} */
108197bd480fSBaptiste Daroussin 
1082c99fb5f9SBaptiste Daroussin #ifdef  __cplusplus
1083c99fb5f9SBaptiste Daroussin }
1084c99fb5f9SBaptiste Daroussin #endif
1085c99fb5f9SBaptiste Daroussin /*
1086c99fb5f9SBaptiste Daroussin  * XXX: Poorly named API functions, need to replace them with the appropriate
1087c99fb5f9SBaptiste Daroussin  * named function. All API functions *must* use naming ucl_object_*. Usage of
1088c99fb5f9SBaptiste Daroussin  * ucl_obj* should be avoided.
1089c99fb5f9SBaptiste Daroussin  */
1090c99fb5f9SBaptiste Daroussin #define ucl_obj_todouble_safe ucl_object_todouble_safe
1091c99fb5f9SBaptiste Daroussin #define ucl_obj_todouble ucl_object_todouble
1092c99fb5f9SBaptiste Daroussin #define ucl_obj_tostring ucl_object_tostring
1093c99fb5f9SBaptiste Daroussin #define ucl_obj_tostring_safe ucl_object_tostring_safe
1094c99fb5f9SBaptiste Daroussin #define ucl_obj_tolstring ucl_object_tolstring
1095c99fb5f9SBaptiste Daroussin #define ucl_obj_tolstring_safe ucl_object_tolstring_safe
1096c99fb5f9SBaptiste Daroussin #define ucl_obj_toint ucl_object_toint
1097c99fb5f9SBaptiste Daroussin #define ucl_obj_toint_safe ucl_object_toint_safe
1098c99fb5f9SBaptiste Daroussin #define ucl_obj_toboolean ucl_object_toboolean
1099c99fb5f9SBaptiste Daroussin #define ucl_obj_toboolean_safe ucl_object_toboolean_safe
1100c99fb5f9SBaptiste Daroussin #define ucl_obj_get_key ucl_object_find_key
1101c99fb5f9SBaptiste Daroussin #define ucl_obj_get_keyl ucl_object_find_keyl
1102c99fb5f9SBaptiste Daroussin #define ucl_obj_unref ucl_object_unref
1103c99fb5f9SBaptiste Daroussin #define ucl_obj_ref ucl_object_ref
1104c99fb5f9SBaptiste Daroussin #define ucl_obj_free ucl_object_free
1105c99fb5f9SBaptiste Daroussin 
1106c99fb5f9SBaptiste Daroussin #endif /* UCL_H_ */
1107