197bd480fSBaptiste Daroussin# API documentation 297bd480fSBaptiste Daroussin 397bd480fSBaptiste Daroussin**Table of Contents** *generated with [DocToc](http://doctoc.herokuapp.com/)* 497bd480fSBaptiste Daroussin 597bd480fSBaptiste Daroussin- [Synopsis](#synopsis) 697bd480fSBaptiste Daroussin- [Description](#description) 797bd480fSBaptiste Daroussin - [Parser functions](#parser-functions) 897bd480fSBaptiste Daroussin - [Emitting functions](#emitting-functions) 997bd480fSBaptiste Daroussin - [Conversion functions](#conversion-functions) 1097bd480fSBaptiste Daroussin - [Generation functions](#generation-functions) 1197bd480fSBaptiste Daroussin - [Iteration functions](#iteration-functions) 1297bd480fSBaptiste Daroussin - [Validation functions](#validation-functions) 1397bd480fSBaptiste Daroussin - [Utility functions](#utility-functions) 1497bd480fSBaptiste Daroussin- [Parser functions](#parser-functions-1) 1597bd480fSBaptiste Daroussin - [ucl_parser_new](#ucl_parser_new) 1697bd480fSBaptiste Daroussin - [ucl_parser_register_macro](#ucl_parser_register_macro) 1797bd480fSBaptiste Daroussin - [ucl_parser_register_variable](#ucl_parser_register_variable) 1897bd480fSBaptiste Daroussin - [ucl_parser_add_chunk](#ucl_parser_add_chunk) 1997bd480fSBaptiste Daroussin - [ucl_parser_add_string](#ucl_parser_add_string) 2097bd480fSBaptiste Daroussin - [ucl_parser_add_file](#ucl_parser_add_file) 2197bd480fSBaptiste Daroussin - [ucl_parser_get_object](#ucl_parser_get_object) 2297bd480fSBaptiste Daroussin - [ucl_parser_get_error](#ucl_parser_get_error) 2397bd480fSBaptiste Daroussin - [ucl_parser_free](#ucl_parser_free) 2497bd480fSBaptiste Daroussin - [ucl_pubkey_add](#ucl_pubkey_add) 2597bd480fSBaptiste Daroussin - [ucl_parser_set_filevars](#ucl_parser_set_filevars) 2697bd480fSBaptiste Daroussin - [Parser usage example](#parser-usage-example) 2797bd480fSBaptiste Daroussin- [Emitting functions](#emitting-functions-1) 2897bd480fSBaptiste Daroussin - [ucl_object_emit](#ucl_object_emit) 2997bd480fSBaptiste Daroussin - [ucl_object_emit_full](#ucl_object_emit_full) 3097bd480fSBaptiste Daroussin- [Conversion functions](#conversion-functions-1) 3197bd480fSBaptiste Daroussin- [Generation functions](#generation-functions-1) 3297bd480fSBaptiste Daroussin - [ucl_object_new](#ucl_object_new) 3397bd480fSBaptiste Daroussin - [ucl_object_typed_new](#ucl_object_typed_new) 3497bd480fSBaptiste Daroussin - [Primitive objects generation](#primitive-objects-generation) 3597bd480fSBaptiste Daroussin - [ucl_object_fromstring_common](#ucl_object_fromstring_common) 3697bd480fSBaptiste Daroussin- [Iteration functions](#iteration-functions-1) 3797bd480fSBaptiste Daroussin - [ucl_iterate_object](#ucl_iterate_object) 3897bd480fSBaptiste Daroussin- [Validation functions](#validation-functions-1) 3997bd480fSBaptiste Daroussin - [ucl_object_validate](#ucl_object_validate) 4097bd480fSBaptiste Daroussin 4197bd480fSBaptiste Daroussin# Synopsis 42c99fb5f9SBaptiste Daroussin 43c99fb5f9SBaptiste Daroussin`#include <ucl.h>` 44c99fb5f9SBaptiste Daroussin 4597bd480fSBaptiste Daroussin# Description 46c99fb5f9SBaptiste Daroussin 47c99fb5f9SBaptiste DaroussinLibucl is a parser and `C` API to parse and generate `ucl` objects. Libucl consist of several groups of functions: 48c99fb5f9SBaptiste Daroussin 49c99fb5f9SBaptiste Daroussin### Parser functions 5097bd480fSBaptiste DaroussinUsed to parse `ucl` files and provide interface to extract `ucl` object. Currently, `libucl` can parse only full `ucl` documents, for instance, it is impossible to parse a part of document and therefore it is impossible to use `libucl` as a streaming parser. In future, this limitation can be removed. 51c99fb5f9SBaptiste Daroussin 52c99fb5f9SBaptiste Daroussin### Emitting functions 5397bd480fSBaptiste DaroussinConvert `ucl` objects to some textual or binary representation. Currently, libucl supports the following exports: 5497bd480fSBaptiste Daroussin 5597bd480fSBaptiste Daroussin- `JSON` - valid json format (can possibly loose some original data, such as implicit arrays) 5697bd480fSBaptiste Daroussin- `Config` - human-readable configuration format (losseless) 5797bd480fSBaptiste Daroussin- `YAML` - embedded yaml format (has the same limitations as `json` output) 58c99fb5f9SBaptiste Daroussin 59c99fb5f9SBaptiste Daroussin### Conversion functions 6097bd480fSBaptiste DaroussinHelp to convert `ucl` objects to C types. These functions are used to convert `ucl_object_t` to C primitive types, such as numbers, strings or boolean values. 61c99fb5f9SBaptiste Daroussin 62c99fb5f9SBaptiste Daroussin### Generation functions 6397bd480fSBaptiste DaroussinAllow creating of `ucl` objects from C types and creating of complex `ucl` objects, such as hashes or arrays from primitive `ucl` objects, such as numbers or strings. 64c99fb5f9SBaptiste Daroussin 65c99fb5f9SBaptiste Daroussin### Iteration functions 6697bd480fSBaptiste DaroussinIterate over `ucl` complex objects or over a chain of values, for example when a key in an object has multiple values (that can be treated as implicit array or implicit consolidation). 6797bd480fSBaptiste Daroussin 6897bd480fSBaptiste Daroussin### Validation functions 6997bd480fSBaptiste DaroussinValidation functions are used to validate some object `obj` using json-schema compatible object `schema`. Both input and schema must be UCL objects to perform validation. 70c99fb5f9SBaptiste Daroussin 71c99fb5f9SBaptiste Daroussin### Utility functions 7297bd480fSBaptiste DaroussinProvide basic utilities to manage `ucl` objects: creating, removing, retaining and releasing reference count and so on. 73c99fb5f9SBaptiste Daroussin 74c99fb5f9SBaptiste Daroussin# Parser functions 75c99fb5f9SBaptiste Daroussin 76c99fb5f9SBaptiste DaroussinParser functions operates with `struct ucl_parser`. 77c99fb5f9SBaptiste Daroussin 78c99fb5f9SBaptiste Daroussin### ucl_parser_new 79c99fb5f9SBaptiste Daroussin 80c99fb5f9SBaptiste Daroussin~~~C 81c99fb5f9SBaptiste Daroussinstruct ucl_parser* ucl_parser_new (int flags); 82c99fb5f9SBaptiste Daroussin~~~ 83c99fb5f9SBaptiste Daroussin 84c99fb5f9SBaptiste DaroussinCreates new parser with the specified flags: 85c99fb5f9SBaptiste Daroussin 86c99fb5f9SBaptiste Daroussin- `UCL_PARSER_KEY_LOWERCASE` - lowercase keys parsed 87c99fb5f9SBaptiste 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) 8897bd480fSBaptiste Daroussin- `UCL_PARSER_NO_TIME` - treat time values as strings without parsing them as floats 89c99fb5f9SBaptiste Daroussin 90c99fb5f9SBaptiste Daroussin### ucl_parser_register_macro 91c99fb5f9SBaptiste Daroussin 92c99fb5f9SBaptiste Daroussin~~~C 93c99fb5f9SBaptiste Daroussinvoid ucl_parser_register_macro (struct ucl_parser *parser, 94c99fb5f9SBaptiste Daroussin const char *macro, ucl_macro_handler handler, void* ud); 95c99fb5f9SBaptiste Daroussin~~~ 96c99fb5f9SBaptiste Daroussin 97c99fb5f9SBaptiste DaroussinRegister new macro with name .`macro` parsed by handler `handler` that accepts opaque data pointer `ud`. Macro handler should be of the following type: 98c99fb5f9SBaptiste Daroussin 99c99fb5f9SBaptiste Daroussin~~~C 100c99fb5f9SBaptiste Daroussinbool (*ucl_macro_handler) (const unsigned char *data, 101c99fb5f9SBaptiste Daroussin size_t len, void* ud);` 102c99fb5f9SBaptiste Daroussin~~~ 103c99fb5f9SBaptiste Daroussin 104c99fb5f9SBaptiste 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. 105c99fb5f9SBaptiste Daroussin 106c99fb5f9SBaptiste Daroussin### ucl_parser_register_variable 107c99fb5f9SBaptiste Daroussin 108c99fb5f9SBaptiste Daroussin~~~C 109c99fb5f9SBaptiste Daroussinvoid ucl_parser_register_variable (struct ucl_parser *parser, 110c99fb5f9SBaptiste Daroussin const char *var, const char *value); 111c99fb5f9SBaptiste Daroussin~~~ 112c99fb5f9SBaptiste Daroussin 113c99fb5f9SBaptiste DaroussinRegister new variable $`var` that should be replaced by the parser to the `value` string. 114c99fb5f9SBaptiste Daroussin 115c99fb5f9SBaptiste Daroussin### ucl_parser_add_chunk 116c99fb5f9SBaptiste Daroussin 117c99fb5f9SBaptiste Daroussin~~~C 118c99fb5f9SBaptiste Daroussinbool ucl_parser_add_chunk (struct ucl_parser *parser, 119c99fb5f9SBaptiste Daroussin const unsigned char *data, size_t len); 120c99fb5f9SBaptiste Daroussin~~~ 121c99fb5f9SBaptiste Daroussin 122c99fb5f9SBaptiste 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: 123c99fb5f9SBaptiste Daroussin 124c99fb5f9SBaptiste Daroussin~~~json 125c99fb5f9SBaptiste Daroussin{ "var": "value" } 126c99fb5f9SBaptiste Daroussin~~~ 127c99fb5f9SBaptiste Daroussin 128c99fb5f9SBaptiste Daroussinwhile this one won't be parsed correctly: 129c99fb5f9SBaptiste Daroussin 130c99fb5f9SBaptiste Daroussin~~~json 131c99fb5f9SBaptiste Daroussin{ "var": 132c99fb5f9SBaptiste Daroussin~~~ 133c99fb5f9SBaptiste Daroussin 134c99fb5f9SBaptiste DaroussinThis limitation may possible be removed in future. 135c99fb5f9SBaptiste Daroussin 13697bd480fSBaptiste Daroussin### ucl_parser_add_string 13797bd480fSBaptiste Daroussin~~~C 13897bd480fSBaptiste Daroussinbool ucl_parser_add_string (struct ucl_parser *parser, 13997bd480fSBaptiste Daroussin const char *data, size_t len); 14097bd480fSBaptiste Daroussin~~~ 14197bd480fSBaptiste Daroussin 14297bd480fSBaptiste DaroussinThis function acts exactly like `ucl_parser_add_chunk` does but if `len` argument is zero, then the string `data` must be zero-terminated and the actual length is calculated up to `\0` character. 14397bd480fSBaptiste Daroussin 144c99fb5f9SBaptiste Daroussin### ucl_parser_add_file 145c99fb5f9SBaptiste Daroussin 146c99fb5f9SBaptiste Daroussin~~~C 147c99fb5f9SBaptiste Daroussinbool ucl_parser_add_file (struct ucl_parser *parser, 148c99fb5f9SBaptiste Daroussin const char *filename); 149c99fb5f9SBaptiste Daroussin~~~ 150c99fb5f9SBaptiste Daroussin 151c99fb5f9SBaptiste 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. 152c99fb5f9SBaptiste Daroussin 153c99fb5f9SBaptiste Daroussin### ucl_parser_get_object 154c99fb5f9SBaptiste Daroussin 155c99fb5f9SBaptiste Daroussin~~~C 156c99fb5f9SBaptiste Daroussinucl_object_t* ucl_parser_get_object (struct ucl_parser *parser); 157c99fb5f9SBaptiste Daroussin~~~ 158c99fb5f9SBaptiste Daroussin 159c99fb5f9SBaptiste 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. 160c99fb5f9SBaptiste Daroussin 161c99fb5f9SBaptiste Daroussin### ucl_parser_get_error 162c99fb5f9SBaptiste Daroussin 163c99fb5f9SBaptiste Daroussin~~~C 164c99fb5f9SBaptiste Daroussinconst char *ucl_parser_get_error(struct ucl_parser *parser); 165c99fb5f9SBaptiste Daroussin~~~ 166c99fb5f9SBaptiste Daroussin 167c99fb5f9SBaptiste 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. 168c99fb5f9SBaptiste Daroussin 169c99fb5f9SBaptiste Daroussin### ucl_parser_free 170c99fb5f9SBaptiste Daroussin 171c99fb5f9SBaptiste Daroussin~~~C 172c99fb5f9SBaptiste Daroussinvoid ucl_parser_free (struct ucl_parser *parser); 173c99fb5f9SBaptiste Daroussin~~~ 174c99fb5f9SBaptiste Daroussin 175c99fb5f9SBaptiste 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. 176c99fb5f9SBaptiste Daroussin 177c99fb5f9SBaptiste Daroussin### ucl_pubkey_add 178c99fb5f9SBaptiste Daroussin 179c99fb5f9SBaptiste Daroussin~~~C 180c99fb5f9SBaptiste Daroussinbool ucl_pubkey_add (struct ucl_parser *parser, 181c99fb5f9SBaptiste Daroussin const unsigned char *key, size_t len); 182c99fb5f9SBaptiste Daroussin~~~ 183c99fb5f9SBaptiste Daroussin 184c99fb5f9SBaptiste 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`. 185c99fb5f9SBaptiste Daroussin 186c99fb5f9SBaptiste Daroussin### ucl_parser_set_filevars 187c99fb5f9SBaptiste Daroussin 188c99fb5f9SBaptiste Daroussin~~~C 189c99fb5f9SBaptiste Daroussinbool ucl_parser_set_filevars (struct ucl_parser *parser, 190c99fb5f9SBaptiste Daroussin const char *filename, bool need_expand); 191c99fb5f9SBaptiste Daroussin~~~ 192c99fb5f9SBaptiste Daroussin 193c99fb5f9SBaptiste DaroussinAdd the standard file variables to the `parser` based on the `filename` specified: 194c99fb5f9SBaptiste Daroussin 195c99fb5f9SBaptiste Daroussin- `$FILENAME` - a filename of `ucl` input 196c99fb5f9SBaptiste Daroussin- `$CURDIR` - a current directory of the input 197c99fb5f9SBaptiste Daroussin 198c99fb5f9SBaptiste DaroussinFor example, if a `filename` param is `../something.conf` then the variables will have the following values: 199c99fb5f9SBaptiste Daroussin 200c99fb5f9SBaptiste Daroussin- `$FILENAME` - "../something.conf" 201c99fb5f9SBaptiste Daroussin- `$CURDIR` - ".." 202c99fb5f9SBaptiste Daroussin 203c99fb5f9SBaptiste 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: 204c99fb5f9SBaptiste Daroussin 205c99fb5f9SBaptiste Daroussin- `$FILENAME` - "/etc/something.conf" 206c99fb5f9SBaptiste Daroussin- `$CURDIR` - "/etc" 207c99fb5f9SBaptiste Daroussin 208c99fb5f9SBaptiste Daroussin## Parser usage example 209c99fb5f9SBaptiste Daroussin 210c99fb5f9SBaptiste DaroussinThe following example loads, parses and extracts `ucl` object from stdin using `libucl` parser functions (the length of input is limited to 8K): 211c99fb5f9SBaptiste Daroussin 212c99fb5f9SBaptiste Daroussin~~~C 213c99fb5f9SBaptiste Daroussinchar inbuf[8192]; 214c99fb5f9SBaptiste Daroussinstruct ucl_parser *parser = NULL; 215c99fb5f9SBaptiste Daroussinint ret = 0, r = 0; 216c99fb5f9SBaptiste Daroussinucl_object_t *obj = NULL; 217c99fb5f9SBaptiste DaroussinFILE *in; 218c99fb5f9SBaptiste Daroussin 219c99fb5f9SBaptiste Daroussinin = stdin; 220c99fb5f9SBaptiste Daroussinparser = ucl_parser_new (0); 221c99fb5f9SBaptiste Daroussinwhile (!feof (in) && r < (int)sizeof (inbuf)) { 222c99fb5f9SBaptiste Daroussin r += fread (inbuf + r, 1, sizeof (inbuf) - r, in); 223c99fb5f9SBaptiste Daroussin} 224c99fb5f9SBaptiste Daroussinucl_parser_add_chunk (parser, inbuf, r); 225c99fb5f9SBaptiste Daroussinfclose (in); 226c99fb5f9SBaptiste Daroussin 227c99fb5f9SBaptiste Daroussinif (ucl_parser_get_error (parser)) { 228c99fb5f9SBaptiste Daroussin printf ("Error occured: %s\n", ucl_parser_get_error (parser)); 229c99fb5f9SBaptiste Daroussin ret = 1; 230c99fb5f9SBaptiste Daroussin} 231c99fb5f9SBaptiste Daroussinelse { 232c99fb5f9SBaptiste Daroussin obj = ucl_parser_get_object (parser); 233c99fb5f9SBaptiste Daroussin} 234c99fb5f9SBaptiste Daroussin 235c99fb5f9SBaptiste Daroussinif (parser != NULL) { 236c99fb5f9SBaptiste Daroussin ucl_parser_free (parser); 237c99fb5f9SBaptiste Daroussin} 238c99fb5f9SBaptiste Daroussinif (obj != NULL) { 239c99fb5f9SBaptiste Daroussin ucl_object_unref (obj); 240c99fb5f9SBaptiste Daroussin} 241c99fb5f9SBaptiste Daroussinreturn ret; 242c99fb5f9SBaptiste Daroussin~~~ 243c99fb5f9SBaptiste Daroussin 244c99fb5f9SBaptiste Daroussin# Emitting functions 245c99fb5f9SBaptiste Daroussin 246c99fb5f9SBaptiste DaroussinLibucl can transform UCL objects to a number of tectual formats: 247c99fb5f9SBaptiste Daroussin 248c99fb5f9SBaptiste Daroussin- configuration (`UCL_EMIT_CONFIG`) - nginx like human readable configuration file where implicit arrays are transformed to the duplicate keys 249c99fb5f9SBaptiste Daroussin- compact json: `UCL_EMIT_JSON_COMPACT` - single line valid json without spaces 250c99fb5f9SBaptiste Daroussin- formatted json: `UCL_EMIT_JSON` - pretty formatted JSON with newlines and spaces 251c99fb5f9SBaptiste Daroussin- compact yaml: `UCL_EMIT_YAML` - compact YAML output 252c99fb5f9SBaptiste Daroussin 253c99fb5f9SBaptiste DaroussinMoreover, libucl API allows to select a custom set of emitting functions allowing 254c99fb5f9SBaptiste Daroussinefficent and zero-copy output of libucl objects. Libucl uses the following structure to support this feature: 255c99fb5f9SBaptiste Daroussin 256c99fb5f9SBaptiste Daroussin~~~C 257c99fb5f9SBaptiste Daroussinstruct ucl_emitter_functions { 258c99fb5f9SBaptiste Daroussin /** Append a single character */ 259c99fb5f9SBaptiste Daroussin int (*ucl_emitter_append_character) (unsigned char c, size_t nchars, void *ud); 260c99fb5f9SBaptiste Daroussin /** Append a string of a specified length */ 261c99fb5f9SBaptiste Daroussin int (*ucl_emitter_append_len) (unsigned const char *str, size_t len, void *ud); 262c99fb5f9SBaptiste Daroussin /** Append a 64 bit integer */ 263c99fb5f9SBaptiste Daroussin int (*ucl_emitter_append_int) (int64_t elt, void *ud); 264c99fb5f9SBaptiste Daroussin /** Append floating point element */ 265c99fb5f9SBaptiste Daroussin int (*ucl_emitter_append_double) (double elt, void *ud); 266c99fb5f9SBaptiste Daroussin /** Opaque userdata pointer */ 267c99fb5f9SBaptiste Daroussin void *ud; 268c99fb5f9SBaptiste Daroussin}; 269c99fb5f9SBaptiste Daroussin~~~ 270c99fb5f9SBaptiste Daroussin 271c99fb5f9SBaptiste DaroussinThis structure defines the following callbacks: 272c99fb5f9SBaptiste Daroussin 273c99fb5f9SBaptiste Daroussin- `ucl_emitter_append_character` - a function that is called to append `nchars` characters equal to `c` 274c99fb5f9SBaptiste Daroussin- `ucl_emitter_append_len` - used to append a string of length `len` starting from pointer `str` 275c99fb5f9SBaptiste Daroussin- `ucl_emitter_append_int` - this function applies to integer numbers 276c99fb5f9SBaptiste Daroussin- `ucl_emitter_append_double` - this function is intended to output floating point variable 277c99fb5f9SBaptiste Daroussin 278c99fb5f9SBaptiste DaroussinThe set of these functions could be used to output text formats of `UCL` objects to different structures or streams. 279c99fb5f9SBaptiste Daroussin 280c99fb5f9SBaptiste DaroussinLibucl provides the following functions for emitting UCL objects: 281c99fb5f9SBaptiste Daroussin 282c99fb5f9SBaptiste Daroussin### ucl_object_emit 283c99fb5f9SBaptiste Daroussin 284c99fb5f9SBaptiste Daroussin~~~C 285*b04a7a0bSBaptiste Daroussinunsigned char *ucl_object_emit (const ucl_object_t *obj, enum ucl_emitter emit_type); 286c99fb5f9SBaptiste Daroussin~~~ 287c99fb5f9SBaptiste Daroussin 288c99fb5f9SBaptiste 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. 289c99fb5f9SBaptiste Daroussin 290c99fb5f9SBaptiste Daroussin### ucl_object_emit_full 291c99fb5f9SBaptiste Daroussin 292c99fb5f9SBaptiste Daroussin~~~C 293*b04a7a0bSBaptiste Daroussinbool ucl_object_emit_full (const ucl_object_t *obj, enum ucl_emitter emit_type, 294c99fb5f9SBaptiste Daroussin struct ucl_emitter_functions *emitter); 295c99fb5f9SBaptiste Daroussin~~~ 296c99fb5f9SBaptiste Daroussin 297c99fb5f9SBaptiste 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). 298c99fb5f9SBaptiste Daroussin 299c99fb5f9SBaptiste Daroussin# Conversion functions 300c99fb5f9SBaptiste Daroussin 301c99fb5f9SBaptiste 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: 302c99fb5f9SBaptiste Daroussin 303c99fb5f9SBaptiste Daroussin- safe: try to convert an ucl object to a primitive type and fail if such a conversion is not possible 304c99fb5f9SBaptiste 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) 305c99fb5f9SBaptiste Daroussin 306c99fb5f9SBaptiste 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. 307c99fb5f9SBaptiste Daroussin 308c99fb5f9SBaptiste DaroussinHere is a list of all conversion functions: 309c99fb5f9SBaptiste Daroussin 310c99fb5f9SBaptiste Daroussin- `ucl_object_toint` - returns `int64_t` of UCL object 311c99fb5f9SBaptiste Daroussin- `ucl_object_todouble` - returns `double` of UCL object 312c99fb5f9SBaptiste Daroussin- `ucl_object_toboolean` - returns `bool` of UCL object 313c99fb5f9SBaptiste Daroussin- `ucl_object_tostring` - returns `const char *` of UCL object (this string is NULL terminated) 314c99fb5f9SBaptiste Daroussin- `ucl_object_tolstring` - returns `const char *` and `size_t` len of UCL object (string can be not NULL terminated) 315c99fb5f9SBaptiste Daroussin- `ucl_object_tostring_forced` - returns string representation of any UCL object 316c99fb5f9SBaptiste Daroussin 317c99fb5f9SBaptiste DaroussinStrings returned by these pointers are associated with the UCL object and exist over its lifetime. A caller should not free this memory. 31836c53d67SBaptiste Daroussin 31936c53d67SBaptiste Daroussin# Generation functions 32036c53d67SBaptiste Daroussin 32136c53d67SBaptiste 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. 32236c53d67SBaptiste Daroussin 32336c53d67SBaptiste Daroussin## ucl_object_new 32436c53d67SBaptiste Daroussin~~~C 32536c53d67SBaptiste Daroussinucl_object_t * ucl_object_new (void) 32636c53d67SBaptiste Daroussin~~~ 32736c53d67SBaptiste Daroussin 32836c53d67SBaptiste DaroussinCreates new object of type `UCL_NULL`. This object should be released by caller. 32936c53d67SBaptiste Daroussin 33036c53d67SBaptiste Daroussin## ucl_object_typed_new 33136c53d67SBaptiste Daroussin~~~C 33236c53d67SBaptiste Daroussinucl_object_t * ucl_object_typed_new (unsigned int type) 33336c53d67SBaptiste Daroussin~~~ 33436c53d67SBaptiste Daroussin 33536c53d67SBaptiste DaroussinCreate an object of a specified type: 33636c53d67SBaptiste Daroussin- `UCL_OBJECT` - UCL object - key/value pairs 33736c53d67SBaptiste Daroussin- `UCL_ARRAY` - UCL array 33836c53d67SBaptiste Daroussin- `UCL_INT` - integer number 33936c53d67SBaptiste Daroussin- `UCL_FLOAT` - floating point number 34036c53d67SBaptiste Daroussin- `UCL_STRING` - NULL terminated string 34136c53d67SBaptiste Daroussin- `UCL_BOOLEAN` - boolean value 34236c53d67SBaptiste Daroussin- `UCL_TIME` - time value (floating point number of seconds) 34336c53d67SBaptiste Daroussin- `UCL_USERDATA` - opaque userdata pointer (may be used in macros) 34436c53d67SBaptiste Daroussin- `UCL_NULL` - null value 34536c53d67SBaptiste Daroussin 34636c53d67SBaptiste DaroussinThis object should be released by caller. 34736c53d67SBaptiste Daroussin 34836c53d67SBaptiste Daroussin## Primitive objects generation 34936c53d67SBaptiste DaroussinLibucl provides the functions similar to inverse conversion functions called with the specific C type: 35036c53d67SBaptiste Daroussin- `ucl_object_fromint` - converts `int64_t` to UCL object 35136c53d67SBaptiste Daroussin- `ucl_object_fromdouble` - converts `double` to UCL object 35236c53d67SBaptiste Daroussin- `ucl_object_fromboolean` - converts `bool` to UCL object 35336c53d67SBaptiste Daroussin- `ucl_object_fromstring` - converts `const char *` to UCL object (this string is NULL terminated) 35436c53d67SBaptiste Daroussin- `ucl_object_fromlstring` - converts `const char *` and `size_t` len to UCL object (string can be not NULL terminated) 35536c53d67SBaptiste Daroussin 35636c53d67SBaptiste DaroussinAlso there is a function to generate UCL object from a string performing various parsing or conversion operations called `ucl_object_fromstring_common`. 35736c53d67SBaptiste Daroussin 35836c53d67SBaptiste Daroussin## ucl_object_fromstring_common 35936c53d67SBaptiste Daroussin~~~C 36036c53d67SBaptiste Daroussinucl_object_t * ucl_object_fromstring_common (const char *str, 36136c53d67SBaptiste Daroussin size_t len, enum ucl_string_flags flags) 36236c53d67SBaptiste Daroussin~~~ 36336c53d67SBaptiste Daroussin 36436c53d67SBaptiste 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): 36536c53d67SBaptiste Daroussin 36636c53d67SBaptiste Daroussin- `UCL_STRING_ESCAPE` - perform JSON escape 36736c53d67SBaptiste Daroussin- `UCL_STRING_TRIM` - trim leading and trailing whitespaces 36836c53d67SBaptiste Daroussin- `UCL_STRING_PARSE_BOOLEAN` - parse passed string and detect boolean 36936c53d67SBaptiste Daroussin- `UCL_STRING_PARSE_INT` - parse passed string and detect integer number 37036c53d67SBaptiste Daroussin- `UCL_STRING_PARSE_DOUBLE` - parse passed string and detect integer or float number 37197bd480fSBaptiste Daroussin- `UCL_STRING_PARSE_TIME` - parse time values as floating point numbers 37297bd480fSBaptiste Daroussin- `UCL_STRING_PARSE_NUMBER` - parse passed string and detect number (both float, integer and time types) 37397bd480fSBaptiste Daroussin- `UCL_STRING_PARSE` - parse passed string (and detect booleans, numbers and time values) 37436c53d67SBaptiste 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 37536c53d67SBaptiste Daroussin 37636c53d67SBaptiste 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. 37736c53d67SBaptiste Daroussin 37897bd480fSBaptiste Daroussin# Iteration functions 37936c53d67SBaptiste Daroussin 38036c53d67SBaptiste 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`. 38136c53d67SBaptiste Daroussin 38236c53d67SBaptiste Daroussin## ucl_iterate_object 38336c53d67SBaptiste Daroussin~~~C 384*b04a7a0bSBaptiste Daroussinconst ucl_object_t* ucl_iterate_object (const ucl_object_t *obj, 38536c53d67SBaptiste Daroussin ucl_object_iter_t *iter, bool expand_values); 38636c53d67SBaptiste Daroussin~~~ 38736c53d67SBaptiste Daroussin 38836c53d67SBaptiste 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): 38936c53d67SBaptiste Daroussin 39036c53d67SBaptiste Daroussin~~~C 39136c53d67SBaptiste Daroussinucl_object_iter_t it = NULL, it_obj = NULL; 392*b04a7a0bSBaptiste Daroussinconst ucl_object_t *cur, *tmp; 39336c53d67SBaptiste Daroussin 39436c53d67SBaptiste Daroussin/* Iterate over the object */ 39536c53d67SBaptiste Daroussinwhile ((obj = ucl_iterate_object (top, &it, true))) { 39636c53d67SBaptiste Daroussin printf ("key: \"%s\"\n", ucl_object_key (obj)); 39736c53d67SBaptiste Daroussin /* Iterate over the values of a key */ 39836c53d67SBaptiste Daroussin while ((cur = ucl_iterate_object (obj, &it_obj, false))) { 39936c53d67SBaptiste Daroussin printf ("value: \"%s\"\n", 40036c53d67SBaptiste Daroussin ucl_object_tostring_forced (cur)); 40136c53d67SBaptiste Daroussin } 40236c53d67SBaptiste Daroussin} 40336c53d67SBaptiste Daroussin~~~ 40497bd480fSBaptiste Daroussin 40597bd480fSBaptiste Daroussin# Validation functions 40697bd480fSBaptiste Daroussin 40797bd480fSBaptiste DaroussinCurrently, there is only one validation function called `ucl_object_validate`. It performs validation of object using the specified schema. This function is defined as following: 40897bd480fSBaptiste Daroussin 40997bd480fSBaptiste Daroussin## ucl_object_validate 41097bd480fSBaptiste Daroussin~~~C 411*b04a7a0bSBaptiste Daroussinbool ucl_object_validate (const ucl_object_t *schema, 412*b04a7a0bSBaptiste Daroussin const ucl_object_t *obj, struct ucl_schema_error *err); 41397bd480fSBaptiste Daroussin~~~ 41497bd480fSBaptiste Daroussin 41597bd480fSBaptiste DaroussinThis function uses ucl object `schema`, that must be valid in terms of `json-schema` draft v4, to validate input object `obj`. If this function returns `true` then validation procedure has been succeed. Otherwise, `false` is returned and `err` is set to a specific value. If caller set `err` to NULL then this function does not set any error just returning `false`. Error is the structure defined as following: 41697bd480fSBaptiste Daroussin 41797bd480fSBaptiste Daroussin~~~C 41897bd480fSBaptiste Daroussinstruct ucl_schema_error { 41997bd480fSBaptiste Daroussin enum ucl_schema_error_code code; /* error code */ 42097bd480fSBaptiste Daroussin char msg[128]; /* error message */ 42197bd480fSBaptiste Daroussin ucl_object_t *obj; /* object where error occured */ 42297bd480fSBaptiste Daroussin}; 42397bd480fSBaptiste Daroussin~~~ 42497bd480fSBaptiste Daroussin 42597bd480fSBaptiste DaroussinCaller may use `code` field to get a numeric error code: 42697bd480fSBaptiste Daroussin 42797bd480fSBaptiste Daroussin~~~C 42897bd480fSBaptiste Daroussinenum ucl_schema_error_code { 42997bd480fSBaptiste Daroussin UCL_SCHEMA_OK = 0, /* no error */ 43097bd480fSBaptiste Daroussin UCL_SCHEMA_TYPE_MISMATCH, /* type of object is incorrect */ 43197bd480fSBaptiste Daroussin UCL_SCHEMA_INVALID_SCHEMA, /* schema is invalid */ 43297bd480fSBaptiste Daroussin UCL_SCHEMA_MISSING_PROPERTY,/* missing properties */ 43397bd480fSBaptiste Daroussin UCL_SCHEMA_CONSTRAINT, /* constraint found */ 43497bd480fSBaptiste Daroussin UCL_SCHEMA_MISSING_DEPENDENCY, /* missing dependency */ 43597bd480fSBaptiste Daroussin UCL_SCHEMA_UNKNOWN /* generic error */ 43697bd480fSBaptiste Daroussin}; 43797bd480fSBaptiste Daroussin~~~ 43897bd480fSBaptiste Daroussin 43997bd480fSBaptiste Daroussin`msg` is a stiring description of an error and `obj` is an object where error has been occurred. Error object is not allocated by libucl, so there is no need to free it after validation (a static object should thus be used).