aboutsummaryrefslogtreecommitdiffstats
path: root/contrib
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2015-12-27 15:12:28 +0000
committerVsevolod Stakhov <vsevolod@highsecure.ru>2015-12-27 15:12:28 +0000
commit2275d0b9ebeda6a1edffb3f1f38d3b3af7c9c8a3 (patch)
tree31435c51aa1e9f6b7f79b5d272f367c3ef134e3a /contrib
parent4ce549ad001660aaf60b3804921a70f2bd8c503a (diff)
downloadrspamd-2275d0b9ebeda6a1edffb3f1f38d3b3af7c9c8a3.tar.gz
rspamd-2275d0b9ebeda6a1edffb3f1f38d3b3af7c9c8a3.zip
Sync with libucl
Diffstat (limited to 'contrib')
-rw-r--r--contrib/libucl/ucl.h49
-rw-r--r--contrib/libucl/ucl_schema.c277
-rw-r--r--contrib/libucl/ucl_util.c90
3 files changed, 297 insertions, 119 deletions
diff --git a/contrib/libucl/ucl.h b/contrib/libucl/ucl.h
index 82a1fd188..cfe62c081 100644
--- a/contrib/libucl/ucl.h
+++ b/contrib/libucl/ucl.h
@@ -306,6 +306,21 @@ UCL_EXTERN ucl_object_t * ucl_object_copy (const ucl_object_t *other)
UCL_EXTERN ucl_type_t ucl_object_type (const ucl_object_t *obj);
/**
+ * Converts ucl object type to its string representation
+ * @param type type of object
+ * @return constant string describing type
+ */
+UCL_EXTERN const char * ucl_object_type_to_string (ucl_type_t type);
+
+/**
+ * Converts string that represents ucl type to real ucl type enum
+ * @param input C string with name of type
+ * @param res resulting target
+ * @return true if `input` is a name of type stored in `res`
+ */
+UCL_EXTERN bool ucl_object_string_to_type (const char *input, ucl_type_t *res);
+
+/**
* Convert any string to an ucl object making the specified transformations
* @param str fixed size or NULL terminated string
* @param len length (if len is zero, than str is treated as NULL terminated)
@@ -1280,6 +1295,9 @@ enum ucl_schema_error_code {
UCL_SCHEMA_MISSING_PROPERTY,/**< one or more missing properties */
UCL_SCHEMA_CONSTRAINT, /**< constraint found */
UCL_SCHEMA_MISSING_DEPENDENCY, /**< missing dependency */
+ UCL_SCHEMA_EXTERNAL_REF_MISSING, /**< cannot fetch external ref */
+ UCL_SCHEMA_EXTERNAL_REF_INVALID, /**< invalid external ref */
+ UCL_SCHEMA_INTERNAL_ERROR, /**< something bad happened */
UCL_SCHEMA_UNKNOWN /**< generic error */
};
@@ -1303,6 +1321,37 @@ struct ucl_schema_error {
UCL_EXTERN bool ucl_object_validate (const ucl_object_t *schema,
const ucl_object_t *obj, struct ucl_schema_error *err);
+/**
+ * Validate object `obj` using schema object `schema` and root schema at `root`.
+ * @param schema schema object
+ * @param obj object to validate
+ * @param root root schema object
+ * @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_root (const ucl_object_t *schema,
+ const ucl_object_t *obj,
+ const ucl_object_t *root,
+ struct ucl_schema_error *err);
+
+/**
+ * Validate object `obj` using schema object `schema` and root schema at `root`
+ * using some external references provided.
+ * @param schema schema object
+ * @param obj object to validate
+ * @param root root schema object
+ * @param ext_refs external references (might be modified during validation)
+ * @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_root_ext (const ucl_object_t *schema,
+ const ucl_object_t *obj,
+ const ucl_object_t *root,
+ ucl_object_t *ext_refs,
+ struct ucl_schema_error *err);
+
/** @} */
#ifdef __cplusplus
diff --git a/contrib/libucl/ucl_schema.c b/contrib/libucl/ucl_schema.c
index 834b62acc..9b96da5ef 100644
--- a/contrib/libucl/ucl_schema.c
+++ b/contrib/libucl/ucl_schema.c
@@ -43,72 +43,8 @@
static bool ucl_schema_validate (const ucl_object_t *schema,
const ucl_object_t *obj, bool try_array,
struct ucl_schema_error *err,
- const ucl_object_t *root);
-
-static bool
-ucl_string_to_type (const char *input, ucl_type_t *res)
-{
- if (strcasecmp (input, "object") == 0) {
- *res = UCL_OBJECT;
- }
- else if (strcasecmp (input, "array") == 0) {
- *res = UCL_ARRAY;
- }
- else if (strcasecmp (input, "integer") == 0) {
- *res = UCL_INT;
- }
- else if (strcasecmp (input, "number") == 0) {
- *res = UCL_FLOAT;
- }
- else if (strcasecmp (input, "string") == 0) {
- *res = UCL_STRING;
- }
- else if (strcasecmp (input, "boolean") == 0) {
- *res = UCL_BOOLEAN;
- }
- else if (strcasecmp (input, "null") == 0) {
- *res = UCL_NULL;
- }
- else {
- return false;
- }
-
- return true;
-}
-
-static const char *
-ucl_object_type_to_string (ucl_type_t type)
-{
- const char *res = "unknown";
-
- switch (type) {
- case UCL_OBJECT:
- res = "object";
- break;
- case UCL_ARRAY:
- res = "array";
- break;
- case UCL_INT:
- res = "integer";
- break;
- case UCL_FLOAT:
- case UCL_TIME:
- res = "number";
- break;
- case UCL_STRING:
- res = "string";
- break;
- case UCL_BOOLEAN:
- res = "boolean";
- break;
- case UCL_NULL:
- case UCL_USERDATA:
- res = "null";
- break;
- }
-
- return res;
-}
+ const ucl_object_t *root,
+ ucl_object_t *ext_ref);
/*
* Create validation error
@@ -160,7 +96,8 @@ ucl_schema_test_pattern (const ucl_object_t *obj, const char *pattern)
static bool
ucl_schema_validate_dependencies (const ucl_object_t *deps,
const ucl_object_t *obj, struct ucl_schema_error *err,
- const ucl_object_t *root)
+ const ucl_object_t *root,
+ ucl_object_t *ext_ref)
{
const ucl_object_t *elt, *cur, *cur_dep;
ucl_object_iter_t iter = NULL, piter;
@@ -183,7 +120,7 @@ ucl_schema_validate_dependencies (const ucl_object_t *deps,
}
}
else if (cur->type == UCL_OBJECT) {
- ret = ucl_schema_validate (cur, obj, true, err, root);
+ ret = ucl_schema_validate (cur, obj, true, err, root, ext_ref);
}
}
}
@@ -197,7 +134,8 @@ ucl_schema_validate_dependencies (const ucl_object_t *deps,
static bool
ucl_schema_validate_object (const ucl_object_t *schema,
const ucl_object_t *obj, struct ucl_schema_error *err,
- const ucl_object_t *root)
+ const ucl_object_t *root,
+ ucl_object_t *ext_ref)
{
const ucl_object_t *elt, *prop, *found, *additional_schema = NULL,
*required = NULL, *pat, *pelt;
@@ -212,7 +150,8 @@ ucl_schema_validate_object (const ucl_object_t *schema,
while (ret && (prop = ucl_iterate_object (elt, &piter, true)) != NULL) {
found = ucl_object_find_key (obj, ucl_object_key (prop));
if (found) {
- ret = ucl_schema_validate (prop, found, true, err, root);
+ ret = ucl_schema_validate (prop, found, true, err, root,
+ ext_ref);
}
}
}
@@ -270,13 +209,15 @@ ucl_schema_validate_object (const ucl_object_t *schema,
while (ret && (prop = ucl_iterate_object (elt, &piter, true)) != NULL) {
found = ucl_schema_test_pattern (obj, ucl_object_key (prop));
if (found) {
- ret = ucl_schema_validate (prop, found, true, err, root);
+ ret = ucl_schema_validate (prop, found, true, err, root,
+ ext_ref);
}
}
}
else if (elt->type == UCL_OBJECT &&
strcmp (ucl_object_key (elt), "dependencies") == 0) {
- ret = ucl_schema_validate_dependencies (elt, obj, err, root);
+ ret = ucl_schema_validate_dependencies (elt, obj, err, root,
+ ext_ref);
}
}
@@ -308,7 +249,8 @@ ucl_schema_validate_object (const ucl_object_t *schema,
break;
}
else if (additional_schema != NULL) {
- if (!ucl_schema_validate (additional_schema, elt, true, err, root)) {
+ if (!ucl_schema_validate (additional_schema, elt,
+ true, err, root, ext_ref)) {
ret = false;
break;
}
@@ -518,7 +460,8 @@ ucl_schema_array_is_unique (const ucl_object_t *obj, struct ucl_schema_error *er
static bool
ucl_schema_validate_array (const ucl_object_t *schema,
const ucl_object_t *obj, struct ucl_schema_error *err,
- const ucl_object_t *root)
+ const ucl_object_t *root,
+ ucl_object_t *ext_ref)
{
const ucl_object_t *elt, *it, *found, *additional_schema = NULL,
*first_unvalidated = NULL;
@@ -533,7 +476,8 @@ ucl_schema_validate_array (const ucl_object_t *schema,
found = ucl_array_head (obj);
while (ret && (it = ucl_iterate_object (elt, &piter, true)) != NULL) {
if (found) {
- ret = ucl_schema_validate (it, found, false, err, root);
+ ret = ucl_schema_validate (it, found, false, err,
+ root, ext_ref);
found = ucl_array_find_index (obj, ++idx);
}
}
@@ -545,7 +489,8 @@ ucl_schema_validate_array (const ucl_object_t *schema,
else if (elt->type == UCL_OBJECT) {
/* Validate all items using the specified schema */
while (ret && (it = ucl_iterate_object (obj, &piter, true)) != NULL) {
- ret = ucl_schema_validate (elt, it, false, err, root);
+ ret = ucl_schema_validate (elt, it, false, err, root,
+ ext_ref);
}
}
else {
@@ -612,7 +557,7 @@ ucl_schema_validate_array (const ucl_object_t *schema,
elt = ucl_array_find_index (obj, idx);
while (elt) {
if (!ucl_schema_validate (additional_schema, elt, false,
- err, root)) {
+ err, root, ext_ref)) {
ret = false;
break;
}
@@ -657,7 +602,7 @@ ucl_schema_type_is_allowed (const ucl_object_t *type, const ucl_object_t *obj,
}
else if (type->type == UCL_STRING) {
type_str = ucl_object_tostring (type);
- if (!ucl_string_to_type (type_str, &t)) {
+ if (!ucl_object_string_to_type (type_str, &t)) {
ucl_schema_create_error (err, UCL_SCHEMA_INVALID_SCHEMA, type,
"Type attribute is invalid in schema");
return false;
@@ -771,31 +716,109 @@ ucl_schema_resolve_ref_component (const ucl_object_t *cur,
*/
static const ucl_object_t *
ucl_schema_resolve_ref (const ucl_object_t *root, const char *ref,
- struct ucl_schema_error *err)
+ struct ucl_schema_error *err, ucl_object_t *ext_ref,
+ ucl_object_t const ** nroot)
{
- const char *p, *c;
- const ucl_object_t *res = NULL;
-
+ UT_string *url_err = NULL;
+ struct ucl_parser *parser;
+ const ucl_object_t *res = NULL, *ext_obj = NULL;
+ ucl_object_t *url_obj;
+ const char *p, *c, *hash_ptr = NULL;
+ char *url_copy = NULL;
+ unsigned char *url_buf;
+ size_t url_buflen;
if (ref[0] != '#') {
- ucl_schema_create_error (err, UCL_SCHEMA_INVALID_SCHEMA, root,
- "reference %s is invalid, not started with #", ref);
- return NULL;
+ hash_ptr = strrchr (ref, '#');
+
+ if (hash_ptr) {
+ url_copy = malloc (hash_ptr - ref + 1);
+
+ if (url_copy == NULL) {
+ ucl_schema_create_error (err, UCL_SCHEMA_INTERNAL_ERROR, root,
+ "cannot allocate memory");
+ return NULL;
+ }
+
+ ucl_strlcpy (url_copy, ref, hash_ptr - ref + 1);
+ p = url_copy;
+ }
+ else {
+ /* Full URL */
+ p = ref;
+ }
+
+ ext_obj = ucl_object_find_key (ext_ref, p);
+
+ if (ext_obj == NULL) {
+ if (ucl_strnstr (p, "://", strlen (p)) != NULL) {
+ if (!ucl_fetch_url (p, &url_buf, &url_buflen, &url_err, true)) {
+ free (url_copy);
+ ucl_schema_create_error (err,
+ UCL_SCHEMA_INVALID_SCHEMA,
+ root,
+ "cannot fetch reference %s: %s",
+ p,
+ url_err != NULL ? utstring_body (url_err)
+ : "unknown");
+ return NULL;
+ }
+ }
+ else {
+ if (!ucl_fetch_file (p, &url_buf, &url_buflen, &url_err,
+ true)) {
+ free (url_copy);
+ ucl_schema_create_error (err,
+ UCL_SCHEMA_INVALID_SCHEMA,
+ root,
+ "cannot fetch reference %s: %s",
+ p,
+ url_err != NULL ? utstring_body (url_err)
+ : "unknown");
+ return NULL;
+ }
+ }
+
+ parser = ucl_parser_new (0);
+
+ if (!ucl_parser_add_chunk (parser, url_buf, url_buflen)) {
+ free (url_copy);
+ ucl_schema_create_error (err, UCL_SCHEMA_INVALID_SCHEMA, root,
+ "cannot fetch reference %s: %s", p,
+ ucl_parser_get_error (parser));
+ ucl_parser_free (parser);
+ return NULL;
+ }
+
+ url_obj = ucl_parser_get_object (parser);
+ ext_obj = url_obj;
+ ucl_object_insert_key (ext_ref, url_obj, p, 0, true);
+ free (url_buf);
+ free (url_copy);
+ }
+
+ if (hash_ptr) {
+ p = hash_ptr + 1;
+ }
+ else {
+ p = "";
+ }
}
- if (ref[1] == '/') {
- p = &ref[2];
+ else {
+ p = ref + 1;
}
- else if (ref[1] == '\0') {
- return root;
+
+ res = ext_obj != NULL ? ext_obj : root;
+ *nroot = res;
+
+ if (*p == '/') {
+ p++;
}
- else {
- ucl_schema_create_error (err, UCL_SCHEMA_INVALID_SCHEMA, root,
- "reference %s is invalid, not started with #/", ref);
- return NULL;
+ else if (*p == '\0') {
+ return res;
}
c = p;
- res = root;
while (*p != '\0') {
if (*p == '/') {
@@ -878,15 +901,17 @@ static bool
ucl_schema_validate (const ucl_object_t *schema,
const ucl_object_t *obj, bool try_array,
struct ucl_schema_error *err,
- const ucl_object_t *root)
+ const ucl_object_t *root,
+ ucl_object_t *external_refs)
{
- const ucl_object_t *elt, *cur;
+ const ucl_object_t *elt, *cur, *ref_root;
ucl_object_iter_t iter = NULL;
bool ret;
if (schema->type != UCL_OBJECT) {
ucl_schema_create_error (err, UCL_SCHEMA_INVALID_SCHEMA, schema,
- "schema is %s instead of object", ucl_object_type_to_string (schema->type));
+ "schema is %s instead of object",
+ ucl_object_type_to_string (schema->type));
return false;
}
@@ -898,7 +923,7 @@ ucl_schema_validate (const ucl_object_t *schema,
return false;
}
LL_FOREACH (obj, cur) {
- if (!ucl_schema_validate (schema, cur, false, err, root)) {
+ if (!ucl_schema_validate (schema, cur, false, err, root, external_refs)) {
return false;
}
}
@@ -916,7 +941,7 @@ ucl_schema_validate (const ucl_object_t *schema,
if (elt != NULL && elt->type == UCL_ARRAY) {
iter = NULL;
while ((cur = ucl_iterate_object (elt, &iter, true)) != NULL) {
- ret = ucl_schema_validate (cur, obj, true, err, root);
+ ret = ucl_schema_validate (cur, obj, true, err, root, external_refs);
if (!ret) {
return false;
}
@@ -927,7 +952,7 @@ ucl_schema_validate (const ucl_object_t *schema,
if (elt != NULL && elt->type == UCL_ARRAY) {
iter = NULL;
while ((cur = ucl_iterate_object (elt, &iter, true)) != NULL) {
- ret = ucl_schema_validate (cur, obj, true, err, root);
+ ret = ucl_schema_validate (cur, obj, true, err, root, external_refs);
if (ret) {
break;
}
@@ -947,9 +972,9 @@ ucl_schema_validate (const ucl_object_t *schema,
ret = false;
while ((cur = ucl_iterate_object (elt, &iter, true)) != NULL) {
if (!ret) {
- ret = ucl_schema_validate (cur, obj, true, err, root);
+ ret = ucl_schema_validate (cur, obj, true, err, root, external_refs);
}
- else if (ucl_schema_validate (cur, obj, true, err, root)) {
+ else if (ucl_schema_validate (cur, obj, true, err, root, external_refs)) {
ret = false;
break;
}
@@ -961,7 +986,7 @@ ucl_schema_validate (const ucl_object_t *schema,
elt = ucl_object_find_key (schema, "not");
if (elt != NULL && elt->type == UCL_OBJECT) {
- if (ucl_schema_validate (elt, obj, true, err, root)) {
+ if (ucl_schema_validate (elt, obj, true, err, root, external_refs)) {
return false;
}
else {
@@ -972,11 +997,15 @@ ucl_schema_validate (const ucl_object_t *schema,
elt = ucl_object_find_key (schema, "$ref");
if (elt != NULL) {
- cur = ucl_schema_resolve_ref (root, ucl_object_tostring (elt), err);
+ ref_root = root;
+ cur = ucl_schema_resolve_ref (root, ucl_object_tostring (elt),
+ err, external_refs, &ref_root);
+
if (cur == NULL) {
return false;
}
- if (!ucl_schema_validate (cur, obj, try_array, err, root)) {
+ if (!ucl_schema_validate (cur, obj, try_array, err, ref_root,
+ external_refs)) {
return false;
}
}
@@ -988,10 +1017,10 @@ ucl_schema_validate (const ucl_object_t *schema,
switch (obj->type) {
case UCL_OBJECT:
- return ucl_schema_validate_object (schema, obj, err, root);
+ return ucl_schema_validate_object (schema, obj, err, root, external_refs);
break;
case UCL_ARRAY:
- return ucl_schema_validate_array (schema, obj, err, root);
+ return ucl_schema_validate_array (schema, obj, err, root, external_refs);
break;
case UCL_INT:
case UCL_FLOAT:
@@ -1011,5 +1040,37 @@ bool
ucl_object_validate (const ucl_object_t *schema,
const ucl_object_t *obj, struct ucl_schema_error *err)
{
- return ucl_schema_validate (schema, obj, true, err, schema);
+ return ucl_object_validate_root_ext (schema, obj, schema, NULL, err);
+}
+
+bool
+ucl_object_validate_root (const ucl_object_t *schema,
+ const ucl_object_t *obj,
+ const ucl_object_t *root,
+ struct ucl_schema_error *err)
+{
+ return ucl_object_validate_root_ext (schema, obj, root, NULL, err);
+}
+
+bool
+ucl_object_validate_root_ext (const ucl_object_t *schema,
+ const ucl_object_t *obj,
+ const ucl_object_t *root,
+ ucl_object_t *ext_refs,
+ struct ucl_schema_error *err)
+{
+ bool ret, need_unref = false;
+
+ if (ext_refs == NULL) {
+ ext_refs = ucl_object_typed_new (UCL_OBJECT);
+ need_unref = true;
+ }
+
+ ret = ucl_schema_validate (schema, obj, true, err, root, ext_refs);
+
+ if (need_unref) {
+ ucl_object_unref (ext_refs);
+ }
+
+ return ret;
}
diff --git a/contrib/libucl/ucl_util.c b/contrib/libucl/ucl_util.c
index 730a5c4af..2bd0c2a3f 100644
--- a/contrib/libucl/ucl_util.c
+++ b/contrib/libucl/ucl_util.c
@@ -437,7 +437,7 @@ ucl_copy_value_trash (const ucl_object_t *obj)
}
deconst->flags |= UCL_OBJECT_ALLOCATED_VALUE;
}
-
+
return obj->trash_stack[UCL_TRASH_VALUE];
}
@@ -628,7 +628,7 @@ ucl_curl_write_callback (void* contents, size_t size, size_t nmemb, void* ud)
* @param buflen target length
* @return
*/
-static bool
+bool
ucl_fetch_url (const unsigned char *url, unsigned char **buf, size_t *buflen,
UT_string **err, bool must_exist)
{
@@ -690,8 +690,8 @@ ucl_fetch_url (const unsigned char *url, unsigned char **buf, size_t *buflen,
return false;
}
curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, ucl_curl_write_callback);
- cbdata.buf = *buf;
- cbdata.buflen = *buflen;
+ cbdata.buf = NULL;
+ cbdata.buflen = 0;
curl_easy_setopt (curl, CURLOPT_WRITEDATA, &cbdata);
if ((r = curl_easy_perform (curl)) != CURLE_OK) {
@@ -723,7 +723,7 @@ ucl_fetch_url (const unsigned char *url, unsigned char **buf, size_t *buflen,
* @param buflen target length
* @return
*/
-static bool
+bool
ucl_fetch_file (const unsigned char *filename, unsigned char **buf, size_t *buflen,
UT_string **err, bool must_exist)
{
@@ -739,7 +739,7 @@ ucl_fetch_file (const unsigned char *filename, unsigned char **buf, size_t *bufl
}
if (st.st_size == 0) {
/* Do not map empty files */
- *buf = "";
+ *buf = NULL;
*buflen = 0;
}
else {
@@ -848,7 +848,7 @@ ucl_include_url (const unsigned char *data, size_t len,
snprintf (urlbuf, sizeof (urlbuf), "%.*s", (int)len, data);
if (!ucl_fetch_url (urlbuf, &buf, &buflen, &parser->err, params->must_exist)) {
- return (!params->must_exist || false);
+ return !params->must_exist;
}
if (params->check_signature) {
@@ -1232,7 +1232,7 @@ ucl_include_file (const unsigned char *data, size_t len,
treat allow_glob/need_glob as a NOOP and just return */
return ucl_include_file_single (data, len, parser, params);
#endif
-
+
return true;
}
@@ -1252,7 +1252,7 @@ ucl_include_common (const unsigned char *data, size_t len,
bool default_try,
bool default_sign)
{
- bool allow_url, search;
+ bool allow_url = false, search = false;
const char *duplicate;
const ucl_object_t *param;
ucl_object_iter_t it = NULL, ip = NULL;
@@ -1271,8 +1271,6 @@ ucl_include_common (const unsigned char *data, size_t len,
params.strat = UCL_DUPLICATE_APPEND;
params.must_exist = !default_try;
- search = false;
-
/* Process arguments */
if (args != NULL && args->type == UCL_OBJECT) {
while ((param = ucl_iterate_object (args, &it, true)) != NULL) {
@@ -3255,3 +3253,73 @@ ucl_object_set_priority (ucl_object_t *obj,
obj->flags = priority;
}
}
+
+bool
+ucl_object_string_to_type (const char *input, ucl_type_t *res)
+{
+ if (strcasecmp (input, "object") == 0) {
+ *res = UCL_OBJECT;
+ }
+ else if (strcasecmp (input, "array") == 0) {
+ *res = UCL_ARRAY;
+ }
+ else if (strcasecmp (input, "integer") == 0) {
+ *res = UCL_INT;
+ }
+ else if (strcasecmp (input, "number") == 0) {
+ *res = UCL_FLOAT;
+ }
+ else if (strcasecmp (input, "string") == 0) {
+ *res = UCL_STRING;
+ }
+ else if (strcasecmp (input, "boolean") == 0) {
+ *res = UCL_BOOLEAN;
+ }
+ else if (strcasecmp (input, "null") == 0) {
+ *res = UCL_NULL;
+ }
+ else if (strcasecmp (input, "userdata") == 0) {
+ *res = UCL_USERDATA;
+ }
+ else {
+ return false;
+ }
+
+ return true;
+}
+
+const char *
+ucl_object_type_to_string (ucl_type_t type)
+{
+ const char *res = "unknown";
+
+ switch (type) {
+ case UCL_OBJECT:
+ res = "object";
+ break;
+ case UCL_ARRAY:
+ res = "array";
+ break;
+ case UCL_INT:
+ res = "integer";
+ break;
+ case UCL_FLOAT:
+ case UCL_TIME:
+ res = "number";
+ break;
+ case UCL_STRING:
+ res = "string";
+ break;
+ case UCL_BOOLEAN:
+ res = "boolean";
+ break;
+ case UCL_USERDATA:
+ res = "userdata";
+ break;
+ case UCL_NULL:
+ res = "null";
+ break;
+ }
+
+ return res;
+}