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 35*36c53d67SBaptiste Daroussin #ifdef _WIN32 36*36c53d67SBaptiste Daroussin # define UCL_EXTERN __declspec(dllexport) 37*36c53d67SBaptiste Daroussin #else 38*36c53d67SBaptiste Daroussin # define UCL_EXTERN 39*36c53d67SBaptiste Daroussin #endif 40*36c53d67SBaptiste 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 84c99fb5f9SBaptiste Daroussin /** 85c99fb5f9SBaptiste Daroussin * @defgroup structures Structures and types 86c99fb5f9SBaptiste Daroussin * UCL defines several enumeration types used for error reporting or specifying flags and attributes. 87c99fb5f9SBaptiste Daroussin * 88c99fb5f9SBaptiste Daroussin * @{ 89c99fb5f9SBaptiste Daroussin */ 90c99fb5f9SBaptiste Daroussin 91c99fb5f9SBaptiste Daroussin /** 92c99fb5f9SBaptiste Daroussin * The common error codes returned by ucl parser 93c99fb5f9SBaptiste Daroussin */ 94c99fb5f9SBaptiste Daroussin typedef enum ucl_error { 95c99fb5f9SBaptiste Daroussin UCL_EOK = 0, /**< No error */ 96c99fb5f9SBaptiste Daroussin UCL_ESYNTAX, /**< Syntax error occurred during parsing */ 97c99fb5f9SBaptiste Daroussin UCL_EIO, /**< IO error occurred during parsing */ 98c99fb5f9SBaptiste Daroussin UCL_ESTATE, /**< Invalid state machine state */ 99c99fb5f9SBaptiste Daroussin UCL_ENESTED, /**< Input has too many recursion levels */ 100c99fb5f9SBaptiste Daroussin UCL_EMACRO, /**< Error processing a macro */ 101c99fb5f9SBaptiste Daroussin UCL_EINTERNAL, /**< Internal unclassified error */ 102c99fb5f9SBaptiste Daroussin UCL_ESSL /**< SSL error */ 103c99fb5f9SBaptiste Daroussin } ucl_error_t; 104c99fb5f9SBaptiste Daroussin 105c99fb5f9SBaptiste Daroussin /** 106c99fb5f9SBaptiste Daroussin * #ucl_object_t may have one of specified types, some types are compatible with each other and some are not. 107c99fb5f9SBaptiste Daroussin * For example, you can always convert #UCL_TIME to #UCL_FLOAT. Also you can convert #UCL_FLOAT to #UCL_INTEGER 108c99fb5f9SBaptiste Daroussin * by loosing floating point. Every object may be converted to a string by #ucl_object_tostring_forced() function. 109c99fb5f9SBaptiste Daroussin * 110c99fb5f9SBaptiste Daroussin */ 111c99fb5f9SBaptiste Daroussin typedef enum ucl_type { 112c99fb5f9SBaptiste Daroussin UCL_OBJECT = 0, /**< UCL object - key/value pairs */ 113c99fb5f9SBaptiste Daroussin UCL_ARRAY, /**< UCL array */ 114c99fb5f9SBaptiste Daroussin UCL_INT, /**< Integer number */ 115c99fb5f9SBaptiste Daroussin UCL_FLOAT, /**< Floating point number */ 116c99fb5f9SBaptiste Daroussin UCL_STRING, /**< Null terminated string */ 117c99fb5f9SBaptiste Daroussin UCL_BOOLEAN, /**< Boolean value */ 118c99fb5f9SBaptiste Daroussin UCL_TIME, /**< Time value (floating point number of seconds) */ 119c99fb5f9SBaptiste Daroussin UCL_USERDATA, /**< Opaque userdata pointer (may be used in macros) */ 120c99fb5f9SBaptiste Daroussin UCL_NULL /**< Null value */ 121c99fb5f9SBaptiste Daroussin } ucl_type_t; 122c99fb5f9SBaptiste Daroussin 123c99fb5f9SBaptiste Daroussin /** 124c99fb5f9SBaptiste Daroussin * You can use one of these types to serialise #ucl_object_t by using ucl_object_emit(). 125c99fb5f9SBaptiste Daroussin */ 126c99fb5f9SBaptiste Daroussin typedef enum ucl_emitter { 127c99fb5f9SBaptiste Daroussin UCL_EMIT_JSON = 0, /**< Emit fine formatted JSON */ 128c99fb5f9SBaptiste Daroussin UCL_EMIT_JSON_COMPACT, /**< Emit compacted JSON */ 129c99fb5f9SBaptiste Daroussin UCL_EMIT_CONFIG, /**< Emit human readable config format */ 130c99fb5f9SBaptiste Daroussin UCL_EMIT_YAML /**< Emit embedded YAML format */ 131c99fb5f9SBaptiste Daroussin } ucl_emitter_t; 132c99fb5f9SBaptiste Daroussin 133c99fb5f9SBaptiste Daroussin /** 134c99fb5f9SBaptiste Daroussin * These flags defines parser behaviour. If you specify #UCL_PARSER_ZEROCOPY you must ensure 135c99fb5f9SBaptiste Daroussin * that the input memory is not freed if an object is in use. Moreover, if you want to use 136c99fb5f9SBaptiste Daroussin * zero-terminated keys and string values then you should not use zero-copy mode, as in this case 137c99fb5f9SBaptiste Daroussin * UCL still has to perform copying implicitly. 138c99fb5f9SBaptiste Daroussin */ 139c99fb5f9SBaptiste Daroussin typedef enum ucl_parser_flags { 140c99fb5f9SBaptiste Daroussin UCL_PARSER_KEY_LOWERCASE = 0x1, /**< Convert all keys to lower case */ 141c99fb5f9SBaptiste Daroussin UCL_PARSER_ZEROCOPY = 0x2 /**< Parse input in zero-copy mode if possible */ 142c99fb5f9SBaptiste Daroussin } ucl_parser_flags_t; 143c99fb5f9SBaptiste Daroussin 144c99fb5f9SBaptiste Daroussin /** 145c99fb5f9SBaptiste Daroussin * String conversion flags, that are used in #ucl_object_fromstring_common function. 146c99fb5f9SBaptiste Daroussin */ 147c99fb5f9SBaptiste Daroussin typedef enum ucl_string_flags { 148c99fb5f9SBaptiste Daroussin UCL_STRING_ESCAPE = 0x1, /**< Perform JSON escape */ 149c99fb5f9SBaptiste Daroussin UCL_STRING_TRIM = 0x2, /**< Trim leading and trailing whitespaces */ 150c99fb5f9SBaptiste Daroussin UCL_STRING_PARSE_BOOLEAN = 0x4, /**< Parse passed string and detect boolean */ 151c99fb5f9SBaptiste Daroussin UCL_STRING_PARSE_INT = 0x8, /**< Parse passed string and detect integer number */ 152c99fb5f9SBaptiste Daroussin UCL_STRING_PARSE_DOUBLE = 0x10, /**< Parse passed string and detect integer or float number */ 153c99fb5f9SBaptiste Daroussin UCL_STRING_PARSE_NUMBER = UCL_STRING_PARSE_INT|UCL_STRING_PARSE_DOUBLE , /**< 154c99fb5f9SBaptiste Daroussin Parse passed string and detect number */ 155c99fb5f9SBaptiste Daroussin UCL_STRING_PARSE = UCL_STRING_PARSE_BOOLEAN|UCL_STRING_PARSE_NUMBER, /**< 156c99fb5f9SBaptiste Daroussin Parse passed string (and detect booleans and numbers) */ 157c99fb5f9SBaptiste Daroussin UCL_STRING_PARSE_BYTES = 0x20 /**< Treat numbers as bytes */ 158c99fb5f9SBaptiste Daroussin } ucl_string_flags_t; 159c99fb5f9SBaptiste Daroussin 160c99fb5f9SBaptiste Daroussin /** 161c99fb5f9SBaptiste Daroussin * Basic flags for an object 162c99fb5f9SBaptiste Daroussin */ 163c99fb5f9SBaptiste Daroussin typedef enum ucl_object_flags { 164c99fb5f9SBaptiste Daroussin UCL_OBJECT_ALLOCATED_KEY = 1, /**< An object has key allocated internally */ 165c99fb5f9SBaptiste Daroussin UCL_OBJECT_ALLOCATED_VALUE = 2, /**< An object has a string value allocated internally */ 166c99fb5f9SBaptiste Daroussin UCL_OBJECT_NEED_KEY_ESCAPE = 4 /**< The key of an object need to be escaped on output */ 167c99fb5f9SBaptiste Daroussin } ucl_object_flags_t; 168c99fb5f9SBaptiste Daroussin 169c99fb5f9SBaptiste Daroussin /** 170c99fb5f9SBaptiste Daroussin * UCL object structure. Please mention that the most of fields should not be touched by 171c99fb5f9SBaptiste Daroussin * UCL users. In future, this structure may be converted to private one. 172c99fb5f9SBaptiste Daroussin */ 173c99fb5f9SBaptiste Daroussin typedef struct ucl_object_s { 174c99fb5f9SBaptiste Daroussin /** 175c99fb5f9SBaptiste Daroussin * Variant value type 176c99fb5f9SBaptiste Daroussin */ 177c99fb5f9SBaptiste Daroussin union { 178c99fb5f9SBaptiste Daroussin int64_t iv; /**< Int value of an object */ 179c99fb5f9SBaptiste Daroussin const char *sv; /**< String value of an object */ 180c99fb5f9SBaptiste Daroussin double dv; /**< Double value of an object */ 181c99fb5f9SBaptiste Daroussin struct ucl_object_s *av; /**< Array */ 182c99fb5f9SBaptiste Daroussin void *ov; /**< Object */ 183c99fb5f9SBaptiste Daroussin void* ud; /**< Opaque user data */ 184c99fb5f9SBaptiste Daroussin } value; 185c99fb5f9SBaptiste Daroussin const char *key; /**< Key of an object */ 186c99fb5f9SBaptiste Daroussin struct ucl_object_s *next; /**< Array handle */ 187c99fb5f9SBaptiste Daroussin struct ucl_object_s *prev; /**< Array handle */ 188c99fb5f9SBaptiste Daroussin unsigned char* trash_stack[2]; /**< Pointer to allocated chunks */ 189c99fb5f9SBaptiste Daroussin unsigned keylen; /**< Lenght of a key */ 190c99fb5f9SBaptiste Daroussin unsigned len; /**< Size of an object */ 191c99fb5f9SBaptiste Daroussin enum ucl_type type; /**< Real type */ 192c99fb5f9SBaptiste Daroussin uint16_t ref; /**< Reference count */ 193c99fb5f9SBaptiste Daroussin uint16_t flags; /**< Object flags */ 194c99fb5f9SBaptiste Daroussin } ucl_object_t; 195c99fb5f9SBaptiste Daroussin 196c99fb5f9SBaptiste Daroussin /** @} */ 197c99fb5f9SBaptiste Daroussin 198c99fb5f9SBaptiste Daroussin /** 199c99fb5f9SBaptiste Daroussin * @defgroup utils Utility functions 200c99fb5f9SBaptiste Daroussin * A number of utility functions simplify handling of UCL objects 201c99fb5f9SBaptiste Daroussin * 202c99fb5f9SBaptiste Daroussin * @{ 203c99fb5f9SBaptiste Daroussin */ 204c99fb5f9SBaptiste Daroussin /** 205c99fb5f9SBaptiste Daroussin * Copy and return a key of an object, returned key is zero-terminated 206c99fb5f9SBaptiste Daroussin * @param obj CL object 207c99fb5f9SBaptiste Daroussin * @return zero terminated key 208c99fb5f9SBaptiste Daroussin */ 209*36c53d67SBaptiste Daroussin UCL_EXTERN char* ucl_copy_key_trash (ucl_object_t *obj); 210c99fb5f9SBaptiste Daroussin 211c99fb5f9SBaptiste Daroussin /** 212c99fb5f9SBaptiste Daroussin * Copy and return a string value of an object, returned key is zero-terminated 213c99fb5f9SBaptiste Daroussin * @param obj CL object 214c99fb5f9SBaptiste Daroussin * @return zero terminated string representation of object value 215c99fb5f9SBaptiste Daroussin */ 216*36c53d67SBaptiste Daroussin UCL_EXTERN char* ucl_copy_value_trash (ucl_object_t *obj); 217c99fb5f9SBaptiste Daroussin 218c99fb5f9SBaptiste Daroussin /** 219c99fb5f9SBaptiste Daroussin * Creates a new object 220c99fb5f9SBaptiste Daroussin * @return new object 221c99fb5f9SBaptiste Daroussin */ 222c99fb5f9SBaptiste Daroussin static inline ucl_object_t* ucl_object_new (void) UCL_WARN_UNUSED_RESULT; 223c99fb5f9SBaptiste Daroussin static inline ucl_object_t * 224c99fb5f9SBaptiste Daroussin ucl_object_new (void) 225c99fb5f9SBaptiste Daroussin { 226c99fb5f9SBaptiste Daroussin ucl_object_t *new; 227c99fb5f9SBaptiste Daroussin new = malloc (sizeof (ucl_object_t)); 228c99fb5f9SBaptiste Daroussin if (new != NULL) { 229c99fb5f9SBaptiste Daroussin memset (new, 0, sizeof (ucl_object_t)); 230c99fb5f9SBaptiste Daroussin new->ref = 1; 231c99fb5f9SBaptiste Daroussin new->type = UCL_NULL; 232c99fb5f9SBaptiste Daroussin } 233c99fb5f9SBaptiste Daroussin return new; 234c99fb5f9SBaptiste Daroussin } 235c99fb5f9SBaptiste Daroussin 236c99fb5f9SBaptiste Daroussin /** 237c99fb5f9SBaptiste Daroussin * Create new object with type specified 238c99fb5f9SBaptiste Daroussin * @param type type of a new object 239c99fb5f9SBaptiste Daroussin * @return new object 240c99fb5f9SBaptiste Daroussin */ 241c99fb5f9SBaptiste Daroussin static inline ucl_object_t* ucl_object_typed_new (unsigned int type) UCL_WARN_UNUSED_RESULT; 242c99fb5f9SBaptiste Daroussin static inline ucl_object_t * 243c99fb5f9SBaptiste Daroussin ucl_object_typed_new (unsigned int type) 244c99fb5f9SBaptiste Daroussin { 245c99fb5f9SBaptiste Daroussin ucl_object_t *new; 246c99fb5f9SBaptiste Daroussin new = malloc (sizeof (ucl_object_t)); 247c99fb5f9SBaptiste Daroussin if (new != NULL) { 248c99fb5f9SBaptiste Daroussin memset (new, 0, sizeof (ucl_object_t)); 249c99fb5f9SBaptiste Daroussin new->ref = 1; 250c99fb5f9SBaptiste Daroussin new->type = (type <= UCL_NULL ? type : UCL_NULL); 251c99fb5f9SBaptiste Daroussin } 252c99fb5f9SBaptiste Daroussin return new; 253c99fb5f9SBaptiste Daroussin } 254c99fb5f9SBaptiste Daroussin 255c99fb5f9SBaptiste Daroussin /** 256c99fb5f9SBaptiste Daroussin * Convert any string to an ucl object making the specified transformations 257c99fb5f9SBaptiste Daroussin * @param str fixed size or NULL terminated string 258c99fb5f9SBaptiste Daroussin * @param len length (if len is zero, than str is treated as NULL terminated) 259c99fb5f9SBaptiste Daroussin * @param flags conversion flags 260c99fb5f9SBaptiste Daroussin * @return new object 261c99fb5f9SBaptiste Daroussin */ 262*36c53d67SBaptiste Daroussin UCL_EXTERN ucl_object_t * ucl_object_fromstring_common (const char *str, size_t len, 263c99fb5f9SBaptiste Daroussin enum ucl_string_flags flags) UCL_WARN_UNUSED_RESULT; 264c99fb5f9SBaptiste Daroussin 265c99fb5f9SBaptiste Daroussin /** 266c99fb5f9SBaptiste Daroussin * Create a UCL object from the specified string 267c99fb5f9SBaptiste Daroussin * @param str NULL terminated string, will be json escaped 268c99fb5f9SBaptiste Daroussin * @return new object 269c99fb5f9SBaptiste Daroussin */ 270c99fb5f9SBaptiste Daroussin static inline ucl_object_t * 271c99fb5f9SBaptiste Daroussin ucl_object_fromstring (const char *str) 272c99fb5f9SBaptiste Daroussin { 273c99fb5f9SBaptiste Daroussin return ucl_object_fromstring_common (str, 0, UCL_STRING_ESCAPE); 274c99fb5f9SBaptiste Daroussin } 275c99fb5f9SBaptiste Daroussin 276c99fb5f9SBaptiste Daroussin /** 277c99fb5f9SBaptiste Daroussin * Create a UCL object from the specified string 278c99fb5f9SBaptiste Daroussin * @param str fixed size string, will be json escaped 279c99fb5f9SBaptiste Daroussin * @param len length of a string 280c99fb5f9SBaptiste Daroussin * @return new object 281c99fb5f9SBaptiste Daroussin */ 282c99fb5f9SBaptiste Daroussin static inline ucl_object_t * 283c99fb5f9SBaptiste Daroussin ucl_object_fromlstring (const char *str, size_t len) 284c99fb5f9SBaptiste Daroussin { 285c99fb5f9SBaptiste Daroussin return ucl_object_fromstring_common (str, len, UCL_STRING_ESCAPE); 286c99fb5f9SBaptiste Daroussin } 287c99fb5f9SBaptiste Daroussin 288c99fb5f9SBaptiste Daroussin /** 289c99fb5f9SBaptiste Daroussin * Create an object from an integer number 290c99fb5f9SBaptiste Daroussin * @param iv number 291c99fb5f9SBaptiste Daroussin * @return new object 292c99fb5f9SBaptiste Daroussin */ 293c99fb5f9SBaptiste Daroussin static inline ucl_object_t * 294c99fb5f9SBaptiste Daroussin ucl_object_fromint (int64_t iv) 295c99fb5f9SBaptiste Daroussin { 296c99fb5f9SBaptiste Daroussin ucl_object_t *obj; 297c99fb5f9SBaptiste Daroussin 298c99fb5f9SBaptiste Daroussin obj = ucl_object_new (); 299c99fb5f9SBaptiste Daroussin if (obj != NULL) { 300c99fb5f9SBaptiste Daroussin obj->type = UCL_INT; 301c99fb5f9SBaptiste Daroussin obj->value.iv = iv; 302c99fb5f9SBaptiste Daroussin } 303c99fb5f9SBaptiste Daroussin 304c99fb5f9SBaptiste Daroussin return obj; 305c99fb5f9SBaptiste Daroussin } 306c99fb5f9SBaptiste Daroussin 307c99fb5f9SBaptiste Daroussin /** 308c99fb5f9SBaptiste Daroussin * Create an object from a float number 309c99fb5f9SBaptiste Daroussin * @param dv number 310c99fb5f9SBaptiste Daroussin * @return new object 311c99fb5f9SBaptiste Daroussin */ 312c99fb5f9SBaptiste Daroussin static inline ucl_object_t * 313c99fb5f9SBaptiste Daroussin ucl_object_fromdouble (double dv) 314c99fb5f9SBaptiste Daroussin { 315c99fb5f9SBaptiste Daroussin ucl_object_t *obj; 316c99fb5f9SBaptiste Daroussin 317c99fb5f9SBaptiste Daroussin obj = ucl_object_new (); 318c99fb5f9SBaptiste Daroussin if (obj != NULL) { 319c99fb5f9SBaptiste Daroussin obj->type = UCL_FLOAT; 320c99fb5f9SBaptiste Daroussin obj->value.dv = dv; 321c99fb5f9SBaptiste Daroussin } 322c99fb5f9SBaptiste Daroussin 323c99fb5f9SBaptiste Daroussin return obj; 324c99fb5f9SBaptiste Daroussin } 325c99fb5f9SBaptiste Daroussin 326c99fb5f9SBaptiste Daroussin /** 327c99fb5f9SBaptiste Daroussin * Create an object from a boolean 328c99fb5f9SBaptiste Daroussin * @param bv bool value 329c99fb5f9SBaptiste Daroussin * @return new object 330c99fb5f9SBaptiste Daroussin */ 331c99fb5f9SBaptiste Daroussin static inline ucl_object_t * 332c99fb5f9SBaptiste Daroussin ucl_object_frombool (bool bv) 333c99fb5f9SBaptiste Daroussin { 334c99fb5f9SBaptiste Daroussin ucl_object_t *obj; 335c99fb5f9SBaptiste Daroussin 336c99fb5f9SBaptiste Daroussin obj = ucl_object_new (); 337c99fb5f9SBaptiste Daroussin if (obj != NULL) { 338c99fb5f9SBaptiste Daroussin obj->type = UCL_BOOLEAN; 339c99fb5f9SBaptiste Daroussin obj->value.iv = bv; 340c99fb5f9SBaptiste Daroussin } 341c99fb5f9SBaptiste Daroussin 342c99fb5f9SBaptiste Daroussin return obj; 343c99fb5f9SBaptiste Daroussin } 344c99fb5f9SBaptiste Daroussin 345c99fb5f9SBaptiste Daroussin /** 346c99fb5f9SBaptiste Daroussin * Insert a object 'elt' to the hash 'top' and associate it with key 'key' 347c99fb5f9SBaptiste Daroussin * @param top destination object (will be created automatically if top is NULL) 348c99fb5f9SBaptiste Daroussin * @param elt element to insert (must NOT be NULL) 349c99fb5f9SBaptiste Daroussin * @param key key to associate with this object (either const or preallocated) 350c99fb5f9SBaptiste Daroussin * @param keylen length of the key (or 0 for NULL terminated keys) 351c99fb5f9SBaptiste Daroussin * @param copy_key make an internal copy of key 352c99fb5f9SBaptiste Daroussin * @return new value of top object 353c99fb5f9SBaptiste Daroussin */ 354*36c53d67SBaptiste Daroussin UCL_EXTERN ucl_object_t* ucl_object_insert_key (ucl_object_t *top, ucl_object_t *elt, 355c99fb5f9SBaptiste Daroussin const char *key, size_t keylen, bool copy_key) UCL_WARN_UNUSED_RESULT; 356c99fb5f9SBaptiste Daroussin 357c99fb5f9SBaptiste Daroussin /** 358c99fb5f9SBaptiste Daroussin * Replace a object 'elt' to the hash 'top' and associate it with key 'key', old object will be unrefed, 359c99fb5f9SBaptiste Daroussin * if no object has been found this function works like ucl_object_insert_key() 360c99fb5f9SBaptiste Daroussin * @param top destination object (will be created automatically if top is NULL) 361c99fb5f9SBaptiste Daroussin * @param elt element to insert (must NOT be NULL) 362c99fb5f9SBaptiste Daroussin * @param key key to associate with this object (either const or preallocated) 363c99fb5f9SBaptiste Daroussin * @param keylen length of the key (or 0 for NULL terminated keys) 364c99fb5f9SBaptiste Daroussin * @param copy_key make an internal copy of key 365c99fb5f9SBaptiste Daroussin * @return new value of top object 366c99fb5f9SBaptiste Daroussin */ 367*36c53d67SBaptiste Daroussin UCL_EXTERN ucl_object_t* ucl_object_replace_key (ucl_object_t *top, ucl_object_t *elt, 368c99fb5f9SBaptiste Daroussin const char *key, size_t keylen, bool copy_key) UCL_WARN_UNUSED_RESULT; 369c99fb5f9SBaptiste Daroussin 370c99fb5f9SBaptiste Daroussin /** 371*36c53d67SBaptiste Daroussin * Delete a object associated with key 'key', old object will be unrefered, 372*36c53d67SBaptiste Daroussin * @param top object 373*36c53d67SBaptiste Daroussin * @param key key associated to the object to remove 374*36c53d67SBaptiste Daroussin * @param keylen length of the key (or 0 for NULL terminated keys) 375*36c53d67SBaptiste Daroussin */ 376*36c53d67SBaptiste Daroussin UCL_EXTERN bool ucl_object_delete_keyl (ucl_object_t *top, const char *key, size_t keylen); 377*36c53d67SBaptiste Daroussin 378*36c53d67SBaptiste Daroussin /** 379*36c53d67SBaptiste Daroussin * Delete a object associated with key 'key', old object will be unrefered, 380*36c53d67SBaptiste Daroussin * @param top object 381*36c53d67SBaptiste Daroussin * @param key key associated to the object to remove 382*36c53d67SBaptiste Daroussin */ 383*36c53d67SBaptiste Daroussin UCL_EXTERN bool ucl_object_delete_key (ucl_object_t *top, const char *key); 384*36c53d67SBaptiste Daroussin 385*36c53d67SBaptiste Daroussin /** 386c99fb5f9SBaptiste Daroussin * Insert a object 'elt' to the hash 'top' and associate it with key 'key', if the specified key exist, 387c99fb5f9SBaptiste Daroussin * try to merge its content 388c99fb5f9SBaptiste Daroussin * @param top destination object (will be created automatically if top is NULL) 389c99fb5f9SBaptiste Daroussin * @param elt element to insert (must NOT be NULL) 390c99fb5f9SBaptiste Daroussin * @param key key to associate with this object (either const or preallocated) 391c99fb5f9SBaptiste Daroussin * @param keylen length of the key (or 0 for NULL terminated keys) 392c99fb5f9SBaptiste Daroussin * @param copy_key make an internal copy of key 393c99fb5f9SBaptiste Daroussin * @return new value of top object 394c99fb5f9SBaptiste Daroussin */ 395*36c53d67SBaptiste Daroussin UCL_EXTERN ucl_object_t* ucl_object_insert_key_merged (ucl_object_t *top, ucl_object_t *elt, 396c99fb5f9SBaptiste Daroussin const char *key, size_t keylen, bool copy_key) UCL_WARN_UNUSED_RESULT; 397c99fb5f9SBaptiste Daroussin 398c99fb5f9SBaptiste Daroussin /** 399c99fb5f9SBaptiste Daroussin * Append an element to the front of array object 400c99fb5f9SBaptiste Daroussin * @param top destination object (will be created automatically if top is NULL) 401c99fb5f9SBaptiste Daroussin * @param elt element to append (must NOT be NULL) 402c99fb5f9SBaptiste Daroussin * @return new value of top object 403c99fb5f9SBaptiste Daroussin */ 404c99fb5f9SBaptiste Daroussin static inline ucl_object_t * ucl_array_append (ucl_object_t *top, 405c99fb5f9SBaptiste Daroussin ucl_object_t *elt) UCL_WARN_UNUSED_RESULT; 406c99fb5f9SBaptiste Daroussin static inline ucl_object_t * 407c99fb5f9SBaptiste Daroussin ucl_array_append (ucl_object_t *top, ucl_object_t *elt) 408c99fb5f9SBaptiste Daroussin { 409c99fb5f9SBaptiste Daroussin ucl_object_t *head; 410c99fb5f9SBaptiste Daroussin 411c99fb5f9SBaptiste Daroussin if (elt == NULL) { 412c99fb5f9SBaptiste Daroussin return NULL; 413c99fb5f9SBaptiste Daroussin } 414c99fb5f9SBaptiste Daroussin 415c99fb5f9SBaptiste Daroussin if (top == NULL) { 416c99fb5f9SBaptiste Daroussin top = ucl_object_typed_new (UCL_ARRAY); 417c99fb5f9SBaptiste Daroussin top->value.av = elt; 418c99fb5f9SBaptiste Daroussin elt->next = NULL; 419c99fb5f9SBaptiste Daroussin elt->prev = elt; 420c99fb5f9SBaptiste Daroussin top->len = 1; 421c99fb5f9SBaptiste Daroussin } 422c99fb5f9SBaptiste Daroussin else { 423c99fb5f9SBaptiste Daroussin head = top->value.av; 424c99fb5f9SBaptiste Daroussin if (head == NULL) { 425c99fb5f9SBaptiste Daroussin top->value.av = elt; 426c99fb5f9SBaptiste Daroussin elt->prev = elt; 427c99fb5f9SBaptiste Daroussin } 428c99fb5f9SBaptiste Daroussin else { 429c99fb5f9SBaptiste Daroussin elt->prev = head->prev; 430c99fb5f9SBaptiste Daroussin head->prev->next = elt; 431c99fb5f9SBaptiste Daroussin head->prev = elt; 432c99fb5f9SBaptiste Daroussin } 433c99fb5f9SBaptiste Daroussin elt->next = NULL; 434c99fb5f9SBaptiste Daroussin top->len ++; 435c99fb5f9SBaptiste Daroussin } 436c99fb5f9SBaptiste Daroussin 437c99fb5f9SBaptiste Daroussin return top; 438c99fb5f9SBaptiste Daroussin } 439c99fb5f9SBaptiste Daroussin 440c99fb5f9SBaptiste Daroussin /** 441c99fb5f9SBaptiste Daroussin * Append an element to the start of array object 442c99fb5f9SBaptiste Daroussin * @param top destination object (will be created automatically if top is NULL) 443c99fb5f9SBaptiste Daroussin * @param elt element to append (must NOT be NULL) 444c99fb5f9SBaptiste Daroussin * @return new value of top object 445c99fb5f9SBaptiste Daroussin */ 446c99fb5f9SBaptiste Daroussin static inline ucl_object_t * ucl_array_prepend (ucl_object_t *top, 447c99fb5f9SBaptiste Daroussin ucl_object_t *elt) UCL_WARN_UNUSED_RESULT; 448c99fb5f9SBaptiste Daroussin static inline ucl_object_t * 449c99fb5f9SBaptiste Daroussin ucl_array_prepend (ucl_object_t *top, ucl_object_t *elt) 450c99fb5f9SBaptiste Daroussin { 451c99fb5f9SBaptiste Daroussin ucl_object_t *head; 452c99fb5f9SBaptiste Daroussin 453c99fb5f9SBaptiste Daroussin if (elt == NULL) { 454c99fb5f9SBaptiste Daroussin return NULL; 455c99fb5f9SBaptiste Daroussin } 456c99fb5f9SBaptiste Daroussin 457c99fb5f9SBaptiste Daroussin if (top == NULL) { 458c99fb5f9SBaptiste Daroussin top = ucl_object_typed_new (UCL_ARRAY); 459c99fb5f9SBaptiste Daroussin top->value.av = elt; 460c99fb5f9SBaptiste Daroussin elt->next = NULL; 461c99fb5f9SBaptiste Daroussin elt->prev = elt; 462c99fb5f9SBaptiste Daroussin top->len = 1; 463c99fb5f9SBaptiste Daroussin } 464c99fb5f9SBaptiste Daroussin else { 465c99fb5f9SBaptiste Daroussin head = top->value.av; 466c99fb5f9SBaptiste Daroussin if (head == NULL) { 467c99fb5f9SBaptiste Daroussin top->value.av = elt; 468c99fb5f9SBaptiste Daroussin elt->prev = elt; 469c99fb5f9SBaptiste Daroussin } 470c99fb5f9SBaptiste Daroussin else { 471c99fb5f9SBaptiste Daroussin elt->prev = head->prev; 472c99fb5f9SBaptiste Daroussin head->prev = elt; 473c99fb5f9SBaptiste Daroussin } 474c99fb5f9SBaptiste Daroussin elt->next = head; 475c99fb5f9SBaptiste Daroussin top->value.av = elt; 476c99fb5f9SBaptiste Daroussin top->len ++; 477c99fb5f9SBaptiste Daroussin } 478c99fb5f9SBaptiste Daroussin 479c99fb5f9SBaptiste Daroussin return top; 480c99fb5f9SBaptiste Daroussin } 481c99fb5f9SBaptiste Daroussin 482c99fb5f9SBaptiste Daroussin /** 483c99fb5f9SBaptiste Daroussin * Removes an element `elt` from the array `top`. Caller must unref the returned object when it is not 484c99fb5f9SBaptiste Daroussin * needed. 485c99fb5f9SBaptiste Daroussin * @param top array ucl object 486c99fb5f9SBaptiste Daroussin * @param elt element to remove 487c99fb5f9SBaptiste Daroussin * @return removed element or NULL if `top` is NULL or not an array 488c99fb5f9SBaptiste Daroussin */ 489c99fb5f9SBaptiste Daroussin static inline ucl_object_t * 490c99fb5f9SBaptiste Daroussin ucl_array_delete (ucl_object_t *top, ucl_object_t *elt) 491c99fb5f9SBaptiste Daroussin { 492c99fb5f9SBaptiste Daroussin ucl_object_t *head; 493c99fb5f9SBaptiste Daroussin 494c99fb5f9SBaptiste Daroussin if (top == NULL || top->type != UCL_ARRAY || top->value.av == NULL) { 495c99fb5f9SBaptiste Daroussin return NULL; 496c99fb5f9SBaptiste Daroussin } 497c99fb5f9SBaptiste Daroussin head = top->value.av; 498c99fb5f9SBaptiste Daroussin 499c99fb5f9SBaptiste Daroussin if (elt->prev == elt) { 500c99fb5f9SBaptiste Daroussin top->value.av = NULL; 501c99fb5f9SBaptiste Daroussin } 502c99fb5f9SBaptiste Daroussin else if (elt == head) { 503c99fb5f9SBaptiste Daroussin elt->next->prev = elt->prev; 504c99fb5f9SBaptiste Daroussin top->value.av = elt->next; 505c99fb5f9SBaptiste Daroussin } 506c99fb5f9SBaptiste Daroussin else { 507c99fb5f9SBaptiste Daroussin elt->prev->next = elt->next; 508c99fb5f9SBaptiste Daroussin if (elt->next) { 509c99fb5f9SBaptiste Daroussin elt->next->prev = elt->prev; 510c99fb5f9SBaptiste Daroussin } 511c99fb5f9SBaptiste Daroussin else { 512c99fb5f9SBaptiste Daroussin head->prev = elt->prev; 513c99fb5f9SBaptiste Daroussin } 514c99fb5f9SBaptiste Daroussin } 515c99fb5f9SBaptiste Daroussin elt->next = NULL; 516c99fb5f9SBaptiste Daroussin elt->prev = elt; 517c99fb5f9SBaptiste Daroussin top->len --; 518c99fb5f9SBaptiste Daroussin 519c99fb5f9SBaptiste Daroussin return elt; 520c99fb5f9SBaptiste Daroussin } 521c99fb5f9SBaptiste Daroussin 522c99fb5f9SBaptiste Daroussin /** 523c99fb5f9SBaptiste Daroussin * Returns the first element of the array `top` 524c99fb5f9SBaptiste Daroussin * @param top array ucl object 525c99fb5f9SBaptiste Daroussin * @return element or NULL if `top` is NULL or not an array 526c99fb5f9SBaptiste Daroussin */ 527c99fb5f9SBaptiste Daroussin static inline ucl_object_t * 528c99fb5f9SBaptiste Daroussin ucl_array_head (ucl_object_t *top) 529c99fb5f9SBaptiste Daroussin { 530c99fb5f9SBaptiste Daroussin if (top == NULL || top->type != UCL_ARRAY || top->value.av == NULL) { 531c99fb5f9SBaptiste Daroussin return NULL; 532c99fb5f9SBaptiste Daroussin } 533c99fb5f9SBaptiste Daroussin return top->value.av; 534c99fb5f9SBaptiste Daroussin } 535c99fb5f9SBaptiste Daroussin 536c99fb5f9SBaptiste Daroussin /** 537c99fb5f9SBaptiste Daroussin * Returns the last element of the array `top` 538c99fb5f9SBaptiste Daroussin * @param top array ucl object 539c99fb5f9SBaptiste Daroussin * @return element or NULL if `top` is NULL or not an array 540c99fb5f9SBaptiste Daroussin */ 541c99fb5f9SBaptiste Daroussin static inline ucl_object_t * 542c99fb5f9SBaptiste Daroussin ucl_array_tail (ucl_object_t *top) 543c99fb5f9SBaptiste Daroussin { 544c99fb5f9SBaptiste Daroussin if (top == NULL || top->type != UCL_ARRAY || top->value.av == NULL) { 545c99fb5f9SBaptiste Daroussin return NULL; 546c99fb5f9SBaptiste Daroussin } 547c99fb5f9SBaptiste Daroussin return top->value.av->prev; 548c99fb5f9SBaptiste Daroussin } 549c99fb5f9SBaptiste Daroussin 550c99fb5f9SBaptiste Daroussin /** 551c99fb5f9SBaptiste Daroussin * Removes the last element from the array `top`. Caller must unref the returned object when it is not 552c99fb5f9SBaptiste Daroussin * needed. 553c99fb5f9SBaptiste Daroussin * @param top array ucl object 554c99fb5f9SBaptiste Daroussin * @return removed element or NULL if `top` is NULL or not an array 555c99fb5f9SBaptiste Daroussin */ 556c99fb5f9SBaptiste Daroussin static inline ucl_object_t * 557c99fb5f9SBaptiste Daroussin ucl_array_pop_last (ucl_object_t *top) 558c99fb5f9SBaptiste Daroussin { 559c99fb5f9SBaptiste Daroussin return ucl_array_delete (top, ucl_array_tail (top)); 560c99fb5f9SBaptiste Daroussin } 561c99fb5f9SBaptiste Daroussin 562c99fb5f9SBaptiste Daroussin /** 563c99fb5f9SBaptiste Daroussin * Removes the first element from the array `top`. Caller must unref the returned object when it is not 564c99fb5f9SBaptiste Daroussin * needed. 565c99fb5f9SBaptiste Daroussin * @param top array ucl object 566c99fb5f9SBaptiste Daroussin * @return removed element or NULL if `top` is NULL or not an array 567c99fb5f9SBaptiste Daroussin */ 568c99fb5f9SBaptiste Daroussin static inline ucl_object_t * 569c99fb5f9SBaptiste Daroussin ucl_array_pop_first (ucl_object_t *top) 570c99fb5f9SBaptiste Daroussin { 571c99fb5f9SBaptiste Daroussin return ucl_array_delete (top, ucl_array_head (top)); 572c99fb5f9SBaptiste Daroussin } 573c99fb5f9SBaptiste Daroussin 574c99fb5f9SBaptiste Daroussin /** 575c99fb5f9SBaptiste Daroussin * Append a element to another element forming an implicit array 576c99fb5f9SBaptiste Daroussin * @param head head to append (may be NULL) 577c99fb5f9SBaptiste Daroussin * @param elt new element 578c99fb5f9SBaptiste Daroussin * @return new head if applicable 579c99fb5f9SBaptiste Daroussin */ 580c99fb5f9SBaptiste Daroussin static inline ucl_object_t * ucl_elt_append (ucl_object_t *head, 581c99fb5f9SBaptiste Daroussin ucl_object_t *elt) UCL_WARN_UNUSED_RESULT; 582c99fb5f9SBaptiste Daroussin static inline ucl_object_t * 583c99fb5f9SBaptiste Daroussin ucl_elt_append (ucl_object_t *head, ucl_object_t *elt) 584c99fb5f9SBaptiste Daroussin { 585c99fb5f9SBaptiste Daroussin 586c99fb5f9SBaptiste Daroussin if (head == NULL) { 587c99fb5f9SBaptiste Daroussin elt->next = NULL; 588c99fb5f9SBaptiste Daroussin elt->prev = elt; 589c99fb5f9SBaptiste Daroussin head = elt; 590c99fb5f9SBaptiste Daroussin } 591c99fb5f9SBaptiste Daroussin else { 592c99fb5f9SBaptiste Daroussin elt->prev = head->prev; 593c99fb5f9SBaptiste Daroussin head->prev->next = elt; 594c99fb5f9SBaptiste Daroussin head->prev = elt; 595c99fb5f9SBaptiste Daroussin elt->next = NULL; 596c99fb5f9SBaptiste Daroussin } 597c99fb5f9SBaptiste Daroussin 598c99fb5f9SBaptiste Daroussin return head; 599c99fb5f9SBaptiste Daroussin } 600c99fb5f9SBaptiste Daroussin 601c99fb5f9SBaptiste Daroussin /** 602c99fb5f9SBaptiste Daroussin * Converts an object to double value 603c99fb5f9SBaptiste Daroussin * @param obj CL object 604c99fb5f9SBaptiste Daroussin * @param target target double variable 605c99fb5f9SBaptiste Daroussin * @return true if conversion was successful 606c99fb5f9SBaptiste Daroussin */ 607c99fb5f9SBaptiste Daroussin static inline bool 608c99fb5f9SBaptiste Daroussin ucl_object_todouble_safe (ucl_object_t *obj, double *target) 609c99fb5f9SBaptiste Daroussin { 610c99fb5f9SBaptiste Daroussin if (obj == NULL) { 611c99fb5f9SBaptiste Daroussin return false; 612c99fb5f9SBaptiste Daroussin } 613c99fb5f9SBaptiste Daroussin switch (obj->type) { 614c99fb5f9SBaptiste Daroussin case UCL_INT: 615c99fb5f9SBaptiste Daroussin *target = obj->value.iv; /* Probaly could cause overflow */ 616c99fb5f9SBaptiste Daroussin break; 617c99fb5f9SBaptiste Daroussin case UCL_FLOAT: 618c99fb5f9SBaptiste Daroussin case UCL_TIME: 619c99fb5f9SBaptiste Daroussin *target = obj->value.dv; 620c99fb5f9SBaptiste Daroussin break; 621c99fb5f9SBaptiste Daroussin default: 622c99fb5f9SBaptiste Daroussin return false; 623c99fb5f9SBaptiste Daroussin } 624c99fb5f9SBaptiste Daroussin 625c99fb5f9SBaptiste Daroussin return true; 626c99fb5f9SBaptiste Daroussin } 627c99fb5f9SBaptiste Daroussin 628c99fb5f9SBaptiste Daroussin /** 629c99fb5f9SBaptiste Daroussin * Unsafe version of \ref ucl_obj_todouble_safe 630c99fb5f9SBaptiste Daroussin * @param obj CL object 631c99fb5f9SBaptiste Daroussin * @return double value 632c99fb5f9SBaptiste Daroussin */ 633c99fb5f9SBaptiste Daroussin static inline double 634c99fb5f9SBaptiste Daroussin ucl_object_todouble (ucl_object_t *obj) 635c99fb5f9SBaptiste Daroussin { 636c99fb5f9SBaptiste Daroussin double result = 0.; 637c99fb5f9SBaptiste Daroussin 638c99fb5f9SBaptiste Daroussin ucl_object_todouble_safe (obj, &result); 639c99fb5f9SBaptiste Daroussin return result; 640c99fb5f9SBaptiste Daroussin } 641c99fb5f9SBaptiste Daroussin 642c99fb5f9SBaptiste Daroussin /** 643c99fb5f9SBaptiste Daroussin * Converts an object to integer value 644c99fb5f9SBaptiste Daroussin * @param obj CL object 645c99fb5f9SBaptiste Daroussin * @param target target integer variable 646c99fb5f9SBaptiste Daroussin * @return true if conversion was successful 647c99fb5f9SBaptiste Daroussin */ 648c99fb5f9SBaptiste Daroussin static inline bool 649c99fb5f9SBaptiste Daroussin ucl_object_toint_safe (ucl_object_t *obj, int64_t *target) 650c99fb5f9SBaptiste Daroussin { 651c99fb5f9SBaptiste Daroussin if (obj == NULL) { 652c99fb5f9SBaptiste Daroussin return false; 653c99fb5f9SBaptiste Daroussin } 654c99fb5f9SBaptiste Daroussin switch (obj->type) { 655c99fb5f9SBaptiste Daroussin case UCL_INT: 656c99fb5f9SBaptiste Daroussin *target = obj->value.iv; 657c99fb5f9SBaptiste Daroussin break; 658c99fb5f9SBaptiste Daroussin case UCL_FLOAT: 659c99fb5f9SBaptiste Daroussin case UCL_TIME: 660c99fb5f9SBaptiste Daroussin *target = obj->value.dv; /* Loosing of decimal points */ 661c99fb5f9SBaptiste Daroussin break; 662c99fb5f9SBaptiste Daroussin default: 663c99fb5f9SBaptiste Daroussin return false; 664c99fb5f9SBaptiste Daroussin } 665c99fb5f9SBaptiste Daroussin 666c99fb5f9SBaptiste Daroussin return true; 667c99fb5f9SBaptiste Daroussin } 668c99fb5f9SBaptiste Daroussin 669c99fb5f9SBaptiste Daroussin /** 670c99fb5f9SBaptiste Daroussin * Unsafe version of \ref ucl_obj_toint_safe 671c99fb5f9SBaptiste Daroussin * @param obj CL object 672c99fb5f9SBaptiste Daroussin * @return int value 673c99fb5f9SBaptiste Daroussin */ 674c99fb5f9SBaptiste Daroussin static inline int64_t 675c99fb5f9SBaptiste Daroussin ucl_object_toint (ucl_object_t *obj) 676c99fb5f9SBaptiste Daroussin { 677c99fb5f9SBaptiste Daroussin int64_t result = 0; 678c99fb5f9SBaptiste Daroussin 679c99fb5f9SBaptiste Daroussin ucl_object_toint_safe (obj, &result); 680c99fb5f9SBaptiste Daroussin return result; 681c99fb5f9SBaptiste Daroussin } 682c99fb5f9SBaptiste Daroussin 683c99fb5f9SBaptiste Daroussin /** 684c99fb5f9SBaptiste Daroussin * Converts an object to boolean value 685c99fb5f9SBaptiste Daroussin * @param obj CL object 686c99fb5f9SBaptiste Daroussin * @param target target boolean variable 687c99fb5f9SBaptiste Daroussin * @return true if conversion was successful 688c99fb5f9SBaptiste Daroussin */ 689c99fb5f9SBaptiste Daroussin static inline bool 690c99fb5f9SBaptiste Daroussin ucl_object_toboolean_safe (ucl_object_t *obj, bool *target) 691c99fb5f9SBaptiste Daroussin { 692c99fb5f9SBaptiste Daroussin if (obj == NULL) { 693c99fb5f9SBaptiste Daroussin return false; 694c99fb5f9SBaptiste Daroussin } 695c99fb5f9SBaptiste Daroussin switch (obj->type) { 696c99fb5f9SBaptiste Daroussin case UCL_BOOLEAN: 697c99fb5f9SBaptiste Daroussin *target = (obj->value.iv == true); 698c99fb5f9SBaptiste Daroussin break; 699c99fb5f9SBaptiste Daroussin default: 700c99fb5f9SBaptiste Daroussin return false; 701c99fb5f9SBaptiste Daroussin } 702c99fb5f9SBaptiste Daroussin 703c99fb5f9SBaptiste Daroussin return true; 704c99fb5f9SBaptiste Daroussin } 705c99fb5f9SBaptiste Daroussin 706c99fb5f9SBaptiste Daroussin /** 707c99fb5f9SBaptiste Daroussin * Unsafe version of \ref ucl_obj_toboolean_safe 708c99fb5f9SBaptiste Daroussin * @param obj CL object 709c99fb5f9SBaptiste Daroussin * @return boolean value 710c99fb5f9SBaptiste Daroussin */ 711c99fb5f9SBaptiste Daroussin static inline bool 712c99fb5f9SBaptiste Daroussin ucl_object_toboolean (ucl_object_t *obj) 713c99fb5f9SBaptiste Daroussin { 714c99fb5f9SBaptiste Daroussin bool result = false; 715c99fb5f9SBaptiste Daroussin 716c99fb5f9SBaptiste Daroussin ucl_object_toboolean_safe (obj, &result); 717c99fb5f9SBaptiste Daroussin return result; 718c99fb5f9SBaptiste Daroussin } 719c99fb5f9SBaptiste Daroussin 720c99fb5f9SBaptiste Daroussin /** 721c99fb5f9SBaptiste Daroussin * Converts an object to string value 722c99fb5f9SBaptiste Daroussin * @param obj CL object 723c99fb5f9SBaptiste Daroussin * @param target target string variable, no need to free value 724c99fb5f9SBaptiste Daroussin * @return true if conversion was successful 725c99fb5f9SBaptiste Daroussin */ 726c99fb5f9SBaptiste Daroussin static inline bool 727c99fb5f9SBaptiste Daroussin ucl_object_tostring_safe (ucl_object_t *obj, const char **target) 728c99fb5f9SBaptiste Daroussin { 729c99fb5f9SBaptiste Daroussin if (obj == NULL) { 730c99fb5f9SBaptiste Daroussin return false; 731c99fb5f9SBaptiste Daroussin } 732c99fb5f9SBaptiste Daroussin 733c99fb5f9SBaptiste Daroussin switch (obj->type) { 734c99fb5f9SBaptiste Daroussin case UCL_STRING: 735c99fb5f9SBaptiste Daroussin *target = ucl_copy_value_trash (obj); 736c99fb5f9SBaptiste Daroussin break; 737c99fb5f9SBaptiste Daroussin default: 738c99fb5f9SBaptiste Daroussin return false; 739c99fb5f9SBaptiste Daroussin } 740c99fb5f9SBaptiste Daroussin 741c99fb5f9SBaptiste Daroussin return true; 742c99fb5f9SBaptiste Daroussin } 743c99fb5f9SBaptiste Daroussin 744c99fb5f9SBaptiste Daroussin /** 745c99fb5f9SBaptiste Daroussin * Unsafe version of \ref ucl_obj_tostring_safe 746c99fb5f9SBaptiste Daroussin * @param obj CL object 747c99fb5f9SBaptiste Daroussin * @return string value 748c99fb5f9SBaptiste Daroussin */ 749c99fb5f9SBaptiste Daroussin static inline const char * 750c99fb5f9SBaptiste Daroussin ucl_object_tostring (ucl_object_t *obj) 751c99fb5f9SBaptiste Daroussin { 752c99fb5f9SBaptiste Daroussin const char *result = NULL; 753c99fb5f9SBaptiste Daroussin 754c99fb5f9SBaptiste Daroussin ucl_object_tostring_safe (obj, &result); 755c99fb5f9SBaptiste Daroussin return result; 756c99fb5f9SBaptiste Daroussin } 757c99fb5f9SBaptiste Daroussin 758c99fb5f9SBaptiste Daroussin /** 759c99fb5f9SBaptiste Daroussin * Convert any object to a string in JSON notation if needed 760c99fb5f9SBaptiste Daroussin * @param obj CL object 761c99fb5f9SBaptiste Daroussin * @return string value 762c99fb5f9SBaptiste Daroussin */ 763c99fb5f9SBaptiste Daroussin static inline const char * 764c99fb5f9SBaptiste Daroussin ucl_object_tostring_forced (ucl_object_t *obj) 765c99fb5f9SBaptiste Daroussin { 766c99fb5f9SBaptiste Daroussin return ucl_copy_value_trash (obj); 767c99fb5f9SBaptiste Daroussin } 768c99fb5f9SBaptiste Daroussin 769c99fb5f9SBaptiste Daroussin /** 770c99fb5f9SBaptiste Daroussin * Return string as char * and len, string may be not zero terminated, more efficient that \ref ucl_obj_tostring as it 771c99fb5f9SBaptiste Daroussin * allows zero-copy (if #UCL_PARSER_ZEROCOPY has been used during parsing) 772c99fb5f9SBaptiste Daroussin * @param obj CL object 773c99fb5f9SBaptiste Daroussin * @param target target string variable, no need to free value 774c99fb5f9SBaptiste Daroussin * @param tlen target length 775c99fb5f9SBaptiste Daroussin * @return true if conversion was successful 776c99fb5f9SBaptiste Daroussin */ 777c99fb5f9SBaptiste Daroussin static inline bool 778c99fb5f9SBaptiste Daroussin ucl_object_tolstring_safe (ucl_object_t *obj, const char **target, size_t *tlen) 779c99fb5f9SBaptiste Daroussin { 780c99fb5f9SBaptiste Daroussin if (obj == NULL) { 781c99fb5f9SBaptiste Daroussin return false; 782c99fb5f9SBaptiste Daroussin } 783c99fb5f9SBaptiste Daroussin switch (obj->type) { 784c99fb5f9SBaptiste Daroussin case UCL_STRING: 785c99fb5f9SBaptiste Daroussin *target = obj->value.sv; 786c99fb5f9SBaptiste Daroussin *tlen = obj->len; 787c99fb5f9SBaptiste Daroussin break; 788c99fb5f9SBaptiste Daroussin default: 789c99fb5f9SBaptiste Daroussin return false; 790c99fb5f9SBaptiste Daroussin } 791c99fb5f9SBaptiste Daroussin 792c99fb5f9SBaptiste Daroussin return true; 793c99fb5f9SBaptiste Daroussin } 794c99fb5f9SBaptiste Daroussin 795c99fb5f9SBaptiste Daroussin /** 796c99fb5f9SBaptiste Daroussin * Unsafe version of \ref ucl_obj_tolstring_safe 797c99fb5f9SBaptiste Daroussin * @param obj CL object 798c99fb5f9SBaptiste Daroussin * @return string value 799c99fb5f9SBaptiste Daroussin */ 800c99fb5f9SBaptiste Daroussin static inline const char * 801c99fb5f9SBaptiste Daroussin ucl_object_tolstring (ucl_object_t *obj, size_t *tlen) 802c99fb5f9SBaptiste Daroussin { 803c99fb5f9SBaptiste Daroussin const char *result = NULL; 804c99fb5f9SBaptiste Daroussin 805c99fb5f9SBaptiste Daroussin ucl_object_tolstring_safe (obj, &result, tlen); 806c99fb5f9SBaptiste Daroussin return result; 807c99fb5f9SBaptiste Daroussin } 808c99fb5f9SBaptiste Daroussin 809c99fb5f9SBaptiste Daroussin /** 810c99fb5f9SBaptiste Daroussin * Return object identified by a key in the specified object 811c99fb5f9SBaptiste Daroussin * @param obj object to get a key from (must be of type UCL_OBJECT) 812c99fb5f9SBaptiste Daroussin * @param key key to search 813c99fb5f9SBaptiste Daroussin * @return object matched the specified key or NULL if key is not found 814c99fb5f9SBaptiste Daroussin */ 815*36c53d67SBaptiste Daroussin UCL_EXTERN ucl_object_t * ucl_object_find_key (ucl_object_t *obj, const char *key); 816c99fb5f9SBaptiste Daroussin 817c99fb5f9SBaptiste Daroussin /** 818c99fb5f9SBaptiste Daroussin * Return object identified by a fixed size key in the specified object 819c99fb5f9SBaptiste Daroussin * @param obj object to get a key from (must be of type UCL_OBJECT) 820c99fb5f9SBaptiste Daroussin * @param key key to search 821c99fb5f9SBaptiste Daroussin * @param klen length of a key 822c99fb5f9SBaptiste Daroussin * @return object matched the specified key or NULL if key is not found 823c99fb5f9SBaptiste Daroussin */ 824*36c53d67SBaptiste Daroussin UCL_EXTERN ucl_object_t *ucl_object_find_keyl (ucl_object_t *obj, const char *key, size_t klen); 825c99fb5f9SBaptiste Daroussin 826c99fb5f9SBaptiste Daroussin /** 827c99fb5f9SBaptiste Daroussin * Returns a key of an object as a NULL terminated string 828c99fb5f9SBaptiste Daroussin * @param obj CL object 829c99fb5f9SBaptiste Daroussin * @return key or NULL if there is no key 830c99fb5f9SBaptiste Daroussin */ 831c99fb5f9SBaptiste Daroussin static inline const char * 832c99fb5f9SBaptiste Daroussin ucl_object_key (ucl_object_t *obj) 833c99fb5f9SBaptiste Daroussin { 834c99fb5f9SBaptiste Daroussin return ucl_copy_key_trash (obj); 835c99fb5f9SBaptiste Daroussin } 836c99fb5f9SBaptiste Daroussin 837c99fb5f9SBaptiste Daroussin /** 838c99fb5f9SBaptiste Daroussin * Returns a key of an object as a fixed size string (may be more efficient) 839c99fb5f9SBaptiste Daroussin * @param obj CL object 840c99fb5f9SBaptiste Daroussin * @param len target key length 841c99fb5f9SBaptiste Daroussin * @return key pointer 842c99fb5f9SBaptiste Daroussin */ 843c99fb5f9SBaptiste Daroussin static inline const char * 844c99fb5f9SBaptiste Daroussin ucl_object_keyl (ucl_object_t *obj, size_t *len) 845c99fb5f9SBaptiste Daroussin { 846c99fb5f9SBaptiste Daroussin *len = obj->keylen; 847c99fb5f9SBaptiste Daroussin return obj->key; 848c99fb5f9SBaptiste Daroussin } 849c99fb5f9SBaptiste Daroussin 850c99fb5f9SBaptiste Daroussin /** 851c99fb5f9SBaptiste Daroussin * Free ucl object 852c99fb5f9SBaptiste Daroussin * @param obj ucl object to free 853c99fb5f9SBaptiste Daroussin */ 854*36c53d67SBaptiste Daroussin UCL_EXTERN void ucl_object_free (ucl_object_t *obj); 855c99fb5f9SBaptiste Daroussin 856c99fb5f9SBaptiste Daroussin /** 857c99fb5f9SBaptiste Daroussin * Increase reference count for an object 858c99fb5f9SBaptiste Daroussin * @param obj object to ref 859c99fb5f9SBaptiste Daroussin */ 860c99fb5f9SBaptiste Daroussin static inline ucl_object_t * 861c99fb5f9SBaptiste Daroussin ucl_object_ref (ucl_object_t *obj) { 862c99fb5f9SBaptiste Daroussin obj->ref ++; 863c99fb5f9SBaptiste Daroussin return obj; 864c99fb5f9SBaptiste Daroussin } 865c99fb5f9SBaptiste Daroussin 866c99fb5f9SBaptiste Daroussin /** 867c99fb5f9SBaptiste Daroussin * Decrease reference count for an object 868c99fb5f9SBaptiste Daroussin * @param obj object to unref 869c99fb5f9SBaptiste Daroussin */ 870c99fb5f9SBaptiste Daroussin static inline void 871c99fb5f9SBaptiste Daroussin ucl_object_unref (ucl_object_t *obj) { 872c99fb5f9SBaptiste Daroussin if (obj != NULL && --obj->ref <= 0) { 873c99fb5f9SBaptiste Daroussin ucl_object_free (obj); 874c99fb5f9SBaptiste Daroussin } 875c99fb5f9SBaptiste Daroussin } 876c99fb5f9SBaptiste Daroussin /** 877c99fb5f9SBaptiste Daroussin * Opaque iterator object 878c99fb5f9SBaptiste Daroussin */ 879c99fb5f9SBaptiste Daroussin typedef void* ucl_object_iter_t; 880c99fb5f9SBaptiste Daroussin 881c99fb5f9SBaptiste Daroussin /** 882c99fb5f9SBaptiste Daroussin * Get next key from an object 883c99fb5f9SBaptiste Daroussin * @param obj object to iterate 884c99fb5f9SBaptiste Daroussin * @param iter opaque iterator, must be set to NULL on the first call: 885c99fb5f9SBaptiste Daroussin * ucl_object_iter_t it = NULL; 886c99fb5f9SBaptiste Daroussin * while ((cur = ucl_iterate_object (obj, &it)) != NULL) ... 887c99fb5f9SBaptiste Daroussin * @return the next object or NULL 888c99fb5f9SBaptiste Daroussin */ 889*36c53d67SBaptiste Daroussin UCL_EXTERN ucl_object_t* ucl_iterate_object (ucl_object_t *obj, ucl_object_iter_t *iter, bool expand_values); 890c99fb5f9SBaptiste Daroussin /** @} */ 891c99fb5f9SBaptiste Daroussin 892c99fb5f9SBaptiste Daroussin 893c99fb5f9SBaptiste Daroussin /** 894c99fb5f9SBaptiste Daroussin * @defgroup parser Parsing functions 895c99fb5f9SBaptiste Daroussin * These functions are used to parse UCL objects 896c99fb5f9SBaptiste Daroussin * 897c99fb5f9SBaptiste Daroussin * @{ 898c99fb5f9SBaptiste Daroussin */ 899c99fb5f9SBaptiste Daroussin 900c99fb5f9SBaptiste Daroussin /** 901c99fb5f9SBaptiste Daroussin * Macro handler for a parser 902c99fb5f9SBaptiste Daroussin * @param data the content of macro 903c99fb5f9SBaptiste Daroussin * @param len the length of content 904c99fb5f9SBaptiste Daroussin * @param ud opaque user data 905c99fb5f9SBaptiste Daroussin * @param err error pointer 906c99fb5f9SBaptiste Daroussin * @return true if macro has been parsed 907c99fb5f9SBaptiste Daroussin */ 908c99fb5f9SBaptiste Daroussin typedef bool (*ucl_macro_handler) (const unsigned char *data, size_t len, void* ud); 909c99fb5f9SBaptiste Daroussin 910c99fb5f9SBaptiste Daroussin /* Opaque parser */ 911c99fb5f9SBaptiste Daroussin struct ucl_parser; 912c99fb5f9SBaptiste Daroussin 913c99fb5f9SBaptiste Daroussin /** 914c99fb5f9SBaptiste Daroussin * Creates new parser object 915c99fb5f9SBaptiste Daroussin * @param pool pool to allocate memory from 916c99fb5f9SBaptiste Daroussin * @return new parser object 917c99fb5f9SBaptiste Daroussin */ 918*36c53d67SBaptiste Daroussin UCL_EXTERN struct ucl_parser* ucl_parser_new (int flags); 919c99fb5f9SBaptiste Daroussin 920c99fb5f9SBaptiste Daroussin /** 921c99fb5f9SBaptiste Daroussin * Register new handler for a macro 922c99fb5f9SBaptiste Daroussin * @param parser parser object 923c99fb5f9SBaptiste Daroussin * @param macro macro name (without leading dot) 924c99fb5f9SBaptiste Daroussin * @param handler handler (it is called immediately after macro is parsed) 925c99fb5f9SBaptiste Daroussin * @param ud opaque user data for a handler 926c99fb5f9SBaptiste Daroussin */ 927*36c53d67SBaptiste Daroussin UCL_EXTERN void ucl_parser_register_macro (struct ucl_parser *parser, const char *macro, 928c99fb5f9SBaptiste Daroussin ucl_macro_handler handler, void* ud); 929c99fb5f9SBaptiste Daroussin 930c99fb5f9SBaptiste Daroussin /** 931c99fb5f9SBaptiste Daroussin * Register new parser variable 932c99fb5f9SBaptiste Daroussin * @param parser parser object 933c99fb5f9SBaptiste Daroussin * @param var variable name 934c99fb5f9SBaptiste Daroussin * @param value variable value 935c99fb5f9SBaptiste Daroussin */ 936*36c53d67SBaptiste Daroussin UCL_EXTERN void ucl_parser_register_variable (struct ucl_parser *parser, const char *var, 937c99fb5f9SBaptiste Daroussin const char *value); 938c99fb5f9SBaptiste Daroussin 939c99fb5f9SBaptiste Daroussin /** 940c99fb5f9SBaptiste Daroussin * Load new chunk to a parser 941c99fb5f9SBaptiste Daroussin * @param parser parser structure 942c99fb5f9SBaptiste Daroussin * @param data the pointer to the beginning of a chunk 943c99fb5f9SBaptiste Daroussin * @param len the length of a chunk 944c99fb5f9SBaptiste Daroussin * @param err if *err is NULL it is set to parser error 945c99fb5f9SBaptiste Daroussin * @return true if chunk has been added and false in case of error 946c99fb5f9SBaptiste Daroussin */ 947*36c53d67SBaptiste Daroussin UCL_EXTERN bool ucl_parser_add_chunk (struct ucl_parser *parser, const unsigned char *data, size_t len); 948c99fb5f9SBaptiste Daroussin 949c99fb5f9SBaptiste Daroussin /** 950c99fb5f9SBaptiste Daroussin * Load and add data from a file 951c99fb5f9SBaptiste Daroussin * @param parser parser structure 952c99fb5f9SBaptiste Daroussin * @param filename the name of file 953c99fb5f9SBaptiste Daroussin * @param err if *err is NULL it is set to parser error 954c99fb5f9SBaptiste Daroussin * @return true if chunk has been added and false in case of error 955c99fb5f9SBaptiste Daroussin */ 956*36c53d67SBaptiste Daroussin UCL_EXTERN bool ucl_parser_add_file (struct ucl_parser *parser, const char *filename); 957c99fb5f9SBaptiste Daroussin 958c99fb5f9SBaptiste Daroussin /** 959c99fb5f9SBaptiste Daroussin * Get a top object for a parser 960c99fb5f9SBaptiste Daroussin * @param parser parser structure 961c99fb5f9SBaptiste Daroussin * @param err if *err is NULL it is set to parser error 962c99fb5f9SBaptiste Daroussin * @return top parser object or NULL 963c99fb5f9SBaptiste Daroussin */ 964*36c53d67SBaptiste Daroussin UCL_EXTERN ucl_object_t* ucl_parser_get_object (struct ucl_parser *parser); 965c99fb5f9SBaptiste Daroussin 966c99fb5f9SBaptiste Daroussin /** 967c99fb5f9SBaptiste Daroussin * Get the error string if failing 968c99fb5f9SBaptiste Daroussin * @param parser parser object 969c99fb5f9SBaptiste Daroussin */ 970*36c53d67SBaptiste Daroussin UCL_EXTERN const char *ucl_parser_get_error(struct ucl_parser *parser); 971c99fb5f9SBaptiste Daroussin /** 972c99fb5f9SBaptiste Daroussin * Free ucl parser object 973c99fb5f9SBaptiste Daroussin * @param parser parser object 974c99fb5f9SBaptiste Daroussin */ 975*36c53d67SBaptiste Daroussin UCL_EXTERN void ucl_parser_free (struct ucl_parser *parser); 976c99fb5f9SBaptiste Daroussin 977c99fb5f9SBaptiste Daroussin /** 978c99fb5f9SBaptiste Daroussin * Add new public key to parser for signatures check 979c99fb5f9SBaptiste Daroussin * @param parser parser object 980c99fb5f9SBaptiste Daroussin * @param key PEM representation of a key 981c99fb5f9SBaptiste Daroussin * @param len length of the key 982c99fb5f9SBaptiste Daroussin * @param err if *err is NULL it is set to parser error 983c99fb5f9SBaptiste Daroussin * @return true if a key has been successfully added 984c99fb5f9SBaptiste Daroussin */ 985*36c53d67SBaptiste Daroussin UCL_EXTERN bool ucl_pubkey_add (struct ucl_parser *parser, const unsigned char *key, size_t len); 986c99fb5f9SBaptiste Daroussin 987c99fb5f9SBaptiste Daroussin /** 988c99fb5f9SBaptiste Daroussin * Set FILENAME and CURDIR variables in parser 989c99fb5f9SBaptiste Daroussin * @param parser parser object 990c99fb5f9SBaptiste Daroussin * @param filename filename to set or NULL to set FILENAME to "undef" and CURDIR to getcwd() 991c99fb5f9SBaptiste Daroussin * @param need_expand perform realpath() if this variable is true and filename is not NULL 992c99fb5f9SBaptiste Daroussin * @return true if variables has been set 993c99fb5f9SBaptiste Daroussin */ 994*36c53d67SBaptiste Daroussin UCL_EXTERN bool ucl_parser_set_filevars (struct ucl_parser *parser, const char *filename, 995c99fb5f9SBaptiste Daroussin bool need_expand); 996c99fb5f9SBaptiste Daroussin 997c99fb5f9SBaptiste Daroussin /** @} */ 998c99fb5f9SBaptiste Daroussin 999c99fb5f9SBaptiste Daroussin /** 1000c99fb5f9SBaptiste Daroussin * @defgroup emitter Emitting functions 1001c99fb5f9SBaptiste Daroussin * These functions are used to serialise UCL objects to some string representation. 1002c99fb5f9SBaptiste Daroussin * 1003c99fb5f9SBaptiste Daroussin * @{ 1004c99fb5f9SBaptiste Daroussin */ 1005c99fb5f9SBaptiste Daroussin 1006c99fb5f9SBaptiste Daroussin /** 1007c99fb5f9SBaptiste Daroussin * Structure using for emitter callbacks 1008c99fb5f9SBaptiste Daroussin */ 1009c99fb5f9SBaptiste Daroussin struct ucl_emitter_functions { 1010c99fb5f9SBaptiste Daroussin /** Append a single character */ 1011c99fb5f9SBaptiste Daroussin int (*ucl_emitter_append_character) (unsigned char c, size_t nchars, void *ud); 1012c99fb5f9SBaptiste Daroussin /** Append a string of a specified length */ 1013c99fb5f9SBaptiste Daroussin int (*ucl_emitter_append_len) (unsigned const char *str, size_t len, void *ud); 1014c99fb5f9SBaptiste Daroussin /** Append a 64 bit integer */ 1015c99fb5f9SBaptiste Daroussin int (*ucl_emitter_append_int) (int64_t elt, void *ud); 1016c99fb5f9SBaptiste Daroussin /** Append floating point element */ 1017c99fb5f9SBaptiste Daroussin int (*ucl_emitter_append_double) (double elt, void *ud); 1018c99fb5f9SBaptiste Daroussin /** Opaque userdata pointer */ 1019c99fb5f9SBaptiste Daroussin void *ud; 1020c99fb5f9SBaptiste Daroussin }; 1021c99fb5f9SBaptiste Daroussin 1022c99fb5f9SBaptiste Daroussin /** 1023c99fb5f9SBaptiste Daroussin * Emit object to a string 1024c99fb5f9SBaptiste Daroussin * @param obj object 1025c99fb5f9SBaptiste Daroussin * @param emit_type if type is #UCL_EMIT_JSON then emit json, if type is 1026c99fb5f9SBaptiste Daroussin * #UCL_EMIT_CONFIG then emit config like object 1027c99fb5f9SBaptiste Daroussin * @return dump of an object (must be freed after using) or NULL in case of error 1028c99fb5f9SBaptiste Daroussin */ 1029*36c53d67SBaptiste Daroussin UCL_EXTERN unsigned char *ucl_object_emit (ucl_object_t *obj, enum ucl_emitter emit_type); 1030c99fb5f9SBaptiste Daroussin 1031c99fb5f9SBaptiste Daroussin /** 1032c99fb5f9SBaptiste Daroussin * Emit object to a string 1033c99fb5f9SBaptiste Daroussin * @param obj object 1034c99fb5f9SBaptiste Daroussin * @param emit_type if type is #UCL_EMIT_JSON then emit json, if type is 1035c99fb5f9SBaptiste Daroussin * #UCL_EMIT_CONFIG then emit config like object 1036c99fb5f9SBaptiste Daroussin * @return dump of an object (must be freed after using) or NULL in case of error 1037c99fb5f9SBaptiste Daroussin */ 1038*36c53d67SBaptiste Daroussin UCL_EXTERN bool ucl_object_emit_full (ucl_object_t *obj, enum ucl_emitter emit_type, 1039c99fb5f9SBaptiste Daroussin struct ucl_emitter_functions *emitter); 1040c99fb5f9SBaptiste Daroussin /** @} */ 1041c99fb5f9SBaptiste Daroussin 1042c99fb5f9SBaptiste Daroussin #ifdef __cplusplus 1043c99fb5f9SBaptiste Daroussin } 1044c99fb5f9SBaptiste Daroussin #endif 1045c99fb5f9SBaptiste Daroussin /* 1046c99fb5f9SBaptiste Daroussin * XXX: Poorly named API functions, need to replace them with the appropriate 1047c99fb5f9SBaptiste Daroussin * named function. All API functions *must* use naming ucl_object_*. Usage of 1048c99fb5f9SBaptiste Daroussin * ucl_obj* should be avoided. 1049c99fb5f9SBaptiste Daroussin */ 1050c99fb5f9SBaptiste Daroussin #define ucl_obj_todouble_safe ucl_object_todouble_safe 1051c99fb5f9SBaptiste Daroussin #define ucl_obj_todouble ucl_object_todouble 1052c99fb5f9SBaptiste Daroussin #define ucl_obj_tostring ucl_object_tostring 1053c99fb5f9SBaptiste Daroussin #define ucl_obj_tostring_safe ucl_object_tostring_safe 1054c99fb5f9SBaptiste Daroussin #define ucl_obj_tolstring ucl_object_tolstring 1055c99fb5f9SBaptiste Daroussin #define ucl_obj_tolstring_safe ucl_object_tolstring_safe 1056c99fb5f9SBaptiste Daroussin #define ucl_obj_toint ucl_object_toint 1057c99fb5f9SBaptiste Daroussin #define ucl_obj_toint_safe ucl_object_toint_safe 1058c99fb5f9SBaptiste Daroussin #define ucl_obj_toboolean ucl_object_toboolean 1059c99fb5f9SBaptiste Daroussin #define ucl_obj_toboolean_safe ucl_object_toboolean_safe 1060c99fb5f9SBaptiste Daroussin #define ucl_obj_get_key ucl_object_find_key 1061c99fb5f9SBaptiste Daroussin #define ucl_obj_get_keyl ucl_object_find_keyl 1062c99fb5f9SBaptiste Daroussin #define ucl_obj_unref ucl_object_unref 1063c99fb5f9SBaptiste Daroussin #define ucl_obj_ref ucl_object_ref 1064c99fb5f9SBaptiste Daroussin #define ucl_obj_free ucl_object_free 1065c99fb5f9SBaptiste Daroussin 1066c99fb5f9SBaptiste Daroussin #endif /* UCL_H_ */ 1067