diff --git a/src/parse.c b/src/parse.c index 30b653c..27d0ffc 100644 --- a/src/parse.c +++ b/src/parse.c @@ -9,6 +9,7 @@ #include #include #include +#include #define START_LIST_CHAR '(' #define END_LIST_CHAR ')' @@ -71,14 +72,24 @@ struct ucl_object *ucl_token_next(const char **curr_src) { str = strndup(start + 1, *curr_src - start - 2); // TODO: free return ucl_string_create(str); + case '-': + case '+': case '0'...'9': { - // TODO: Add support for negative integers char *end = NULL; + errno = 0; long value = strtol(*curr_src, &end, 0); + if (errno || *curr_src == end) { + goto symbol_case; + } + *curr_src = end; + if (!ucl_is_delimiter(*end)) { + return ucl_error_create("Integer value contained non-digits"); + } return ucl_int_create(value); } default: + symbol_case: while (!ucl_is_delimiter(**curr_src)) { (*curr_src)++; } @@ -100,6 +111,7 @@ struct ucl_object *ucl_tokenize(const char *source) { const char *curr_src = source; while ((curr_token = ucl_token_next(&curr_src)) != NULL) { + UCL_RET_IF_ERROR(curr_token); tokens_tail = ucl_list_append(tokens_tail, curr_token); } diff --git a/test/test_parse.c b/test/test_parse.c index cbf0acf..fc89a4a 100644 --- a/test/test_parse.c +++ b/test/test_parse.c @@ -320,6 +320,35 @@ static void test_parse_mismatched_closed(void) { TEST_ASSERT_OBJ_ERROR(response); } +static void test_parse_int(void) { + response = ucl_parse("123"); + + TEST_ASSERT_OBJ_INT_V(response->cell.car, 123); +} + +static void test_parse_int_hex(void) { + response = ucl_parse("0xa"); + + TEST_ASSERT_OBJ_INT_V(response->cell.car, 0xa); +} + +static void test_parse_int_neg(void) { + response = ucl_parse("-7"); + + TEST_ASSERT_OBJ_INT_V(response->cell.car, -7); +} + +static void test_parse_int_plus(void) { + response = ucl_parse("+7"); + + TEST_ASSERT_OBJ_INT_V(response->cell.car, 7); +} + +static void test_parse_int_garbled(void) { + response = ucl_parse("+1234g7"); + + TEST_ASSERT_OBJ_ERROR(response); +} int main(void) { UNITY_BEGIN(); @@ -348,5 +377,10 @@ int main(void) { RUN_TEST(test_parse_nested); RUN_TEST(test_parse_mismatched_open); RUN_TEST(test_parse_mismatched_closed); + RUN_TEST(test_parse_int); + RUN_TEST(test_parse_int_hex); + RUN_TEST(test_parse_int_neg); + RUN_TEST(test_parse_int_plus); + RUN_TEST(test_parse_int_garbled); return UNITY_END(); }