1262395Sbapt/* Copyright (c) 2013, Vsevolod Stakhov 2262395Sbapt * All rights reserved. 3262395Sbapt * 4262395Sbapt * Redistribution and use in source and binary forms, with or without 5262395Sbapt * modification, are permitted provided that the following conditions are met: 6262395Sbapt * * Redistributions of source code must retain the above copyright 7262395Sbapt * notice, this list of conditions and the following disclaimer. 8262395Sbapt * * Redistributions in binary form must reproduce the above copyright 9262395Sbapt * notice, this list of conditions and the following disclaimer in the 10262395Sbapt * documentation and/or other materials provided with the distribution. 11262395Sbapt * 12262395Sbapt * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY 13262395Sbapt * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 14262395Sbapt * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 15262395Sbapt * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY 16262395Sbapt * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 17262395Sbapt * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 18262395Sbapt * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 19262395Sbapt * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 20262395Sbapt * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 21262395Sbapt * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 22262395Sbapt */ 23262395Sbapt 24262395Sbapt#ifndef UCL_H_ 25262395Sbapt#define UCL_H_ 26262395Sbapt 27262395Sbapt#include <string.h> 28262395Sbapt#include <stddef.h> 29262395Sbapt#include <stdlib.h> 30262395Sbapt#include <stdint.h> 31262395Sbapt#include <stdbool.h> 32262395Sbapt#include <stdarg.h> 33262395Sbapt#include <stdio.h> 34262395Sbapt 35263032Sbapt#ifdef _WIN32 36263032Sbapt# define UCL_EXTERN __declspec(dllexport) 37263032Sbapt#else 38263032Sbapt# define UCL_EXTERN 39263032Sbapt#endif 40263032Sbapt 41262395Sbapt/** 42262395Sbapt * @mainpage 43262395Sbapt * This is a reference manual for UCL API. You may find the description of UCL format by following this 44262395Sbapt * [github repository](https://github.com/vstakhov/libucl). 45262395Sbapt * 46262395Sbapt * This manual has several main sections: 47262395Sbapt * - @ref structures 48262395Sbapt * - @ref utils 49262395Sbapt * - @ref parser 50262395Sbapt * - @ref emitter 51262395Sbapt */ 52262395Sbapt 53262395Sbapt/** 54262395Sbapt * @file ucl.h 55262395Sbapt * @brief UCL parsing and emitting functions 56262395Sbapt * 57262395Sbapt * UCL is universal configuration language, which is a form of 58262395Sbapt * JSON with less strict rules that make it more comfortable for 59262395Sbapt * using as a configuration language 60262395Sbapt */ 61262395Sbapt#ifdef __cplusplus 62262395Sbaptextern "C" { 63262395Sbapt#endif 64262395Sbapt/* 65262395Sbapt * Memory allocation utilities 66262395Sbapt * UCL_ALLOC(size) - allocate memory for UCL 67262395Sbapt * UCL_FREE(size, ptr) - free memory of specified size at ptr 68262395Sbapt * Default: malloc and free 69262395Sbapt */ 70262395Sbapt#ifndef UCL_ALLOC 71262395Sbapt#define UCL_ALLOC(size) malloc(size) 72262395Sbapt#endif 73262395Sbapt#ifndef UCL_FREE 74262395Sbapt#define UCL_FREE(size, ptr) free(ptr) 75262395Sbapt#endif 76262395Sbapt 77262395Sbapt#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) 78262395Sbapt#define UCL_WARN_UNUSED_RESULT \ 79262395Sbapt __attribute__((warn_unused_result)) 80262395Sbapt#else 81262395Sbapt#define UCL_WARN_UNUSED_RESULT 82262395Sbapt#endif 83262395Sbapt 84262395Sbapt/** 85262395Sbapt * @defgroup structures Structures and types 86262395Sbapt * UCL defines several enumeration types used for error reporting or specifying flags and attributes. 87262395Sbapt * 88262395Sbapt * @{ 89262395Sbapt */ 90262395Sbapt 91262395Sbapt/** 92262395Sbapt * The common error codes returned by ucl parser 93262395Sbapt */ 94262395Sbapttypedef enum ucl_error { 95262395Sbapt UCL_EOK = 0, /**< No error */ 96262395Sbapt UCL_ESYNTAX, /**< Syntax error occurred during parsing */ 97262395Sbapt UCL_EIO, /**< IO error occurred during parsing */ 98262395Sbapt UCL_ESTATE, /**< Invalid state machine state */ 99262395Sbapt UCL_ENESTED, /**< Input has too many recursion levels */ 100262395Sbapt UCL_EMACRO, /**< Error processing a macro */ 101262395Sbapt UCL_EINTERNAL, /**< Internal unclassified error */ 102262395Sbapt UCL_ESSL /**< SSL error */ 103262395Sbapt} ucl_error_t; 104262395Sbapt 105262395Sbapt/** 106262395Sbapt * #ucl_object_t may have one of specified types, some types are compatible with each other and some are not. 107262395Sbapt * For example, you can always convert #UCL_TIME to #UCL_FLOAT. Also you can convert #UCL_FLOAT to #UCL_INTEGER 108262395Sbapt * by loosing floating point. Every object may be converted to a string by #ucl_object_tostring_forced() function. 109262395Sbapt * 110262395Sbapt */ 111262395Sbapttypedef enum ucl_type { 112262395Sbapt UCL_OBJECT = 0, /**< UCL object - key/value pairs */ 113262395Sbapt UCL_ARRAY, /**< UCL array */ 114262395Sbapt UCL_INT, /**< Integer number */ 115262395Sbapt UCL_FLOAT, /**< Floating point number */ 116262395Sbapt UCL_STRING, /**< Null terminated string */ 117262395Sbapt UCL_BOOLEAN, /**< Boolean value */ 118262395Sbapt UCL_TIME, /**< Time value (floating point number of seconds) */ 119262395Sbapt UCL_USERDATA, /**< Opaque userdata pointer (may be used in macros) */ 120262395Sbapt UCL_NULL /**< Null value */ 121262395Sbapt} ucl_type_t; 122262395Sbapt 123262395Sbapt/** 124262395Sbapt * You can use one of these types to serialise #ucl_object_t by using ucl_object_emit(). 125262395Sbapt */ 126262395Sbapttypedef enum ucl_emitter { 127262395Sbapt UCL_EMIT_JSON = 0, /**< Emit fine formatted JSON */ 128262395Sbapt UCL_EMIT_JSON_COMPACT, /**< Emit compacted JSON */ 129262395Sbapt UCL_EMIT_CONFIG, /**< Emit human readable config format */ 130262395Sbapt UCL_EMIT_YAML /**< Emit embedded YAML format */ 131262395Sbapt} ucl_emitter_t; 132262395Sbapt 133262395Sbapt/** 134262395Sbapt * These flags defines parser behaviour. If you specify #UCL_PARSER_ZEROCOPY you must ensure 135262395Sbapt * that the input memory is not freed if an object is in use. Moreover, if you want to use 136262395Sbapt * zero-terminated keys and string values then you should not use zero-copy mode, as in this case 137262395Sbapt * UCL still has to perform copying implicitly. 138262395Sbapt */ 139262395Sbapttypedef enum ucl_parser_flags { 140262395Sbapt UCL_PARSER_KEY_LOWERCASE = 0x1, /**< Convert all keys to lower case */ 141262395Sbapt UCL_PARSER_ZEROCOPY = 0x2 /**< Parse input in zero-copy mode if possible */ 142262395Sbapt} ucl_parser_flags_t; 143262395Sbapt 144262395Sbapt/** 145262395Sbapt * String conversion flags, that are used in #ucl_object_fromstring_common function. 146262395Sbapt */ 147262395Sbapttypedef enum ucl_string_flags { 148262395Sbapt UCL_STRING_ESCAPE = 0x1, /**< Perform JSON escape */ 149262395Sbapt UCL_STRING_TRIM = 0x2, /**< Trim leading and trailing whitespaces */ 150262395Sbapt UCL_STRING_PARSE_BOOLEAN = 0x4, /**< Parse passed string and detect boolean */ 151262395Sbapt UCL_STRING_PARSE_INT = 0x8, /**< Parse passed string and detect integer number */ 152262395Sbapt UCL_STRING_PARSE_DOUBLE = 0x10, /**< Parse passed string and detect integer or float number */ 153262395Sbapt UCL_STRING_PARSE_NUMBER = UCL_STRING_PARSE_INT|UCL_STRING_PARSE_DOUBLE , /**< 154262395Sbapt Parse passed string and detect number */ 155262395Sbapt UCL_STRING_PARSE = UCL_STRING_PARSE_BOOLEAN|UCL_STRING_PARSE_NUMBER, /**< 156262395Sbapt Parse passed string (and detect booleans and numbers) */ 157262395Sbapt UCL_STRING_PARSE_BYTES = 0x20 /**< Treat numbers as bytes */ 158262395Sbapt} ucl_string_flags_t; 159262395Sbapt 160262395Sbapt/** 161262395Sbapt * Basic flags for an object 162262395Sbapt */ 163262395Sbapttypedef enum ucl_object_flags { 164262395Sbapt UCL_OBJECT_ALLOCATED_KEY = 1, /**< An object has key allocated internally */ 165262395Sbapt UCL_OBJECT_ALLOCATED_VALUE = 2, /**< An object has a string value allocated internally */ 166262395Sbapt UCL_OBJECT_NEED_KEY_ESCAPE = 4 /**< The key of an object need to be escaped on output */ 167262395Sbapt} ucl_object_flags_t; 168262395Sbapt 169262395Sbapt/** 170262395Sbapt * UCL object structure. Please mention that the most of fields should not be touched by 171262395Sbapt * UCL users. In future, this structure may be converted to private one. 172262395Sbapt */ 173262395Sbapttypedef struct ucl_object_s { 174262395Sbapt /** 175262395Sbapt * Variant value type 176262395Sbapt */ 177262395Sbapt union { 178262395Sbapt int64_t iv; /**< Int value of an object */ 179262395Sbapt const char *sv; /**< String value of an object */ 180262395Sbapt double dv; /**< Double value of an object */ 181262395Sbapt struct ucl_object_s *av; /**< Array */ 182262395Sbapt void *ov; /**< Object */ 183262395Sbapt void* ud; /**< Opaque user data */ 184262395Sbapt } value; 185262395Sbapt const char *key; /**< Key of an object */ 186262395Sbapt struct ucl_object_s *next; /**< Array handle */ 187262395Sbapt struct ucl_object_s *prev; /**< Array handle */ 188262395Sbapt unsigned char* trash_stack[2]; /**< Pointer to allocated chunks */ 189262395Sbapt unsigned keylen; /**< Lenght of a key */ 190262395Sbapt unsigned len; /**< Size of an object */ 191262395Sbapt enum ucl_type type; /**< Real type */ 192262395Sbapt uint16_t ref; /**< Reference count */ 193262395Sbapt uint16_t flags; /**< Object flags */ 194262395Sbapt} ucl_object_t; 195262395Sbapt 196262395Sbapt/** @} */ 197262395Sbapt 198262395Sbapt/** 199262395Sbapt * @defgroup utils Utility functions 200262395Sbapt * A number of utility functions simplify handling of UCL objects 201262395Sbapt * 202262395Sbapt * @{ 203262395Sbapt */ 204262395Sbapt/** 205262395Sbapt * Copy and return a key of an object, returned key is zero-terminated 206262395Sbapt * @param obj CL object 207262395Sbapt * @return zero terminated key 208262395Sbapt */ 209263032SbaptUCL_EXTERN char* ucl_copy_key_trash (ucl_object_t *obj); 210262395Sbapt 211262395Sbapt/** 212262395Sbapt * Copy and return a string value of an object, returned key is zero-terminated 213262395Sbapt * @param obj CL object 214262395Sbapt * @return zero terminated string representation of object value 215262395Sbapt */ 216263032SbaptUCL_EXTERN char* ucl_copy_value_trash (ucl_object_t *obj); 217262395Sbapt 218262395Sbapt/** 219262395Sbapt * Creates a new object 220262395Sbapt * @return new object 221262395Sbapt */ 222262395Sbaptstatic inline ucl_object_t* ucl_object_new (void) UCL_WARN_UNUSED_RESULT; 223262395Sbaptstatic inline ucl_object_t * 224262395Sbaptucl_object_new (void) 225262395Sbapt{ 226262395Sbapt ucl_object_t *new; 227262395Sbapt new = malloc (sizeof (ucl_object_t)); 228262395Sbapt if (new != NULL) { 229262395Sbapt memset (new, 0, sizeof (ucl_object_t)); 230262395Sbapt new->ref = 1; 231262395Sbapt new->type = UCL_NULL; 232262395Sbapt } 233262395Sbapt return new; 234262395Sbapt} 235262395Sbapt 236262395Sbapt/** 237262395Sbapt * Create new object with type specified 238262395Sbapt * @param type type of a new object 239262395Sbapt * @return new object 240262395Sbapt */ 241262395Sbaptstatic inline ucl_object_t* ucl_object_typed_new (unsigned int type) UCL_WARN_UNUSED_RESULT; 242262395Sbaptstatic inline ucl_object_t * 243262395Sbaptucl_object_typed_new (unsigned int type) 244262395Sbapt{ 245262395Sbapt ucl_object_t *new; 246262395Sbapt new = malloc (sizeof (ucl_object_t)); 247262395Sbapt if (new != NULL) { 248262395Sbapt memset (new, 0, sizeof (ucl_object_t)); 249262395Sbapt new->ref = 1; 250262395Sbapt new->type = (type <= UCL_NULL ? type : UCL_NULL); 251262395Sbapt } 252262395Sbapt return new; 253262395Sbapt} 254262395Sbapt 255262395Sbapt/** 256262395Sbapt * Convert any string to an ucl object making the specified transformations 257262395Sbapt * @param str fixed size or NULL terminated string 258262395Sbapt * @param len length (if len is zero, than str is treated as NULL terminated) 259262395Sbapt * @param flags conversion flags 260262395Sbapt * @return new object 261262395Sbapt */ 262263032SbaptUCL_EXTERN ucl_object_t * ucl_object_fromstring_common (const char *str, size_t len, 263262395Sbapt enum ucl_string_flags flags) UCL_WARN_UNUSED_RESULT; 264262395Sbapt 265262395Sbapt/** 266262395Sbapt * Create a UCL object from the specified string 267262395Sbapt * @param str NULL terminated string, will be json escaped 268262395Sbapt * @return new object 269262395Sbapt */ 270262395Sbaptstatic inline ucl_object_t * 271262395Sbaptucl_object_fromstring (const char *str) 272262395Sbapt{ 273262395Sbapt return ucl_object_fromstring_common (str, 0, UCL_STRING_ESCAPE); 274262395Sbapt} 275262395Sbapt 276262395Sbapt/** 277262395Sbapt * Create a UCL object from the specified string 278262395Sbapt * @param str fixed size string, will be json escaped 279262395Sbapt * @param len length of a string 280262395Sbapt * @return new object 281262395Sbapt */ 282262395Sbaptstatic inline ucl_object_t * 283262395Sbaptucl_object_fromlstring (const char *str, size_t len) 284262395Sbapt{ 285262395Sbapt return ucl_object_fromstring_common (str, len, UCL_STRING_ESCAPE); 286262395Sbapt} 287262395Sbapt 288262395Sbapt/** 289262395Sbapt * Create an object from an integer number 290262395Sbapt * @param iv number 291262395Sbapt * @return new object 292262395Sbapt */ 293262395Sbaptstatic inline ucl_object_t * 294262395Sbaptucl_object_fromint (int64_t iv) 295262395Sbapt{ 296262395Sbapt ucl_object_t *obj; 297262395Sbapt 298262395Sbapt obj = ucl_object_new (); 299262395Sbapt if (obj != NULL) { 300262395Sbapt obj->type = UCL_INT; 301262395Sbapt obj->value.iv = iv; 302262395Sbapt } 303262395Sbapt 304262395Sbapt return obj; 305262395Sbapt} 306262395Sbapt 307262395Sbapt/** 308262395Sbapt * Create an object from a float number 309262395Sbapt * @param dv number 310262395Sbapt * @return new object 311262395Sbapt */ 312262395Sbaptstatic inline ucl_object_t * 313262395Sbaptucl_object_fromdouble (double dv) 314262395Sbapt{ 315262395Sbapt ucl_object_t *obj; 316262395Sbapt 317262395Sbapt obj = ucl_object_new (); 318262395Sbapt if (obj != NULL) { 319262395Sbapt obj->type = UCL_FLOAT; 320262395Sbapt obj->value.dv = dv; 321262395Sbapt } 322262395Sbapt 323262395Sbapt return obj; 324262395Sbapt} 325262395Sbapt 326262395Sbapt/** 327262395Sbapt * Create an object from a boolean 328262395Sbapt * @param bv bool value 329262395Sbapt * @return new object 330262395Sbapt */ 331262395Sbaptstatic inline ucl_object_t * 332262395Sbaptucl_object_frombool (bool bv) 333262395Sbapt{ 334262395Sbapt ucl_object_t *obj; 335262395Sbapt 336262395Sbapt obj = ucl_object_new (); 337262395Sbapt if (obj != NULL) { 338262395Sbapt obj->type = UCL_BOOLEAN; 339262395Sbapt obj->value.iv = bv; 340262395Sbapt } 341262395Sbapt 342262395Sbapt return obj; 343262395Sbapt} 344262395Sbapt 345262395Sbapt/** 346262395Sbapt * Insert a object 'elt' to the hash 'top' and associate it with key 'key' 347262395Sbapt * @param top destination object (will be created automatically if top is NULL) 348262395Sbapt * @param elt element to insert (must NOT be NULL) 349262395Sbapt * @param key key to associate with this object (either const or preallocated) 350262395Sbapt * @param keylen length of the key (or 0 for NULL terminated keys) 351262395Sbapt * @param copy_key make an internal copy of key 352262395Sbapt * @return new value of top object 353262395Sbapt */ 354263032SbaptUCL_EXTERN ucl_object_t* ucl_object_insert_key (ucl_object_t *top, ucl_object_t *elt, 355262395Sbapt const char *key, size_t keylen, bool copy_key) UCL_WARN_UNUSED_RESULT; 356262395Sbapt 357262395Sbapt/** 358262395Sbapt * Replace a object 'elt' to the hash 'top' and associate it with key 'key', old object will be unrefed, 359262395Sbapt * if no object has been found this function works like ucl_object_insert_key() 360262395Sbapt * @param top destination object (will be created automatically if top is NULL) 361262395Sbapt * @param elt element to insert (must NOT be NULL) 362262395Sbapt * @param key key to associate with this object (either const or preallocated) 363262395Sbapt * @param keylen length of the key (or 0 for NULL terminated keys) 364262395Sbapt * @param copy_key make an internal copy of key 365262395Sbapt * @return new value of top object 366262395Sbapt */ 367263032SbaptUCL_EXTERN ucl_object_t* ucl_object_replace_key (ucl_object_t *top, ucl_object_t *elt, 368262395Sbapt const char *key, size_t keylen, bool copy_key) UCL_WARN_UNUSED_RESULT; 369262395Sbapt 370262395Sbapt/** 371263032Sbapt * Delete a object associated with key 'key', old object will be unrefered, 372263032Sbapt * @param top object 373263032Sbapt * @param key key associated to the object to remove 374263032Sbapt * @param keylen length of the key (or 0 for NULL terminated keys) 375263032Sbapt */ 376263032SbaptUCL_EXTERN bool ucl_object_delete_keyl (ucl_object_t *top, const char *key, size_t keylen); 377263032Sbapt 378263032Sbapt/** 379263032Sbapt * Delete a object associated with key 'key', old object will be unrefered, 380263032Sbapt * @param top object 381263032Sbapt * @param key key associated to the object to remove 382263032Sbapt */ 383263032SbaptUCL_EXTERN bool ucl_object_delete_key (ucl_object_t *top, const char *key); 384263032Sbapt 385263032Sbapt/** 386262395Sbapt * Insert a object 'elt' to the hash 'top' and associate it with key 'key', if the specified key exist, 387262395Sbapt * try to merge its content 388262395Sbapt * @param top destination object (will be created automatically if top is NULL) 389262395Sbapt * @param elt element to insert (must NOT be NULL) 390262395Sbapt * @param key key to associate with this object (either const or preallocated) 391262395Sbapt * @param keylen length of the key (or 0 for NULL terminated keys) 392262395Sbapt * @param copy_key make an internal copy of key 393262395Sbapt * @return new value of top object 394262395Sbapt */ 395263032SbaptUCL_EXTERN ucl_object_t* ucl_object_insert_key_merged (ucl_object_t *top, ucl_object_t *elt, 396262395Sbapt const char *key, size_t keylen, bool copy_key) UCL_WARN_UNUSED_RESULT; 397262395Sbapt 398262395Sbapt/** 399262395Sbapt * Append an element to the front of array object 400262395Sbapt * @param top destination object (will be created automatically if top is NULL) 401262395Sbapt * @param elt element to append (must NOT be NULL) 402262395Sbapt * @return new value of top object 403262395Sbapt */ 404262395Sbaptstatic inline ucl_object_t * ucl_array_append (ucl_object_t *top, 405262395Sbapt ucl_object_t *elt) UCL_WARN_UNUSED_RESULT; 406262395Sbaptstatic inline ucl_object_t * 407262395Sbaptucl_array_append (ucl_object_t *top, ucl_object_t *elt) 408262395Sbapt{ 409262395Sbapt ucl_object_t *head; 410262395Sbapt 411262395Sbapt if (elt == NULL) { 412262395Sbapt return NULL; 413262395Sbapt } 414262395Sbapt 415262395Sbapt if (top == NULL) { 416262395Sbapt top = ucl_object_typed_new (UCL_ARRAY); 417262395Sbapt top->value.av = elt; 418262395Sbapt elt->next = NULL; 419262395Sbapt elt->prev = elt; 420262395Sbapt top->len = 1; 421262395Sbapt } 422262395Sbapt else { 423262395Sbapt head = top->value.av; 424262395Sbapt if (head == NULL) { 425262395Sbapt top->value.av = elt; 426262395Sbapt elt->prev = elt; 427262395Sbapt } 428262395Sbapt else { 429262395Sbapt elt->prev = head->prev; 430262395Sbapt head->prev->next = elt; 431262395Sbapt head->prev = elt; 432262395Sbapt } 433262395Sbapt elt->next = NULL; 434262395Sbapt top->len ++; 435262395Sbapt } 436262395Sbapt 437262395Sbapt return top; 438262395Sbapt} 439262395Sbapt 440262395Sbapt/** 441262395Sbapt * Append an element to the start of array object 442262395Sbapt * @param top destination object (will be created automatically if top is NULL) 443262395Sbapt * @param elt element to append (must NOT be NULL) 444262395Sbapt * @return new value of top object 445262395Sbapt */ 446262395Sbaptstatic inline ucl_object_t * ucl_array_prepend (ucl_object_t *top, 447262395Sbapt ucl_object_t *elt) UCL_WARN_UNUSED_RESULT; 448262395Sbaptstatic inline ucl_object_t * 449262395Sbaptucl_array_prepend (ucl_object_t *top, ucl_object_t *elt) 450262395Sbapt{ 451262395Sbapt ucl_object_t *head; 452262395Sbapt 453262395Sbapt if (elt == NULL) { 454262395Sbapt return NULL; 455262395Sbapt } 456262395Sbapt 457262395Sbapt if (top == NULL) { 458262395Sbapt top = ucl_object_typed_new (UCL_ARRAY); 459262395Sbapt top->value.av = elt; 460262395Sbapt elt->next = NULL; 461262395Sbapt elt->prev = elt; 462262395Sbapt top->len = 1; 463262395Sbapt } 464262395Sbapt else { 465262395Sbapt head = top->value.av; 466262395Sbapt if (head == NULL) { 467262395Sbapt top->value.av = elt; 468262395Sbapt elt->prev = elt; 469262395Sbapt } 470262395Sbapt else { 471262395Sbapt elt->prev = head->prev; 472262395Sbapt head->prev = elt; 473262395Sbapt } 474262395Sbapt elt->next = head; 475262395Sbapt top->value.av = elt; 476262395Sbapt top->len ++; 477262395Sbapt } 478262395Sbapt 479262395Sbapt return top; 480262395Sbapt} 481262395Sbapt 482262395Sbapt/** 483262395Sbapt * Removes an element `elt` from the array `top`. Caller must unref the returned object when it is not 484262395Sbapt * needed. 485262395Sbapt * @param top array ucl object 486262395Sbapt * @param elt element to remove 487262395Sbapt * @return removed element or NULL if `top` is NULL or not an array 488262395Sbapt */ 489262395Sbaptstatic inline ucl_object_t * 490262395Sbaptucl_array_delete (ucl_object_t *top, ucl_object_t *elt) 491262395Sbapt{ 492262395Sbapt ucl_object_t *head; 493262395Sbapt 494262395Sbapt if (top == NULL || top->type != UCL_ARRAY || top->value.av == NULL) { 495262395Sbapt return NULL; 496262395Sbapt } 497262395Sbapt head = top->value.av; 498262395Sbapt 499262395Sbapt if (elt->prev == elt) { 500262395Sbapt top->value.av = NULL; 501262395Sbapt } 502262395Sbapt else if (elt == head) { 503262395Sbapt elt->next->prev = elt->prev; 504262395Sbapt top->value.av = elt->next; 505262395Sbapt } 506262395Sbapt else { 507262395Sbapt elt->prev->next = elt->next; 508262395Sbapt if (elt->next) { 509262395Sbapt elt->next->prev = elt->prev; 510262395Sbapt } 511262395Sbapt else { 512262395Sbapt head->prev = elt->prev; 513262395Sbapt } 514262395Sbapt } 515262395Sbapt elt->next = NULL; 516262395Sbapt elt->prev = elt; 517262395Sbapt top->len --; 518262395Sbapt 519262395Sbapt return elt; 520262395Sbapt} 521262395Sbapt 522262395Sbapt/** 523262395Sbapt * Returns the first element of the array `top` 524262395Sbapt * @param top array ucl object 525262395Sbapt * @return element or NULL if `top` is NULL or not an array 526262395Sbapt */ 527262395Sbaptstatic inline ucl_object_t * 528262395Sbaptucl_array_head (ucl_object_t *top) 529262395Sbapt{ 530262395Sbapt if (top == NULL || top->type != UCL_ARRAY || top->value.av == NULL) { 531262395Sbapt return NULL; 532262395Sbapt } 533262395Sbapt return top->value.av; 534262395Sbapt} 535262395Sbapt 536262395Sbapt/** 537262395Sbapt * Returns the last element of the array `top` 538262395Sbapt * @param top array ucl object 539262395Sbapt * @return element or NULL if `top` is NULL or not an array 540262395Sbapt */ 541262395Sbaptstatic inline ucl_object_t * 542262395Sbaptucl_array_tail (ucl_object_t *top) 543262395Sbapt{ 544262395Sbapt if (top == NULL || top->type != UCL_ARRAY || top->value.av == NULL) { 545262395Sbapt return NULL; 546262395Sbapt } 547262395Sbapt return top->value.av->prev; 548262395Sbapt} 549262395Sbapt 550262395Sbapt/** 551262395Sbapt * Removes the last element from the array `top`. Caller must unref the returned object when it is not 552262395Sbapt * needed. 553262395Sbapt * @param top array ucl object 554262395Sbapt * @return removed element or NULL if `top` is NULL or not an array 555262395Sbapt */ 556262395Sbaptstatic inline ucl_object_t * 557262395Sbaptucl_array_pop_last (ucl_object_t *top) 558262395Sbapt{ 559262395Sbapt return ucl_array_delete (top, ucl_array_tail (top)); 560262395Sbapt} 561262395Sbapt 562262395Sbapt/** 563262395Sbapt * Removes the first element from the array `top`. Caller must unref the returned object when it is not 564262395Sbapt * needed. 565262395Sbapt * @param top array ucl object 566262395Sbapt * @return removed element or NULL if `top` is NULL or not an array 567262395Sbapt */ 568262395Sbaptstatic inline ucl_object_t * 569262395Sbaptucl_array_pop_first (ucl_object_t *top) 570262395Sbapt{ 571262395Sbapt return ucl_array_delete (top, ucl_array_head (top)); 572262395Sbapt} 573262395Sbapt 574262395Sbapt/** 575262395Sbapt * Append a element to another element forming an implicit array 576262395Sbapt * @param head head to append (may be NULL) 577262395Sbapt * @param elt new element 578262395Sbapt * @return new head if applicable 579262395Sbapt */ 580262395Sbaptstatic inline ucl_object_t * ucl_elt_append (ucl_object_t *head, 581262395Sbapt ucl_object_t *elt) UCL_WARN_UNUSED_RESULT; 582262395Sbaptstatic inline ucl_object_t * 583262395Sbaptucl_elt_append (ucl_object_t *head, ucl_object_t *elt) 584262395Sbapt{ 585262395Sbapt 586262395Sbapt if (head == NULL) { 587262395Sbapt elt->next = NULL; 588262395Sbapt elt->prev = elt; 589262395Sbapt head = elt; 590262395Sbapt } 591262395Sbapt else { 592262395Sbapt elt->prev = head->prev; 593262395Sbapt head->prev->next = elt; 594262395Sbapt head->prev = elt; 595262395Sbapt elt->next = NULL; 596262395Sbapt } 597262395Sbapt 598262395Sbapt return head; 599262395Sbapt} 600262395Sbapt 601262395Sbapt/** 602262395Sbapt * Converts an object to double value 603262395Sbapt * @param obj CL object 604262395Sbapt * @param target target double variable 605262395Sbapt * @return true if conversion was successful 606262395Sbapt */ 607262395Sbaptstatic inline bool 608262395Sbaptucl_object_todouble_safe (ucl_object_t *obj, double *target) 609262395Sbapt{ 610262395Sbapt if (obj == NULL) { 611262395Sbapt return false; 612262395Sbapt } 613262395Sbapt switch (obj->type) { 614262395Sbapt case UCL_INT: 615262395Sbapt *target = obj->value.iv; /* Probaly could cause overflow */ 616262395Sbapt break; 617262395Sbapt case UCL_FLOAT: 618262395Sbapt case UCL_TIME: 619262395Sbapt *target = obj->value.dv; 620262395Sbapt break; 621262395Sbapt default: 622262395Sbapt return false; 623262395Sbapt } 624262395Sbapt 625262395Sbapt return true; 626262395Sbapt} 627262395Sbapt 628262395Sbapt/** 629262395Sbapt * Unsafe version of \ref ucl_obj_todouble_safe 630262395Sbapt * @param obj CL object 631262395Sbapt * @return double value 632262395Sbapt */ 633262395Sbaptstatic inline double 634262395Sbaptucl_object_todouble (ucl_object_t *obj) 635262395Sbapt{ 636262395Sbapt double result = 0.; 637262395Sbapt 638262395Sbapt ucl_object_todouble_safe (obj, &result); 639262395Sbapt return result; 640262395Sbapt} 641262395Sbapt 642262395Sbapt/** 643262395Sbapt * Converts an object to integer value 644262395Sbapt * @param obj CL object 645262395Sbapt * @param target target integer variable 646262395Sbapt * @return true if conversion was successful 647262395Sbapt */ 648262395Sbaptstatic inline bool 649262395Sbaptucl_object_toint_safe (ucl_object_t *obj, int64_t *target) 650262395Sbapt{ 651262395Sbapt if (obj == NULL) { 652262395Sbapt return false; 653262395Sbapt } 654262395Sbapt switch (obj->type) { 655262395Sbapt case UCL_INT: 656262395Sbapt *target = obj->value.iv; 657262395Sbapt break; 658262395Sbapt case UCL_FLOAT: 659262395Sbapt case UCL_TIME: 660262395Sbapt *target = obj->value.dv; /* Loosing of decimal points */ 661262395Sbapt break; 662262395Sbapt default: 663262395Sbapt return false; 664262395Sbapt } 665262395Sbapt 666262395Sbapt return true; 667262395Sbapt} 668262395Sbapt 669262395Sbapt/** 670262395Sbapt * Unsafe version of \ref ucl_obj_toint_safe 671262395Sbapt * @param obj CL object 672262395Sbapt * @return int value 673262395Sbapt */ 674262395Sbaptstatic inline int64_t 675262395Sbaptucl_object_toint (ucl_object_t *obj) 676262395Sbapt{ 677262395Sbapt int64_t result = 0; 678262395Sbapt 679262395Sbapt ucl_object_toint_safe (obj, &result); 680262395Sbapt return result; 681262395Sbapt} 682262395Sbapt 683262395Sbapt/** 684262395Sbapt * Converts an object to boolean value 685262395Sbapt * @param obj CL object 686262395Sbapt * @param target target boolean variable 687262395Sbapt * @return true if conversion was successful 688262395Sbapt */ 689262395Sbaptstatic inline bool 690262395Sbaptucl_object_toboolean_safe (ucl_object_t *obj, bool *target) 691262395Sbapt{ 692262395Sbapt if (obj == NULL) { 693262395Sbapt return false; 694262395Sbapt } 695262395Sbapt switch (obj->type) { 696262395Sbapt case UCL_BOOLEAN: 697262395Sbapt *target = (obj->value.iv == true); 698262395Sbapt break; 699262395Sbapt default: 700262395Sbapt return false; 701262395Sbapt } 702262395Sbapt 703262395Sbapt return true; 704262395Sbapt} 705262395Sbapt 706262395Sbapt/** 707262395Sbapt * Unsafe version of \ref ucl_obj_toboolean_safe 708262395Sbapt * @param obj CL object 709262395Sbapt * @return boolean value 710262395Sbapt */ 711262395Sbaptstatic inline bool 712262395Sbaptucl_object_toboolean (ucl_object_t *obj) 713262395Sbapt{ 714262395Sbapt bool result = false; 715262395Sbapt 716262395Sbapt ucl_object_toboolean_safe (obj, &result); 717262395Sbapt return result; 718262395Sbapt} 719262395Sbapt 720262395Sbapt/** 721262395Sbapt * Converts an object to string value 722262395Sbapt * @param obj CL object 723262395Sbapt * @param target target string variable, no need to free value 724262395Sbapt * @return true if conversion was successful 725262395Sbapt */ 726262395Sbaptstatic inline bool 727262395Sbaptucl_object_tostring_safe (ucl_object_t *obj, const char **target) 728262395Sbapt{ 729262395Sbapt if (obj == NULL) { 730262395Sbapt return false; 731262395Sbapt } 732262395Sbapt 733262395Sbapt switch (obj->type) { 734262395Sbapt case UCL_STRING: 735262395Sbapt *target = ucl_copy_value_trash (obj); 736262395Sbapt break; 737262395Sbapt default: 738262395Sbapt return false; 739262395Sbapt } 740262395Sbapt 741262395Sbapt return true; 742262395Sbapt} 743262395Sbapt 744262395Sbapt/** 745262395Sbapt * Unsafe version of \ref ucl_obj_tostring_safe 746262395Sbapt * @param obj CL object 747262395Sbapt * @return string value 748262395Sbapt */ 749262395Sbaptstatic inline const char * 750262395Sbaptucl_object_tostring (ucl_object_t *obj) 751262395Sbapt{ 752262395Sbapt const char *result = NULL; 753262395Sbapt 754262395Sbapt ucl_object_tostring_safe (obj, &result); 755262395Sbapt return result; 756262395Sbapt} 757262395Sbapt 758262395Sbapt/** 759262395Sbapt * Convert any object to a string in JSON notation if needed 760262395Sbapt * @param obj CL object 761262395Sbapt * @return string value 762262395Sbapt */ 763262395Sbaptstatic inline const char * 764262395Sbaptucl_object_tostring_forced (ucl_object_t *obj) 765262395Sbapt{ 766262395Sbapt return ucl_copy_value_trash (obj); 767262395Sbapt} 768262395Sbapt 769262395Sbapt/** 770262395Sbapt * Return string as char * and len, string may be not zero terminated, more efficient that \ref ucl_obj_tostring as it 771262395Sbapt * allows zero-copy (if #UCL_PARSER_ZEROCOPY has been used during parsing) 772262395Sbapt * @param obj CL object 773262395Sbapt * @param target target string variable, no need to free value 774262395Sbapt * @param tlen target length 775262395Sbapt * @return true if conversion was successful 776262395Sbapt */ 777262395Sbaptstatic inline bool 778262395Sbaptucl_object_tolstring_safe (ucl_object_t *obj, const char **target, size_t *tlen) 779262395Sbapt{ 780262395Sbapt if (obj == NULL) { 781262395Sbapt return false; 782262395Sbapt } 783262395Sbapt switch (obj->type) { 784262395Sbapt case UCL_STRING: 785262395Sbapt *target = obj->value.sv; 786262395Sbapt *tlen = obj->len; 787262395Sbapt break; 788262395Sbapt default: 789262395Sbapt return false; 790262395Sbapt } 791262395Sbapt 792262395Sbapt return true; 793262395Sbapt} 794262395Sbapt 795262395Sbapt/** 796262395Sbapt * Unsafe version of \ref ucl_obj_tolstring_safe 797262395Sbapt * @param obj CL object 798262395Sbapt * @return string value 799262395Sbapt */ 800262395Sbaptstatic inline const char * 801262395Sbaptucl_object_tolstring (ucl_object_t *obj, size_t *tlen) 802262395Sbapt{ 803262395Sbapt const char *result = NULL; 804262395Sbapt 805262395Sbapt ucl_object_tolstring_safe (obj, &result, tlen); 806262395Sbapt return result; 807262395Sbapt} 808262395Sbapt 809262395Sbapt/** 810262395Sbapt * Return object identified by a key in the specified object 811262395Sbapt * @param obj object to get a key from (must be of type UCL_OBJECT) 812262395Sbapt * @param key key to search 813262395Sbapt * @return object matched the specified key or NULL if key is not found 814262395Sbapt */ 815263032SbaptUCL_EXTERN ucl_object_t * ucl_object_find_key (ucl_object_t *obj, const char *key); 816262395Sbapt 817262395Sbapt/** 818262395Sbapt * Return object identified by a fixed size key in the specified object 819262395Sbapt * @param obj object to get a key from (must be of type UCL_OBJECT) 820262395Sbapt * @param key key to search 821262395Sbapt * @param klen length of a key 822262395Sbapt * @return object matched the specified key or NULL if key is not found 823262395Sbapt */ 824263032SbaptUCL_EXTERN ucl_object_t *ucl_object_find_keyl (ucl_object_t *obj, const char *key, size_t klen); 825262395Sbapt 826262395Sbapt/** 827262395Sbapt * Returns a key of an object as a NULL terminated string 828262395Sbapt * @param obj CL object 829262395Sbapt * @return key or NULL if there is no key 830262395Sbapt */ 831262395Sbaptstatic inline const char * 832262395Sbaptucl_object_key (ucl_object_t *obj) 833262395Sbapt{ 834262395Sbapt return ucl_copy_key_trash (obj); 835262395Sbapt} 836262395Sbapt 837262395Sbapt/** 838262395Sbapt * Returns a key of an object as a fixed size string (may be more efficient) 839262395Sbapt * @param obj CL object 840262395Sbapt * @param len target key length 841262395Sbapt * @return key pointer 842262395Sbapt */ 843262395Sbaptstatic inline const char * 844262395Sbaptucl_object_keyl (ucl_object_t *obj, size_t *len) 845262395Sbapt{ 846262395Sbapt *len = obj->keylen; 847262395Sbapt return obj->key; 848262395Sbapt} 849262395Sbapt 850262395Sbapt/** 851262395Sbapt * Free ucl object 852262395Sbapt * @param obj ucl object to free 853262395Sbapt */ 854263032SbaptUCL_EXTERN void ucl_object_free (ucl_object_t *obj); 855262395Sbapt 856262395Sbapt/** 857262395Sbapt * Increase reference count for an object 858262395Sbapt * @param obj object to ref 859262395Sbapt */ 860262395Sbaptstatic inline ucl_object_t * 861262395Sbaptucl_object_ref (ucl_object_t *obj) { 862262395Sbapt obj->ref ++; 863262395Sbapt return obj; 864262395Sbapt} 865262395Sbapt 866262395Sbapt/** 867262395Sbapt * Decrease reference count for an object 868262395Sbapt * @param obj object to unref 869262395Sbapt */ 870262395Sbaptstatic inline void 871262395Sbaptucl_object_unref (ucl_object_t *obj) { 872262395Sbapt if (obj != NULL && --obj->ref <= 0) { 873262395Sbapt ucl_object_free (obj); 874262395Sbapt } 875262395Sbapt} 876262395Sbapt/** 877262395Sbapt * Opaque iterator object 878262395Sbapt */ 879262395Sbapttypedef void* ucl_object_iter_t; 880262395Sbapt 881262395Sbapt/** 882262395Sbapt * Get next key from an object 883262395Sbapt * @param obj object to iterate 884262395Sbapt * @param iter opaque iterator, must be set to NULL on the first call: 885262395Sbapt * ucl_object_iter_t it = NULL; 886262395Sbapt * while ((cur = ucl_iterate_object (obj, &it)) != NULL) ... 887262395Sbapt * @return the next object or NULL 888262395Sbapt */ 889263032SbaptUCL_EXTERN ucl_object_t* ucl_iterate_object (ucl_object_t *obj, ucl_object_iter_t *iter, bool expand_values); 890262395Sbapt/** @} */ 891262395Sbapt 892262395Sbapt 893262395Sbapt/** 894262395Sbapt * @defgroup parser Parsing functions 895262395Sbapt * These functions are used to parse UCL objects 896262395Sbapt * 897262395Sbapt * @{ 898262395Sbapt */ 899262395Sbapt 900262395Sbapt/** 901262395Sbapt * Macro handler for a parser 902262395Sbapt * @param data the content of macro 903262395Sbapt * @param len the length of content 904262395Sbapt * @param ud opaque user data 905262395Sbapt * @param err error pointer 906262395Sbapt * @return true if macro has been parsed 907262395Sbapt */ 908262395Sbapttypedef bool (*ucl_macro_handler) (const unsigned char *data, size_t len, void* ud); 909262395Sbapt 910262395Sbapt/* Opaque parser */ 911262395Sbaptstruct ucl_parser; 912262395Sbapt 913262395Sbapt/** 914262395Sbapt * Creates new parser object 915262395Sbapt * @param pool pool to allocate memory from 916262395Sbapt * @return new parser object 917262395Sbapt */ 918263032SbaptUCL_EXTERN struct ucl_parser* ucl_parser_new (int flags); 919262395Sbapt 920262395Sbapt/** 921262395Sbapt * Register new handler for a macro 922262395Sbapt * @param parser parser object 923262395Sbapt * @param macro macro name (without leading dot) 924262395Sbapt * @param handler handler (it is called immediately after macro is parsed) 925262395Sbapt * @param ud opaque user data for a handler 926262395Sbapt */ 927263032SbaptUCL_EXTERN void ucl_parser_register_macro (struct ucl_parser *parser, const char *macro, 928262395Sbapt ucl_macro_handler handler, void* ud); 929262395Sbapt 930262395Sbapt/** 931262395Sbapt * Register new parser variable 932262395Sbapt * @param parser parser object 933262395Sbapt * @param var variable name 934262395Sbapt * @param value variable value 935262395Sbapt */ 936263032SbaptUCL_EXTERN void ucl_parser_register_variable (struct ucl_parser *parser, const char *var, 937262395Sbapt const char *value); 938262395Sbapt 939262395Sbapt/** 940262395Sbapt * Load new chunk to a parser 941262395Sbapt * @param parser parser structure 942262395Sbapt * @param data the pointer to the beginning of a chunk 943262395Sbapt * @param len the length of a chunk 944262395Sbapt * @param err if *err is NULL it is set to parser error 945262395Sbapt * @return true if chunk has been added and false in case of error 946262395Sbapt */ 947263032SbaptUCL_EXTERN bool ucl_parser_add_chunk (struct ucl_parser *parser, const unsigned char *data, size_t len); 948262395Sbapt 949262395Sbapt/** 950262395Sbapt * Load and add data from a file 951262395Sbapt * @param parser parser structure 952262395Sbapt * @param filename the name of file 953262395Sbapt * @param err if *err is NULL it is set to parser error 954262395Sbapt * @return true if chunk has been added and false in case of error 955262395Sbapt */ 956263032SbaptUCL_EXTERN bool ucl_parser_add_file (struct ucl_parser *parser, const char *filename); 957262395Sbapt 958262395Sbapt/** 959262395Sbapt * Get a top object for a parser 960262395Sbapt * @param parser parser structure 961262395Sbapt * @param err if *err is NULL it is set to parser error 962262395Sbapt * @return top parser object or NULL 963262395Sbapt */ 964263032SbaptUCL_EXTERN ucl_object_t* ucl_parser_get_object (struct ucl_parser *parser); 965262395Sbapt 966262395Sbapt/** 967262395Sbapt * Get the error string if failing 968262395Sbapt * @param parser parser object 969262395Sbapt */ 970263032SbaptUCL_EXTERN const char *ucl_parser_get_error(struct ucl_parser *parser); 971262395Sbapt/** 972262395Sbapt * Free ucl parser object 973262395Sbapt * @param parser parser object 974262395Sbapt */ 975263032SbaptUCL_EXTERN void ucl_parser_free (struct ucl_parser *parser); 976262395Sbapt 977262395Sbapt/** 978262395Sbapt * Add new public key to parser for signatures check 979262395Sbapt * @param parser parser object 980262395Sbapt * @param key PEM representation of a key 981262395Sbapt * @param len length of the key 982262395Sbapt * @param err if *err is NULL it is set to parser error 983262395Sbapt * @return true if a key has been successfully added 984262395Sbapt */ 985263032SbaptUCL_EXTERN bool ucl_pubkey_add (struct ucl_parser *parser, const unsigned char *key, size_t len); 986262395Sbapt 987262395Sbapt/** 988262395Sbapt * Set FILENAME and CURDIR variables in parser 989262395Sbapt * @param parser parser object 990262395Sbapt * @param filename filename to set or NULL to set FILENAME to "undef" and CURDIR to getcwd() 991262395Sbapt * @param need_expand perform realpath() if this variable is true and filename is not NULL 992262395Sbapt * @return true if variables has been set 993262395Sbapt */ 994263032SbaptUCL_EXTERN bool ucl_parser_set_filevars (struct ucl_parser *parser, const char *filename, 995262395Sbapt bool need_expand); 996262395Sbapt 997262395Sbapt/** @} */ 998262395Sbapt 999262395Sbapt/** 1000262395Sbapt * @defgroup emitter Emitting functions 1001262395Sbapt * These functions are used to serialise UCL objects to some string representation. 1002262395Sbapt * 1003262395Sbapt * @{ 1004262395Sbapt */ 1005262395Sbapt 1006262395Sbapt/** 1007262395Sbapt * Structure using for emitter callbacks 1008262395Sbapt */ 1009262395Sbaptstruct ucl_emitter_functions { 1010262395Sbapt /** Append a single character */ 1011262395Sbapt int (*ucl_emitter_append_character) (unsigned char c, size_t nchars, void *ud); 1012262395Sbapt /** Append a string of a specified length */ 1013262395Sbapt int (*ucl_emitter_append_len) (unsigned const char *str, size_t len, void *ud); 1014262395Sbapt /** Append a 64 bit integer */ 1015262395Sbapt int (*ucl_emitter_append_int) (int64_t elt, void *ud); 1016262395Sbapt /** Append floating point element */ 1017262395Sbapt int (*ucl_emitter_append_double) (double elt, void *ud); 1018262395Sbapt /** Opaque userdata pointer */ 1019262395Sbapt void *ud; 1020262395Sbapt}; 1021262395Sbapt 1022262395Sbapt/** 1023262395Sbapt * Emit object to a string 1024262395Sbapt * @param obj object 1025262395Sbapt * @param emit_type if type is #UCL_EMIT_JSON then emit json, if type is 1026262395Sbapt * #UCL_EMIT_CONFIG then emit config like object 1027262395Sbapt * @return dump of an object (must be freed after using) or NULL in case of error 1028262395Sbapt */ 1029263032SbaptUCL_EXTERN unsigned char *ucl_object_emit (ucl_object_t *obj, enum ucl_emitter emit_type); 1030262395Sbapt 1031262395Sbapt/** 1032262395Sbapt * Emit object to a string 1033262395Sbapt * @param obj object 1034262395Sbapt * @param emit_type if type is #UCL_EMIT_JSON then emit json, if type is 1035262395Sbapt * #UCL_EMIT_CONFIG then emit config like object 1036262395Sbapt * @return dump of an object (must be freed after using) or NULL in case of error 1037262395Sbapt */ 1038263032SbaptUCL_EXTERN bool ucl_object_emit_full (ucl_object_t *obj, enum ucl_emitter emit_type, 1039262395Sbapt struct ucl_emitter_functions *emitter); 1040262395Sbapt/** @} */ 1041262395Sbapt 1042262395Sbapt#ifdef __cplusplus 1043262395Sbapt} 1044262395Sbapt#endif 1045262395Sbapt/* 1046262395Sbapt * XXX: Poorly named API functions, need to replace them with the appropriate 1047262395Sbapt * named function. All API functions *must* use naming ucl_object_*. Usage of 1048262395Sbapt * ucl_obj* should be avoided. 1049262395Sbapt */ 1050262395Sbapt#define ucl_obj_todouble_safe ucl_object_todouble_safe 1051262395Sbapt#define ucl_obj_todouble ucl_object_todouble 1052262395Sbapt#define ucl_obj_tostring ucl_object_tostring 1053262395Sbapt#define ucl_obj_tostring_safe ucl_object_tostring_safe 1054262395Sbapt#define ucl_obj_tolstring ucl_object_tolstring 1055262395Sbapt#define ucl_obj_tolstring_safe ucl_object_tolstring_safe 1056262395Sbapt#define ucl_obj_toint ucl_object_toint 1057262395Sbapt#define ucl_obj_toint_safe ucl_object_toint_safe 1058262395Sbapt#define ucl_obj_toboolean ucl_object_toboolean 1059262395Sbapt#define ucl_obj_toboolean_safe ucl_object_toboolean_safe 1060262395Sbapt#define ucl_obj_get_key ucl_object_find_key 1061262395Sbapt#define ucl_obj_get_keyl ucl_object_find_keyl 1062262395Sbapt#define ucl_obj_unref ucl_object_unref 1063262395Sbapt#define ucl_obj_ref ucl_object_ref 1064262395Sbapt#define ucl_obj_free ucl_object_free 1065262395Sbapt 1066262395Sbapt#endif /* UCL_H_ */ 1067