1c99fb5f9SBaptiste Daroussin /* Copyright (c) 2013, Vsevolod Stakhov 2c99fb5f9SBaptiste Daroussin * All rights reserved. 3c99fb5f9SBaptiste Daroussin * 4c99fb5f9SBaptiste Daroussin * Redistribution and use in source and binary forms, with or without 5c99fb5f9SBaptiste Daroussin * modification, are permitted provided that the following conditions are met: 6c99fb5f9SBaptiste Daroussin * * Redistributions of source code must retain the above copyright 7c99fb5f9SBaptiste Daroussin * notice, this list of conditions and the following disclaimer. 8c99fb5f9SBaptiste Daroussin * * Redistributions in binary form must reproduce the above copyright 9c99fb5f9SBaptiste Daroussin * notice, this list of conditions and the following disclaimer in the 10c99fb5f9SBaptiste Daroussin * documentation and/or other materials provided with the distribution. 11c99fb5f9SBaptiste Daroussin * 12c99fb5f9SBaptiste Daroussin * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY 13c99fb5f9SBaptiste Daroussin * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 14c99fb5f9SBaptiste Daroussin * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 15c99fb5f9SBaptiste Daroussin * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY 16c99fb5f9SBaptiste Daroussin * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 17c99fb5f9SBaptiste Daroussin * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 18c99fb5f9SBaptiste Daroussin * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 19c99fb5f9SBaptiste Daroussin * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 20c99fb5f9SBaptiste Daroussin * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 21c99fb5f9SBaptiste Daroussin * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 22c99fb5f9SBaptiste Daroussin */ 23c99fb5f9SBaptiste Daroussin 24c99fb5f9SBaptiste Daroussin #ifndef UCL_H_ 25c99fb5f9SBaptiste Daroussin #define UCL_H_ 26c99fb5f9SBaptiste Daroussin 27c99fb5f9SBaptiste Daroussin #include <string.h> 28c99fb5f9SBaptiste Daroussin #include <stddef.h> 29c99fb5f9SBaptiste Daroussin #include <stdlib.h> 30c99fb5f9SBaptiste Daroussin #include <stdint.h> 31c99fb5f9SBaptiste Daroussin #include <stdbool.h> 32c99fb5f9SBaptiste Daroussin #include <stdarg.h> 33c99fb5f9SBaptiste Daroussin #include <stdio.h> 34c99fb5f9SBaptiste Daroussin 3536c53d67SBaptiste Daroussin #ifdef _WIN32 3636c53d67SBaptiste Daroussin # define UCL_EXTERN __declspec(dllexport) 3736c53d67SBaptiste Daroussin #else 3836c53d67SBaptiste Daroussin # define UCL_EXTERN 3936c53d67SBaptiste Daroussin #endif 4036c53d67SBaptiste Daroussin 41c99fb5f9SBaptiste Daroussin /** 42c99fb5f9SBaptiste Daroussin * @mainpage 43c99fb5f9SBaptiste Daroussin * This is a reference manual for UCL API. You may find the description of UCL format by following this 44c99fb5f9SBaptiste Daroussin * [github repository](https://github.com/vstakhov/libucl). 45c99fb5f9SBaptiste Daroussin * 46c99fb5f9SBaptiste Daroussin * This manual has several main sections: 47c99fb5f9SBaptiste Daroussin * - @ref structures 48c99fb5f9SBaptiste Daroussin * - @ref utils 49c99fb5f9SBaptiste Daroussin * - @ref parser 50c99fb5f9SBaptiste Daroussin * - @ref emitter 51c99fb5f9SBaptiste Daroussin */ 52c99fb5f9SBaptiste Daroussin 53c99fb5f9SBaptiste Daroussin /** 54c99fb5f9SBaptiste Daroussin * @file ucl.h 55c99fb5f9SBaptiste Daroussin * @brief UCL parsing and emitting functions 56c99fb5f9SBaptiste Daroussin * 57c99fb5f9SBaptiste Daroussin * UCL is universal configuration language, which is a form of 58c99fb5f9SBaptiste Daroussin * JSON with less strict rules that make it more comfortable for 59c99fb5f9SBaptiste Daroussin * using as a configuration language 60c99fb5f9SBaptiste Daroussin */ 61c99fb5f9SBaptiste Daroussin #ifdef __cplusplus 62c99fb5f9SBaptiste Daroussin extern "C" { 63c99fb5f9SBaptiste Daroussin #endif 64c99fb5f9SBaptiste Daroussin /* 65c99fb5f9SBaptiste Daroussin * Memory allocation utilities 66c99fb5f9SBaptiste Daroussin * UCL_ALLOC(size) - allocate memory for UCL 67c99fb5f9SBaptiste Daroussin * UCL_FREE(size, ptr) - free memory of specified size at ptr 68c99fb5f9SBaptiste Daroussin * Default: malloc and free 69c99fb5f9SBaptiste Daroussin */ 70c99fb5f9SBaptiste Daroussin #ifndef UCL_ALLOC 71c99fb5f9SBaptiste Daroussin #define UCL_ALLOC(size) malloc(size) 72c99fb5f9SBaptiste Daroussin #endif 73c99fb5f9SBaptiste Daroussin #ifndef UCL_FREE 74c99fb5f9SBaptiste Daroussin #define UCL_FREE(size, ptr) free(ptr) 75c99fb5f9SBaptiste Daroussin #endif 76c99fb5f9SBaptiste Daroussin 77c99fb5f9SBaptiste Daroussin #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) 78c99fb5f9SBaptiste Daroussin #define UCL_WARN_UNUSED_RESULT \ 79c99fb5f9SBaptiste Daroussin __attribute__((warn_unused_result)) 80c99fb5f9SBaptiste Daroussin #else 81c99fb5f9SBaptiste Daroussin #define UCL_WARN_UNUSED_RESULT 82c99fb5f9SBaptiste Daroussin #endif 83c99fb5f9SBaptiste Daroussin 84*b04a7a0bSBaptiste Daroussin #ifdef __GNUC__ 85*b04a7a0bSBaptiste Daroussin #define UCL_DEPRECATED(func) func __attribute__ ((deprecated)) 86*b04a7a0bSBaptiste Daroussin #elif defined(_MSC_VER) 87*b04a7a0bSBaptiste Daroussin #define UCL_DEPRECATED(func) __declspec(deprecated) func 88*b04a7a0bSBaptiste Daroussin #else 89*b04a7a0bSBaptiste Daroussin #define UCL_DEPRECATED(func) func 90*b04a7a0bSBaptiste Daroussin #endif 91*b04a7a0bSBaptiste Daroussin 92c99fb5f9SBaptiste Daroussin /** 93c99fb5f9SBaptiste Daroussin * @defgroup structures Structures and types 94c99fb5f9SBaptiste Daroussin * UCL defines several enumeration types used for error reporting or specifying flags and attributes. 95c99fb5f9SBaptiste Daroussin * 96c99fb5f9SBaptiste Daroussin * @{ 97c99fb5f9SBaptiste Daroussin */ 98c99fb5f9SBaptiste Daroussin 99c99fb5f9SBaptiste Daroussin /** 100c99fb5f9SBaptiste Daroussin * The common error codes returned by ucl parser 101c99fb5f9SBaptiste Daroussin */ 102c99fb5f9SBaptiste Daroussin typedef enum ucl_error { 103c99fb5f9SBaptiste Daroussin UCL_EOK = 0, /**< No error */ 104c99fb5f9SBaptiste Daroussin UCL_ESYNTAX, /**< Syntax error occurred during parsing */ 105c99fb5f9SBaptiste Daroussin UCL_EIO, /**< IO error occurred during parsing */ 106c99fb5f9SBaptiste Daroussin UCL_ESTATE, /**< Invalid state machine state */ 107c99fb5f9SBaptiste Daroussin UCL_ENESTED, /**< Input has too many recursion levels */ 108c99fb5f9SBaptiste Daroussin UCL_EMACRO, /**< Error processing a macro */ 109c99fb5f9SBaptiste Daroussin UCL_EINTERNAL, /**< Internal unclassified error */ 110c99fb5f9SBaptiste Daroussin UCL_ESSL /**< SSL error */ 111c99fb5f9SBaptiste Daroussin } ucl_error_t; 112c99fb5f9SBaptiste Daroussin 113c99fb5f9SBaptiste Daroussin /** 114c99fb5f9SBaptiste Daroussin * #ucl_object_t may have one of specified types, some types are compatible with each other and some are not. 115c99fb5f9SBaptiste Daroussin * For example, you can always convert #UCL_TIME to #UCL_FLOAT. Also you can convert #UCL_FLOAT to #UCL_INTEGER 116c99fb5f9SBaptiste Daroussin * by loosing floating point. Every object may be converted to a string by #ucl_object_tostring_forced() function. 117c99fb5f9SBaptiste Daroussin * 118c99fb5f9SBaptiste Daroussin */ 119c99fb5f9SBaptiste Daroussin typedef enum ucl_type { 120c99fb5f9SBaptiste Daroussin UCL_OBJECT = 0, /**< UCL object - key/value pairs */ 121c99fb5f9SBaptiste Daroussin UCL_ARRAY, /**< UCL array */ 122c99fb5f9SBaptiste Daroussin UCL_INT, /**< Integer number */ 123c99fb5f9SBaptiste Daroussin UCL_FLOAT, /**< Floating point number */ 124c99fb5f9SBaptiste Daroussin UCL_STRING, /**< Null terminated string */ 125c99fb5f9SBaptiste Daroussin UCL_BOOLEAN, /**< Boolean value */ 126c99fb5f9SBaptiste Daroussin UCL_TIME, /**< Time value (floating point number of seconds) */ 127c99fb5f9SBaptiste Daroussin UCL_USERDATA, /**< Opaque userdata pointer (may be used in macros) */ 128c99fb5f9SBaptiste Daroussin UCL_NULL /**< Null value */ 129c99fb5f9SBaptiste Daroussin } ucl_type_t; 130c99fb5f9SBaptiste Daroussin 131c99fb5f9SBaptiste Daroussin /** 132c99fb5f9SBaptiste Daroussin * You can use one of these types to serialise #ucl_object_t by using ucl_object_emit(). 133c99fb5f9SBaptiste Daroussin */ 134c99fb5f9SBaptiste Daroussin typedef enum ucl_emitter { 135c99fb5f9SBaptiste Daroussin UCL_EMIT_JSON = 0, /**< Emit fine formatted JSON */ 136c99fb5f9SBaptiste Daroussin UCL_EMIT_JSON_COMPACT, /**< Emit compacted JSON */ 137c99fb5f9SBaptiste Daroussin UCL_EMIT_CONFIG, /**< Emit human readable config format */ 138c99fb5f9SBaptiste Daroussin UCL_EMIT_YAML /**< Emit embedded YAML format */ 139c99fb5f9SBaptiste Daroussin } ucl_emitter_t; 140c99fb5f9SBaptiste Daroussin 141c99fb5f9SBaptiste Daroussin /** 142c99fb5f9SBaptiste Daroussin * These flags defines parser behaviour. If you specify #UCL_PARSER_ZEROCOPY you must ensure 143c99fb5f9SBaptiste Daroussin * that the input memory is not freed if an object is in use. Moreover, if you want to use 144c99fb5f9SBaptiste Daroussin * zero-terminated keys and string values then you should not use zero-copy mode, as in this case 145c99fb5f9SBaptiste Daroussin * UCL still has to perform copying implicitly. 146c99fb5f9SBaptiste Daroussin */ 147c99fb5f9SBaptiste Daroussin typedef enum ucl_parser_flags { 148c99fb5f9SBaptiste Daroussin UCL_PARSER_KEY_LOWERCASE = 0x1, /**< Convert all keys to lower case */ 14997bd480fSBaptiste Daroussin UCL_PARSER_ZEROCOPY = 0x2, /**< Parse input in zero-copy mode if possible */ 15097bd480fSBaptiste Daroussin UCL_PARSER_NO_TIME = 0x4 /**< Do not parse time and treat time values as strings */ 151c99fb5f9SBaptiste Daroussin } ucl_parser_flags_t; 152c99fb5f9SBaptiste Daroussin 153c99fb5f9SBaptiste Daroussin /** 154c99fb5f9SBaptiste Daroussin * String conversion flags, that are used in #ucl_object_fromstring_common function. 155c99fb5f9SBaptiste Daroussin */ 156c99fb5f9SBaptiste Daroussin typedef enum ucl_string_flags { 157c99fb5f9SBaptiste Daroussin UCL_STRING_ESCAPE = 0x1, /**< Perform JSON escape */ 158c99fb5f9SBaptiste Daroussin UCL_STRING_TRIM = 0x2, /**< Trim leading and trailing whitespaces */ 159c99fb5f9SBaptiste Daroussin UCL_STRING_PARSE_BOOLEAN = 0x4, /**< Parse passed string and detect boolean */ 160c99fb5f9SBaptiste Daroussin UCL_STRING_PARSE_INT = 0x8, /**< Parse passed string and detect integer number */ 161c99fb5f9SBaptiste Daroussin UCL_STRING_PARSE_DOUBLE = 0x10, /**< Parse passed string and detect integer or float number */ 16297bd480fSBaptiste Daroussin UCL_STRING_PARSE_TIME = 0x20, /**< Parse time strings */ 16397bd480fSBaptiste Daroussin UCL_STRING_PARSE_NUMBER = UCL_STRING_PARSE_INT|UCL_STRING_PARSE_DOUBLE|UCL_STRING_PARSE_TIME, /**< 164c99fb5f9SBaptiste Daroussin Parse passed string and detect number */ 165c99fb5f9SBaptiste Daroussin UCL_STRING_PARSE = UCL_STRING_PARSE_BOOLEAN|UCL_STRING_PARSE_NUMBER, /**< 166c99fb5f9SBaptiste Daroussin Parse passed string (and detect booleans and numbers) */ 16797bd480fSBaptiste Daroussin UCL_STRING_PARSE_BYTES = 0x40 /**< Treat numbers as bytes */ 168c99fb5f9SBaptiste Daroussin } ucl_string_flags_t; 169c99fb5f9SBaptiste Daroussin 170c99fb5f9SBaptiste Daroussin /** 171c99fb5f9SBaptiste Daroussin * Basic flags for an object 172c99fb5f9SBaptiste Daroussin */ 173c99fb5f9SBaptiste Daroussin typedef enum ucl_object_flags { 174c99fb5f9SBaptiste Daroussin UCL_OBJECT_ALLOCATED_KEY = 1, /**< An object has key allocated internally */ 175c99fb5f9SBaptiste Daroussin UCL_OBJECT_ALLOCATED_VALUE = 2, /**< An object has a string value allocated internally */ 176c99fb5f9SBaptiste Daroussin UCL_OBJECT_NEED_KEY_ESCAPE = 4 /**< The key of an object need to be escaped on output */ 177c99fb5f9SBaptiste Daroussin } ucl_object_flags_t; 178c99fb5f9SBaptiste Daroussin 179c99fb5f9SBaptiste Daroussin /** 180c99fb5f9SBaptiste Daroussin * UCL object structure. Please mention that the most of fields should not be touched by 181c99fb5f9SBaptiste Daroussin * UCL users. In future, this structure may be converted to private one. 182c99fb5f9SBaptiste Daroussin */ 183c99fb5f9SBaptiste Daroussin typedef struct ucl_object_s { 184c99fb5f9SBaptiste Daroussin /** 185c99fb5f9SBaptiste Daroussin * Variant value type 186c99fb5f9SBaptiste Daroussin */ 187c99fb5f9SBaptiste Daroussin union { 188c99fb5f9SBaptiste Daroussin int64_t iv; /**< Int value of an object */ 189c99fb5f9SBaptiste Daroussin const char *sv; /**< String value of an object */ 190c99fb5f9SBaptiste Daroussin double dv; /**< Double value of an object */ 191c99fb5f9SBaptiste Daroussin struct ucl_object_s *av; /**< Array */ 192c99fb5f9SBaptiste Daroussin void *ov; /**< Object */ 193c99fb5f9SBaptiste Daroussin void* ud; /**< Opaque user data */ 194c99fb5f9SBaptiste Daroussin } value; 195c99fb5f9SBaptiste Daroussin const char *key; /**< Key of an object */ 196c99fb5f9SBaptiste Daroussin struct ucl_object_s *next; /**< Array handle */ 197c99fb5f9SBaptiste Daroussin struct ucl_object_s *prev; /**< Array handle */ 198c99fb5f9SBaptiste Daroussin unsigned char* trash_stack[2]; /**< Pointer to allocated chunks */ 199c99fb5f9SBaptiste Daroussin unsigned keylen; /**< Lenght of a key */ 200c99fb5f9SBaptiste Daroussin unsigned len; /**< Size of an object */ 201c99fb5f9SBaptiste Daroussin enum ucl_type type; /**< Real type */ 202c99fb5f9SBaptiste Daroussin uint16_t ref; /**< Reference count */ 203c99fb5f9SBaptiste Daroussin uint16_t flags; /**< Object flags */ 204c99fb5f9SBaptiste Daroussin } ucl_object_t; 205c99fb5f9SBaptiste Daroussin 206c99fb5f9SBaptiste Daroussin /** @} */ 207c99fb5f9SBaptiste Daroussin 208c99fb5f9SBaptiste Daroussin /** 209c99fb5f9SBaptiste Daroussin * @defgroup utils Utility functions 210c99fb5f9SBaptiste Daroussin * A number of utility functions simplify handling of UCL objects 211c99fb5f9SBaptiste Daroussin * 212c99fb5f9SBaptiste Daroussin * @{ 213c99fb5f9SBaptiste Daroussin */ 214c99fb5f9SBaptiste Daroussin /** 215c99fb5f9SBaptiste Daroussin * Copy and return a key of an object, returned key is zero-terminated 216c99fb5f9SBaptiste Daroussin * @param obj CL object 217c99fb5f9SBaptiste Daroussin * @return zero terminated key 218c99fb5f9SBaptiste Daroussin */ 219*b04a7a0bSBaptiste Daroussin UCL_EXTERN char* ucl_copy_key_trash (const ucl_object_t *obj); 220c99fb5f9SBaptiste Daroussin 221c99fb5f9SBaptiste Daroussin /** 222c99fb5f9SBaptiste Daroussin * Copy and return a string value of an object, returned key is zero-terminated 223c99fb5f9SBaptiste Daroussin * @param obj CL object 224c99fb5f9SBaptiste Daroussin * @return zero terminated string representation of object value 225c99fb5f9SBaptiste Daroussin */ 226*b04a7a0bSBaptiste Daroussin UCL_EXTERN char* ucl_copy_value_trash (const ucl_object_t *obj); 227c99fb5f9SBaptiste Daroussin 228c99fb5f9SBaptiste Daroussin /** 229c99fb5f9SBaptiste Daroussin * Creates a new object 230c99fb5f9SBaptiste Daroussin * @return new object 231c99fb5f9SBaptiste Daroussin */ 23297bd480fSBaptiste Daroussin UCL_EXTERN ucl_object_t* ucl_object_new (void) UCL_WARN_UNUSED_RESULT; 233c99fb5f9SBaptiste Daroussin 234c99fb5f9SBaptiste Daroussin /** 235c99fb5f9SBaptiste Daroussin * Create new object with type specified 236c99fb5f9SBaptiste Daroussin * @param type type of a new object 237c99fb5f9SBaptiste Daroussin * @return new object 238c99fb5f9SBaptiste Daroussin */ 23997bd480fSBaptiste Daroussin UCL_EXTERN ucl_object_t* ucl_object_typed_new (unsigned int type) UCL_WARN_UNUSED_RESULT; 240c99fb5f9SBaptiste Daroussin 241c99fb5f9SBaptiste Daroussin /** 242c99fb5f9SBaptiste Daroussin * Convert any string to an ucl object making the specified transformations 243c99fb5f9SBaptiste Daroussin * @param str fixed size or NULL terminated string 244c99fb5f9SBaptiste Daroussin * @param len length (if len is zero, than str is treated as NULL terminated) 245c99fb5f9SBaptiste Daroussin * @param flags conversion flags 246c99fb5f9SBaptiste Daroussin * @return new object 247c99fb5f9SBaptiste Daroussin */ 24836c53d67SBaptiste Daroussin UCL_EXTERN ucl_object_t * ucl_object_fromstring_common (const char *str, size_t len, 249c99fb5f9SBaptiste Daroussin enum ucl_string_flags flags) UCL_WARN_UNUSED_RESULT; 250c99fb5f9SBaptiste Daroussin 251c99fb5f9SBaptiste Daroussin /** 252c99fb5f9SBaptiste Daroussin * Create a UCL object from the specified string 253c99fb5f9SBaptiste Daroussin * @param str NULL terminated string, will be json escaped 254c99fb5f9SBaptiste Daroussin * @return new object 255c99fb5f9SBaptiste Daroussin */ 256*b04a7a0bSBaptiste Daroussin UCL_EXTERN ucl_object_t *ucl_object_fromstring (const char *str) UCL_WARN_UNUSED_RESULT; 257c99fb5f9SBaptiste Daroussin 258c99fb5f9SBaptiste Daroussin /** 259c99fb5f9SBaptiste Daroussin * Create a UCL object from the specified string 260c99fb5f9SBaptiste Daroussin * @param str fixed size string, will be json escaped 261c99fb5f9SBaptiste Daroussin * @param len length of a string 262c99fb5f9SBaptiste Daroussin * @return new object 263c99fb5f9SBaptiste Daroussin */ 264*b04a7a0bSBaptiste Daroussin UCL_EXTERN ucl_object_t *ucl_object_fromlstring (const char *str, 265*b04a7a0bSBaptiste Daroussin size_t len) UCL_WARN_UNUSED_RESULT; 266c99fb5f9SBaptiste Daroussin 267c99fb5f9SBaptiste Daroussin /** 268c99fb5f9SBaptiste Daroussin * Create an object from an integer number 269c99fb5f9SBaptiste Daroussin * @param iv number 270c99fb5f9SBaptiste Daroussin * @return new object 271c99fb5f9SBaptiste Daroussin */ 272*b04a7a0bSBaptiste Daroussin UCL_EXTERN ucl_object_t* ucl_object_fromint (int64_t iv) UCL_WARN_UNUSED_RESULT; 273c99fb5f9SBaptiste Daroussin 274c99fb5f9SBaptiste Daroussin /** 275c99fb5f9SBaptiste Daroussin * Create an object from a float number 276c99fb5f9SBaptiste Daroussin * @param dv number 277c99fb5f9SBaptiste Daroussin * @return new object 278c99fb5f9SBaptiste Daroussin */ 279*b04a7a0bSBaptiste Daroussin UCL_EXTERN ucl_object_t* ucl_object_fromdouble (double dv) UCL_WARN_UNUSED_RESULT; 280c99fb5f9SBaptiste Daroussin 281c99fb5f9SBaptiste Daroussin /** 282c99fb5f9SBaptiste Daroussin * Create an object from a boolean 283c99fb5f9SBaptiste Daroussin * @param bv bool value 284c99fb5f9SBaptiste Daroussin * @return new object 285c99fb5f9SBaptiste Daroussin */ 286*b04a7a0bSBaptiste Daroussin UCL_EXTERN ucl_object_t* ucl_object_frombool (bool bv) UCL_WARN_UNUSED_RESULT; 287c99fb5f9SBaptiste Daroussin 288c99fb5f9SBaptiste Daroussin /** 289c99fb5f9SBaptiste Daroussin * Insert a object 'elt' to the hash 'top' and associate it with key 'key' 290c99fb5f9SBaptiste Daroussin * @param top destination object (will be created automatically if top is NULL) 291c99fb5f9SBaptiste Daroussin * @param elt element to insert (must NOT be NULL) 292c99fb5f9SBaptiste Daroussin * @param key key to associate with this object (either const or preallocated) 293c99fb5f9SBaptiste Daroussin * @param keylen length of the key (or 0 for NULL terminated keys) 294c99fb5f9SBaptiste Daroussin * @param copy_key make an internal copy of key 295*b04a7a0bSBaptiste Daroussin * @return true if key has been inserted 296c99fb5f9SBaptiste Daroussin */ 297*b04a7a0bSBaptiste Daroussin UCL_EXTERN bool ucl_object_insert_key (ucl_object_t *top, ucl_object_t *elt, 298*b04a7a0bSBaptiste Daroussin const char *key, size_t keylen, bool copy_key); 299c99fb5f9SBaptiste Daroussin 300c99fb5f9SBaptiste Daroussin /** 301c99fb5f9SBaptiste Daroussin * Replace a object 'elt' to the hash 'top' and associate it with key 'key', old object will be unrefed, 302c99fb5f9SBaptiste Daroussin * if no object has been found this function works like ucl_object_insert_key() 303c99fb5f9SBaptiste Daroussin * @param top destination object (will be created automatically if top is NULL) 304c99fb5f9SBaptiste Daroussin * @param elt element to insert (must NOT be NULL) 305c99fb5f9SBaptiste Daroussin * @param key key to associate with this object (either const or preallocated) 306c99fb5f9SBaptiste Daroussin * @param keylen length of the key (or 0 for NULL terminated keys) 307c99fb5f9SBaptiste Daroussin * @param copy_key make an internal copy of key 308*b04a7a0bSBaptiste Daroussin * @return true if key has been inserted 309c99fb5f9SBaptiste Daroussin */ 310*b04a7a0bSBaptiste Daroussin UCL_EXTERN bool ucl_object_replace_key (ucl_object_t *top, ucl_object_t *elt, 311*b04a7a0bSBaptiste Daroussin const char *key, size_t keylen, bool copy_key); 312c99fb5f9SBaptiste Daroussin 313c99fb5f9SBaptiste Daroussin /** 31436c53d67SBaptiste Daroussin * Delete a object associated with key 'key', old object will be unrefered, 31536c53d67SBaptiste Daroussin * @param top object 31636c53d67SBaptiste Daroussin * @param key key associated to the object to remove 31736c53d67SBaptiste Daroussin * @param keylen length of the key (or 0 for NULL terminated keys) 31836c53d67SBaptiste Daroussin */ 319*b04a7a0bSBaptiste Daroussin UCL_EXTERN bool ucl_object_delete_keyl (ucl_object_t *top, 320*b04a7a0bSBaptiste Daroussin const char *key, size_t keylen); 32136c53d67SBaptiste Daroussin 32236c53d67SBaptiste Daroussin /** 32336c53d67SBaptiste Daroussin * Delete a object associated with key 'key', old object will be unrefered, 32436c53d67SBaptiste Daroussin * @param top object 32536c53d67SBaptiste Daroussin * @param key key associated to the object to remove 32636c53d67SBaptiste Daroussin */ 327*b04a7a0bSBaptiste Daroussin UCL_EXTERN bool ucl_object_delete_key (ucl_object_t *top, 328*b04a7a0bSBaptiste Daroussin const char *key); 32936c53d67SBaptiste Daroussin 33097bd480fSBaptiste Daroussin 33197bd480fSBaptiste Daroussin /** 33297bd480fSBaptiste Daroussin * Delete key from `top` object returning the object deleted. This object is not 33397bd480fSBaptiste Daroussin * released 33497bd480fSBaptiste Daroussin * @param top object 33597bd480fSBaptiste Daroussin * @param key key to remove 33697bd480fSBaptiste Daroussin * @param keylen length of the key (or 0 for NULL terminated keys) 33797bd480fSBaptiste Daroussin * @return removed object or NULL if object has not been found 33897bd480fSBaptiste Daroussin */ 33997bd480fSBaptiste Daroussin UCL_EXTERN ucl_object_t* ucl_object_pop_keyl (ucl_object_t *top, const char *key, 34097bd480fSBaptiste Daroussin size_t keylen) UCL_WARN_UNUSED_RESULT; 34197bd480fSBaptiste Daroussin 34297bd480fSBaptiste Daroussin /** 34397bd480fSBaptiste Daroussin * Delete key from `top` object returning the object deleted. This object is not 34497bd480fSBaptiste Daroussin * released 34597bd480fSBaptiste Daroussin * @param top object 34697bd480fSBaptiste Daroussin * @param key key to remove 34797bd480fSBaptiste Daroussin * @return removed object or NULL if object has not been found 34897bd480fSBaptiste Daroussin */ 34997bd480fSBaptiste Daroussin UCL_EXTERN ucl_object_t* ucl_object_pop_key (ucl_object_t *top, const char *key) 35097bd480fSBaptiste Daroussin UCL_WARN_UNUSED_RESULT; 35197bd480fSBaptiste Daroussin 35236c53d67SBaptiste Daroussin /** 353c99fb5f9SBaptiste Daroussin * Insert a object 'elt' to the hash 'top' and associate it with key 'key', if the specified key exist, 354c99fb5f9SBaptiste Daroussin * try to merge its content 355c99fb5f9SBaptiste Daroussin * @param top destination object (will be created automatically if top is NULL) 356c99fb5f9SBaptiste Daroussin * @param elt element to insert (must NOT be NULL) 357c99fb5f9SBaptiste Daroussin * @param key key to associate with this object (either const or preallocated) 358c99fb5f9SBaptiste Daroussin * @param keylen length of the key (or 0 for NULL terminated keys) 359c99fb5f9SBaptiste Daroussin * @param copy_key make an internal copy of key 360*b04a7a0bSBaptiste Daroussin * @return true if key has been inserted 361c99fb5f9SBaptiste Daroussin */ 362*b04a7a0bSBaptiste Daroussin UCL_EXTERN bool ucl_object_insert_key_merged (ucl_object_t *top, ucl_object_t *elt, 363*b04a7a0bSBaptiste Daroussin const char *key, size_t keylen, bool copy_key); 364c99fb5f9SBaptiste Daroussin 365c99fb5f9SBaptiste Daroussin /** 366c99fb5f9SBaptiste Daroussin * Append an element to the front of array object 367c99fb5f9SBaptiste Daroussin * @param top destination object (will be created automatically if top is NULL) 368c99fb5f9SBaptiste Daroussin * @param elt element to append (must NOT be NULL) 369*b04a7a0bSBaptiste Daroussin * @return true if value has been inserted 370c99fb5f9SBaptiste Daroussin */ 371*b04a7a0bSBaptiste Daroussin UCL_EXTERN bool ucl_array_append (ucl_object_t *top, 372*b04a7a0bSBaptiste Daroussin ucl_object_t *elt); 373c99fb5f9SBaptiste Daroussin 374c99fb5f9SBaptiste Daroussin /** 375c99fb5f9SBaptiste Daroussin * Append an element to the start of array object 376c99fb5f9SBaptiste Daroussin * @param top destination object (will be created automatically if top is NULL) 377c99fb5f9SBaptiste Daroussin * @param elt element to append (must NOT be NULL) 378*b04a7a0bSBaptiste Daroussin * @return true if value has been inserted 379c99fb5f9SBaptiste Daroussin */ 380*b04a7a0bSBaptiste Daroussin UCL_EXTERN bool ucl_array_prepend (ucl_object_t *top, 381*b04a7a0bSBaptiste Daroussin ucl_object_t *elt); 382c99fb5f9SBaptiste Daroussin 383c99fb5f9SBaptiste Daroussin /** 384c99fb5f9SBaptiste Daroussin * Removes an element `elt` from the array `top`. Caller must unref the returned object when it is not 385c99fb5f9SBaptiste Daroussin * needed. 386c99fb5f9SBaptiste Daroussin * @param top array ucl object 387c99fb5f9SBaptiste Daroussin * @param elt element to remove 388c99fb5f9SBaptiste Daroussin * @return removed element or NULL if `top` is NULL or not an array 389c99fb5f9SBaptiste Daroussin */ 390*b04a7a0bSBaptiste Daroussin UCL_EXTERN ucl_object_t* ucl_array_delete (ucl_object_t *top, 391*b04a7a0bSBaptiste Daroussin ucl_object_t *elt); 392c99fb5f9SBaptiste Daroussin 393c99fb5f9SBaptiste Daroussin /** 394c99fb5f9SBaptiste Daroussin * Returns the first element of the array `top` 395c99fb5f9SBaptiste Daroussin * @param top array ucl object 396c99fb5f9SBaptiste Daroussin * @return element or NULL if `top` is NULL or not an array 397c99fb5f9SBaptiste Daroussin */ 398*b04a7a0bSBaptiste Daroussin UCL_EXTERN const ucl_object_t* ucl_array_head (const ucl_object_t *top); 399c99fb5f9SBaptiste Daroussin 400c99fb5f9SBaptiste Daroussin /** 401c99fb5f9SBaptiste Daroussin * Returns the last element of the array `top` 402c99fb5f9SBaptiste Daroussin * @param top array ucl object 403c99fb5f9SBaptiste Daroussin * @return element or NULL if `top` is NULL or not an array 404c99fb5f9SBaptiste Daroussin */ 405*b04a7a0bSBaptiste Daroussin UCL_EXTERN const ucl_object_t* ucl_array_tail (const ucl_object_t *top); 406c99fb5f9SBaptiste Daroussin 407c99fb5f9SBaptiste Daroussin /** 408c99fb5f9SBaptiste Daroussin * Removes the last element from the array `top`. Caller must unref the returned object when it is not 409c99fb5f9SBaptiste Daroussin * needed. 410c99fb5f9SBaptiste Daroussin * @param top array ucl object 411c99fb5f9SBaptiste Daroussin * @return removed element or NULL if `top` is NULL or not an array 412c99fb5f9SBaptiste Daroussin */ 41397bd480fSBaptiste Daroussin UCL_EXTERN ucl_object_t* ucl_array_pop_last (ucl_object_t *top); 414c99fb5f9SBaptiste Daroussin 415c99fb5f9SBaptiste Daroussin /** 416c99fb5f9SBaptiste Daroussin * Removes the first element from the array `top`. Caller must unref the returned object when it is not 417c99fb5f9SBaptiste Daroussin * needed. 418c99fb5f9SBaptiste Daroussin * @param top array ucl object 419c99fb5f9SBaptiste Daroussin * @return removed element or NULL if `top` is NULL or not an array 420c99fb5f9SBaptiste Daroussin */ 42197bd480fSBaptiste Daroussin UCL_EXTERN ucl_object_t* ucl_array_pop_first (ucl_object_t *top); 422c99fb5f9SBaptiste Daroussin 423c99fb5f9SBaptiste Daroussin /** 424c99fb5f9SBaptiste Daroussin * Append a element to another element forming an implicit array 425c99fb5f9SBaptiste Daroussin * @param head head to append (may be NULL) 426c99fb5f9SBaptiste Daroussin * @param elt new element 427*b04a7a0bSBaptiste Daroussin * @return true if element has been inserted 428c99fb5f9SBaptiste Daroussin */ 42997bd480fSBaptiste Daroussin UCL_EXTERN ucl_object_t * ucl_elt_append (ucl_object_t *head, 430*b04a7a0bSBaptiste Daroussin ucl_object_t *elt); 431c99fb5f9SBaptiste Daroussin 432c99fb5f9SBaptiste Daroussin /** 433c99fb5f9SBaptiste Daroussin * Converts an object to double value 434c99fb5f9SBaptiste Daroussin * @param obj CL object 435c99fb5f9SBaptiste Daroussin * @param target target double variable 436c99fb5f9SBaptiste Daroussin * @return true if conversion was successful 437c99fb5f9SBaptiste Daroussin */ 438*b04a7a0bSBaptiste Daroussin UCL_EXTERN bool ucl_object_todouble_safe (const ucl_object_t *obj, double *target); 439c99fb5f9SBaptiste Daroussin 440c99fb5f9SBaptiste Daroussin /** 441c99fb5f9SBaptiste Daroussin * Unsafe version of \ref ucl_obj_todouble_safe 442c99fb5f9SBaptiste Daroussin * @param obj CL object 443c99fb5f9SBaptiste Daroussin * @return double value 444c99fb5f9SBaptiste Daroussin */ 445*b04a7a0bSBaptiste Daroussin UCL_EXTERN double ucl_object_todouble (const ucl_object_t *obj); 446c99fb5f9SBaptiste Daroussin 447c99fb5f9SBaptiste Daroussin /** 448c99fb5f9SBaptiste Daroussin * Converts an object to integer value 449c99fb5f9SBaptiste Daroussin * @param obj CL object 450c99fb5f9SBaptiste Daroussin * @param target target integer variable 451c99fb5f9SBaptiste Daroussin * @return true if conversion was successful 452c99fb5f9SBaptiste Daroussin */ 453*b04a7a0bSBaptiste Daroussin UCL_EXTERN bool ucl_object_toint_safe (const ucl_object_t *obj, int64_t *target); 454c99fb5f9SBaptiste Daroussin 455c99fb5f9SBaptiste Daroussin /** 456c99fb5f9SBaptiste Daroussin * Unsafe version of \ref ucl_obj_toint_safe 457c99fb5f9SBaptiste Daroussin * @param obj CL object 458c99fb5f9SBaptiste Daroussin * @return int value 459c99fb5f9SBaptiste Daroussin */ 460*b04a7a0bSBaptiste Daroussin UCL_EXTERN int64_t ucl_object_toint (const ucl_object_t *obj); 461c99fb5f9SBaptiste Daroussin 462c99fb5f9SBaptiste Daroussin /** 463c99fb5f9SBaptiste Daroussin * Converts an object to boolean value 464c99fb5f9SBaptiste Daroussin * @param obj CL object 465c99fb5f9SBaptiste Daroussin * @param target target boolean variable 466c99fb5f9SBaptiste Daroussin * @return true if conversion was successful 467c99fb5f9SBaptiste Daroussin */ 468*b04a7a0bSBaptiste Daroussin UCL_EXTERN bool ucl_object_toboolean_safe (const ucl_object_t *obj, bool *target); 469c99fb5f9SBaptiste Daroussin 470c99fb5f9SBaptiste Daroussin /** 471c99fb5f9SBaptiste Daroussin * Unsafe version of \ref ucl_obj_toboolean_safe 472c99fb5f9SBaptiste Daroussin * @param obj CL object 473c99fb5f9SBaptiste Daroussin * @return boolean value 474c99fb5f9SBaptiste Daroussin */ 475*b04a7a0bSBaptiste Daroussin UCL_EXTERN bool ucl_object_toboolean (const ucl_object_t *obj); 476c99fb5f9SBaptiste Daroussin 477c99fb5f9SBaptiste Daroussin /** 478c99fb5f9SBaptiste Daroussin * Converts an object to string value 479c99fb5f9SBaptiste Daroussin * @param obj CL object 480c99fb5f9SBaptiste Daroussin * @param target target string variable, no need to free value 481c99fb5f9SBaptiste Daroussin * @return true if conversion was successful 482c99fb5f9SBaptiste Daroussin */ 483*b04a7a0bSBaptiste Daroussin UCL_EXTERN bool ucl_object_tostring_safe (const ucl_object_t *obj, const char **target); 484c99fb5f9SBaptiste Daroussin 485c99fb5f9SBaptiste Daroussin /** 486c99fb5f9SBaptiste Daroussin * Unsafe version of \ref ucl_obj_tostring_safe 487c99fb5f9SBaptiste Daroussin * @param obj CL object 488c99fb5f9SBaptiste Daroussin * @return string value 489c99fb5f9SBaptiste Daroussin */ 490*b04a7a0bSBaptiste Daroussin UCL_EXTERN const char* ucl_object_tostring (const ucl_object_t *obj); 491c99fb5f9SBaptiste Daroussin 492c99fb5f9SBaptiste Daroussin /** 493c99fb5f9SBaptiste Daroussin * Convert any object to a string in JSON notation if needed 494c99fb5f9SBaptiste Daroussin * @param obj CL object 495c99fb5f9SBaptiste Daroussin * @return string value 496c99fb5f9SBaptiste Daroussin */ 497*b04a7a0bSBaptiste Daroussin UCL_EXTERN const char* ucl_object_tostring_forced (const ucl_object_t *obj); 498c99fb5f9SBaptiste Daroussin 499c99fb5f9SBaptiste Daroussin /** 500c99fb5f9SBaptiste Daroussin * Return string as char * and len, string may be not zero terminated, more efficient that \ref ucl_obj_tostring as it 501c99fb5f9SBaptiste Daroussin * allows zero-copy (if #UCL_PARSER_ZEROCOPY has been used during parsing) 502c99fb5f9SBaptiste Daroussin * @param obj CL object 503c99fb5f9SBaptiste Daroussin * @param target target string variable, no need to free value 504c99fb5f9SBaptiste Daroussin * @param tlen target length 505c99fb5f9SBaptiste Daroussin * @return true if conversion was successful 506c99fb5f9SBaptiste Daroussin */ 507*b04a7a0bSBaptiste Daroussin UCL_EXTERN bool ucl_object_tolstring_safe (const ucl_object_t *obj, 50897bd480fSBaptiste Daroussin const char **target, size_t *tlen); 509c99fb5f9SBaptiste Daroussin 510c99fb5f9SBaptiste Daroussin /** 511c99fb5f9SBaptiste Daroussin * Unsafe version of \ref ucl_obj_tolstring_safe 512c99fb5f9SBaptiste Daroussin * @param obj CL object 513c99fb5f9SBaptiste Daroussin * @return string value 514c99fb5f9SBaptiste Daroussin */ 515*b04a7a0bSBaptiste Daroussin UCL_EXTERN const char* ucl_object_tolstring (const ucl_object_t *obj, size_t *tlen); 516c99fb5f9SBaptiste Daroussin 517c99fb5f9SBaptiste Daroussin /** 518c99fb5f9SBaptiste Daroussin * Return object identified by a key in the specified object 519c99fb5f9SBaptiste Daroussin * @param obj object to get a key from (must be of type UCL_OBJECT) 520c99fb5f9SBaptiste Daroussin * @param key key to search 521c99fb5f9SBaptiste Daroussin * @return object matched the specified key or NULL if key is not found 522c99fb5f9SBaptiste Daroussin */ 523*b04a7a0bSBaptiste Daroussin UCL_EXTERN const ucl_object_t* ucl_object_find_key (const ucl_object_t *obj, 524*b04a7a0bSBaptiste Daroussin const char *key); 525c99fb5f9SBaptiste Daroussin 526c99fb5f9SBaptiste Daroussin /** 527c99fb5f9SBaptiste Daroussin * Return object identified by a fixed size key in the specified object 528c99fb5f9SBaptiste Daroussin * @param obj object to get a key from (must be of type UCL_OBJECT) 529c99fb5f9SBaptiste Daroussin * @param key key to search 530c99fb5f9SBaptiste Daroussin * @param klen length of a key 531c99fb5f9SBaptiste Daroussin * @return object matched the specified key or NULL if key is not found 532c99fb5f9SBaptiste Daroussin */ 533*b04a7a0bSBaptiste Daroussin UCL_EXTERN const ucl_object_t* ucl_object_find_keyl (const ucl_object_t *obj, 534*b04a7a0bSBaptiste Daroussin const char *key, size_t klen); 535c99fb5f9SBaptiste Daroussin 536c99fb5f9SBaptiste Daroussin /** 537c99fb5f9SBaptiste Daroussin * Returns a key of an object as a NULL terminated string 538c99fb5f9SBaptiste Daroussin * @param obj CL object 539c99fb5f9SBaptiste Daroussin * @return key or NULL if there is no key 540c99fb5f9SBaptiste Daroussin */ 541*b04a7a0bSBaptiste Daroussin UCL_EXTERN const char* ucl_object_key (const ucl_object_t *obj); 542c99fb5f9SBaptiste Daroussin 543c99fb5f9SBaptiste Daroussin /** 544c99fb5f9SBaptiste Daroussin * Returns a key of an object as a fixed size string (may be more efficient) 545c99fb5f9SBaptiste Daroussin * @param obj CL object 546c99fb5f9SBaptiste Daroussin * @param len target key length 547c99fb5f9SBaptiste Daroussin * @return key pointer 548c99fb5f9SBaptiste Daroussin */ 549*b04a7a0bSBaptiste Daroussin UCL_EXTERN const char* ucl_object_keyl (const ucl_object_t *obj, size_t *len); 550c99fb5f9SBaptiste Daroussin 551c99fb5f9SBaptiste Daroussin /** 552c99fb5f9SBaptiste Daroussin * Increase reference count for an object 553c99fb5f9SBaptiste Daroussin * @param obj object to ref 554c99fb5f9SBaptiste Daroussin */ 555*b04a7a0bSBaptiste Daroussin UCL_EXTERN ucl_object_t* ucl_object_ref (const ucl_object_t *obj); 556*b04a7a0bSBaptiste Daroussin 557*b04a7a0bSBaptiste Daroussin /** 558*b04a7a0bSBaptiste Daroussin * Free ucl object 559*b04a7a0bSBaptiste Daroussin * @param obj ucl object to free 560*b04a7a0bSBaptiste Daroussin */ 561*b04a7a0bSBaptiste Daroussin UCL_DEPRECATED(UCL_EXTERN void ucl_object_free (ucl_object_t *obj)); 562c99fb5f9SBaptiste Daroussin 563c99fb5f9SBaptiste Daroussin /** 564c99fb5f9SBaptiste Daroussin * Decrease reference count for an object 565c99fb5f9SBaptiste Daroussin * @param obj object to unref 566c99fb5f9SBaptiste Daroussin */ 56797bd480fSBaptiste Daroussin UCL_EXTERN void ucl_object_unref (ucl_object_t *obj); 56897bd480fSBaptiste Daroussin 56997bd480fSBaptiste Daroussin /** 57097bd480fSBaptiste Daroussin * Compare objects `o1` and `o2` 57197bd480fSBaptiste Daroussin * @param o1 the first object 57297bd480fSBaptiste Daroussin * @param o2 the second object 57397bd480fSBaptiste Daroussin * @return values >0, 0 and <0 if `o1` is more than, equal and less than `o2`. 57497bd480fSBaptiste Daroussin * The order of comparison: 57597bd480fSBaptiste Daroussin * 1) Type of objects 57697bd480fSBaptiste Daroussin * 2) Size of objects 57797bd480fSBaptiste Daroussin * 3) Content of objects 57897bd480fSBaptiste Daroussin */ 579*b04a7a0bSBaptiste Daroussin UCL_EXTERN int ucl_object_compare (const ucl_object_t *o1, 580*b04a7a0bSBaptiste Daroussin const ucl_object_t *o2); 58197bd480fSBaptiste Daroussin 58297bd480fSBaptiste Daroussin /** 58397bd480fSBaptiste Daroussin * Sort UCL array using `cmp` compare function 58497bd480fSBaptiste Daroussin * @param ar 58597bd480fSBaptiste Daroussin * @param cmp 58697bd480fSBaptiste Daroussin */ 58797bd480fSBaptiste Daroussin UCL_EXTERN void ucl_object_array_sort (ucl_object_t *ar, 588*b04a7a0bSBaptiste Daroussin int (*cmp)(const ucl_object_t *o1, const ucl_object_t *o2)); 58997bd480fSBaptiste Daroussin 590c99fb5f9SBaptiste Daroussin /** 591c99fb5f9SBaptiste Daroussin * Opaque iterator object 592c99fb5f9SBaptiste Daroussin */ 593c99fb5f9SBaptiste Daroussin typedef void* ucl_object_iter_t; 594c99fb5f9SBaptiste Daroussin 595c99fb5f9SBaptiste Daroussin /** 596c99fb5f9SBaptiste Daroussin * Get next key from an object 597c99fb5f9SBaptiste Daroussin * @param obj object to iterate 598c99fb5f9SBaptiste Daroussin * @param iter opaque iterator, must be set to NULL on the first call: 599c99fb5f9SBaptiste Daroussin * ucl_object_iter_t it = NULL; 600c99fb5f9SBaptiste Daroussin * while ((cur = ucl_iterate_object (obj, &it)) != NULL) ... 601c99fb5f9SBaptiste Daroussin * @return the next object or NULL 602c99fb5f9SBaptiste Daroussin */ 603*b04a7a0bSBaptiste Daroussin UCL_EXTERN const ucl_object_t* ucl_iterate_object (const ucl_object_t *obj, 604*b04a7a0bSBaptiste Daroussin ucl_object_iter_t *iter, bool expand_values); 605c99fb5f9SBaptiste Daroussin /** @} */ 606c99fb5f9SBaptiste Daroussin 607c99fb5f9SBaptiste Daroussin 608c99fb5f9SBaptiste Daroussin /** 609c99fb5f9SBaptiste Daroussin * @defgroup parser Parsing functions 610c99fb5f9SBaptiste Daroussin * These functions are used to parse UCL objects 611c99fb5f9SBaptiste Daroussin * 612c99fb5f9SBaptiste Daroussin * @{ 613c99fb5f9SBaptiste Daroussin */ 614c99fb5f9SBaptiste Daroussin 615c99fb5f9SBaptiste Daroussin /** 616c99fb5f9SBaptiste Daroussin * Macro handler for a parser 617c99fb5f9SBaptiste Daroussin * @param data the content of macro 618c99fb5f9SBaptiste Daroussin * @param len the length of content 619c99fb5f9SBaptiste Daroussin * @param ud opaque user data 620c99fb5f9SBaptiste Daroussin * @param err error pointer 621c99fb5f9SBaptiste Daroussin * @return true if macro has been parsed 622c99fb5f9SBaptiste Daroussin */ 623c99fb5f9SBaptiste Daroussin typedef bool (*ucl_macro_handler) (const unsigned char *data, size_t len, void* ud); 624c99fb5f9SBaptiste Daroussin 625c99fb5f9SBaptiste Daroussin /* Opaque parser */ 626c99fb5f9SBaptiste Daroussin struct ucl_parser; 627c99fb5f9SBaptiste Daroussin 628c99fb5f9SBaptiste Daroussin /** 629c99fb5f9SBaptiste Daroussin * Creates new parser object 630c99fb5f9SBaptiste Daroussin * @param pool pool to allocate memory from 631c99fb5f9SBaptiste Daroussin * @return new parser object 632c99fb5f9SBaptiste Daroussin */ 63336c53d67SBaptiste Daroussin UCL_EXTERN struct ucl_parser* ucl_parser_new (int flags); 634c99fb5f9SBaptiste Daroussin 635c99fb5f9SBaptiste Daroussin /** 636c99fb5f9SBaptiste Daroussin * Register new handler for a macro 637c99fb5f9SBaptiste Daroussin * @param parser parser object 638c99fb5f9SBaptiste Daroussin * @param macro macro name (without leading dot) 639c99fb5f9SBaptiste Daroussin * @param handler handler (it is called immediately after macro is parsed) 640c99fb5f9SBaptiste Daroussin * @param ud opaque user data for a handler 641c99fb5f9SBaptiste Daroussin */ 64236c53d67SBaptiste Daroussin UCL_EXTERN void ucl_parser_register_macro (struct ucl_parser *parser, const char *macro, 643c99fb5f9SBaptiste Daroussin ucl_macro_handler handler, void* ud); 644c99fb5f9SBaptiste Daroussin 645c99fb5f9SBaptiste Daroussin /** 646c99fb5f9SBaptiste Daroussin * Register new parser variable 647c99fb5f9SBaptiste Daroussin * @param parser parser object 648c99fb5f9SBaptiste Daroussin * @param var variable name 649c99fb5f9SBaptiste Daroussin * @param value variable value 650c99fb5f9SBaptiste Daroussin */ 65136c53d67SBaptiste Daroussin UCL_EXTERN void ucl_parser_register_variable (struct ucl_parser *parser, const char *var, 652c99fb5f9SBaptiste Daroussin const char *value); 653c99fb5f9SBaptiste Daroussin 654c99fb5f9SBaptiste Daroussin /** 655c99fb5f9SBaptiste Daroussin * Load new chunk to a parser 656c99fb5f9SBaptiste Daroussin * @param parser parser structure 657c99fb5f9SBaptiste Daroussin * @param data the pointer to the beginning of a chunk 658c99fb5f9SBaptiste Daroussin * @param len the length of a chunk 659c99fb5f9SBaptiste Daroussin * @param err if *err is NULL it is set to parser error 660c99fb5f9SBaptiste Daroussin * @return true if chunk has been added and false in case of error 661c99fb5f9SBaptiste Daroussin */ 66297bd480fSBaptiste Daroussin UCL_EXTERN bool ucl_parser_add_chunk (struct ucl_parser *parser, 66397bd480fSBaptiste Daroussin const unsigned char *data, size_t len); 66497bd480fSBaptiste Daroussin 66597bd480fSBaptiste Daroussin /** 66697bd480fSBaptiste Daroussin * Load ucl object from a string 66797bd480fSBaptiste Daroussin * @param parser parser structure 66897bd480fSBaptiste Daroussin * @param data the pointer to the string 66997bd480fSBaptiste Daroussin * @param len the length of the string, if `len` is 0 then `data` must be zero-terminated string 67097bd480fSBaptiste Daroussin * @return true if string has been added and false in case of error 67197bd480fSBaptiste Daroussin */ 67297bd480fSBaptiste Daroussin UCL_EXTERN bool ucl_parser_add_string (struct ucl_parser *parser, 67397bd480fSBaptiste Daroussin const char *data,size_t len); 674c99fb5f9SBaptiste Daroussin 675c99fb5f9SBaptiste Daroussin /** 676c99fb5f9SBaptiste Daroussin * Load and add data from a file 677c99fb5f9SBaptiste Daroussin * @param parser parser structure 678c99fb5f9SBaptiste Daroussin * @param filename the name of file 679c99fb5f9SBaptiste Daroussin * @param err if *err is NULL it is set to parser error 680c99fb5f9SBaptiste Daroussin * @return true if chunk has been added and false in case of error 681c99fb5f9SBaptiste Daroussin */ 682*b04a7a0bSBaptiste Daroussin UCL_EXTERN bool ucl_parser_add_file (struct ucl_parser *parser, 683*b04a7a0bSBaptiste Daroussin const char *filename); 684c99fb5f9SBaptiste Daroussin 685c99fb5f9SBaptiste Daroussin /** 686*b04a7a0bSBaptiste Daroussin * Load and add data from a file descriptor 687*b04a7a0bSBaptiste Daroussin * @param parser parser structure 688*b04a7a0bSBaptiste Daroussin * @param filename the name of file 689*b04a7a0bSBaptiste Daroussin * @param err if *err is NULL it is set to parser error 690*b04a7a0bSBaptiste Daroussin * @return true if chunk has been added and false in case of error 691*b04a7a0bSBaptiste Daroussin */ 692*b04a7a0bSBaptiste Daroussin UCL_EXTERN bool ucl_parser_add_fd (struct ucl_parser *parser, 693*b04a7a0bSBaptiste Daroussin int fd); 694*b04a7a0bSBaptiste Daroussin 695*b04a7a0bSBaptiste Daroussin /** 696*b04a7a0bSBaptiste Daroussin * Get a top object for a parser (refcount is increased) 697c99fb5f9SBaptiste Daroussin * @param parser parser structure 698c99fb5f9SBaptiste Daroussin * @param err if *err is NULL it is set to parser error 699c99fb5f9SBaptiste Daroussin * @return top parser object or NULL 700c99fb5f9SBaptiste Daroussin */ 70136c53d67SBaptiste Daroussin UCL_EXTERN ucl_object_t* ucl_parser_get_object (struct ucl_parser *parser); 702c99fb5f9SBaptiste Daroussin 703c99fb5f9SBaptiste Daroussin /** 704c99fb5f9SBaptiste Daroussin * Get the error string if failing 705c99fb5f9SBaptiste Daroussin * @param parser parser object 706c99fb5f9SBaptiste Daroussin */ 70736c53d67SBaptiste Daroussin UCL_EXTERN const char *ucl_parser_get_error(struct ucl_parser *parser); 708c99fb5f9SBaptiste Daroussin /** 709c99fb5f9SBaptiste Daroussin * Free ucl parser object 710c99fb5f9SBaptiste Daroussin * @param parser parser object 711c99fb5f9SBaptiste Daroussin */ 71236c53d67SBaptiste Daroussin UCL_EXTERN void ucl_parser_free (struct ucl_parser *parser); 713c99fb5f9SBaptiste Daroussin 714c99fb5f9SBaptiste Daroussin /** 715c99fb5f9SBaptiste Daroussin * Add new public key to parser for signatures check 716c99fb5f9SBaptiste Daroussin * @param parser parser object 717c99fb5f9SBaptiste Daroussin * @param key PEM representation of a key 718c99fb5f9SBaptiste Daroussin * @param len length of the key 719c99fb5f9SBaptiste Daroussin * @param err if *err is NULL it is set to parser error 720c99fb5f9SBaptiste Daroussin * @return true if a key has been successfully added 721c99fb5f9SBaptiste Daroussin */ 72236c53d67SBaptiste Daroussin UCL_EXTERN bool ucl_pubkey_add (struct ucl_parser *parser, const unsigned char *key, size_t len); 723c99fb5f9SBaptiste Daroussin 724c99fb5f9SBaptiste Daroussin /** 725c99fb5f9SBaptiste Daroussin * Set FILENAME and CURDIR variables in parser 726c99fb5f9SBaptiste Daroussin * @param parser parser object 727c99fb5f9SBaptiste Daroussin * @param filename filename to set or NULL to set FILENAME to "undef" and CURDIR to getcwd() 728c99fb5f9SBaptiste Daroussin * @param need_expand perform realpath() if this variable is true and filename is not NULL 729c99fb5f9SBaptiste Daroussin * @return true if variables has been set 730c99fb5f9SBaptiste Daroussin */ 73136c53d67SBaptiste Daroussin UCL_EXTERN bool ucl_parser_set_filevars (struct ucl_parser *parser, const char *filename, 732c99fb5f9SBaptiste Daroussin bool need_expand); 733c99fb5f9SBaptiste Daroussin 734c99fb5f9SBaptiste Daroussin /** @} */ 735c99fb5f9SBaptiste Daroussin 736c99fb5f9SBaptiste Daroussin /** 737c99fb5f9SBaptiste Daroussin * @defgroup emitter Emitting functions 738c99fb5f9SBaptiste Daroussin * These functions are used to serialise UCL objects to some string representation. 739c99fb5f9SBaptiste Daroussin * 740c99fb5f9SBaptiste Daroussin * @{ 741c99fb5f9SBaptiste Daroussin */ 742c99fb5f9SBaptiste Daroussin 743c99fb5f9SBaptiste Daroussin /** 744c99fb5f9SBaptiste Daroussin * Structure using for emitter callbacks 745c99fb5f9SBaptiste Daroussin */ 746c99fb5f9SBaptiste Daroussin struct ucl_emitter_functions { 747c99fb5f9SBaptiste Daroussin /** Append a single character */ 748c99fb5f9SBaptiste Daroussin int (*ucl_emitter_append_character) (unsigned char c, size_t nchars, void *ud); 749c99fb5f9SBaptiste Daroussin /** Append a string of a specified length */ 750c99fb5f9SBaptiste Daroussin int (*ucl_emitter_append_len) (unsigned const char *str, size_t len, void *ud); 751c99fb5f9SBaptiste Daroussin /** Append a 64 bit integer */ 752c99fb5f9SBaptiste Daroussin int (*ucl_emitter_append_int) (int64_t elt, void *ud); 753c99fb5f9SBaptiste Daroussin /** Append floating point element */ 754c99fb5f9SBaptiste Daroussin int (*ucl_emitter_append_double) (double elt, void *ud); 755c99fb5f9SBaptiste Daroussin /** Opaque userdata pointer */ 756c99fb5f9SBaptiste Daroussin void *ud; 757c99fb5f9SBaptiste Daroussin }; 758c99fb5f9SBaptiste Daroussin 759c99fb5f9SBaptiste Daroussin /** 760c99fb5f9SBaptiste Daroussin * Emit object to a string 761c99fb5f9SBaptiste Daroussin * @param obj object 762c99fb5f9SBaptiste Daroussin * @param emit_type if type is #UCL_EMIT_JSON then emit json, if type is 763c99fb5f9SBaptiste Daroussin * #UCL_EMIT_CONFIG then emit config like object 764c99fb5f9SBaptiste Daroussin * @return dump of an object (must be freed after using) or NULL in case of error 765c99fb5f9SBaptiste Daroussin */ 766*b04a7a0bSBaptiste Daroussin UCL_EXTERN unsigned char *ucl_object_emit (const ucl_object_t *obj, 767*b04a7a0bSBaptiste Daroussin enum ucl_emitter emit_type); 768c99fb5f9SBaptiste Daroussin 769c99fb5f9SBaptiste Daroussin /** 770c99fb5f9SBaptiste Daroussin * Emit object to a string 771c99fb5f9SBaptiste Daroussin * @param obj object 772c99fb5f9SBaptiste Daroussin * @param emit_type if type is #UCL_EMIT_JSON then emit json, if type is 773c99fb5f9SBaptiste Daroussin * #UCL_EMIT_CONFIG then emit config like object 774c99fb5f9SBaptiste Daroussin * @return dump of an object (must be freed after using) or NULL in case of error 775c99fb5f9SBaptiste Daroussin */ 776*b04a7a0bSBaptiste Daroussin UCL_EXTERN bool ucl_object_emit_full (const ucl_object_t *obj, 777*b04a7a0bSBaptiste Daroussin enum ucl_emitter emit_type, 778c99fb5f9SBaptiste Daroussin struct ucl_emitter_functions *emitter); 779c99fb5f9SBaptiste Daroussin /** @} */ 780c99fb5f9SBaptiste Daroussin 78197bd480fSBaptiste Daroussin /** 78297bd480fSBaptiste Daroussin * @defgroup schema Schema functions 78397bd480fSBaptiste Daroussin * These functions are used to validate UCL objects using json schema format 78497bd480fSBaptiste Daroussin * 78597bd480fSBaptiste Daroussin * @{ 78697bd480fSBaptiste Daroussin */ 78797bd480fSBaptiste Daroussin 78897bd480fSBaptiste Daroussin /** 78997bd480fSBaptiste Daroussin * Used to define UCL schema error 79097bd480fSBaptiste Daroussin */ 79197bd480fSBaptiste Daroussin enum ucl_schema_error_code { 79297bd480fSBaptiste Daroussin UCL_SCHEMA_OK = 0, /**< no error */ 79397bd480fSBaptiste Daroussin UCL_SCHEMA_TYPE_MISMATCH, /**< type of object is incorrect */ 79497bd480fSBaptiste Daroussin UCL_SCHEMA_INVALID_SCHEMA, /**< schema is invalid */ 79597bd480fSBaptiste Daroussin UCL_SCHEMA_MISSING_PROPERTY,/**< one or more missing properties */ 79697bd480fSBaptiste Daroussin UCL_SCHEMA_CONSTRAINT, /**< constraint found */ 79797bd480fSBaptiste Daroussin UCL_SCHEMA_MISSING_DEPENDENCY, /**< missing dependency */ 79897bd480fSBaptiste Daroussin UCL_SCHEMA_UNKNOWN /**< generic error */ 79997bd480fSBaptiste Daroussin }; 80097bd480fSBaptiste Daroussin 80197bd480fSBaptiste Daroussin /** 80297bd480fSBaptiste Daroussin * Generic ucl schema error 80397bd480fSBaptiste Daroussin */ 80497bd480fSBaptiste Daroussin struct ucl_schema_error { 80597bd480fSBaptiste Daroussin enum ucl_schema_error_code code; /**< error code */ 80697bd480fSBaptiste Daroussin char msg[128]; /**< error message */ 807*b04a7a0bSBaptiste Daroussin const ucl_object_t *obj; /**< object where error occured */ 80897bd480fSBaptiste Daroussin }; 80997bd480fSBaptiste Daroussin 81097bd480fSBaptiste Daroussin /** 81197bd480fSBaptiste Daroussin * Validate object `obj` using schema object `schema`. 81297bd480fSBaptiste Daroussin * @param schema schema object 81397bd480fSBaptiste Daroussin * @param obj object to validate 81497bd480fSBaptiste Daroussin * @param err error pointer, if this parameter is not NULL and error has been 81597bd480fSBaptiste Daroussin * occured, then `err` is filled with the exact error definition. 81697bd480fSBaptiste Daroussin * @return true if `obj` is valid using `schema` 81797bd480fSBaptiste Daroussin */ 818*b04a7a0bSBaptiste Daroussin UCL_EXTERN bool ucl_object_validate (const ucl_object_t *schema, 819*b04a7a0bSBaptiste Daroussin const ucl_object_t *obj, struct ucl_schema_error *err); 82097bd480fSBaptiste Daroussin 82197bd480fSBaptiste Daroussin /** @} */ 82297bd480fSBaptiste Daroussin 823c99fb5f9SBaptiste Daroussin #ifdef __cplusplus 824c99fb5f9SBaptiste Daroussin } 825c99fb5f9SBaptiste Daroussin #endif 826c99fb5f9SBaptiste Daroussin /* 827c99fb5f9SBaptiste Daroussin * XXX: Poorly named API functions, need to replace them with the appropriate 828c99fb5f9SBaptiste Daroussin * named function. All API functions *must* use naming ucl_object_*. Usage of 829c99fb5f9SBaptiste Daroussin * ucl_obj* should be avoided. 830c99fb5f9SBaptiste Daroussin */ 831c99fb5f9SBaptiste Daroussin #define ucl_obj_todouble_safe ucl_object_todouble_safe 832c99fb5f9SBaptiste Daroussin #define ucl_obj_todouble ucl_object_todouble 833c99fb5f9SBaptiste Daroussin #define ucl_obj_tostring ucl_object_tostring 834c99fb5f9SBaptiste Daroussin #define ucl_obj_tostring_safe ucl_object_tostring_safe 835c99fb5f9SBaptiste Daroussin #define ucl_obj_tolstring ucl_object_tolstring 836c99fb5f9SBaptiste Daroussin #define ucl_obj_tolstring_safe ucl_object_tolstring_safe 837c99fb5f9SBaptiste Daroussin #define ucl_obj_toint ucl_object_toint 838c99fb5f9SBaptiste Daroussin #define ucl_obj_toint_safe ucl_object_toint_safe 839c99fb5f9SBaptiste Daroussin #define ucl_obj_toboolean ucl_object_toboolean 840c99fb5f9SBaptiste Daroussin #define ucl_obj_toboolean_safe ucl_object_toboolean_safe 841c99fb5f9SBaptiste Daroussin #define ucl_obj_get_key ucl_object_find_key 842c99fb5f9SBaptiste Daroussin #define ucl_obj_get_keyl ucl_object_find_keyl 843c99fb5f9SBaptiste Daroussin #define ucl_obj_unref ucl_object_unref 844c99fb5f9SBaptiste Daroussin #define ucl_obj_ref ucl_object_ref 845c99fb5f9SBaptiste Daroussin #define ucl_obj_free ucl_object_free 846c99fb5f9SBaptiste Daroussin 847c99fb5f9SBaptiste Daroussin #endif /* UCL_H_ */ 848