Deleted Added
full compact
ucl_util.c (290071) ucl_util.c (298166)
1/* Copyright (c) 2013, Vsevolod Stakhov
2 * Copyright (c) 2015 Allan Jude <allanjude@freebsd.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.

--- 13 unchanged lines hidden (view full) ---

22 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 */
24
25#include "ucl.h"
26#include "ucl_internal.h"
27#include "ucl_chartable.h"
28#include "kvec.h"
29#include <stdarg.h>
1/* Copyright (c) 2013, Vsevolod Stakhov
2 * Copyright (c) 2015 Allan Jude <allanjude@freebsd.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.

--- 13 unchanged lines hidden (view full) ---

22 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 */
24
25#include "ucl.h"
26#include "ucl_internal.h"
27#include "ucl_chartable.h"
28#include "kvec.h"
29#include <stdarg.h>
30#include <stdio.h> /* for snprintf */
30
31#ifndef _WIN32
32#include <glob.h>
33#endif
34
35#ifdef HAVE_LIBGEN_H
36#include <libgen.h> /* For dirname */
37#endif

--- 7 unchanged lines hidden (view full) ---

45#include <openssl/err.h>
46#include <openssl/sha.h>
47#include <openssl/rsa.h>
48#include <openssl/ssl.h>
49#include <openssl/evp.h>
50#endif
51
52#ifdef CURL_FOUND
31
32#ifndef _WIN32
33#include <glob.h>
34#endif
35
36#ifdef HAVE_LIBGEN_H
37#include <libgen.h> /* For dirname */
38#endif

--- 7 unchanged lines hidden (view full) ---

46#include <openssl/err.h>
47#include <openssl/sha.h>
48#include <openssl/rsa.h>
49#include <openssl/ssl.h>
50#include <openssl/evp.h>
51#endif
52
53#ifdef CURL_FOUND
54/* Seems to be broken */
55#define CURL_DISABLE_TYPECHECK 1
53#include <curl/curl.h>
54#endif
55#ifdef HAVE_FETCH_H
56#include <fetch.h>
57#endif
58
59#ifdef _WIN32
60#include <windows.h>

--- 170 unchanged lines hidden (view full) ---

231 }
232 kv_destroy (*vec);
233 UCL_FREE (sizeof (*vec), vec);
234 }
235 obj->value.av = NULL;
236 }
237 else if (obj->type == UCL_OBJECT) {
238 if (obj->value.ov != NULL) {
56#include <curl/curl.h>
57#endif
58#ifdef HAVE_FETCH_H
59#include <fetch.h>
60#endif
61
62#ifdef _WIN32
63#include <windows.h>

--- 170 unchanged lines hidden (view full) ---

234 }
235 kv_destroy (*vec);
236 UCL_FREE (sizeof (*vec), vec);
237 }
238 obj->value.av = NULL;
239 }
240 else if (obj->type == UCL_OBJECT) {
241 if (obj->value.ov != NULL) {
239 ucl_hash_destroy (obj->value.ov, (ucl_hash_free_func *)dtor);
242 ucl_hash_destroy (obj->value.ov, (ucl_hash_free_func)dtor);
240 }
241 obj->value.ov = NULL;
242 }
243 tmp = obj->next;
244 dtor (obj);
245 obj = tmp;
246
247 if (!allow_rec) {

--- 53 unchanged lines hidden (view full) ---

301 *t++ = '\\';
302 break;
303 case '"':
304 *t++ = '"';
305 break;
306 case 'u':
307 /* Unicode escape */
308 uval = 0;
243 }
244 obj->value.ov = NULL;
245 }
246 tmp = obj->next;
247 dtor (obj);
248 obj = tmp;
249
250 if (!allow_rec) {

--- 53 unchanged lines hidden (view full) ---

304 *t++ = '\\';
305 break;
306 case '"':
307 *t++ = '"';
308 break;
309 case 'u':
310 /* Unicode escape */
311 uval = 0;
312 h ++; /* u character */
313 len --;
314
309 if (len > 3) {
310 for (i = 0; i < 4; i++) {
311 uval <<= 4;
312 if (isdigit (h[i])) {
313 uval += h[i] - '0';
314 }
315 else if (h[i] >= 'a' && h[i] <= 'f') {
316 uval += h[i] - 'a' + 10;
317 }
318 else if (h[i] >= 'A' && h[i] <= 'F') {
319 uval += h[i] - 'A' + 10;
320 }
321 else {
322 break;
323 }
324 }
315 if (len > 3) {
316 for (i = 0; i < 4; i++) {
317 uval <<= 4;
318 if (isdigit (h[i])) {
319 uval += h[i] - '0';
320 }
321 else if (h[i] >= 'a' && h[i] <= 'f') {
322 uval += h[i] - 'a' + 10;
323 }
324 else if (h[i] >= 'A' && h[i] <= 'F') {
325 uval += h[i] - 'A' + 10;
326 }
327 else {
328 break;
329 }
330 }
325 h += 3;
326 len -= 3;
331
327 /* Encode */
328 if(uval < 0x80) {
329 t[0] = (char)uval;
330 t ++;
331 }
332 else if(uval < 0x800) {
333 t[0] = 0xC0 + ((uval & 0x7C0) >> 6);
334 t[1] = 0x80 + ((uval & 0x03F));
335 t += 2;
336 }
337 else if(uval < 0x10000) {
338 t[0] = 0xE0 + ((uval & 0xF000) >> 12);
339 t[1] = 0x80 + ((uval & 0x0FC0) >> 6);
340 t[2] = 0x80 + ((uval & 0x003F));
341 t += 3;
342 }
332 /* Encode */
333 if(uval < 0x80) {
334 t[0] = (char)uval;
335 t ++;
336 }
337 else if(uval < 0x800) {
338 t[0] = 0xC0 + ((uval & 0x7C0) >> 6);
339 t[1] = 0x80 + ((uval & 0x03F));
340 t += 2;
341 }
342 else if(uval < 0x10000) {
343 t[0] = 0xE0 + ((uval & 0xF000) >> 12);
344 t[1] = 0x80 + ((uval & 0x0FC0) >> 6);
345 t[2] = 0x80 + ((uval & 0x003F));
346 t += 3;
347 }
348#if 0
349 /* It's not actually supported now */
343 else if(uval <= 0x10FFFF) {
344 t[0] = 0xF0 + ((uval & 0x1C0000) >> 18);
345 t[1] = 0x80 + ((uval & 0x03F000) >> 12);
346 t[2] = 0x80 + ((uval & 0x000FC0) >> 6);
347 t[3] = 0x80 + ((uval & 0x00003F));
348 t += 4;
349 }
350 else if(uval <= 0x10FFFF) {
351 t[0] = 0xF0 + ((uval & 0x1C0000) >> 18);
352 t[1] = 0x80 + ((uval & 0x03F000) >> 12);
353 t[2] = 0x80 + ((uval & 0x000FC0) >> 6);
354 t[3] = 0x80 + ((uval & 0x00003F));
355 t += 4;
356 }
357#endif
350 else {
351 *t++ = '?';
352 }
358 else {
359 *t++ = '?';
360 }
361
362 /* Consume 4 characters of source */
363 h += 4;
364 len -= 4;
365
366 if (len > 0) {
367 len --; /* for '\' character */
368 }
369 continue;
353 }
354 else {
355 *t++ = 'u';
356 }
357 break;
358 default:
359 *t++ = *h;
360 break;

--- 71 unchanged lines hidden (view full) ---

432 }
433 else {
434 /* Just emit value in json notation */
435 deconst->trash_stack[UCL_TRASH_VALUE] = ucl_object_emit_single_json (obj);
436 deconst->len = strlen (obj->trash_stack[UCL_TRASH_VALUE]);
437 }
438 deconst->flags |= UCL_OBJECT_ALLOCATED_VALUE;
439 }
370 }
371 else {
372 *t++ = 'u';
373 }
374 break;
375 default:
376 *t++ = *h;
377 break;

--- 71 unchanged lines hidden (view full) ---

