aboutsummaryrefslogtreecommitdiff
path: root/contrib/libucl/src/ucl_util.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/libucl/src/ucl_util.c')
-rw-r--r--contrib/libucl/src/ucl_util.c377
1 files changed, 304 insertions, 73 deletions
diff --git a/contrib/libucl/src/ucl_util.c b/contrib/libucl/src/ucl_util.c
index 730a5c4afd57..261bf95f5b7d 100644
--- a/contrib/libucl/src/ucl_util.c
+++ b/contrib/libucl/src/ucl_util.c
@@ -27,6 +27,7 @@
#include "ucl_chartable.h"
#include "kvec.h"
#include <stdarg.h>
+#include <stdio.h> /* for snprintf */
#ifndef _WIN32
#include <glob.h>
@@ -50,6 +51,8 @@ typedef kvec_t(ucl_object_t *) ucl_array_t;
#endif
#ifdef CURL_FOUND
+/* Seems to be broken */
+#define CURL_DISABLE_TYPECHECK 1
#include <curl/curl.h>
#endif
#ifdef HAVE_FETCH_H
@@ -236,7 +239,7 @@ ucl_object_free_internal (ucl_object_t *obj, bool allow_rec, ucl_object_dtor dto
}
else if (obj->type == UCL_OBJECT) {
if (obj->value.ov != NULL) {
- ucl_hash_destroy (obj->value.ov, (ucl_hash_free_func *)dtor);
+ ucl_hash_destroy (obj->value.ov, (ucl_hash_free_func)dtor);
}
obj->value.ov = NULL;
}
@@ -306,6 +309,9 @@ ucl_unescape_json_string (char *str, size_t len)
case 'u':
/* Unicode escape */
uval = 0;
+ h ++; /* u character */
+ len --;
+
if (len > 3) {
for (i = 0; i < 4; i++) {
uval <<= 4;
@@ -322,8 +328,7 @@ ucl_unescape_json_string (char *str, size_t len)
break;
}
}
- h += 3;
- len -= 3;
+
/* Encode */
if(uval < 0x80) {
t[0] = (char)uval;
@@ -340,6 +345,8 @@ ucl_unescape_json_string (char *str, size_t len)
t[2] = 0x80 + ((uval & 0x003F));
t += 3;
}
+#if 0
+ /* It's not actually supported now */
else if(uval <= 0x10FFFF) {
t[0] = 0xF0 + ((uval & 0x1C0000) >> 18);
t[1] = 0x80 + ((uval & 0x03F000) >> 12);
@@ -347,9 +354,19 @@ ucl_unescape_json_string (char *str, size_t len)
t[3] = 0x80 + ((uval & 0x00003F));
t += 4;
}
+#endif
else {
*t++ = '?';
}
+
+ /* Consume 4 characters of source */
+ h += 4;
+ len -= 4;
+
+ if (len > 0) {
+ len --; /* for '\' character */
+ }
+ continue;
}
else {
*t++ = 'u';
@@ -437,7 +454,7 @@ ucl_copy_value_trash (const ucl_object_t *obj)
}
deconst->flags |= UCL_OBJECT_ALLOCATED_VALUE;
}
-
+
return obj->trash_stack[UCL_TRASH_VALUE];
}
@@ -504,6 +521,10 @@ ucl_parser_free (struct ucl_parser *parser)
free (parser->cur_file);
}
+ if (parser->comments) {
+ ucl_object_unref (parser->comments);
+ }
+
UCL_FREE (sizeof (struct ucl_parser), parser);
}
@@ -628,7 +649,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 +711,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 +744,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 +760,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 {
@@ -752,6 +773,8 @@ ucl_fetch_file (const unsigned char *filename, unsigned char **buf, size_t *bufl
close (fd);
ucl_create_err (err, "cannot mmap file %s: %s",
filename, strerror (errno));
+ *buf = NULL;
+
return false;
}
*buflen = st.st_size;
@@ -848,7 +871,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) {
@@ -968,12 +991,12 @@ ucl_include_file_single (const unsigned char *data, size_t len,
ucl_create_err (&parser->err, "cannot verify file %s: %s",
filebuf,
ERR_error_string (ERR_get_error (), NULL));
- if (siglen > 0) {
+ if (sigbuf) {
ucl_munmap (sigbuf, siglen);
}
return false;
}
- if (siglen > 0) {
+ if (sigbuf) {
ucl_munmap (sigbuf, siglen);
}
#endif
@@ -1037,6 +1060,16 @@ ucl_include_file_single (const unsigned char *data, size_t len,
else if (old_obj == NULL) {
/* Create an object with key: prefix */
nest_obj = ucl_object_new_full (UCL_OBJECT, params->priority);
+
+ if (nest_obj == NULL) {
+ ucl_create_err (&parser->err, "cannot allocate memory for an object");
+ if (buf) {
+ ucl_munmap (buf, buflen);
+ }
+
+ return false;
+ }
+
nest_obj->key = params->prefix;
nest_obj->keylen = strlen (params->prefix);
ucl_copy_key_trash(nest_obj);
@@ -1052,6 +1085,14 @@ ucl_include_file_single (const unsigned char *data, size_t len,
if (ucl_object_type(old_obj) == UCL_ARRAY) {
/* Append to the existing array */
nest_obj = ucl_object_new_full (UCL_OBJECT, params->priority);
+ if (nest_obj == NULL) {
+ ucl_create_err (&parser->err, "cannot allocate memory for an object");
+ if (buf) {
+ ucl_munmap (buf, buflen);
+ }
+
+ return false;
+ }
nest_obj->prev = nest_obj;
nest_obj->next = NULL;
@@ -1060,6 +1101,14 @@ ucl_include_file_single (const unsigned char *data, size_t len,
else {
/* Convert the object to an array */
new_obj = ucl_object_typed_new (UCL_ARRAY);
+ if (new_obj == NULL) {
+ ucl_create_err (&parser->err, "cannot allocate memory for an object");
+ if (buf) {
+ ucl_munmap (buf, buflen);
+ }
+
+ return false;
+ }
new_obj->key = old_obj->key;
new_obj->keylen = old_obj->keylen;
new_obj->flags |= UCL_OBJECT_MULTIVALUE;
@@ -1067,6 +1116,14 @@ ucl_include_file_single (const unsigned char *data, size_t len,
new_obj->next = NULL;
nest_obj = ucl_object_new_full (UCL_OBJECT, params->priority);
+ if (nest_obj == NULL) {
+ ucl_create_err (&parser->err, "cannot allocate memory for an object");
+ if (buf) {
+ ucl_munmap (buf, buflen);
+ }
+
+ return false;
+ }
nest_obj->prev = nest_obj;
nest_obj->next = NULL;
@@ -1085,6 +1142,10 @@ ucl_include_file_single (const unsigned char *data, size_t len,
ucl_create_err (&parser->err,
"Conflicting type for key: %s",
params->prefix);
+ if (buf) {
+ ucl_munmap (buf, buflen);
+ }
+
return false;
}
}
@@ -1092,18 +1153,21 @@ ucl_include_file_single (const unsigned char *data, size_t len,
/* Put all of the content of the include inside that object */
parser->stack->obj->value.ov = container;
- if (nest_obj != NULL) {
- st = UCL_ALLOC (sizeof (struct ucl_stack));
- if (st == NULL) {
- ucl_create_err (&parser->err, "cannot allocate memory for an object");
- ucl_object_unref (nest_obj);
- return NULL;
+ st = UCL_ALLOC (sizeof (struct ucl_stack));
+ if (st == NULL) {
+ ucl_create_err (&parser->err, "cannot allocate memory for an object");
+ ucl_object_unref (nest_obj);
+
+ if (buf) {
+ ucl_munmap (buf, buflen);
}
- st->obj = nest_obj;
- st->level = parser->stack->level;
- LL_PREPEND (parser->stack, st);
- parser->cur_obj = nest_obj;
+
+ return false;
}
+ st->obj = nest_obj;
+ st->level = parser->stack->level;
+ LL_PREPEND (parser->stack, st);
+ parser->cur_obj = nest_obj;
}
res = ucl_parser_add_chunk_full (parser, buf, buflen, params->priority,
@@ -1232,7 +1296,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 +1316,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,11 +1335,9 @@ 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) {
+ while ((param = ucl_object_iterate (args, &it, true)) != NULL) {
if (param->type == UCL_BOOLEAN) {
if (strncmp (param->key, "try", param->keylen) == 0) {
params.must_exist = !ucl_object_toboolean (param);
@@ -1450,7 +1512,7 @@ ucl_priority_handler (const unsigned char *data, size_t len,
/* Process arguments */
if (args != NULL && args->type == UCL_OBJECT) {
- while ((param = ucl_iterate_object (args, &it, true)) != NULL) {
+ while ((param = ucl_object_iterate (args, &it, true)) != NULL) {
if (param->type == UCL_INT) {
if (strncmp (param->key, "priority", param->keylen) == 0) {
priority = ucl_object_toint (param);
@@ -1506,7 +1568,7 @@ ucl_load_handler (const unsigned char *data, size_t len,
size_t buflen;
unsigned priority;
int64_t iv;
- ucl_hash_t *container = NULL;
+ ucl_object_t *container = NULL;
enum ucl_string_flags flags;
/* Default values */
@@ -1529,7 +1591,7 @@ ucl_load_handler (const unsigned char *data, size_t len,
/* Process arguments */
if (args != NULL && args->type == UCL_OBJECT) {
- while ((param = ucl_iterate_object (args, &it, true)) != NULL) {
+ while ((param = ucl_object_iterate (args, &it, true)) != NULL) {
if (param->type == UCL_BOOLEAN) {
if (strncmp (param->key, "try", param->keylen) == 0) {
try_load = ucl_object_toboolean (param);
@@ -1566,21 +1628,39 @@ ucl_load_handler (const unsigned char *data, size_t len,
}
}
- if (prefix == NULL || strlen(prefix) == 0) {
+ if (prefix == NULL || strlen (prefix) == 0) {
ucl_create_err (&parser->err, "No Key specified in load macro");
return false;
}
if (len > 0) {
- asprintf (&load_file, "%.*s", (int)len, data);
- if (!ucl_fetch_file (load_file, &buf, &buflen, &parser->err, !try_load)) {
+ load_file = malloc (len + 1);
+ if (!load_file) {
+ ucl_create_err (&parser->err, "cannot allocate memory for suffix");
+
+ return false;
+ }
+
+ snprintf (load_file, len + 1, "%.*s", (int)len, data);
+
+ if (!ucl_fetch_file (load_file, &buf, &buflen, &parser->err,
+ !try_load)) {
+ free (load_file);
+
return (try_load || false);
}
- container = parser->stack->obj->value.ov;
- old_obj = __DECONST (ucl_object_t *, ucl_hash_search (container, prefix, strlen (prefix)));
+ free (load_file);
+ container = parser->stack->obj;
+ old_obj = __DECONST (ucl_object_t *, ucl_object_lookup (container,
+ prefix));
+
if (old_obj != NULL) {
ucl_create_err (&parser->err, "Key %s already exists", prefix);
+ if (buf) {
+ ucl_munmap (buf, buflen);
+ }
+
return false;
}
@@ -1592,26 +1672,37 @@ ucl_load_handler (const unsigned char *data, size_t len,
}
}
else if (strcasecmp (target, "int") == 0) {
- asprintf(&tmp, "%.*s", (int)buflen, buf);
- iv = strtoll(tmp, NULL, 10);
- obj = ucl_object_fromint(iv);
+ tmp = malloc (buflen + 1);
+
+ if (tmp == NULL) {
+ ucl_create_err (&parser->err, "Memory allocation failed");
+ if (buf) {
+ ucl_munmap (buf, buflen);
+ }
+
+ return false;
+ }
+
+ snprintf (tmp, buflen + 1, "%.*s", (int)buflen, buf);
+ iv = strtoll (tmp, NULL, 10);
+ obj = ucl_object_fromint (iv);
+ free (tmp);
}
- if (buflen > 0) {
+ if (buf) {
ucl_munmap (buf, buflen);
}
if (obj != NULL) {
obj->key = prefix;
obj->keylen = strlen (prefix);
- ucl_copy_key_trash(obj);
+ ucl_copy_key_trash (obj);
obj->prev = obj;
obj->next = NULL;
ucl_object_set_priority (obj, priority);
- container = ucl_hash_insert_object (container, obj,
- parser->flags & UCL_PARSER_KEY_LOWERCASE);
- parser->stack->obj->value.ov = container;
+ ucl_object_insert_key (container, obj, obj->key, obj->keylen, false);
}
+
return true;
}
@@ -1629,7 +1720,7 @@ ucl_inherit_handler (const unsigned char *data, size_t len,
bool replace = false;
struct ucl_parser *parser = ud;
- parent = ucl_object_find_keyl (ctx, data, len);
+ parent = ucl_object_lookup_len (ctx, data, len);
/* Some sanity checks */
if (parent == NULL || ucl_object_type (parent) != UCL_OBJECT) {
@@ -1646,13 +1737,13 @@ ucl_inherit_handler (const unsigned char *data, size_t len,
target = parser->stack->obj;
- if (args && (cur = ucl_object_find_key (args, "replace")) != NULL) {
+ if (args && (cur = ucl_object_lookup (args, "replace")) != NULL) {
replace = ucl_object_toboolean (cur);
}
- while ((cur = ucl_iterate_object (parent, &it, true))) {
+ while ((cur = ucl_object_iterate (parent, &it, true))) {
/* We do not replace existing keys */
- if (!replace && ucl_object_find_keyl (target, cur->key, cur->keylen)) {
+ if (!replace && ucl_object_lookup_len (target, cur->key, cur->keylen)) {
continue;
}
@@ -2097,7 +2188,7 @@ ucl_object_insert_key_common (ucl_object_t *top, ucl_object_t *elt,
}
else if (found->type == UCL_OBJECT && elt->type == UCL_OBJECT) {
/* Mix two hashes */
- while ((cur = ucl_iterate_object (elt, &it, true)) != NULL) {
+ while ((cur = ucl_object_iterate (elt, &it, true)) != NULL) {
tmp = ucl_object_ref (cur);
ucl_object_insert_key_common (found, tmp, cur->key,
cur->keylen, copy_key, false, false);
@@ -2126,7 +2217,7 @@ ucl_object_delete_keyl (ucl_object_t *top, const char *key, size_t keylen)
return false;
}
- found = __DECONST (ucl_object_t *, ucl_object_find_keyl (top, key, keylen));
+ found = __DECONST (ucl_object_t *, ucl_object_lookup_len (top, key, keylen));
if (found == NULL) {
return false;
@@ -2153,7 +2244,7 @@ ucl_object_pop_keyl (ucl_object_t *top, const char *key, size_t keylen)
if (top == NULL || key == NULL) {
return false;
}
- found = ucl_object_find_keyl (top, key, keylen);
+ found = ucl_object_lookup_len (top, key, keylen);
if (found == NULL) {
return NULL;
@@ -2226,7 +2317,7 @@ ucl_object_merge (ucl_object_t *top, ucl_object_t *elt, bool copy)
}
const ucl_object_t *
-ucl_object_find_keyl (const ucl_object_t *obj, const char *key, size_t klen)
+ucl_object_lookup_len (const ucl_object_t *obj, const char *key, size_t klen)
{
const ucl_object_t *ret;
ucl_object_t srch;
@@ -2243,17 +2334,17 @@ ucl_object_find_keyl (const ucl_object_t *obj, const char *key, size_t klen)
}
const ucl_object_t *
-ucl_object_find_key (const ucl_object_t *obj, const char *key)
+ucl_object_lookup (const ucl_object_t *obj, const char *key)
{
if (key == NULL) {
return NULL;
}
- return ucl_object_find_keyl (obj, key, strlen (key));
+ return ucl_object_lookup_len (obj, key, strlen (key));
}
const ucl_object_t*
-ucl_object_find_any_key (const ucl_object_t *obj,
+ucl_object_lookup_any (const ucl_object_t *obj,
const char *key, ...)
{
va_list ap;
@@ -2264,7 +2355,7 @@ ucl_object_find_any_key (const ucl_object_t *obj,
return NULL;
}
- ret = ucl_object_find_keyl (obj, key, strlen (key));
+ ret = ucl_object_lookup_len (obj, key, strlen (key));
if (ret == NULL) {
va_start (ap, key);
@@ -2276,7 +2367,7 @@ ucl_object_find_any_key (const ucl_object_t *obj,
break;
}
else {
- ret = ucl_object_find_keyl (obj, nk, strlen (nk));
+ ret = ucl_object_lookup_len (obj, nk, strlen (nk));
}
}
@@ -2287,7 +2378,7 @@ ucl_object_find_any_key (const ucl_object_t *obj,
}
const ucl_object_t*
-ucl_iterate_object (const ucl_object_t *obj, ucl_object_iter_t *iter, bool expand_values)
+ucl_object_iterate (const ucl_object_t *obj, ucl_object_iter_t *iter, bool expand_values)
{
const ucl_object_t *elt = NULL;
@@ -2394,7 +2485,7 @@ ucl_object_iterate_safe (ucl_object_iter_t it, bool expand_values)
}
if (rit->impl_it->type == UCL_OBJECT || rit->impl_it->type == UCL_ARRAY) {
- ret = ucl_iterate_object (rit->impl_it, &rit->expl_it, true);
+ ret = ucl_object_iterate (rit->impl_it, &rit->expl_it, true);
if (ret == NULL) {
/* Need to switch to another implicit object in chain */
@@ -2429,13 +2520,13 @@ ucl_object_iterate_free (ucl_object_iter_t it)
}
const ucl_object_t *
-ucl_lookup_path (const ucl_object_t *top, const char *path_in) {
- return ucl_lookup_path_char (top, path_in, '.');
+ucl_object_lookup_path (const ucl_object_t *top, const char *path_in) {
+ return ucl_object_lookup_path_char (top, path_in, '.');
}
const ucl_object_t *
-ucl_lookup_path_char (const ucl_object_t *top, const char *path_in, const char sep) {
+ucl_object_lookup_path_char (const ucl_object_t *top, const char *path_in, const char sep) {
const ucl_object_t *o = NULL, *found;
const char *p, *c;
char *err_str;
@@ -2468,7 +2559,7 @@ ucl_lookup_path_char (const ucl_object_t *top, const char *path_in, const char s
o = ucl_array_find_index (top, index);
break;
default:
- o = ucl_object_find_keyl (top, c, p - c);
+ o = ucl_object_lookup_len (top, c, p - c);
break;
}
if (o == NULL) {
@@ -2527,7 +2618,7 @@ ucl_object_new_full (ucl_type_t type, unsigned priority)
}
}
else {
- new = ucl_object_new_userdata (NULL, NULL);
+ new = ucl_object_new_userdata (NULL, NULL, NULL);
ucl_object_set_priority (new, priority);
}
@@ -2535,7 +2626,9 @@ ucl_object_new_full (ucl_type_t type, unsigned priority)
}
ucl_object_t*
-ucl_object_new_userdata (ucl_userdata_dtor dtor, ucl_userdata_emitter emitter)
+ucl_object_new_userdata (ucl_userdata_dtor dtor,
+ ucl_userdata_emitter emitter,
+ void *ptr)
{
struct ucl_object_userdata *new;
size_t nsize = sizeof (*new);
@@ -2549,6 +2642,7 @@ ucl_object_new_userdata (ucl_userdata_dtor dtor, ucl_userdata_emitter emitter)
new->obj.prev = (ucl_object_t *)new;
new->dtor = dtor;
new->emitter = emitter;
+ new->obj.value.ud = ptr;
}
return (ucl_object_t *)new;
@@ -2691,14 +2785,16 @@ ucl_array_merge (ucl_object_t *top, ucl_object_t *elt, bool copy)
UCL_ARRAY_GET (v1, top);
UCL_ARRAY_GET (v2, cp);
- kv_concat (ucl_object_t *, *v1, *v2);
+ if (v1 && v2) {
+ kv_concat (ucl_object_t *, *v1, *v2);
- for (i = v2->n; i < v1->n; i ++) {
- obj = &kv_A (*v1, i);
- if (*obj == NULL) {
- continue;
+ for (i = v2->n; i < v1->n; i ++) {
+ obj = &kv_A (*v1, i);
+ if (*obj == NULL) {
+ continue;
+ }
+ top->len ++;
}
- top->len ++;
}
return true;
@@ -3087,7 +3183,7 @@ ucl_object_copy_internal (const ucl_object_t *other, bool allow_array)
/* reset old value */
memset (&new->value, 0, sizeof (new->value));
- while ((cur = ucl_iterate_object (other, &it, true)) != NULL) {
+ while ((cur = ucl_object_iterate (other, &it, true)) != NULL) {
if (other->type == UCL_ARRAY) {
ucl_array_append (new, ucl_object_copy_internal (cur, false));
}
@@ -3193,8 +3289,8 @@ ucl_object_compare (const ucl_object_t *o1, const ucl_object_t *o2)
break;
case UCL_OBJECT:
if (o1->len == o2->len && o1->len > 0) {
- while ((it1 = ucl_iterate_object (o1, &iter, true)) != NULL) {
- it2 = ucl_object_find_key (o2, ucl_object_key (it1));
+ while ((it1 = ucl_object_iterate (o1, &iter, true)) != NULL) {
+ it2 = ucl_object_lookup (o2, ucl_object_key (it1));
if (it2 == NULL) {
ret = 1;
break;
@@ -3217,6 +3313,13 @@ ucl_object_compare (const ucl_object_t *o1, const ucl_object_t *o2)
return ret;
}
+int
+ucl_object_compare_qsort (const ucl_object_t **o1,
+ const ucl_object_t **o2)
+{
+ return ucl_object_compare (*o1, *o2);
+}
+
void
ucl_object_array_sort (ucl_object_t *ar,
int (*cmp)(const ucl_object_t **o1, const ucl_object_t **o2))
@@ -3255,3 +3358,131 @@ 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;
+}
+
+const ucl_object_t *
+ucl_parser_get_comments (struct ucl_parser *parser)
+{
+ if (parser && parser->comments) {
+ return parser->comments;
+ }
+
+ return NULL;
+}
+
+const ucl_object_t *
+ucl_comments_find (const ucl_object_t *comments,
+ const ucl_object_t *srch)
+{
+ if (comments && srch) {
+ return ucl_object_lookup_len (comments, (const char *)&srch,
+ sizeof (void *));
+ }
+
+ return NULL;
+}
+
+bool
+ucl_comments_move (ucl_object_t *comments,
+ const ucl_object_t *from, const ucl_object_t *to)
+{
+ const ucl_object_t *found;
+ ucl_object_t *obj;
+
+ if (comments && from && to) {
+ found = ucl_object_lookup_len (comments,
+ (const char *)&from, sizeof (void *));
+
+ if (found) {
+ /* Replace key */
+ obj = ucl_object_ref (found);
+ ucl_object_delete_keyl (comments, (const char *)&from,
+ sizeof (void *));
+ ucl_object_insert_key (comments, obj, (const char *)&to,
+ sizeof (void *), true);
+
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void
+ucl_comments_add (ucl_object_t *comments, const ucl_object_t *obj,
+ const char *comment)
+{
+ if (comments && obj && comment) {
+ ucl_object_insert_key (comments, ucl_object_fromstring (comment),
+ (const char *)&obj, sizeof (void *), true);
+ }
+}