blob: a1601bb16bdcbf96c1c5407ec5200a096c4e9a21 [file] [log] [blame] [edit]
#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));
}