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} |
|