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
62extern "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 */
102typedef 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 */
121typedef 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 */
136typedef 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 */
151typedef 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 */
165typedef 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 */
184typedef 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 */
199enum 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 */
209enum 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 */
220typedef 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 */
247typedef void (*ucl_userdata_dtor)(void *ud);
248typedef 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 */
263UCL_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 */
270UCL_EXTERN char* ucl_copy_value_trash (const ucl_object_t *obj);
271
272/**
273 * Creates a new object
274 * @return new object
275 */
276UCL_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 */
283UCL_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 */
291UCL_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 */
301UCL_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 */
309UCL_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 */
316UCL_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 */
323UCL_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 */
331UCL_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 */
340UCL_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 */
348UCL_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 */
356UCL_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 */
364UCL_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 */
371UCL_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 */
378UCL_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 */
389UCL_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 */
402UCL_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 */
412UCL_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 */
420UCL_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 */
428UCL_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 */
441UCL_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 */
452UCL_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 */
465UCL_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 */
474UCL_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 */
482UCL_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 */
491UCL_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 */
501UCL_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 */
512UCL_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 */
520UCL_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 */
527UCL_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 */
536UCL_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 */
545UCL_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 */
552UCL_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 */
560UCL_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 */
569UCL_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 */
581ucl_object_t *
582ucl_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 */
591UCL_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 */
600UCL_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 */
607UCL_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 */
615UCL_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 */
622UCL_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 */
630UCL_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 */
637UCL_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 */
645UCL_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 */
652UCL_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 */
659UCL_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 */
669UCL_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 */
677UCL_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 */
685UCL_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 */
699UCL_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 */
710UCL_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 */
720UCL_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 */
731UCL_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 */
740UCL_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 */
748UCL_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 */
755UCL_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 */
761UCL_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 */
767UCL_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 */
779UCL_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 */
792UCL_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 */
800UCL_EXTERN void ucl_object_array_sort (ucl_object_t *ar,
801		int (*cmp)(const ucl_object_t **o1, const ucl_object_t **o2));
802
803enum 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 */
813UCL_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 */
821UCL_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 */
828UCL_EXTERN void ucl_object_set_priority (ucl_object_t *obj,
829		unsigned int priority);
830
831/**
832 * Opaque iterator object
833 */
834typedef 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 */
845UCL_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 */
856UCL_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 */
865UCL_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 */
872UCL_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 */
882UCL_EXTERN const ucl_object_t* ucl_object_iterate_safe (ucl_object_iter_t iter,
883		bool expand_values);
884/**
885 * Iteration type enumerator
886 */
887enum 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 */
900UCL_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 */
907UCL_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 */
928typedef 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 */
942typedef 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 */
948struct ucl_parser;
949
950/**
951 * Creates new parser object
952 * @param pool pool to allocate memory from
953 * @return new parser object
954 */
955UCL_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 */
964UCL_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 */
972UCL_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 */
982UCL_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 */
994UCL_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 */
1009typedef 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 */
1018UCL_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 */
1027UCL_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 */
1037UCL_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 */
1049UCL_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 */
1059UCL_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 */
1073UCL_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 */
1084UCL_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 */
1096UCL_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 */
1106UCL_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 */
1118UCL_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 */
1131UCL_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 */
1142UCL_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 */
1154UCL_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 */
1168UCL_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 */
1179UCL_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 */
1188UCL_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 */
1197UCL_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 */
1204UCL_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 */
1211UCL_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 */
1218UCL_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 */
1225UCL_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 */
1232UCL_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 */
1239UCL_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 */
1245UCL_EXTERN void ucl_parser_clear_error (struct ucl_parser *parser);
1246
1247/**
1248 * Free ucl parser object
1249 * @param parser parser object
1250 */
1251UCL_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 */
1259UCL_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 */
1267UCL_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 */
1277UCL_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 */
1286UCL_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 */
1297UCL_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 */
1307UCL_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 */
1315UCL_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 */
1320typedef 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 */
1328enum 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 */
1336struct 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 */
1351UCL_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 */
1363typedef 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 */
1376UCL_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
1389struct ucl_emitter_context;
1390/**
1391 * Structure using for emitter callbacks
1392 */
1393struct 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
1408struct 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 */
1428struct 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 */
1452UCL_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 */
1463UCL_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 */
1475UCL_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 */
1488UCL_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 */
1497UCL_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 */
1504UCL_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 */
1510UCL_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 */
1516UCL_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 */
1524UCL_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 */
1532UCL_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 */
1539UCL_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 */
1546UCL_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 */
1560enum 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 */
1576struct 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 */
1590UCL_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 */
1602UCL_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 */
1618UCL_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