ucl_parser.c (262975) | ucl_parser.c (263648) |
---|---|
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 --- 530 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)); | 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 --- 530 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)); |
547 if (st == NULL) { 548 ucl_set_err (parser->chunks, 0, "cannot allocate memory for an object", &parser->err); 549 return NULL; 550 } |
|
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, | 551 st->obj = obj; 552 st->level = level; 553 LL_PREPEND (parser->stack, st); 554 parser->cur_obj = obj; 555 556 return obj; 557} 558 559int 560ucl_maybe_parse_number (ucl_object_t *obj, |
557 const char *start, const char *end, const char **pos, bool allow_double, bool number_bytes) | 561 const char *start, const char *end, const char **pos, 562 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, | 563{ 564 const char *p = start, *c = start; 565 char *endptr; 566 bool got_dot = false, got_exp = false, need_double = false, |
562 is_date = false, valid_start = false, is_hex = false, | 567 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 */ | 568 is_neg = false; 569 double dv = 0; 570 int64_t lv = 0; 571 572 if (*p == '-') { 573 is_neg = true; 574 c ++; 575 p ++; --- 81 unchanged lines hidden (view full) --- 657 } 658 } 659 if (errno == ERANGE) { 660 *pos = start; 661 return ERANGE; 662 } 663 664 /* Now check endptr */ |
660 if (endptr == NULL || ucl_lex_is_atom_end (*endptr) || *endptr == '\0') { | 665 if (endptr == NULL || ucl_lex_is_atom_end (*endptr) || *endptr == '\0' || 666 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 } | 667 p = endptr; 668 goto set_obj; 669 } 670 671 if (endptr < end && endptr != start) { 672 p = endptr; 673 switch (*p) { 674 case 'm': --- 4 unchanged lines hidden (view full) --- 679 case 'K': 680 if (end - p >= 2) { 681 if (p[1] == 's' || p[1] == 'S') { 682 /* Milliseconds */ 683 if (!need_double) { 684 need_double = true; 685 dv = lv; 686 } |
681 is_date = true; | 687 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 } | 688 if (p[0] == 'm' || p[0] == 'M') { 689 dv /= 1000.; 690 } 691 else { 692 dv *= ucl_lex_num_multiplier (*p, false); 693 } 694 p += 2; 695 goto set_obj; --- 13 unchanged lines hidden (view full) --- 709 dv *= ucl_lex_num_multiplier (*p, false); 710 } 711 else { 712 lv *= ucl_lex_num_multiplier (*p, number_bytes); 713 } 714 p ++; 715 goto set_obj; 716 } |
711 else if (end - p >= 3) { | 717 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 } | 718 if (tolower (p[0]) == 'm' && 719 tolower (p[1]) == 'i' && 720 tolower (p[2]) == 'n') { 721 /* Minutes */ 722 if (!need_double) { 723 need_double = true; 724 dv = lv; 725 } |
720 is_date = true; | 726 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': | 727 dv *= 60.; 728 p += 3; 729 goto set_obj; 730 } 731 } 732 } 733 else { 734 if (need_double) { 735 dv *= ucl_lex_num_multiplier (*p, false); 736 } 737 else { 738 lv *= ucl_lex_num_multiplier (*p, number_bytes); 739 } 740 p ++; 741 goto set_obj; 742 } 743 break; 744 case 'S': 745 case 's': |
740 if (p == end - 1 || ucl_lex_is_atom_end (p[1])) { | 746 if (allow_time && 747 (p == end - 1 || ucl_lex_is_atom_end (p[1]))) { |
741 if (!need_double) { 742 need_double = true; 743 dv = lv; 744 } 745 p ++; | 748 if (!need_double) { 749 need_double = true; 750 dv = lv; 751 } 752 p ++; |
746 is_date = true; | 753 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': | 754 goto set_obj; 755 } 756 break; 757 case 'h': 758 case 'H': 759 case 'd': 760 case 'D': 761 case 'w': 762 case 'W': 763 case 'Y': 764 case 'y': |
758 if (p == end - 1 || ucl_lex_is_atom_end (p[1])) { | 765 if (allow_time && 766 (p == end - 1 || ucl_lex_is_atom_end (p[1]))) { |
759 if (!need_double) { 760 need_double = true; 761 dv = lv; 762 } | 767 if (!need_double) { 768 need_double = true; 769 dv = lv; 770 } |
763 is_date = true; | 771 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: | 772 dv *= ucl_lex_time_multiplier (*p); 773 p ++; 774 goto set_obj; 775 } 776 break; 777 } 778 } 779 780 *pos = c; 781 return EINVAL; 782 783 set_obj: |
776 if (allow_double && (need_double || is_date)) { 777 if (!is_date) { | 784 if (allow_double && (need_double || is_time)) { 785 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 | 786 obj->type = UCL_FLOAT; 787 } 788 else { 789 obj->type = UCL_TIME; 790 } 791 obj->value.dv = is_neg ? (-dv) : dv; 792 } 793 else { --- 12 unchanged lines hidden (view full) --- 806 */ 807static bool 808ucl_lex_number (struct ucl_parser *parser, 809 struct ucl_chunk *chunk, ucl_object_t *obj) 810{ 811 const unsigned char *pos; 812 int ret; 813 |
806 ret = ucl_maybe_parse_number (obj, chunk->pos, chunk->end, (const char **)&pos, true, false); | 814 ret = ucl_maybe_parse_number (obj, chunk->pos, chunk->end, (const char **)&pos, 815 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) { --- 488 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); | 816 817 if (ret == 0) { 818 chunk->remain -= pos - chunk->pos; 819 chunk->column += pos - chunk->pos; 820 chunk->pos = pos; 821 return true; 822 } 823 else if (ret == ERANGE) { --- 488 unchanged lines hidden (view full) --- 1312 parser->state = UCL_STATE_AFTER_VALUE; 1313 p = chunk->pos; 1314 return true; 1315 break; 1316 case '{': 1317 obj = ucl_get_value_object (parser); 1318 /* We have a new object */ 1319 obj = ucl_add_parser_stack (obj, parser, false, parser->stack->level); |
1320 if (obj == NULL) { 1321 return false; 1322 } |
|
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); | 1323 1324 ucl_chunk_skipc (chunk, p); 1325 return true; 1326 break; 1327 case '[': 1328 obj = ucl_get_value_object (parser); 1329 /* We have a new array */ 1330 obj = ucl_add_parser_stack (obj, parser, true, parser->stack->level); |
1331 if (obj == NULL) { 1332 return false; 1333 } |
|
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 } | 1334 1335 ucl_chunk_skipc (chunk, p); 1336 return true; 1337 break; 1338 case ']': 1339 /* We have the array ending */ 1340 if (parser->stack && parser->stack->obj->type == UCL_ARRAY) { 1341 parser->state = UCL_STATE_AFTER_VALUE; --- 276 unchanged lines hidden (view full) --- 1618 1619 if (parser->top_obj == NULL) { 1620 if (*chunk->pos == '[') { 1621 obj = ucl_add_parser_stack (NULL, parser, true, 0); 1622 } 1623 else { 1624 obj = ucl_add_parser_stack (NULL, parser, false, 0); 1625 } |
1626 if (obj == NULL) { 1627 return false; 1628 } |
|
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 */ | 1629 parser->top_obj = obj; 1630 parser->cur_obj = obj; 1631 parser->state = UCL_STATE_INIT; 1632 } 1633 1634 p = chunk->pos; 1635 while (chunk->pos < chunk->end) { 1636 switch (parser->state) { --- 49 unchanged lines hidden (view full) --- 1686 if (end_of_object) { 1687 p = chunk->pos; 1688 parser->state = UCL_STATE_AFTER_VALUE; 1689 continue; 1690 } 1691 else if (parser->state != UCL_STATE_MACRO_NAME) { 1692 if (next_key && parser->stack->obj->type == UCL_OBJECT) { 1693 /* Parse more keys and nest objects accordingly */ |
1676 obj = ucl_add_parser_stack (parser->cur_obj, parser, false, parser->stack->level + 1); | 1694 obj = ucl_add_parser_stack (parser->cur_obj, parser, false, 1695 parser->stack->level + 1); 1696 if (obj == NULL) { 1697 return false; 1698 } |
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)); | 1699 } 1700 else { 1701 parser->state = UCL_STATE_VALUE; 1702 } 1703 } 1704 else { 1705 c = chunk->pos; 1706 } --- 97 unchanged lines hidden (view full) --- 1804} 1805 1806struct ucl_parser* 1807ucl_parser_new (int flags) 1808{ 1809 struct ucl_parser *new; 1810 1811 new = UCL_ALLOC (sizeof (struct ucl_parser)); |
1812 if (new == NULL) { 1813 return NULL; 1814 } |
|
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 | 1815 memset (new, 0, sizeof (struct ucl_parser)); 1816 1817 ucl_parser_register_macro (new, "include", ucl_include_handler, new); 1818 ucl_parser_register_macro (new, "try_include", ucl_try_include_handler, new); 1819 ucl_parser_register_macro (new, "includes", ucl_includes_handler, new); 1820 1821 new->flags = flags; 1822 --- 5 unchanged lines hidden (view full) --- 1828 1829 1830void 1831ucl_parser_register_macro (struct ucl_parser *parser, const char *macro, 1832 ucl_macro_handler handler, void* ud) 1833{ 1834 struct ucl_macro *new; 1835 |
1836 if (macro == NULL || handler == NULL) { 1837 return; 1838 } |
|
1811 new = UCL_ALLOC (sizeof (struct ucl_macro)); | 1839 new = UCL_ALLOC (sizeof (struct ucl_macro)); |
1840 if (new == NULL) { 1841 return; 1842 } |
|
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)); | 1843 memset (new, 0, sizeof (struct ucl_macro)); 1844 new->handler = handler; 1845 new->name = strdup (macro); 1846 new->ud = ud; 1847 HASH_ADD_KEYPTR (hh, parser->macroes, new->name, strlen (new->name), new); 1848} 1849 1850void --- 26 unchanged lines hidden (view full) --- 1877 else { 1878 /* Do nothing */ 1879 return; 1880 } 1881 } 1882 else { 1883 if (new == NULL) { 1884 new = UCL_ALLOC (sizeof (struct ucl_variable)); |
1885 if (new == NULL) { 1886 return; 1887 } |
|
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 } --- 6 unchanged lines hidden (view full) --- 1868} 1869 1870bool 1871ucl_parser_add_chunk (struct ucl_parser *parser, const unsigned char *data, 1872 size_t len) 1873{ 1874 struct ucl_chunk *chunk; 1875 | 1888 memset (new, 0, sizeof (struct ucl_variable)); 1889 new->var = strdup (var); 1890 new->var_len = strlen (var); 1891 new->value = strdup (value); 1892 new->value_len = strlen (value); 1893 1894 LL_PREPEND (parser->variables, new); 1895 } --- 6 unchanged lines hidden (view full) --- 1902} 1903 1904bool 1905ucl_parser_add_chunk (struct ucl_parser *parser, const unsigned char *data, 1906 size_t len) 1907{ 1908 struct ucl_chunk *chunk; 1909 |
1910 if (data == NULL || len == 0) { 1911 ucl_create_err (&parser->err, "invalid chunk added"); 1912 return false; 1913 } |
|
1876 if (parser->state != UCL_STATE_ERROR) { 1877 chunk = UCL_ALLOC (sizeof (struct ucl_chunk)); | 1914 if (parser->state != UCL_STATE_ERROR) { 1915 chunk = UCL_ALLOC (sizeof (struct ucl_chunk)); |
1916 if (chunk == NULL) { 1917 ucl_create_err (&parser->err, "cannot allocate chunk structure"); 1918 return false; 1919 } |
|
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} | 1920 chunk->begin = data; 1921 chunk->remain = len; 1922 chunk->pos = chunk->begin; 1923 chunk->end = chunk->begin + len; 1924 chunk->line = 1; 1925 chunk->column = 0; 1926 LL_PREPEND (parser->chunks, chunk); 1927 parser->recursion ++; --- 4 unchanged lines hidden (view full) --- 1932 } 1933 return ucl_state_machine (parser); 1934 } 1935 1936 ucl_create_err (&parser->err, "a parser is in an invalid state"); 1937 1938 return false; 1939} |
1940 1941bool 1942ucl_parser_add_string (struct ucl_parser *parser, const char *data, 1943 size_t len) 1944{ 1945 if (data == NULL) { 1946 ucl_create_err (&parser->err, "invalid string added"); 1947 return false; 1948 } 1949 if (len == 0) { 1950 len = strlen (data); 1951 } 1952 1953 return ucl_parser_add_chunk (parser, (const unsigned char *)data, len); 1954} |
|