27a28
> #ifdef HAVE_LIBGEN_H
28a30
> #endif
37a40,46
> #ifdef CURL_FOUND
> #include <curl/curl.h>
> #endif
> #ifdef HAVE_FETCH_H
> #include <fetch.h>
> #endif
>
40a50
> #ifndef PROT_READ
41a52,53
> #endif
> #ifndef PROT_WRITE
42a55,56
> #endif
> #ifndef PROT_READWRITE
43a58,59
> #endif
> #ifndef MAP_SHARED
44a61,62
> #endif
> #ifndef MAP_PRIVATE
45a64,65
> #endif
> #ifndef MAP_FAILED
46a67
> #endif
48c69
< static void *mmap(char *addr, size_t length, int prot, int access, int fd, off_t offset)
---
> static void *ucl_mmap(char *addr, size_t length, int prot, int access, int fd, off_t offset)
86c107
< static int munmap(void *map,size_t length)
---
> static int ucl_munmap(void *map,size_t length)
94c115
< static char* realpath(const char *path, char *resolved_path) {
---
> static char* ucl_realpath(const char *path, char *resolved_path) {
104a126,129
> #else
> #define ucl_mmap mmap
> #define ucl_munmap munmap
> #define ucl_realpath realpath
160a186,188
> if (len <= 1) {
> return len;
> }
191,194c219,233
< for (i = 0; i < 4; i++) {
< uval <<= 4;
< if (isdigit (h[i])) {
< uval += h[i] - '0';
---
> if (len > 3) {
> for (i = 0; i < 4; i++) {
> uval <<= 4;
> if (isdigit (h[i])) {
> uval += h[i] - '0';
> }
> else if (h[i] >= 'a' && h[i] <= 'f') {
> uval += h[i] - 'a' + 10;
> }
> else if (h[i] >= 'A' && h[i] <= 'F') {
> uval += h[i] - 'A' + 10;
> }
> else {
> break;
> }
196,197c235,240
< else if (h[i] >= 'a' && h[i] <= 'f') {
< uval += h[i] - 'a' + 10;
---
> h += 3;
> len -= 3;
> /* Encode */
> if(uval < 0x80) {
> t[0] = (char)uval;
> t ++;
199,200c242,245
< else if (h[i] >= 'A' && h[i] <= 'F') {
< uval += h[i] - 'A' + 10;
---
> else if(uval < 0x800) {
> t[0] = 0xC0 + ((uval & 0x7C0) >> 6);
> t[1] = 0x80 + ((uval & 0x03F));
> t += 2;
201a247,262
> else if(uval < 0x10000) {
> t[0] = 0xE0 + ((uval & 0xF000) >> 12);
> t[1] = 0x80 + ((uval & 0x0FC0) >> 6);
> t[2] = 0x80 + ((uval & 0x003F));
> t += 3;
> }
> else if(uval <= 0x10FFFF) {
> t[0] = 0xF0 + ((uval & 0x1C0000) >> 18);
> t[1] = 0x80 + ((uval & 0x03F000) >> 12);
> t[2] = 0x80 + ((uval & 0x000FC0) >> 6);
> t[3] = 0x80 + ((uval & 0x00003F));
> t += 4;
> }
> else {
> *t++ = '?';
> }
203,227d263
< h += 3;
< len -= 3;
< /* Encode */
< if(uval < 0x80) {
< t[0] = (char)uval;
< t ++;
< }
< else if(uval < 0x800) {
< t[0] = 0xC0 + ((uval & 0x7C0) >> 6);
< t[1] = 0x80 + ((uval & 0x03F));
< t += 2;
< }
< else if(uval < 0x10000) {
< t[0] = 0xE0 + ((uval & 0xF000) >> 12);
< t[1] = 0x80 + ((uval & 0x0FC0) >> 6);
< t[2] = 0x80 + ((uval & 0x003F));
< t += 3;
< }
< else if(uval <= 0x10FFFF) {
< t[0] = 0xF0 + ((uval & 0x1C0000) >> 18);
< t[1] = 0x80 + ((uval & 0x03F000) >> 12);
< t[2] = 0x80 + ((uval & 0x000FC0) >> 6);
< t[3] = 0x80 + ((uval & 0x00003F));
< t += 4;
< }
229c265
< *t++ = '?';
---
> *t++ = 'u';
251a288,290
> if (obj == NULL) {
> return NULL;
> }
267a307,309
> if (obj == NULL) {
> return NULL;
> }
306a349,352
> if (parser == NULL) {
> return;
> }
>
340a387,390
> if (parser == NULL) {
> return NULL;
> }
>
362a413,416
> if (nkey == NULL) {
> ucl_create_err (&parser->err, "cannot allocate memory for key");
> return false;
> }
530c584
< if ((*buf = mmap (NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) {
---
> if ((*buf = ucl_mmap (NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) {
632c686
< munmap (sigbuf, siglen);
---
> ucl_munmap (sigbuf, siglen);
637c691
< munmap (sigbuf, siglen);
---
> ucl_munmap (sigbuf, siglen);
681c735
< if (realpath (filebuf, realbuf) == NULL) {
---
> if (ucl_realpath (filebuf, realbuf) == NULL) {
709c763
< munmap (sigbuf, siglen);
---
> ucl_munmap (sigbuf, siglen);
714c768
< munmap (sigbuf, siglen);
---
> ucl_munmap (sigbuf, siglen);
737c791
< munmap (buf, buflen);
---
> ucl_munmap (buf, buflen);
806c860
< if (realpath (filename, realbuf) == NULL) {
---
> if (ucl_realpath (filename, realbuf) == NULL) {
837c891
< if (realpath (filename, realbuf) == NULL) {
---
> if (ucl_realpath (filename, realbuf) == NULL) {
852c906
< munmap (buf, len);
---
> ucl_munmap (buf, len);
1017c1071,1072
< flags & UCL_STRING_PARSE_BYTES);
---
> flags & UCL_STRING_PARSE_BYTES,
> flags & UCL_STRING_PARSE_TIME);
1023c1078,1079
< flags & UCL_STRING_PARSE_BYTES);
---
> flags & UCL_STRING_PARSE_BYTES,
> flags & UCL_STRING_PARSE_TIME);
1085a1142
> top->len ++;
1131a1189,1192
> if (top == NULL || key == NULL) {
> return false;
> }
>
1134c1195
< if (found == NULL)
---
> if (found == NULL) {
1135a1197
> }
1149a1212,1236
> ucl_object_t*
> ucl_object_pop_keyl (ucl_object_t *top, const char *key, size_t keylen)
> {
> ucl_object_t *found;
>
> if (top == NULL || key == NULL) {
> return false;
> }
> found = ucl_object_find_keyl(top, key, keylen);
>
> if (found == NULL) {
> return NULL;
> }
> ucl_hash_delete(top->value.ov, found);
> top->len --;
>
> return found;
> }
>
> ucl_object_t*
> ucl_object_pop_key (ucl_object_t *top, const char *key)
> {
> return ucl_object_pop_keyl (top, key, 0);
> }
>
1209a1297,1300
> if (obj == NULL || iter == NULL) {
> return NULL;
> }
>
1249a1341,1835
>
>
> 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_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_object_t*
> ucl_object_fromstring (const char *str)
> {
> return ucl_object_fromstring_common (str, 0, UCL_STRING_ESCAPE);
> }
>
> ucl_object_t *
> ucl_object_fromlstring (const char *str, size_t len)
> {
> return ucl_object_fromstring_common (str, len, UCL_STRING_ESCAPE);
> }
>
> 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_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_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_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;
> }
>
> 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;
> }
>
> 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_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_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_object_t *
> ucl_array_pop_last (ucl_object_t *top)
> {
> return ucl_array_delete (top, ucl_array_tail (top));
> }
>
> ucl_object_t *
> ucl_array_pop_first (ucl_object_t *top)
> {
> return ucl_array_delete (top, ucl_array_head (top));
> }
>
> 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;
> }
>
> bool
> ucl_object_todouble_safe (ucl_object_t *obj, double *target)
> {
> if (obj == NULL || target == 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;
> }
>
> double
> ucl_object_todouble (ucl_object_t *obj)
> {
> double result = 0.;
>
> ucl_object_todouble_safe (obj, &result);
> return result;
> }
>
> bool
> ucl_object_toint_safe (ucl_object_t *obj, int64_t *target)
> {
> if (obj == NULL || target == 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;
> }
>
> int64_t
> ucl_object_toint (ucl_object_t *obj)
> {
> int64_t result = 0;
>
> ucl_object_toint_safe (obj, &result);
> return result;
> }
>
> bool
> ucl_object_toboolean_safe (ucl_object_t *obj, bool *target)
> {
> if (obj == NULL || target == NULL) {
> return false;
> }
> switch (obj->type) {
> case UCL_BOOLEAN:
> *target = (obj->value.iv == true);
> break;
> default:
> return false;
> }
>
> return true;
> }
>
> bool
> ucl_object_toboolean (ucl_object_t *obj)
> {
> bool result = false;
>
> ucl_object_toboolean_safe (obj, &result);
> return result;
> }
>
> bool
> ucl_object_tostring_safe (ucl_object_t *obj, const char **target)
> {
> if (obj == NULL || target == NULL) {
> return false;
> }
>
> switch (obj->type) {
> case UCL_STRING:
> *target = ucl_copy_value_trash (obj);
> break;
> default:
> return false;
> }
>
> return true;
> }
>
> const char *
> ucl_object_tostring (ucl_object_t *obj)
> {
> const char *result = NULL;
>
> ucl_object_tostring_safe (obj, &result);
> return result;
> }
>
> const char *
> ucl_object_tostring_forced (ucl_object_t *obj)
> {
> return ucl_copy_value_trash (obj);
> }
>
> bool
> ucl_object_tolstring_safe (ucl_object_t *obj, const char **target, size_t *tlen)
> {
> if (obj == NULL || target == NULL) {
> return false;
> }
> switch (obj->type) {
> case UCL_STRING:
> *target = obj->value.sv;
> if (tlen != NULL) {
> *tlen = obj->len;
> }
> break;
> default:
> return false;
> }
>
> return true;
> }
>
> 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;
> }
>
> const char *
> ucl_object_key (ucl_object_t *obj)
> {
> return ucl_copy_key_trash (obj);
> }
>
> const char *
> ucl_object_keyl (ucl_object_t *obj, size_t *len)
> {
> if (len == NULL || obj == NULL) {
> return NULL;
> }
> *len = obj->keylen;
> return obj->key;
> }
>
> ucl_object_t *
> ucl_object_ref (ucl_object_t *obj)
> {
> if (obj != NULL) {
> obj->ref ++;
> }
> return obj;
> }
>
> void
> ucl_object_unref (ucl_object_t *obj)
> {
> if (obj != NULL && --obj->ref <= 0) {
> ucl_object_free (obj);
> }
> }
>
> int
> ucl_object_compare (ucl_object_t *o1, ucl_object_t *o2)
> {
> ucl_object_t *it1, *it2;
> ucl_object_iter_t iter = NULL;
> int ret = 0;
>
> if (o1->type != o2->type) {
> return (o1->type) - (o2->type);
> }
>
> switch (o1->type) {
> case UCL_STRING:
> if (o1->len == o2->len) {
> ret = strcmp (ucl_object_tostring(o1), ucl_object_tostring(o2));
> }
> else {
> ret = o1->len - o2->len;
> }
> break;
> case UCL_FLOAT:
> case UCL_INT:
> case UCL_TIME:
> ret = ucl_object_todouble (o1) - ucl_object_todouble (o2);
> break;
> case UCL_BOOLEAN:
> ret = ucl_object_toboolean (o1) - ucl_object_toboolean (o2);
> break;
> case UCL_ARRAY:
> if (o1->len == o2->len) {
> it1 = o1->value.av;
> it2 = o2->value.av;
> /* Compare all elements in both arrays */
> while (it1 != NULL && it2 != NULL) {
> ret = ucl_object_compare (it1, it2);
> if (ret != 0) {
> break;
> }
> it1 = it1->next;
> it2 = it2->next;
> }
> }
> else {
> ret = o1->len - o2->len;
> }
> break;
> case UCL_OBJECT:
> if (o1->len == o2->len) {
> while ((it1 = ucl_iterate_object (o1, &iter, true)) != NULL) {
> it2 = ucl_object_find_key (o2, ucl_object_key (it1));
> if (it2 == NULL) {
> ret = 1;
> break;
> }
> ret = ucl_object_compare (it1, it2);
> if (ret != 0) {
> break;
> }
> }
> }
> else {
> ret = o1->len - o2->len;
> }
> break;
> default:
> ret = 0;
> break;
> }
>
> return ret;
> }
>
> void
> ucl_object_array_sort (ucl_object_t *ar,
> int (*cmp)(ucl_object_t *o1, ucl_object_t *o2))
> {
> if (cmp == NULL || ar == NULL || ar->type != UCL_ARRAY) {
> return;
> }
>
> DL_SORT (ar->value.av, cmp);
> }
> #ifdef HAVE_LIBGEN_H
28a30
> #endif
37a40,46
> #ifdef CURL_FOUND
> #include <curl/curl.h>
> #endif
> #ifdef HAVE_FETCH_H
> #include <fetch.h>
> #endif
>
40a50
> #ifndef PROT_READ
41a52,53
> #endif
> #ifndef PROT_WRITE
42a55,56
> #endif
> #ifndef PROT_READWRITE
43a58,59
> #endif
> #ifndef MAP_SHARED
44a61,62
> #endif
> #ifndef MAP_PRIVATE
45a64,65
> #endif
> #ifndef MAP_FAILED
46a67
> #endif
48c69
< static void *mmap(char *addr, size_t length, int prot, int access, int fd, off_t offset)
---
> static void *ucl_mmap(char *addr, size_t length, int prot, int access, int fd, off_t offset)
86c107
< static int munmap(void *map,size_t length)
---
> static int ucl_munmap(void *map,size_t length)
94c115
< static char* realpath(const char *path, char *resolved_path) {
---
> static char* ucl_realpath(const char *path, char *resolved_path) {
104a126,129
> #else
> #define ucl_mmap mmap
> #define ucl_munmap munmap
> #define ucl_realpath realpath
160a186,188
> if (len <= 1) {
> return len;
> }
191,194c219,233
< for (i = 0; i < 4; i++) {
< uval <<= 4;
< if (isdigit (h[i])) {
< uval += h[i] - '0';
---
> if (len > 3) {
> for (i = 0; i < 4; i++) {
> uval <<= 4;
> if (isdigit (h[i])) {
> uval += h[i] - '0';
> }
> else if (h[i] >= 'a' && h[i] <= 'f') {
> uval += h[i] - 'a' + 10;
> }
> else if (h[i] >= 'A' && h[i] <= 'F') {
> uval += h[i] - 'A' + 10;
> }
> else {
> break;
> }
196,197c235,240
< else if (h[i] >= 'a' && h[i] <= 'f') {
< uval += h[i] - 'a' + 10;
---
> h += 3;
> len -= 3;
> /* Encode */
> if(uval < 0x80) {
> t[0] = (char)uval;
> t ++;
199,200c242,245
< else if (h[i] >= 'A' && h[i] <= 'F') {
< uval += h[i] - 'A' + 10;
---
> else if(uval < 0x800) {
> t[0] = 0xC0 + ((uval & 0x7C0) >> 6);
> t[1] = 0x80 + ((uval & 0x03F));
> t += 2;
201a247,262
> else if(uval < 0x10000) {
> t[0] = 0xE0 + ((uval & 0xF000) >> 12);
> t[1] = 0x80 + ((uval & 0x0FC0) >> 6);
> t[2] = 0x80 + ((uval & 0x003F));
> t += 3;
> }
> else if(uval <= 0x10FFFF) {
> t[0] = 0xF0 + ((uval & 0x1C0000) >> 18);
> t[1] = 0x80 + ((uval & 0x03F000) >> 12);
> t[2] = 0x80 + ((uval & 0x000FC0) >> 6);
> t[3] = 0x80 + ((uval & 0x00003F));
> t += 4;
> }
> else {
> *t++ = '?';
> }
203,227d263
< h += 3;
< len -= 3;
< /* Encode */
< if(uval < 0x80) {
< t[0] = (char)uval;
< t ++;
< }
< else if(uval < 0x800) {
< t[0] = 0xC0 + ((uval & 0x7C0) >> 6);
< t[1] = 0x80 + ((uval & 0x03F));
< t += 2;
< }
< else if(uval < 0x10000) {
< t[0] = 0xE0 + ((uval & 0xF000) >> 12);
< t[1] = 0x80 + ((uval & 0x0FC0) >> 6);
< t[2] = 0x80 + ((uval & 0x003F));
< t += 3;
< }
< else if(uval <= 0x10FFFF) {
< t[0] = 0xF0 + ((uval & 0x1C0000) >> 18);
< t[1] = 0x80 + ((uval & 0x03F000) >> 12);
< t[2] = 0x80 + ((uval & 0x000FC0) >> 6);
< t[3] = 0x80 + ((uval & 0x00003F));
< t += 4;
< }
229c265
< *t++ = '?';
---
> *t++ = 'u';
251a288,290
> if (obj == NULL) {
> return NULL;
> }
267a307,309
> if (obj == NULL) {
> return NULL;
> }
306a349,352
> if (parser == NULL) {
> return;
> }
>
340a387,390
> if (parser == NULL) {
> return NULL;
> }
>
362a413,416
> if (nkey == NULL) {
> ucl_create_err (&parser->err, "cannot allocate memory for key");
> return false;
> }
530c584
< if ((*buf = mmap (NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) {
---
> if ((*buf = ucl_mmap (NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) {
632c686
< munmap (sigbuf, siglen);
---
> ucl_munmap (sigbuf, siglen);
637c691
< munmap (sigbuf, siglen);
---
> ucl_munmap (sigbuf, siglen);
681c735
< if (realpath (filebuf, realbuf) == NULL) {
---
> if (ucl_realpath (filebuf, realbuf) == NULL) {
709c763
< munmap (sigbuf, siglen);
---
> ucl_munmap (sigbuf, siglen);
714c768
< munmap (sigbuf, siglen);
---
> ucl_munmap (sigbuf, siglen);
737c791
< munmap (buf, buflen);
---
> ucl_munmap (buf, buflen);
806c860
< if (realpath (filename, realbuf) == NULL) {
---
> if (ucl_realpath (filename, realbuf) == NULL) {
837c891
< if (realpath (filename, realbuf) == NULL) {
---
> if (ucl_realpath (filename, realbuf) == NULL) {
852c906
< munmap (buf, len);
---
> ucl_munmap (buf, len);
1017c1071,1072
< flags & UCL_STRING_PARSE_BYTES);
---
> flags & UCL_STRING_PARSE_BYTES,
> flags & UCL_STRING_PARSE_TIME);
1023c1078,1079
< flags & UCL_STRING_PARSE_BYTES);
---
> flags & UCL_STRING_PARSE_BYTES,
> flags & UCL_STRING_PARSE_TIME);
1085a1142
> top->len ++;
1131a1189,1192
> if (top == NULL || key == NULL) {
> return false;
> }
>
1134c1195
< if (found == NULL)
---
> if (found == NULL) {
1135a1197
> }
1149a1212,1236
> ucl_object_t*
> ucl_object_pop_keyl (ucl_object_t *top, const char *key, size_t keylen)
> {
> ucl_object_t *found;
>
> if (top == NULL || key == NULL) {
> return false;
> }
> found = ucl_object_find_keyl(top, key, keylen);
>
> if (found == NULL) {
> return NULL;
> }
> ucl_hash_delete(top->value.ov, found);
> top->len --;
>
> return found;
> }
>
> ucl_object_t*
> ucl_object_pop_key (ucl_object_t *top, const char *key)
> {
> return ucl_object_pop_keyl (top, key, 0);
> }
>
1209a1297,1300
> if (obj == NULL || iter == NULL) {
> return NULL;
> }
>
1249a1341,1835
>
>
> 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_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_object_t*
> ucl_object_fromstring (const char *str)
> {
> return ucl_object_fromstring_common (str, 0, UCL_STRING_ESCAPE);
> }
>
> ucl_object_t *
> ucl_object_fromlstring (const char *str, size_t len)
> {
> return ucl_object_fromstring_common (str, len, UCL_STRING_ESCAPE);
> }
>
> 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_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_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_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;
> }
>
> 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;
> }
>
> 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_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_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_object_t *
> ucl_array_pop_last (ucl_object_t *top)
> {
> return ucl_array_delete (top, ucl_array_tail (top));
> }
>
> ucl_object_t *
> ucl_array_pop_first (ucl_object_t *top)
> {
> return ucl_array_delete (top, ucl_array_head (top));
> }
>
> 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;
> }
>
> bool
> ucl_object_todouble_safe (ucl_object_t *obj, double *target)
> {
> if (obj == NULL || target == 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;
> }
>
> double
> ucl_object_todouble (ucl_object_t *obj)
> {
> double result = 0.;
>
> ucl_object_todouble_safe (obj, &result);
> return result;
> }
>
> bool
> ucl_object_toint_safe (ucl_object_t *obj, int64_t *target)
> {
> if (obj == NULL || target == 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;
> }
>
> int64_t
> ucl_object_toint (ucl_object_t *obj)
> {
> int64_t result = 0;
>
> ucl_object_toint_safe (obj, &result);
> return result;
> }
>
> bool
> ucl_object_toboolean_safe (ucl_object_t *obj, bool *target)
> {
> if (obj == NULL || target == NULL) {
> return false;
> }
> switch (obj->type) {
> case UCL_BOOLEAN:
> *target = (obj->value.iv == true);
> break;
> default:
> return false;
> }
>
> return true;
> }
>
> bool
> ucl_object_toboolean (ucl_object_t *obj)
> {
> bool result = false;
>
> ucl_object_toboolean_safe (obj, &result);
> return result;
> }
>
> bool
> ucl_object_tostring_safe (ucl_object_t *obj, const char **target)
> {
> if (obj == NULL || target == NULL) {
> return false;
> }
>
> switch (obj->type) {
> case UCL_STRING:
> *target = ucl_copy_value_trash (obj);
> break;
> default:
> return false;
> }
>
> return true;
> }
>
> const char *
> ucl_object_tostring (ucl_object_t *obj)
> {
> const char *result = NULL;
>
> ucl_object_tostring_safe (obj, &result);
> return result;
> }
>
> const char *
> ucl_object_tostring_forced (ucl_object_t *obj)
> {
> return ucl_copy_value_trash (obj);
> }
>
> bool
> ucl_object_tolstring_safe (ucl_object_t *obj, const char **target, size_t *tlen)
> {
> if (obj == NULL || target == NULL) {
> return false;
> }
> switch (obj->type) {
> case UCL_STRING:
> *target = obj->value.sv;
> if (tlen != NULL) {
> *tlen = obj->len;
> }
> break;
> default:
> return false;
> }
>
> return true;
> }
>
> 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;
> }
>
> const char *
> ucl_object_key (ucl_object_t *obj)
> {
> return ucl_copy_key_trash (obj);
> }
>
> const char *
> ucl_object_keyl (ucl_object_t *obj, size_t *len)
> {
> if (len == NULL || obj == NULL) {
> return NULL;
> }
> *len = obj->keylen;
> return obj->key;
> }
>
> ucl_object_t *
> ucl_object_ref (ucl_object_t *obj)
> {
> if (obj != NULL) {
> obj->ref ++;
> }
> return obj;
> }
>
> void
> ucl_object_unref (ucl_object_t *obj)
> {
> if (obj != NULL && --obj->ref <= 0) {
> ucl_object_free (obj);
> }
> }
>
> int
> ucl_object_compare (ucl_object_t *o1, ucl_object_t *o2)
> {
> ucl_object_t *it1, *it2;
> ucl_object_iter_t iter = NULL;
> int ret = 0;
>
> if (o1->type != o2->type) {
> return (o1->type) - (o2->type);
> }
>
> switch (o1->type) {
> case UCL_STRING:
> if (o1->len == o2->len) {
> ret = strcmp (ucl_object_tostring(o1), ucl_object_tostring(o2));
> }
> else {
> ret = o1->len - o2->len;
> }
> break;
> case UCL_FLOAT:
> case UCL_INT:
> case UCL_TIME:
> ret = ucl_object_todouble (o1) - ucl_object_todouble (o2);
> break;
> case UCL_BOOLEAN:
> ret = ucl_object_toboolean (o1) - ucl_object_toboolean (o2);
> break;
> case UCL_ARRAY:
> if (o1->len == o2->len) {
> it1 = o1->value.av;
> it2 = o2->value.av;
> /* Compare all elements in both arrays */
> while (it1 != NULL && it2 != NULL) {
> ret = ucl_object_compare (it1, it2);
> if (ret != 0) {
> break;
> }
> it1 = it1->next;
> it2 = it2->next;
> }
> }
> else {
> ret = o1->len - o2->len;
> }
> break;
> case UCL_OBJECT:
> if (o1->len == o2->len) {
> while ((it1 = ucl_iterate_object (o1, &iter, true)) != NULL) {
> it2 = ucl_object_find_key (o2, ucl_object_key (it1));
> if (it2 == NULL) {
> ret = 1;
> break;
> }
> ret = ucl_object_compare (it1, it2);
> if (ret != 0) {
> break;
> }
> }
> }
> else {
> ret = o1->len - o2->len;
> }
> break;
> default:
> ret = 0;
> break;
> }
>
> return ret;
> }
>
> void
> ucl_object_array_sort (ucl_object_t *ar,
> int (*cmp)(ucl_object_t *o1, ucl_object_t *o2))
> {
> if (cmp == NULL || ar == NULL || ar->type != UCL_ARRAY) {
> return;
> }
>
> DL_SORT (ar->value.av, cmp);
> }