1c99fb5f9SBaptiste DaroussinSynopsis 2c99fb5f9SBaptiste Daroussin======== 3c99fb5f9SBaptiste Daroussin 4c99fb5f9SBaptiste Daroussin`#include <ucl.h>` 5c99fb5f9SBaptiste Daroussin 6c99fb5f9SBaptiste DaroussinDescription 7c99fb5f9SBaptiste Daroussin=========== 8c99fb5f9SBaptiste Daroussin 9c99fb5f9SBaptiste DaroussinLibucl is a parser and `C` API to parse and generate `ucl` objects. Libucl consist of several groups of functions: 10c99fb5f9SBaptiste Daroussin 11c99fb5f9SBaptiste Daroussin### Parser functions 12c99fb5f9SBaptiste DaroussinUsed to parse `ucl` files and provide interface to extract `ucl` object 13c99fb5f9SBaptiste Daroussin 14c99fb5f9SBaptiste Daroussin### Emitting functions 15c99fb5f9SBaptiste DaroussinConvert `ucl` objects to some textual or binary representation. 16c99fb5f9SBaptiste Daroussin 17c99fb5f9SBaptiste Daroussin### Conversion functions 18c99fb5f9SBaptiste DaroussinHelp to convert `ucl` objects to C types 19c99fb5f9SBaptiste Daroussin 20c99fb5f9SBaptiste Daroussin### Generation functions 21c99fb5f9SBaptiste DaroussinAllow creating of `ucl` objects from C types 22c99fb5f9SBaptiste Daroussin 23c99fb5f9SBaptiste Daroussin### Iteration functions 24c99fb5f9SBaptiste DaroussinIterate over `ucl` objects 25c99fb5f9SBaptiste Daroussin 26c99fb5f9SBaptiste Daroussin### Utility functions 27c99fb5f9SBaptiste DaroussinProvide basic utilities to manage `ucl` objects 28c99fb5f9SBaptiste Daroussin 29c99fb5f9SBaptiste Daroussin# Parser functions 30c99fb5f9SBaptiste Daroussin 31c99fb5f9SBaptiste DaroussinParser functions operates with `struct ucl_parser`. 32c99fb5f9SBaptiste Daroussin 33c99fb5f9SBaptiste Daroussin### ucl_parser_new 34c99fb5f9SBaptiste Daroussin 35c99fb5f9SBaptiste Daroussin~~~C 36c99fb5f9SBaptiste Daroussinstruct ucl_parser* ucl_parser_new (int flags); 37c99fb5f9SBaptiste Daroussin~~~ 38c99fb5f9SBaptiste Daroussin 39c99fb5f9SBaptiste DaroussinCreates new parser with the specified flags: 40c99fb5f9SBaptiste Daroussin 41c99fb5f9SBaptiste Daroussin- `UCL_PARSER_KEY_LOWERCASE` - lowercase keys parsed 42c99fb5f9SBaptiste Daroussin- `UCL_PARSER_ZEROCOPY` - try to use zero-copy mode when reading files (in zero-copy mode text chunk being parsed without copying strings so it should exist till any object parsed is used) 43c99fb5f9SBaptiste Daroussin 44c99fb5f9SBaptiste Daroussin### ucl_parser_register_macro 45c99fb5f9SBaptiste Daroussin 46c99fb5f9SBaptiste Daroussin~~~C 47c99fb5f9SBaptiste Daroussinvoid ucl_parser_register_macro (struct ucl_parser *parser, 48c99fb5f9SBaptiste Daroussin const char *macro, ucl_macro_handler handler, void* ud); 49c99fb5f9SBaptiste Daroussin~~~ 50c99fb5f9SBaptiste Daroussin 51c99fb5f9SBaptiste DaroussinRegister new macro with name .`macro` parsed by handler `handler` that accepts opaque data pointer `ud`. Macro handler should be of the following type: 52c99fb5f9SBaptiste Daroussin 53c99fb5f9SBaptiste Daroussin~~~C 54c99fb5f9SBaptiste Daroussinbool (*ucl_macro_handler) (const unsigned char *data, 55c99fb5f9SBaptiste Daroussin size_t len, void* ud);` 56c99fb5f9SBaptiste Daroussin~~~ 57c99fb5f9SBaptiste Daroussin 58c99fb5f9SBaptiste DaroussinHandler function accepts macro text `data` of length `len` and the opaque pointer `ud`. If macro is parsed successfully the handler should return `true`. `false` indicates parsing failure and the parser can be terminated. 59c99fb5f9SBaptiste Daroussin 60c99fb5f9SBaptiste Daroussin### ucl_parser_register_variable 61c99fb5f9SBaptiste Daroussin 62c99fb5f9SBaptiste Daroussin~~~C 63c99fb5f9SBaptiste Daroussinvoid ucl_parser_register_variable (struct ucl_parser *parser, 64c99fb5f9SBaptiste Daroussin const char *var, const char *value); 65c99fb5f9SBaptiste Daroussin~~~ 66c99fb5f9SBaptiste Daroussin 67c99fb5f9SBaptiste DaroussinRegister new variable $`var` that should be replaced by the parser to the `value` string. 68c99fb5f9SBaptiste Daroussin 69c99fb5f9SBaptiste Daroussin### ucl_parser_add_chunk 70c99fb5f9SBaptiste Daroussin 71c99fb5f9SBaptiste Daroussin~~~C 72c99fb5f9SBaptiste Daroussinbool ucl_parser_add_chunk (struct ucl_parser *parser, 73c99fb5f9SBaptiste Daroussin const unsigned char *data, size_t len); 74c99fb5f9SBaptiste Daroussin~~~ 75c99fb5f9SBaptiste Daroussin 76c99fb5f9SBaptiste DaroussinAdd new text chunk with `data` of length `len` to the parser. At the moment, `libucl` parser is not a streamlined parser and chunk *must* contain the *valid* ucl object. For example, this object should be valid: 77c99fb5f9SBaptiste Daroussin 78c99fb5f9SBaptiste Daroussin~~~json 79c99fb5f9SBaptiste Daroussin{ "var": "value" } 80c99fb5f9SBaptiste Daroussin~~~ 81c99fb5f9SBaptiste Daroussin 82c99fb5f9SBaptiste Daroussinwhile this one won't be parsed correctly: 83c99fb5f9SBaptiste Daroussin 84c99fb5f9SBaptiste Daroussin~~~json 85c99fb5f9SBaptiste Daroussin{ "var": 86c99fb5f9SBaptiste Daroussin~~~ 87c99fb5f9SBaptiste Daroussin 88c99fb5f9SBaptiste DaroussinThis limitation may possible be removed in future. 89c99fb5f9SBaptiste Daroussin 90c99fb5f9SBaptiste Daroussin### ucl_parser_add_file 91c99fb5f9SBaptiste Daroussin 92c99fb5f9SBaptiste Daroussin~~~C 93c99fb5f9SBaptiste Daroussinbool ucl_parser_add_file (struct ucl_parser *parser, 94c99fb5f9SBaptiste Daroussin const char *filename); 95c99fb5f9SBaptiste Daroussin~~~ 96c99fb5f9SBaptiste Daroussin 97c99fb5f9SBaptiste DaroussinLoad file `filename` and parse it with the specified `parser`. This function uses `mmap` call to load file, therefore, it should not be `shrinked` during parsing. Otherwise, `libucl` can cause memory corruption and terminate the calling application. This function is also used by the internal handler of `include` macro, hence, this macro has the same limitation. 98c99fb5f9SBaptiste Daroussin 99c99fb5f9SBaptiste Daroussin### ucl_parser_get_object 100c99fb5f9SBaptiste Daroussin 101c99fb5f9SBaptiste Daroussin~~~C 102c99fb5f9SBaptiste Daroussinucl_object_t* ucl_parser_get_object (struct ucl_parser *parser); 103c99fb5f9SBaptiste Daroussin~~~ 104c99fb5f9SBaptiste Daroussin 105c99fb5f9SBaptiste DaroussinIf the `ucl` data has been parsed correctly this function returns the top object for the parser. Otherwise, this function returns the `NULL` pointer. The reference count for `ucl` object returned is increased by one, therefore, a caller should decrease reference by using `ucl_object_unref` to free object after usage. 106c99fb5f9SBaptiste Daroussin 107c99fb5f9SBaptiste Daroussin### ucl_parser_get_error 108c99fb5f9SBaptiste Daroussin 109c99fb5f9SBaptiste Daroussin~~~C 110c99fb5f9SBaptiste Daroussinconst char *ucl_parser_get_error(struct ucl_parser *parser); 111c99fb5f9SBaptiste Daroussin~~~ 112c99fb5f9SBaptiste Daroussin 113c99fb5f9SBaptiste DaroussinReturns the constant error string for the parser object. If no error occurred during parsing a `NULL` object is returned. A caller should not try to free or modify this string. 114c99fb5f9SBaptiste Daroussin 115c99fb5f9SBaptiste Daroussin### ucl_parser_free 116c99fb5f9SBaptiste Daroussin 117c99fb5f9SBaptiste Daroussin~~~C 118c99fb5f9SBaptiste Daroussinvoid ucl_parser_free (struct ucl_parser *parser); 119c99fb5f9SBaptiste Daroussin~~~ 120c99fb5f9SBaptiste Daroussin 121c99fb5f9SBaptiste DaroussinFrees memory occupied by the parser object. The reference count for top object is decreased as well, however if the function `ucl_parser_get_object` was called previously then the top object won't be freed. 122c99fb5f9SBaptiste Daroussin 123c99fb5f9SBaptiste Daroussin### ucl_pubkey_add 124c99fb5f9SBaptiste Daroussin 125c99fb5f9SBaptiste Daroussin~~~C 126c99fb5f9SBaptiste Daroussinbool ucl_pubkey_add (struct ucl_parser *parser, 127c99fb5f9SBaptiste Daroussin const unsigned char *key, size_t len); 128c99fb5f9SBaptiste Daroussin~~~ 129c99fb5f9SBaptiste Daroussin 130c99fb5f9SBaptiste DaroussinThis function adds a public key from text blob `key` of length `len` to the `parser` object. This public key should be in the `PEM` format and can be used by `.includes` macro for checking signatures of files included. `Openssl` support should be enabled to make this function working. If a key cannot be added (e.g. due to format error) or `openssl` was not linked to `libucl` then this function returns `false`. 131c99fb5f9SBaptiste Daroussin 132c99fb5f9SBaptiste Daroussin### ucl_parser_set_filevars 133c99fb5f9SBaptiste Daroussin 134c99fb5f9SBaptiste Daroussin~~~C 135c99fb5f9SBaptiste Daroussinbool ucl_parser_set_filevars (struct ucl_parser *parser, 136c99fb5f9SBaptiste Daroussin const char *filename, bool need_expand); 137c99fb5f9SBaptiste Daroussin~~~ 138c99fb5f9SBaptiste Daroussin 139c99fb5f9SBaptiste DaroussinAdd the standard file variables to the `parser` based on the `filename` specified: 140c99fb5f9SBaptiste Daroussin 141c99fb5f9SBaptiste Daroussin- `$FILENAME` - a filename of `ucl` input 142c99fb5f9SBaptiste Daroussin- `$CURDIR` - a current directory of the input 143c99fb5f9SBaptiste Daroussin 144c99fb5f9SBaptiste DaroussinFor example, if a `filename` param is `../something.conf` then the variables will have the following values: 145c99fb5f9SBaptiste Daroussin 146c99fb5f9SBaptiste Daroussin- `$FILENAME` - "../something.conf" 147c99fb5f9SBaptiste Daroussin- `$CURDIR` - ".." 148c99fb5f9SBaptiste Daroussin 149c99fb5f9SBaptiste Daroussinif `need_expand` parameter is `true` then all relative paths are expanded using `realpath` call. In this example if `..` is `/etc/dir` then variables will have these values: 150c99fb5f9SBaptiste Daroussin 151c99fb5f9SBaptiste Daroussin- `$FILENAME` - "/etc/something.conf" 152c99fb5f9SBaptiste Daroussin- `$CURDIR` - "/etc" 153c99fb5f9SBaptiste Daroussin 154c99fb5f9SBaptiste Daroussin## Parser usage example 155c99fb5f9SBaptiste Daroussin 156c99fb5f9SBaptiste DaroussinThe following example loads, parses and extracts `ucl` object from stdin using `libucl` parser functions (the length of input is limited to 8K): 157c99fb5f9SBaptiste Daroussin 158c99fb5f9SBaptiste Daroussin~~~C 159c99fb5f9SBaptiste Daroussinchar inbuf[8192]; 160c99fb5f9SBaptiste Daroussinstruct ucl_parser *parser = NULL; 161c99fb5f9SBaptiste Daroussinint ret = 0, r = 0; 162c99fb5f9SBaptiste Daroussinucl_object_t *obj = NULL; 163c99fb5f9SBaptiste DaroussinFILE *in; 164c99fb5f9SBaptiste Daroussin 165c99fb5f9SBaptiste Daroussinin = stdin; 166c99fb5f9SBaptiste Daroussinparser = ucl_parser_new (0); 167c99fb5f9SBaptiste Daroussinwhile (!feof (in) && r < (int)sizeof (inbuf)) { 168c99fb5f9SBaptiste Daroussin r += fread (inbuf + r, 1, sizeof (inbuf) - r, in); 169c99fb5f9SBaptiste Daroussin} 170c99fb5f9SBaptiste Daroussinucl_parser_add_chunk (parser, inbuf, r); 171c99fb5f9SBaptiste Daroussinfclose (in); 172c99fb5f9SBaptiste Daroussin 173c99fb5f9SBaptiste Daroussinif (ucl_parser_get_error (parser)) { 174c99fb5f9SBaptiste Daroussin printf ("Error occured: %s\n", ucl_parser_get_error (parser)); 175c99fb5f9SBaptiste Daroussin ret = 1; 176c99fb5f9SBaptiste Daroussin} 177c99fb5f9SBaptiste Daroussinelse { 178c99fb5f9SBaptiste Daroussin obj = ucl_parser_get_object (parser); 179c99fb5f9SBaptiste Daroussin} 180c99fb5f9SBaptiste Daroussin 181c99fb5f9SBaptiste Daroussinif (parser != NULL) { 182c99fb5f9SBaptiste Daroussin ucl_parser_free (parser); 183c99fb5f9SBaptiste Daroussin} 184c99fb5f9SBaptiste Daroussinif (obj != NULL) { 185c99fb5f9SBaptiste Daroussin ucl_object_unref (obj); 186c99fb5f9SBaptiste Daroussin} 187c99fb5f9SBaptiste Daroussinreturn ret; 188c99fb5f9SBaptiste Daroussin~~~ 189c99fb5f9SBaptiste Daroussin 190c99fb5f9SBaptiste Daroussin# Emitting functions 191c99fb5f9SBaptiste Daroussin 192c99fb5f9SBaptiste DaroussinLibucl can transform UCL objects to a number of tectual formats: 193c99fb5f9SBaptiste Daroussin 194c99fb5f9SBaptiste Daroussin- configuration (`UCL_EMIT_CONFIG`) - nginx like human readable configuration file where implicit arrays are transformed to the duplicate keys 195c99fb5f9SBaptiste Daroussin- compact json: `UCL_EMIT_JSON_COMPACT` - single line valid json without spaces 196c99fb5f9SBaptiste Daroussin- formatted json: `UCL_EMIT_JSON` - pretty formatted JSON with newlines and spaces 197c99fb5f9SBaptiste Daroussin- compact yaml: `UCL_EMIT_YAML` - compact YAML output 198c99fb5f9SBaptiste Daroussin 199c99fb5f9SBaptiste DaroussinMoreover, libucl API allows to select a custom set of emitting functions allowing 200c99fb5f9SBaptiste Daroussinefficent and zero-copy output of libucl objects. Libucl uses the following structure to support this feature: 201c99fb5f9SBaptiste Daroussin 202c99fb5f9SBaptiste Daroussin~~~C 203c99fb5f9SBaptiste Daroussinstruct ucl_emitter_functions { 204c99fb5f9SBaptiste Daroussin /** Append a single character */ 205c99fb5f9SBaptiste Daroussin int (*ucl_emitter_append_character) (unsigned char c, size_t nchars, void *ud); 206c99fb5f9SBaptiste Daroussin /** Append a string of a specified length */ 207c99fb5f9SBaptiste Daroussin int (*ucl_emitter_append_len) (unsigned const char *str, size_t len, void *ud); 208c99fb5f9SBaptiste Daroussin /** Append a 64 bit integer */ 209c99fb5f9SBaptiste Daroussin int (*ucl_emitter_append_int) (int64_t elt, void *ud); 210c99fb5f9SBaptiste Daroussin /** Append floating point element */ 211c99fb5f9SBaptiste Daroussin int (*ucl_emitter_append_double) (double elt, void *ud); 212c99fb5f9SBaptiste Daroussin /** Opaque userdata pointer */ 213c99fb5f9SBaptiste Daroussin void *ud; 214c99fb5f9SBaptiste Daroussin}; 215c99fb5f9SBaptiste Daroussin~~~ 216c99fb5f9SBaptiste Daroussin 217c99fb5f9SBaptiste DaroussinThis structure defines the following callbacks: 218c99fb5f9SBaptiste Daroussin 219c99fb5f9SBaptiste Daroussin- `ucl_emitter_append_character` - a function that is called to append `nchars` characters equal to `c` 220c99fb5f9SBaptiste Daroussin- `ucl_emitter_append_len` - used to append a string of length `len` starting from pointer `str` 221c99fb5f9SBaptiste Daroussin- `ucl_emitter_append_int` - this function applies to integer numbers 222c99fb5f9SBaptiste Daroussin- `ucl_emitter_append_double` - this function is intended to output floating point variable 223c99fb5f9SBaptiste Daroussin 224c99fb5f9SBaptiste DaroussinThe set of these functions could be used to output text formats of `UCL` objects to different structures or streams. 225c99fb5f9SBaptiste Daroussin 226c99fb5f9SBaptiste DaroussinLibucl provides the following functions for emitting UCL objects: 227c99fb5f9SBaptiste Daroussin 228c99fb5f9SBaptiste Daroussin### ucl_object_emit 229c99fb5f9SBaptiste Daroussin 230c99fb5f9SBaptiste Daroussin~~~C 231c99fb5f9SBaptiste Daroussinunsigned char *ucl_object_emit (ucl_object_t *obj, enum ucl_emitter emit_type); 232c99fb5f9SBaptiste Daroussin~~~ 233c99fb5f9SBaptiste Daroussin 234c99fb5f9SBaptiste DaroussinAllocate a string that is suitable to fit the underlying UCL object `obj` and fill it with the textual representation of the object `obj` according to style `emit_type`. The caller should free the returned string after using. 235c99fb5f9SBaptiste Daroussin 236c99fb5f9SBaptiste Daroussin### ucl_object_emit_full 237c99fb5f9SBaptiste Daroussin 238c99fb5f9SBaptiste Daroussin~~~C 239c99fb5f9SBaptiste Daroussinbool ucl_object_emit_full (ucl_object_t *obj, enum ucl_emitter emit_type, 240c99fb5f9SBaptiste Daroussin struct ucl_emitter_functions *emitter); 241c99fb5f9SBaptiste Daroussin~~~ 242c99fb5f9SBaptiste Daroussin 243c99fb5f9SBaptiste DaroussinThis function is similar to the previous with the exception that it accepts the additional argument `emitter` that defines the concrete set of output functions. This emit function could be useful for custom structures or streams emitters (including C++ ones, for example). 244c99fb5f9SBaptiste Daroussin 245c99fb5f9SBaptiste Daroussin# Conversion functions 246c99fb5f9SBaptiste Daroussin 247c99fb5f9SBaptiste DaroussinConversion functions are used to convert UCL objects to primitive types, such as strings, numbers or boolean values. There are two types of conversion functions: 248c99fb5f9SBaptiste Daroussin 249c99fb5f9SBaptiste Daroussin- safe: try to convert an ucl object to a primitive type and fail if such a conversion is not possible 250c99fb5f9SBaptiste Daroussin- unsafe: return primitive type without additional checks, if the object cannot be converted then some reasonable default is returned (NULL for strings and 0 for numbers) 251c99fb5f9SBaptiste Daroussin 252c99fb5f9SBaptiste DaroussinAlso there is a single `ucl_object_tostring_forced` function that converts any UCL object (including compound types - arrays and objects) to a string representation. For compound and numeric types this function performs emitting to a compact json format actually. 253c99fb5f9SBaptiste Daroussin 254c99fb5f9SBaptiste DaroussinHere is a list of all conversion functions: 255c99fb5f9SBaptiste Daroussin 256c99fb5f9SBaptiste Daroussin- `ucl_object_toint` - returns `int64_t` of UCL object 257c99fb5f9SBaptiste Daroussin- `ucl_object_todouble` - returns `double` of UCL object 258c99fb5f9SBaptiste Daroussin- `ucl_object_toboolean` - returns `bool` of UCL object 259c99fb5f9SBaptiste Daroussin- `ucl_object_tostring` - returns `const char *` of UCL object (this string is NULL terminated) 260c99fb5f9SBaptiste Daroussin- `ucl_object_tolstring` - returns `const char *` and `size_t` len of UCL object (string can be not NULL terminated) 261c99fb5f9SBaptiste Daroussin- `ucl_object_tostring_forced` - returns string representation of any UCL object 262c99fb5f9SBaptiste Daroussin 263c99fb5f9SBaptiste DaroussinStrings returned by these pointers are associated with the UCL object and exist over its lifetime. A caller should not free this memory. 264*36c53d67SBaptiste Daroussin 265*36c53d67SBaptiste Daroussin# Generation functions 266*36c53d67SBaptiste Daroussin 267*36c53d67SBaptiste DaroussinIt is possible to generate UCL objects from C primitive types. Moreover, libucl permits to create and modify complex UCL objects, such as arrays or associative objects. 268*36c53d67SBaptiste Daroussin 269*36c53d67SBaptiste Daroussin## ucl_object_new 270*36c53d67SBaptiste Daroussin~~~C 271*36c53d67SBaptiste Daroussinucl_object_t * ucl_object_new (void) 272*36c53d67SBaptiste Daroussin~~~ 273*36c53d67SBaptiste Daroussin 274*36c53d67SBaptiste DaroussinCreates new object of type `UCL_NULL`. This object should be released by caller. 275*36c53d67SBaptiste Daroussin 276*36c53d67SBaptiste Daroussin## ucl_object_typed_new 277*36c53d67SBaptiste Daroussin~~~C 278*36c53d67SBaptiste Daroussinucl_object_t * ucl_object_typed_new (unsigned int type) 279*36c53d67SBaptiste Daroussin~~~ 280*36c53d67SBaptiste Daroussin 281*36c53d67SBaptiste DaroussinCreate an object of a specified type: 282*36c53d67SBaptiste Daroussin- `UCL_OBJECT` - UCL object - key/value pairs 283*36c53d67SBaptiste Daroussin- `UCL_ARRAY` - UCL array 284*36c53d67SBaptiste Daroussin- `UCL_INT` - integer number 285*36c53d67SBaptiste Daroussin- `UCL_FLOAT` - floating point number 286*36c53d67SBaptiste Daroussin- `UCL_STRING` - NULL terminated string 287*36c53d67SBaptiste Daroussin- `UCL_BOOLEAN` - boolean value 288*36c53d67SBaptiste Daroussin- `UCL_TIME` - time value (floating point number of seconds) 289*36c53d67SBaptiste Daroussin- `UCL_USERDATA` - opaque userdata pointer (may be used in macros) 290*36c53d67SBaptiste Daroussin- `UCL_NULL` - null value 291*36c53d67SBaptiste Daroussin 292*36c53d67SBaptiste DaroussinThis object should be released by caller. 293*36c53d67SBaptiste Daroussin 294*36c53d67SBaptiste Daroussin## Primitive objects generation 295*36c53d67SBaptiste DaroussinLibucl provides the functions similar to inverse conversion functions called with the specific C type: 296*36c53d67SBaptiste Daroussin- `ucl_object_fromint` - converts `int64_t` to UCL object 297*36c53d67SBaptiste Daroussin- `ucl_object_fromdouble` - converts `double` to UCL object 298*36c53d67SBaptiste Daroussin- `ucl_object_fromboolean` - converts `bool` to UCL object 299*36c53d67SBaptiste Daroussin- `ucl_object_fromstring` - converts `const char *` to UCL object (this string is NULL terminated) 300*36c53d67SBaptiste Daroussin- `ucl_object_fromlstring` - converts `const char *` and `size_t` len to UCL object (string can be not NULL terminated) 301*36c53d67SBaptiste Daroussin 302*36c53d67SBaptiste DaroussinAlso there is a function to generate UCL object from a string performing various parsing or conversion operations called `ucl_object_fromstring_common`. 303*36c53d67SBaptiste Daroussin 304*36c53d67SBaptiste Daroussin## ucl_object_fromstring_common 305*36c53d67SBaptiste Daroussin~~~C 306*36c53d67SBaptiste Daroussinucl_object_t * ucl_object_fromstring_common (const char *str, 307*36c53d67SBaptiste Daroussin size_t len, enum ucl_string_flags flags) 308*36c53d67SBaptiste Daroussin~~~ 309*36c53d67SBaptiste Daroussin 310*36c53d67SBaptiste DaroussinThis function is used to convert a string `str` of size `len` to an UCL objects applying `flags` conversions. If `len` is equal to zero then a `str` is assumed as NULL-terminated. This function supports the following flags (a set of flags can be specified using logical `OR` operation): 311*36c53d67SBaptiste Daroussin 312*36c53d67SBaptiste Daroussin- `UCL_STRING_ESCAPE` - perform JSON escape 313*36c53d67SBaptiste Daroussin- `UCL_STRING_TRIM` - trim leading and trailing whitespaces 314*36c53d67SBaptiste Daroussin- `UCL_STRING_PARSE_BOOLEAN` - parse passed string and detect boolean 315*36c53d67SBaptiste Daroussin- `UCL_STRING_PARSE_INT` - parse passed string and detect integer number 316*36c53d67SBaptiste Daroussin- `UCL_STRING_PARSE_DOUBLE` - parse passed string and detect integer or float number 317*36c53d67SBaptiste Daroussin- `UCL_STRING_PARSE_NUMBER` - parse passed string and detect number (both float or integer types) 318*36c53d67SBaptiste Daroussin- `UCL_STRING_PARSE` - parse passed string (and detect booleans and numbers) 319*36c53d67SBaptiste Daroussin- `UCL_STRING_PARSE_BYTES` - assume that numeric multipliers are in bytes notation, for example `10k` means `10*1024` and not `10*1000` as assumed without this flag 320*36c53d67SBaptiste Daroussin 321*36c53d67SBaptiste DaroussinIf parsing operations fail then the resulting UCL object will be a `UCL_STRING`. A caller should always check the type of the returned object and release it after using. 322*36c53d67SBaptiste Daroussin 323*36c53d67SBaptiste Daroussin# Iteration function 324*36c53d67SBaptiste Daroussin 325*36c53d67SBaptiste DaroussinIteration are used to iterate over UCL compound types: arrays and objects. Moreover, iterations could be performed over the keys with multiple values (implicit arrays). To iterate over an object, an array or a key with multiple values there is a function `ucl_iterate_object`. 326*36c53d67SBaptiste Daroussin 327*36c53d67SBaptiste Daroussin## ucl_iterate_object 328*36c53d67SBaptiste Daroussin~~~C 329*36c53d67SBaptiste Daroussinucl_object_t* ucl_iterate_object (ucl_object_t *obj, 330*36c53d67SBaptiste Daroussin ucl_object_iter_t *iter, bool expand_values); 331*36c53d67SBaptiste Daroussin~~~ 332*36c53d67SBaptiste Daroussin 333*36c53d67SBaptiste DaroussinThis function accept opaque iterator pointer `iter`. In the first call this iterator *must* be initialized to `NULL`. Iterator is changed by this function call. `ucl_iterate_object` returns the next UCL object in the compound object `obj` or `NULL` if all objects have been iterated. The reference count of the object returned is not increased, so a caller should not unref the object or modify its content (e.g. by inserting to another compound object). The object `obj` should not be changed during the iteration process as well. `expand_values` flag speicifies whether `ucl_iterate_object` should expand keys with multiple values. The general rule is that if you need to iterate throught the *object* or *explicit array*, then you always need to set this flag to `true`. However, if you get some key in the object and want to extract all its values then you should set `expand_values` to `false`. Mixing of iteration types are not permitted since the iterator is set according to the iteration type and cannot be reused. Here is an example of iteration over the objects using libucl API (assuming that `top` is `UCL_OBJECT` in this example): 334*36c53d67SBaptiste Daroussin 335*36c53d67SBaptiste Daroussin~~~C 336*36c53d67SBaptiste Daroussinucl_object_iter_t it = NULL, it_obj = NULL; 337*36c53d67SBaptiste Daroussinucl_object_t *cur, *tmp; 338*36c53d67SBaptiste Daroussin 339*36c53d67SBaptiste Daroussin/* Iterate over the object */ 340*36c53d67SBaptiste Daroussinwhile ((obj = ucl_iterate_object (top, &it, true))) { 341*36c53d67SBaptiste Daroussin printf ("key: \"%s\"\n", ucl_object_key (obj)); 342*36c53d67SBaptiste Daroussin /* Iterate over the values of a key */ 343*36c53d67SBaptiste Daroussin while ((cur = ucl_iterate_object (obj, &it_obj, false))) { 344*36c53d67SBaptiste Daroussin printf ("value: \"%s\"\n", 345*36c53d67SBaptiste Daroussin ucl_object_tostring_forced (cur)); 346*36c53d67SBaptiste Daroussin } 347*36c53d67SBaptiste Daroussin} 348*36c53d67SBaptiste Daroussin~~~