xref: /freebsd/contrib/libucl/src/ucl_parser.c (revision 1f4bcc459a76b7aa664f3fd557684cd0ba6da352)
1 /* Copyright (c) 2013, Vsevolod Stakhov
2  * All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *       * Redistributions of source code must retain the above copyright
7  *         notice, this list of conditions and the following disclaimer.
8  *       * Redistributions in binary form must reproduce the above copyright
9  *         notice, this list of conditions and the following disclaimer in the
10  *         documentation and/or other materials provided with the distribution.
11  *
12  * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY
13  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
14  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
15  * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY
16  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
17  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
18  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
19  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
20  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22  */
23 
24 #include "ucl.h"
25 #include "ucl_internal.h"
26 #include "ucl_chartable.h"
27 
28 /**
29  * @file ucl_parser.c
30  * The implementation of ucl parser
31  */
32 
33 struct ucl_parser_saved_state {
34 	unsigned int line;
35 	unsigned int column;
36 	size_t remain;
37 	const unsigned char *pos;
38 };
39 
40 /**
41  * Move up to len characters
42  * @param parser
43  * @param begin
44  * @param len
45  * @return new position in chunk
46  */
47 #define ucl_chunk_skipc(chunk, p)    do{					\
48     if (*(p) == '\n') {										\
49         (chunk)->line ++;									\
50         (chunk)->column = 0;								\
51     }														\
52     else (chunk)->column ++;								\
53     (p++);													\
54     (chunk)->pos ++;										\
55     (chunk)->remain --;										\
56     } while (0)
57 
58 static inline void
59 ucl_set_err (struct ucl_parser *parser, int code, const char *str, UT_string **err)
60 {
61 	const char *fmt_string, *filename;
62 	struct ucl_chunk *chunk = parser->chunks;
63 
64 	if (parser->cur_file) {
65 		filename = parser->cur_file;
66 	}
67 	else {
68 		filename = "<unknown>";
69 	}
70 
71 	if (chunk->pos < chunk->end) {
72 		if (isgraph (*chunk->pos)) {
73 			fmt_string = "error while parsing %s: "
74 					"line: %d, column: %d - '%s', character: '%c'";
75 		}
76 		else {
77 			fmt_string = "error while parsing %s: "
78 					"line: %d, column: %d - '%s', character: '0x%02x'";
79 		}
80 		ucl_create_err (err, fmt_string,
81 			filename, chunk->line, chunk->column,
82 			str, *chunk->pos);
83 	}
84 	else {
85 		ucl_create_err (err, "error while parsing %s: at the end of chunk: %s",
86 			filename, str);
87 	}
88 
89 	parser->err_code = code;
90 }
91 
92 /**
93  * Skip all comments from the current pos resolving nested and multiline comments
94  * @param parser
95  * @return
96  */
97 static bool
98 ucl_skip_comments (struct ucl_parser *parser)
99 {
100 	struct ucl_chunk *chunk = parser->chunks;
101 	const unsigned char *p;
102 	int comments_nested = 0;
103 	bool quoted = false;
104 
105 	p = chunk->pos;
106 
107 start:
108 	if (chunk->remain > 0 && *p == '#') {
109 		if (parser->state != UCL_STATE_SCOMMENT &&
110 				parser->state != UCL_STATE_MCOMMENT) {
111 			while (p < chunk->end) {
112 				if (*p == '\n') {
113 					ucl_chunk_skipc (chunk, p);
114 					goto start;
115 				}
116 				ucl_chunk_skipc (chunk, p);
117 			}
118 		}
119 	}
120 	else if (chunk->remain >= 2 && *p == '/') {
121 		if (p[1] == '*') {
122 			ucl_chunk_skipc (chunk, p);
123 			comments_nested ++;
124 			ucl_chunk_skipc (chunk, p);
125 
126 			while (p < chunk->end) {
127 				if (*p == '"' && *(p - 1) != '\\') {
128 					quoted = !quoted;
129 				}
130 
131 				if (!quoted) {
132 					if (*p == '*') {
133 						ucl_chunk_skipc (chunk, p);
134 						if (*p == '/') {
135 							comments_nested --;
136 							if (comments_nested == 0) {
137 								ucl_chunk_skipc (chunk, p);
138 								goto start;
139 							}
140 						}
141 						ucl_chunk_skipc (chunk, p);
142 					}
143 					else if (p[0] == '/' && chunk->remain >= 2 && p[1] == '*') {
144 						comments_nested ++;
145 						ucl_chunk_skipc (chunk, p);
146 						ucl_chunk_skipc (chunk, p);
147 						continue;
148 					}
149 				}
150 				ucl_chunk_skipc (chunk, p);
151 			}
152 			if (comments_nested != 0) {
153 				ucl_set_err (parser, UCL_ENESTED,
154 						"unfinished multiline comment", &parser->err);
155 				return false;
156 			}
157 		}
158 	}
159 
160 	return true;
161 }
162 
163 /**
164  * Return multiplier for a character
165  * @param c multiplier character
166  * @param is_bytes if true use 1024 multiplier
167  * @return multiplier
168  */
169 static inline unsigned long
170 ucl_lex_num_multiplier (const unsigned char c, bool is_bytes) {
171 	const struct {
172 		char c;
173 		long mult_normal;
174 		long mult_bytes;
175 	} multipliers[] = {
176 			{'m', 1000 * 1000, 1024 * 1024},
177 			{'k', 1000, 1024},
178 			{'g', 1000 * 1000 * 1000, 1024 * 1024 * 1024}
179 	};
180 	int i;
181 
182 	for (i = 0; i < 3; i ++) {
183 		if (tolower (c) == multipliers[i].c) {
184 			if (is_bytes) {
185 				return multipliers[i].mult_bytes;
186 			}
187 			return multipliers[i].mult_normal;
188 		}
189 	}
190 
191 	return 1;
192 }
193 
194 
195 /**
196  * Return multiplier for time scaling
197  * @param c
198  * @return
199  */
200 static inline double
201 ucl_lex_time_multiplier (const unsigned char c) {
202 	const struct {
203 		char c;
204 		double mult;
205 	} multipliers[] = {
206 			{'m', 60},
207 			{'h', 60 * 60},
208 			{'d', 60 * 60 * 24},
209 			{'w', 60 * 60 * 24 * 7},
210 			{'y', 60 * 60 * 24 * 7 * 365}
211 	};
212 	int i;
213 
214 	for (i = 0; i < 5; i ++) {
215 		if (tolower (c) == multipliers[i].c) {
216 			return multipliers[i].mult;
217 		}
218 	}
219 
220 	return 1;
221 }
222 
223 /**
224  * Return true if a character is a end of an atom
225  * @param c
226  * @return
227  */
228 static inline bool
229 ucl_lex_is_atom_end (const unsigned char c)
230 {
231 	return ucl_test_character (c, UCL_CHARACTER_VALUE_END);
232 }
233 
234 static inline bool
235 ucl_lex_is_comment (const unsigned char c1, const unsigned char c2)
236 {
237 	if (c1 == '/') {
238 		if (c2 == '*') {
239 			return true;
240 		}
241 	}
242 	else if (c1 == '#') {
243 		return true;
244 	}
245 	return false;
246 }
247 
248 /**
249  * Check variable found
250  * @param parser
251  * @param ptr
252  * @param remain
253  * @param out_len
254  * @param strict
255  * @param found
256  * @return
257  */
258 static inline const char *
259 ucl_check_variable_safe (struct ucl_parser *parser, const char *ptr, size_t remain,
260 		size_t *out_len, bool strict, bool *found)
261 {
262 	struct ucl_variable *var;
263 	unsigned char *dst;
264 	size_t dstlen;
265 	bool need_free = false;
266 
267 	LL_FOREACH (parser->variables, var) {
268 		if (strict) {
269 			if (remain == var->var_len) {
270 				if (memcmp (ptr, var->var, var->var_len) == 0) {
271 					*out_len += var->value_len;
272 					*found = true;
273 					return (ptr + var->var_len);
274 				}
275 			}
276 		}
277 		else {
278 			if (remain >= var->var_len) {
279 				if (memcmp (ptr, var->var, var->var_len) == 0) {
280 					*out_len += var->value_len;
281 					*found = true;
282 					return (ptr + var->var_len);
283 				}
284 			}
285 		}
286 	}
287 
288 	/* XXX: can only handle ${VAR} */
289 	if (!(*found) && parser->var_handler != NULL && strict) {
290 		/* Call generic handler */
291 		if (parser->var_handler (ptr, remain, &dst, &dstlen, &need_free,
292 				parser->var_data)) {
293 			*found = true;
294 			if (need_free) {
295 				free (dst);
296 			}
297 			return (ptr + remain);
298 		}
299 	}
300 
301 	return ptr;
302 }
303 
304 /**
305  * Check for a variable in a given string
306  * @param parser
307  * @param ptr
308  * @param remain
309  * @param out_len
310  * @param vars_found
311  * @return
312  */
313 static const char *
314 ucl_check_variable (struct ucl_parser *parser, const char *ptr,
315 		size_t remain, size_t *out_len, bool *vars_found)
316 {
317 	const char *p, *end, *ret = ptr;
318 	bool found = false;
319 
320 	if (*ptr == '{') {
321 		/* We need to match the variable enclosed in braces */
322 		p = ptr + 1;
323 		end = ptr + remain;
324 		while (p < end) {
325 			if (*p == '}') {
326 				ret = ucl_check_variable_safe (parser, ptr + 1, p - ptr - 1,
327 						out_len, true, &found);
328 				if (found) {
329 					/* {} must be excluded actually */
330 					ret ++;
331 					if (!*vars_found) {
332 						*vars_found = true;
333 					}
334 				}
335 				else {
336 					*out_len += 2;
337 				}
338 				break;
339 			}
340 			p ++;
341 		}
342 	}
343 	else if (*ptr != '$') {
344 		/* Not count escaped dollar sign */
345 		ret = ucl_check_variable_safe (parser, ptr, remain, out_len, false, &found);
346 		if (found && !*vars_found) {
347 			*vars_found = true;
348 		}
349 		if (!found) {
350 			(*out_len) ++;
351 		}
352 	}
353 	else {
354 		ret ++;
355 		(*out_len) ++;
356 	}
357 
358 	return ret;
359 }
360 
361 /**
362  * Expand a single variable
363  * @param parser
364  * @param ptr
365  * @param remain
366  * @param dest
367  * @return
368  */
369 static const char *
370 ucl_expand_single_variable (struct ucl_parser *parser, const char *ptr,
371 		size_t remain, unsigned char **dest)
372 {
373 	unsigned char *d = *dest, *dst;
374 	const char *p = ptr + 1, *ret;
375 	struct ucl_variable *var;
376 	size_t dstlen;
377 	bool need_free = false;
378 	bool found = false;
379 	bool strict = false;
380 
381 	ret = ptr + 1;
382 	remain --;
383 
384 	if (*p == '$') {
385 		*d++ = *p++;
386 		*dest = d;
387 		return p;
388 	}
389 	else if (*p == '{') {
390 		p ++;
391 		strict = true;
392 		ret += 2;
393 		remain -= 2;
394 	}
395 
396 	LL_FOREACH (parser->variables, var) {
397 		if (remain >= var->var_len) {
398 			if (memcmp (p, var->var, var->var_len) == 0) {
399 				memcpy (d, var->value, var->value_len);
400 				ret += var->var_len;
401 				d += var->value_len;
402 				found = true;
403 				break;
404 			}
405 		}
406 	}
407 	if (!found) {
408 		if (strict && parser->var_handler != NULL) {
409 			if (parser->var_handler (ptr, remain, &dst, &dstlen, &need_free,
410 							parser->var_data)) {
411 				memcpy (d, dst, dstlen);
412 				ret += dstlen;
413 				d += remain;
414 				found = true;
415 			}
416 		}
417 
418 		/* Leave variable as is */
419 		if (!found) {
420 			if (strict) {
421 				/* Copy '${' */
422 				memcpy (d, ptr, 2);
423 				d += 2;
424 				ret --;
425 			}
426 			else {
427 				memcpy (d, ptr, 1);
428 				d ++;
429 			}
430 		}
431 	}
432 
433 	*dest = d;
434 	return ret;
435 }
436 
437 /**
438  * Expand variables in string
439  * @param parser
440  * @param dst
441  * @param src
442  * @param in_len
443  * @return
444  */
445 static ssize_t
446 ucl_expand_variable (struct ucl_parser *parser, unsigned char **dst,
447 		const char *src, size_t in_len)
448 {
449 	const char *p, *end = src + in_len;
450 	unsigned char *d;
451 	size_t out_len = 0;
452 	bool vars_found = false;
453 
454 	p = src;
455 	while (p != end) {
456 		if (*p == '$') {
457 			p = ucl_check_variable (parser, p + 1, end - p - 1, &out_len, &vars_found);
458 		}
459 		else {
460 			p ++;
461 			out_len ++;
462 		}
463 	}
464 
465 	if (!vars_found) {
466 		/* Trivial case */
467 		*dst = NULL;
468 		return in_len;
469 	}
470 
471 	*dst = UCL_ALLOC (out_len + 1);
472 	if (*dst == NULL) {
473 		return in_len;
474 	}
475 
476 	d = *dst;
477 	p = src;
478 	while (p != end) {
479 		if (*p == '$') {
480 			p = ucl_expand_single_variable (parser, p, end - p, &d);
481 		}
482 		else {
483 			*d++ = *p++;
484 		}
485 	}
486 
487 	*d = '\0';
488 
489 	return out_len;
490 }
491 
492 /**
493  * Store or copy pointer to the trash stack
494  * @param parser parser object
495  * @param src src string
496  * @param dst destination buffer (trash stack pointer)
497  * @param dst_const const destination pointer (e.g. value of object)
498  * @param in_len input length
499  * @param need_unescape need to unescape source (and copy it)
500  * @param need_lowercase need to lowercase value (and copy)
501  * @param need_expand need to expand variables (and copy as well)
502  * @return output length (excluding \0 symbol)
503  */
504 static inline ssize_t
505 ucl_copy_or_store_ptr (struct ucl_parser *parser,
506 		const unsigned char *src, unsigned char **dst,
507 		const char **dst_const, size_t in_len,
508 		bool need_unescape, bool need_lowercase, bool need_expand)
509 {
510 	ssize_t ret = -1, tret;
511 	unsigned char *tmp;
512 
513 	if (need_unescape || need_lowercase ||
514 			(need_expand && parser->variables != NULL) ||
515 			!(parser->flags & UCL_PARSER_ZEROCOPY)) {
516 		/* Copy string */
517 		*dst = UCL_ALLOC (in_len + 1);
518 		if (*dst == NULL) {
519 			ucl_set_err (parser, UCL_EINTERNAL, "cannot allocate memory for a string",
520 					&parser->err);
521 			return false;
522 		}
523 		if (need_lowercase) {
524 			ret = ucl_strlcpy_tolower (*dst, src, in_len + 1);
525 		}
526 		else {
527 			ret = ucl_strlcpy_unsafe (*dst, src, in_len + 1);
528 		}
529 
530 		if (need_unescape) {
531 			ret = ucl_unescape_json_string (*dst, ret);
532 		}
533 		if (need_expand) {
534 			tmp = *dst;
535 			tret = ret;
536 			ret = ucl_expand_variable (parser, dst, tmp, ret);
537 			if (*dst == NULL) {
538 				/* Nothing to expand */
539 				*dst = tmp;
540 				ret = tret;
541 			}
542 			else {
543 				/* Free unexpanded value */
544 				UCL_FREE (in_len + 1, tmp);
545 			}
546 		}
547 		*dst_const = *dst;
548 	}
549 	else {
550 		*dst_const = src;
551 		ret = in_len;
552 	}
553 
554 	return ret;
555 }
556 
557 /**
558  * Create and append an object at the specified level
559  * @param parser
560  * @param is_array
561  * @param level
562  * @return
563  */
564 static inline ucl_object_t *
565 ucl_parser_add_container (ucl_object_t *obj, struct ucl_parser *parser,
566 		bool is_array, int level)
567 {
568 	struct ucl_stack *st;
569 
570 	if (!is_array) {
571 		if (obj == NULL) {
572 			obj = ucl_object_new_full (UCL_OBJECT, parser->chunks->priority);
573 		}
574 		else {
575 			obj->type = UCL_OBJECT;
576 		}
577 		if (obj->value.ov == NULL) {
578 			obj->value.ov = ucl_hash_create (parser->flags & UCL_PARSER_KEY_LOWERCASE);
579 		}
580 		parser->state = UCL_STATE_KEY;
581 	}
582 	else {
583 		if (obj == NULL) {
584 			obj = ucl_object_new_full (UCL_ARRAY, parser->chunks->priority);
585 		}
586 		else {
587 			obj->type = UCL_ARRAY;
588 		}
589 		parser->state = UCL_STATE_VALUE;
590 	}
591 
592 	st = UCL_ALLOC (sizeof (struct ucl_stack));
593 	if (st == NULL) {
594 		ucl_set_err (parser, UCL_EINTERNAL, "cannot allocate memory for an object",
595 				&parser->err);
596 		ucl_object_unref (obj);
597 		return NULL;
598 	}
599 	st->obj = obj;
600 	st->level = level;
601 	LL_PREPEND (parser->stack, st);
602 	parser->cur_obj = obj;
603 
604 	return obj;
605 }
606 
607 int
608 ucl_maybe_parse_number (ucl_object_t *obj,
609 		const char *start, const char *end, const char **pos,
610 		bool allow_double, bool number_bytes, bool allow_time)
611 {
612 	const char *p = start, *c = start;
613 	char *endptr;
614 	bool got_dot = false, got_exp = false, need_double = false,
615 			is_time = false, valid_start = false, is_hex = false,
616 			is_neg = false;
617 	double dv = 0;
618 	int64_t lv = 0;
619 
620 	if (*p == '-') {
621 		is_neg = true;
622 		c ++;
623 		p ++;
624 	}
625 	while (p < end) {
626 		if (is_hex && isxdigit (*p)) {
627 			p ++;
628 		}
629 		else if (isdigit (*p)) {
630 			valid_start = true;
631 			p ++;
632 		}
633 		else if (!is_hex && (*p == 'x' || *p == 'X')) {
634 			is_hex = true;
635 			allow_double = false;
636 			c = p + 1;
637 		}
638 		else if (allow_double) {
639 			if (p == c) {
640 				/* Empty digits sequence, not a number */
641 				*pos = start;
642 				return EINVAL;
643 			}
644 			else if (*p == '.') {
645 				if (got_dot) {
646 					/* Double dots, not a number */
647 					*pos = start;
648 					return EINVAL;
649 				}
650 				else {
651 					got_dot = true;
652 					need_double = true;
653 					p ++;
654 				}
655 			}
656 			else if (*p == 'e' || *p == 'E') {
657 				if (got_exp) {
658 					/* Double exp, not a number */
659 					*pos = start;
660 					return EINVAL;
661 				}
662 				else {
663 					got_exp = true;
664 					need_double = true;
665 					p ++;
666 					if (p >= end) {
667 						*pos = start;
668 						return EINVAL;
669 					}
670 					if (!isdigit (*p) && *p != '+' && *p != '-') {
671 						/* Wrong exponent sign */
672 						*pos = start;
673 						return EINVAL;
674 					}
675 					else {
676 						p ++;
677 					}
678 				}
679 			}
680 			else {
681 				/* Got the end of the number, need to check */
682 				break;
683 			}
684 		}
685 		else {
686 			break;
687 		}
688 	}
689 
690 	if (!valid_start) {
691 		*pos = start;
692 		return EINVAL;
693 	}
694 
695 	errno = 0;
696 	if (need_double) {
697 		dv = strtod (c, &endptr);
698 	}
699 	else {
700 		if (is_hex) {
701 			lv = strtoimax (c, &endptr, 16);
702 		}
703 		else {
704 			lv = strtoimax (c, &endptr, 10);
705 		}
706 	}
707 	if (errno == ERANGE) {
708 		*pos = start;
709 		return ERANGE;
710 	}
711 
712 	/* Now check endptr */
713 	if (endptr == NULL || ucl_lex_is_atom_end (*endptr) || *endptr == '\0') {
714 		p = endptr;
715 		goto set_obj;
716 	}
717 
718 	if (endptr < end && endptr != start) {
719 		p = endptr;
720 		switch (*p) {
721 		case 'm':
722 		case 'M':
723 		case 'g':
724 		case 'G':
725 		case 'k':
726 		case 'K':
727 			if (end - p >= 2) {
728 				if (p[1] == 's' || p[1] == 'S') {
729 					/* Milliseconds */
730 					if (!need_double) {
731 						need_double = true;
732 						dv = lv;
733 					}
734 					is_time = true;
735 					if (p[0] == 'm' || p[0] == 'M') {
736 						dv /= 1000.;
737 					}
738 					else {
739 						dv *= ucl_lex_num_multiplier (*p, false);
740 					}
741 					p += 2;
742 					goto set_obj;
743 				}
744 				else if (number_bytes || (p[1] == 'b' || p[1] == 'B')) {
745 					/* Bytes */
746 					if (need_double) {
747 						need_double = false;
748 						lv = dv;
749 					}
750 					lv *= ucl_lex_num_multiplier (*p, true);
751 					p += 2;
752 					goto set_obj;
753 				}
754 				else if (ucl_lex_is_atom_end (p[1])) {
755 					if (need_double) {
756 						dv *= ucl_lex_num_multiplier (*p, false);
757 					}
758 					else {
759 						lv *= ucl_lex_num_multiplier (*p, number_bytes);
760 					}
761 					p ++;
762 					goto set_obj;
763 				}
764 				else if (allow_time && end - p >= 3) {
765 					if (tolower (p[0]) == 'm' &&
766 							tolower (p[1]) == 'i' &&
767 							tolower (p[2]) == 'n') {
768 						/* Minutes */
769 						if (!need_double) {
770 							need_double = true;
771 							dv = lv;
772 						}
773 						is_time = true;
774 						dv *= 60.;
775 						p += 3;
776 						goto set_obj;
777 					}
778 				}
779 			}
780 			else {
781 				if (need_double) {
782 					dv *= ucl_lex_num_multiplier (*p, false);
783 				}
784 				else {
785 					lv *= ucl_lex_num_multiplier (*p, number_bytes);
786 				}
787 				p ++;
788 				goto set_obj;
789 			}
790 			break;
791 		case 'S':
792 		case 's':
793 			if (allow_time &&
794 					(p == end - 1 || ucl_lex_is_atom_end (p[1]))) {
795 				if (!need_double) {
796 					need_double = true;
797 					dv = lv;
798 				}
799 				p ++;
800 				is_time = true;
801 				goto set_obj;
802 			}
803 			break;
804 		case 'h':
805 		case 'H':
806 		case 'd':
807 		case 'D':
808 		case 'w':
809 		case 'W':
810 		case 'Y':
811 		case 'y':
812 			if (allow_time &&
813 					(p == end - 1 || ucl_lex_is_atom_end (p[1]))) {
814 				if (!need_double) {
815 					need_double = true;
816 					dv = lv;
817 				}
818 				is_time = true;
819 				dv *= ucl_lex_time_multiplier (*p);
820 				p ++;
821 				goto set_obj;
822 			}
823 			break;
824 		case '\t':
825 		case ' ':
826 			while (p < end && ucl_test_character(*p, UCL_CHARACTER_WHITESPACE)) {
827 				p++;
828 			}
829 			if (ucl_lex_is_atom_end(*p))
830 				goto set_obj;
831 			break;
832 		}
833 	}
834 	else if (endptr == end) {
835 		/* Just a number at the end of chunk */
836 		p = endptr;
837 		goto set_obj;
838 	}
839 
840 	*pos = c;
841 	return EINVAL;
842 
843 set_obj:
844 	if (obj != NULL) {
845 		if (allow_double && (need_double || is_time)) {
846 			if (!is_time) {
847 				obj->type = UCL_FLOAT;
848 			}
849 			else {
850 				obj->type = UCL_TIME;
851 			}
852 			obj->value.dv = is_neg ? (-dv) : dv;
853 		}
854 		else {
855 			obj->type = UCL_INT;
856 			obj->value.iv = is_neg ? (-lv) : lv;
857 		}
858 	}
859 	*pos = p;
860 	return 0;
861 }
862 
863 /**
864  * Parse possible number
865  * @param parser
866  * @param chunk
867  * @param obj
868  * @return true if a number has been parsed
869  */
870 static bool
871 ucl_lex_number (struct ucl_parser *parser,
872 		struct ucl_chunk *chunk, ucl_object_t *obj)
873 {
874 	const unsigned char *pos;
875 	int ret;
876 
877 	ret = ucl_maybe_parse_number (obj, chunk->pos, chunk->end, (const char **)&pos,
878 			true, false, ((parser->flags & UCL_PARSER_NO_TIME) == 0));
879 
880 	if (ret == 0) {
881 		chunk->remain -= pos - chunk->pos;
882 		chunk->column += pos - chunk->pos;
883 		chunk->pos = pos;
884 		return true;
885 	}
886 	else if (ret == ERANGE) {
887 		ucl_set_err (parser, UCL_ESYNTAX, "numeric value out of range",
888 				&parser->err);
889 	}
890 
891 	return false;
892 }
893 
894 /**
895  * Parse quoted string with possible escapes
896  * @param parser
897  * @param chunk
898  * @param need_unescape
899  * @param ucl_escape
900  * @param var_expand
901  * @return true if a string has been parsed
902  */
903 static bool
904 ucl_lex_json_string (struct ucl_parser *parser,
905 		struct ucl_chunk *chunk, bool *need_unescape, bool *ucl_escape, bool *var_expand)
906 {
907 	const unsigned char *p = chunk->pos;
908 	unsigned char c;
909 	int i;
910 
911 	while (p < chunk->end) {
912 		c = *p;
913 		if (c < 0x1F) {
914 			/* Unmasked control character */
915 			if (c == '\n') {
916 				ucl_set_err (parser, UCL_ESYNTAX, "unexpected newline",
917 						&parser->err);
918 			}
919 			else {
920 				ucl_set_err (parser, UCL_ESYNTAX, "unexpected control character",
921 						&parser->err);
922 			}
923 			return false;
924 		}
925 		else if (c == '\\') {
926 			ucl_chunk_skipc (chunk, p);
927 			c = *p;
928 			if (p >= chunk->end) {
929 				ucl_set_err (parser, UCL_ESYNTAX, "unfinished escape character",
930 						&parser->err);
931 				return false;
932 			}
933 			else if (ucl_test_character (c, UCL_CHARACTER_ESCAPE)) {
934 				if (c == 'u') {
935 					ucl_chunk_skipc (chunk, p);
936 					for (i = 0; i < 4 && p < chunk->end; i ++) {
937 						if (!isxdigit (*p)) {
938 							ucl_set_err (parser, UCL_ESYNTAX, "invalid utf escape",
939 									&parser->err);
940 							return false;
941 						}
942 						ucl_chunk_skipc (chunk, p);
943 					}
944 					if (p >= chunk->end) {
945 						ucl_set_err (parser, UCL_ESYNTAX, "unfinished escape character",
946 								&parser->err);
947 						return false;
948 					}
949 				}
950 				else {
951 					ucl_chunk_skipc (chunk, p);
952 				}
953 			}
954 			*need_unescape = true;
955 			*ucl_escape = true;
956 			continue;
957 		}
958 		else if (c == '"') {
959 			ucl_chunk_skipc (chunk, p);
960 			return true;
961 		}
962 		else if (ucl_test_character (c, UCL_CHARACTER_UCL_UNSAFE)) {
963 			*ucl_escape = true;
964 		}
965 		else if (c == '$') {
966 			*var_expand = true;
967 		}
968 		ucl_chunk_skipc (chunk, p);
969 	}
970 
971 	ucl_set_err (parser, UCL_ESYNTAX, "no quote at the end of json string",
972 			&parser->err);
973 	return false;
974 }
975 
976 static void
977 ucl_parser_append_elt (struct ucl_parser *parser, ucl_hash_t *cont,
978 		ucl_object_t *top,
979 		ucl_object_t *elt)
980 {
981 	ucl_object_t *nobj;
982 
983 	if ((parser->flags & UCL_PARSER_NO_IMPLICIT_ARRAYS) == 0) {
984 		/* Implicit array */
985 		top->flags |= UCL_OBJECT_MULTIVALUE;
986 		DL_APPEND (top, elt);
987 		parser->stack->obj->len ++;
988 	}
989 	else {
990 		if ((top->flags & UCL_OBJECT_MULTIVALUE) != 0) {
991 			/* Just add to the explicit array */
992 			ucl_array_append (top, elt);
993 		}
994 		else {
995 			/* Convert to an array */
996 			nobj = ucl_object_typed_new (UCL_ARRAY);
997 			nobj->key = top->key;
998 			nobj->keylen = top->keylen;
999 			nobj->flags |= UCL_OBJECT_MULTIVALUE;
1000 			ucl_array_append (nobj, top);
1001 			ucl_array_append (nobj, elt);
1002 			ucl_hash_replace (cont, top, nobj);
1003 		}
1004 	}
1005 }
1006 
1007 bool
1008 ucl_parser_process_object_element (struct ucl_parser *parser, ucl_object_t *nobj)
1009 {
1010 	ucl_hash_t *container;
1011 	ucl_object_t *tobj;
1012 
1013 	container = parser->stack->obj->value.ov;
1014 
1015 	tobj = __DECONST (ucl_object_t *, ucl_hash_search_obj (container, nobj));
1016 	if (tobj == NULL) {
1017 		container = ucl_hash_insert_object (container, nobj,
1018 				parser->flags & UCL_PARSER_KEY_LOWERCASE);
1019 		nobj->prev = nobj;
1020 		nobj->next = NULL;
1021 		parser->stack->obj->len ++;
1022 	}
1023 	else {
1024 		unsigned priold = ucl_object_get_priority (tobj),
1025 				prinew = ucl_object_get_priority (nobj);
1026 		switch (parser->chunks->strategy) {
1027 
1028 		case UCL_DUPLICATE_APPEND:
1029 			/*
1030 			 * The logic here is the following:
1031 			 *
1032 			 * - if we have two objects with the same priority, then we form an
1033 			 * implicit or explicit array
1034 			 * - if a new object has bigger priority, then we overwrite an old one
1035 			 * - if a new object has lower priority, then we ignore it
1036 			 */
1037 
1038 
1039 			/* Special case for inherited objects */
1040 			if (tobj->flags & UCL_OBJECT_INHERITED) {
1041 				prinew = priold + 1;
1042 			}
1043 
1044 			if (priold == prinew) {
1045 				ucl_parser_append_elt (parser, container, tobj, nobj);
1046 			}
1047 			else if (priold > prinew) {
1048 				/*
1049 				 * We add this new object to a list of trash objects just to ensure
1050 				 * that it won't come to any real object
1051 				 * XXX: rather inefficient approach
1052 				 */
1053 				DL_APPEND (parser->trash_objs, nobj);
1054 			}
1055 			else {
1056 				ucl_hash_replace (container, tobj, nobj);
1057 				ucl_object_unref (tobj);
1058 			}
1059 
1060 			break;
1061 
1062 		case UCL_DUPLICATE_REWRITE:
1063 			/* We just rewrite old values regardless of priority */
1064 			ucl_hash_replace (container, tobj, nobj);
1065 			ucl_object_unref (tobj);
1066 
1067 			break;
1068 
1069 		case UCL_DUPLICATE_ERROR:
1070 			ucl_create_err (&parser->err, "error while parsing %s: "
1071 					"line: %d, column: %d: duplicate element for key '%s' "
1072 					"has been found",
1073 					parser->cur_file ? parser->cur_file : "<unknown>",
1074 					parser->chunks->line, parser->chunks->column, nobj->key);
1075 			return false;
1076 
1077 		case UCL_DUPLICATE_MERGE:
1078 			/*
1079 			 * Here we do have some old object so we just push it on top of objects stack
1080 			 */
1081 			if (tobj->type == UCL_OBJECT || tobj->type == UCL_ARRAY) {
1082 				ucl_object_unref (nobj);
1083 				nobj = tobj;
1084 			}
1085 			else {
1086 				/* For other types we create implicit array as usual */
1087 				ucl_parser_append_elt (parser, container, tobj, nobj);
1088 			}
1089 			break;
1090 		}
1091 	}
1092 
1093 	parser->stack->obj->value.ov = container;
1094 	parser->cur_obj = nobj;
1095 
1096 	return true;
1097 }
1098 
1099 /**
1100  * Parse a key in an object
1101  * @param parser
1102  * @param chunk
1103  * @param next_key
1104  * @param end_of_object
1105  * @return true if a key has been parsed
1106  */
1107 static bool
1108 ucl_parse_key (struct ucl_parser *parser, struct ucl_chunk *chunk,
1109 		bool *next_key, bool *end_of_object)
1110 {
1111 	const unsigned char *p, *c = NULL, *end, *t;
1112 	const char *key = NULL;
1113 	bool got_quote = false, got_eq = false, got_semicolon = false,
1114 			need_unescape = false, ucl_escape = false, var_expand = false,
1115 			got_content = false, got_sep = false;
1116 	ucl_object_t *nobj;
1117 	ssize_t keylen;
1118 
1119 	p = chunk->pos;
1120 
1121 	if (*p == '.') {
1122 		/* It is macro actually */
1123 		ucl_chunk_skipc (chunk, p);
1124 		parser->prev_state = parser->state;
1125 		parser->state = UCL_STATE_MACRO_NAME;
1126 		*end_of_object = false;
1127 		return true;
1128 	}
1129 	while (p < chunk->end) {
1130 		/*
1131 		 * A key must start with alpha, number, '/' or '_' and end with space character
1132 		 */
1133 		if (c == NULL) {
1134 			if (chunk->remain >= 2 && ucl_lex_is_comment (p[0], p[1])) {
1135 				if (!ucl_skip_comments (parser)) {
1136 					return false;
1137 				}
1138 				p = chunk->pos;
1139 			}
1140 			else if (ucl_test_character (*p, UCL_CHARACTER_WHITESPACE_UNSAFE)) {
1141 				ucl_chunk_skipc (chunk, p);
1142 			}
1143 			else if (ucl_test_character (*p, UCL_CHARACTER_KEY_START)) {
1144 				/* The first symbol */
1145 				c = p;
1146 				ucl_chunk_skipc (chunk, p);
1147 				got_content = true;
1148 			}
1149 			else if (*p == '"') {
1150 				/* JSON style key */
1151 				c = p + 1;
1152 				got_quote = true;
1153 				got_content = true;
1154 				ucl_chunk_skipc (chunk, p);
1155 			}
1156 			else if (*p == '}') {
1157 				/* We have actually end of an object */
1158 				*end_of_object = true;
1159 				return true;
1160 			}
1161 			else if (*p == '.') {
1162 				ucl_chunk_skipc (chunk, p);
1163 				parser->prev_state = parser->state;
1164 				parser->state = UCL_STATE_MACRO_NAME;
1165 				return true;
1166 			}
1167 			else {
1168 				/* Invalid identifier */
1169 				ucl_set_err (parser, UCL_ESYNTAX, "key must begin with a letter",
1170 						&parser->err);
1171 				return false;
1172 			}
1173 		}
1174 		else {
1175 			/* Parse the body of a key */
1176 			if (!got_quote) {
1177 				if (ucl_test_character (*p, UCL_CHARACTER_KEY)) {
1178 					got_content = true;
1179 					ucl_chunk_skipc (chunk, p);
1180 				}
1181 				else if (ucl_test_character (*p, UCL_CHARACTER_KEY_SEP)) {
1182 					end = p;
1183 					break;
1184 				}
1185 				else {
1186 					ucl_set_err (parser, UCL_ESYNTAX, "invalid character in a key",
1187 							&parser->err);
1188 					return false;
1189 				}
1190 			}
1191 			else {
1192 				/* We need to parse json like quoted string */
1193 				if (!ucl_lex_json_string (parser, chunk, &need_unescape, &ucl_escape, &var_expand)) {
1194 					return false;
1195 				}
1196 				/* Always escape keys obtained via json */
1197 				end = chunk->pos - 1;
1198 				p = chunk->pos;
1199 				break;
1200 			}
1201 		}
1202 	}
1203 
1204 	if (p >= chunk->end && got_content) {
1205 		ucl_set_err (parser, UCL_ESYNTAX, "unfinished key", &parser->err);
1206 		return false;
1207 	}
1208 	else if (!got_content) {
1209 		return true;
1210 	}
1211 	*end_of_object = false;
1212 	/* We are now at the end of the key, need to parse the rest */
1213 	while (p < chunk->end) {
1214 		if (ucl_test_character (*p, UCL_CHARACTER_WHITESPACE)) {
1215 			ucl_chunk_skipc (chunk, p);
1216 		}
1217 		else if (*p == '=') {
1218 			if (!got_eq && !got_semicolon) {
1219 				ucl_chunk_skipc (chunk, p);
1220 				got_eq = true;
1221 			}
1222 			else {
1223 				ucl_set_err (parser, UCL_ESYNTAX, "unexpected '=' character",
1224 						&parser->err);
1225 				return false;
1226 			}
1227 		}
1228 		else if (*p == ':') {
1229 			if (!got_eq && !got_semicolon) {
1230 				ucl_chunk_skipc (chunk, p);
1231 				got_semicolon = true;
1232 			}
1233 			else {
1234 				ucl_set_err (parser, UCL_ESYNTAX, "unexpected ':' character",
1235 						&parser->err);
1236 				return false;
1237 			}
1238 		}
1239 		else if (chunk->remain >= 2 && ucl_lex_is_comment (p[0], p[1])) {
1240 			/* Check for comment */
1241 			if (!ucl_skip_comments (parser)) {
1242 				return false;
1243 			}
1244 			p = chunk->pos;
1245 		}
1246 		else {
1247 			/* Start value */
1248 			break;
1249 		}
1250 	}
1251 
1252 	if (p >= chunk->end && got_content) {
1253 		ucl_set_err (parser, UCL_ESYNTAX, "unfinished key", &parser->err);
1254 		return false;
1255 	}
1256 
1257 	got_sep = got_semicolon || got_eq;
1258 
1259 	if (!got_sep) {
1260 		/*
1261 		 * Maybe we have more keys nested, so search for termination character.
1262 		 * Possible choices:
1263 		 * 1) key1 key2 ... keyN [:=] value <- we treat that as error
1264 		 * 2) key1 ... keyN {} or [] <- we treat that as nested objects
1265 		 * 3) key1 value[;,\n] <- we treat that as linear object
1266 		 */
1267 		t = p;
1268 		*next_key = false;
1269 		while (ucl_test_character (*t, UCL_CHARACTER_WHITESPACE)) {
1270 			t ++;
1271 		}
1272 		/* Check first non-space character after a key */
1273 		if (*t != '{' && *t != '[') {
1274 			while (t < chunk->end) {
1275 				if (*t == ',' || *t == ';' || *t == '\n' || *t == '\r') {
1276 					break;
1277 				}
1278 				else if (*t == '{' || *t == '[') {
1279 					*next_key = true;
1280 					break;
1281 				}
1282 				t ++;
1283 			}
1284 		}
1285 	}
1286 
1287 	/* Create a new object */
1288 	nobj = ucl_object_new_full (UCL_NULL, parser->chunks->priority);
1289 	keylen = ucl_copy_or_store_ptr (parser, c, &nobj->trash_stack[UCL_TRASH_KEY],
1290 			&key, end - c, need_unescape, parser->flags & UCL_PARSER_KEY_LOWERCASE, false);
1291 	if (keylen == -1) {
1292 		ucl_object_unref (nobj);
1293 		return false;
1294 	}
1295 	else if (keylen == 0) {
1296 		ucl_set_err (parser, UCL_ESYNTAX, "empty keys are not allowed", &parser->err);
1297 		ucl_object_unref (nobj);
1298 		return false;
1299 	}
1300 
1301 	nobj->key = key;
1302 	nobj->keylen = keylen;
1303 
1304 	if (!ucl_parser_process_object_element (parser, nobj)) {
1305 		return false;
1306 	}
1307 
1308 	if (ucl_escape) {
1309 		nobj->flags |= UCL_OBJECT_NEED_KEY_ESCAPE;
1310 	}
1311 
1312 
1313 	return true;
1314 }
1315 
1316 /**
1317  * Parse a cl string
1318  * @param parser
1319  * @param chunk
1320  * @param var_expand
1321  * @param need_unescape
1322  * @return true if a key has been parsed
1323  */
1324 static bool
1325 ucl_parse_string_value (struct ucl_parser *parser,
1326 		struct ucl_chunk *chunk, bool *var_expand, bool *need_unescape)
1327 {
1328 	const unsigned char *p;
1329 	enum {
1330 		UCL_BRACE_ROUND = 0,
1331 		UCL_BRACE_SQUARE,
1332 		UCL_BRACE_FIGURE
1333 	};
1334 	int braces[3][2] = {{0, 0}, {0, 0}, {0, 0}};
1335 
1336 	p = chunk->pos;
1337 
1338 	while (p < chunk->end) {
1339 
1340 		/* Skip pairs of figure braces */
1341 		if (*p == '{') {
1342 			braces[UCL_BRACE_FIGURE][0] ++;
1343 		}
1344 		else if (*p == '}') {
1345 			braces[UCL_BRACE_FIGURE][1] ++;
1346 			if (braces[UCL_BRACE_FIGURE][1] <= braces[UCL_BRACE_FIGURE][0]) {
1347 				/* This is not a termination symbol, continue */
1348 				ucl_chunk_skipc (chunk, p);
1349 				continue;
1350 			}
1351 		}
1352 		/* Skip pairs of square braces */
1353 		else if (*p == '[') {
1354 			braces[UCL_BRACE_SQUARE][0] ++;
1355 		}
1356 		else if (*p == ']') {
1357 			braces[UCL_BRACE_SQUARE][1] ++;
1358 			if (braces[UCL_BRACE_SQUARE][1] <= braces[UCL_BRACE_SQUARE][0]) {
1359 				/* This is not a termination symbol, continue */
1360 				ucl_chunk_skipc (chunk, p);
1361 				continue;
1362 			}
1363 		}
1364 		else if (*p == '$') {
1365 			*var_expand = true;
1366 		}
1367 		else if (*p == '\\') {
1368 			*need_unescape = true;
1369 			ucl_chunk_skipc (chunk, p);
1370 			if (p < chunk->end) {
1371 				ucl_chunk_skipc (chunk, p);
1372 			}
1373 			continue;
1374 		}
1375 
1376 		if (ucl_lex_is_atom_end (*p) || (chunk->remain >= 2 && ucl_lex_is_comment (p[0], p[1]))) {
1377 			break;
1378 		}
1379 		ucl_chunk_skipc (chunk, p);
1380 	}
1381 
1382 	return true;
1383 }
1384 
1385 /**
1386  * Parse multiline string ending with \n{term}\n
1387  * @param parser
1388  * @param chunk
1389  * @param term
1390  * @param term_len
1391  * @param beg
1392  * @param var_expand
1393  * @return size of multiline string or 0 in case of error
1394  */
1395 static int
1396 ucl_parse_multiline_string (struct ucl_parser *parser,
1397 		struct ucl_chunk *chunk, const unsigned char *term,
1398 		int term_len, unsigned char const **beg,
1399 		bool *var_expand)
1400 {
1401 	const unsigned char *p, *c, *tend;
1402 	bool newline = false;
1403 	int len = 0;
1404 
1405 	p = chunk->pos;
1406 
1407 	c = p;
1408 
1409 	while (p < chunk->end) {
1410 		if (newline) {
1411 			if (chunk->end - p < term_len) {
1412 				return 0;
1413 			}
1414 			else if (memcmp (p, term, term_len) == 0) {
1415 				tend = p + term_len;
1416 				if (*tend != '\n' && *tend != ';' && *tend != ',') {
1417 					/* Incomplete terminator */
1418 					ucl_chunk_skipc (chunk, p);
1419 					continue;
1420 				}
1421 				len = p - c;
1422 				chunk->remain -= term_len;
1423 				chunk->pos = p + term_len;
1424 				chunk->column = term_len;
1425 				*beg = c;
1426 				break;
1427 			}
1428 		}
1429 		if (*p == '\n') {
1430 			newline = true;
1431 		}
1432 		else {
1433 			if (*p == '$') {
1434 				*var_expand = true;
1435 			}
1436 			newline = false;
1437 		}
1438 		ucl_chunk_skipc (chunk, p);
1439 	}
1440 
1441 	return len;
1442 }
1443 
1444 static inline ucl_object_t*
1445 ucl_parser_get_container (struct ucl_parser *parser)
1446 {
1447 	ucl_object_t *t, *obj = NULL;
1448 
1449 	if (parser == NULL || parser->stack == NULL || parser->stack->obj == NULL) {
1450 		return NULL;
1451 	}
1452 
1453 	if (parser->stack->obj->type == UCL_ARRAY) {
1454 		/* Object must be allocated */
1455 		obj = ucl_object_new_full (UCL_NULL, parser->chunks->priority);
1456 		t = parser->stack->obj;
1457 
1458 		if (!ucl_array_append (t, obj)) {
1459 			ucl_object_unref (obj);
1460 			return NULL;
1461 		}
1462 
1463 		parser->cur_obj = obj;
1464 	}
1465 	else {
1466 		/* Object has been already allocated */
1467 		obj = parser->cur_obj;
1468 	}
1469 
1470 	return obj;
1471 }
1472 
1473 /**
1474  * Handle value data
1475  * @param parser
1476  * @param chunk
1477  * @return
1478  */
1479 static bool
1480 ucl_parse_value (struct ucl_parser *parser, struct ucl_chunk *chunk)
1481 {
1482 	const unsigned char *p, *c;
1483 	ucl_object_t *obj = NULL;
1484 	unsigned int stripped_spaces;
1485 	int str_len;
1486 	bool need_unescape = false, ucl_escape = false, var_expand = false;
1487 
1488 	p = chunk->pos;
1489 
1490 	/* Skip any spaces and comments */
1491 	if (ucl_test_character (*p, UCL_CHARACTER_WHITESPACE_UNSAFE) ||
1492 			(chunk->remain >= 2 && ucl_lex_is_comment (p[0], p[1]))) {
1493 		while (p < chunk->end && ucl_test_character (*p, UCL_CHARACTER_WHITESPACE_UNSAFE)) {
1494 			ucl_chunk_skipc (chunk, p);
1495 		}
1496 		if (!ucl_skip_comments (parser)) {
1497 			return false;
1498 		}
1499 		p = chunk->pos;
1500 	}
1501 
1502 	while (p < chunk->end) {
1503 		c = p;
1504 		switch (*p) {
1505 		case '"':
1506 			ucl_chunk_skipc (chunk, p);
1507 
1508 			if (!ucl_lex_json_string (parser, chunk, &need_unescape, &ucl_escape,
1509 					&var_expand)) {
1510 				return false;
1511 			}
1512 
1513 			obj = ucl_parser_get_container (parser);
1514 			str_len = chunk->pos - c - 2;
1515 			obj->type = UCL_STRING;
1516 			if ((str_len = ucl_copy_or_store_ptr (parser, c + 1,
1517 					&obj->trash_stack[UCL_TRASH_VALUE],
1518 					&obj->value.sv, str_len, need_unescape, false,
1519 					var_expand)) == -1) {
1520 				return false;
1521 			}
1522 			obj->len = str_len;
1523 
1524 			parser->state = UCL_STATE_AFTER_VALUE;
1525 			p = chunk->pos;
1526 
1527 			return true;
1528 			break;
1529 		case '{':
1530 			obj = ucl_parser_get_container (parser);
1531 			/* We have a new object */
1532 			obj = ucl_parser_add_container (obj, parser, false, parser->stack->level);
1533 			if (obj == NULL) {
1534 				return false;
1535 			}
1536 
1537 			ucl_chunk_skipc (chunk, p);
1538 
1539 			return true;
1540 			break;
1541 		case '[':
1542 			obj = ucl_parser_get_container (parser);
1543 			/* We have a new array */
1544 			obj = ucl_parser_add_container (obj, parser, true, parser->stack->level);
1545 			if (obj == NULL) {
1546 				return false;
1547 			}
1548 
1549 			ucl_chunk_skipc (chunk, p);
1550 
1551 			return true;
1552 			break;
1553 		case ']':
1554 			/* We have the array ending */
1555 			if (parser->stack && parser->stack->obj->type == UCL_ARRAY) {
1556 				parser->state = UCL_STATE_AFTER_VALUE;
1557 				return true;
1558 			}
1559 			else {
1560 				goto parse_string;
1561 			}
1562 			break;
1563 		case '<':
1564 			obj = ucl_parser_get_container (parser);
1565 			/* We have something like multiline value, which must be <<[A-Z]+\n */
1566 			if (chunk->end - p > 3) {
1567 				if (memcmp (p, "<<", 2) == 0) {
1568 					p += 2;
1569 					/* We allow only uppercase characters in multiline definitions */
1570 					while (p < chunk->end && *p >= 'A' && *p <= 'Z') {
1571 						p ++;
1572 					}
1573 					if (*p =='\n') {
1574 						/* Set chunk positions and start multiline parsing */
1575 						c += 2;
1576 						chunk->remain -= p - c;
1577 						chunk->pos = p + 1;
1578 						chunk->column = 0;
1579 						chunk->line ++;
1580 						if ((str_len = ucl_parse_multiline_string (parser, chunk, c,
1581 								p - c, &c, &var_expand)) == 0) {
1582 							ucl_set_err (parser, UCL_ESYNTAX,
1583 									"unterminated multiline value", &parser->err);
1584 							return false;
1585 						}
1586 
1587 						obj->type = UCL_STRING;
1588 						obj->flags |= UCL_OBJECT_MULTILINE;
1589 						if ((str_len = ucl_copy_or_store_ptr (parser, c,
1590 								&obj->trash_stack[UCL_TRASH_VALUE],
1591 								&obj->value.sv, str_len - 1, false,
1592 								false, var_expand)) == -1) {
1593 							return false;
1594 						}
1595 						obj->len = str_len;
1596 
1597 						parser->state = UCL_STATE_AFTER_VALUE;
1598 
1599 						return true;
1600 					}
1601 				}
1602 			}
1603 			/* Fallback to ordinary strings */
1604 		default:
1605 parse_string:
1606 			if (obj == NULL) {
1607 				obj = ucl_parser_get_container (parser);
1608 			}
1609 
1610 			/* Parse atom */
1611 			if (ucl_test_character (*p, UCL_CHARACTER_VALUE_DIGIT_START)) {
1612 				if (!ucl_lex_number (parser, chunk, obj)) {
1613 					if (parser->state == UCL_STATE_ERROR) {
1614 						return false;
1615 					}
1616 				}
1617 				else {
1618 					parser->state = UCL_STATE_AFTER_VALUE;
1619 					return true;
1620 				}
1621 				/* Fallback to normal string */
1622 			}
1623 
1624 			if (!ucl_parse_string_value (parser, chunk, &var_expand,
1625 					&need_unescape)) {
1626 				return false;
1627 			}
1628 			/* Cut trailing spaces */
1629 			stripped_spaces = 0;
1630 			while (ucl_test_character (*(chunk->pos - 1 - stripped_spaces),
1631 					UCL_CHARACTER_WHITESPACE)) {
1632 				stripped_spaces ++;
1633 			}
1634 			str_len = chunk->pos - c - stripped_spaces;
1635 			if (str_len <= 0) {
1636 				ucl_set_err (parser, UCL_ESYNTAX, "string value must not be empty",
1637 						&parser->err);
1638 				return false;
1639 			}
1640 			else if (str_len == 4 && memcmp (c, "null", 4) == 0) {
1641 				obj->len = 0;
1642 				obj->type = UCL_NULL;
1643 			}
1644 			else if (!ucl_maybe_parse_boolean (obj, c, str_len)) {
1645 				obj->type = UCL_STRING;
1646 				if ((str_len = ucl_copy_or_store_ptr (parser, c,
1647 						&obj->trash_stack[UCL_TRASH_VALUE],
1648 						&obj->value.sv, str_len, need_unescape,
1649 						false, var_expand)) == -1) {
1650 					return false;
1651 				}
1652 				obj->len = str_len;
1653 			}
1654 			parser->state = UCL_STATE_AFTER_VALUE;
1655 			p = chunk->pos;
1656 
1657 			return true;
1658 			break;
1659 		}
1660 	}
1661 
1662 	return true;
1663 }
1664 
1665 /**
1666  * Handle after value data
1667  * @param parser
1668  * @param chunk
1669  * @return
1670  */
1671 static bool
1672 ucl_parse_after_value (struct ucl_parser *parser, struct ucl_chunk *chunk)
1673 {
1674 	const unsigned char *p;
1675 	bool got_sep = false;
1676 	struct ucl_stack *st;
1677 
1678 	p = chunk->pos;
1679 
1680 	while (p < chunk->end) {
1681 		if (ucl_test_character (*p, UCL_CHARACTER_WHITESPACE)) {
1682 			/* Skip whitespaces */
1683 			ucl_chunk_skipc (chunk, p);
1684 		}
1685 		else if (chunk->remain >= 2 && ucl_lex_is_comment (p[0], p[1])) {
1686 			/* Skip comment */
1687 			if (!ucl_skip_comments (parser)) {
1688 				return false;
1689 			}
1690 			/* Treat comment as a separator */
1691 			got_sep = true;
1692 			p = chunk->pos;
1693 		}
1694 		else if (ucl_test_character (*p, UCL_CHARACTER_VALUE_END)) {
1695 			if (*p == '}' || *p == ']') {
1696 				if (parser->stack == NULL) {
1697 					ucl_set_err (parser, UCL_ESYNTAX,
1698 							"end of array or object detected without corresponding start",
1699 							&parser->err);
1700 					return false;
1701 				}
1702 				if ((*p == '}' && parser->stack->obj->type == UCL_OBJECT) ||
1703 						(*p == ']' && parser->stack->obj->type == UCL_ARRAY)) {
1704 
1705 					/* Pop all nested objects from a stack */
1706 					st = parser->stack;
1707 					parser->stack = st->next;
1708 					UCL_FREE (sizeof (struct ucl_stack), st);
1709 
1710 					while (parser->stack != NULL) {
1711 						st = parser->stack;
1712 						if (st->next == NULL || st->next->level == st->level) {
1713 							break;
1714 						}
1715 						parser->stack = st->next;
1716 						UCL_FREE (sizeof (struct ucl_stack), st);
1717 					}
1718 				}
1719 				else {
1720 					ucl_set_err (parser, UCL_ESYNTAX,
1721 							"unexpected terminating symbol detected",
1722 							&parser->err);
1723 					return false;
1724 				}
1725 
1726 				if (parser->stack == NULL) {
1727 					/* Ignore everything after a top object */
1728 					return true;
1729 				}
1730 				else {
1731 					ucl_chunk_skipc (chunk, p);
1732 				}
1733 				got_sep = true;
1734 			}
1735 			else {
1736 				/* Got a separator */
1737 				got_sep = true;
1738 				ucl_chunk_skipc (chunk, p);
1739 			}
1740 		}
1741 		else {
1742 			/* Anything else */
1743 			if (!got_sep) {
1744 				ucl_set_err (parser, UCL_ESYNTAX, "delimiter is missing",
1745 						&parser->err);
1746 				return false;
1747 			}
1748 			return true;
1749 		}
1750 	}
1751 
1752 	return true;
1753 }
1754 
1755 /**
1756  * Handle macro data
1757  * @param parser
1758  * @param chunk
1759  * @param marco
1760  * @param macro_start
1761  * @param macro_len
1762  * @return
1763  */
1764 static bool
1765 ucl_parse_macro_value (struct ucl_parser *parser,
1766 		struct ucl_chunk *chunk, struct ucl_macro *macro,
1767 		unsigned char const **macro_start, size_t *macro_len)
1768 {
1769 	const unsigned char *p, *c;
1770 	bool need_unescape = false, ucl_escape = false, var_expand = false;
1771 
1772 	p = chunk->pos;
1773 
1774 	switch (*p) {
1775 	case '"':
1776 		/* We have macro value encoded in quotes */
1777 		c = p;
1778 		ucl_chunk_skipc (chunk, p);
1779 		if (!ucl_lex_json_string (parser, chunk, &need_unescape, &ucl_escape, &var_expand)) {
1780 			return false;
1781 		}
1782 
1783 		*macro_start = c + 1;
1784 		*macro_len = chunk->pos - c - 2;
1785 		p = chunk->pos;
1786 		break;
1787 	case '{':
1788 		/* We got a multiline macro body */
1789 		ucl_chunk_skipc (chunk, p);
1790 		/* Skip spaces at the beginning */
1791 		while (p < chunk->end) {
1792 			if (ucl_test_character (*p, UCL_CHARACTER_WHITESPACE_UNSAFE)) {
1793 				ucl_chunk_skipc (chunk, p);
1794 			}
1795 			else {
1796 				break;
1797 			}
1798 		}
1799 		c = p;
1800 		while (p < chunk->end) {
1801 			if (*p == '}') {
1802 				break;
1803 			}
1804 			ucl_chunk_skipc (chunk, p);
1805 		}
1806 		*macro_start = c;
1807 		*macro_len = p - c;
1808 		ucl_chunk_skipc (chunk, p);
1809 		break;
1810 	default:
1811 		/* Macro is not enclosed in quotes or braces */
1812 		c = p;
1813 		while (p < chunk->end) {
1814 			if (ucl_lex_is_atom_end (*p)) {
1815 				break;
1816 			}
1817 			ucl_chunk_skipc (chunk, p);
1818 		}
1819 		*macro_start = c;
1820 		*macro_len = p - c;
1821 		break;
1822 	}
1823 
1824 	/* We are at the end of a macro */
1825 	/* Skip ';' and space characters and return to previous state */
1826 	while (p < chunk->end) {
1827 		if (!ucl_test_character (*p, UCL_CHARACTER_WHITESPACE_UNSAFE) && *p != ';') {
1828 			break;
1829 		}
1830 		ucl_chunk_skipc (chunk, p);
1831 	}
1832 	return true;
1833 }
1834 
1835 /**
1836  * Parse macro arguments as UCL object
1837  * @param parser parser structure
1838  * @param chunk the current data chunk
1839  * @return
1840  */
1841 static ucl_object_t *
1842 ucl_parse_macro_arguments (struct ucl_parser *parser,
1843 		struct ucl_chunk *chunk)
1844 {
1845 	ucl_object_t *res = NULL;
1846 	struct ucl_parser *params_parser;
1847 	int obraces = 1, ebraces = 0, state = 0;
1848 	const unsigned char *p, *c;
1849 	size_t args_len = 0;
1850 	struct ucl_parser_saved_state saved;
1851 
1852 	saved.column = chunk->column;
1853 	saved.line = chunk->line;
1854 	saved.pos = chunk->pos;
1855 	saved.remain = chunk->remain;
1856 	p = chunk->pos;
1857 
1858 	if (*p != '(' || chunk->remain < 2) {
1859 		return NULL;
1860 	}
1861 
1862 	/* Set begin and start */
1863 	ucl_chunk_skipc (chunk, p);
1864 	c = p;
1865 
1866 	while ((p) < (chunk)->end) {
1867 		switch (state) {
1868 		case 0:
1869 			/* Parse symbols and check for '(', ')' and '"' */
1870 			if (*p == '(') {
1871 				obraces ++;
1872 			}
1873 			else if (*p == ')') {
1874 				ebraces ++;
1875 			}
1876 			else if (*p == '"') {
1877 				state = 1;
1878 			}
1879 			/* Check pairing */
1880 			if (obraces == ebraces) {
1881 				state = 99;
1882 			}
1883 			else {
1884 				args_len ++;
1885 			}
1886 			/* Check overflow */
1887 			if (chunk->remain == 0) {
1888 				goto restore_chunk;
1889 			}
1890 			ucl_chunk_skipc (chunk, p);
1891 			break;
1892 		case 1:
1893 			/* We have quote character, so skip all but quotes */
1894 			if (*p == '"' && *(p - 1) != '\\') {
1895 				state = 0;
1896 			}
1897 			if (chunk->remain == 0) {
1898 				goto restore_chunk;
1899 			}
1900 			args_len ++;
1901 			ucl_chunk_skipc (chunk, p);
1902 			break;
1903 		case 99:
1904 			/*
1905 			 * We have read the full body of arguments, so we need to parse and set
1906 			 * object from that
1907 			 */
1908 			params_parser = ucl_parser_new (parser->flags);
1909 			if (!ucl_parser_add_chunk (params_parser, c, args_len)) {
1910 				ucl_set_err (parser, UCL_ESYNTAX, "macro arguments parsing error",
1911 						&parser->err);
1912 			}
1913 			else {
1914 				res = ucl_parser_get_object (params_parser);
1915 			}
1916 			ucl_parser_free (params_parser);
1917 
1918 			return res;
1919 
1920 			break;
1921 		}
1922 	}
1923 
1924 	return res;
1925 
1926 restore_chunk:
1927 	chunk->column = saved.column;
1928 	chunk->line = saved.line;
1929 	chunk->pos = saved.pos;
1930 	chunk->remain = saved.remain;
1931 
1932 	return NULL;
1933 }
1934 
1935 #define SKIP_SPACES_COMMENTS(parser, chunk, p) do {								\
1936 	while ((p) < (chunk)->end) {												\
1937 		if (!ucl_test_character (*(p), UCL_CHARACTER_WHITESPACE_UNSAFE)) {		\
1938 			if ((chunk)->remain >= 2 && ucl_lex_is_comment ((p)[0], (p)[1])) {	\
1939 				if (!ucl_skip_comments (parser)) {								\
1940 					return false;												\
1941 				}																\
1942 				p = (chunk)->pos;												\
1943 			}																	\
1944 			break;																\
1945 		}																		\
1946 		ucl_chunk_skipc (chunk, p);												\
1947 	}																			\
1948 } while(0)
1949 
1950 /**
1951  * Handle the main states of rcl parser
1952  * @param parser parser structure
1953  * @return true if chunk has been parsed and false in case of error
1954  */
1955 static bool
1956 ucl_state_machine (struct ucl_parser *parser)
1957 {
1958 	ucl_object_t *obj, *macro_args;
1959 	struct ucl_chunk *chunk = parser->chunks;
1960 	const unsigned char *p, *c = NULL, *macro_start = NULL;
1961 	unsigned char *macro_escaped;
1962 	size_t macro_len = 0;
1963 	struct ucl_macro *macro = NULL;
1964 	bool next_key = false, end_of_object = false, ret;
1965 
1966 	if (parser->top_obj == NULL) {
1967 		parser->state = UCL_STATE_INIT;
1968 	}
1969 
1970 	p = chunk->pos;
1971 	while (chunk->pos < chunk->end) {
1972 		switch (parser->state) {
1973 		case UCL_STATE_INIT:
1974 			/*
1975 			 * At the init state we can either go to the parse array or object
1976 			 * if we got [ or { correspondingly or can just treat new data as
1977 			 * a key of newly created object
1978 			 */
1979 			if (!ucl_skip_comments (parser)) {
1980 				parser->prev_state = parser->state;
1981 				parser->state = UCL_STATE_ERROR;
1982 				return false;
1983 			}
1984 			else {
1985 				/* Skip any spaces */
1986 				while (p < chunk->end && ucl_test_character (*p,
1987 						UCL_CHARACTER_WHITESPACE_UNSAFE)) {
1988 					ucl_chunk_skipc (chunk, p);
1989 				}
1990 
1991 				p = chunk->pos;
1992 
1993 				if (*p == '[') {
1994 					parser->state = UCL_STATE_VALUE;
1995 					ucl_chunk_skipc (chunk, p);
1996 				}
1997 				else {
1998 					parser->state = UCL_STATE_KEY;
1999 					if (*p == '{') {
2000 						ucl_chunk_skipc (chunk, p);
2001 					}
2002 				}
2003 
2004 				if (parser->top_obj == NULL) {
2005 					if (parser->state == UCL_STATE_VALUE) {
2006 						obj = ucl_parser_add_container (NULL, parser, true, 0);
2007 					}
2008 					else {
2009 						obj = ucl_parser_add_container (NULL, parser, false, 0);
2010 					}
2011 
2012 					if (obj == NULL) {
2013 						return false;
2014 					}
2015 
2016 					parser->top_obj = obj;
2017 					parser->cur_obj = obj;
2018 				}
2019 
2020 			}
2021 			break;
2022 		case UCL_STATE_KEY:
2023 			/* Skip any spaces */
2024 			while (p < chunk->end && ucl_test_character (*p, UCL_CHARACTER_WHITESPACE_UNSAFE)) {
2025 				ucl_chunk_skipc (chunk, p);
2026 			}
2027 			if (*p == '}') {
2028 				/* We have the end of an object */
2029 				parser->state = UCL_STATE_AFTER_VALUE;
2030 				continue;
2031 			}
2032 			if (parser->stack == NULL) {
2033 				/* No objects are on stack, but we want to parse a key */
2034 				ucl_set_err (parser, UCL_ESYNTAX, "top object is finished but the parser "
2035 						"expects a key", &parser->err);
2036 				parser->prev_state = parser->state;
2037 				parser->state = UCL_STATE_ERROR;
2038 				return false;
2039 			}
2040 			if (!ucl_parse_key (parser, chunk, &next_key, &end_of_object)) {
2041 				parser->prev_state = parser->state;
2042 				parser->state = UCL_STATE_ERROR;
2043 				return false;
2044 			}
2045 			if (end_of_object) {
2046 				p = chunk->pos;
2047 				parser->state = UCL_STATE_AFTER_VALUE;
2048 				continue;
2049 			}
2050 			else if (parser->state != UCL_STATE_MACRO_NAME) {
2051 				if (next_key && parser->stack->obj->type == UCL_OBJECT) {
2052 					/* Parse more keys and nest objects accordingly */
2053 					obj = ucl_parser_add_container (parser->cur_obj, parser, false,
2054 							parser->stack->level + 1);
2055 					if (obj == NULL) {
2056 						return false;
2057 					}
2058 				}
2059 				else {
2060 					parser->state = UCL_STATE_VALUE;
2061 				}
2062 			}
2063 			else {
2064 				c = chunk->pos;
2065 			}
2066 			p = chunk->pos;
2067 			break;
2068 		case UCL_STATE_VALUE:
2069 			/* We need to check what we do have */
2070 			if (!ucl_parse_value (parser, chunk)) {
2071 				parser->prev_state = parser->state;
2072 				parser->state = UCL_STATE_ERROR;
2073 				return false;
2074 			}
2075 			/* State is set in ucl_parse_value call */
2076 			p = chunk->pos;
2077 			break;
2078 		case UCL_STATE_AFTER_VALUE:
2079 			if (!ucl_parse_after_value (parser, chunk)) {
2080 				parser->prev_state = parser->state;
2081 				parser->state = UCL_STATE_ERROR;
2082 				return false;
2083 			}
2084 
2085 			if (parser->stack != NULL) {
2086 				if (parser->stack->obj->type == UCL_OBJECT) {
2087 					parser->state = UCL_STATE_KEY;
2088 				}
2089 				else {
2090 					/* Array */
2091 					parser->state = UCL_STATE_VALUE;
2092 				}
2093 			}
2094 			else {
2095 				/* Skip everything at the end */
2096 				return true;
2097 			}
2098 			p = chunk->pos;
2099 			break;
2100 		case UCL_STATE_MACRO_NAME:
2101 			if (!ucl_test_character (*p, UCL_CHARACTER_WHITESPACE_UNSAFE) &&
2102 					*p != '(') {
2103 				ucl_chunk_skipc (chunk, p);
2104 			}
2105 			else {
2106 				if (p - c > 0) {
2107 					/* We got macro name */
2108 					macro_len = (size_t) (p - c);
2109 					HASH_FIND (hh, parser->macroes, c, macro_len, macro);
2110 					if (macro == NULL) {
2111 						ucl_create_err (&parser->err,
2112 								"error on line %d at column %d: "
2113 										"unknown macro: '%.*s', character: '%c'",
2114 								chunk->line,
2115 								chunk->column,
2116 								(int) (p - c),
2117 								c,
2118 								*chunk->pos);
2119 						parser->state = UCL_STATE_ERROR;
2120 						return false;
2121 					}
2122 					/* Now we need to skip all spaces */
2123 					SKIP_SPACES_COMMENTS(parser, chunk, p);
2124 					parser->state = UCL_STATE_MACRO;
2125 				}
2126 				else {
2127 					/* We have invalid macro name */
2128 					ucl_create_err (&parser->err,
2129 							"error on line %d at column %d: invalid macro name",
2130 							chunk->line,
2131 							chunk->column);
2132 					parser->state = UCL_STATE_ERROR;
2133 					return false;
2134 				}
2135 			}
2136 			break;
2137 		case UCL_STATE_MACRO:
2138 			if (*chunk->pos == '(') {
2139 				macro_args = ucl_parse_macro_arguments (parser, chunk);
2140 				p = chunk->pos;
2141 				if (macro_args) {
2142 					SKIP_SPACES_COMMENTS(parser, chunk, p);
2143 				}
2144 			}
2145 			else {
2146 				macro_args = NULL;
2147 			}
2148 			if (!ucl_parse_macro_value (parser, chunk, macro,
2149 					&macro_start, &macro_len)) {
2150 				parser->prev_state = parser->state;
2151 				parser->state = UCL_STATE_ERROR;
2152 				return false;
2153 			}
2154 			macro_len = ucl_expand_variable (parser, &macro_escaped,
2155 					macro_start, macro_len);
2156 			parser->state = parser->prev_state;
2157 			if (macro_escaped == NULL) {
2158 				if (macro->is_context) {
2159 					ret = macro->h.context_handler (macro_start, macro_len,
2160 							macro_args,
2161 							parser->top_obj,
2162 							macro->ud);
2163 				}
2164 				else {
2165 					ret = macro->h.handler (macro_start, macro_len, macro_args,
2166 							macro->ud);
2167 				}
2168 			}
2169 			else {
2170 				if (macro->is_context) {
2171 					ret = macro->h.context_handler (macro_escaped, macro_len,
2172 							macro_args,
2173 							parser->top_obj,
2174 							macro->ud);
2175 				}
2176 				else {
2177 					ret = macro->h.handler (macro_escaped, macro_len, macro_args,
2178 						macro->ud);
2179 				}
2180 
2181 				UCL_FREE (macro_len + 1, macro_escaped);
2182 			}
2183 
2184 			/*
2185 			 * Chunk can be modified within macro handler
2186 			 */
2187 			chunk = parser->chunks;
2188 			p = chunk->pos;
2189 			if (macro_args) {
2190 				ucl_object_unref (macro_args);
2191 			}
2192 			if (!ret) {
2193 				return false;
2194 			}
2195 			break;
2196 		default:
2197 			/* TODO: add all states */
2198 			ucl_set_err (parser, UCL_EINTERNAL,
2199 					"internal error: parser is in an unknown state", &parser->err);
2200 			parser->state = UCL_STATE_ERROR;
2201 			return false;
2202 		}
2203 	}
2204 
2205 	return true;
2206 }
2207 
2208 struct ucl_parser*
2209 ucl_parser_new (int flags)
2210 {
2211 	struct ucl_parser *new;
2212 
2213 	new = UCL_ALLOC (sizeof (struct ucl_parser));
2214 	if (new == NULL) {
2215 		return NULL;
2216 	}
2217 
2218 	memset (new, 0, sizeof (struct ucl_parser));
2219 
2220 	ucl_parser_register_macro (new, "include", ucl_include_handler, new);
2221 	ucl_parser_register_macro (new, "try_include", ucl_try_include_handler, new);
2222 	ucl_parser_register_macro (new, "includes", ucl_includes_handler, new);
2223 	ucl_parser_register_macro (new, "priority", ucl_priority_handler, new);
2224 	ucl_parser_register_macro (new, "load", ucl_load_handler, new);
2225 	ucl_parser_register_context_macro (new, "inherit", ucl_inherit_handler, new);
2226 
2227 	new->flags = flags;
2228 	new->includepaths = NULL;
2229 
2230 	/* Initial assumption about filevars */
2231 	ucl_parser_set_filevars (new, NULL, false);
2232 
2233 	return new;
2234 }
2235 
2236 bool
2237 ucl_parser_set_default_priority (struct ucl_parser *parser, unsigned prio)
2238 {
2239 	if (parser == NULL) {
2240 		return false;
2241 	}
2242 
2243 	parser->default_priority = prio;
2244 
2245 	return true;
2246 }
2247 
2248 void
2249 ucl_parser_register_macro (struct ucl_parser *parser, const char *macro,
2250 		ucl_macro_handler handler, void* ud)
2251 {
2252 	struct ucl_macro *new;
2253 
2254 	if (macro == NULL || handler == NULL) {
2255 		return;
2256 	}
2257 
2258 	new = UCL_ALLOC (sizeof (struct ucl_macro));
2259 	if (new == NULL) {
2260 		return;
2261 	}
2262 
2263 	memset (new, 0, sizeof (struct ucl_macro));
2264 	new->h.handler = handler;
2265 	new->name = strdup (macro);
2266 	new->ud = ud;
2267 	HASH_ADD_KEYPTR (hh, parser->macroes, new->name, strlen (new->name), new);
2268 }
2269 
2270 void
2271 ucl_parser_register_context_macro (struct ucl_parser *parser, const char *macro,
2272 		ucl_context_macro_handler handler, void* ud)
2273 {
2274 	struct ucl_macro *new;
2275 
2276 	if (macro == NULL || handler == NULL) {
2277 		return;
2278 	}
2279 
2280 	new = UCL_ALLOC (sizeof (struct ucl_macro));
2281 	if (new == NULL) {
2282 		return;
2283 	}
2284 
2285 	memset (new, 0, sizeof (struct ucl_macro));
2286 	new->h.context_handler = handler;
2287 	new->name = strdup (macro);
2288 	new->ud = ud;
2289 	new->is_context = true;
2290 	HASH_ADD_KEYPTR (hh, parser->macroes, new->name, strlen (new->name), new);
2291 }
2292 
2293 void
2294 ucl_parser_register_variable (struct ucl_parser *parser, const char *var,
2295 		const char *value)
2296 {
2297 	struct ucl_variable *new = NULL, *cur;
2298 
2299 	if (var == NULL) {
2300 		return;
2301 	}
2302 
2303 	/* Find whether a variable already exists */
2304 	LL_FOREACH (parser->variables, cur) {
2305 		if (strcmp (cur->var, var) == 0) {
2306 			new = cur;
2307 			break;
2308 		}
2309 	}
2310 
2311 	if (value == NULL) {
2312 
2313 		if (new != NULL) {
2314 			/* Remove variable */
2315 			DL_DELETE (parser->variables, new);
2316 			free (new->var);
2317 			free (new->value);
2318 			UCL_FREE (sizeof (struct ucl_variable), new);
2319 		}
2320 		else {
2321 			/* Do nothing */
2322 			return;
2323 		}
2324 	}
2325 	else {
2326 		if (new == NULL) {
2327 			new = UCL_ALLOC (sizeof (struct ucl_variable));
2328 			if (new == NULL) {
2329 				return;
2330 			}
2331 			memset (new, 0, sizeof (struct ucl_variable));
2332 			new->var = strdup (var);
2333 			new->var_len = strlen (var);
2334 			new->value = strdup (value);
2335 			new->value_len = strlen (value);
2336 
2337 			DL_APPEND (parser->variables, new);
2338 		}
2339 		else {
2340 			free (new->value);
2341 			new->value = strdup (value);
2342 			new->value_len = strlen (value);
2343 		}
2344 	}
2345 }
2346 
2347 void
2348 ucl_parser_set_variables_handler (struct ucl_parser *parser,
2349 		ucl_variable_handler handler, void *ud)
2350 {
2351 	parser->var_handler = handler;
2352 	parser->var_data = ud;
2353 }
2354 
2355 bool
2356 ucl_parser_add_chunk_full (struct ucl_parser *parser, const unsigned char *data,
2357 		size_t len, unsigned priority, enum ucl_duplicate_strategy strat,
2358 		enum ucl_parse_type parse_type)
2359 {
2360 	struct ucl_chunk *chunk;
2361 
2362 	if (parser == NULL) {
2363 		return false;
2364 	}
2365 
2366 	if (data == NULL) {
2367 		ucl_create_err (&parser->err, "invalid chunk added");
2368 		return false;
2369 	}
2370 	if (len == 0) {
2371 		parser->top_obj = ucl_object_new_full (UCL_OBJECT, priority);
2372 		return true;
2373 	}
2374 	if (parser->state != UCL_STATE_ERROR) {
2375 		chunk = UCL_ALLOC (sizeof (struct ucl_chunk));
2376 		if (chunk == NULL) {
2377 			ucl_create_err (&parser->err, "cannot allocate chunk structure");
2378 			return false;
2379 		}
2380 		chunk->begin = data;
2381 		chunk->remain = len;
2382 		chunk->pos = chunk->begin;
2383 		chunk->end = chunk->begin + len;
2384 		chunk->line = 1;
2385 		chunk->column = 0;
2386 		chunk->priority = priority;
2387 		chunk->strategy = strat;
2388 		chunk->parse_type = parse_type;
2389 		LL_PREPEND (parser->chunks, chunk);
2390 		parser->recursion ++;
2391 
2392 		if (parser->recursion > UCL_MAX_RECURSION) {
2393 			ucl_create_err (&parser->err, "maximum include nesting limit is reached: %d",
2394 					parser->recursion);
2395 			return false;
2396 		}
2397 
2398 		switch (parse_type) {
2399 		default:
2400 		case UCL_PARSE_UCL:
2401 			return ucl_state_machine (parser);
2402 		case UCL_PARSE_MSGPACK:
2403 			return ucl_parse_msgpack (parser);
2404 		}
2405 	}
2406 
2407 	ucl_create_err (&parser->err, "a parser is in an invalid state");
2408 
2409 	return false;
2410 }
2411 
2412 bool
2413 ucl_parser_add_chunk_priority (struct ucl_parser *parser,
2414 		const unsigned char *data, size_t len, unsigned priority)
2415 {
2416 	/* We dereference parser, so this check is essential */
2417 	if (parser == NULL) {
2418 		return false;
2419 	}
2420 
2421 	return ucl_parser_add_chunk_full (parser, data, len,
2422 				priority, UCL_DUPLICATE_APPEND, UCL_PARSE_UCL);
2423 }
2424 
2425 bool
2426 ucl_parser_add_chunk (struct ucl_parser *parser, const unsigned char *data,
2427 		size_t len)
2428 {
2429 	if (parser == NULL) {
2430 		return false;
2431 	}
2432 
2433 	return ucl_parser_add_chunk_full (parser, data, len,
2434 			parser->default_priority, UCL_DUPLICATE_APPEND, UCL_PARSE_UCL);
2435 }
2436 
2437 bool
2438 ucl_parser_add_string_priority (struct ucl_parser *parser, const char *data,
2439 		size_t len, unsigned priority)
2440 {
2441 	if (data == NULL) {
2442 		ucl_create_err (&parser->err, "invalid string added");
2443 		return false;
2444 	}
2445 	if (len == 0) {
2446 		len = strlen (data);
2447 	}
2448 
2449 	return ucl_parser_add_chunk_priority (parser,
2450 			(const unsigned char *)data, len, priority);
2451 }
2452 
2453 bool
2454 ucl_parser_add_string (struct ucl_parser *parser, const char *data,
2455 		size_t len)
2456 {
2457 	if (parser == NULL) {
2458 		return false;
2459 	}
2460 
2461 	return ucl_parser_add_string_priority (parser,
2462 			(const unsigned char *)data, len, parser->default_priority);
2463 }
2464 
2465 bool
2466 ucl_set_include_path (struct ucl_parser *parser, ucl_object_t *paths)
2467 {
2468 	if (parser == NULL || paths == NULL) {
2469 		return false;
2470 	}
2471 
2472 	if (parser->includepaths == NULL) {
2473 		parser->includepaths = ucl_object_copy (paths);
2474 	}
2475 	else {
2476 		ucl_object_unref (parser->includepaths);
2477 		parser->includepaths = ucl_object_copy (paths);
2478 	}
2479 
2480 	if (parser->includepaths == NULL) {
2481 		return false;
2482 	}
2483 
2484 	return true;
2485 }
2486