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