Deleted Added
full compact
ucl_parser.c (263019) ucl_parser.c (268896)
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

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

50 (chunk)->column = 0; \
51 } \
52 else (chunk)->column ++; \
53 (p++); \
54 (chunk)->pos ++; \
55 (chunk)->remain --; \
56 } while (0)
57
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

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

50 (chunk)->column = 0; \
51 } \
52 else (chunk)->column ++; \
53 (p++); \
54 (chunk)->pos ++; \
55 (chunk)->remain --; \
56 } while (0)
57
58/**
59 * Save parser state
60 * @param chunk
61 * @param s
62 */
63static inline void
58static inline void
64ucl_chunk_save_state (struct ucl_chunk *chunk, struct ucl_parser_saved_state *s)
65{
66 s->column = chunk->column;
67 s->pos = chunk->pos;
68 s->line = chunk->line;
69 s->remain = chunk->remain;
70}
71
72/**
73 * Restore parser state
74 * @param chunk
75 * @param s
76 */
77static inline void
78ucl_chunk_restore_state (struct ucl_chunk *chunk, struct ucl_parser_saved_state *s)
79{
80 chunk->column = s->column;
81 chunk->pos = s->pos;
82 chunk->line = s->line;
83 chunk->remain = s->remain;
84}
85
86static inline void
87ucl_set_err (struct ucl_chunk *chunk, int code, const char *str, UT_string **err)
88{
89 if (chunk->pos < chunk->end) {
90 if (isgraph (*chunk->pos)) {
91 ucl_create_err (err, "error on line %d at column %d: '%s', character: '%c'",
92 chunk->line, chunk->column, str, *chunk->pos);
93 }
94 else {

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

259 * @param found
260 * @return
261 */
262static inline const char *
263ucl_check_variable_safe (struct ucl_parser *parser, const char *ptr, size_t remain,
264 size_t *out_len, bool strict, bool *found)
265{
266 struct ucl_variable *var;
59ucl_set_err (struct ucl_chunk *chunk, int code, const char *str, UT_string **err)
60{
61 if (chunk->pos < chunk->end) {
62 if (isgraph (*chunk->pos)) {
63 ucl_create_err (err, "error on line %d at column %d: '%s', character: '%c'",
64 chunk->line, chunk->column, str, *chunk->pos);
65 }
66 else {

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

231 * @param found
232 * @return
233 */
234static inline const char *
235ucl_check_variable_safe (struct ucl_parser *parser, const char *ptr, size_t remain,
236 size_t *out_len, bool strict, bool *found)
237{
238 struct ucl_variable *var;
239 unsigned char *dst;
240 size_t dstlen;
241 bool need_free = false;
267
268 LL_FOREACH (parser->variables, var) {
269 if (strict) {
270 if (remain == var->var_len) {
271 if (memcmp (ptr, var->var, var->var_len) == 0) {
272 *out_len += var->value_len;
273 *found = true;
274 return (ptr + var->var_len);

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

281 *out_len += var->value_len;
282 *found = true;
283 return (ptr + var->var_len);
284 }
285 }
286 }
287 }
288
242
243 LL_FOREACH (parser->variables, var) {
244 if (strict) {
245 if (remain == var->var_len) {
246 if (memcmp (ptr, var->var, var->var_len) == 0) {
247 *out_len += var->value_len;
248 *found = true;
249 return (ptr + var->var_len);

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

256 *out_len += var->value_len;
257 *found = true;
258 return (ptr + var->var_len);
259 }
260 }
261 }
262 }
263
264 /* XXX: can only handle ${VAR} */
265 if (!(*found) && parser->var_handler != NULL && strict) {
266 /* Call generic handler */
267 if (parser->var_handler (ptr, remain, &dst, &dstlen, &need_free,
268 parser->var_data)) {
269 *found = true;
270 if (need_free) {
271 free (dst);
272 }
273 return (ptr + remain);
274 }
275 }
276
289 return ptr;
290}
291
292/**
293 * Check for a variable in a given string
294 * @param parser
295 * @param ptr
296 * @param remain
297 * @param out_len
298 * @param vars_found
299 * @return
300 */
301static const char *
277 return ptr;
278}
279
280/**
281 * Check for a variable in a given string
282 * @param parser
283 * @param ptr
284 * @param remain
285 * @param out_len
286 * @param vars_found
287 * @return
288 */
289static const char *
302ucl_check_variable (struct ucl_parser *parser, const char *ptr, size_t remain, size_t *out_len, bool *vars_found)
290ucl_check_variable (struct ucl_parser *parser, const char *ptr,
291 size_t remain, size_t *out_len, bool *vars_found)
303{
304 const char *p, *end, *ret = ptr;
305 bool found = false;
306
307 if (*ptr == '{') {
308 /* We need to match the variable enclosed in braces */
309 p = ptr + 1;
310 end = ptr + remain;
311 while (p < end) {
312 if (*p == '}') {
292{
293 const char *p, *end, *ret = ptr;
294 bool found = false;
295
296 if (*ptr == '{') {
297 /* We need to match the variable enclosed in braces */
298 p = ptr + 1;
299 end = ptr + remain;
300 while (p < end) {
301 if (*p == '}') {
313 ret = ucl_check_variable_safe (parser, ptr + 1, p - ptr - 1, out_len, true, &found);
302 ret = ucl_check_variable_safe (parser, ptr + 1, p - ptr - 1,
303 out_len, true, &found);
314 if (found) {
315 /* {} must be excluded actually */
316 ret ++;
317 if (!*vars_found) {
318 *vars_found = true;
319 }
320 }
321 else {

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

351 * @param remain
352 * @param dest
353 * @return
354 */
355static const char *
356ucl_expand_single_variable (struct ucl_parser *parser, const char *ptr,
357 size_t remain, unsigned char **dest)
358{
304 if (found) {
305 /* {} must be excluded actually */
306 ret ++;
307 if (!*vars_found) {
308 *vars_found = true;
309 }
310 }
311 else {

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

341 * @param remain
342 * @param dest
343 * @return
344 */
345static const char *
346ucl_expand_single_variable (struct ucl_parser *parser, const char *ptr,
347 size_t remain, unsigned char **dest)
348{
359 unsigned char *d = *dest;
349 unsigned char *d = *dest, *dst;
360 const char *p = ptr + 1, *ret;
361 struct ucl_variable *var;
350 const char *p = ptr + 1, *ret;
351 struct ucl_variable *var;
352 size_t dstlen;
353 bool need_free = false;
362 bool found = false;
354 bool found = false;
355 bool strict = false;
363
364 ret = ptr + 1;
365 remain --;
366
367 if (*p == '$') {
368 *d++ = *p++;
369 *dest = d;
370 return p;
371 }
372 else if (*p == '{') {
373 p ++;
356
357 ret = ptr + 1;
358 remain --;
359
360 if (*p == '$') {
361 *d++ = *p++;
362 *dest = d;
363 return p;
364 }
365 else if (*p == '{') {
366 p ++;
367 strict = true;
374 ret += 2;
375 remain -= 2;
376 }
377
378 LL_FOREACH (parser->variables, var) {
379 if (remain >= var->var_len) {
380 if (memcmp (p, var->var, var->var_len) == 0) {
381 memcpy (d, var->value, var->value_len);
382 ret += var->var_len;
383 d += var->value_len;
384 found = true;
385 break;
386 }
387 }
388 }
389 if (!found) {
368 ret += 2;
369 remain -= 2;
370 }
371
372 LL_FOREACH (parser->variables, var) {
373 if (remain >= var->var_len) {
374 if (memcmp (p, var->var, var->var_len) == 0) {
375 memcpy (d, var->value, var->value_len);
376 ret += var->var_len;
377 d += var->value_len;
378 found = true;
379 break;
380 }
381 }
382 }
383 if (!found) {
390 memcpy (d, ptr, 2);
391 d += 2;
392 ret --;
384 if (strict && parser->var_handler != NULL) {
385 if (parser->var_handler (ptr, remain, &dst, &dstlen, &need_free,
386 parser->var_data)) {
387 memcpy (d, dst, dstlen);
388 ret += dstlen;
389 d += remain;
390 found = true;
391 }
392 }
393
394 /* Leave variable as is */
395 if (!found) {
396 memcpy (d, ptr, 2);
397 d += 2;
398 ret --;
399 }
393 }
394
395 *dest = d;
396 return ret;
397}
398
399/**
400 * Expand variables in string

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

539 }
540 else {
541 obj->type = UCL_ARRAY;
542 }
543 parser->state = UCL_STATE_VALUE;
544 }
545
546 st = UCL_ALLOC (sizeof (struct ucl_stack));
400 }
401
402 *dest = d;
403 return ret;
404}
405
406/**
407 * Expand variables in string

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

546 }
547 else {
548 obj->type = UCL_ARRAY;
549 }
550 parser->state = UCL_STATE_VALUE;
551 }
552
553 st = UCL_ALLOC (sizeof (struct ucl_stack));
554 if (st == NULL) {
555 ucl_set_err (parser->chunks, 0, "cannot allocate memory for an object", &parser->err);
556 return NULL;
557 }
547 st->obj = obj;
548 st->level = level;
549 LL_PREPEND (parser->stack, st);
550 parser->cur_obj = obj;
551
552 return obj;
553}
554
555int
556ucl_maybe_parse_number (ucl_object_t *obj,
558 st->obj = obj;
559 st->level = level;
560 LL_PREPEND (parser->stack, st);
561 parser->cur_obj = obj;
562
563 return obj;
564}
565
566int
567ucl_maybe_parse_number (ucl_object_t *obj,
557 const char *start, const char *end, const char **pos, bool allow_double, bool number_bytes)
568 const char *start, const char *end, const char **pos,
569 bool allow_double, bool number_bytes, bool allow_time)
558{
559 const char *p = start, *c = start;
560 char *endptr;
561 bool got_dot = false, got_exp = false, need_double = false,
570{
571 const char *p = start, *c = start;
572 char *endptr;
573 bool got_dot = false, got_exp = false, need_double = false,
562 is_date = false, valid_start = false, is_hex = false,
574 is_time = false, valid_start = false, is_hex = false,
563 is_neg = false;
564 double dv = 0;
565 int64_t lv = 0;
566
567 if (*p == '-') {
568 is_neg = true;
569 c ++;
570 p ++;

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

652 }
653 }
654 if (errno == ERANGE) {
655 *pos = start;
656 return ERANGE;
657 }
658
659 /* Now check endptr */
575 is_neg = false;
576 double dv = 0;
577 int64_t lv = 0;
578
579 if (*p == '-') {
580 is_neg = true;
581 c ++;
582 p ++;

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

664 }
665 }
666 if (errno == ERANGE) {
667 *pos = start;
668 return ERANGE;
669 }
670
671 /* Now check endptr */
660 if (endptr == NULL || ucl_lex_is_atom_end (*endptr) || *endptr == '\0') {
672 if (endptr == NULL || ucl_lex_is_atom_end (*endptr) || *endptr == '\0' ||
673 ucl_test_character (*endptr, UCL_CHARACTER_WHITESPACE_UNSAFE)) {
661 p = endptr;
662 goto set_obj;
663 }
664
665 if (endptr < end && endptr != start) {
666 p = endptr;
667 switch (*p) {
668 case 'm':

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

673 case 'K':
674 if (end - p >= 2) {
675 if (p[1] == 's' || p[1] == 'S') {
676 /* Milliseconds */
677 if (!need_double) {
678 need_double = true;
679 dv = lv;
680 }
674 p = endptr;
675 goto set_obj;
676 }
677
678 if (endptr < end && endptr != start) {
679 p = endptr;
680 switch (*p) {
681 case 'm':

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

686 case 'K':
687 if (end - p >= 2) {
688 if (p[1] == 's' || p[1] == 'S') {
689 /* Milliseconds */
690 if (!need_double) {
691 need_double = true;
692 dv = lv;
693 }
681 is_date = true;
694 is_time = true;
682 if (p[0] == 'm' || p[0] == 'M') {
683 dv /= 1000.;
684 }
685 else {
686 dv *= ucl_lex_num_multiplier (*p, false);
687 }
688 p += 2;
689 goto set_obj;

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

703 dv *= ucl_lex_num_multiplier (*p, false);
704 }
705 else {
706 lv *= ucl_lex_num_multiplier (*p, number_bytes);
707 }
708 p ++;
709 goto set_obj;
710 }
695 if (p[0] == 'm' || p[0] == 'M') {
696 dv /= 1000.;
697 }
698 else {
699 dv *= ucl_lex_num_multiplier (*p, false);
700 }
701 p += 2;
702 goto set_obj;

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

716 dv *= ucl_lex_num_multiplier (*p, false);
717 }
718 else {
719 lv *= ucl_lex_num_multiplier (*p, number_bytes);
720 }
721 p ++;
722 goto set_obj;
723 }
711 else if (end - p >= 3) {
724 else if (allow_time && end - p >= 3) {
712 if (tolower (p[0]) == 'm' &&
713 tolower (p[1]) == 'i' &&
714 tolower (p[2]) == 'n') {
715 /* Minutes */
716 if (!need_double) {
717 need_double = true;
718 dv = lv;
719 }
725 if (tolower (p[0]) == 'm' &&
726 tolower (p[1]) == 'i' &&
727 tolower (p[2]) == 'n') {
728 /* Minutes */
729 if (!need_double) {
730 need_double = true;
731 dv = lv;
732 }
720 is_date = true;
733 is_time = true;
721 dv *= 60.;
722 p += 3;
723 goto set_obj;
724 }
725 }
726 }
727 else {
728 if (need_double) {
729 dv *= ucl_lex_num_multiplier (*p, false);
730 }
731 else {
732 lv *= ucl_lex_num_multiplier (*p, number_bytes);
733 }
734 p ++;
735 goto set_obj;
736 }
737 break;
738 case 'S':
739 case 's':
734 dv *= 60.;
735 p += 3;
736 goto set_obj;
737 }
738 }
739 }
740 else {
741 if (need_double) {
742 dv *= ucl_lex_num_multiplier (*p, false);
743 }
744 else {
745 lv *= ucl_lex_num_multiplier (*p, number_bytes);
746 }
747 p ++;
748 goto set_obj;
749 }
750 break;
751 case 'S':
752 case 's':
740 if (p == end - 1 || ucl_lex_is_atom_end (p[1])) {
753 if (allow_time &&
754 (p == end - 1 || ucl_lex_is_atom_end (p[1]))) {
741 if (!need_double) {
742 need_double = true;
743 dv = lv;
744 }
745 p ++;
755 if (!need_double) {
756 need_double = true;
757 dv = lv;
758 }
759 p ++;
746 is_date = true;
760 is_time = true;
747 goto set_obj;
748 }
749 break;
750 case 'h':
751 case 'H':
752 case 'd':
753 case 'D':
754 case 'w':
755 case 'W':
756 case 'Y':
757 case 'y':
761 goto set_obj;
762 }
763 break;
764 case 'h':
765 case 'H':
766 case 'd':
767 case 'D':
768 case 'w':
769 case 'W':
770 case 'Y':
771 case 'y':
758 if (p == end - 1 || ucl_lex_is_atom_end (p[1])) {
772 if (allow_time &&
773 (p == end - 1 || ucl_lex_is_atom_end (p[1]))) {
759 if (!need_double) {
760 need_double = true;
761 dv = lv;
762 }
774 if (!need_double) {
775 need_double = true;
776 dv = lv;
777 }
763 is_date = true;
778 is_time = true;
764 dv *= ucl_lex_time_multiplier (*p);
765 p ++;
766 goto set_obj;
767 }
768 break;
769 }
770 }
771
772 *pos = c;
773 return EINVAL;
774
775 set_obj:
779 dv *= ucl_lex_time_multiplier (*p);
780 p ++;
781 goto set_obj;
782 }
783 break;
784 }
785 }
786
787 *pos = c;
788 return EINVAL;
789
790 set_obj:
776 if (allow_double && (need_double || is_date)) {
777 if (!is_date) {
791 if (allow_double && (need_double || is_time)) {
792 if (!is_time) {
778 obj->type = UCL_FLOAT;
779 }
780 else {
781 obj->type = UCL_TIME;
782 }
783 obj->value.dv = is_neg ? (-dv) : dv;
784 }
785 else {

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

798 */
799static bool
800ucl_lex_number (struct ucl_parser *parser,
801 struct ucl_chunk *chunk, ucl_object_t *obj)
802{
803 const unsigned char *pos;
804 int ret;
805
793 obj->type = UCL_FLOAT;
794 }
795 else {
796 obj->type = UCL_TIME;
797 }
798 obj->value.dv = is_neg ? (-dv) : dv;
799 }
800 else {

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

813 */
814static bool
815ucl_lex_number (struct ucl_parser *parser,
816 struct ucl_chunk *chunk, ucl_object_t *obj)
817{
818 const unsigned char *pos;
819 int ret;
820
806 ret = ucl_maybe_parse_number (obj, chunk->pos, chunk->end, (const char **)&pos, true, false);
821 ret = ucl_maybe_parse_number (obj, chunk->pos, chunk->end, (const char **)&pos,
822 true, false, ((parser->flags & UCL_PARSER_NO_TIME) == 0));
807
808 if (ret == 0) {
809 chunk->remain -= pos - chunk->pos;
810 chunk->column += pos - chunk->pos;
811 chunk->pos = pos;
812 return true;
813 }
814 else if (ret == ERANGE) {

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

1072 }
1073 }
1074
1075 /* Create a new object */
1076 nobj = ucl_object_new ();
1077 keylen = ucl_copy_or_store_ptr (parser, c, &nobj->trash_stack[UCL_TRASH_KEY],
1078 &key, end - c, need_unescape, parser->flags & UCL_PARSER_KEY_LOWERCASE, false);
1079 if (keylen == -1) {
823
824 if (ret == 0) {
825 chunk->remain -= pos - chunk->pos;
826 chunk->column += pos - chunk->pos;
827 chunk->pos = pos;
828 return true;
829 }
830 else if (ret == ERANGE) {

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

1088 }
1089 }
1090
1091 /* Create a new object */
1092 nobj = ucl_object_new ();
1093 keylen = ucl_copy_or_store_ptr (parser, c, &nobj->trash_stack[UCL_TRASH_KEY],
1094 &key, end - c, need_unescape, parser->flags & UCL_PARSER_KEY_LOWERCASE, false);
1095 if (keylen == -1) {
1080 ucl_object_free(nobj);
1096 ucl_object_unref (nobj);
1081 return false;
1082 }
1083 else if (keylen == 0) {
1084 ucl_set_err (chunk, UCL_ESYNTAX, "empty keys are not allowed", &parser->err);
1097 return false;
1098 }
1099 else if (keylen == 0) {
1100 ucl_set_err (chunk, UCL_ESYNTAX, "empty keys are not allowed", &parser->err);
1085 ucl_object_free(nobj);
1101 ucl_object_unref (nobj);
1086 return false;
1087 }
1088
1089 container = parser->stack->obj->value.ov;
1090 nobj->key = key;
1091 nobj->keylen = keylen;
1102 return false;
1103 }
1104
1105 container = parser->stack->obj->value.ov;
1106 nobj->key = key;
1107 nobj->keylen = keylen;
1092 tobj = ucl_hash_search_obj (container, nobj);
1108 tobj = __DECONST (ucl_object_t *, ucl_hash_search_obj (container, nobj));
1093 if (tobj == NULL) {
1094 container = ucl_hash_insert_object (container, nobj);
1095 nobj->prev = nobj;
1096 nobj->next = NULL;
1097 parser->stack->obj->len ++;
1098 }
1099 else {
1100 DL_APPEND (tobj, nobj);

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

1303 parser->state = UCL_STATE_AFTER_VALUE;
1304 p = chunk->pos;
1305 return true;
1306 break;
1307 case '{':
1308 obj = ucl_get_value_object (parser);
1309 /* We have a new object */
1310 obj = ucl_add_parser_stack (obj, parser, false, parser->stack->level);
1109 if (tobj == NULL) {
1110 container = ucl_hash_insert_object (container, nobj);
1111 nobj->prev = nobj;
1112 nobj->next = NULL;
1113 parser->stack->obj->len ++;
1114 }
1115 else {
1116 DL_APPEND (tobj, nobj);

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

1319 parser->state = UCL_STATE_AFTER_VALUE;
1320 p = chunk->pos;
1321 return true;
1322 break;
1323 case '{':
1324 obj = ucl_get_value_object (parser);
1325 /* We have a new object */
1326 obj = ucl_add_parser_stack (obj, parser, false, parser->stack->level);
1327 if (obj == NULL) {
1328 return false;
1329 }
1311
1312 ucl_chunk_skipc (chunk, p);
1313 return true;
1314 break;
1315 case '[':
1316 obj = ucl_get_value_object (parser);
1317 /* We have a new array */
1318 obj = ucl_add_parser_stack (obj, parser, true, parser->stack->level);
1330
1331 ucl_chunk_skipc (chunk, p);
1332 return true;
1333 break;
1334 case '[':
1335 obj = ucl_get_value_object (parser);
1336 /* We have a new array */
1337 obj = ucl_add_parser_stack (obj, parser, true, parser->stack->level);
1338 if (obj == NULL) {
1339 return false;
1340 }
1319
1320 ucl_chunk_skipc (chunk, p);
1321 return true;
1322 break;
1323 case ']':
1324 /* We have the array ending */
1325 if (parser->stack && parser->stack->obj->type == UCL_ARRAY) {
1326 parser->state = UCL_STATE_AFTER_VALUE;

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

1603
1604 if (parser->top_obj == NULL) {
1605 if (*chunk->pos == '[') {
1606 obj = ucl_add_parser_stack (NULL, parser, true, 0);
1607 }
1608 else {
1609 obj = ucl_add_parser_stack (NULL, parser, false, 0);
1610 }
1341
1342 ucl_chunk_skipc (chunk, p);
1343 return true;
1344 break;
1345 case ']':
1346 /* We have the array ending */
1347 if (parser->stack && parser->stack->obj->type == UCL_ARRAY) {
1348 parser->state = UCL_STATE_AFTER_VALUE;

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

1625
1626 if (parser->top_obj == NULL) {
1627 if (*chunk->pos == '[') {
1628 obj = ucl_add_parser_stack (NULL, parser, true, 0);
1629 }
1630 else {
1631 obj = ucl_add_parser_stack (NULL, parser, false, 0);
1632 }
1633 if (obj == NULL) {
1634 return false;
1635 }
1611 parser->top_obj = obj;
1612 parser->cur_obj = obj;
1613 parser->state = UCL_STATE_INIT;
1614 }
1615
1616 p = chunk->pos;
1617 while (chunk->pos < chunk->end) {
1618 switch (parser->state) {

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

1668 if (end_of_object) {
1669 p = chunk->pos;
1670 parser->state = UCL_STATE_AFTER_VALUE;
1671 continue;
1672 }
1673 else if (parser->state != UCL_STATE_MACRO_NAME) {
1674 if (next_key && parser->stack->obj->type == UCL_OBJECT) {
1675 /* Parse more keys and nest objects accordingly */
1636 parser->top_obj = obj;
1637 parser->cur_obj = obj;
1638 parser->state = UCL_STATE_INIT;
1639 }
1640
1641 p = chunk->pos;
1642 while (chunk->pos < chunk->end) {
1643 switch (parser->state) {

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

1693 if (end_of_object) {
1694 p = chunk->pos;
1695 parser->state = UCL_STATE_AFTER_VALUE;
1696 continue;
1697 }
1698 else if (parser->state != UCL_STATE_MACRO_NAME) {
1699 if (next_key && parser->stack->obj->type == UCL_OBJECT) {
1700 /* Parse more keys and nest objects accordingly */
1676 obj = ucl_add_parser_stack (parser->cur_obj, parser, false, parser->stack->level + 1);
1701 obj = ucl_add_parser_stack (parser->cur_obj, parser, false,
1702 parser->stack->level + 1);
1703 if (obj == NULL) {
1704 return false;
1705 }
1677 }
1678 else {
1679 parser->state = UCL_STATE_VALUE;
1680 }
1681 }
1682 else {
1683 c = chunk->pos;
1684 }

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

1782}
1783
1784struct ucl_parser*
1785ucl_parser_new (int flags)
1786{
1787 struct ucl_parser *new;
1788
1789 new = UCL_ALLOC (sizeof (struct ucl_parser));
1706 }
1707 else {
1708 parser->state = UCL_STATE_VALUE;
1709 }
1710 }
1711 else {
1712 c = chunk->pos;
1713 }

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

1811}
1812
1813struct ucl_parser*
1814ucl_parser_new (int flags)
1815{
1816 struct ucl_parser *new;
1817
1818 new = UCL_ALLOC (sizeof (struct ucl_parser));
1819 if (new == NULL) {
1820 return NULL;
1821 }
1790 memset (new, 0, sizeof (struct ucl_parser));
1791
1792 ucl_parser_register_macro (new, "include", ucl_include_handler, new);
1793 ucl_parser_register_macro (new, "try_include", ucl_try_include_handler, new);
1794 ucl_parser_register_macro (new, "includes", ucl_includes_handler, new);
1795
1796 new->flags = flags;
1797

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

1803
1804
1805void
1806ucl_parser_register_macro (struct ucl_parser *parser, const char *macro,
1807 ucl_macro_handler handler, void* ud)
1808{
1809 struct ucl_macro *new;
1810
1822 memset (new, 0, sizeof (struct ucl_parser));
1823
1824 ucl_parser_register_macro (new, "include", ucl_include_handler, new);
1825 ucl_parser_register_macro (new, "try_include", ucl_try_include_handler, new);
1826 ucl_parser_register_macro (new, "includes", ucl_includes_handler, new);
1827
1828 new->flags = flags;
1829

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

1835
1836
1837void
1838ucl_parser_register_macro (struct ucl_parser *parser, const char *macro,
1839 ucl_macro_handler handler, void* ud)
1840{
1841 struct ucl_macro *new;
1842
1843 if (macro == NULL || handler == NULL) {
1844 return;
1845 }
1811 new = UCL_ALLOC (sizeof (struct ucl_macro));
1846 new = UCL_ALLOC (sizeof (struct ucl_macro));
1847 if (new == NULL) {
1848 return;
1849 }
1812 memset (new, 0, sizeof (struct ucl_macro));
1813 new->handler = handler;
1814 new->name = strdup (macro);
1815 new->ud = ud;
1816 HASH_ADD_KEYPTR (hh, parser->macroes, new->name, strlen (new->name), new);
1817}
1818
1819void

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

1846 else {
1847 /* Do nothing */
1848 return;
1849 }
1850 }
1851 else {
1852 if (new == NULL) {
1853 new = UCL_ALLOC (sizeof (struct ucl_variable));
1850 memset (new, 0, sizeof (struct ucl_macro));
1851 new->handler = handler;
1852 new->name = strdup (macro);
1853 new->ud = ud;
1854 HASH_ADD_KEYPTR (hh, parser->macroes, new->name, strlen (new->name), new);
1855}
1856
1857void

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

1884 else {
1885 /* Do nothing */
1886 return;
1887 }
1888 }
1889 else {
1890 if (new == NULL) {
1891 new = UCL_ALLOC (sizeof (struct ucl_variable));
1892 if (new == NULL) {
1893 return;
1894 }
1854 memset (new, 0, sizeof (struct ucl_variable));
1855 new->var = strdup (var);
1856 new->var_len = strlen (var);
1857 new->value = strdup (value);
1858 new->value_len = strlen (value);
1859
1860 LL_PREPEND (parser->variables, new);
1861 }
1862 else {
1863 free (new->value);
1864 new->value = strdup (value);
1865 new->value_len = strlen (value);
1866 }
1867 }
1868}
1869
1895 memset (new, 0, sizeof (struct ucl_variable));
1896 new->var = strdup (var);
1897 new->var_len = strlen (var);
1898 new->value = strdup (value);
1899 new->value_len = strlen (value);
1900
1901 LL_PREPEND (parser->variables, new);
1902 }
1903 else {
1904 free (new->value);
1905 new->value = strdup (value);
1906 new->value_len = strlen (value);
1907 }
1908 }
1909}
1910
1911void
1912ucl_parser_set_variables_handler (struct ucl_parser *parser,
1913 ucl_variable_handler handler, void *ud)
1914{
1915 parser->var_handler = handler;
1916 parser->var_data = ud;
1917}
1918
1870bool
1871ucl_parser_add_chunk (struct ucl_parser *parser, const unsigned char *data,
1872 size_t len)
1873{
1874 struct ucl_chunk *chunk;
1875
1919bool
1920ucl_parser_add_chunk (struct ucl_parser *parser, const unsigned char *data,
1921 size_t len)
1922{
1923 struct ucl_chunk *chunk;
1924
1925 if (data == NULL || len == 0) {
1926 ucl_create_err (&parser->err, "invalid chunk added");
1927 return false;
1928 }
1876 if (parser->state != UCL_STATE_ERROR) {
1877 chunk = UCL_ALLOC (sizeof (struct ucl_chunk));
1929 if (parser->state != UCL_STATE_ERROR) {
1930 chunk = UCL_ALLOC (sizeof (struct ucl_chunk));
1931 if (chunk == NULL) {
1932 ucl_create_err (&parser->err, "cannot allocate chunk structure");
1933 return false;
1934 }
1878 chunk->begin = data;
1879 chunk->remain = len;
1880 chunk->pos = chunk->begin;
1881 chunk->end = chunk->begin + len;
1882 chunk->line = 1;
1883 chunk->column = 0;
1884 LL_PREPEND (parser->chunks, chunk);
1885 parser->recursion ++;

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

1890 }
1891 return ucl_state_machine (parser);
1892 }
1893
1894 ucl_create_err (&parser->err, "a parser is in an invalid state");
1895
1896 return false;
1897}
1935 chunk->begin = data;
1936 chunk->remain = len;
1937 chunk->pos = chunk->begin;
1938 chunk->end = chunk->begin + len;
1939 chunk->line = 1;
1940 chunk->column = 0;
1941 LL_PREPEND (parser->chunks, chunk);
1942 parser->recursion ++;

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

1947 }
1948 return ucl_state_machine (parser);
1949 }
1950
1951 ucl_create_err (&parser->err, "a parser is in an invalid state");
1952
1953 return false;
1954}
1955
1956bool
1957ucl_parser_add_string (struct ucl_parser *parser, const char *data,
1958 size_t len)
1959{
1960 if (data == NULL) {
1961 ucl_create_err (&parser->err, "invalid string added");
1962 return false;
1963 }
1964 if (len == 0) {
1965 len = strlen (data);
1966 }
1967
1968 return ucl_parser_add_chunk (parser, (const unsigned char *)data, len);
1969}