xref: /freebsd/contrib/libucl/doc/api.md (revision b04a7a0baf6523245034b8ccd06cd0176b8a18cf)
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).