/* Copyright (c) 2013-2015, Vsevolod Stakhov1* All rights reserved.2*3* Redistribution and use in source and binary forms, with or without4* modification, are permitted provided that the following conditions are met:5* * Redistributions of source code must retain the above copyright6* notice, this list of conditions and the following disclaimer.7* * Redistributions in binary form must reproduce the above copyright8* notice, this list of conditions and the following disclaimer in the9* documentation and/or other materials provided with the distribution.10*11* THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY12* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED13* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE14* DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY15* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES16* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;17* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND18* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT19* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS20* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.21*/2223#ifndef UCL_H_24#define UCL_H_2526#include <string.h>27#include <stddef.h>28#include <stdlib.h>29#include <stdint.h>30#include <stdbool.h>31#include <stdarg.h>32#include <stdio.h>3334#ifdef _WIN3235# define UCL_EXTERN __declspec(dllexport)36#else37# define UCL_EXTERN38#endif3940/**41* @mainpage42* This is a reference manual for UCL API. You may find the description of UCL format by following this43* [github repository](https://github.com/vstakhov/libucl).44*45* This manual has several main sections:46* - @ref structures47* - @ref utils48* - @ref parser49* - @ref emitter50*/5152/**53* @file ucl.h54* @brief UCL parsing and emitting functions55*56* UCL is universal configuration language, which is a form of57* JSON with less strict rules that make it more comfortable for58* using as a configuration language59*/60#ifdef __cplusplus61extern "C" {62#endif63/*64* Memory allocation utilities65* UCL_ALLOC(size) - allocate memory for UCL66* UCL_FREE(size, ptr) - free memory of specified size at ptr67* Default: malloc and free68*/69#ifndef UCL_ALLOC70#define UCL_ALLOC(size) malloc(size)71#endif72#ifndef UCL_FREE73#define UCL_FREE(size, ptr) free(ptr)74#endif7576#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)77#define UCL_WARN_UNUSED_RESULT \78__attribute__((warn_unused_result))79#else80#define UCL_WARN_UNUSED_RESULT81#endif8283#ifdef __GNUC__84#define UCL_DEPRECATED(func) func __attribute__ ((deprecated))85#elif defined(_MSC_VER)86#define UCL_DEPRECATED(func) __declspec(deprecated) func87#else88#define UCL_DEPRECATED(func) func89#endif9091/**92* @defgroup structures Structures and types93* UCL defines several enumeration types used for error reporting or specifying flags and attributes.94*95* @{96*/9798/**99* The common error codes returned by ucl parser100*/101typedef enum ucl_error {102UCL_EOK = 0, /**< No error */103UCL_ESYNTAX, /**< Syntax error occurred during parsing */104UCL_EIO, /**< IO error occurred during parsing */105UCL_ESTATE, /**< Invalid state machine state */106UCL_ENESTED, /**< Input has too many recursion levels */107UCL_EUNPAIRED, /**< Input has too many recursion levels */108UCL_EMACRO, /**< Error processing a macro */109UCL_EINTERNAL, /**< Internal unclassified error */110UCL_ESSL, /**< SSL error */111UCL_EMERGE /**< A merge error occurred */112} ucl_error_t;113114/**115* #ucl_object_t may have one of specified types, some types are compatible with each other and some are not.116* For example, you can always convert #UCL_TIME to #UCL_FLOAT. Also you can convert #UCL_FLOAT to #UCL_INTEGER117* by loosing floating point. Every object may be converted to a string by #ucl_object_tostring_forced() function.118*119*/120typedef enum ucl_type {121UCL_OBJECT = 0, /**< UCL object - key/value pairs */122UCL_ARRAY, /**< UCL array */123UCL_INT, /**< Integer number */124UCL_FLOAT, /**< Floating point number */125UCL_STRING, /**< Null terminated string */126UCL_BOOLEAN, /**< Boolean value */127UCL_TIME, /**< Time value (floating point number of seconds) */128UCL_USERDATA, /**< Opaque userdata pointer (may be used in macros) */129UCL_NULL /**< Null value */130} ucl_type_t;131132/**133* You can use one of these types to serialise #ucl_object_t by using ucl_object_emit().134*/135typedef enum ucl_emitter {136UCL_EMIT_JSON = 0, /**< Emit fine formatted JSON */137UCL_EMIT_JSON_COMPACT, /**< Emit compacted JSON */138UCL_EMIT_CONFIG, /**< Emit human readable config format */139UCL_EMIT_YAML, /**< Emit embedded YAML format */140UCL_EMIT_MSGPACK, /**< Emit msgpack output */141UCL_EMIT_MAX /**< Unsupported emitter type */142} ucl_emitter_t;143144/**145* These flags defines parser behaviour. If you specify #UCL_PARSER_ZEROCOPY you must ensure146* that the input memory is not freed if an object is in use. Moreover, if you want to use147* zero-terminated keys and string values then you should not use zero-copy mode, as in this case148* UCL still has to perform copying implicitly.149*/150typedef enum ucl_parser_flags {151UCL_PARSER_DEFAULT = 0, /**< No special flags */152UCL_PARSER_KEY_LOWERCASE = (1 << 0), /**< Convert all keys to lower case */153UCL_PARSER_ZEROCOPY = (1 << 1), /**< Parse input in zero-copy mode if possible */154UCL_PARSER_NO_TIME = (1 << 2), /**< Do not parse time and treat time values as strings */155UCL_PARSER_NO_IMPLICIT_ARRAYS = (1 << 3), /** Create explicit arrays instead of implicit ones */156UCL_PARSER_SAVE_COMMENTS = (1 << 4), /** Save comments in the parser context */157UCL_PARSER_DISABLE_MACRO = (1 << 5), /** Treat macros as comments */158UCL_PARSER_NO_FILEVARS = (1 << 6) /** Do not set file vars */159} ucl_parser_flags_t;160161/**162* String conversion flags, that are used in #ucl_object_fromstring_common function.163*/164typedef enum ucl_string_flags {165UCL_STRING_RAW = 0x0, /**< Treat string as is */166UCL_STRING_ESCAPE = (1 << 0), /**< Perform JSON escape */167UCL_STRING_TRIM = (1 << 1), /**< Trim leading and trailing whitespaces */168UCL_STRING_PARSE_BOOLEAN = (1 << 2), /**< Parse passed string and detect boolean */169UCL_STRING_PARSE_INT = (1 << 3), /**< Parse passed string and detect integer number */170UCL_STRING_PARSE_DOUBLE = (1 << 4), /**< Parse passed string and detect integer or float number */171UCL_STRING_PARSE_TIME = (1 << 5), /**< Parse time strings */172UCL_STRING_PARSE_NUMBER = UCL_STRING_PARSE_INT|UCL_STRING_PARSE_DOUBLE|UCL_STRING_PARSE_TIME, /**<173Parse passed string and detect number */174UCL_STRING_PARSE = UCL_STRING_PARSE_BOOLEAN|UCL_STRING_PARSE_NUMBER, /**<175Parse passed string (and detect booleans and numbers) */176UCL_STRING_PARSE_BYTES = (1 << 6) /**< Treat numbers as bytes */177} ucl_string_flags_t;178179/**180* Basic flags for an object (can use up to 12 bits as higher 4 bits are used181* for priorities)182*/183typedef enum ucl_object_flags {184UCL_OBJECT_ALLOCATED_KEY = (1 << 0), /**< An object has key allocated internally */185UCL_OBJECT_ALLOCATED_VALUE = (1 << 1), /**< An object has a string value allocated internally */186UCL_OBJECT_NEED_KEY_ESCAPE = (1 << 2), /**< The key of an object need to be escaped on output */187UCL_OBJECT_EPHEMERAL = (1 << 3), /**< Temporary object that does not need to be freed really */188UCL_OBJECT_MULTILINE = (1 << 4), /**< String should be displayed as multiline string */189UCL_OBJECT_MULTIVALUE = (1 << 5), /**< Object is a key with multiple values */190UCL_OBJECT_INHERITED = (1 << 6), /**< Object has been inherited from another */191UCL_OBJECT_BINARY = (1 << 7), /**< Object contains raw binary data */192UCL_OBJECT_SQUOTED = (1 << 8) /**< Object has been enclosed in single quotes */193} ucl_object_flags_t;194195/**196* Duplicate policy types197*/198enum ucl_duplicate_strategy {199UCL_DUPLICATE_APPEND = 0, /**< Default policy to merge based on priorities */200UCL_DUPLICATE_MERGE, /**< Merge new object with old one */201UCL_DUPLICATE_REWRITE, /**< Rewrite old keys */202UCL_DUPLICATE_ERROR /**< Stop parsing on duplicate found */203};204205/**206* Input format type207*/208enum ucl_parse_type {209UCL_PARSE_UCL = 0, /**< Default ucl format */210UCL_PARSE_MSGPACK, /**< Message pack input format */211UCL_PARSE_CSEXP, /**< Canonical S-expressions */212UCL_PARSE_AUTO /**< Try to detect parse type */213};214215/**216* UCL object structure. Please mention that the most of fields should not be touched by217* UCL users. In future, this structure may be converted to private one.218*/219typedef struct ucl_object_s {220/**221* Variant value type222*/223union {224int64_t iv; /**< Int value of an object */225const char *sv; /**< String value of an object */226double dv; /**< Double value of an object */227void *av; /**< Array */228void *ov; /**< Object */229void* ud; /**< Opaque user data */230} value;231const char *key; /**< Key of an object */232struct ucl_object_s *next; /**< Array handle */233struct ucl_object_s *prev; /**< Array handle */234uint32_t keylen; /**< Length of a key */235uint32_t len; /**< Size of an object */236uint32_t ref; /**< Reference count */237uint16_t flags; /**< Object flags */238uint16_t type; /**< Real type */239unsigned char* trash_stack[2]; /**< Pointer to allocated chunks */240} ucl_object_t;241242/**243* Destructor type for userdata objects244* @param ud user specified data pointer245*/246typedef void (*ucl_userdata_dtor)(void *ud);247typedef const char* (*ucl_userdata_emitter)(void *ud);248249/** @} */250251/**252* @defgroup utils Utility functions253* A number of utility functions simplify handling of UCL objects254*255* @{256*/257/**258* Copy and return a key of an object, returned key is zero-terminated259* @param obj CL object260* @return zero terminated key261*/262UCL_EXTERN char* ucl_copy_key_trash (const ucl_object_t *obj);263264/**265* Copy and return a string value of an object, returned key is zero-terminated266* @param obj CL object267* @return zero terminated string representation of object value268*/269UCL_EXTERN char* ucl_copy_value_trash (const ucl_object_t *obj);270271/**272* Creates a new object273* @return new object274*/275UCL_EXTERN ucl_object_t* ucl_object_new (void) UCL_WARN_UNUSED_RESULT;276277/**278* Create new object with type specified279* @param type type of a new object280* @return new object281*/282UCL_EXTERN ucl_object_t* ucl_object_typed_new (ucl_type_t type) UCL_WARN_UNUSED_RESULT;283284/**285* Create new object with type and priority specified286* @param type type of a new object287* @param priority priority of an object288* @return new object289*/290UCL_EXTERN ucl_object_t* ucl_object_new_full (ucl_type_t type, unsigned priority)291UCL_WARN_UNUSED_RESULT;292293/**294* Create new object with userdata dtor295* @param dtor destructor function296* @param emitter emitter for userdata297* @param ptr opaque pointer298* @return new object299*/300UCL_EXTERN ucl_object_t* ucl_object_new_userdata (ucl_userdata_dtor dtor,301ucl_userdata_emitter emitter, void *ptr) UCL_WARN_UNUSED_RESULT;302303/**304* Perform deep copy of an object copying everything305* @param other object to copy306* @return new object with refcount equal to 1307*/308UCL_EXTERN ucl_object_t * ucl_object_copy (const ucl_object_t *other)309UCL_WARN_UNUSED_RESULT;310311/**312* Return the type of an object313* @return the object type314*/315UCL_EXTERN ucl_type_t ucl_object_type (const ucl_object_t *obj);316317/**318* Converts ucl object type to its string representation319* @param type type of object320* @return constant string describing type321*/322UCL_EXTERN const char * ucl_object_type_to_string (ucl_type_t type);323324/**325* Converts string that represents ucl type to real ucl type enum326* @param input C string with name of type327* @param res resulting target328* @return true if `input` is a name of type stored in `res`329*/330UCL_EXTERN bool ucl_object_string_to_type (const char *input, ucl_type_t *res);331332/**333* Convert any string to an ucl object making the specified transformations334* @param str fixed size or NULL terminated string335* @param len length (if len is zero, than str is treated as NULL terminated)336* @param flags conversion flags337* @return new object338*/339UCL_EXTERN ucl_object_t * ucl_object_fromstring_common (const char *str, size_t len,340enum ucl_string_flags flags) UCL_WARN_UNUSED_RESULT;341342/**343* Create a UCL object from the specified string344* @param str NULL terminated string, will be json escaped345* @return new object346*/347UCL_EXTERN ucl_object_t *ucl_object_fromstring (const char *str) UCL_WARN_UNUSED_RESULT;348349/**350* Create a UCL object from the specified string351* @param str fixed size string, will be json escaped352* @param len length of a string353* @return new object354*/355UCL_EXTERN ucl_object_t *ucl_object_fromlstring (const char *str,356size_t len) UCL_WARN_UNUSED_RESULT;357358/**359* Create an object from an integer number360* @param iv number361* @return new object362*/363UCL_EXTERN ucl_object_t* ucl_object_fromint (int64_t iv) UCL_WARN_UNUSED_RESULT;364365/**366* Create an object from a float number367* @param dv number368* @return new object369*/370UCL_EXTERN ucl_object_t* ucl_object_fromdouble (double dv) UCL_WARN_UNUSED_RESULT;371372/**373* Create an object from a boolean374* @param bv bool value375* @return new object376*/377UCL_EXTERN ucl_object_t* ucl_object_frombool (bool bv) UCL_WARN_UNUSED_RESULT;378379/**380* Insert a object 'elt' to the hash 'top' and associate it with key 'key'381* @param top destination object (must be of type UCL_OBJECT)382* @param elt element to insert (must NOT be NULL)383* @param key key to associate with this object (either const or preallocated)384* @param keylen length of the key (or 0 for NULL terminated keys)385* @param copy_key make an internal copy of key386* @return true if key has been inserted387*/388UCL_EXTERN bool ucl_object_insert_key (ucl_object_t *top, ucl_object_t *elt,389const char *key, size_t keylen, bool copy_key);390391/**392* Replace a object 'elt' to the hash 'top' and associate it with key 'key', old object will be unrefed,393* if no object has been found this function works like ucl_object_insert_key()394* @param top destination object (must be of type UCL_OBJECT)395* @param elt element to insert (must NOT be NULL)396* @param key key to associate with this object (either const or preallocated)397* @param keylen length of the key (or 0 for NULL terminated keys)398* @param copy_key make an internal copy of key399* @return true if key has been inserted400*/401UCL_EXTERN bool ucl_object_replace_key (ucl_object_t *top, ucl_object_t *elt,402const char *key, size_t keylen, bool copy_key);403404/**405* Merge the keys from one object to another object. Overwrite on conflict406* @param top destination object (must be of type UCL_OBJECT)407* @param elt element to insert (must be of type UCL_OBJECT)408* @param copy copy rather than reference the elements409* @return true if all keys have been merged410*/411UCL_EXTERN bool ucl_object_merge (ucl_object_t *top, ucl_object_t *elt, bool copy);412413/**414* Delete a object associated with key 'key', old object will be unrefered,415* @param top object416* @param key key associated to the object to remove417* @param keylen length of the key (or 0 for NULL terminated keys)418*/419UCL_EXTERN bool ucl_object_delete_keyl (ucl_object_t *top,420const char *key, size_t keylen);421422/**423* Delete a object associated with key 'key', old object will be unrefered,424* @param top object425* @param key key associated to the object to remove426*/427UCL_EXTERN bool ucl_object_delete_key (ucl_object_t *top,428const char *key);429430431/**432* Removes `key` from `top` object, returning the object that was removed. This433* object is not released, caller must unref the returned object when it is no434* longer needed.435* @param top object436* @param key key to remove437* @param keylen length of the key (or 0 for NULL terminated keys)438* @return removed object or NULL if object has not been found439*/440UCL_EXTERN ucl_object_t* ucl_object_pop_keyl (ucl_object_t *top, const char *key,441size_t keylen) UCL_WARN_UNUSED_RESULT;442443/**444* Removes `key` from `top` object returning the object that was removed. This445* object is not released, caller must unref the returned object when it is no446* longer needed.447* @param top object448* @param key key to remove449* @return removed object or NULL if object has not been found450*/451UCL_EXTERN ucl_object_t* ucl_object_pop_key (ucl_object_t *top, const char *key)452UCL_WARN_UNUSED_RESULT;453454/**455* Insert a object 'elt' to the hash 'top' and associate it with key 'key', if456* the specified key exist, try to merge its content457* @param top destination object (must be of type UCL_OBJECT)458* @param elt element to insert (must NOT be NULL)459* @param key key to associate with this object (either const or preallocated)460* @param keylen length of the key (or 0 for NULL terminated keys)461* @param copy_key make an internal copy of key462* @return true if key has been inserted463*/464UCL_EXTERN bool ucl_object_insert_key_merged (ucl_object_t *top, ucl_object_t *elt,465const char *key, size_t keylen, bool copy_key);466467/**468* Reserve space in ucl array or object for `elt` elements469* @param obj object to reserve470* @param reserved size to reserve in an object471* @return 0 on success, -1 on failure (i.e. ENOMEM)472*/473UCL_EXTERN bool ucl_object_reserve (ucl_object_t *obj, size_t reserved);474475/**476* Append an element to the end of array object477* @param top destination object (must NOT be NULL)478* @param elt element to append (must NOT be NULL)479* @return true if value has been inserted480*/481UCL_EXTERN bool ucl_array_append (ucl_object_t *top,482ucl_object_t *elt);483484/**485* Append an element to the start of array object486* @param top destination object (must NOT be NULL)487* @param elt element to append (must NOT be NULL)488* @return true if value has been inserted489*/490UCL_EXTERN bool ucl_array_prepend (ucl_object_t *top,491ucl_object_t *elt);492493/**494* Merge all elements of second array into the first array495* @param top destination array (must be of type UCL_ARRAY)496* @param elt array to copy elements from (must be of type UCL_ARRAY)497* @param copy copy elements instead of referencing them498* @return true if arrays were merged499*/500UCL_EXTERN bool ucl_array_merge (ucl_object_t *top, ucl_object_t *elt,501bool copy);502503/**504* Removes an element `elt` from the array `top`, returning the object that was505* removed. This object is not released, caller must unref the returned object506* when it is no longer needed.507* @param top array ucl object508* @param elt element to remove509* @return removed element or NULL if `top` is NULL or not an array510*/511UCL_EXTERN ucl_object_t* ucl_array_delete (ucl_object_t *top,512ucl_object_t *elt);513514/**515* Returns the first element of the array `top`516* @param top array ucl object517* @return element or NULL if `top` is NULL or not an array518*/519UCL_EXTERN const ucl_object_t* ucl_array_head (const ucl_object_t *top);520521/**522* Returns the last element of the array `top`523* @param top array ucl object524* @return element or NULL if `top` is NULL or not an array525*/526UCL_EXTERN const ucl_object_t* ucl_array_tail (const ucl_object_t *top);527528/**529* Removes the last element from the array `top`, returning the object that was530* removed. This object is not released, caller must unref the returned object531* when it is no longer needed.532* @param top array ucl object533* @return removed element or NULL if `top` is NULL or not an array534*/535UCL_EXTERN ucl_object_t* ucl_array_pop_last (ucl_object_t *top);536537/**538* Removes the first element from the array `top`, returning the object that was539* removed. This object is not released, caller must unref the returned object540* when it is no longer needed.541* @param top array ucl object542* @return removed element or NULL if `top` is NULL or not an array543*/544UCL_EXTERN ucl_object_t* ucl_array_pop_first (ucl_object_t *top);545546/**547* Return size of the array `top`548* @param top object to get size from (must be of type UCL_ARRAY)549* @return size of the array550*/551UCL_EXTERN unsigned int ucl_array_size (const ucl_object_t *top);552553/**554* Return object identified by index of the array `top`555* @param top object to get a key from (must be of type UCL_ARRAY)556* @param index array index to return557* @return object at the specified index or NULL if index is not found558*/559UCL_EXTERN const ucl_object_t* ucl_array_find_index (const ucl_object_t *top,560unsigned int index);561562/**563* Return the index of `elt` in the array `top`564* @param top object to get a key from (must be of type UCL_ARRAY)565* @param elt element to find index of (must NOT be NULL)566* @return index of `elt` in the array `top or (unsigned int)-1 if `elt` is not found567*/568UCL_EXTERN unsigned int ucl_array_index_of (ucl_object_t *top,569ucl_object_t *elt);570571/**572* Replace an element in an array with a different element, returning the object573* that was replaced. This object is not released, caller must unref the574* returned object when it is no longer needed.575* @param top destination object (must be of type UCL_ARRAY)576* @param elt element to append (must NOT be NULL)577* @param index array index in destination to overwrite with elt578* @return object that was replaced or NULL if index is not found579*/580ucl_object_t *581ucl_array_replace_index (ucl_object_t *top, ucl_object_t *elt,582unsigned int index);583584/**585* Append a element to another element forming an implicit array586* @param head head to append (may be NULL)587* @param elt new element588* @return the new implicit array589*/590UCL_EXTERN ucl_object_t * ucl_elt_append (ucl_object_t *head,591ucl_object_t *elt);592593/**594* Converts an object to double value595* @param obj CL object596* @param target target double variable597* @return true if conversion was successful598*/599UCL_EXTERN bool ucl_object_todouble_safe (const ucl_object_t *obj, double *target);600601/**602* Unsafe version of \ref ucl_obj_todouble_safe603* @param obj CL object604* @return double value605*/606UCL_EXTERN double ucl_object_todouble (const ucl_object_t *obj);607608/**609* Converts an object to integer value610* @param obj CL object611* @param target target integer variable612* @return true if conversion was successful613*/614UCL_EXTERN bool ucl_object_toint_safe (const ucl_object_t *obj, int64_t *target);615616/**617* Unsafe version of \ref ucl_obj_toint_safe618* @param obj CL object619* @return int value620*/621UCL_EXTERN int64_t ucl_object_toint (const ucl_object_t *obj);622623/**624* Converts an object to boolean value625* @param obj CL object626* @param target target boolean variable627* @return true if conversion was successful628*/629UCL_EXTERN bool ucl_object_toboolean_safe (const ucl_object_t *obj, bool *target);630631/**632* Unsafe version of \ref ucl_obj_toboolean_safe633* @param obj CL object634* @return boolean value635*/636UCL_EXTERN bool ucl_object_toboolean (const ucl_object_t *obj);637638/**639* Converts an object to string value640* @param obj CL object641* @param target target string variable, no need to free value642* @return true if conversion was successful643*/644UCL_EXTERN bool ucl_object_tostring_safe (const ucl_object_t *obj, const char **target);645646/**647* Unsafe version of \ref ucl_obj_tostring_safe648* @param obj CL object649* @return string value650*/651UCL_EXTERN const char* ucl_object_tostring (const ucl_object_t *obj);652653/**654* Convert any object to a string in JSON notation if needed655* @param obj CL object656* @return string value657*/658UCL_EXTERN const char* ucl_object_tostring_forced (const ucl_object_t *obj);659660/**661* Return string as char * and len, string may be not zero terminated, more efficient that \ref ucl_obj_tostring as it662* allows zero-copy (if #UCL_PARSER_ZEROCOPY has been used during parsing)663* @param obj CL object664* @param target target string variable, no need to free value665* @param tlen target length666* @return true if conversion was successful667*/668UCL_EXTERN bool ucl_object_tolstring_safe (const ucl_object_t *obj,669const char **target, size_t *tlen);670671/**672* Unsafe version of \ref ucl_obj_tolstring_safe673* @param obj CL object674* @return string value675*/676UCL_EXTERN const char* ucl_object_tolstring (const ucl_object_t *obj, size_t *tlen);677678/**679* Return object identified by a key in the specified object680* @param obj object to get a key from (must be of type UCL_OBJECT)681* @param key key to search682* @return object matching the specified key or NULL if key was not found683*/684UCL_EXTERN const ucl_object_t* ucl_object_lookup (const ucl_object_t *obj,685const char *key);686#define ucl_object_find_key ucl_object_lookup687688/**689* Return object identified by a key in the specified object, if the first key is690* not found then look for the next one. This process is repeated unless691* the next argument in the list is not NULL. So, `ucl_object_find_any_key(obj, key, NULL)`692* is equal to `ucl_object_find_key(obj, key)`693* @param obj object to get a key from (must be of type UCL_OBJECT)694* @param key key to search695* @param ... list of alternative keys to search (NULL terminated)696* @return object matching the specified key or NULL if key was not found697*/698UCL_EXTERN const ucl_object_t* ucl_object_lookup_any (const ucl_object_t *obj,699const char *key, ...);700#define ucl_object_find_any_key ucl_object_lookup_any701702/**703* Return object identified by a fixed size key in the specified object704* @param obj object to get a key from (must be of type UCL_OBJECT)705* @param key key to search706* @param klen length of a key707* @return object matching the specified key or NULL if key was not found708*/709UCL_EXTERN const ucl_object_t* ucl_object_lookup_len (const ucl_object_t *obj,710const char *key, size_t klen);711#define ucl_object_find_keyl ucl_object_lookup_len712713/**714* Return object identified by dot notation string715* @param obj object to search in716* @param path dot.notation.path to the path to lookup. May use numeric .index on arrays717* @return object matched the specified path or NULL if path is not found718*/719UCL_EXTERN const ucl_object_t *ucl_object_lookup_path (const ucl_object_t *obj,720const char *path);721#define ucl_lookup_path ucl_object_lookup_path722723/**724* Return object identified by object notation string using arbitrary delimiter725* @param obj object to search in726* @param path dot.notation.path to the path to lookup. May use numeric .index on arrays727* @param sep the sepatorator to use in place of . (incase keys have . in them)728* @return object matched the specified path or NULL if path is not found729*/730UCL_EXTERN const ucl_object_t *ucl_object_lookup_path_char (const ucl_object_t *obj,731const char *path, char sep);732#define ucl_lookup_path_char ucl_object_lookup_path_char733734/**735* Returns a key of an object as a NULL terminated string736* @param obj CL object737* @return key or NULL if there is no key738*/739UCL_EXTERN const char* ucl_object_key (const ucl_object_t *obj);740741/**742* Returns a key of an object as a fixed size string (may be more efficient)743* @param obj CL object744* @param len target key length745* @return key pointer746*/747UCL_EXTERN const char* ucl_object_keyl (const ucl_object_t *obj, size_t *len);748749/**750* Increase reference count for an object751* @param obj object to ref752* @return the referenced object753*/754UCL_EXTERN ucl_object_t* ucl_object_ref (const ucl_object_t *obj);755756/**757* Free ucl object758* @param obj ucl object to free759*/760UCL_DEPRECATED(UCL_EXTERN void ucl_object_free (ucl_object_t *obj));761762/**763* Decrease reference count for an object764* @param obj object to unref765*/766UCL_EXTERN void ucl_object_unref (ucl_object_t *obj);767768/**769* Compare objects `o1` and `o2`770* @param o1 the first object771* @param o2 the second object772* @return values >0, 0 and <0 if `o1` is more than, equal and less than `o2`.773* The order of comparison:774* 1) Type of objects775* 2) Size of objects776* 3) Content of objects777*/778UCL_EXTERN int ucl_object_compare (const ucl_object_t *o1,779const ucl_object_t *o2);780781/**782* Compare objects `o1` and `o2` useful for sorting783* @param o1 the first object784* @param o2 the second object785* @return values >0, 0 and <0 if `o1` is more than, equal and less than `o2`.786* The order of comparison:787* 1) Type of objects788* 2) Size of objects789* 3) Content of objects790*/791UCL_EXTERN int ucl_object_compare_qsort (const ucl_object_t **o1,792const ucl_object_t **o2);793794/**795* Sort UCL array using `cmp` compare function796* @param ar797* @param cmp798*/799UCL_EXTERN void ucl_object_array_sort (ucl_object_t *ar,800int (*cmp)(const ucl_object_t **o1, const ucl_object_t **o2));801802enum ucl_object_keys_sort_flags {803UCL_SORT_KEYS_DEFAULT = 0,804UCL_SORT_KEYS_ICASE = (1u << 0u),805UCL_SORT_KEYS_RECURSIVE = (1u << 1u),806};807/***808* Sorts keys in object in place809* @param obj810* @param how811*/812UCL_EXTERN void ucl_object_sort_keys (ucl_object_t *obj,813enum ucl_object_keys_sort_flags how);814815/**816* Get the priority for specific UCL object817* @param obj any ucl object818* @return priority of an object819*/820UCL_EXTERN unsigned int ucl_object_get_priority (const ucl_object_t *obj);821822/**823* Set explicit priority of an object.824* @param obj any ucl object825* @param priority new priroity value (only 4 least significant bits are considred)826*/827UCL_EXTERN void ucl_object_set_priority (ucl_object_t *obj,828unsigned int priority);829830/**831* Opaque iterator object832*/833typedef void* ucl_object_iter_t;834835/**836* Get next key from an object837* @param obj object to iterate838* @param iter opaque iterator, must be set to NULL on the first call:839* ucl_object_iter_t it = NULL;840* while ((cur = ucl_iterate_object (obj, &it)) != NULL) ...841* @param ep pointer record exception (such as ENOMEM), could be NULL842* @return the next object or NULL843*/844UCL_EXTERN const ucl_object_t* ucl_object_iterate_with_error (const ucl_object_t *obj,845ucl_object_iter_t *iter, bool expand_values, int *ep);846847#define ucl_iterate_object ucl_object_iterate848#define ucl_object_iterate(ob, it, ev) ucl_object_iterate_with_error((ob), (it), (ev), NULL)849850/**851* Create new safe iterator for the specified object852* @param obj object to iterate853* @return new iterator object that should be used with safe iterators API only854*/855UCL_EXTERN ucl_object_iter_t ucl_object_iterate_new (const ucl_object_t *obj)856UCL_WARN_UNUSED_RESULT;857/**858* Check safe iterator object after performing some operations on it859* (such as ucl_object_iterate_safe()) to see if operation has encountered860* fatal exception while performing that operation (e.g. ENOMEM).861* @param iter opaque iterator862* @return true if exception has occurred, false otherwise863*/864UCL_EXTERN bool ucl_object_iter_chk_excpn(ucl_object_iter_t *it);865866/**867* Reset initialized iterator to a new object868* @param obj new object to iterate869* @return modified iterator object870*/871UCL_EXTERN ucl_object_iter_t ucl_object_iterate_reset (ucl_object_iter_t it,872const ucl_object_t *obj);873874/**875* Get the next object from the `obj`. This function iterates over arrays, objects876* and implicit arrays877* @param iter safe iterator878* @param expand_values expand explicit arrays and objects879* @return the next object in sequence880*/881UCL_EXTERN const ucl_object_t* ucl_object_iterate_safe (ucl_object_iter_t iter,882bool expand_values);883/**884* Iteration type enumerator885*/886enum ucl_iterate_type {887UCL_ITERATE_EXPLICIT = 1 << 0, /**< Iterate just explicit arrays and objects */888UCL_ITERATE_IMPLICIT = 1 << 1, /**< Iterate just implicit arrays */889UCL_ITERATE_BOTH = (1 << 0) | (1 << 1), /**< Iterate both explicit and implicit arrays*/890};891892/**893* Get the next object from the `obj`. This function iterates over arrays, objects894* and implicit arrays if needed895* @param iter safe iterator896* @param897* @return the next object in sequence898*/899UCL_EXTERN const ucl_object_t* ucl_object_iterate_full (ucl_object_iter_t iter,900enum ucl_iterate_type type);901902/**903* Free memory associated with the safe iterator904* @param it safe iterator object905*/906UCL_EXTERN void ucl_object_iterate_free (ucl_object_iter_t it);907908/** @} */909910911/**912* @defgroup parser Parsing functions913* These functions are used to parse UCL objects914*915* @{916*/917918/**919* Macro handler for a parser920* @param data the content of macro921* @param len the length of content922* @param arguments arguments object923* @param ud opaque user data924* @param err error pointer925* @return true if macro has been parsed926*/927typedef bool (*ucl_macro_handler) (const unsigned char *data, size_t len,928const ucl_object_t *arguments,929void* ud);930931/**932* Context dependent macro handler for a parser933* @param data the content of macro934* @param len the length of content935* @param arguments arguments object936* @param context previously parsed context937* @param ud opaque user data938* @param err error pointer939* @return true if macro has been parsed940*/941typedef bool (*ucl_context_macro_handler) (const unsigned char *data, size_t len,942const ucl_object_t *arguments,943const ucl_object_t *context,944void* ud);945946/* Opaque parser */947struct ucl_parser;948949/**950* Creates new parser object951* @param pool pool to allocate memory from952* @return new parser object953*/954UCL_EXTERN struct ucl_parser* ucl_parser_new (int flags);955956/**957* Sets the default priority for the parser applied to chunks that do not958* specify priority explicitly959* @param parser parser object960* @param prio default priority (0 .. 16)961* @return true if parser's default priority was set962*/963UCL_EXTERN bool ucl_parser_set_default_priority (struct ucl_parser *parser,964unsigned prio);965/**966* Gets the default priority for the parser applied to chunks that do not967* specify priority explicitly968* @param parser parser object969* @return true default priority (0 .. 16), -1 for failure970*/971UCL_EXTERN int ucl_parser_get_default_priority (struct ucl_parser *parser);972973/**974* Register new handler for a macro975* @param parser parser object976* @param macro macro name (without leading dot)977* @param handler handler (it is called immediately after macro is parsed)978* @param ud opaque user data for a handler979* @return true on success, false on failure (i.e. ENOMEM)980*/981UCL_EXTERN bool ucl_parser_register_macro (struct ucl_parser *parser,982const char *macro,983ucl_macro_handler handler, void* ud);984985/**986* Register new context dependent handler for a macro987* @param parser parser object988* @param macro macro name (without leading dot)989* @param handler handler (it is called immediately after macro is parsed)990* @param ud opaque user data for a handler991* @return true on success, false on failure (i.e. ENOMEM)992*/993UCL_EXTERN bool ucl_parser_register_context_macro (struct ucl_parser *parser,994const char *macro,995ucl_context_macro_handler handler,996void* ud);997998/**999* Handler to detect unregistered variables1000* @param data variable data1001* @param len length of variable1002* @param replace (out) replace value for variable1003* @param replace_len (out) replace length for variable1004* @param need_free (out) UCL will free `dest` after usage1005* @param ud opaque userdata1006* @return true if variable1007*/1008typedef bool (*ucl_variable_handler) (const unsigned char *data, size_t len,1009unsigned char **replace, size_t *replace_len, bool *need_free, void* ud);10101011/**1012* Register new parser variable1013* @param parser parser object1014* @param var variable name1015* @param value variable value1016*/1017UCL_EXTERN void ucl_parser_register_variable (struct ucl_parser *parser, const char *var,1018const char *value);10191020/**1021* Set handler for unknown variables1022* @param parser parser structure1023* @param handler desired handler1024* @param ud opaque data for the handler1025*/1026UCL_EXTERN void ucl_parser_set_variables_handler (struct ucl_parser *parser,1027ucl_variable_handler handler, void *ud);10281029/**1030* Load new chunk to a parser1031* @param parser parser structure1032* @param data the pointer to the beginning of a chunk1033* @param len the length of a chunk1034* @return true if chunk has been added and false in case of error1035*/1036UCL_EXTERN bool ucl_parser_add_chunk (struct ucl_parser *parser,1037const unsigned char *data, size_t len);10381039/**1040* Load new chunk to a parser with the specified priority1041* @param parser parser structure1042* @param data the pointer to the beginning of a chunk1043* @param len the length of a chunk1044* @param priority the desired priority of a chunk (only 4 least significant bits1045* are considered for this parameter)1046* @return true if chunk has been added and false in case of error1047*/1048UCL_EXTERN bool ucl_parser_add_chunk_priority (struct ucl_parser *parser,1049const unsigned char *data, size_t len, unsigned priority);10501051/**1052* Insert new chunk to a parser (must have previously processed data with an existing top object)1053* @param parser parser structure1054* @param data the pointer to the beginning of a chunk1055* @param len the length of a chunk1056* @return true if chunk has been added and false in case of error1057*/1058UCL_EXTERN bool ucl_parser_insert_chunk (struct ucl_parser *parser,1059const unsigned char *data, size_t len);10601061/**1062* Full version of ucl_add_chunk with priority and duplicate strategy1063* @param parser parser structure1064* @param data the pointer to the beginning of a chunk1065* @param len the length of a chunk1066* @param priority the desired priority of a chunk (only 4 least significant bits1067* are considered for this parameter)1068* @param strat duplicates merging strategy1069* @param parse_type input format1070* @return true if chunk has been added and false in case of error1071*/1072UCL_EXTERN bool ucl_parser_add_chunk_full (struct ucl_parser *parser,1073const unsigned char *data, size_t len, unsigned priority,1074enum ucl_duplicate_strategy strat, enum ucl_parse_type parse_type);10751076/**1077* Load ucl object from a string1078* @param parser parser structure1079* @param data the pointer to the string1080* @param len the length of the string, if `len` is 0 then `data` must be zero-terminated string1081* @return true if string has been added and false in case of error1082*/1083UCL_EXTERN bool ucl_parser_add_string (struct ucl_parser *parser,1084const char *data, size_t len);10851086/**1087* Load ucl object from a string1088* @param parser parser structure1089* @param data the pointer to the string1090* @param len the length of the string, if `len` is 0 then `data` must be zero-terminated string1091* @param priority the desired priority of a chunk (only 4 least significant bits1092* are considered for this parameter)1093* @return true if string has been added and false in case of error1094*/1095UCL_EXTERN bool ucl_parser_add_string_priority (struct ucl_parser *parser,1096const char *data, size_t len, unsigned priority);10971098/**1099* Load and add data from a file1100* @param parser parser structure1101* @param filename the name of file1102* @param err if *err is NULL it is set to parser error1103* @return true if chunk has been added and false in case of error1104*/1105UCL_EXTERN bool ucl_parser_add_file (struct ucl_parser *parser,1106const char *filename);11071108/**1109* Load and add data from a file1110* @param parser parser structure1111* @param filename the name of file1112* @param err if *err is NULL it is set to parser error1113* @param priority the desired priority of a chunk (only 4 least significant bits1114* are considered for this parameter)1115* @return true if chunk has been added and false in case of error1116*/1117UCL_EXTERN bool ucl_parser_add_file_priority (struct ucl_parser *parser,1118const char *filename, unsigned priority);11191120/**1121* Load and add data from a file1122* @param parser parser structure1123* @param filename the name of file1124* @param priority the desired priority of a chunk (only 4 least significant bits1125* are considered for this parameter)1126* @param strat Merge strategy to use while parsing this file1127* @param parse_type Parser type to use while parsing this file1128* @return true if chunk has been added and false in case of error1129*/1130UCL_EXTERN bool ucl_parser_add_file_full (struct ucl_parser *parser, const char *filename,1131unsigned priority, enum ucl_duplicate_strategy strat,1132enum ucl_parse_type parse_type);11331134/**1135* Load and add data from a file descriptor1136* @param parser parser structure1137* @param filename the name of file1138* @param err if *err is NULL it is set to parser error1139* @return true if chunk has been added and false in case of error1140*/1141UCL_EXTERN bool ucl_parser_add_fd (struct ucl_parser *parser,1142int fd);11431144/**1145* Load and add data from a file descriptor1146* @param parser parser structure1147* @param filename the name of file1148* @param err if *err is NULL it is set to parser error1149* @param priority the desired priority of a chunk (only 4 least significant bits1150* are considered for this parameter)1151* @return true if chunk has been added and false in case of error1152*/1153UCL_EXTERN bool ucl_parser_add_fd_priority (struct ucl_parser *parser,1154int fd, unsigned priority);11551156/**1157* Load and add data from a file descriptor1158* @param parser parser structure1159* @param filename the name of file1160* @param err if *err is NULL it is set to parser error1161* @param priority the desired priority of a chunk (only 4 least significant bits1162* are considered for this parameter)1163* @param strat Merge strategy to use while parsing this file1164* @param parse_type Parser type to use while parsing this file1165* @return true if chunk has been added and false in case of error1166*/1167UCL_EXTERN bool ucl_parser_add_fd_full (struct ucl_parser *parser, int fd,1168unsigned priority, enum ucl_duplicate_strategy strat,1169enum ucl_parse_type parse_type);11701171/**1172* Provide a UCL_ARRAY of paths to search for include files. The object is1173* copied so caller must unref the object.1174* @param parser parser structure1175* @param paths UCL_ARRAY of paths to search1176* @return true if the path search array was replaced in the parser1177*/1178UCL_EXTERN bool ucl_set_include_path (struct ucl_parser *parser,1179ucl_object_t *paths);11801181/**1182* Get a top object for a parser (refcount is increased)1183* @param parser parser structure1184* @param err if *err is NULL it is set to parser error1185* @return top parser object or NULL1186*/1187UCL_EXTERN ucl_object_t* ucl_parser_get_object (struct ucl_parser *parser);11881189/**1190* Get the current stack object as stack accessor function for use in macro1191* functions (refcount is increased)1192* @param parser parser object1193* @param depth depth of stack to retrieve (top is 0)1194* @return current stack object or NULL1195*/1196UCL_EXTERN ucl_object_t* ucl_parser_get_current_stack_object (struct ucl_parser *parser, unsigned int depth);11971198/**1199* Peek at the character at the current chunk position1200* @param parser parser structure1201* @return current chunk position character1202*/1203UCL_EXTERN unsigned char ucl_parser_chunk_peek (struct ucl_parser *parser);12041205/**1206* Skip the character at the current chunk position1207* @param parser parser structure1208* @return success boolean1209*/1210UCL_EXTERN bool ucl_parser_chunk_skip (struct ucl_parser *parser);12111212/**1213* Get the error string if parsing has been failed1214* @param parser parser object1215* @return error description1216*/1217UCL_EXTERN const char *ucl_parser_get_error (struct ucl_parser *parser);12181219/**1220* Get the code of the last error1221* @param parser parser object1222* @return error code1223*/1224UCL_EXTERN int ucl_parser_get_error_code (struct ucl_parser *parser);12251226/**1227* Get the current column number within parser1228* @param parser parser object1229* @return current column number1230*/1231UCL_EXTERN unsigned ucl_parser_get_column (struct ucl_parser *parser);12321233/**1234* Get the current line number within parser1235* @param parser parser object1236* @return current line number1237*/1238UCL_EXTERN unsigned ucl_parser_get_linenum (struct ucl_parser *parser);12391240/**1241* Clear the error in the parser1242* @param parser parser object1243*/1244UCL_EXTERN void ucl_parser_clear_error (struct ucl_parser *parser);12451246/**1247* Free ucl parser object1248* @param parser parser object1249*/1250UCL_EXTERN void ucl_parser_free (struct ucl_parser *parser);12511252/**1253* Get constant opaque pointer to comments structure for this parser. Increase1254* refcount to prevent this object to be destroyed on parser's destruction1255* @param parser parser structure1256* @return ucl comments pointer or NULL1257*/1258UCL_EXTERN const ucl_object_t * ucl_parser_get_comments (struct ucl_parser *parser);12591260/**1261* Utility function to find a comment object for the specified object in the input1262* @param comments comments object1263* @param srch search object1264* @return string comment enclosed in ucl_object_t1265*/1266UCL_EXTERN const ucl_object_t * ucl_comments_find (const ucl_object_t *comments,1267const ucl_object_t *srch);12681269/**1270* Move comment from `from` object to `to` object1271* @param comments comments object1272* @param what source object1273* @param with destination object1274* @return `true` if `from` has comment and it has been moved to `to`1275*/1276UCL_EXTERN bool ucl_comments_move (ucl_object_t *comments,1277const ucl_object_t *from, const ucl_object_t *to);12781279/**1280* Adds a new comment for an object1281* @param comments comments object1282* @param obj object to add comment to1283* @param comment string representation of a comment1284*/1285UCL_EXTERN void ucl_comments_add (ucl_object_t *comments,1286const ucl_object_t *obj, const char *comment);12871288/**1289* Add new public key to parser for signatures check1290* @param parser parser object1291* @param key PEM representation of a key1292* @param len length of the key1293* @param err if *err is NULL it is set to parser error1294* @return true if a key has been successfully added1295*/1296UCL_EXTERN bool ucl_parser_pubkey_add (struct ucl_parser *parser,1297const unsigned char *key, size_t len);12981299/**1300* Set FILENAME and CURDIR variables in parser1301* @param parser parser object1302* @param filename filename to set or NULL to set FILENAME to "undef" and CURDIR to getcwd()1303* @param need_expand perform realpath() if this variable is true and filename is not NULL1304* @return true if variables has been set1305*/1306UCL_EXTERN bool ucl_parser_set_filevars (struct ucl_parser *parser, const char *filename,1307bool need_expand);13081309/**1310* Returns current file for the parser1311* @param parser parser object1312* @return current file or NULL if parsing memory1313*/1314UCL_EXTERN const char *ucl_parser_get_cur_file (struct ucl_parser *parser);13151316/**1317* Defines special handler for certain types of data (identified by magic)1318*/1319typedef bool (*ucl_parser_special_handler_t) (struct ucl_parser *parser,1320const unsigned char *source, size_t source_len,1321unsigned char **destination, size_t *dest_len,1322void *user_data);13231324/**1325* Special handler flags1326*/1327enum ucl_special_handler_flags {1328UCL_SPECIAL_HANDLER_DEFAULT = 0,1329UCL_SPECIAL_HANDLER_PREPROCESS_ALL = (1u << 0),1330};13311332/**1333* Special handler structure1334*/1335struct ucl_parser_special_handler {1336const unsigned char *magic;1337size_t magic_len;1338enum ucl_special_handler_flags flags;1339ucl_parser_special_handler_t handler;1340void (*free_function) (unsigned char *data, size_t len, void *user_data);1341void *user_data;1342struct ucl_parser_special_handler *next; /* Used internally */1343};13441345/**1346* Add special handler for a parser, handles special sequences identified by magic1347* @param parser parser structure1348* @param handler handler structure1349*/1350UCL_EXTERN void ucl_parser_add_special_handler (struct ucl_parser *parser,1351struct ucl_parser_special_handler *handler);13521353/**1354* Handler for include traces:1355* @param parser parser object1356* @param parent where include is done from1357* @param args arguments to an include1358* @param path path of the include1359* @param pathlen length of the path1360* @param user_data opaque userdata1361*/1362typedef void (ucl_include_trace_func_t) (struct ucl_parser *parser,1363const ucl_object_t *parent,1364const ucl_object_t *args,1365const char *path,1366size_t pathlen,1367void *user_data);13681369/**1370* Register trace function for an include handler1371* @param parser parser object1372* @param func function to trace includes1373* @param user_data opaque data1374*/1375UCL_EXTERN void ucl_parser_set_include_tracer (struct ucl_parser *parser,1376ucl_include_trace_func_t func,1377void *user_data);13781379/** @} */13801381/**1382* @defgroup emitter Emitting functions1383* These functions are used to serialise UCL objects to some string representation.1384*1385* @{1386*/13871388struct ucl_emitter_context;1389/**1390* Structure using for emitter callbacks1391*/1392struct ucl_emitter_functions {1393/** Append a single character */1394int (*ucl_emitter_append_character) (unsigned char c, size_t nchars, void *ud);1395/** Append a string of a specified length */1396int (*ucl_emitter_append_len) (unsigned const char *str, size_t len, void *ud);1397/** Append a 64 bit integer */1398int (*ucl_emitter_append_int) (int64_t elt, void *ud);1399/** Append floating point element */1400int (*ucl_emitter_append_double) (double elt, void *ud);1401/** Free userdata */1402void (*ucl_emitter_free_func)(void *ud);1403/** Opaque userdata pointer */1404void *ud;1405};14061407struct ucl_emitter_operations {1408/** Write a primitive element */1409void (*ucl_emitter_write_elt) (struct ucl_emitter_context *ctx,1410const ucl_object_t *obj, bool first, bool print_key);1411/** Start ucl object */1412void (*ucl_emitter_start_object) (struct ucl_emitter_context *ctx,1413const ucl_object_t *obj, bool first, bool print_key);1414/** End ucl object */1415void (*ucl_emitter_end_object) (struct ucl_emitter_context *ctx,1416const ucl_object_t *obj);1417/** Start ucl array */1418void (*ucl_emitter_start_array) (struct ucl_emitter_context *ctx,1419const ucl_object_t *obj, bool first, bool print_key);1420void (*ucl_emitter_end_array) (struct ucl_emitter_context *ctx,1421const ucl_object_t *obj);1422};14231424/**1425* Structure that defines emitter functions1426*/1427struct ucl_emitter_context {1428/** Name of emitter (e.g. json, compact_json) */1429const char *name;1430/** Unique id (e.g. UCL_EMIT_JSON for standard emitters */1431int id;1432/** A set of output functions */1433const struct ucl_emitter_functions *func;1434/** A set of output operations */1435const struct ucl_emitter_operations *ops;1436/** Current amount of indent tabs */1437unsigned int indent;1438/** Top level object */1439const ucl_object_t *top;1440/** Optional comments */1441const ucl_object_t *comments;1442};14431444/**1445* Emit object to a string1446* @param obj object1447* @param emit_type if type is #UCL_EMIT_JSON then emit json, if type is1448* #UCL_EMIT_CONFIG then emit config like object1449* @return dump of an object (must be freed after using) or NULL in case of error1450*/1451UCL_EXTERN unsigned char *ucl_object_emit (const ucl_object_t *obj,1452enum ucl_emitter emit_type);14531454/**1455* Emit object to a string that can contain `\0` inside1456* @param obj object1457* @param emit_type if type is #UCL_EMIT_JSON then emit json, if type is1458* #UCL_EMIT_CONFIG then emit config like object1459* @param len the resulting length1460* @return dump of an object (must be freed after using) or NULL in case of error1461*/1462UCL_EXTERN unsigned char *ucl_object_emit_len (const ucl_object_t *obj,1463enum ucl_emitter emit_type, size_t *len);14641465/**1466* Emit object to a string1467* @param obj object1468* @param emit_type if type is #UCL_EMIT_JSON then emit json, if type is1469* #UCL_EMIT_CONFIG then emit config like object1470* @param emitter a set of emitter functions1471* @param comments optional comments for the parser1472* @return dump of an object (must be freed after using) or NULL in case of error1473*/1474UCL_EXTERN bool ucl_object_emit_full (const ucl_object_t *obj,1475enum ucl_emitter emit_type,1476struct ucl_emitter_functions *emitter,1477const ucl_object_t *comments);14781479/**1480* Start streamlined UCL object emitter1481* @param obj top UCL object1482* @param emit_type emit type1483* @param emitter a set of emitter functions1484* @return new streamlined context that should be freed by1485* `ucl_object_emit_streamline_finish`1486*/1487UCL_EXTERN struct ucl_emitter_context* ucl_object_emit_streamline_new (1488const ucl_object_t *obj, enum ucl_emitter emit_type,1489struct ucl_emitter_functions *emitter);14901491/**1492* Start object or array container for the streamlined output1493* @param ctx streamlined context1494* @param obj container object1495*/1496UCL_EXTERN void ucl_object_emit_streamline_start_container (1497struct ucl_emitter_context *ctx, const ucl_object_t *obj);1498/**1499* Add a complete UCL object to streamlined output1500* @param ctx streamlined context1501* @param obj object to output1502*/1503UCL_EXTERN void ucl_object_emit_streamline_add_object (1504struct ucl_emitter_context *ctx, const ucl_object_t *obj);1505/**1506* End previously added container1507* @param ctx streamlined context1508*/1509UCL_EXTERN void ucl_object_emit_streamline_end_container (1510struct ucl_emitter_context *ctx);1511/**1512* Terminate streamlined container finishing all containers in it1513* @param ctx streamlined context1514*/1515UCL_EXTERN void ucl_object_emit_streamline_finish (1516struct ucl_emitter_context *ctx);15171518/**1519* Returns functions to emit object to memory1520* @param pmem target pointer (should be freed by caller)1521* @return emitter functions structure1522*/1523UCL_EXTERN struct ucl_emitter_functions* ucl_object_emit_memory_funcs (1524void **pmem);15251526/**1527* Returns functions to emit object to FILE *1528* @param fp FILE * object1529* @return emitter functions structure1530*/1531UCL_EXTERN struct ucl_emitter_functions* ucl_object_emit_file_funcs (1532FILE *fp);1533/**1534* Returns functions to emit object to a file descriptor1535* @param fd file descriptor1536* @return emitter functions structure1537*/1538UCL_EXTERN struct ucl_emitter_functions* ucl_object_emit_fd_funcs (1539int fd);15401541/**1542* Free emitter functions1543* @param f pointer to functions1544*/1545UCL_EXTERN void ucl_object_emit_funcs_free (struct ucl_emitter_functions *f);15461547/** @} */15481549/**1550* @defgroup schema Schema functions1551* These functions are used to validate UCL objects using json schema format1552*1553* @{1554*/15551556/**1557* Used to define UCL schema error1558*/1559enum ucl_schema_error_code {1560UCL_SCHEMA_OK = 0, /**< no error */1561UCL_SCHEMA_TYPE_MISMATCH, /**< type of object is incorrect */1562UCL_SCHEMA_INVALID_SCHEMA, /**< schema is invalid */1563UCL_SCHEMA_MISSING_PROPERTY,/**< one or more missing properties */1564UCL_SCHEMA_CONSTRAINT, /**< constraint found */1565UCL_SCHEMA_MISSING_DEPENDENCY, /**< missing dependency */1566UCL_SCHEMA_EXTERNAL_REF_MISSING, /**< cannot fetch external ref */1567UCL_SCHEMA_EXTERNAL_REF_INVALID, /**< invalid external ref */1568UCL_SCHEMA_INTERNAL_ERROR, /**< something bad happened */1569UCL_SCHEMA_UNKNOWN /**< generic error */1570};15711572/**1573* Generic ucl schema error1574*/1575struct ucl_schema_error {1576enum ucl_schema_error_code code; /**< error code */1577char msg[128]; /**< error message */1578const ucl_object_t *obj; /**< object where error occurred */1579};15801581/**1582* Validate object `obj` using schema object `schema`.1583* @param schema schema object1584* @param obj object to validate1585* @param err error pointer, if this parameter is not NULL and error has been1586* occurred, then `err` is filled with the exact error definition.1587* @return true if `obj` is valid using `schema`1588*/1589UCL_EXTERN bool ucl_object_validate (const ucl_object_t *schema,1590const ucl_object_t *obj, struct ucl_schema_error *err);15911592/**1593* Validate object `obj` using schema object `schema` and root schema at `root`.1594* @param schema schema object1595* @param obj object to validate1596* @param root root schema object1597* @param err error pointer, if this parameter is not NULL and error has been1598* occurred, then `err` is filled with the exact error definition.1599* @return true if `obj` is valid using `schema`1600*/1601UCL_EXTERN bool ucl_object_validate_root (const ucl_object_t *schema,1602const ucl_object_t *obj,1603const ucl_object_t *root,1604struct ucl_schema_error *err);16051606/**1607* Validate object `obj` using schema object `schema` and root schema at `root`1608* using some external references provided.1609* @param schema schema object1610* @param obj object to validate1611* @param root root schema object1612* @param ext_refs external references (might be modified during validation)1613* @param err error pointer, if this parameter is not NULL and error has been1614* occurred, then `err` is filled with the exact error definition.1615* @return true if `obj` is valid using `schema`1616*/1617UCL_EXTERN bool ucl_object_validate_root_ext (const ucl_object_t *schema,1618const ucl_object_t *obj,1619const ucl_object_t *root,1620ucl_object_t *ext_refs,1621struct ucl_schema_error *err);16221623/** @} */16241625#ifdef __cplusplus1626}1627#endif1628/*1629* XXX: Poorly named API functions, need to replace them with the appropriate1630* named function. All API functions *must* use naming ucl_object_*. Usage of1631* ucl_obj* should be avoided.1632*/1633#define ucl_obj_todouble_safe ucl_object_todouble_safe1634#define ucl_obj_todouble ucl_object_todouble1635#define ucl_obj_tostring ucl_object_tostring1636#define ucl_obj_tostring_safe ucl_object_tostring_safe1637#define ucl_obj_tolstring ucl_object_tolstring1638#define ucl_obj_tolstring_safe ucl_object_tolstring_safe1639#define ucl_obj_toint ucl_object_toint1640#define ucl_obj_toint_safe ucl_object_toint_safe1641#define ucl_obj_toboolean ucl_object_toboolean1642#define ucl_obj_toboolean_safe ucl_object_toboolean_safe1643#define ucl_obj_get_key ucl_object_find_key1644#define ucl_obj_get_keyl ucl_object_find_keyl1645#define ucl_obj_unref ucl_object_unref1646#define ucl_obj_ref ucl_object_ref1647#define ucl_obj_free ucl_object_free16481649#define UCL_PRIORITY_MIN 01650#define UCL_PRIORITY_MAX 1516511652#endif /* UCL_H_ */165316541655