76 lines
2.2 KiB
C
76 lines
2.2 KiB
C
|
|
/*
|
||
|
|
* KNOWN FAILING -- TODO.md section 2.1.5
|
||
|
|
*
|
||
|
|
* The ato* wrappers cannot report a conversion failure. atoi(3) and friends have
|
||
|
|
* no error channel at all: "not a number" converts to 0 and an overflowing
|
||
|
|
* literal converts to a wrapped value, and in both cases the wrapper hands back
|
||
|
|
* success. A library whose entire purpose is turning silent libc failures into
|
||
|
|
* error contexts should not be the one place a bad conversion passes unnoticed.
|
||
|
|
*
|
||
|
|
* This test asserts the contract the fix should provide -- reimplemented over
|
||
|
|
* strtol/strtoll/strtod with errno cleared, an endptr check for "no digits
|
||
|
|
* consumed" and "trailing junk", and a range check:
|
||
|
|
*
|
||
|
|
* no digits consumed / trailing junk -> AKERR_VALUE
|
||
|
|
* value out of range -> ERANGE
|
||
|
|
*
|
||
|
|
* Registered in AKSL_KNOWN_FAILING_TESTS (WILL_FAIL). When the wrappers get a
|
||
|
|
* real error channel, CTest reports this as unexpectedly passing -- move it into
|
||
|
|
* AKSL_TESTS then, and fold the cases into tests/test_convert.c.
|
||
|
|
*/
|
||
|
|
|
||
|
|
#include "aksl_capture.h"
|
||
|
|
|
||
|
|
#include <errno.h>
|
||
|
|
|
||
|
|
static int test_non_numeric_input_is_a_value_error(void)
|
||
|
|
{
|
||
|
|
int out = 0;
|
||
|
|
|
||
|
|
AKSL_CHECK_STATUS(aksl_atoi("not a number", &out), AKERR_VALUE);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
static int test_empty_input_is_a_value_error(void)
|
||
|
|
{
|
||
|
|
int out = 0;
|
||
|
|
|
||
|
|
AKSL_CHECK_STATUS(aksl_atoi("", &out), AKERR_VALUE);
|
||
|
|
AKSL_CHECK_STATUS(aksl_atoi(" ", &out), AKERR_VALUE);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
static int test_trailing_junk_is_a_value_error(void)
|
||
|
|
{
|
||
|
|
int out = 0;
|
||
|
|
|
||
|
|
AKSL_CHECK_STATUS(aksl_atoi("12abc", &out), AKERR_VALUE);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
static int test_overflow_is_erange(void)
|
||
|
|
{
|
||
|
|
int out = 0;
|
||
|
|
long lout = 0;
|
||
|
|
long long llout = 0;
|
||
|
|
|
||
|
|
AKSL_CHECK_STATUS(aksl_atoi("99999999999999999999", &out), ERANGE);
|
||
|
|
AKSL_CHECK_STATUS(aksl_atol("99999999999999999999999999", &lout), ERANGE);
|
||
|
|
AKSL_CHECK_STATUS(aksl_atoll("99999999999999999999999999", &llout), ERANGE);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
int main(void)
|
||
|
|
{
|
||
|
|
int failures = 0;
|
||
|
|
|
||
|
|
akerr_init();
|
||
|
|
|
||
|
|
AKSL_RUN(failures, test_non_numeric_input_is_a_value_error);
|
||
|
|
AKSL_RUN(failures, test_empty_input_is_a_value_error);
|
||
|
|
AKSL_RUN(failures, test_trailing_junk_is_a_value_error);
|
||
|
|
AKSL_RUN(failures, test_overflow_is_erange);
|
||
|
|
|
||
|
|
AKSL_REPORT(failures);
|
||
|
|
}
|