summaryrefslogtreecommitdiffstats
path: root/contrib/libucl/doc
diff options
context:
space:
mode:
authorbapt <bapt@FreeBSD.org>2014-07-19 23:44:57 +0000
committerbapt <bapt@FreeBSD.org>2014-07-19 23:44:57 +0000
commit6f718e3669e9ecc1b1ca407a465d6ee20571a2b8 (patch)
treeba71cc26671c93ed9809f7cadb07734c0bddb4c7 /contrib/libucl/doc
parent6095428430d025abcf6983536297f168bf62b45b (diff)
downloadFreeBSD-src-6f718e3669e9ecc1b1ca407a465d6ee20571a2b8.zip
FreeBSD-src-6f718e3669e9ecc1b1ca407a465d6ee20571a2b8.tar.gz
MFC: r263648, r264789, r266636
This brings: - schema validation - xpath-like interface for ucl objects Adapt pkg(7) to the new libucl API
Diffstat (limited to 'contrib/libucl/doc')
-rw-r--r--contrib/libucl/doc/Makefile.am8
-rw-r--r--contrib/libucl/doc/api.md127
-rw-r--r--contrib/libucl/doc/libucl.3637
-rw-r--r--contrib/libucl/doc/pandoc.template12
4 files changed, 766 insertions, 18 deletions
diff --git a/contrib/libucl/doc/Makefile.am b/contrib/libucl/doc/Makefile.am
new file mode 100644
index 0000000..7e57a82
--- /dev/null
+++ b/contrib/libucl/doc/Makefile.am
@@ -0,0 +1,8 @@
+EXTRA_DIST = api.md
+
+dist_man_MANS = libucl.3
+
+gen-man: @PANDOC@
+ tail -n +$$(grep -n '# Synopsis' api.md | cut -d':' -f1) api.md | \
+ cat pandoc.template - | sed -e 's/^# \(.*\)/# \U\1/' | \
+ @PANDOC@ -s -f markdown -t man -o libucl.3 \ No newline at end of file
diff --git a/contrib/libucl/doc/api.md b/contrib/libucl/doc/api.md
index 0523f53..41e660a 100644
--- a/contrib/libucl/doc/api.md
+++ b/contrib/libucl/doc/api.md
@@ -1,30 +1,75 @@
-Synopsis
-========
+# API documentation
+
+**Table of Contents** *generated with [DocToc](http://doctoc.herokuapp.com/)*
+
+- [Synopsis](#synopsis)
+- [Description](#description)
+ - [Parser functions](#parser-functions)
+ - [Emitting functions](#emitting-functions)
+ - [Conversion functions](#conversion-functions)
+ - [Generation functions](#generation-functions)
+ - [Iteration functions](#iteration-functions)
+ - [Validation functions](#validation-functions)
+ - [Utility functions](#utility-functions)
+- [Parser functions](#parser-functions-1)
+ - [ucl_parser_new](#ucl_parser_new)
+ - [ucl_parser_register_macro](#ucl_parser_register_macro)
+ - [ucl_parser_register_variable](#ucl_parser_register_variable)
+ - [ucl_parser_add_chunk](#ucl_parser_add_chunk)
+ - [ucl_parser_add_string](#ucl_parser_add_string)
+ - [ucl_parser_add_file](#ucl_parser_add_file)
+ - [ucl_parser_get_object](#ucl_parser_get_object)
+ - [ucl_parser_get_error](#ucl_parser_get_error)
+ - [ucl_parser_free](#ucl_parser_free)
+ - [ucl_pubkey_add](#ucl_pubkey_add)
+ - [ucl_parser_set_filevars](#ucl_parser_set_filevars)
+ - [Parser usage example](#parser-usage-example)
+- [Emitting functions](#emitting-functions-1)
+ - [ucl_object_emit](#ucl_object_emit)
+ - [ucl_object_emit_full](#ucl_object_emit_full)
+- [Conversion functions](#conversion-functions-1)
+- [Generation functions](#generation-functions-1)
+ - [ucl_object_new](#ucl_object_new)
+ - [ucl_object_typed_new](#ucl_object_typed_new)
+ - [Primitive objects generation](#primitive-objects-generation)
+ - [ucl_object_fromstring_common](#ucl_object_fromstring_common)
+- [Iteration functions](#iteration-functions-1)
+ - [ucl_iterate_object](#ucl_iterate_object)
+- [Validation functions](#validation-functions-1)
+ - [ucl_object_validate](#ucl_object_validate)
+
+# Synopsis
`#include <ucl.h>`
-Description
-===========
+# Description
Libucl is a parser and `C` API to parse and generate `ucl` objects. Libucl consist of several groups of functions:
### Parser functions
-Used to parse `ucl` files and provide interface to extract `ucl` object
+Used 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.
### Emitting functions
-Convert `ucl` objects to some textual or binary representation.
+Convert `ucl` objects to some textual or binary representation. Currently, libucl supports the following exports:
+
+- `JSON` - valid json format (can possibly loose some original data, such as implicit arrays)
+- `Config` - human-readable configuration format (losseless)
+- `YAML` - embedded yaml format (has the same limitations as `json` output)
### Conversion functions
-Help to convert `ucl` objects to C types
+Help 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.
### Generation functions
-Allow creating of `ucl` objects from C types
+Allow 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.
### Iteration functions
-Iterate over `ucl` objects
+Iterate 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).
+
+### Validation functions
+Validation 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.
### Utility functions
-Provide basic utilities to manage `ucl` objects
+Provide basic utilities to manage `ucl` objects: creating, removing, retaining and releasing reference count and so on.
# Parser functions
@@ -40,6 +85,7 @@ Creates new parser with the specified flags:
- `UCL_PARSER_KEY_LOWERCASE` - lowercase keys parsed
- `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)
+- `UCL_PARSER_NO_TIME` - treat time values as strings without parsing them as floats
### ucl_parser_register_macro
@@ -87,6 +133,14 @@ while this one won't be parsed correctly:
This limitation may possible be removed in future.
+### ucl_parser_add_string
+~~~C
+bool ucl_parser_add_string (struct ucl_parser *parser,
+ const char *data, size_t len);
+~~~
+
+This 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.
+
### ucl_parser_add_file
~~~C
@@ -228,7 +282,7 @@ Libucl provides the following functions for emitting UCL objects:
### ucl_object_emit
~~~C
-unsigned char *ucl_object_emit (ucl_object_t *obj, enum ucl_emitter emit_type);
+unsigned char *ucl_object_emit (const ucl_object_t *obj, enum ucl_emitter emit_type);
~~~
Allocate 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.
@@ -236,7 +290,7 @@ Allocate a string that is suitable to fit the underlying UCL object `obj` and fi
### ucl_object_emit_full
~~~C
-bool ucl_object_emit_full (ucl_object_t *obj, enum ucl_emitter emit_type,
+bool ucl_object_emit_full (const ucl_object_t *obj, enum ucl_emitter emit_type,
struct ucl_emitter_functions *emitter);
~~~
@@ -314,19 +368,20 @@ This function is used to convert a string `str` of size `len` to an UCL objects
- `UCL_STRING_PARSE_BOOLEAN` - parse passed string and detect boolean
- `UCL_STRING_PARSE_INT` - parse passed string and detect integer number
- `UCL_STRING_PARSE_DOUBLE` - parse passed string and detect integer or float number
-- `UCL_STRING_PARSE_NUMBER` - parse passed string and detect number (both float or integer types)
-- `UCL_STRING_PARSE` - parse passed string (and detect booleans and numbers)
+- `UCL_STRING_PARSE_TIME` - parse time values as floating point numbers
+- `UCL_STRING_PARSE_NUMBER` - parse passed string and detect number (both float, integer and time types)
+- `UCL_STRING_PARSE` - parse passed string (and detect booleans, numbers and time values)
- `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
If 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.
-# Iteration function
+# Iteration functions
Iteration 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`.
## ucl_iterate_object
~~~C
-ucl_object_t* ucl_iterate_object (ucl_object_t *obj,
+const ucl_object_t* ucl_iterate_object (const ucl_object_t *obj,
ucl_object_iter_t *iter, bool expand_values);
~~~
@@ -334,7 +389,7 @@ This function accept opaque iterator pointer `iter`. In the first call this iter
~~~C
ucl_object_iter_t it = NULL, it_obj = NULL;
-ucl_object_t *cur, *tmp;
+const ucl_object_t *cur, *tmp;
/* Iterate over the object */
while ((obj = ucl_iterate_object (top, &it, true))) {
@@ -345,4 +400,40 @@ while ((obj = ucl_iterate_object (top, &it, true))) {
ucl_object_tostring_forced (cur));
}
}
-~~~ \ No newline at end of file
+~~~
+
+# Validation functions
+
+Currently, 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:
+
+## ucl_object_validate
+~~~C
+bool ucl_object_validate (const ucl_object_t *schema,
+ const ucl_object_t *obj, struct ucl_schema_error *err);
+~~~
+
+This 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:
+
+~~~C
+struct ucl_schema_error {
+ enum ucl_schema_error_code code; /* error code */
+ char msg[128]; /* error message */
+ ucl_object_t *obj; /* object where error occured */
+};
+~~~
+
+Caller may use `code` field to get a numeric error code:
+
+~~~C
+enum ucl_schema_error_code {
+ UCL_SCHEMA_OK = 0, /* no error */
+ UCL_SCHEMA_TYPE_MISMATCH, /* type of object is incorrect */
+ UCL_SCHEMA_INVALID_SCHEMA, /* schema is invalid */
+ UCL_SCHEMA_MISSING_PROPERTY,/* missing properties */
+ UCL_SCHEMA_CONSTRAINT, /* constraint found */
+ UCL_SCHEMA_MISSING_DEPENDENCY, /* missing dependency */
+ UCL_SCHEMA_UNKNOWN /* generic error */
+};
+~~~
+
+`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). \ No newline at end of file
diff --git a/contrib/libucl/doc/libucl.3 b/contrib/libucl/doc/libucl.3
new file mode 100644
index 0000000..a185d1a
--- /dev/null
+++ b/contrib/libucl/doc/libucl.3
@@ -0,0 +1,637 @@
+.TH LIBUCL 5 "March 20, 2014" "Libucl manual"
+.SH NAME
+.PP
+\f[B]ucl_parser_new\f[], \f[B]ucl_parser_register_macro\f[],
+\f[B]ucl_parser_register_variable\f[], \f[B]ucl_parser_add_chunk\f[],
+\f[B]ucl_parser_add_string\f[], \f[B]ucl_parser_add_file\f[],
+\f[B]ucl_parser_get_object\f[], \f[B]ucl_parser_get_error\f[],
+\f[B]ucl_parser_free\f[], \f[B]ucl_pubkey_add\f[],
+\f[B]ucl_parser_set_filevars\f[] \- universal configuration library
+parser and utility functions
+.SH LIBRARY
+.PP
+UCL library (libucl, \-lucl)
+.SH SYNOPSIS
+.PP
+\f[C]#include\ <ucl.h>\f[]
+.SH DESCRIPTION
+.PP
+Libucl is a parser and \f[C]C\f[] API to parse and generate \f[C]ucl\f[]
+objects.
+Libucl consist of several groups of functions:
+.SS Parser functions
+.PP
+Used to parse \f[C]ucl\f[] files and provide interface to extract
+\f[C]ucl\f[] object.
+Currently, \f[C]libucl\f[] can parse only full \f[C]ucl\f[] documents,
+for instance, it is impossible to parse a part of document and therefore
+it is impossible to use \f[C]libucl\f[] as a streaming parser.
+In future, this limitation can be removed.
+.SS Emitting functions
+.PP
+Convert \f[C]ucl\f[] objects to some textual or binary representation.
+Currently, libucl supports the following exports:
+.IP \[bu] 2
+\f[C]JSON\f[] \- valid json format (can possibly loose some original
+data, such as implicit arrays)
+.IP \[bu] 2
+\f[C]Config\f[] \- human\-readable configuration format (losseless)
+.IP \[bu] 2
+\f[C]YAML\f[] \- embedded yaml format (has the same limitations as
+\f[C]json\f[] output)
+.SS Conversion functions
+.PP
+Help to convert \f[C]ucl\f[] objects to C types.
+These functions are used to convert \f[C]ucl_object_t\f[] to C primitive
+types, such as numbers, strings or boolean values.
+.SS Generation functions
+.PP
+Allow creating of \f[C]ucl\f[] objects from C types and creating of
+complex \f[C]ucl\f[] objects, such as hashes or arrays from primitive
+\f[C]ucl\f[] objects, such as numbers or strings.
+.SS Iteration functions
+.PP
+Iterate over \f[C]ucl\f[] 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).
+.SS Validation functions
+.PP
+Validation functions are used to validate some object \f[C]obj\f[] using
+json\-schema compatible object \f[C]schema\f[].
+Both input and schema must be UCL objects to perform validation.
+.SS Utility functions
+.PP
+Provide basic utilities to manage \f[C]ucl\f[] objects: creating,
+removing, retaining and releasing reference count and so on.
+.SH PARSER FUNCTIONS
+.PP
+Parser functions operates with \f[C]struct\ ucl_parser\f[].
+.SS ucl_parser_new
+.IP
+.nf
+\f[C]
+struct\ ucl_parser*\ ucl_parser_new\ (int\ flags);
+\f[]
+.fi
+.PP
+Creates new parser with the specified flags:
+.IP \[bu] 2
+\f[C]UCL_PARSER_KEY_LOWERCASE\f[] \- lowercase keys parsed
+.IP \[bu] 2
+\f[C]UCL_PARSER_ZEROCOPY\f[] \- 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)
+.IP \[bu] 2
+\f[C]UCL_PARSER_NO_TIME\f[] \- treat time values as strings without
+parsing them as floats
+.SS ucl_parser_register_macro
+.IP
+.nf
+\f[C]
+void\ ucl_parser_register_macro\ (struct\ ucl_parser\ *parser,
+\ \ \ \ const\ char\ *macro,\ ucl_macro_handler\ handler,\ void*\ ud);
+\f[]
+.fi
+.PP
+Register new macro with name .\f[C]macro\f[] parsed by handler
+\f[C]handler\f[] that accepts opaque data pointer \f[C]ud\f[].
+Macro handler should be of the following type:
+.IP
+.nf
+\f[C]
+bool\ (*ucl_macro_handler)\ (const\ unsigned\ char\ *data,
+\ \ \ \ size_t\ len,\ void*\ ud);`
+\f[]
+.fi
+.PP
+Handler function accepts macro text \f[C]data\f[] of length \f[C]len\f[]
+and the opaque pointer \f[C]ud\f[].
+If macro is parsed successfully the handler should return \f[C]true\f[].
+\f[C]false\f[] indicates parsing failure and the parser can be
+terminated.
+.SS ucl_parser_register_variable
+.IP
+.nf
+\f[C]
+void\ ucl_parser_register_variable\ (struct\ ucl_parser\ *parser,
+\ \ \ \ const\ char\ *var,\ const\ char\ *value);
+\f[]
+.fi
+.PP
+Register new variable $\f[C]var\f[] that should be replaced by the
+parser to the \f[C]value\f[] string.
+.SS ucl_parser_add_chunk
+.IP
+.nf
+\f[C]
+bool\ ucl_parser_add_chunk\ (struct\ ucl_parser\ *parser,\
+\ \ \ \ const\ unsigned\ char\ *data,\ size_t\ len);
+\f[]
+.fi
+.PP
+Add new text chunk with \f[C]data\f[] of length \f[C]len\f[] to the
+parser.
+At the moment, \f[C]libucl\f[] parser is not a streamlined parser and
+chunk \f[I]must\f[] contain the \f[I]valid\f[] ucl object.
+For example, this object should be valid:
+.IP
+.nf
+\f[C]
+{\ "var":\ "value"\ }
+\f[]
+.fi
+.PP
+while this one won\[aq]t be parsed correctly:
+.IP
+.nf
+\f[C]
+{\ "var":\
+\f[]
+.fi
+.PP
+This limitation may possible be removed in future.
+.SS ucl_parser_add_string
+.IP
+.nf
+\f[C]
+bool\ ucl_parser_add_string\ (struct\ ucl_parser\ *parser,\
+\ \ \ \ const\ char\ *data,\ size_t\ len);
+\f[]
+.fi
+.PP
+This function acts exactly like \f[C]ucl_parser_add_chunk\f[] does but
+if \f[C]len\f[] argument is zero, then the string \f[C]data\f[] must be
+zero\-terminated and the actual length is calculated up to \f[C]\\0\f[]
+character.
+.SS ucl_parser_add_file
+.IP
+.nf
+\f[C]
+bool\ ucl_parser_add_file\ (struct\ ucl_parser\ *parser,\
+\ \ \ \ const\ char\ *filename);
+\f[]
+.fi
+.PP
+Load file \f[C]filename\f[] and parse it with the specified
+\f[C]parser\f[].
+This function uses \f[C]mmap\f[] call to load file, therefore, it should
+not be \f[C]shrinked\f[] during parsing.
+Otherwise, \f[C]libucl\f[] can cause memory corruption and terminate the
+calling application.
+This function is also used by the internal handler of \f[C]include\f[]
+macro, hence, this macro has the same limitation.
+.SS ucl_parser_get_object
+.IP
+.nf
+\f[C]
+ucl_object_t*\ ucl_parser_get_object\ (struct\ ucl_parser\ *parser);
+\f[]
+.fi
+.PP
+If the \f[C]ucl\f[] data has been parsed correctly this function returns
+the top object for the parser.
+Otherwise, this function returns the \f[C]NULL\f[] pointer.
+The reference count for \f[C]ucl\f[] object returned is increased by
+one, therefore, a caller should decrease reference by using
+\f[C]ucl_object_unref\f[] to free object after usage.
+.SS ucl_parser_get_error
+.IP
+.nf
+\f[C]
+const\ char\ *ucl_parser_get_error(struct\ ucl_parser\ *parser);
+\f[]
+.fi
+.PP
+Returns the constant error string for the parser object.
+If no error occurred during parsing a \f[C]NULL\f[] object is returned.
+A caller should not try to free or modify this string.
+.SS ucl_parser_free
+.IP
+.nf
+\f[C]
+void\ ucl_parser_free\ (struct\ ucl_parser\ *parser);
+\f[]
+.fi
+.PP
+Frees memory occupied by the parser object.
+The reference count for top object is decreased as well, however if the
+function \f[C]ucl_parser_get_object\f[] was called previously then the
+top object won\[aq]t be freed.
+.SS ucl_pubkey_add
+.IP
+.nf
+\f[C]
+bool\ ucl_pubkey_add\ (struct\ ucl_parser\ *parser,\
+\ \ \ \ const\ unsigned\ char\ *key,\ size_t\ len);
+\f[]
+.fi
+.PP
+This function adds a public key from text blob \f[C]key\f[] of length
+\f[C]len\f[] to the \f[C]parser\f[] object.
+This public key should be in the \f[C]PEM\f[] format and can be used by
+\f[C]\&.includes\f[] macro for checking signatures of files included.
+\f[C]Openssl\f[] support should be enabled to make this function
+working.
+If a key cannot be added (e.g.
+due to format error) or \f[C]openssl\f[] was not linked to
+\f[C]libucl\f[] then this function returns \f[C]false\f[].
+.SS ucl_parser_set_filevars
+.IP
+.nf
+\f[C]
+bool\ ucl_parser_set_filevars\ (struct\ ucl_parser\ *parser,\
+\ \ \ \ const\ char\ *filename,\ bool\ need_expand);
+\f[]
+.fi
+.PP
+Add the standard file variables to the \f[C]parser\f[] based on the
+\f[C]filename\f[] specified:
+.IP \[bu] 2
+\f[C]$FILENAME\f[] \- a filename of \f[C]ucl\f[] input
+.IP \[bu] 2
+\f[C]$CURDIR\f[] \- a current directory of the input
+.PP
+For example, if a \f[C]filename\f[] param is
+\f[C]\&../something.conf\f[] then the variables will have the following
+values:
+.IP \[bu] 2
+\f[C]$FILENAME\f[] \- "../something.conf"
+.IP \[bu] 2
+\f[C]$CURDIR\f[] \- ".."
+.PP
+if \f[C]need_expand\f[] parameter is \f[C]true\f[] then all relative
+paths are expanded using \f[C]realpath\f[] call.
+In this example if \f[C]\&..\f[] is \f[C]/etc/dir\f[] then variables
+will have these values:
+.IP \[bu] 2
+\f[C]$FILENAME\f[] \- "/etc/something.conf"
+.IP \[bu] 2
+\f[C]$CURDIR\f[] \- "/etc"
+.SS Parser usage example
+.PP
+The following example loads, parses and extracts \f[C]ucl\f[] object
+from stdin using \f[C]libucl\f[] parser functions (the length of input
+is limited to 8K):
+.IP
+.nf
+\f[C]
+char\ inbuf[8192];
+struct\ ucl_parser\ *parser\ =\ NULL;
+int\ ret\ =\ 0,\ r\ =\ 0;
+ucl_object_t\ *obj\ =\ NULL;
+FILE\ *in;
+
+in\ =\ stdin;
+parser\ =\ ucl_parser_new\ (0);
+while\ (!feof\ (in)\ &&\ r\ <\ (int)sizeof\ (inbuf))\ {
+\ \ \ \ r\ +=\ fread\ (inbuf\ +\ r,\ 1,\ sizeof\ (inbuf)\ \-\ r,\ in);
+}
+ucl_parser_add_chunk\ (parser,\ inbuf,\ r);
+fclose\ (in);
+
+if\ (ucl_parser_get_error\ (parser))\ {
+\ \ \ \ printf\ ("Error\ occured:\ %s\\n",\ ucl_parser_get_error\ (parser));
+\ \ \ \ ret\ =\ 1;
+}
+else\ {
+\ \ \ \ obj\ =\ ucl_parser_get_object\ (parser);
+}
+
+if\ (parser\ !=\ NULL)\ {
+\ \ \ \ ucl_parser_free\ (parser);
+}
+if\ (obj\ !=\ NULL)\ {
+\ \ \ \ ucl_object_unref\ (obj);
+}
+return\ ret;
+\f[]
+.fi
+.SH EMITTING FUNCTIONS
+.PP
+Libucl can transform UCL objects to a number of tectual formats:
+.IP \[bu] 2
+configuration (\f[C]UCL_EMIT_CONFIG\f[]) \- nginx like human readable
+configuration file where implicit arrays are transformed to the
+duplicate keys
+.IP \[bu] 2
+compact json: \f[C]UCL_EMIT_JSON_COMPACT\f[] \- single line valid json
+without spaces
+.IP \[bu] 2
+formatted json: \f[C]UCL_EMIT_JSON\f[] \- pretty formatted JSON with
+newlines and spaces
+.IP \[bu] 2
+compact yaml: \f[C]UCL_EMIT_YAML\f[] \- compact YAML output
+.PP
+Moreover, libucl API allows to select a custom set of emitting functions
+allowing efficent and zero\-copy output of libucl objects.
+Libucl uses the following structure to support this feature:
+.IP
+.nf
+\f[C]
+struct\ ucl_emitter_functions\ {
+\ \ \ \ /**\ Append\ a\ single\ character\ */
+\ \ \ \ int\ (*ucl_emitter_append_character)\ (unsigned\ char\ c,\ size_t\ nchars,\ void\ *ud);
+\ \ \ \ /**\ Append\ a\ string\ of\ a\ specified\ length\ */
+\ \ \ \ int\ (*ucl_emitter_append_len)\ (unsigned\ const\ char\ *str,\ size_t\ len,\ void\ *ud);
+\ \ \ \ /**\ Append\ a\ 64\ bit\ integer\ */
+\ \ \ \ int\ (*ucl_emitter_append_int)\ (int64_t\ elt,\ void\ *ud);
+\ \ \ \ /**\ Append\ floating\ point\ element\ */
+\ \ \ \ int\ (*ucl_emitter_append_double)\ (double\ elt,\ void\ *ud);
+\ \ \ \ /**\ Opaque\ userdata\ pointer\ */
+\ \ \ \ void\ *ud;
+};
+\f[]
+.fi
+.PP
+This structure defines the following callbacks:
+.IP \[bu] 2
+\f[C]ucl_emitter_append_character\f[] \- a function that is called to
+append \f[C]nchars\f[] characters equal to \f[C]c\f[]
+.IP \[bu] 2
+\f[C]ucl_emitter_append_len\f[] \- used to append a string of length
+\f[C]len\f[] starting from pointer \f[C]str\f[]
+.IP \[bu] 2
+\f[C]ucl_emitter_append_int\f[] \- this function applies to integer
+numbers
+.IP \[bu] 2
+\f[C]ucl_emitter_append_double\f[] \- this function is intended to
+output floating point variable
+.PP
+The set of these functions could be used to output text formats of
+\f[C]UCL\f[] objects to different structures or streams.
+.PP
+Libucl provides the following functions for emitting UCL objects:
+.SS ucl_object_emit
+.IP
+.nf
+\f[C]
+unsigned\ char\ *ucl_object_emit\ (const\ ucl_object_t\ *obj,\ enum\ ucl_emitter\ emit_type);
+\f[]
+.fi
+.PP
+Allocate a string that is suitable to fit the underlying UCL object
+\f[C]obj\f[] and fill it with the textual representation of the object
+\f[C]obj\f[] according to style \f[C]emit_type\f[].
+The caller should free the returned string after using.
+.SS ucl_object_emit_full
+.IP
+.nf
+\f[C]
+bool\ ucl_object_emit_full\ (const\ ucl_object_t\ *obj,\ enum\ ucl_emitter\ emit_type,
+\ \ \ \ \ \ \ \ struct\ ucl_emitter_functions\ *emitter);
+\f[]
+.fi
+.PP
+This function is similar to the previous with the exception that it
+accepts the additional argument \f[C]emitter\f[] 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).
+.SH CONVERSION FUNCTIONS
+.PP
+Conversion functions are used to convert UCL objects to primitive types,
+such as strings, numbers or boolean values.
+There are two types of conversion functions:
+.IP \[bu] 2
+safe: try to convert an ucl object to a primitive type and fail if such
+a conversion is not possible
+.IP \[bu] 2
+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)
+.PP
+Also there is a single \f[C]ucl_object_tostring_forced\f[] 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.
+.PP
+Here is a list of all conversion functions:
+.IP \[bu] 2
+\f[C]ucl_object_toint\f[] \- returns \f[C]int64_t\f[] of UCL object
+.IP \[bu] 2
+\f[C]ucl_object_todouble\f[] \- returns \f[C]double\f[] of UCL object
+.IP \[bu] 2
+\f[C]ucl_object_toboolean\f[] \- returns \f[C]bool\f[] of UCL object
+.IP \[bu] 2
+\f[C]ucl_object_tostring\f[] \- returns \f[C]const\ char\ *\f[] of UCL
+object (this string is NULL terminated)
+.IP \[bu] 2
+\f[C]ucl_object_tolstring\f[] \- returns \f[C]const\ char\ *\f[] and
+\f[C]size_t\f[] len of UCL object (string can be not NULL terminated)
+.IP \[bu] 2
+\f[C]ucl_object_tostring_forced\f[] \- returns string representation of
+any UCL object
+.PP
+Strings returned by these pointers are associated with the UCL object
+and exist over its lifetime.
+A caller should not free this memory.
+.SH GENERATION FUNCTIONS
+.PP
+It 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.
+.SS ucl_object_new
+.IP
+.nf
+\f[C]
+ucl_object_t\ *\ ucl_object_new\ (void)
+\f[]
+.fi
+.PP
+Creates new object of type \f[C]UCL_NULL\f[].
+This object should be released by caller.
+.SS ucl_object_typed_new
+.IP
+.nf
+\f[C]
+ucl_object_t\ *\ ucl_object_typed_new\ (unsigned\ int\ type)
+\f[]
+.fi
+.PP
+Create an object of a specified type: \- \f[C]UCL_OBJECT\f[] \- UCL
+object \- key/value pairs \- \f[C]UCL_ARRAY\f[] \- UCL array \-
+\f[C]UCL_INT\f[] \- integer number \- \f[C]UCL_FLOAT\f[] \- floating
+point number \- \f[C]UCL_STRING\f[] \- NULL terminated string \-
+\f[C]UCL_BOOLEAN\f[] \- boolean value \- \f[C]UCL_TIME\f[] \- time value
+(floating point number of seconds) \- \f[C]UCL_USERDATA\f[] \- opaque
+userdata pointer (may be used in macros) \- \f[C]UCL_NULL\f[] \- null
+value
+.PP
+This object should be released by caller.
+.SS Primitive objects generation
+.PP
+Libucl provides the functions similar to inverse conversion functions
+called with the specific C type: \- \f[C]ucl_object_fromint\f[] \-
+converts \f[C]int64_t\f[] to UCL object \-
+\f[C]ucl_object_fromdouble\f[] \- converts \f[C]double\f[] to UCL object
+\- \f[C]ucl_object_fromboolean\f[] \- converts \f[C]bool\f[] to UCL
+object \- \f[C]ucl_object_fromstring\f[] \- converts
+\f[C]const\ char\ *\f[] to UCL object (this string is NULL terminated)
+\- \f[C]ucl_object_fromlstring\f[] \- converts \f[C]const\ char\ *\f[]
+and \f[C]size_t\f[] len to UCL object (string can be not NULL
+terminated)
+.PP
+Also there is a function to generate UCL object from a string performing
+various parsing or conversion operations called
+\f[C]ucl_object_fromstring_common\f[].
+.SS ucl_object_fromstring_common
+.IP
+.nf
+\f[C]
+ucl_object_t\ *\ ucl_object_fromstring_common\ (const\ char\ *str,\
+\ \ \ \ size_t\ len,\ enum\ ucl_string_flags\ flags)
+\f[]
+.fi
+.PP
+This function is used to convert a string \f[C]str\f[] of size
+\f[C]len\f[] to an UCL objects applying \f[C]flags\f[] conversions.
+If \f[C]len\f[] is equal to zero then a \f[C]str\f[] is assumed as
+NULL\-terminated.
+This function supports the following flags (a set of flags can be
+specified using logical \f[C]OR\f[] operation):
+.IP \[bu] 2
+\f[C]UCL_STRING_ESCAPE\f[] \- perform JSON escape
+.IP \[bu] 2
+\f[C]UCL_STRING_TRIM\f[] \- trim leading and trailing whitespaces
+.IP \[bu] 2
+\f[C]UCL_STRING_PARSE_BOOLEAN\f[] \- parse passed string and detect
+boolean
+.IP \[bu] 2
+\f[C]UCL_STRING_PARSE_INT\f[] \- parse passed string and detect integer
+number
+.IP \[bu] 2
+\f[C]UCL_STRING_PARSE_DOUBLE\f[] \- parse passed string and detect
+integer or float number
+.IP \[bu] 2
+\f[C]UCL_STRING_PARSE_TIME\f[] \- parse time values as floating point
+numbers
+.IP \[bu] 2
+\f[C]UCL_STRING_PARSE_NUMBER\f[] \- parse passed string and detect
+number (both float, integer and time types)
+.IP \[bu] 2
+\f[C]UCL_STRING_PARSE\f[] \- parse passed string (and detect booleans,
+numbers and time values)
+.IP \[bu] 2
+\f[C]UCL_STRING_PARSE_BYTES\f[] \- assume that numeric multipliers are
+in bytes notation, for example \f[C]10k\f[] means \f[C]10*1024\f[] and
+not \f[C]10*1000\f[] as assumed without this flag
+.PP
+If parsing operations fail then the resulting UCL object will be a
+\f[C]UCL_STRING\f[].
+A caller should always check the type of the returned object and release
+it after using.
+.SH ITERATION FUNCTIONS
+.PP
+Iteration 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 \f[C]ucl_iterate_object\f[].
+.SS ucl_iterate_object
+.IP
+.nf
+\f[C]
+const\ ucl_object_t*\ ucl_iterate_object\ (const\ ucl_object_t\ *obj,\
+\ \ \ \ ucl_object_iter_t\ *iter,\ bool\ expand_values);
+\f[]
+.fi
+.PP
+This function accept opaque iterator pointer \f[C]iter\f[].
+In the first call this iterator \f[I]must\f[] be initialized to
+\f[C]NULL\f[].
+Iterator is changed by this function call.
+\f[C]ucl_iterate_object\f[] returns the next UCL object in the compound
+object \f[C]obj\f[] or \f[C]NULL\f[] 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 \f[C]obj\f[] should not be changed during the iteration
+process as well.
+\f[C]expand_values\f[] flag speicifies whether
+\f[C]ucl_iterate_object\f[] should expand keys with multiple values.
+The general rule is that if you need to iterate throught the
+\f[I]object\f[] or \f[I]explicit array\f[], then you always need to set
+this flag to \f[C]true\f[].
+However, if you get some key in the object and want to extract all its
+values then you should set \f[C]expand_values\f[] to \f[C]false\f[].
+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 \f[C]top\f[] is \f[C]UCL_OBJECT\f[] in this example):
+.IP
+.nf
+\f[C]
+ucl_object_iter_t\ it\ =\ NULL,\ it_obj\ =\ NULL;
+const\ ucl_object_t\ *cur,\ *tmp;
+
+/*\ Iterate\ over\ the\ object\ */
+while\ ((obj\ =\ ucl_iterate_object\ (top,\ &it,\ true)))\ {
+\ \ \ \ printf\ ("key:\ \\"%s\\"\\n",\ ucl_object_key\ (obj));
+\ \ \ \ /*\ Iterate\ over\ the\ values\ of\ a\ key\ */
+\ \ \ \ while\ ((cur\ =\ ucl_iterate_object\ (obj,\ &it_obj,\ false)))\ {
+\ \ \ \ \ \ \ \ printf\ ("value:\ \\"%s\\"\\n",\
+\ \ \ \ \ \ \ \ \ \ \ \ ucl_object_tostring_forced\ (cur));
+\ \ \ \ }
+}
+\f[]
+.fi
+.SH VALIDATION FUNCTIONS
+.PP
+Currently, there is only one validation function called
+\f[C]ucl_object_validate\f[].
+It performs validation of object using the specified schema.
+This function is defined as following:
+.SS ucl_object_validate
+.IP
+.nf
+\f[C]
+bool\ ucl_object_validate\ (const\ ucl_object_t\ *schema,
+\ \ \ \ const\ ucl_object_t\ *obj,\ struct\ ucl_schema_error\ *err);
+\f[]
+.fi
+.PP
+This function uses ucl object \f[C]schema\f[], that must be valid in
+terms of \f[C]json\-schema\f[] draft v4, to validate input object
+\f[C]obj\f[].
+If this function returns \f[C]true\f[] then validation procedure has
+been succeed.
+Otherwise, \f[C]false\f[] is returned and \f[C]err\f[] is set to a
+specific value.
+If caller set \f[C]err\f[] to NULL then this function does not set any
+error just returning \f[C]false\f[].
+Error is the structure defined as following:
+.IP
+.nf
+\f[C]
+struct\ ucl_schema_error\ {
+\ \ \ \ enum\ ucl_schema_error_code\ code;\ \ \ \ /*\ error\ code\ */
+\ \ \ \ char\ msg[128];\ \ \ \ \ \ \ \ \ \ \ \ \ \ /*\ error\ message\ */
+\ \ \ \ ucl_object_t\ *obj;\ \ \ \ \ \ \ \ \ \ /*\ object\ where\ error\ occured\ */
+};
+\f[]
+.fi
+.PP
+Caller may use \f[C]code\f[] field to get a numeric error code:
+.IP
+.nf
+\f[C]
+enum\ ucl_schema_error_code\ {
+\ \ \ \ UCL_SCHEMA_OK\ =\ 0,\ \ \ \ \ \ \ \ \ \ /*\ no\ error\ */
+\ \ \ \ UCL_SCHEMA_TYPE_MISMATCH,\ \ \ /*\ type\ of\ object\ is\ incorrect\ */
+\ \ \ \ UCL_SCHEMA_INVALID_SCHEMA,\ \ /*\ schema\ is\ invalid\ */
+\ \ \ \ UCL_SCHEMA_MISSING_PROPERTY,/*\ missing\ properties\ */
+\ \ \ \ UCL_SCHEMA_CONSTRAINT,\ \ \ \ \ \ /*\ constraint\ found\ */
+\ \ \ \ UCL_SCHEMA_MISSING_DEPENDENCY,\ /*\ missing\ dependency\ */
+\ \ \ \ UCL_SCHEMA_UNKNOWN\ \ \ \ \ \ \ \ \ \ /*\ generic\ error\ */
+};
+\f[]
+.fi
+.PP
+\f[C]msg\f[] is a stiring description of an error and \f[C]obj\f[] 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).
+.SH AUTHORS
+Vsevolod Stakhov <vsevolod@highsecure.ru>.
diff --git a/contrib/libucl/doc/pandoc.template b/contrib/libucl/doc/pandoc.template
new file mode 100644
index 0000000..e29e20c
--- /dev/null
+++ b/contrib/libucl/doc/pandoc.template
@@ -0,0 +1,12 @@
+% LIBUCL(5) Libucl manual
+% Vsevolod Stakhov <vsevolod@highsecure.ru>
+% March 20, 2014
+
+# Name
+
+**ucl_parser_new**, **ucl_parser_register_macro**, **ucl_parser_register_variable**, **ucl_parser_add_chunk**, **ucl_parser_add_string**, **ucl_parser_add_file**, **ucl_parser_get_object**, **ucl_parser_get_error**, **ucl_parser_free**, **ucl_pubkey_add**, **ucl_parser_set_filevars** - universal configuration library parser and utility functions
+
+# Library
+
+UCL library (libucl, -lucl)
+
OpenPOWER on IntegriCloud