449 }
450 else {
451 /* Just emit value in json notation */
452 deconst->trash_stack[UCL_TRASH_VALUE] = ucl_object_emit_single_json (obj);
453 deconst->len = strlen (obj->trash_stack[UCL_TRASH_VALUE]);
454 }
455 deconst->flags |= UCL_OBJECT_ALLOCATED_VALUE;
456 }
440
457
441 return obj->trash_stack[UCL_TRASH_VALUE];
442}
443
444ucl_object_t*
445ucl_parser_get_object (struct ucl_parser *parser)
446{
447 if (parser->state != UCL_STATE_ERROR && parser->top_obj != NULL) {
448 return ucl_object_ref (parser->top_obj);

--- 50 unchanged lines hidden (view full) ---

499 if (parser->err != NULL) {
500 utstring_free (parser->err);
501 }
502
503 if (parser->cur_file) {
504 free (parser->cur_file);
505 }
506
458 return obj->trash_stack[UCL_TRASH_VALUE];
459}
460
461ucl_object_t*
462ucl_parser_get_object (struct ucl_parser *parser)
463{
464 if (parser->state != UCL_STATE_ERROR && parser->top_obj != NULL) {
465 return ucl_object_ref (parser->top_obj);

--- 50 unchanged lines hidden (view full) ---

516 if (parser->err != NULL) {
517 utstring_free (parser->err);
518 }
519
520 if (parser->cur_file) {
521 free (parser->cur_file);
522 }
523
524 if (parser->comments) {
525 ucl_object_unref (parser->comments);
526 }
527
507 UCL_FREE (sizeof (struct ucl_parser), parser);
508}
509
510const char *
511ucl_parser_get_error(struct ucl_parser *parser)
512{
513 if (parser == NULL) {
514 return NULL;

--- 108 unchanged lines hidden (view full) ---

623/**
624 * Fetch a url and save results to the memory buffer
625 * @param url url to fetch
626 * @param len length of url
627 * @param buf target buffer
628 * @param buflen target length
629 * @return
630 */
528 UCL_FREE (sizeof (struct ucl_parser), parser);
529}
530
531const char *
532ucl_parser_get_error(struct ucl_parser *parser)
533{
534 if (parser == NULL) {
535 return NULL;

--- 108 unchanged lines hidden (view full) ---

644/**
645 * Fetch a url and save results to the memory buffer
646 * @param url url to fetch
647 * @param len length of url
648 * @param buf target buffer
649 * @param buflen target length
650 * @return
651 */
631static bool
652bool
632ucl_fetch_url (const unsigned char *url, unsigned char **buf, size_t *buflen,
633 UT_string **err, bool must_exist)
634{
635
636#ifdef HAVE_FETCH_H
637 struct url *fetch_url;
638 struct url_stat us;
639 FILE *in;

--- 45 unchanged lines hidden (view full) ---

685 }
686 if ((r = curl_easy_setopt (curl, CURLOPT_URL, url)) != CURLE_OK) {
687 ucl_create_err (err, "invalid URL %s: %s",
688 url, curl_easy_strerror (r));
689 curl_easy_cleanup (curl);
690 return false;
691 }
692 curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, ucl_curl_write_callback);
653ucl_fetch_url (const unsigned char *url, unsigned char **buf, size_t *buflen,
654 UT_string **err, bool must_exist)
655{
656
657#ifdef HAVE_FETCH_H
658 struct url *fetch_url;
659 struct url_stat us;
660 FILE *in;

--- 45 unchanged lines hidden (view full) ---

706 }
707 if ((r = curl_easy_setopt (curl, CURLOPT_URL, url)) != CURLE_OK) {
708 ucl_create_err (err, "invalid URL %s: %s",
709 url, curl_easy_strerror (r));
710 curl_easy_cleanup (curl);
711 return false;
712 }
713 curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, ucl_curl_write_callback);
693 cbdata.buf = *buf;
694 cbdata.buflen = *buflen;
714 cbdata.buf = NULL;
715 cbdata.buflen = 0;
695 curl_easy_setopt (curl, CURLOPT_WRITEDATA, &cbdata);
696
697 if ((r = curl_easy_perform (curl)) != CURLE_OK) {
698 if (!must_exist) {
699 ucl_create_err (err, "error fetching URL %s: %s",
700 url, curl_easy_strerror (r));
701 }
702 curl_easy_cleanup (curl);

--- 15 unchanged lines hidden (view full) ---

718/**
719 * Fetch a file and save results to the memory buffer
720 * @param filename filename to fetch
721 * @param len length of filename
722 * @param buf target buffer
723 * @param buflen target length
724 * @return
725 */
716 curl_easy_setopt (curl, CURLOPT_WRITEDATA, &cbdata);
717
718 if ((r = curl_easy_perform (curl)) != CURLE_OK) {
719 if (!must_exist) {
720 ucl_create_err (err, "error fetching URL %s: %s",
721 url, curl_easy_strerror (r));
722 }
723 curl_easy_cleanup (curl);

--- 15 unchanged lines hidden (view full) ---

739/**
740 * Fetch a file and save results to the memory buffer
741 * @param filename filename to fetch
742 * @param len length of filename
743 * @param buf target buffer
744 * @param buflen target length
745 * @return
746 */
726static bool
747bool
727ucl_fetch_file (const unsigned char *filename, unsigned char **buf, size_t *buflen,
728 UT_string **err, bool must_exist)
729{
730 int fd;
731 struct stat st;
732
733 if (stat (filename, &st) == -1 || !S_ISREG (st.st_mode)) {
734 if (must_exist) {
735 ucl_create_err (err, "cannot stat file %s: %s",
736 filename, strerror (errno));
737 }
738 return false;
739 }
740 if (st.st_size == 0) {
741 /* Do not map empty files */
748ucl_fetch_file (const unsigned char *filename, unsigned char **buf, size_t *buflen,
749 UT_string **err, bool must_exist)
750{
751 int fd;
752 struct stat st;
753
754 if (stat (filename, &st) == -1 || !S_ISREG (st.st_mode)) {
755 if (must_exist) {
756 ucl_create_err (err, "cannot stat file %s: %s",
757 filename, strerror (errno));
758 }
759 return false;
760 }
761 if (st.st_size == 0) {
762 /* Do not map empty files */
742 *buf = "";
763 *buf = NULL;
743 *buflen = 0;
744 }
745 else {
746 if ((fd = open (filename, O_RDONLY)) == -1) {
747 ucl_create_err (err, "cannot open file %s: %s",
748 filename, strerror (errno));
749 return false;
750 }
751 if ((*buf = ucl_mmap (NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) {
752 close (fd);
753 ucl_create_err (err, "cannot mmap file %s: %s",
754 filename, strerror (errno));
764 *buflen = 0;
765 }
766 else {
767 if ((fd = open (filename, O_RDONLY)) == -1) {
768 ucl_create_err (err, "cannot open file %s: %s",
769 filename, strerror (errno));
770 return false;
771 }
772 if ((*buf = ucl_mmap (NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) {
773 close (fd);
774 ucl_create_err (err, "cannot mmap file %s: %s",
775 filename, strerror (errno));
776 *buf = NULL;
777
755 return false;
756 }
757 *buflen = st.st_size;
758 close (fd);
759 }
760
761 return true;
762}

--- 80 unchanged lines hidden (view full) ---

843 size_t buflen = 0;
844 struct ucl_chunk *chunk;
845 char urlbuf[PATH_MAX];
846 int prev_state;
847
848 snprintf (urlbuf, sizeof (urlbuf), "%.*s", (int)len, data);
849
850 if (!ucl_fetch_url (urlbuf, &buf, &buflen, &parser->err, params->must_exist)) {
778 return false;
779 }
780 *buflen = st.st_size;
781 close (fd);
782 }
783
784 return true;
785}

--- 80 unchanged lines hidden (view full) ---

866 size_t buflen = 0;
867 struct ucl_chunk *chunk;
868 char urlbuf[PATH_MAX];
869 int prev_state;
870
871 snprintf (urlbuf, sizeof (urlbuf), "%.*s", (int)len, data);
872
873 if (!ucl_fetch_url (urlbuf, &buf, &buflen, &parser->err, params->must_exist)) {
851 return (!params->must_exist || false);
874 return !params->must_exist;
852 }
853
854 if (params->check_signature) {
855#if (defined(HAVE_OPENSSL) && OPENSSL_VERSION_NUMBER >= 0x10000000L)
856 unsigned char *sigbuf = NULL;
857 size_t siglen = 0;
858 /* We need to check signature first */
859 snprintf (urlbuf, sizeof (urlbuf), "%.*s.sig", (int)len, data);

--- 103 unchanged lines hidden (view full) ---

963 snprintf (filebuf, sizeof (filebuf), "%s.sig", realbuf);
964 if (!ucl_fetch_file (filebuf, &sigbuf, &siglen, &parser->err, true)) {
965 return false;
966 }
967 if (!ucl_sig_check (buf, buflen, sigbuf, siglen, parser)) {
968 ucl_create_err (&parser->err, "cannot verify file %s: %s",
969 filebuf,
970 ERR_error_string (ERR_get_error (), NULL));
875 }
876
877 if (params->check_signature) {
878#if (defined(HAVE_OPENSSL) && OPENSSL_VERSION_NUMBER >= 0x10000000L)
879 unsigned char *sigbuf = NULL;
880 size_t siglen = 0;
881 /* We need to check signature first */
882 snprintf (urlbuf, sizeof (urlbuf), "%.*s.sig", (int)len, data);

--- 103 unchanged lines hidden (view full) ---

986 snprintf (filebuf, sizeof (filebuf), "%s.sig", realbuf);
987 if (!ucl_fetch_file (filebuf, &sigbuf, &siglen, &parser->err, true)) {
988 return false;
989 }
990 if (!ucl_sig_check (buf, buflen, sigbuf, siglen, parser)) {
991 ucl_create_err (&parser->err, "cannot verify file %s: %s",
992 filebuf,
993 ERR_error_string (ERR_get_error (), NULL));
971 if (siglen > 0) {
994 if (sigbuf) {
972 ucl_munmap (sigbuf, siglen);
973 }
974 return false;
975 }
995 ucl_munmap (sigbuf, siglen);
996 }
997 return false;
998 }
976 if (siglen > 0) {
999 if (sigbuf) {
977 ucl_munmap (sigbuf, siglen);
978 }
979#endif
980 }
981
982 old_curfile = parser->cur_file;
983 parser->cur_file = strdup (realbuf);
984

--- 47 unchanged lines hidden (view full) ---

1032 nest_obj->prev = nest_obj;
1033 nest_obj->next = NULL;
1034
1035 ucl_array_append (old_obj, nest_obj);
1036 }
1037 else if (old_obj == NULL) {
1038 /* Create an object with key: prefix */
1039 nest_obj = ucl_object_new_full (UCL_OBJECT, params->priority);
1000 ucl_munmap (sigbuf, siglen);
1001 }
1002#endif
1003 }
1004
1005 old_curfile = parser->cur_file;
1006 parser->cur_file = strdup (realbuf);
1007

--- 47 unchanged lines hidden (view full) ---

1055 nest_obj->prev = nest_obj;
1056 nest_obj->next = NULL;
1057
1058 ucl_array_append (old_obj, nest_obj);
1059 }
1060 else if (old_obj == NULL) {
1061 /* Create an object with key: prefix */
1062 nest_obj = ucl_object_new_full (UCL_OBJECT, params->priority);
1063
1064 if (nest_obj == NULL) {
1065 ucl_create_err (&parser->err, "cannot allocate memory for an object");
1066 if (buf) {
1067 ucl_munmap (buf, buflen);
1068 }
1069
1070 return false;
1071 }
1072
1040 nest_obj->key = params->prefix;
1041 nest_obj->keylen = strlen (params->prefix);
1042 ucl_copy_key_trash(nest_obj);
1043 nest_obj->prev = nest_obj;
1044 nest_obj->next = NULL;
1045
1046 container = ucl_hash_insert_object (container, nest_obj,
1047 parser->flags & UCL_PARSER_KEY_LOWERCASE);
1048 parser->stack->obj->len ++;
1049 }
1050 else if (strcasecmp (params->target, "array") == 0 ||
1051 ucl_object_type(old_obj) == UCL_ARRAY) {
1052 if (ucl_object_type(old_obj) == UCL_ARRAY) {
1053 /* Append to the existing array */
1054 nest_obj = ucl_object_new_full (UCL_OBJECT, params->priority);
1073 nest_obj->key = params->prefix;
1074 nest_obj->keylen = strlen (params->prefix);
1075 ucl_copy_key_trash(nest_obj);
1076 nest_obj->prev = nest_obj;
1077 nest_obj->next = NULL;
1078
1079 container = ucl_hash_insert_object (container, nest_obj,
1080 parser->flags & UCL_PARSER_KEY_LOWERCASE);
1081 parser->stack->obj->len ++;
1082 }
1083 else if (strcasecmp (params->target, "array") == 0 ||
1084 ucl_object_type(old_obj) == UCL_ARRAY) {
1085 if (ucl_object_type(old_obj) == UCL_ARRAY) {
1086 /* Append to the existing array */
1087 nest_obj = ucl_object_new_full (UCL_OBJECT, params->priority);
1088 if (nest_obj == NULL) {
1089 ucl_create_err (&parser->err, "cannot allocate memory for an object");
1090 if (buf) {
1091 ucl_munmap (buf, buflen);
1092 }
1093
1094 return false;
1095 }
1055 nest_obj->prev = nest_obj;
1056 nest_obj->next = NULL;
1057
1058 ucl_array_append (old_obj, nest_obj);
1059 }
1060 else {
1061 /* Convert the object to an array */
1062 new_obj = ucl_object_typed_new (UCL_ARRAY);
1096 nest_obj->prev = nest_obj;
1097 nest_obj->next = NULL;
1098
1099 ucl_array_append (old_obj, nest_obj);
1100 }
1101 else {
1102 /* Convert the object to an array */
1103 new_obj = ucl_object_typed_new (UCL_ARRAY);
1104 if (new_obj == NULL) {
1105 ucl_create_err (&parser->err, "cannot allocate memory for an object");
1106 if (buf) {
1107 ucl_munmap (buf, buflen);
1108 }
1109
1110 return false;
1111 }
1063 new_obj->key = old_obj->key;
1064 new_obj->keylen = old_obj->keylen;
1065 new_obj->flags |= UCL_OBJECT_MULTIVALUE;
1066 new_obj->prev = new_obj;
1067 new_obj->next = NULL;
1068
1069 nest_obj = ucl_object_new_full (UCL_OBJECT, params->priority);
1112 new_obj->key = old_obj->key;
1113 new_obj->keylen = old_obj->keylen;
1114 new_obj->flags |= UCL_OBJECT_MULTIVALUE;
1115 new_obj->prev = new_obj;
1116 new_obj->next = NULL;
1117
1118 nest_obj = ucl_object_new_full (UCL_OBJECT, params->priority);
1119 if (nest_obj == NULL) {
1120 ucl_create_err (&parser->err, "cannot allocate memory for an object");
1121 if (buf) {
1122 ucl_munmap (buf, buflen);
1123 }
1124
1125 return false;
1126 }
1070 nest_obj->prev = nest_obj;
1071 nest_obj->next = NULL;
1072
1073 ucl_array_append (new_obj, old_obj);
1074 ucl_array_append (new_obj, nest_obj);
1075 ucl_hash_replace (container, old_obj, new_obj);
1076 }
1077 }
1078 else {
1079 if (ucl_object_type (old_obj) == UCL_OBJECT) {
1080 /* Append to existing Object*/
1081 nest_obj = old_obj;
1082 }
1083 else {
1084 /* The key is not an object */
1085 ucl_create_err (&parser->err,
1086 "Conflicting type for key: %s",
1087 params->prefix);
1127 nest_obj->prev = nest_obj;
1128 nest_obj->next = NULL;
1129
1130 ucl_array_append (new_obj, old_obj);
1131 ucl_array_append (new_obj, nest_obj);
1132 ucl_hash_replace (container, old_obj, new_obj);
1133 }
1134 }
1135 else {
1136 if (ucl_object_type (old_obj) == UCL_OBJECT) {
1137 /* Append to existing Object*/
1138 nest_obj = old_obj;
1139 }
1140 else {
1141 /* The key is not an object */
1142 ucl_create_err (&parser->err,
1143 "Conflicting type for key: %s",
1144 params->prefix);
1145 if (buf) {
1146 ucl_munmap (buf, buflen);
1147 }
1148
1088 return false;
1089 }
1090 }
1091
1092 /* Put all of the content of the include inside that object */
1093 parser->stack->obj->value.ov = container;
1094
1149 return false;
1150 }
1151 }
1152
1153 /* Put all of the content of the include inside that object */
1154 parser->stack->obj->value.ov = container;
1155
1095 if (nest_obj != NULL) {
1096 st = UCL_ALLOC (sizeof (struct ucl_stack));
1097 if (st == NULL) {
1098 ucl_create_err (&parser->err, "cannot allocate memory for an object");
1099 ucl_object_unref (nest_obj);
1100 return NULL;
1156 st = UCL_ALLOC (sizeof (struct ucl_stack));
1157 if (st == NULL) {
1158 ucl_create_err (&parser->err, "cannot allocate memory for an object");
1159 ucl_object_unref (nest_obj);
1160
1161 if (buf) {
1162 ucl_munmap (buf, buflen);
1101 }
1163 }
1102 st->obj = nest_obj;
1103 st->level = parser->stack->level;
1104 LL_PREPEND (parser->stack, st);
1105 parser->cur_obj = nest_obj;
1164
1165 return false;
1106 }
1166 }
1167 st->obj = nest_obj;
1168 st->level = parser->stack->level;
1169 LL_PREPEND (parser->stack, st);
1170 parser->cur_obj = nest_obj;
1107 }
1108
1109 res = ucl_parser_add_chunk_full (parser, buf, buflen, params->priority,
1110 params->strat, params->parse_type);
1111 if (!res && !params->must_exist) {
1112 /* Free error */
1113 utstring_free (parser->err);
1114 parser->err = NULL;

--- 112 unchanged lines hidden (view full) ---

1227 return ucl_include_file_single (data, len, parser, params);
1228 }
1229 }
1230#else
1231 /* Win32 compilers do not support globbing. Therefore, for Win32,
1232 treat allow_glob/need_glob as a NOOP and just return */
1233 return ucl_include_file_single (data, len, parser, params);
1234#endif
1171 }
1172
1173 res = ucl_parser_add_chunk_full (parser, buf, buflen, params->priority,
1174 params->strat, params->parse_type);
1175 if (!res && !params->must_exist) {
1176 /* Free error */
1177 utstring_free (parser->err);
1178 parser->err = NULL;

--- 112 unchanged lines hidden (view full) ---

1291 return ucl_include_file_single (data, len, parser, params);
1292 }
1293 }
1294#else
1295 /* Win32 compilers do not support globbing. Therefore, for Win32,
1296 treat allow_glob/need_glob as a NOOP and just return */
1297 return ucl_include_file_single (data, len, parser, params);
1298#endif
1235
1299
1236 return true;
1237}
1238
1239/**
1240 * Common function to handle .*include* macros
1241 * @param data
1242 * @param len
1243 * @param args
1244 * @param parser
1245 * @param default_try
1246 * @param default_sign
1247 * @return
1248 */
1249static bool
1250ucl_include_common (const unsigned char *data, size_t len,
1251 const ucl_object_t *args, struct ucl_parser *parser,
1252 bool default_try,
1253 bool default_sign)
1254{
1300 return true;
1301}
1302
1303/**
1304 * Common function to handle .*include* macros
1305 * @param data
1306 * @param len
1307 * @param args
1308 * @param parser
1309 * @param default_try
1310 * @param default_sign
1311 * @return
1312 */
1313static bool
1314ucl_include_common (const unsigned char *data, size_t len,
1315 const ucl_object_t *args, struct ucl_parser *parser,
1316 bool default_try,
1317 bool default_sign)
1318{
1255 bool allow_url, search;
1319 bool allow_url = false, search = false;
1256 const char *duplicate;
1257 const ucl_object_t *param;
1258 ucl_object_iter_t it = NULL, ip = NULL;
1259 char ipath[PATH_MAX];
1260 struct ucl_include_params params;
1261
1262 /* Default values */
1263 params.soft_fail = default_try;
1264 params.allow_glob = false;
1265 params.check_signature = default_sign;
1266 params.use_prefix = false;
1267 params.target = "object";
1268 params.prefix = NULL;
1269 params.priority = 0;
1270 params.parse_type = UCL_PARSE_UCL;
1271 params.strat = UCL_DUPLICATE_APPEND;
1272 params.must_exist = !default_try;
1273
1320 const char *duplicate;
1321 const ucl_object_t *param;
1322 ucl_object_iter_t it = NULL, ip = NULL;
1323 char ipath[PATH_MAX];
1324 struct ucl_include_params params;
1325
1326 /* Default values */
1327 params.soft_fail = default_try;
1328 params.allow_glob = false;
1329 params.check_signature = default_sign;
1330 params.use_prefix = false;
1331 params.target = "object";
1332 params.prefix = NULL;
1333 params.priority = 0;
1334 params.parse_type = UCL_PARSE_UCL;
1335 params.strat = UCL_DUPLICATE_APPEND;
1336 params.must_exist = !default_try;
1337
1274 search = false;
1275
1276 /* Process arguments */
1277 if (args != NULL && args->type == UCL_OBJECT) {
1338 /* Process arguments */
1339 if (args != NULL && args->type == UCL_OBJECT) {
1278 while ((param = ucl_iterate_object (args, &it, true)) != NULL) {
1340 while ((param = ucl_object_iterate (args, &it, true)) != NULL) {
1279 if (param->type == UCL_BOOLEAN) {
1280 if (strncmp (param->key, "try", param->keylen) == 0) {
1281 params.must_exist = !ucl_object_toboolean (param);
1282 }
1283 else if (strncmp (param->key, "sign", param->keylen) == 0) {
1284 params.check_signature = ucl_object_toboolean (param);
1285 }
1286 else if (strncmp (param->key, "glob", param->keylen) == 0) {

--- 158 unchanged lines hidden (view full) ---

1445 ucl_object_iter_t it = NULL;
1446
1447 if (parser == NULL) {
1448 return false;
1449 }
1450
1451 /* Process arguments */
1452 if (args != NULL && args->type == UCL_OBJECT) {
1341 if (param->type == UCL_BOOLEAN) {
1342 if (strncmp (param->key, "try", param->keylen) == 0) {
1343 params.must_exist = !ucl_object_toboolean (param);
1344 }
1345 else if (strncmp (param->key, "sign", param->keylen) == 0) {
1346 params.check_signature = ucl_object_toboolean (param);
1347 }
1348 else if (strncmp (param->key, "glob", param->keylen) == 0) {

--- 158 unchanged lines hidden (view full) ---

1507 ucl_object_iter_t it = NULL;
1508
1509 if (parser == NULL) {
1510 return false;
1511 }
1512
1513 /* Process arguments */
1514 if (args != NULL && args->type == UCL_OBJECT) {
1453 while ((param = ucl_iterate_object (args, &it, true)) != NULL) {
1515 while ((param = ucl_object_iterate (args, &it, true)) != NULL) {
1454 if (param->type == UCL_INT) {
1455 if (strncmp (param->key, "priority", param->keylen) == 0) {
1456 priority = ucl_object_toint (param);
1457 found = true;
1458 }
1459 }
1460 }
1461 }

--- 39 unchanged lines hidden (view full) ---

1501 ucl_object_iter_t it = NULL;
1502 bool try_load, multiline, test;
1503 const char *target, *prefix;
1504 char *load_file, *tmp;
1505 unsigned char *buf;
1506 size_t buflen;
1507 unsigned priority;
1508 int64_t iv;
1516 if (param->type == UCL_INT) {
1517 if (strncmp (param->key, "priority", param->keylen) == 0) {
1518 priority = ucl_object_toint (param);
1519 found = true;
1520 }
1521 }
1522 }
1523 }

--- 39 unchanged lines hidden (view full) ---

1563 ucl_object_iter_t it = NULL;
1564 bool try_load, multiline, test;
1565 const char *target, *prefix;
1566 char *load_file, *tmp;
1567 unsigned char *buf;
1568 size_t buflen;
1569 unsigned priority;
1570 int64_t iv;
1509 ucl_hash_t *container = NULL;
1571 ucl_object_t *container = NULL;
1510 enum ucl_string_flags flags;
1511
1512 /* Default values */
1513 try_load = false;
1514 multiline = false;
1515 test = false;
1516 target = "string";
1517 prefix = NULL;

--- 6 unchanged lines hidden (view full) ---

1524 flags = 0;
1525
1526 if (parser == NULL) {
1527 return false;
1528 }
1529
1530 /* Process arguments */
1531 if (args != NULL && args->type == UCL_OBJECT) {
1572 enum ucl_string_flags flags;
1573
1574 /* Default values */
1575 try_load = false;
1576 multiline = false;
1577 test = false;
1578 target = "string";
1579 prefix = NULL;

--- 6 unchanged lines hidden (view full) ---

1586 flags = 0;
1587
1588 if (parser == NULL) {
1589 return false;
1590 }
1591
1592 /* Process arguments */
1593 if (args != NULL && args->type == UCL_OBJECT) {
1532 while ((param = ucl_iterate_object (args, &it, true)) != NULL) {
1594 while ((param = ucl_object_iterate (args, &it, true)) != NULL) {
1533 if (param->type == UCL_BOOLEAN) {
1534 if (strncmp (param->key, "try", param->keylen) == 0) {
1535 try_load = ucl_object_toboolean (param);
1536 }
1537 else if (strncmp (param->key, "multiline", param->keylen) == 0) {
1538 multiline = ucl_object_toboolean (param);
1539 }
1540 else if (strncmp (param->key, "escape", param->keylen) == 0) {

--- 20 unchanged lines hidden (view full) ---

1561 else if (param->type == UCL_INT) {
1562 if (strncmp (param->key, "priority", param->keylen) == 0) {
1563 priority = ucl_object_toint (param);
1564 }
1565 }
1566 }
1567 }
1568
1595 if (param->type == UCL_BOOLEAN) {
1596 if (strncmp (param->key, "try", param->keylen) == 0) {
1597 try_load = ucl_object_toboolean (param);
1598 }
1599 else if (strncmp (param->key, "multiline", param->keylen) == 0) {
1600 multiline = ucl_object_toboolean (param);
1601 }
1602 else if (strncmp (param->key, "escape", param->keylen) == 0) {

--- 20 unchanged lines hidden (view full) ---

1623 else if (param->type == UCL_INT) {
1624 if (strncmp (param->key, "priority", param->keylen) == 0) {
1625 priority = ucl_object_toint (param);
1626 }
1627 }
1628 }
1629 }
1630
1569 if (prefix == NULL || strlen(prefix) == 0) {
1631 if (prefix == NULL || strlen (prefix) == 0) {
1570 ucl_create_err (&parser->err, "No Key specified in load macro");
1571 return false;
1572 }
1573
1574 if (len > 0) {
1632 ucl_create_err (&parser->err, "No Key specified in load macro");
1633 return false;
1634 }
1635
1636 if (len > 0) {
1575 asprintf (&load_file, "%.*s", (int)len, data);
1576 if (!ucl_fetch_file (load_file, &buf, &buflen, &parser->err, !try_load)) {
1637 load_file = malloc (len + 1);
1638 if (!load_file) {
1639 ucl_create_err (&parser->err, "cannot allocate memory for suffix");
1640
1641 return false;
1642 }
1643
1644 snprintf (load_file, len + 1, "%.*s", (int)len, data);
1645
1646 if (!ucl_fetch_file (load_file, &buf, &buflen, &parser->err,
1647 !try_load)) {
1648 free (load_file);
1649
1577 return (try_load || false);
1578 }
1579
1650 return (try_load || false);
1651 }
1652
1580 container = parser->stack->obj->value.ov;
1581 old_obj = __DECONST (ucl_object_t *, ucl_hash_search (container, prefix, strlen (prefix)));
1653 free (load_file);
1654 container = parser->stack->obj;
1655 old_obj = __DECONST (ucl_object_t *, ucl_object_lookup (container,
1656 prefix));
1657
1582 if (old_obj != NULL) {
1583 ucl_create_err (&parser->err, "Key %s already exists", prefix);
1658 if (old_obj != NULL) {
1659 ucl_create_err (&parser->err, "Key %s already exists", prefix);
1660 if (buf) {
1661 ucl_munmap (buf, buflen);
1662 }
1663
1584 return false;
1585 }
1586
1587 if (strcasecmp (target, "string") == 0) {
1588 obj = ucl_object_fromstring_common (buf, buflen, flags);
1589 ucl_copy_value_trash (obj);
1590 if (multiline) {
1591 obj->flags |= UCL_OBJECT_MULTILINE;
1592 }
1593 }
1594 else if (strcasecmp (target, "int") == 0) {
1664 return false;
1665 }
1666
1667 if (strcasecmp (target, "string") == 0) {
1668 obj = ucl_object_fromstring_common (buf, buflen, flags);
1669 ucl_copy_value_trash (obj);
1670 if (multiline) {
1671 obj->flags |= UCL_OBJECT_MULTILINE;
1672 }
1673 }
1674 else if (strcasecmp (target, "int") == 0) {
1595 asprintf(&tmp, "%.*s", (int)buflen, buf);
1596 iv = strtoll(tmp, NULL, 10);
1597 obj = ucl_object_fromint(iv);
1675 tmp = malloc (buflen + 1);
1676
1677 if (tmp == NULL) {
1678 ucl_create_err (&parser->err, "Memory allocation failed");
1679 if (buf) {
1680 ucl_munmap (buf, buflen);
1681 }
1682
1683 return false;
1684 }
1685
1686 snprintf (tmp, buflen + 1, "%.*s", (int)buflen, buf);
1687 iv = strtoll (tmp, NULL, 10);
1688 obj = ucl_object_fromint (iv);
1689 free (tmp);
1598 }
1599
1690 }
1691
1600 if (buflen > 0) {
1692 if (buf) {
1601 ucl_munmap (buf, buflen);
1602 }
1603
1604 if (obj != NULL) {
1605 obj->key = prefix;
1606 obj->keylen = strlen (prefix);
1693 ucl_munmap (buf, buflen);
1694 }
1695
1696 if (obj != NULL) {
1697 obj->key = prefix;
1698 obj->keylen = strlen (prefix);
1607 ucl_copy_key_trash(obj);
1699 ucl_copy_key_trash (obj);
1608 obj->prev = obj;
1609 obj->next = NULL;
1610 ucl_object_set_priority (obj, priority);
1700 obj->prev = obj;
1701 obj->next = NULL;
1702 ucl_object_set_priority (obj, priority);
1611 container = ucl_hash_insert_object (container, obj,
1612 parser->flags & UCL_PARSER_KEY_LOWERCASE);
1613 parser->stack->obj->value.ov = container;
1703 ucl_object_insert_key (container, obj, obj->key, obj->keylen, false);
1614 }
1704 }
1705
1615 return true;
1616 }
1617
1618 ucl_create_err (&parser->err, "Unable to parse load macro");
1619 return false;
1620}
1621
1622bool
1623ucl_inherit_handler (const unsigned char *data, size_t len,
1624 const ucl_object_t *args, const ucl_object_t *ctx, void* ud)
1625{
1626 const ucl_object_t *parent, *cur;
1627 ucl_object_t *target, *copy;
1628 ucl_object_iter_t it = NULL;
1629 bool replace = false;
1630 struct ucl_parser *parser = ud;
1631
1706 return true;
1707 }
1708
1709 ucl_create_err (&parser->err, "Unable to parse load macro");
1710 return false;
1711}
1712
1713bool
1714ucl_inherit_handler (const unsigned char *data, size_t len,
1715 const ucl_object_t *args, const ucl_object_t *ctx, void* ud)
1716{
1717 const ucl_object_t *parent, *cur;
1718 ucl_object_t *target, *copy;
1719 ucl_object_iter_t it = NULL;
1720 bool replace = false;
1721 struct ucl_parser *parser = ud;
1722
1632 parent = ucl_object_find_keyl (ctx, data, len);
1723 parent = ucl_object_lookup_len (ctx, data, len);
1633
1634 /* Some sanity checks */
1635 if (parent == NULL || ucl_object_type (parent) != UCL_OBJECT) {
1636 ucl_create_err (&parser->err, "Unable to find inherited object %*.s",
1637 (int)len, data);
1638 return false;
1639 }
1640
1641 if (parser->stack == NULL || parser->stack->obj == NULL ||
1642 ucl_object_type (parser->stack->obj) != UCL_OBJECT) {
1643 ucl_create_err (&parser->err, "Invalid inherit context");
1644 return false;
1645 }
1646
1647 target = parser->stack->obj;
1648
1724
1725 /* Some sanity checks */
1726 if (parent == NULL || ucl_object_type (parent) != UCL_OBJECT) {
1727 ucl_create_err (&parser->err, "Unable to find inherited object %*.s",
1728 (int)len, data);
1729 return false;
1730 }
1731
1732 if (parser->stack == NULL || parser->stack->obj == NULL ||
1733 ucl_object_type (parser->stack->obj) != UCL_OBJECT) {
1734 ucl_create_err (&parser->err, "Invalid inherit context");
1735 return false;
1736 }
1737
1738 target = parser->stack->obj;
1739
1649 if (args && (cur = ucl_object_find_key (args, "replace")) != NULL) {
1740 if (args && (cur = ucl_object_lookup (args, "replace")) != NULL) {
1650 replace = ucl_object_toboolean (cur);
1651 }
1652
1741 replace = ucl_object_toboolean (cur);
1742 }
1743
1653 while ((cur = ucl_iterate_object (parent, &it, true))) {
1744 while ((cur = ucl_object_iterate (parent, &it, true))) {
1654 /* We do not replace existing keys */
1745 /* We do not replace existing keys */
1655 if (!replace && ucl_object_find_keyl (target, cur->key, cur->keylen)) {
1746 if (!replace && ucl_object_lookup_len (target, cur->key, cur->keylen)) {
1656 continue;
1657 }
1658
1659 copy = ucl_object_copy (cur);
1660
1661 if (!replace) {
1662 copy->flags |= UCL_OBJECT_INHERITED;
1663 }

--- 428 unchanged lines hidden (view full) ---

2092 }
2093 else if (found->type == UCL_OBJECT && elt->type != UCL_OBJECT) {
2094 /* Insert new to old */
2095 ucl_object_insert_key_common (found, elt, elt->key,
2096 elt->keylen, copy_key, false, false);
2097 }
2098 else if (found->type == UCL_OBJECT && elt->type == UCL_OBJECT) {
2099 /* Mix two hashes */
1747 continue;
1748 }
1749
1750 copy = ucl_object_copy (cur);
1751
1752 if (!replace) {
1753 copy->flags |= UCL_OBJECT_INHERITED;
1754 }

--- 428 unchanged lines hidden (view full) ---

2183 }
2184 else if (found->type == UCL_OBJECT && elt->type != UCL_OBJECT) {
2185 /* Insert new to old */
2186 ucl_object_insert_key_common (found, elt, elt->key,
2187 elt->keylen, copy_key, false, false);
2188 }
2189 else if (found->type == UCL_OBJECT && elt->type == UCL_OBJECT) {
2190 /* Mix two hashes */
2100 while ((cur = ucl_iterate_object (elt, &it, true)) != NULL) {
2191 while ((cur = ucl_object_iterate (elt, &it, true)) != NULL) {
2101 tmp = ucl_object_ref (cur);
2102 ucl_object_insert_key_common (found, tmp, cur->key,
2103 cur->keylen, copy_key, false, false);
2104 }
2105 ucl_object_unref (elt);
2106 }
2107 else {
2108 /* Just make a list of scalars */

--- 12 unchanged lines hidden (view full) ---

2121ucl_object_delete_keyl (ucl_object_t *top, const char *key, size_t keylen)
2122{
2123 ucl_object_t *found;
2124
2125 if (top == NULL || key == NULL) {
2126 return false;
2127 }
2128
2192 tmp = ucl_object_ref (cur);
2193 ucl_object_insert_key_common (found, tmp, cur->key,
2194 cur->keylen, copy_key, false, false);
2195 }
2196 ucl_object_unref (elt);
2197 }
2198 else {
2199 /* Just make a list of scalars */

--- 12 unchanged lines hidden (view full) ---

2212ucl_object_delete_keyl (ucl_object_t *top, const char *key, size_t keylen)
2213{
2214 ucl_object_t *found;
2215
2216 if (top == NULL || key == NULL) {
2217 return false;
2218 }
2219
2129 found = __DECONST (ucl_object_t *, ucl_object_find_keyl (top, key, keylen));
2220 found = __DECONST (ucl_object_t *, ucl_object_lookup_len (top, key, keylen));
2130
2131 if (found == NULL) {
2132 return false;
2133 }
2134
2135 ucl_hash_delete (top->value.ov, found);
2136 ucl_object_unref (found);
2137 top->len --;

--- 10 unchanged lines hidden (view full) ---

2148ucl_object_t*
2149ucl_object_pop_keyl (ucl_object_t *top, const char *key, size_t keylen)
2150{
2151 const ucl_object_t *found;
2152
2153 if (top == NULL || key == NULL) {
2154 return false;
2155 }
2221
2222 if (found == NULL) {
2223 return false;
2224 }
2225
2226 ucl_hash_delete (top->value.ov, found);
2227 ucl_object_unref (found);
2228 top->len --;

--- 10 unchanged lines hidden (view full) ---

2239ucl_object_t*
2240ucl_object_pop_keyl (ucl_object_t *top, const char *key, size_t keylen)
2241{
2242 const ucl_object_t *found;
2243
2244 if (top == NULL || key == NULL) {
2245 return false;
2246 }
2156 found = ucl_object_find_keyl (top, key, keylen);
2247 found = ucl_object_lookup_len (top, key, keylen);
2157
2158 if (found == NULL) {
2159 return NULL;
2160 }
2161 ucl_hash_delete (top->value.ov, found);
2162 top->len --;
2163
2164 return __DECONST (ucl_object_t *, found);

--- 56 unchanged lines hidden (view full) ---

2221 ucl_object_unref (found);
2222 }
2223 }
2224
2225 return true;
2226}
2227
2228const ucl_object_t *
2248
2249 if (found == NULL) {
2250 return NULL;
2251 }
2252 ucl_hash_delete (top->value.ov, found);
2253 top->len --;
2254
2255 return __DECONST (ucl_object_t *, found);

--- 56 unchanged lines hidden (view full) ---

2312 ucl_object_unref (found);
2313 }
2314 }
2315
2316 return true;
2317}
2318
2319const ucl_object_t *
2229ucl_object_find_keyl (const ucl_object_t *obj, const char *key, size_t klen)
2320ucl_object_lookup_len (const ucl_object_t *obj, const char *key, size_t klen)
2230{
2231 const ucl_object_t *ret;
2232 ucl_object_t srch;
2233
2234 if (obj == NULL || obj->type != UCL_OBJECT || key == NULL) {
2235 return NULL;
2236 }
2237
2238 srch.key = key;
2239 srch.keylen = klen;
2240 ret = ucl_hash_search_obj (obj->value.ov, &srch);
2241
2242 return ret;
2243}
2244
2245const ucl_object_t *
2321{
2322 const ucl_object_t *ret;
2323 ucl_object_t srch;
2324
2325 if (obj == NULL || obj->type != UCL_OBJECT || key == NULL) {
2326 return NULL;
2327 }
2328
2329 srch.key = key;
2330 srch.keylen = klen;
2331 ret = ucl_hash_search_obj (obj->value.ov, &srch);
2332
2333 return ret;
2334}
2335
2336const ucl_object_t *
2246ucl_object_find_key (const ucl_object_t *obj, const char *key)
2337ucl_object_lookup (const ucl_object_t *obj, const char *key)
2247{
2248 if (key == NULL) {
2249 return NULL;
2250 }
2251
2338{
2339 if (key == NULL) {
2340 return NULL;
2341 }
2342
2252 return ucl_object_find_keyl (obj, key, strlen (key));
2343 return ucl_object_lookup_len (obj, key, strlen (key));
2253}
2254
2255const ucl_object_t*
2344}
2345
2346const ucl_object_t*
2256ucl_object_find_any_key (const ucl_object_t *obj,
2347ucl_object_lookup_any (const ucl_object_t *obj,
2257 const char *key, ...)
2258{
2259 va_list ap;
2260 const ucl_object_t *ret = NULL;
2261 const char *nk = NULL;
2262
2263 if (obj == NULL || key == NULL) {
2264 return NULL;
2265 }
2266
2348 const char *key, ...)
2349{
2350 va_list ap;
2351 const ucl_object_t *ret = NULL;
2352 const char *nk = NULL;
2353
2354 if (obj == NULL || key == NULL) {
2355 return NULL;
2356 }
2357
2267 ret = ucl_object_find_keyl (obj, key, strlen (key));
2358 ret = ucl_object_lookup_len (obj, key, strlen (key));
2268
2269 if (ret == NULL) {
2270 va_start (ap, key);
2271
2272 while (ret == NULL) {
2273 nk = va_arg (ap, const char *);
2274
2275 if (nk == NULL) {
2276 break;
2277 }
2278 else {
2359
2360 if (ret == NULL) {
2361 va_start (ap, key);
2362
2363 while (ret == NULL) {
2364 nk = va_arg (ap, const char *);
2365
2366 if (nk == NULL) {
2367 break;
2368 }
2369 else {
2279 ret = ucl_object_find_keyl (obj, nk, strlen (nk));
2370 ret = ucl_object_lookup_len (obj, nk, strlen (nk));
2280 }
2281 }
2282
2283 va_end (ap);
2284 }
2285
2286 return ret;
2287}
2288
2289const ucl_object_t*
2371 }
2372 }
2373
2374 va_end (ap);
2375 }
2376
2377 return ret;
2378}
2379
2380const ucl_object_t*
2290ucl_iterate_object (const ucl_object_t *obj, ucl_object_iter_t *iter, bool expand_values)
2381ucl_object_iterate (const ucl_object_t *obj, ucl_object_iter_t *iter, bool expand_values)
2291{
2292 const ucl_object_t *elt = NULL;
2293
2294 if (obj == NULL || iter == NULL) {
2295 return NULL;
2296 }
2297
2298 if (expand_values) {

--- 90 unchanged lines hidden (view full) ---

2389
2390 UCL_SAFE_ITER_CHECK (rit);
2391
2392 if (rit->impl_it == NULL) {
2393 return NULL;
2394 }
2395
2396 if (rit->impl_it->type == UCL_OBJECT || rit->impl_it->type == UCL_ARRAY) {
2382{
2383 const ucl_object_t *elt = NULL;
2384
2385 if (obj == NULL || iter == NULL) {
2386 return NULL;
2387 }
2388
2389 if (expand_values) {

--- 90 unchanged lines hidden (view full) ---

2480
2481 UCL_SAFE_ITER_CHECK (rit);
2482
2483 if (rit->impl_it == NULL) {
2484 return NULL;
2485 }
2486
2487 if (rit->impl_it->type == UCL_OBJECT || rit->impl_it->type == UCL_ARRAY) {
2397 ret = ucl_iterate_object (rit->impl_it, &rit->expl_it, true);
2488 ret = ucl_object_iterate (rit->impl_it, &rit->expl_it, true);
2398
2399 if (ret == NULL) {
2400 /* Need to switch to another implicit object in chain */
2401 rit->impl_it = rit->impl_it->next;
2402 rit->expl_it = NULL;
2403 return ucl_object_iterate_safe (it, expand_values);
2404 }
2405 }

--- 18 unchanged lines hidden (view full) ---

2424 struct ucl_object_safe_iter *rit = UCL_SAFE_ITER (it);
2425
2426 UCL_SAFE_ITER_CHECK (rit);
2427
2428 UCL_FREE (sizeof (*rit), it);
2429}
2430
2431const ucl_object_t *
2489
2490 if (ret == NULL) {
2491 /* Need to switch to another implicit object in chain */
2492 rit->impl_it = rit->impl_it->next;
2493 rit->expl_it = NULL;
2494 return ucl_object_iterate_safe (it, expand_values);
2495 }
2496 }

--- 18 unchanged lines hidden (view full) ---

2515 struct ucl_object_safe_iter *rit = UCL_SAFE_ITER (it);
2516
2517 UCL_SAFE_ITER_CHECK (rit);
2518
2519 UCL_FREE (sizeof (*rit), it);
2520}
2521
2522const ucl_object_t *
2432ucl_lookup_path (const ucl_object_t *top, const char *path_in) {
2433 return ucl_lookup_path_char (top, path_in, '.');
2523ucl_object_lookup_path (const ucl_object_t *top, const char *path_in) {
2524 return ucl_object_lookup_path_char (top, path_in, '.');
2434}
2435
2436
2437const ucl_object_t *
2525}
2526
2527
2528const ucl_object_t *
2438ucl_lookup_path_char (const ucl_object_t *top, const char *path_in, const char sep) {
2529ucl_object_lookup_path_char (const ucl_object_t *top, const char *path_in, const char sep) {
2439 const ucl_object_t *o = NULL, *found;
2440 const char *p, *c;
2441 char *err_str;
2442 unsigned index;
2443
2444 if (path_in == NULL || top == NULL) {
2445 return NULL;
2446 }

--- 16 unchanged lines hidden (view full) ---

2463 /* Key should be an int */
2464 index = strtoul (c, &err_str, 10);
2465 if (err_str != NULL && (*err_str != sep && *err_str != '\0')) {
2466 return NULL;
2467 }
2468 o = ucl_array_find_index (top, index);
2469 break;
2470 default:
2530 const ucl_object_t *o = NULL, *found;
2531 const char *p, *c;
2532 char *err_str;
2533 unsigned index;
2534
2535 if (path_in == NULL || top == NULL) {
2536 return NULL;
2537 }

--- 16 unchanged lines hidden (view full) ---

2554 /* Key should be an int */
2555 index = strtoul (c, &err_str, 10);
2556 if (err_str != NULL && (*err_str != sep && *err_str != '\0')) {
2557 return NULL;
2558 }
2559 o = ucl_array_find_index (top, index);
2560 break;
2561 default:
2471 o = ucl_object_find_keyl (top, c, p - c);
2562 o = ucl_object_lookup_len (top, c, p - c);
2472 break;
2473 }
2474 if (o == NULL) {
2475 return NULL;
2476 }
2477 top = o;
2478 }
2479 if (*p != '\0') {

--- 42 unchanged lines hidden (view full) ---

2522
2523 /* Preallocate some space for arrays */
2524 kv_resize (ucl_object_t *, *vec, 8);
2525 }
2526 }
2527 }
2528 }
2529 else {
2563 break;
2564 }
2565 if (o == NULL) {
2566 return NULL;
2567 }
2568 top = o;
2569 }
2570 if (*p != '\0') {

--- 42 unchanged lines hidden (view full) ---

2613
2614 /* Preallocate some space for arrays */
2615 kv_resize (ucl_object_t *, *vec, 8);
2616 }
2617 }
2618 }
2619 }
2620 else {
2530 new = ucl_object_new_userdata (NULL, NULL);
2621 new = ucl_object_new_userdata (NULL, NULL, NULL);
2531 ucl_object_set_priority (new, priority);
2532 }
2533
2534 return new;
2535}
2536
2537ucl_object_t*
2622 ucl_object_set_priority (new, priority);
2623 }
2624
2625 return new;
2626}
2627
2628ucl_object_t*
2538ucl_object_new_userdata (ucl_userdata_dtor dtor, ucl_userdata_emitter emitter)
2629ucl_object_new_userdata (ucl_userdata_dtor dtor,
2630 ucl_userdata_emitter emitter,
2631 void *ptr)
2539{
2540 struct ucl_object_userdata *new;
2541 size_t nsize = sizeof (*new);
2542
2543 new = UCL_ALLOC (nsize);
2544 if (new != NULL) {
2545 memset (new, 0, nsize);
2546 new->obj.ref = 1;
2547 new->obj.type = UCL_USERDATA;
2548 new->obj.next = NULL;
2549 new->obj.prev = (ucl_object_t *)new;
2550 new->dtor = dtor;
2551 new->emitter = emitter;
2632{
2633 struct ucl_object_userdata *new;
2634 size_t nsize = sizeof (*new);
2635
2636 new = UCL_ALLOC (nsize);
2637 if (new != NULL) {
2638 memset (new, 0, nsize);
2639 new->obj.ref = 1;
2640 new->obj.type = UCL_USERDATA;
2641 new->obj.next = NULL;
2642 new->obj.prev = (ucl_object_t *)new;
2643 new->dtor = dtor;
2644 new->emitter = emitter;
2645 new->obj.value.ud = ptr;
2552 }
2553
2554 return (ucl_object_t *)new;
2555}
2556
2557ucl_type_t
2558ucl_object_type (const ucl_object_t *obj)
2559{

--- 126 unchanged lines hidden (view full) ---

2686 }
2687 else {
2688 cp = ucl_object_ref (elt);
2689 }
2690
2691 UCL_ARRAY_GET (v1, top);
2692 UCL_ARRAY_GET (v2, cp);
2693
2646 }
2647
2648 return (ucl_object_t *)new;
2649}
2650
2651ucl_type_t
2652ucl_object_type (const ucl_object_t *obj)
2653{

--- 126 unchanged lines hidden (view full) ---

2780 }
2781 else {
2782 cp = ucl_object_ref (elt);
2783 }
2784
2785 UCL_ARRAY_GET (v1, top);
2786 UCL_ARRAY_GET (v2, cp);
2787
2694 kv_concat (ucl_object_t *, *v1, *v2);
2788 if (v1 && v2) {
2789 kv_concat (ucl_object_t *, *v1, *v2);
2695
2790
2696 for (i = v2->n; i < v1->n; i ++) {
2697 obj = &kv_A (*v1, i);
2698 if (*obj == NULL) {
2699 continue;
2791 for (i = v2->n; i < v1->n; i ++) {
2792 obj = &kv_A (*v1, i);
2793 if (*obj == NULL) {
2794 continue;
2795 }
2796 top->len ++;
2700 }
2797 }
2701 top->len ++;
2702 }
2703
2704 return true;
2705}
2706
2707ucl_object_t *
2708ucl_array_delete (ucl_object_t *top, ucl_object_t *elt)
2709{

--- 372 unchanged lines hidden (view full) ---

3082 new->value.sv = new->trash_stack[UCL_TRASH_VALUE];
3083 }
3084 }
3085
3086 if (other->type == UCL_ARRAY || other->type == UCL_OBJECT) {
3087 /* reset old value */
3088 memset (&new->value, 0, sizeof (new->value));
3089
2798 }
2799
2800 return true;
2801}
2802
2803ucl_object_t *
2804ucl_array_delete (ucl_object_t *top, ucl_object_t *elt)
2805{

--- 372 unchanged lines hidden (view full) ---

3178 new->value.sv = new->trash_stack[UCL_TRASH_VALUE];
3179 }
3180 }
3181
3182 if (other->type == UCL_ARRAY || other->type == UCL_OBJECT) {
3183 /* reset old value */
3184 memset (&new->value, 0, sizeof (new->value));
3185
3090 while ((cur = ucl_iterate_object (other, &it, true)) != NULL) {
3186 while ((cur = ucl_object_iterate (other, &it, true)) != NULL) {
3091 if (other->type == UCL_ARRAY) {
3092 ucl_array_append (new, ucl_object_copy_internal (cur, false));
3093 }
3094 else {
3095 ucl_object_t *cp = ucl_object_copy_internal (cur, true);
3096 if (cp != NULL) {
3097 ucl_object_insert_key (new, cp, cp->key, cp->keylen,
3098 false);

--- 89 unchanged lines hidden (view full) ---

3188 }
3189 }
3190 else {
3191 ret = o1->len - o2->len;
3192 }
3193 break;
3194 case UCL_OBJECT:
3195 if (o1->len == o2->len && o1->len > 0) {
3187 if (other->type == UCL_ARRAY) {
3188 ucl_array_append (new, ucl_object_copy_internal (cur, false));
3189 }
3190 else {
3191 ucl_object_t *cp = ucl_object_copy_internal (cur, true);
3192 if (cp != NULL) {
3193 ucl_object_insert_key (new, cp, cp->key, cp->keylen,
3194 false);

--- 89 unchanged lines hidden (view full) ---

3284 }
3285 }
3286 else {
3287 ret = o1->len - o2->len;
3288 }
3289 break;
3290 case UCL_OBJECT:
3291 if (o1->len == o2->len && o1->len > 0) {
3196 while ((it1 = ucl_iterate_object (o1, &iter, true)) != NULL) {
3197 it2 = ucl_object_find_key (o2, ucl_object_key (it1));
3292 while ((it1 = ucl_object_iterate (o1, &iter, true)) != NULL) {
3293 it2 = ucl_object_lookup (o2, ucl_object_key (it1));
3198 if (it2 == NULL) {
3199 ret = 1;
3200 break;
3201 }
3202 ret = ucl_object_compare (it1, it2);
3203 if (ret != 0) {
3204 break;
3205 }

--- 6 unchanged lines hidden (view full) ---

3212 default:
3213 ret = 0;
3214 break;
3215 }
3216
3217 return ret;
3218}
3219
3294 if (it2 == NULL) {
3295 ret = 1;
3296 break;
3297 }
3298 ret = ucl_object_compare (it1, it2);
3299 if (ret != 0) {
3300 break;
3301 }

--- 6 unchanged lines hidden (view full) ---

3308 default:
3309 ret = 0;
3310 break;
3311 }
3312
3313 return ret;
3314}
3315
3316int
3317ucl_object_compare_qsort (const ucl_object_t **o1,
3318 const ucl_object_t **o2)
3319{
3320 return ucl_object_compare (*o1, *o2);
3321}
3322
3220void
3221ucl_object_array_sort (ucl_object_t *ar,
3222 int (*cmp)(const ucl_object_t **o1, const ucl_object_t **o2))
3223{
3224 UCL_ARRAY_GET (vec, ar);
3225
3226 if (cmp == NULL || ar == NULL || ar->type != UCL_ARRAY) {
3227 return;

--- 22 unchanged lines hidden (view full) ---

3250 if (obj != NULL) {
3251 priority &= (0x1 << PRIOBITS) - 1;
3252 priority <<= ((sizeof (obj->flags) * NBBY) - PRIOBITS);
3253 priority |= obj->flags & ((1 << ((sizeof (obj->flags) * NBBY) -
3254 PRIOBITS)) - 1);
3255 obj->flags = priority;
3256 }
3257}
3323void
3324ucl_object_array_sort (ucl_object_t *ar,
3325 int (*cmp)(const ucl_object_t **o1, const ucl_object_t **o2))
3326{
3327 UCL_ARRAY_GET (vec, ar);
3328
3329 if (cmp == NULL || ar == NULL || ar->type != UCL_ARRAY) {
3330 return;

--- 22 unchanged lines hidden (view full) ---

3353 if (obj != NULL) {
3354 priority &= (0x1 << PRIOBITS) - 1;
3355 priority <<= ((sizeof (obj->flags) * NBBY) - PRIOBITS);
3356 priority |= obj->flags & ((1 << ((sizeof (obj->flags) * NBBY) -
3357 PRIOBITS)) - 1);
3358 obj->flags = priority;
3359 }
3360}
3361
3362bool
3363ucl_object_string_to_type (const char *input, ucl_type_t *res)
3364{
3365 if (strcasecmp (input, "object") == 0) {
3366 *res = UCL_OBJECT;
3367 }
3368 else if (strcasecmp (input, "array") == 0) {
3369 *res = UCL_ARRAY;
3370 }
3371 else if (strcasecmp (input, "integer") == 0) {
3372 *res = UCL_INT;
3373 }
3374 else if (strcasecmp (input, "number") == 0) {
3375 *res = UCL_FLOAT;
3376 }
3377 else if (strcasecmp (input, "string") == 0) {
3378 *res = UCL_STRING;
3379 }
3380 else if (strcasecmp (input, "boolean") == 0) {
3381 *res = UCL_BOOLEAN;
3382 }
3383 else if (strcasecmp (input, "null") == 0) {
3384 *res = UCL_NULL;
3385 }
3386 else if (strcasecmp (input, "userdata") == 0) {
3387 *res = UCL_USERDATA;
3388 }
3389 else {
3390 return false;
3391 }
3392
3393 return true;
3394}
3395
3396const char *
3397ucl_object_type_to_string (ucl_type_t type)
3398{
3399 const char *res = "unknown";
3400
3401 switch (type) {
3402 case UCL_OBJECT:
3403 res = "object";
3404 break;
3405 case UCL_ARRAY:
3406 res = "array";
3407 break;
3408 case UCL_INT:
3409 res = "integer";
3410 break;
3411 case UCL_FLOAT:
3412 case UCL_TIME:
3413 res = "number";
3414 break;
3415 case UCL_STRING:
3416 res = "string";
3417 break;
3418 case UCL_BOOLEAN:
3419 res = "boolean";
3420 break;
3421 case UCL_USERDATA:
3422 res = "userdata";
3423 break;
3424 case UCL_NULL:
3425 res = "null";
3426 break;
3427 }
3428
3429 return res;
3430}
3431
3432const ucl_object_t *
3433ucl_parser_get_comments (struct ucl_parser *parser)
3434{
3435 if (parser && parser->comments) {
3436 return parser->comments;
3437 }
3438
3439 return NULL;
3440}
3441
3442const ucl_object_t *
3443ucl_comments_find (const ucl_object_t *comments,
3444 const ucl_object_t *srch)
3445{
3446 if (comments && srch) {
3447 return ucl_object_lookup_len (comments, (const char *)&srch,
3448 sizeof (void *));
3449 }
3450
3451 return NULL;
3452}
3453
3454bool
3455ucl_comments_move (ucl_object_t *comments,
3456 const ucl_object_t *from, const ucl_object_t *to)
3457{
3458 const ucl_object_t *found;
3459 ucl_object_t *obj;
3460
3461 if (comments && from && to) {
3462 found = ucl_object_lookup_len (comments,
3463 (const char *)&from, sizeof (void *));
3464
3465 if (found) {
3466 /* Replace key */
3467 obj = ucl_object_ref (found);
3468 ucl_object_delete_keyl (comments, (const char *)&from,
3469 sizeof (void *));
3470 ucl_object_insert_key (comments, obj, (const char *)&to,
3471 sizeof (void *), true);
3472
3473 return true;
3474 }
3475 }
3476
3477 return false;
3478}
3479
3480void
3481ucl_comments_add (ucl_object_t *comments, const ucl_object_t *obj,
3482 const char *comment)
3483{
3484 if (comments && obj && comment) {
3485 ucl_object_insert_key (comments, ucl_object_fromstring (comment),
3486 (const char *)&obj, sizeof (void *), true);
3487 }
3488}