aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorBaptiste Daroussin <bapt@FreeBSD.org>2014-03-22 17:22:29 +0000
committerBaptiste Daroussin <bapt@FreeBSD.org>2014-03-22 17:22:29 +0000
commitbfc6d68337150c52c8ce2dc6a7d19a9d1bd92795 (patch)
tree7f1e53bb95f9bc2624280f027e3f0aeb280f9667 /include
parent2ae6de7c252d1781a158740c2481220dfdd6cc77 (diff)
downloadsrc-bfc6d68337150c52c8ce2dc6a7d19a9d1bd92795.tar.gz
src-bfc6d68337150c52c8ce2dc6a7d19a9d1bd92795.zip
Update 20140302vendor/libucl/20140321
In particular this brings schema validation support.
Notes
Notes: svn path=/vendor/libucl/dist/; revision=263646 svn path=/vendor/libucl/20140321/; revision=263647; tag=vendor/libucl/20140321
Diffstat (limited to 'include')
-rw-r--r--include/ucl.h518
1 files changed, 135 insertions, 383 deletions
diff --git a/include/ucl.h b/include/ucl.h
index a464a006ef78..6cd7faf4c991 100644
--- a/include/ucl.h
+++ b/include/ucl.h
@@ -138,7 +138,8 @@ typedef enum ucl_emitter {
*/
typedef enum ucl_parser_flags {
UCL_PARSER_KEY_LOWERCASE = 0x1, /**< Convert all keys to lower case */
- UCL_PARSER_ZEROCOPY = 0x2 /**< Parse input in zero-copy mode if possible */
+ UCL_PARSER_ZEROCOPY = 0x2, /**< Parse input in zero-copy mode if possible */
+ UCL_PARSER_NO_TIME = 0x4 /**< Do not parse time and treat time values as strings */
} ucl_parser_flags_t;
/**
@@ -150,11 +151,12 @@ typedef enum ucl_string_flags {
UCL_STRING_PARSE_BOOLEAN = 0x4, /**< Parse passed string and detect boolean */
UCL_STRING_PARSE_INT = 0x8, /**< Parse passed string and detect integer number */
UCL_STRING_PARSE_DOUBLE = 0x10, /**< Parse passed string and detect integer or float number */
- UCL_STRING_PARSE_NUMBER = UCL_STRING_PARSE_INT|UCL_STRING_PARSE_DOUBLE , /**<
+ UCL_STRING_PARSE_TIME = 0x20, /**< Parse time strings */
+ UCL_STRING_PARSE_NUMBER = UCL_STRING_PARSE_INT|UCL_STRING_PARSE_DOUBLE|UCL_STRING_PARSE_TIME, /**<
Parse passed string and detect number */
UCL_STRING_PARSE = UCL_STRING_PARSE_BOOLEAN|UCL_STRING_PARSE_NUMBER, /**<
Parse passed string (and detect booleans and numbers) */
- UCL_STRING_PARSE_BYTES = 0x20 /**< Treat numbers as bytes */
+ UCL_STRING_PARSE_BYTES = 0x40 /**< Treat numbers as bytes */
} ucl_string_flags_t;
/**
@@ -219,38 +221,14 @@ UCL_EXTERN char* ucl_copy_value_trash (ucl_object_t *obj);
* Creates a new object
* @return new object
*/
-static inline ucl_object_t* ucl_object_new (void) UCL_WARN_UNUSED_RESULT;
-static inline ucl_object_t *
-ucl_object_new (void)
-{
- ucl_object_t *new;
- new = malloc (sizeof (ucl_object_t));
- if (new != NULL) {
- memset (new, 0, sizeof (ucl_object_t));
- new->ref = 1;
- new->type = UCL_NULL;
- }
- return new;
-}
+UCL_EXTERN ucl_object_t* ucl_object_new (void) UCL_WARN_UNUSED_RESULT;
/**
* Create new object with type specified
* @param type type of a new object
* @return new object
*/
-static inline ucl_object_t* ucl_object_typed_new (unsigned int type) UCL_WARN_UNUSED_RESULT;
-static inline ucl_object_t *
-ucl_object_typed_new (unsigned int type)
-{
- ucl_object_t *new;
- new = malloc (sizeof (ucl_object_t));
- if (new != NULL) {
- memset (new, 0, sizeof (ucl_object_t));
- new->ref = 1;
- new->type = (type <= UCL_NULL ? type : UCL_NULL);
- }
- return new;
-}
+UCL_EXTERN ucl_object_t* ucl_object_typed_new (unsigned int type) UCL_WARN_UNUSED_RESULT;
/**
* Convert any string to an ucl object making the specified transformations
@@ -267,11 +245,7 @@ UCL_EXTERN ucl_object_t * ucl_object_fromstring_common (const char *str, size_t
* @param str NULL terminated string, will be json escaped
* @return new object
*/
-static inline ucl_object_t *
-ucl_object_fromstring (const char *str)
-{
- return ucl_object_fromstring_common (str, 0, UCL_STRING_ESCAPE);
-}
+UCL_EXTERN ucl_object_t *ucl_object_fromstring (const char *str);
/**
* Create a UCL object from the specified string
@@ -279,68 +253,28 @@ ucl_object_fromstring (const char *str)
* @param len length of a string
* @return new object
*/
-static inline ucl_object_t *
-ucl_object_fromlstring (const char *str, size_t len)
-{
- return ucl_object_fromstring_common (str, len, UCL_STRING_ESCAPE);
-}
+UCL_EXTERN ucl_object_t *ucl_object_fromlstring (const char *str, size_t len);
/**
* Create an object from an integer number
* @param iv number
* @return new object
*/
-static inline ucl_object_t *
-ucl_object_fromint (int64_t iv)
-{
- ucl_object_t *obj;
-
- obj = ucl_object_new ();
- if (obj != NULL) {
- obj->type = UCL_INT;
- obj->value.iv = iv;
- }
-
- return obj;
-}
+UCL_EXTERN ucl_object_t* ucl_object_fromint (int64_t iv);
/**
* Create an object from a float number
* @param dv number
* @return new object
*/
-static inline ucl_object_t *
-ucl_object_fromdouble (double dv)
-{
- ucl_object_t *obj;
-
- obj = ucl_object_new ();
- if (obj != NULL) {
- obj->type = UCL_FLOAT;
- obj->value.dv = dv;
- }
-
- return obj;
-}
+UCL_EXTERN ucl_object_t* ucl_object_fromdouble (double dv);
/**
* Create an object from a boolean
* @param bv bool value
* @return new object
*/
-static inline ucl_object_t *
-ucl_object_frombool (bool bv)
-{
- ucl_object_t *obj;
-
- obj = ucl_object_new ();
- if (obj != NULL) {
- obj->type = UCL_BOOLEAN;
- obj->value.iv = bv;
- }
-
- return obj;
-}
+UCL_EXTERN ucl_object_t* ucl_object_frombool (bool bv);
/**
* Insert a object 'elt' to the hash 'top' and associate it with key 'key'
@@ -382,6 +316,28 @@ UCL_EXTERN bool ucl_object_delete_keyl (ucl_object_t *top, const char *key, size
*/
UCL_EXTERN bool ucl_object_delete_key (ucl_object_t *top, const char *key);
+
+/**
+ * Delete key from `top` object returning the object deleted. This object is not
+ * released
+ * @param top object
+ * @param key key to remove
+ * @param keylen length of the key (or 0 for NULL terminated keys)
+ * @return removed object or NULL if object has not been found
+ */
+UCL_EXTERN ucl_object_t* ucl_object_pop_keyl (ucl_object_t *top, const char *key,
+ size_t keylen) UCL_WARN_UNUSED_RESULT;
+
+/**
+ * Delete key from `top` object returning the object deleted. This object is not
+ * released
+ * @param top object
+ * @param key key to remove
+ * @return removed object or NULL if object has not been found
+ */
+UCL_EXTERN ucl_object_t* ucl_object_pop_key (ucl_object_t *top, const char *key)
+ UCL_WARN_UNUSED_RESULT;
+
/**
* Insert a object 'elt' to the hash 'top' and associate it with key 'key', if the specified key exist,
* try to merge its content
@@ -401,41 +357,8 @@ UCL_EXTERN ucl_object_t* ucl_object_insert_key_merged (ucl_object_t *top, ucl_ob
* @param elt element to append (must NOT be NULL)
* @return new value of top object
*/
-static inline ucl_object_t * ucl_array_append (ucl_object_t *top,
+UCL_EXTERN ucl_object_t* ucl_array_append (ucl_object_t *top,
ucl_object_t *elt) UCL_WARN_UNUSED_RESULT;
-static inline ucl_object_t *
-ucl_array_append (ucl_object_t *top, ucl_object_t *elt)
-{
- ucl_object_t *head;
-
- if (elt == NULL) {
- return NULL;
- }
-
- if (top == NULL) {
- top = ucl_object_typed_new (UCL_ARRAY);
- top->value.av = elt;
- elt->next = NULL;
- elt->prev = elt;
- top->len = 1;
- }
- else {
- head = top->value.av;
- if (head == NULL) {
- top->value.av = elt;
- elt->prev = elt;
- }
- else {
- elt->prev = head->prev;
- head->prev->next = elt;
- head->prev = elt;
- }
- elt->next = NULL;
- top->len ++;
- }
-
- return top;
-}
/**
* Append an element to the start of array object
@@ -443,41 +366,8 @@ ucl_array_append (ucl_object_t *top, ucl_object_t *elt)
* @param elt element to append (must NOT be NULL)
* @return new value of top object
*/
-static inline ucl_object_t * ucl_array_prepend (ucl_object_t *top,
+UCL_EXTERN ucl_object_t* ucl_array_prepend (ucl_object_t *top,
ucl_object_t *elt) UCL_WARN_UNUSED_RESULT;
-static inline ucl_object_t *
-ucl_array_prepend (ucl_object_t *top, ucl_object_t *elt)
-{
- ucl_object_t *head;
-
- if (elt == NULL) {
- return NULL;
- }
-
- if (top == NULL) {
- top = ucl_object_typed_new (UCL_ARRAY);
- top->value.av = elt;
- elt->next = NULL;
- elt->prev = elt;
- top->len = 1;
- }
- else {
- head = top->value.av;
- if (head == NULL) {
- top->value.av = elt;
- elt->prev = elt;
- }
- else {
- elt->prev = head->prev;
- head->prev = elt;
- }
- elt->next = head;
- top->value.av = elt;
- top->len ++;
- }
-
- return top;
-}
/**
* Removes an element `elt` from the array `top`. Caller must unref the returned object when it is not
@@ -486,66 +376,21 @@ ucl_array_prepend (ucl_object_t *top, ucl_object_t *elt)
* @param elt element to remove
* @return removed element or NULL if `top` is NULL or not an array
*/
-static inline ucl_object_t *
-ucl_array_delete (ucl_object_t *top, ucl_object_t *elt)
-{
- ucl_object_t *head;
-
- if (top == NULL || top->type != UCL_ARRAY || top->value.av == NULL) {
- return NULL;
- }
- head = top->value.av;
-
- if (elt->prev == elt) {
- top->value.av = NULL;
- }
- else if (elt == head) {
- elt->next->prev = elt->prev;
- top->value.av = elt->next;
- }
- else {
- elt->prev->next = elt->next;
- if (elt->next) {
- elt->next->prev = elt->prev;
- }
- else {
- head->prev = elt->prev;
- }
- }
- elt->next = NULL;
- elt->prev = elt;
- top->len --;
-
- return elt;
-}
+UCL_EXTERN ucl_object_t* ucl_array_delete (ucl_object_t *top, ucl_object_t *elt);
/**
* Returns the first element of the array `top`
* @param top array ucl object
* @return element or NULL if `top` is NULL or not an array
*/
-static inline ucl_object_t *
-ucl_array_head (ucl_object_t *top)
-{
- if (top == NULL || top->type != UCL_ARRAY || top->value.av == NULL) {
- return NULL;
- }
- return top->value.av;
-}
+UCL_EXTERN ucl_object_t* ucl_array_head (ucl_object_t *top);
/**
* Returns the last element of the array `top`
* @param top array ucl object
* @return element or NULL if `top` is NULL or not an array
*/
-static inline ucl_object_t *
-ucl_array_tail (ucl_object_t *top)
-{
- if (top == NULL || top->type != UCL_ARRAY || top->value.av == NULL) {
- return NULL;
- }
- return top->value.av->prev;
-}
+UCL_EXTERN ucl_object_t* ucl_array_tail (ucl_object_t *top);
/**
* Removes the last element from the array `top`. Caller must unref the returned object when it is not
@@ -553,11 +398,7 @@ ucl_array_tail (ucl_object_t *top)
* @param top array ucl object
* @return removed element or NULL if `top` is NULL or not an array
*/
-static inline ucl_object_t *
-ucl_array_pop_last (ucl_object_t *top)
-{
- return ucl_array_delete (top, ucl_array_tail (top));
-}
+UCL_EXTERN ucl_object_t* ucl_array_pop_last (ucl_object_t *top);
/**
* Removes the first element from the array `top`. Caller must unref the returned object when it is not
@@ -565,11 +406,7 @@ ucl_array_pop_last (ucl_object_t *top)
* @param top array ucl object
* @return removed element or NULL if `top` is NULL or not an array
*/
-static inline ucl_object_t *
-ucl_array_pop_first (ucl_object_t *top)
-{
- return ucl_array_delete (top, ucl_array_head (top));
-}
+UCL_EXTERN ucl_object_t* ucl_array_pop_first (ucl_object_t *top);
/**
* Append a element to another element forming an implicit array
@@ -577,26 +414,8 @@ ucl_array_pop_first (ucl_object_t *top)
* @param elt new element
* @return new head if applicable
*/
-static inline ucl_object_t * ucl_elt_append (ucl_object_t *head,
+UCL_EXTERN ucl_object_t* ucl_elt_append (ucl_object_t *head,
ucl_object_t *elt) UCL_WARN_UNUSED_RESULT;
-static inline ucl_object_t *
-ucl_elt_append (ucl_object_t *head, ucl_object_t *elt)
-{
-
- if (head == NULL) {
- elt->next = NULL;
- elt->prev = elt;
- head = elt;
- }
- else {
- elt->prev = head->prev;
- head->prev->next = elt;
- head->prev = elt;
- elt->next = NULL;
- }
-
- return head;
-}
/**
* Converts an object to double value
@@ -604,40 +423,14 @@ ucl_elt_append (ucl_object_t *head, ucl_object_t *elt)
* @param target target double variable
* @return true if conversion was successful
*/
-static inline bool
-ucl_object_todouble_safe (ucl_object_t *obj, double *target)
-{
- if (obj == NULL) {
- return false;
- }
- switch (obj->type) {
- case UCL_INT:
- *target = obj->value.iv; /* Probaly could cause overflow */
- break;
- case UCL_FLOAT:
- case UCL_TIME:
- *target = obj->value.dv;
- break;
- default:
- return false;
- }
-
- return true;
-}
+UCL_EXTERN bool ucl_object_todouble_safe (ucl_object_t *obj, double *target);
/**
* Unsafe version of \ref ucl_obj_todouble_safe
* @param obj CL object
* @return double value
*/
-static inline double
-ucl_object_todouble (ucl_object_t *obj)
-{
- double result = 0.;
-
- ucl_object_todouble_safe (obj, &result);
- return result;
-}
+UCL_EXTERN double ucl_object_todouble (ucl_object_t *obj);
/**
* Converts an object to integer value
@@ -645,40 +438,14 @@ ucl_object_todouble (ucl_object_t *obj)
* @param target target integer variable
* @return true if conversion was successful
*/
-static inline bool
-ucl_object_toint_safe (ucl_object_t *obj, int64_t *target)
-{
- if (obj == NULL) {
- return false;
- }
- switch (obj->type) {
- case UCL_INT:
- *target = obj->value.iv;
- break;
- case UCL_FLOAT:
- case UCL_TIME:
- *target = obj->value.dv; /* Loosing of decimal points */
- break;
- default:
- return false;
- }
-
- return true;
-}
+UCL_EXTERN bool ucl_object_toint_safe (ucl_object_t *obj, int64_t *target);
/**
* Unsafe version of \ref ucl_obj_toint_safe
* @param obj CL object
* @return int value
*/
-static inline int64_t
-ucl_object_toint (ucl_object_t *obj)
-{
- int64_t result = 0;
-
- ucl_object_toint_safe (obj, &result);
- return result;
-}
+UCL_EXTERN int64_t ucl_object_toint (ucl_object_t *obj);
/**
* Converts an object to boolean value
@@ -686,36 +453,14 @@ ucl_object_toint (ucl_object_t *obj)
* @param target target boolean variable
* @return true if conversion was successful
*/
-static inline bool
-ucl_object_toboolean_safe (ucl_object_t *obj, bool *target)
-{
- if (obj == NULL) {
- return false;
- }
- switch (obj->type) {
- case UCL_BOOLEAN:
- *target = (obj->value.iv == true);
- break;
- default:
- return false;
- }
-
- return true;
-}
+UCL_EXTERN bool ucl_object_toboolean_safe (ucl_object_t *obj, bool *target);
/**
* Unsafe version of \ref ucl_obj_toboolean_safe
* @param obj CL object
* @return boolean value
*/
-static inline bool
-ucl_object_toboolean (ucl_object_t *obj)
-{
- bool result = false;
-
- ucl_object_toboolean_safe (obj, &result);
- return result;
-}
+UCL_EXTERN bool ucl_object_toboolean (ucl_object_t *obj);
/**
* Converts an object to string value
@@ -723,48 +468,21 @@ ucl_object_toboolean (ucl_object_t *obj)
* @param target target string variable, no need to free value
* @return true if conversion was successful
*/
-static inline bool
-ucl_object_tostring_safe (ucl_object_t *obj, const char **target)
-{
- if (obj == NULL) {
- return false;
- }
-
- switch (obj->type) {
- case UCL_STRING:
- *target = ucl_copy_value_trash (obj);
- break;
- default:
- return false;
- }
-
- return true;
-}
+UCL_EXTERN bool ucl_object_tostring_safe (ucl_object_t *obj, const char **target);
/**
* Unsafe version of \ref ucl_obj_tostring_safe
* @param obj CL object
* @return string value
*/
-static inline const char *
-ucl_object_tostring (ucl_object_t *obj)
-{
- const char *result = NULL;
-
- ucl_object_tostring_safe (obj, &result);
- return result;
-}
+UCL_EXTERN const char* ucl_object_tostring (ucl_object_t *obj);
/**
* Convert any object to a string in JSON notation if needed
* @param obj CL object
* @return string value
*/
-static inline const char *
-ucl_object_tostring_forced (ucl_object_t *obj)
-{
- return ucl_copy_value_trash (obj);
-}
+UCL_EXTERN const char* ucl_object_tostring_forced (ucl_object_t *obj);
/**
* Return string as char * and len, string may be not zero terminated, more efficient that \ref ucl_obj_tostring as it
@@ -774,37 +492,15 @@ ucl_object_tostring_forced (ucl_object_t *obj)
* @param tlen target length
* @return true if conversion was successful
*/
-static inline bool
-ucl_object_tolstring_safe (ucl_object_t *obj, const char **target, size_t *tlen)
-{
- if (obj == NULL) {
- return false;
- }
- switch (obj->type) {
- case UCL_STRING:
- *target = obj->value.sv;
- *tlen = obj->len;
- break;
- default:
- return false;
- }
-
- return true;
-}
+UCL_EXTERN bool ucl_object_tolstring_safe (ucl_object_t *obj,
+ const char **target, size_t *tlen);
/**
* Unsafe version of \ref ucl_obj_tolstring_safe
* @param obj CL object
* @return string value
*/
-static inline const char *
-ucl_object_tolstring (ucl_object_t *obj, size_t *tlen)
-{
- const char *result = NULL;
-
- ucl_object_tolstring_safe (obj, &result, tlen);
- return result;
-}
+UCL_EXTERN const char* ucl_object_tolstring (ucl_object_t *obj, size_t *tlen);
/**
* Return object identified by a key in the specified object
@@ -812,7 +508,7 @@ ucl_object_tolstring (ucl_object_t *obj, size_t *tlen)
* @param key key to search
* @return object matched the specified key or NULL if key is not found
*/
-UCL_EXTERN ucl_object_t * ucl_object_find_key (ucl_object_t *obj, const char *key);
+UCL_EXTERN ucl_object_t* ucl_object_find_key (ucl_object_t *obj, const char *key);
/**
* Return object identified by a fixed size key in the specified object
@@ -821,18 +517,14 @@ UCL_EXTERN ucl_object_t * ucl_object_find_key (ucl_object_t *obj, const char *ke
* @param klen length of a key
* @return object matched the specified key or NULL if key is not found
*/
-UCL_EXTERN ucl_object_t *ucl_object_find_keyl (ucl_object_t *obj, const char *key, size_t klen);
+UCL_EXTERN ucl_object_t* ucl_object_find_keyl (ucl_object_t *obj, const char *key, size_t klen);
/**
* Returns a key of an object as a NULL terminated string
* @param obj CL object
* @return key or NULL if there is no key
*/
-static inline const char *
-ucl_object_key (ucl_object_t *obj)
-{
- return ucl_copy_key_trash (obj);
-}
+UCL_EXTERN const char* ucl_object_key (ucl_object_t *obj);
/**
* Returns a key of an object as a fixed size string (may be more efficient)
@@ -840,12 +532,7 @@ ucl_object_key (ucl_object_t *obj)
* @param len target key length
* @return key pointer
*/
-static inline const char *
-ucl_object_keyl (ucl_object_t *obj, size_t *len)
-{
- *len = obj->keylen;
- return obj->key;
-}
+UCL_EXTERN const char* ucl_object_keyl (ucl_object_t *obj, size_t *len);
/**
* Free ucl object
@@ -857,22 +544,34 @@ UCL_EXTERN void ucl_object_free (ucl_object_t *obj);
* Increase reference count for an object
* @param obj object to ref
*/
-static inline ucl_object_t *
-ucl_object_ref (ucl_object_t *obj) {
- obj->ref ++;
- return obj;
-}
+UCL_EXTERN ucl_object_t* ucl_object_ref (ucl_object_t *obj);
/**
* Decrease reference count for an object
* @param obj object to unref
*/
-static inline void
-ucl_object_unref (ucl_object_t *obj) {
- if (obj != NULL && --obj->ref <= 0) {
- ucl_object_free (obj);
- }
-}
+UCL_EXTERN void ucl_object_unref (ucl_object_t *obj);
+
+/**
+ * Compare objects `o1` and `o2`
+ * @param o1 the first object
+ * @param o2 the second object
+ * @return values >0, 0 and <0 if `o1` is more than, equal and less than `o2`.
+ * The order of comparison:
+ * 1) Type of objects
+ * 2) Size of objects
+ * 3) Content of objects
+ */
+UCL_EXTERN int ucl_object_compare (ucl_object_t *o1, ucl_object_t *o2);
+
+/**
+ * Sort UCL array using `cmp` compare function
+ * @param ar
+ * @param cmp
+ */
+UCL_EXTERN void ucl_object_array_sort (ucl_object_t *ar,
+ int (*cmp)(ucl_object_t *o1, ucl_object_t *o2));
+
/**
* Opaque iterator object
*/
@@ -944,7 +643,18 @@ UCL_EXTERN void ucl_parser_register_variable (struct ucl_parser *parser, const c
* @param err if *err is NULL it is set to parser error
* @return true if chunk has been added and false in case of error
*/
-UCL_EXTERN bool ucl_parser_add_chunk (struct ucl_parser *parser, const unsigned char *data, size_t len);
+UCL_EXTERN bool ucl_parser_add_chunk (struct ucl_parser *parser,
+ const unsigned char *data, size_t len);
+
+/**
+ * Load ucl object from a string
+ * @param parser parser structure
+ * @param data the pointer to the string
+ * @param len the length of the string, if `len` is 0 then `data` must be zero-terminated string
+ * @return true if string has been added and false in case of error
+ */
+UCL_EXTERN bool ucl_parser_add_string (struct ucl_parser *parser,
+ const char *data,size_t len);
/**
* Load and add data from a file
@@ -1039,6 +749,48 @@ UCL_EXTERN bool ucl_object_emit_full (ucl_object_t *obj, enum ucl_emitter emit_t
struct ucl_emitter_functions *emitter);
/** @} */
+/**
+ * @defgroup schema Schema functions
+ * These functions are used to validate UCL objects using json schema format
+ *
+ * @{
+ */
+
+/**
+ * Used to define UCL schema error
+ */
+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,/**< one or more missing properties */
+ UCL_SCHEMA_CONSTRAINT, /**< constraint found */
+ UCL_SCHEMA_MISSING_DEPENDENCY, /**< missing dependency */
+ UCL_SCHEMA_UNKNOWN /**< generic error */
+};
+
+/**
+ * Generic ucl schema error
+ */
+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 */
+};
+
+/**
+ * Validate object `obj` using schema object `schema`.
+ * @param schema schema object
+ * @param obj object to validate
+ * @param err error pointer, if this parameter is not NULL and error has been
+ * occured, then `err` is filled with the exact error definition.
+ * @return true if `obj` is valid using `schema`
+ */
+UCL_EXTERN bool ucl_object_validate (ucl_object_t *schema,
+ ucl_object_t *obj, struct ucl_schema_error *err);
+
+/** @} */
+
#ifdef __cplusplus
}
#endif