xref: /freebsd/contrib/libucl/include/ucl.h (revision 5ca8e32633c4ffbbcd6762e5888b6a4ba0708c6c)
1 /* Copyright (c) 2013-2015, Vsevolod Stakhov
2  * All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *       * Redistributions of source code must retain the above copyright
7  *         notice, this list of conditions and the following disclaimer.
8  *       * Redistributions in binary form must reproduce the above copyright
9  *         notice, this list of conditions and the following disclaimer in the
10  *         documentation and/or other materials provided with the distribution.
11  *
12  * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY
13  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
14  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
15  * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY
16  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
17  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
18  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
19  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
20  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22  */
23 
24 #ifndef UCL_H_
25 #define UCL_H_
26 
27 #include <string.h>
28 #include <stddef.h>
29 #include <stdlib.h>
30 #include <stdint.h>
31 #include <stdbool.h>
32 #include <stdarg.h>
33 #include <stdio.h>
34 
35 #ifdef _WIN32
36 # define UCL_EXTERN __declspec(dllexport)
37 #else
38 # define UCL_EXTERN
39 #endif
40 
41 /**
42  * @mainpage
43  * This is a reference manual for UCL API. You may find the description of UCL format by following this
44  * [github repository](https://github.com/vstakhov/libucl).
45  *
46  * This manual has several main sections:
47  *  - @ref structures
48  *  - @ref utils
49  *  - @ref parser
50  *  - @ref emitter
51  */
52 
53 /**
54  * @file ucl.h
55  * @brief UCL parsing and emitting functions
56  *
57  * UCL is universal configuration language, which is a form of
58  * JSON with less strict rules that make it more comfortable for
59  * using as a configuration language
60  */
61 #ifdef  __cplusplus
62 extern "C" {
63 #endif
64 /*
65  * Memory allocation utilities
66  * UCL_ALLOC(size) - allocate memory for UCL
67  * UCL_FREE(size, ptr) - free memory of specified size at ptr
68  * Default: malloc and free
69  */
70 #ifndef UCL_ALLOC
71 #define UCL_ALLOC(size) malloc(size)
72 #endif
73 #ifndef UCL_FREE
74 #define UCL_FREE(size, ptr) free(ptr)
75 #endif
76 
77 #if    __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
78 #define UCL_WARN_UNUSED_RESULT               \
79   __attribute__((warn_unused_result))
80 #else
81 #define UCL_WARN_UNUSED_RESULT
82 #endif
83 
84 #ifdef __GNUC__
85 #define UCL_DEPRECATED(func) func __attribute__ ((deprecated))
86 #elif defined(_MSC_VER)
87 #define UCL_DEPRECATED(func) __declspec(deprecated) func
88 #else
89 #define UCL_DEPRECATED(func) func
90 #endif
91 
92 /**
93  * @defgroup structures Structures and types
94  * UCL defines several enumeration types used for error reporting or specifying flags and attributes.
95  *
96  * @{
97  */
98 
99 /**
100  * The common error codes returned by ucl parser
101  */
102 typedef enum ucl_error {
103 	UCL_EOK = 0, /**< No error */
104 	UCL_ESYNTAX, /**< Syntax error occurred during parsing */
105 	UCL_EIO, /**< IO error occurred during parsing */
106 	UCL_ESTATE, /**< Invalid state machine state */
107 	UCL_ENESTED, /**< Input has too many recursion levels */
108 	UCL_EUNPAIRED, /**< Input has too many recursion levels */
109 	UCL_EMACRO, /**< Error processing a macro */
110 	UCL_EINTERNAL, /**< Internal unclassified error */
111 	UCL_ESSL, /**< SSL error */
112 	UCL_EMERGE /**< A merge error occurred */
113 } ucl_error_t;
114 
115 /**
116  * #ucl_object_t may have one of specified types, some types are compatible with each other and some are not.
117  * For example, you can always convert #UCL_TIME to #UCL_FLOAT. Also you can convert #UCL_FLOAT to #UCL_INTEGER
118  * by loosing floating point. Every object may be converted to a string by #ucl_object_tostring_forced() function.
119  *
120  */
121 typedef enum ucl_type {
122 	UCL_OBJECT = 0, /**< UCL object - key/value pairs */
123 	UCL_ARRAY, /**< UCL array */
124 	UCL_INT, /**< Integer number */
125 	UCL_FLOAT, /**< Floating point number */
126 	UCL_STRING, /**< Null terminated string */
127 	UCL_BOOLEAN, /**< Boolean value */
128 	UCL_TIME, /**< Time value (floating point number of seconds) */
129 	UCL_USERDATA, /**< Opaque userdata pointer (may be used in macros) */
130 	UCL_NULL /**< Null value */
131 } ucl_type_t;
132 
133 /**
134  * You can use one of these types to serialise #ucl_object_t by using ucl_object_emit().
135  */
136 typedef enum ucl_emitter {
137 	UCL_EMIT_JSON = 0, /**< Emit fine formatted JSON */
138 	UCL_EMIT_JSON_COMPACT, /**< Emit compacted JSON */
139 	UCL_EMIT_CONFIG, /**< Emit human readable config format */
140 	UCL_EMIT_YAML, /**< Emit embedded YAML format */
141 	UCL_EMIT_MSGPACK, /**< Emit msgpack output */
142 	UCL_EMIT_MAX /**< Unsupported emitter type */
143 } ucl_emitter_t;
144 
145 /**
146  * These flags defines parser behaviour. If you specify #UCL_PARSER_ZEROCOPY you must ensure
147  * that the input memory is not freed if an object is in use. Moreover, if you want to use
148  * zero-terminated keys and string values then you should not use zero-copy mode, as in this case
149  * UCL still has to perform copying implicitly.
150  */
151 typedef enum ucl_parser_flags {
152 	UCL_PARSER_DEFAULT = 0,       /**< No special flags */
153 	UCL_PARSER_KEY_LOWERCASE = (1 << 0), /**< Convert all keys to lower case */
154 	UCL_PARSER_ZEROCOPY = (1 << 1), /**< Parse input in zero-copy mode if possible */
155 	UCL_PARSER_NO_TIME = (1 << 2), /**< Do not parse time and treat time values as strings */
156 	UCL_PARSER_NO_IMPLICIT_ARRAYS = (1 << 3), /** Create explicit arrays instead of implicit ones */
157 	UCL_PARSER_SAVE_COMMENTS = (1 << 4), /** Save comments in the parser context */
158 	UCL_PARSER_DISABLE_MACRO = (1 << 5), /** Treat macros as comments */
159 	UCL_PARSER_NO_FILEVARS = (1 << 6) /** Do not set file vars */
160 } ucl_parser_flags_t;
161 
162 /**
163  * String conversion flags, that are used in #ucl_object_fromstring_common function.
164  */
165 typedef enum ucl_string_flags {
166 	UCL_STRING_RAW = 0x0,     /**< Treat string as is */
167 	UCL_STRING_ESCAPE = (1 << 0),  /**< Perform JSON escape */
168 	UCL_STRING_TRIM = (1 << 1),    /**< Trim leading and trailing whitespaces */
169 	UCL_STRING_PARSE_BOOLEAN = (1 << 2),    /**< Parse passed string and detect boolean */
170 	UCL_STRING_PARSE_INT = (1 << 3),    /**< Parse passed string and detect integer number */
171 	UCL_STRING_PARSE_DOUBLE = (1 << 4),    /**< Parse passed string and detect integer or float number */
172 	UCL_STRING_PARSE_TIME = (1 << 5), /**< Parse time strings */
173 	UCL_STRING_PARSE_NUMBER =  UCL_STRING_PARSE_INT|UCL_STRING_PARSE_DOUBLE|UCL_STRING_PARSE_TIME,  /**<
174 									Parse passed string and detect number */
175 	UCL_STRING_PARSE =  UCL_STRING_PARSE_BOOLEAN|UCL_STRING_PARSE_NUMBER,   /**<
176 									Parse passed string (and detect booleans and numbers) */
177 	UCL_STRING_PARSE_BYTES = (1 << 6)  /**< Treat numbers as bytes */
178 } ucl_string_flags_t;
179 
180 /**
181  * Basic flags for an object (can use up to 12 bits as higher 4 bits are used
182  * for priorities)
183  */
184 typedef enum ucl_object_flags {
185 	UCL_OBJECT_ALLOCATED_KEY = (1 << 0), /**< An object has key allocated internally */
186 	UCL_OBJECT_ALLOCATED_VALUE = (1 << 1), /**< An object has a string value allocated internally */
187 	UCL_OBJECT_NEED_KEY_ESCAPE = (1 << 2), /**< The key of an object need to be escaped on output */
188 	UCL_OBJECT_EPHEMERAL = (1 << 3), /**< Temporary object that does not need to be freed really */
189 	UCL_OBJECT_MULTILINE = (1 << 4), /**< String should be displayed as multiline string */
190 	UCL_OBJECT_MULTIVALUE = (1 << 5), /**< Object is a key with multiple values */
191 	UCL_OBJECT_INHERITED = (1 << 6), /**< Object has been inherited from another */
192 	UCL_OBJECT_BINARY = (1 << 7), /**< Object contains raw binary data */
193 	UCL_OBJECT_SQUOTED = (1 << 8) /**< Object has been enclosed in single quotes */
194 } ucl_object_flags_t;
195 
196 /**
197  * Duplicate policy types
198  */
199 enum ucl_duplicate_strategy {
200 	UCL_DUPLICATE_APPEND = 0, /**< Default policy to merge based on priorities */
201 	UCL_DUPLICATE_MERGE,     /**< Merge new object with old one */
202 	UCL_DUPLICATE_REWRITE,   /**< Rewrite old keys */
203 	UCL_DUPLICATE_ERROR      /**< Stop parsing on duplicate found */
204 };
205 
206 /**
207  * Input format type
208  */
209 enum ucl_parse_type {
210 	UCL_PARSE_UCL = 0, /**< Default ucl format */
211 	UCL_PARSE_MSGPACK, /**< Message pack input format */
212 	UCL_PARSE_CSEXP, /**< Canonical S-expressions */
213 	UCL_PARSE_AUTO /**< Try to detect parse type */
214 };
215 
216 /**
217  * UCL object structure. Please mention that the most of fields should not be touched by
218  * UCL users. In future, this structure may be converted to private one.
219  */
220 typedef struct ucl_object_s {
221 	/**
222 	 * Variant value type
223 	 */
224 	union {
225 		int64_t iv;							/**< Int value of an object */
226 		const char *sv;						/**< String value of an object */
227 		double dv;							/**< Double value of an object */
228 		void *av;							/**< Array					*/
229 		void *ov;							/**< Object					*/
230 		void* ud;							/**< Opaque user data		*/
231 	} value;
232 	const char *key;						/**< Key of an object		*/
233 	struct ucl_object_s *next;				/**< Array handle			*/
234 	struct ucl_object_s *prev;				/**< Array handle			*/
235 	uint32_t keylen;						/**< Length of a key		*/
236 	uint32_t len;							/**< Size of an object		*/
237 	uint32_t ref;							/**< Reference count		*/
238 	uint16_t flags;							/**< Object flags			*/
239 	uint16_t type;							/**< Real type				*/
240 	unsigned char* trash_stack[2];			/**< Pointer to allocated chunks */
241 } ucl_object_t;
242 
243 /**
244  * Destructor type for userdata objects
245  * @param ud user specified data pointer
246  */
247 typedef void (*ucl_userdata_dtor)(void *ud);
248 typedef const char* (*ucl_userdata_emitter)(void *ud);
249 
250 /** @} */
251 
252 /**
253  * @defgroup utils Utility functions
254  * A number of utility functions simplify handling of UCL objects
255  *
256  * @{
257  */
258 /**
259  * Copy and return a key of an object, returned key is zero-terminated
260  * @param obj CL object
261  * @return zero terminated key
262  */
263 UCL_EXTERN char* ucl_copy_key_trash (const ucl_object_t *obj);
264 
265 /**
266  * Copy and return a string value of an object, returned key is zero-terminated
267  * @param obj CL object
268  * @return zero terminated string representation of object value
269  */
270 UCL_EXTERN char* ucl_copy_value_trash (const ucl_object_t *obj);
271 
272 /**
273  * Creates a new object
274  * @return new object
275  */
276 UCL_EXTERN ucl_object_t* ucl_object_new (void) UCL_WARN_UNUSED_RESULT;
277 
278 /**
279  * Create new object with type specified
280  * @param type type of a new object
281  * @return new object
282  */
283 UCL_EXTERN ucl_object_t* ucl_object_typed_new (ucl_type_t type) UCL_WARN_UNUSED_RESULT;
284 
285 /**
286  * Create new object with type and priority specified
287  * @param type type of a new object
288  * @param priority priority of an object
289  * @return new object
290  */
291 UCL_EXTERN ucl_object_t* ucl_object_new_full (ucl_type_t type, unsigned priority)
292 	UCL_WARN_UNUSED_RESULT;
293 
294 /**
295  * Create new object with userdata dtor
296  * @param dtor destructor function
297  * @param emitter emitter for userdata
298  * @param ptr opaque pointer
299  * @return new object
300  */
301 UCL_EXTERN ucl_object_t* ucl_object_new_userdata (ucl_userdata_dtor dtor,
302 		ucl_userdata_emitter emitter, void *ptr) UCL_WARN_UNUSED_RESULT;
303 
304 /**
305  * Perform deep copy of an object copying everything
306  * @param other object to copy
307  * @return new object with refcount equal to 1
308  */
309 UCL_EXTERN ucl_object_t * ucl_object_copy (const ucl_object_t *other)
310 	UCL_WARN_UNUSED_RESULT;
311 
312 /**
313  * Return the type of an object
314  * @return the object type
315  */
316 UCL_EXTERN ucl_type_t ucl_object_type (const ucl_object_t *obj);
317 
318 /**
319  * Converts ucl object type to its string representation
320  * @param type type of object
321  * @return constant string describing type
322  */
323 UCL_EXTERN const char * ucl_object_type_to_string (ucl_type_t type);
324 
325 /**
326  * Converts string that represents ucl type to real ucl type enum
327  * @param input C string with name of type
328  * @param res resulting target
329  * @return true if `input` is a name of type stored in `res`
330  */
331 UCL_EXTERN bool ucl_object_string_to_type (const char *input, ucl_type_t *res);
332 
333 /**
334  * Convert any string to an ucl object making the specified transformations
335  * @param str fixed size or NULL terminated string
336  * @param len length (if len is zero, than str is treated as NULL terminated)
337  * @param flags conversion flags
338  * @return new object
339  */
340 UCL_EXTERN ucl_object_t * ucl_object_fromstring_common (const char *str, size_t len,
341 		enum ucl_string_flags flags) UCL_WARN_UNUSED_RESULT;
342 
343 /**
344  * Create a UCL object from the specified string
345  * @param str NULL terminated string, will be json escaped
346  * @return new object
347  */
348 UCL_EXTERN ucl_object_t *ucl_object_fromstring (const char *str) UCL_WARN_UNUSED_RESULT;
349 
350 /**
351  * Create a UCL object from the specified string
352  * @param str fixed size string, will be json escaped
353  * @param len length of a string
354  * @return new object
355  */
356 UCL_EXTERN ucl_object_t *ucl_object_fromlstring (const char *str,
357 		size_t len) UCL_WARN_UNUSED_RESULT;
358 
359 /**
360  * Create an object from an integer number
361  * @param iv number
362  * @return new object
363  */
364 UCL_EXTERN ucl_object_t* ucl_object_fromint (int64_t iv) UCL_WARN_UNUSED_RESULT;
365 
366 /**
367  * Create an object from a float number
368  * @param dv number
369  * @return new object
370  */
371 UCL_EXTERN ucl_object_t* ucl_object_fromdouble (double dv) UCL_WARN_UNUSED_RESULT;
372 
373 /**
374  * Create an object from a boolean
375  * @param bv bool value
376  * @return new object
377  */
378 UCL_EXTERN ucl_object_t* ucl_object_frombool (bool bv) UCL_WARN_UNUSED_RESULT;
379 
380 /**
381  * Insert a object 'elt' to the hash 'top' and associate it with key 'key'
382  * @param top destination object (must be of type UCL_OBJECT)
383  * @param elt element to insert (must NOT be NULL)
384  * @param key key to associate with this object (either const or preallocated)
385  * @param keylen length of the key (or 0 for NULL terminated keys)
386  * @param copy_key make an internal copy of key
387  * @return true if key has been inserted
388  */
389 UCL_EXTERN bool ucl_object_insert_key (ucl_object_t *top, ucl_object_t *elt,
390 		const char *key, size_t keylen, bool copy_key);
391 
392 /**
393  * Replace a object 'elt' to the hash 'top' and associate it with key 'key', old object will be unrefed,
394  * if no object has been found this function works like ucl_object_insert_key()
395  * @param top destination object (must be of type UCL_OBJECT)
396  * @param elt element to insert (must NOT be NULL)
397  * @param key key to associate with this object (either const or preallocated)
398  * @param keylen length of the key (or 0 for NULL terminated keys)
399  * @param copy_key make an internal copy of key
400  * @return true if key has been inserted
401  */
402 UCL_EXTERN bool ucl_object_replace_key (ucl_object_t *top, ucl_object_t *elt,
403 		const char *key, size_t keylen, bool copy_key);
404 
405 /**
406  * Merge the keys from one object to another object. Overwrite on conflict
407  * @param top destination object (must be of type UCL_OBJECT)
408  * @param elt element to insert (must be of type UCL_OBJECT)
409  * @param copy copy rather than reference the elements
410  * @return true if all keys have been merged
411  */
412 UCL_EXTERN bool ucl_object_merge (ucl_object_t *top, ucl_object_t *elt, bool copy);
413 
414 /**
415  * Delete a object associated with key 'key', old object will be unrefered,
416  * @param top object
417  * @param key key associated to the object to remove
418  * @param keylen length of the key (or 0 for NULL terminated keys)
419  */
420 UCL_EXTERN bool ucl_object_delete_keyl (ucl_object_t *top,
421 		const char *key, size_t keylen);
422 
423 /**
424  * Delete a object associated with key 'key', old object will be unrefered,
425  * @param top object
426  * @param key key associated to the object to remove
427  */
428 UCL_EXTERN bool ucl_object_delete_key (ucl_object_t *top,
429 		const char *key);
430 
431 
432 /**
433  * Removes `key` from `top` object, returning the object that was removed. This
434  * object is not released, caller must unref the returned object when it is no
435  * longer needed.
436  * @param top object
437  * @param key key to remove
438  * @param keylen length of the key (or 0 for NULL terminated keys)
439  * @return removed object or NULL if object has not been found
440  */
441 UCL_EXTERN ucl_object_t* ucl_object_pop_keyl (ucl_object_t *top, const char *key,
442 		size_t keylen) UCL_WARN_UNUSED_RESULT;
443 
444 /**
445  * Removes `key` from `top` object returning the object that was removed. This
446  * object is not released, caller must unref the returned object when it is no
447  * longer needed.
448  * @param top object
449  * @param key key to remove
450  * @return removed object or NULL if object has not been found
451  */
452 UCL_EXTERN ucl_object_t* ucl_object_pop_key (ucl_object_t *top, const char *key)
453 	UCL_WARN_UNUSED_RESULT;
454 
455 /**
456  * Insert a object 'elt' to the hash 'top' and associate it with key 'key', if
457  * the specified key exist, try to merge its content
458  * @param top destination object (must be of type UCL_OBJECT)
459  * @param elt element to insert (must NOT be NULL)
460  * @param key key to associate with this object (either const or preallocated)
461  * @param keylen length of the key (or 0 for NULL terminated keys)
462  * @param copy_key make an internal copy of key
463  * @return true if key has been inserted
464  */
465 UCL_EXTERN bool ucl_object_insert_key_merged (ucl_object_t *top, ucl_object_t *elt,
466 		const char *key, size_t keylen, bool copy_key);
467 
468 /**
469  * Reserve space in ucl array or object for `elt` elements
470  * @param obj object to reserve
471  * @param reserved size to reserve in an object
472  * @return 0 on success, -1 on failure (i.e. ENOMEM)
473  */
474 UCL_EXTERN bool ucl_object_reserve (ucl_object_t *obj, size_t reserved);
475 
476 /**
477  * Append an element to the end of array object
478  * @param top destination object (must NOT be NULL)
479  * @param elt element to append (must NOT be NULL)
480  * @return true if value has been inserted
481  */
482 UCL_EXTERN bool ucl_array_append (ucl_object_t *top,
483 		ucl_object_t *elt);
484 
485 /**
486  * Append an element to the start of array object
487  * @param top destination object (must NOT be NULL)
488  * @param elt element to append (must NOT be NULL)
489  * @return true if value has been inserted
490  */
491 UCL_EXTERN bool ucl_array_prepend (ucl_object_t *top,
492 		ucl_object_t *elt);
493 
494 /**
495  * Merge all elements of second array into the first array
496  * @param top destination array (must be of type UCL_ARRAY)
497  * @param elt array to copy elements from (must be of type UCL_ARRAY)
498  * @param copy copy elements instead of referencing them
499  * @return true if arrays were merged
500  */
501 UCL_EXTERN bool ucl_array_merge (ucl_object_t *top, ucl_object_t *elt,
502 		bool copy);
503 
504 /**
505  * Removes an element `elt` from the array `top`, returning the object that was
506  * removed. This object is not released, caller must unref the returned object
507  * when it is no longer needed.
508  * @param top array ucl object
509  * @param elt element to remove
510  * @return removed element or NULL if `top` is NULL or not an array
511  */
512 UCL_EXTERN ucl_object_t* ucl_array_delete (ucl_object_t *top,
513 		ucl_object_t *elt);
514 
515 /**
516  * Returns the first element of the array `top`
517  * @param top array ucl object
518  * @return element or NULL if `top` is NULL or not an array
519  */
520 UCL_EXTERN const ucl_object_t* ucl_array_head (const ucl_object_t *top);
521 
522 /**
523  * Returns the last element of the array `top`
524  * @param top array ucl object
525  * @return element or NULL if `top` is NULL or not an array
526  */
527 UCL_EXTERN const ucl_object_t* ucl_array_tail (const ucl_object_t *top);
528 
529 /**
530  * Removes the last element from the array `top`, returning the object that was
531  * removed. This object is not released, caller must unref the returned object
532  * when it is no longer needed.
533  * @param top array ucl object
534  * @return removed element or NULL if `top` is NULL or not an array
535  */
536 UCL_EXTERN ucl_object_t* ucl_array_pop_last (ucl_object_t *top);
537 
538 /**
539  * Removes the first element from the array `top`, returning the object that was
540  * removed. This object is not released, caller must unref the returned object
541  * when it is no longer needed.
542  * @param top array ucl object
543  * @return removed element or NULL if `top` is NULL or not an array
544  */
545 UCL_EXTERN ucl_object_t* ucl_array_pop_first (ucl_object_t *top);
546 
547 /**
548  * Return size of the array `top`
549  * @param top object to get size from (must be of type UCL_ARRAY)
550  * @return size of the array
551  */
552 UCL_EXTERN unsigned int ucl_array_size (const ucl_object_t *top);
553 
554 /**
555  * Return object identified by index of the array `top`
556  * @param top object to get a key from (must be of type UCL_ARRAY)
557  * @param index array index to return
558  * @return object at the specified index or NULL if index is not found
559  */
560 UCL_EXTERN const ucl_object_t* ucl_array_find_index (const ucl_object_t *top,
561 		unsigned int index);
562 
563 /**
564  * Return the index of `elt` in the array `top`
565  * @param top object to get a key from (must be of type UCL_ARRAY)
566  * @param elt element to find index of (must NOT be NULL)
567  * @return index of `elt` in the array `top or (unsigned int)-1 if `elt` is not found
568  */
569 UCL_EXTERN unsigned int ucl_array_index_of (ucl_object_t *top,
570 		ucl_object_t *elt);
571 
572 /**
573  * Replace an element in an array with a different element, returning the object
574  * that was replaced. This object is not released, caller must unref the
575  * returned object when it is no longer needed.
576  * @param top destination object (must be of type UCL_ARRAY)
577  * @param elt element to append (must NOT be NULL)
578  * @param index array index in destination to overwrite with elt
579  * @return object that was replaced or NULL if index is not found
580  */
581 ucl_object_t *
582 ucl_array_replace_index (ucl_object_t *top, ucl_object_t *elt,
583 	unsigned int index);
584 
585 /**
586  * Append a element to another element forming an implicit array
587  * @param head head to append (may be NULL)
588  * @param elt new element
589  * @return the new implicit array
590  */
591 UCL_EXTERN ucl_object_t * ucl_elt_append (ucl_object_t *head,
592 		ucl_object_t *elt);
593 
594 /**
595  * Converts an object to double value
596  * @param obj CL object
597  * @param target target double variable
598  * @return true if conversion was successful
599  */
600 UCL_EXTERN bool ucl_object_todouble_safe (const ucl_object_t *obj, double *target);
601 
602 /**
603  * Unsafe version of \ref ucl_obj_todouble_safe
604  * @param obj CL object
605  * @return double value
606  */
607 UCL_EXTERN double ucl_object_todouble (const ucl_object_t *obj);
608 
609 /**
610  * Converts an object to integer value
611  * @param obj CL object
612  * @param target target integer variable
613  * @return true if conversion was successful
614  */
615 UCL_EXTERN bool ucl_object_toint_safe (const ucl_object_t *obj, int64_t *target);
616 
617 /**
618  * Unsafe version of \ref ucl_obj_toint_safe
619  * @param obj CL object
620  * @return int value
621  */
622 UCL_EXTERN int64_t ucl_object_toint (const ucl_object_t *obj);
623 
624 /**
625  * Converts an object to boolean value
626  * @param obj CL object
627  * @param target target boolean variable
628  * @return true if conversion was successful
629  */
630 UCL_EXTERN bool ucl_object_toboolean_safe (const ucl_object_t *obj, bool *target);
631 
632 /**
633  * Unsafe version of \ref ucl_obj_toboolean_safe
634  * @param obj CL object
635  * @return boolean value
636  */
637 UCL_EXTERN bool ucl_object_toboolean (const ucl_object_t *obj);
638 
639 /**
640  * Converts an object to string value
641  * @param obj CL object
642  * @param target target string variable, no need to free value
643  * @return true if conversion was successful
644  */
645 UCL_EXTERN bool ucl_object_tostring_safe (const ucl_object_t *obj, const char **target);
646 
647 /**
648  * Unsafe version of \ref ucl_obj_tostring_safe
649  * @param obj CL object
650  * @return string value
651  */
652 UCL_EXTERN const char* ucl_object_tostring (const ucl_object_t *obj);
653 
654 /**
655  * Convert any object to a string in JSON notation if needed
656  * @param obj CL object
657  * @return string value
658  */
659 UCL_EXTERN const char* ucl_object_tostring_forced (const ucl_object_t *obj);
660 
661 /**
662  * Return string as char * and len, string may be not zero terminated, more efficient that \ref ucl_obj_tostring as it
663  * allows zero-copy (if #UCL_PARSER_ZEROCOPY has been used during parsing)
664  * @param obj CL object
665  * @param target target string variable, no need to free value
666  * @param tlen target length
667  * @return true if conversion was successful
668  */
669 UCL_EXTERN bool ucl_object_tolstring_safe (const ucl_object_t *obj,
670 		const char **target, size_t *tlen);
671 
672 /**
673  * Unsafe version of \ref ucl_obj_tolstring_safe
674  * @param obj CL object
675  * @return string value
676  */
677 UCL_EXTERN const char* ucl_object_tolstring (const ucl_object_t *obj, size_t *tlen);
678 
679 /**
680  * Return object identified by a key in the specified object
681  * @param obj object to get a key from (must be of type UCL_OBJECT)
682  * @param key key to search
683  * @return object matching the specified key or NULL if key was not found
684  */
685 UCL_EXTERN const ucl_object_t* ucl_object_lookup (const ucl_object_t *obj,
686 		const char *key);
687 #define ucl_object_find_key ucl_object_lookup
688 
689 /**
690  * Return object identified by a key in the specified object, if the first key is
691  * not found then look for the next one. This process is repeated unless
692  * the next argument in the list is not NULL. So, `ucl_object_find_any_key(obj, key, NULL)`
693  * is equal to `ucl_object_find_key(obj, key)`
694  * @param obj object to get a key from (must be of type UCL_OBJECT)
695  * @param key key to search
696  * @param ... list of alternative keys to search (NULL terminated)
697  * @return object matching the specified key or NULL if key was not found
698  */
699 UCL_EXTERN const ucl_object_t* ucl_object_lookup_any (const ucl_object_t *obj,
700 		const char *key, ...);
701 #define ucl_object_find_any_key ucl_object_lookup_any
702 
703 /**
704  * Return object identified by a fixed size key in the specified object
705  * @param obj object to get a key from (must be of type UCL_OBJECT)
706  * @param key key to search
707  * @param klen length of a key
708  * @return object matching the specified key or NULL if key was not found
709  */
710 UCL_EXTERN const ucl_object_t* ucl_object_lookup_len (const ucl_object_t *obj,
711 		const char *key, size_t klen);
712 #define ucl_object_find_keyl ucl_object_lookup_len
713 
714 /**
715  * Return object identified by dot notation string
716  * @param obj object to search in
717  * @param path dot.notation.path to the path to lookup. May use numeric .index on arrays
718  * @return object matched the specified path or NULL if path is not found
719  */
720 UCL_EXTERN const ucl_object_t *ucl_object_lookup_path (const ucl_object_t *obj,
721 		const char *path);
722 #define ucl_lookup_path ucl_object_lookup_path
723 
724 /**
725  * Return object identified by object notation string using arbitrary delimiter
726  * @param obj object to search in
727  * @param path dot.notation.path to the path to lookup. May use numeric .index on arrays
728  * @param sep the sepatorator to use in place of . (incase keys have . in them)
729  * @return object matched the specified path or NULL if path is not found
730  */
731 UCL_EXTERN const ucl_object_t *ucl_object_lookup_path_char (const ucl_object_t *obj,
732 		const char *path, char sep);
733 #define ucl_lookup_path_char ucl_object_lookup_path_char
734 
735 /**
736  * Returns a key of an object as a NULL terminated string
737  * @param obj CL object
738  * @return key or NULL if there is no key
739  */
740 UCL_EXTERN const char* ucl_object_key (const ucl_object_t *obj);
741 
742 /**
743  * Returns a key of an object as a fixed size string (may be more efficient)
744  * @param obj CL object
745  * @param len target key length
746  * @return key pointer
747  */
748 UCL_EXTERN const char* ucl_object_keyl (const ucl_object_t *obj, size_t *len);
749 
750 /**
751  * Increase reference count for an object
752  * @param obj object to ref
753  * @return the referenced object
754  */
755 UCL_EXTERN ucl_object_t* ucl_object_ref (const ucl_object_t *obj);
756 
757 /**
758  * Free ucl object
759  * @param obj ucl object to free
760  */
761 UCL_DEPRECATED(UCL_EXTERN void ucl_object_free (ucl_object_t *obj));
762 
763 /**
764  * Decrease reference count for an object
765  * @param obj object to unref
766  */
767 UCL_EXTERN void ucl_object_unref (ucl_object_t *obj);
768 
769 /**
770  * Compare objects `o1` and `o2`
771  * @param o1 the first object
772  * @param o2 the second object
773  * @return values >0, 0 and <0 if `o1` is more than, equal and less than `o2`.
774  * The order of comparison:
775  * 1) Type of objects
776  * 2) Size of objects
777  * 3) Content of objects
778  */
779 UCL_EXTERN int ucl_object_compare (const ucl_object_t *o1,
780 		const ucl_object_t *o2);
781 
782 /**
783  * Compare objects `o1` and `o2` useful for sorting
784  * @param o1 the first object
785  * @param o2 the second object
786  * @return values >0, 0 and <0 if `o1` is more than, equal and less than `o2`.
787  * The order of comparison:
788  * 1) Type of objects
789  * 2) Size of objects
790  * 3) Content of objects
791  */
792 UCL_EXTERN int ucl_object_compare_qsort (const ucl_object_t **o1,
793 		const ucl_object_t **o2);
794 
795 /**
796  * Sort UCL array using `cmp` compare function
797  * @param ar
798  * @param cmp
799  */
800 UCL_EXTERN void ucl_object_array_sort (ucl_object_t *ar,
801 		int (*cmp)(const ucl_object_t **o1, const ucl_object_t **o2));
802 
803 enum ucl_object_keys_sort_flags {
804 	UCL_SORT_KEYS_DEFAULT = 0,
805 	UCL_SORT_KEYS_ICASE = (1u << 0u),
806 	UCL_SORT_KEYS_RECURSIVE = (1u << 1u),
807 };
808 /***
809  * Sorts keys in object in place
810  * @param obj
811  * @param how
812  */
813 UCL_EXTERN void ucl_object_sort_keys (ucl_object_t *obj,
814 		enum ucl_object_keys_sort_flags how);
815 
816 /**
817  * Get the priority for specific UCL object
818  * @param obj any ucl object
819  * @return priority of an object
820  */
821 UCL_EXTERN unsigned int ucl_object_get_priority (const ucl_object_t *obj);
822 
823 /**
824  * Set explicit priority of an object.
825  * @param obj any ucl object
826  * @param priority new priroity value (only 4 least significant bits are considred)
827  */
828 UCL_EXTERN void ucl_object_set_priority (ucl_object_t *obj,
829 		unsigned int priority);
830 
831 /**
832  * Opaque iterator object
833  */
834 typedef void* ucl_object_iter_t;
835 
836 /**
837  * Get next key from an object
838  * @param obj object to iterate
839  * @param iter opaque iterator, must be set to NULL on the first call:
840  * ucl_object_iter_t it = NULL;
841  * while ((cur = ucl_iterate_object (obj, &it)) != NULL) ...
842  * @param ep pointer record exception (such as ENOMEM), could be NULL
843  * @return the next object or NULL
844  */
845 UCL_EXTERN const ucl_object_t* ucl_object_iterate_with_error (const ucl_object_t *obj,
846 		ucl_object_iter_t *iter, bool expand_values, int *ep);
847 
848 #define ucl_iterate_object ucl_object_iterate
849 #define ucl_object_iterate(ob, it, ev) ucl_object_iterate_with_error((ob), (it), (ev), NULL)
850 
851 /**
852  * Create new safe iterator for the specified object
853  * @param obj object to iterate
854  * @return new iterator object that should be used with safe iterators API only
855  */
856 UCL_EXTERN ucl_object_iter_t ucl_object_iterate_new (const ucl_object_t *obj)
857 	UCL_WARN_UNUSED_RESULT;
858 /**
859  * Check safe iterator object after performing some operations on it
860  * (such as ucl_object_iterate_safe()) to see if operation has encountered
861  * fatal exception while performing that operation (e.g. ENOMEM).
862  * @param iter opaque iterator
863  * @return true if exception has occured, false otherwise
864  */
865 UCL_EXTERN bool ucl_object_iter_chk_excpn(ucl_object_iter_t *it);
866 
867 /**
868  * Reset initialized iterator to a new object
869  * @param obj new object to iterate
870  * @return modified iterator object
871  */
872 UCL_EXTERN ucl_object_iter_t ucl_object_iterate_reset (ucl_object_iter_t it,
873 		const ucl_object_t *obj);
874 
875 /**
876  * Get the next object from the `obj`. This function iterates over arrays, objects
877  * and implicit arrays
878  * @param iter safe iterator
879  * @param expand_values expand explicit arrays and objects
880  * @return the next object in sequence
881  */
882 UCL_EXTERN const ucl_object_t* ucl_object_iterate_safe (ucl_object_iter_t iter,
883 		bool expand_values);
884 /**
885  * Iteration type enumerator
886  */
887 enum ucl_iterate_type {
888 	UCL_ITERATE_EXPLICIT = 1 << 0, /**< Iterate just explicit arrays and objects */
889 	UCL_ITERATE_IMPLICIT = 1 << 1,  /**< Iterate just implicit arrays */
890 	UCL_ITERATE_BOTH = (1 << 0) | (1 << 1),   /**< Iterate both explicit and implicit arrays*/
891 };
892 
893 /**
894  * Get the next object from the `obj`. This function iterates over arrays, objects
895  * and implicit arrays if needed
896  * @param iter safe iterator
897  * @param
898  * @return the next object in sequence
899  */
900 UCL_EXTERN const ucl_object_t* ucl_object_iterate_full (ucl_object_iter_t iter,
901 		enum ucl_iterate_type type);
902 
903 /**
904  * Free memory associated with the safe iterator
905  * @param it safe iterator object
906  */
907 UCL_EXTERN void ucl_object_iterate_free (ucl_object_iter_t it);
908 
909 /** @} */
910 
911 
912 /**
913  * @defgroup parser Parsing functions
914  * These functions are used to parse UCL objects
915  *
916  * @{
917  */
918 
919 /**
920  * Macro handler for a parser
921  * @param data the content of macro
922  * @param len the length of content
923  * @param arguments arguments object
924  * @param ud opaque user data
925  * @param err error pointer
926  * @return true if macro has been parsed
927  */
928 typedef bool (*ucl_macro_handler) (const unsigned char *data, size_t len,
929 		const ucl_object_t *arguments,
930 		void* ud);
931 
932 /**
933  * Context dependent macro handler for a parser
934  * @param data the content of macro
935  * @param len the length of content
936  * @param arguments arguments object
937  * @param context previously parsed context
938  * @param ud opaque user data
939  * @param err error pointer
940  * @return true if macro has been parsed
941  */
942 typedef bool (*ucl_context_macro_handler) (const unsigned char *data, size_t len,
943 		const ucl_object_t *arguments,
944 		const ucl_object_t *context,
945 		void* ud);
946 
947 /* Opaque parser */
948 struct ucl_parser;
949 
950 /**
951  * Creates new parser object
952  * @param pool pool to allocate memory from
953  * @return new parser object
954  */
955 UCL_EXTERN struct ucl_parser* ucl_parser_new (int flags);
956 
957 /**
958  * Sets the default priority for the parser applied to chunks that do not
959  * specify priority explicitly
960  * @param parser parser object
961  * @param prio default priority (0 .. 16)
962  * @return true if parser's default priority was set
963  */
964 UCL_EXTERN bool ucl_parser_set_default_priority (struct ucl_parser *parser,
965 		unsigned prio);
966 /**
967  * Gets the default priority for the parser applied to chunks that do not
968  * specify priority explicitly
969  * @param parser parser object
970  * @return true default priority (0 .. 16), -1 for failure
971  */
972 UCL_EXTERN int ucl_parser_get_default_priority (struct ucl_parser *parser);
973 
974 /**
975  * Register new handler for a macro
976  * @param parser parser object
977  * @param macro macro name (without leading dot)
978  * @param handler handler (it is called immediately after macro is parsed)
979  * @param ud opaque user data for a handler
980  * @return true on success, false on failure (i.e. ENOMEM)
981  */
982 UCL_EXTERN bool ucl_parser_register_macro (struct ucl_parser *parser,
983 		const char *macro,
984 		ucl_macro_handler handler, void* ud);
985 
986 /**
987  * Register new context dependent handler for a macro
988  * @param parser parser object
989  * @param macro macro name (without leading dot)
990  * @param handler handler (it is called immediately after macro is parsed)
991  * @param ud opaque user data for a handler
992  * @return true on success, false on failure (i.e. ENOMEM)
993  */
994 UCL_EXTERN bool ucl_parser_register_context_macro (struct ucl_parser *parser,
995 		const char *macro,
996 		ucl_context_macro_handler handler,
997 		void* ud);
998 
999 /**
1000  * Handler to detect unregistered variables
1001  * @param data variable data
1002  * @param len length of variable
1003  * @param replace (out) replace value for variable
1004  * @param replace_len (out) replace length for variable
1005  * @param need_free (out) UCL will free `dest` after usage
1006  * @param ud opaque userdata
1007  * @return true if variable
1008  */
1009 typedef bool (*ucl_variable_handler) (const unsigned char *data, size_t len,
1010 		unsigned char **replace, size_t *replace_len, bool *need_free, void* ud);
1011 
1012 /**
1013  * Register new parser variable
1014  * @param parser parser object
1015  * @param var variable name
1016  * @param value variable value
1017  */
1018 UCL_EXTERN void ucl_parser_register_variable (struct ucl_parser *parser, const char *var,
1019 		const char *value);
1020 
1021 /**
1022  * Set handler for unknown variables
1023  * @param parser parser structure
1024  * @param handler desired handler
1025  * @param ud opaque data for the handler
1026  */
1027 UCL_EXTERN void ucl_parser_set_variables_handler (struct ucl_parser *parser,
1028 		ucl_variable_handler handler, void *ud);
1029 
1030 /**
1031  * Load new chunk to a parser
1032  * @param parser parser structure
1033  * @param data the pointer to the beginning of a chunk
1034  * @param len the length of a chunk
1035  * @return true if chunk has been added and false in case of error
1036  */
1037 UCL_EXTERN bool ucl_parser_add_chunk (struct ucl_parser *parser,
1038 		const unsigned char *data, size_t len);
1039 
1040 /**
1041  * Load new chunk to a parser with the specified priority
1042  * @param parser parser structure
1043  * @param data the pointer to the beginning of a chunk
1044  * @param len the length of a chunk
1045  * @param priority the desired priority of a chunk (only 4 least significant bits
1046  * are considered for this parameter)
1047  * @return true if chunk has been added and false in case of error
1048  */
1049 UCL_EXTERN bool ucl_parser_add_chunk_priority (struct ucl_parser *parser,
1050 		const unsigned char *data, size_t len, unsigned priority);
1051 
1052 /**
1053  * Insert new chunk to a parser (must have previously processed data with an existing top object)
1054  * @param parser parser structure
1055  * @param data the pointer to the beginning of a chunk
1056  * @param len the length of a chunk
1057  * @return true if chunk has been added and false in case of error
1058  */
1059 UCL_EXTERN bool ucl_parser_insert_chunk (struct ucl_parser *parser,
1060 		const unsigned char *data, size_t len);
1061 
1062 /**
1063  * Full version of ucl_add_chunk with priority and duplicate strategy
1064  * @param parser parser structure
1065  * @param data the pointer to the beginning of a chunk
1066  * @param len the length of a chunk
1067  * @param priority the desired priority of a chunk (only 4 least significant bits
1068  * are considered for this parameter)
1069  * @param strat duplicates merging strategy
1070  * @param parse_type input format
1071  * @return true if chunk has been added and false in case of error
1072  */
1073 UCL_EXTERN bool ucl_parser_add_chunk_full (struct ucl_parser *parser,
1074 		const unsigned char *data, size_t len, unsigned priority,
1075 		enum ucl_duplicate_strategy strat, enum ucl_parse_type parse_type);
1076 
1077 /**
1078  * Load ucl object from a string
1079  * @param parser parser structure
1080  * @param data the pointer to the string
1081  * @param len the length of the string, if `len` is 0 then `data` must be zero-terminated string
1082  * @return true if string has been added and false in case of error
1083  */
1084 UCL_EXTERN bool ucl_parser_add_string (struct ucl_parser *parser,
1085 		const char *data, size_t len);
1086 
1087 /**
1088  * Load ucl object from a string
1089  * @param parser parser structure
1090  * @param data the pointer to the string
1091  * @param len the length of the string, if `len` is 0 then `data` must be zero-terminated string
1092  * @param priority the desired priority of a chunk (only 4 least significant bits
1093  * are considered for this parameter)
1094  * @return true if string has been added and false in case of error
1095  */
1096 UCL_EXTERN bool ucl_parser_add_string_priority (struct ucl_parser *parser,
1097 		const char *data, size_t len, unsigned priority);
1098 
1099 /**
1100  * Load and add data from a file
1101  * @param parser parser structure
1102  * @param filename the name of file
1103  * @param err if *err is NULL it is set to parser error
1104  * @return true if chunk has been added and false in case of error
1105  */
1106 UCL_EXTERN bool ucl_parser_add_file (struct ucl_parser *parser,
1107 		const char *filename);
1108 
1109 /**
1110  * Load and add data from a file
1111  * @param parser parser structure
1112  * @param filename the name of file
1113  * @param err if *err is NULL it is set to parser error
1114  * @param priority the desired priority of a chunk (only 4 least significant bits
1115  * are considered for this parameter)
1116  * @return true if chunk has been added and false in case of error
1117  */
1118 UCL_EXTERN bool ucl_parser_add_file_priority (struct ucl_parser *parser,
1119 		const char *filename, unsigned priority);
1120 
1121 /**
1122  * Load and add data from a file
1123  * @param parser parser structure
1124  * @param filename the name of file
1125  * @param priority the desired priority of a chunk (only 4 least significant bits
1126  * are considered for this parameter)
1127  * @param strat Merge strategy to use while parsing this file
1128  * @param parse_type Parser type to use while parsing this file
1129  * @return true if chunk has been added and false in case of error
1130  */
1131 UCL_EXTERN bool ucl_parser_add_file_full (struct ucl_parser *parser, const char *filename,
1132 		unsigned priority, enum ucl_duplicate_strategy strat,
1133 		enum ucl_parse_type parse_type);
1134 
1135 /**
1136  * Load and add data from a file descriptor
1137  * @param parser parser structure
1138  * @param filename the name of file
1139  * @param err if *err is NULL it is set to parser error
1140  * @return true if chunk has been added and false in case of error
1141  */
1142 UCL_EXTERN bool ucl_parser_add_fd (struct ucl_parser *parser,
1143 		int fd);
1144 
1145 /**
1146  * Load and add data from a file descriptor
1147  * @param parser parser structure
1148  * @param filename the name of file
1149  * @param err if *err is NULL it is set to parser error
1150  * @param priority the desired priority of a chunk (only 4 least significant bits
1151  * are considered for this parameter)
1152  * @return true if chunk has been added and false in case of error
1153  */
1154 UCL_EXTERN bool ucl_parser_add_fd_priority (struct ucl_parser *parser,
1155 		int fd, unsigned priority);
1156 
1157 /**
1158  * Load and add data from a file descriptor
1159  * @param parser parser structure
1160  * @param filename the name of file
1161  * @param err if *err is NULL it is set to parser error
1162  * @param priority the desired priority of a chunk (only 4 least significant bits
1163  * are considered for this parameter)
1164  * @param strat Merge strategy to use while parsing this file
1165  * @param parse_type Parser type to use while parsing this file
1166  * @return true if chunk has been added and false in case of error
1167  */
1168 UCL_EXTERN bool ucl_parser_add_fd_full (struct ucl_parser *parser, int fd,
1169 		unsigned priority, enum ucl_duplicate_strategy strat,
1170 		enum ucl_parse_type parse_type);
1171 
1172 /**
1173  * Provide a UCL_ARRAY of paths to search for include files. The object is
1174  * copied so caller must unref the object.
1175  * @param parser parser structure
1176  * @param paths UCL_ARRAY of paths to search
1177  * @return true if the path search array was replaced in the parser
1178  */
1179 UCL_EXTERN bool ucl_set_include_path (struct ucl_parser *parser,
1180 		ucl_object_t *paths);
1181 
1182 /**
1183  * Get a top object for a parser (refcount is increased)
1184  * @param parser parser structure
1185  * @param err if *err is NULL it is set to parser error
1186  * @return top parser object or NULL
1187  */
1188 UCL_EXTERN ucl_object_t* ucl_parser_get_object (struct ucl_parser *parser);
1189 
1190 /**
1191  * Get the current stack object as stack accessor function for use in macro
1192  * functions (refcount is increased)
1193  * @param parser parser object
1194  * @param depth depth of stack to retrieve (top is 0)
1195  * @return current stack object or NULL
1196  */
1197 UCL_EXTERN ucl_object_t* ucl_parser_get_current_stack_object (struct ucl_parser *parser, unsigned int depth);
1198 
1199 /**
1200  * Peek at the character at the current chunk position
1201  * @param parser parser structure
1202  * @return current chunk position character
1203  */
1204 UCL_EXTERN unsigned char ucl_parser_chunk_peek (struct ucl_parser *parser);
1205 
1206 /**
1207  * Skip the character at the current chunk position
1208  * @param parser parser structure
1209  * @return success boolean
1210  */
1211 UCL_EXTERN bool ucl_parser_chunk_skip (struct ucl_parser *parser);
1212 
1213 /**
1214  * Get the error string if parsing has been failed
1215  * @param parser parser object
1216  * @return error description
1217  */
1218 UCL_EXTERN const char *ucl_parser_get_error (struct ucl_parser *parser);
1219 
1220 /**
1221  * Get the code of the last error
1222  * @param parser parser object
1223  * @return error code
1224  */
1225 UCL_EXTERN int ucl_parser_get_error_code (struct ucl_parser *parser);
1226 
1227 /**
1228  * Get the current column number within parser
1229  * @param parser parser object
1230  * @return current column number
1231  */
1232 UCL_EXTERN unsigned ucl_parser_get_column (struct ucl_parser *parser);
1233 
1234 /**
1235  * Get the current line number within parser
1236  * @param parser parser object
1237  * @return current line number
1238  */
1239 UCL_EXTERN unsigned ucl_parser_get_linenum (struct ucl_parser *parser);
1240 
1241 /**
1242  * Clear the error in the parser
1243  * @param parser parser object
1244  */
1245 UCL_EXTERN void ucl_parser_clear_error (struct ucl_parser *parser);
1246 
1247 /**
1248  * Free ucl parser object
1249  * @param parser parser object
1250  */
1251 UCL_EXTERN void ucl_parser_free (struct ucl_parser *parser);
1252 
1253 /**
1254  * Get constant opaque pointer to comments structure for this parser. Increase
1255  * refcount to prevent this object to be destroyed on parser's destruction
1256  * @param parser parser structure
1257  * @return ucl comments pointer or NULL
1258  */
1259 UCL_EXTERN const ucl_object_t * ucl_parser_get_comments (struct ucl_parser *parser);
1260 
1261 /**
1262  * Utility function to find a comment object for the specified object in the input
1263  * @param comments comments object
1264  * @param srch search object
1265  * @return string comment enclosed in ucl_object_t
1266  */
1267 UCL_EXTERN const ucl_object_t * ucl_comments_find (const ucl_object_t *comments,
1268 		const ucl_object_t *srch);
1269 
1270 /**
1271  * Move comment from `from` object to `to` object
1272  * @param comments comments object
1273  * @param what source object
1274  * @param with destination object
1275  * @return `true` if `from` has comment and it has been moved to `to`
1276  */
1277 UCL_EXTERN bool ucl_comments_move (ucl_object_t *comments,
1278 		const ucl_object_t *from, const ucl_object_t *to);
1279 
1280 /**
1281  * Adds a new comment for an object
1282  * @param comments comments object
1283  * @param obj object to add comment to
1284  * @param comment string representation of a comment
1285  */
1286 UCL_EXTERN void ucl_comments_add (ucl_object_t *comments,
1287 		const ucl_object_t *obj, const char *comment);
1288 
1289 /**
1290  * Add new public key to parser for signatures check
1291  * @param parser parser object
1292  * @param key PEM representation of a key
1293  * @param len length of the key
1294  * @param err if *err is NULL it is set to parser error
1295  * @return true if a key has been successfully added
1296  */
1297 UCL_EXTERN bool ucl_parser_pubkey_add (struct ucl_parser *parser,
1298 		const unsigned char *key, size_t len);
1299 
1300 /**
1301  * Set FILENAME and CURDIR variables in parser
1302  * @param parser parser object
1303  * @param filename filename to set or NULL to set FILENAME to "undef" and CURDIR to getcwd()
1304  * @param need_expand perform realpath() if this variable is true and filename is not NULL
1305  * @return true if variables has been set
1306  */
1307 UCL_EXTERN bool ucl_parser_set_filevars (struct ucl_parser *parser, const char *filename,
1308 		bool need_expand);
1309 
1310 /**
1311  * Returns current file for the parser
1312  * @param parser parser object
1313  * @return current file or NULL if parsing memory
1314  */
1315 UCL_EXTERN const char *ucl_parser_get_cur_file (struct ucl_parser *parser);
1316 
1317 /**
1318  * Defines special handler for certain types of data (identified by magic)
1319  */
1320 typedef bool (*ucl_parser_special_handler_t) (struct ucl_parser *parser,
1321 		const unsigned char *source, size_t source_len,
1322 		unsigned char **destination, size_t *dest_len,
1323 		void *user_data);
1324 
1325 /**
1326  * Special handler flags
1327  */
1328 enum ucl_special_handler_flags {
1329 	UCL_SPECIAL_HANDLER_DEFAULT = 0,
1330 	UCL_SPECIAL_HANDLER_PREPROCESS_ALL = (1u << 0),
1331 };
1332 
1333 /**
1334  * Special handler structure
1335  */
1336 struct ucl_parser_special_handler {
1337 	const unsigned char *magic;
1338 	size_t magic_len;
1339 	enum ucl_special_handler_flags flags;
1340 	ucl_parser_special_handler_t handler;
1341 	void (*free_function) (unsigned char *data, size_t len, void *user_data);
1342 	void *user_data;
1343 	struct ucl_parser_special_handler *next; /* Used internally */
1344 };
1345 
1346 /**
1347  * Add special handler for a parser, handles special sequences identified by magic
1348  * @param parser parser structure
1349  * @param handler handler structure
1350  */
1351 UCL_EXTERN void ucl_parser_add_special_handler (struct ucl_parser *parser,
1352 		struct ucl_parser_special_handler *handler);
1353 
1354 /**
1355  * Handler for include traces:
1356  * @param parser parser object
1357  * @param parent where include is done from
1358  * @param args arguments to an include
1359  * @param path path of the include
1360  * @param pathlen length of the path
1361  * @param user_data opaque userdata
1362  */
1363 typedef void (ucl_include_trace_func_t) (struct ucl_parser *parser,
1364 		const ucl_object_t *parent,
1365 		const ucl_object_t *args,
1366 		const char *path,
1367 		size_t pathlen,
1368 		void *user_data);
1369 
1370 /**
1371  * Register trace function for an include handler
1372  * @param parser parser object
1373  * @param func function to trace includes
1374  * @param user_data opaque data
1375  */
1376 UCL_EXTERN void ucl_parser_set_include_tracer (struct ucl_parser *parser,
1377 											   ucl_include_trace_func_t func,
1378 											   void *user_data);
1379 
1380 /** @} */
1381 
1382 /**
1383  * @defgroup emitter Emitting functions
1384  * These functions are used to serialise UCL objects to some string representation.
1385  *
1386  * @{
1387  */
1388 
1389 struct ucl_emitter_context;
1390 /**
1391  * Structure using for emitter callbacks
1392  */
1393 struct ucl_emitter_functions {
1394 	/** Append a single character */
1395 	int (*ucl_emitter_append_character) (unsigned char c, size_t nchars, void *ud);
1396 	/** Append a string of a specified length */
1397 	int (*ucl_emitter_append_len) (unsigned const char *str, size_t len, void *ud);
1398 	/** Append a 64 bit integer */
1399 	int (*ucl_emitter_append_int) (int64_t elt, void *ud);
1400 	/** Append floating point element */
1401 	int (*ucl_emitter_append_double) (double elt, void *ud);
1402 	/** Free userdata */
1403 	void (*ucl_emitter_free_func)(void *ud);
1404 	/** Opaque userdata pointer */
1405 	void *ud;
1406 };
1407 
1408 struct ucl_emitter_operations {
1409 	/** Write a primitive element */
1410 	void (*ucl_emitter_write_elt) (struct ucl_emitter_context *ctx,
1411 		const ucl_object_t *obj, bool first, bool print_key);
1412 	/** Start ucl object */
1413 	void (*ucl_emitter_start_object) (struct ucl_emitter_context *ctx,
1414 		const ucl_object_t *obj, bool print_key);
1415 	/** End ucl object */
1416 	void (*ucl_emitter_end_object) (struct ucl_emitter_context *ctx,
1417 		const ucl_object_t *obj);
1418 	/** Start ucl array */
1419 	void (*ucl_emitter_start_array) (struct ucl_emitter_context *ctx,
1420 		const ucl_object_t *obj, bool print_key);
1421 	void (*ucl_emitter_end_array) (struct ucl_emitter_context *ctx,
1422 		const ucl_object_t *obj);
1423 };
1424 
1425 /**
1426  * Structure that defines emitter functions
1427  */
1428 struct ucl_emitter_context {
1429 	/** Name of emitter (e.g. json, compact_json) */
1430 	const char *name;
1431 	/** Unique id (e.g. UCL_EMIT_JSON for standard emitters */
1432 	int id;
1433 	/** A set of output functions */
1434 	const struct ucl_emitter_functions *func;
1435 	/** A set of output operations */
1436 	const struct ucl_emitter_operations *ops;
1437 	/** Current amount of indent tabs */
1438 	unsigned int indent;
1439 	/** Top level object */
1440 	const ucl_object_t *top;
1441 	/** Optional comments */
1442 	const ucl_object_t *comments;
1443 };
1444 
1445 /**
1446  * Emit object to a string
1447  * @param obj object
1448  * @param emit_type if type is #UCL_EMIT_JSON then emit json, if type is
1449  * #UCL_EMIT_CONFIG then emit config like object
1450  * @return dump of an object (must be freed after using) or NULL in case of error
1451  */
1452 UCL_EXTERN unsigned char *ucl_object_emit (const ucl_object_t *obj,
1453 		enum ucl_emitter emit_type);
1454 
1455 /**
1456  * Emit object to a string that can contain `\0` inside
1457  * @param obj object
1458  * @param emit_type if type is #UCL_EMIT_JSON then emit json, if type is
1459  * #UCL_EMIT_CONFIG then emit config like object
1460  * @param len the resulting length
1461  * @return dump of an object (must be freed after using) or NULL in case of error
1462  */
1463 UCL_EXTERN unsigned char *ucl_object_emit_len (const ucl_object_t *obj,
1464 		enum ucl_emitter emit_type, size_t *len);
1465 
1466 /**
1467  * Emit object to a string
1468  * @param obj object
1469  * @param emit_type if type is #UCL_EMIT_JSON then emit json, if type is
1470  * #UCL_EMIT_CONFIG then emit config like object
1471  * @param emitter a set of emitter functions
1472  * @param comments optional comments for the parser
1473  * @return dump of an object (must be freed after using) or NULL in case of error
1474  */
1475 UCL_EXTERN bool ucl_object_emit_full (const ucl_object_t *obj,
1476 		enum ucl_emitter emit_type,
1477 		struct ucl_emitter_functions *emitter,
1478 		const ucl_object_t *comments);
1479 
1480 /**
1481  * Start streamlined UCL object emitter
1482  * @param obj top UCL object
1483  * @param emit_type emit type
1484  * @param emitter a set of emitter functions
1485  * @return new streamlined context that should be freed by
1486  * `ucl_object_emit_streamline_finish`
1487  */
1488 UCL_EXTERN struct ucl_emitter_context* ucl_object_emit_streamline_new (
1489 		const ucl_object_t *obj, enum ucl_emitter emit_type,
1490 		struct ucl_emitter_functions *emitter);
1491 
1492 /**
1493  * Start object or array container for the streamlined output
1494  * @param ctx streamlined context
1495  * @param obj container object
1496  */
1497 UCL_EXTERN void ucl_object_emit_streamline_start_container (
1498 		struct ucl_emitter_context *ctx, const ucl_object_t *obj);
1499 /**
1500  * Add a complete UCL object to streamlined output
1501  * @param ctx streamlined context
1502  * @param obj object to output
1503  */
1504 UCL_EXTERN void ucl_object_emit_streamline_add_object (
1505 		struct ucl_emitter_context *ctx, const ucl_object_t *obj);
1506 /**
1507  * End previously added container
1508  * @param ctx streamlined context
1509  */
1510 UCL_EXTERN void ucl_object_emit_streamline_end_container (
1511 		struct ucl_emitter_context *ctx);
1512 /**
1513  * Terminate streamlined container finishing all containers in it
1514  * @param ctx streamlined context
1515  */
1516 UCL_EXTERN void ucl_object_emit_streamline_finish (
1517 		struct ucl_emitter_context *ctx);
1518 
1519 /**
1520  * Returns functions to emit object to memory
1521  * @param pmem target pointer (should be freed by caller)
1522  * @return emitter functions structure
1523  */
1524 UCL_EXTERN struct ucl_emitter_functions* ucl_object_emit_memory_funcs (
1525 		void **pmem);
1526 
1527 /**
1528  * Returns functions to emit object to FILE *
1529  * @param fp FILE * object
1530  * @return emitter functions structure
1531  */
1532 UCL_EXTERN struct ucl_emitter_functions* ucl_object_emit_file_funcs (
1533 		FILE *fp);
1534 /**
1535  * Returns functions to emit object to a file descriptor
1536  * @param fd file descriptor
1537  * @return emitter functions structure
1538  */
1539 UCL_EXTERN struct ucl_emitter_functions* ucl_object_emit_fd_funcs (
1540 		int fd);
1541 
1542 /**
1543  * Free emitter functions
1544  * @param f pointer to functions
1545  */
1546 UCL_EXTERN void ucl_object_emit_funcs_free (struct ucl_emitter_functions *f);
1547 
1548 /** @} */
1549 
1550 /**
1551  * @defgroup schema Schema functions
1552  * These functions are used to validate UCL objects using json schema format
1553  *
1554  * @{
1555  */
1556 
1557 /**
1558  * Used to define UCL schema error
1559  */
1560 enum ucl_schema_error_code {
1561 	UCL_SCHEMA_OK = 0,          /**< no error */
1562 	UCL_SCHEMA_TYPE_MISMATCH,   /**< type of object is incorrect */
1563 	UCL_SCHEMA_INVALID_SCHEMA,  /**< schema is invalid */
1564 	UCL_SCHEMA_MISSING_PROPERTY,/**< one or more missing properties */
1565 	UCL_SCHEMA_CONSTRAINT,      /**< constraint found */
1566 	UCL_SCHEMA_MISSING_DEPENDENCY, /**< missing dependency */
1567 	UCL_SCHEMA_EXTERNAL_REF_MISSING, /**< cannot fetch external ref */
1568 	UCL_SCHEMA_EXTERNAL_REF_INVALID, /**< invalid external ref */
1569 	UCL_SCHEMA_INTERNAL_ERROR, /**< something bad happened */
1570 	UCL_SCHEMA_UNKNOWN          /**< generic error */
1571 };
1572 
1573 /**
1574  * Generic ucl schema error
1575  */
1576 struct ucl_schema_error {
1577 	enum ucl_schema_error_code code;	/**< error code */
1578 	char msg[128];						/**< error message */
1579 	const ucl_object_t *obj;			/**< object where error occurred */
1580 };
1581 
1582 /**
1583  * Validate object `obj` using schema object `schema`.
1584  * @param schema schema object
1585  * @param obj object to validate
1586  * @param err error pointer, if this parameter is not NULL and error has been
1587  * occurred, then `err` is filled with the exact error definition.
1588  * @return true if `obj` is valid using `schema`
1589  */
1590 UCL_EXTERN bool ucl_object_validate (const ucl_object_t *schema,
1591 		const ucl_object_t *obj, struct ucl_schema_error *err);
1592 
1593 /**
1594  * Validate object `obj` using schema object `schema` and root schema at `root`.
1595  * @param schema schema object
1596  * @param obj object to validate
1597  * @param root root schema object
1598  * @param err error pointer, if this parameter is not NULL and error has been
1599  * occurred, then `err` is filled with the exact error definition.
1600  * @return true if `obj` is valid using `schema`
1601  */
1602 UCL_EXTERN bool ucl_object_validate_root (const ucl_object_t *schema,
1603 		const ucl_object_t *obj,
1604 		const ucl_object_t *root,
1605 		struct ucl_schema_error *err);
1606 
1607 /**
1608  * Validate object `obj` using schema object `schema` and root schema at `root`
1609  * using some external references provided.
1610  * @param schema schema object
1611  * @param obj object to validate
1612  * @param root root schema object
1613  * @param ext_refs external references (might be modified during validation)
1614  * @param err error pointer, if this parameter is not NULL and error has been
1615  * occurred, then `err` is filled with the exact error definition.
1616  * @return true if `obj` is valid using `schema`
1617  */
1618 UCL_EXTERN bool ucl_object_validate_root_ext (const ucl_object_t *schema,
1619 		const ucl_object_t *obj,
1620 		const ucl_object_t *root,
1621 		ucl_object_t *ext_refs,
1622 		struct ucl_schema_error *err);
1623 
1624 /** @} */
1625 
1626 #ifdef  __cplusplus
1627 }
1628 #endif
1629 /*
1630  * XXX: Poorly named API functions, need to replace them with the appropriate
1631  * named function. All API functions *must* use naming ucl_object_*. Usage of
1632  * ucl_obj* should be avoided.
1633  */
1634 #define ucl_obj_todouble_safe ucl_object_todouble_safe
1635 #define ucl_obj_todouble ucl_object_todouble
1636 #define ucl_obj_tostring ucl_object_tostring
1637 #define ucl_obj_tostring_safe ucl_object_tostring_safe
1638 #define ucl_obj_tolstring ucl_object_tolstring
1639 #define ucl_obj_tolstring_safe ucl_object_tolstring_safe
1640 #define ucl_obj_toint ucl_object_toint
1641 #define ucl_obj_toint_safe ucl_object_toint_safe
1642 #define ucl_obj_toboolean ucl_object_toboolean
1643 #define ucl_obj_toboolean_safe ucl_object_toboolean_safe
1644 #define ucl_obj_get_key ucl_object_find_key
1645 #define ucl_obj_get_keyl ucl_object_find_keyl
1646 #define ucl_obj_unref ucl_object_unref
1647 #define ucl_obj_ref ucl_object_ref
1648 #define ucl_obj_free ucl_object_free
1649 
1650 #define UCL_PRIORITY_MIN 0
1651 #define UCL_PRIORITY_MAX 15
1652 
1653 #endif /* UCL_H_ */
1654