Deleted Added
full compact
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}