#include "unit-test.h" #include "parse.h" static void check_int(const char *buf, size_t len, size_t expect_ep_ofs, int expect_errno, int expect_result) { const char *ep; int result; bool ok = parse_int_from_buf(buf, len, &ep, &result); if (expect_errno) { cl_assert(!ok); cl_assert_equal_i(expect_errno, errno); return; } cl_assert(ok); cl_assert_equal_i(expect_result, result); cl_assert_equal_i(expect_ep_ofs, ep - buf); } static void check_int_str(const char *buf, size_t ofs, int err, int res) { check_int(buf, strlen(buf), ofs, err, res); } static void check_int_full(const char *buf, int res) { check_int_str(buf, strlen(buf), 0, res); } static void check_int_err(const char *buf, int err) { check_int(buf, strlen(buf), 0, err, 0); } void test_parse_int__basic(void) { cl_invoke(check_int_full("0", 0)); cl_invoke(check_int_full("11", 11)); cl_invoke(check_int_full("-23", -23)); cl_invoke(check_int_full("+23", 23)); cl_invoke(check_int_str(" 31337 ", 7, 0, 31337)); cl_invoke(check_int_err(" garbage", EINVAL)); cl_invoke(check_int_err("", EINVAL)); cl_invoke(check_int_err("-", EINVAL)); cl_invoke(check_int("123", 2, 2, 0, 12)); } void test_parse_int__range(void) { /* * These assume a 32-bit int. We could avoid that with some * conditionals, but it's probably better for the test to * fail noisily and we can decide how to handle it then. */ cl_invoke(check_int_full("2147483647", 2147483647)); cl_invoke(check_int_err("2147483648", ERANGE)); cl_invoke(check_int_full("-2147483647", -2147483647)); cl_invoke(check_int_full("-2147483648", -2147483648)); cl_invoke(check_int_err("-2147483649", ERANGE)); } static void check_unsigned(const char *buf, uintmax_t max, int expect_errno, uintmax_t expect_result) { const char *ep; uintmax_t result; bool ok = parse_unsigned_from_buf(buf, strlen(buf), &ep, &result, max); if (expect_errno) { cl_assert(!ok); cl_assert_equal_i(expect_errno, errno); return; } cl_assert(ok); cl_assert_equal_s(ep, ""); /* * Do not use cl_assert_equal_i_fmt(..., PRIuMAX) here. The macro * casts to int under the hood, corrupting the values. */ clar__assert_equal(CLAR_CURRENT_FILE, CLAR_CURRENT_FUNC, CLAR_CURRENT_LINE, "expect_result != result", 1, "%"PRIuMAX, expect_result, result); } void test_parse_int__unsigned(void) { cl_invoke(check_unsigned("4294967295", UINT_MAX, 0, 4294967295U)); cl_invoke(check_unsigned("1053", 1000, ERANGE, 0)); cl_invoke(check_unsigned("-17", UINT_MAX, EINVAL, 0)); }