From d546887cd6d807f258fc4fb2f47a655310e356ba Mon Sep 17 00:00:00 2001 From: Nick Bowler Date: Thu, 28 Dec 2023 01:59:08 -0500 Subject: [PATCH] tests: Avoid dependency on strtoumax. Pretty easy to implement string-to-integer conversion in the tests now that we have some helpers to do so that can be shared with the main library code. There is very little advantage to this change in the test programs, as the reduced-range fallback is pretty much fine here. However, as there are no other users, getting rid of this also allows us to remove the configure probes for strtoumax and its alternatives. --- configure.ac | 5 +---- t/randomdecl.c | 2 +- t/rendertest.c | 2 +- t/rng.c | 26 +++++--------------------- t/test.h | 12 +++++++++++- t/testlib.c | 35 +++++++++++++++++++++++++++++------ 6 files changed, 48 insertions(+), 34 deletions(-) diff --git a/configure.ac b/configure.ac index 2f71721..645e871 100644 --- a/configure.ac +++ b/configure.ac @@ -109,9 +109,6 @@ AH_BOTTOM([#include ]) AC_CONFIG_TESTDIR([.], [t:.]) DX_PROG_AUTOTEST_AM -AC_CHECK_FUNCS_ONCE([strtoumax strtoull __strtoull]) -AC_CONFIG_FILES([ - Makefile -]) +AC_CONFIG_FILES([Makefile]) AC_OUTPUT diff --git a/t/randomdecl.c b/t/randomdecl.c index 49a3d23..177f553 100644 --- a/t/randomdecl.c +++ b/t/randomdecl.c @@ -136,7 +136,7 @@ int main(int argc, char **argv) } } - if (count_str && !strict_strtoul(&count, count_str, 0)) { + if (count_str && !test_strtoul(&count, count_str)) { fprintf(stderr, "%s: invalid count: %s\n", progname, count_str); return EXIT_FAILURE; } diff --git a/t/rendertest.c b/t/rendertest.c index e5299c2..42a2c5e 100644 --- a/t/rendertest.c +++ b/t/rendertest.c @@ -109,7 +109,7 @@ int main(int argc, char **argv) mode = MODE_ENGLISH; break; case 'n': - if (!strict_strtoul(&n, optarg, 0) || n > (size_t)-2) { + if (!test_strtoul(&n, optarg) || n > (size_t)-2) { fprintf(stderr, "%s: invalid count: %s\n", progname, optarg); return EXIT_FAILURE; diff --git a/t/rng.c b/t/rng.c index fec991c..cbab4a7 100644 --- a/t/rng.c +++ b/t/rng.c @@ -70,34 +70,18 @@ static unsigned long long splitmix64(unsigned long long *state) return z ^ (z >> 31); } -#if HAVE_STRTOULL -# define STRTOULL strtoull -#elif HAVE___STRTOULL -/* HP-UX 11 has __strtoull in */ -# define STRTOULL __strtoull -#else -/* - * Just fall back to strtoul -- in the worst case we just lose the ability - * to set all 64 bits of the seed. - */ -# define STRTOULL strtoul -#endif - struct test_rng *test_rng_alloc(const char *seed_str) { unsigned long long seed; + uintmax_t limit, seed_val; struct test_rng *rng; - char *end; - errno = 0; - seed = STRTOULL(seed_str, &end, 0); - if (*end != 0) { + limit = (uintmax_t)0xffffffff; + limit |= (limit << 16 << 16); + + if (!test_strtoumax(&seed_val, seed_str, limit)) { fprintf(stderr, "%s: invalid seed\n", seed_str); return NULL; - } else if (errno != 0) { - fprintf(stderr, "%s: invalid seed: %s\n", - seed_str, strerror(errno)); - return NULL; } rng = malloc_nofail(sizeof *rng); diff --git a/t/test.h b/t/test.h index 0d009f0..a6382e2 100644 --- a/t/test.h +++ b/t/test.h @@ -38,7 +38,17 @@ struct test_rng; void *malloc_nofail(size_t size); void *realloc_nofail(void *ptr, size_t size); -bool strict_strtoul(unsigned long *val, const char *str, int base); +bool test_strtoumax(uintmax_t *out, const char *s, uintmax_t limit); + +static inline bool test_strtoul(unsigned long *val, const char *str) +{ + uintmax_t v; + bool rc; + + rc = test_strtoumax(&v, str, (unsigned long)-1); + *val = v; + return rc; +} void test_print_options(const struct option *lopts); diff --git a/t/testlib.c b/t/testlib.c index 5c76bb4..41ea1fc 100644 --- a/t/testlib.c +++ b/t/testlib.c @@ -19,12 +19,14 @@ #include #include #include +#include #include #include #include #include "help.h" #include "test.h" +#include "intconv.h" void *realloc_nofail(void *ptr, size_t size) { @@ -44,15 +46,36 @@ void *malloc_nofail(size_t size) return realloc_nofail(NULL, size); } -bool strict_strtoul(unsigned long *val, const char *str, int base) +static unsigned intconv_base(const char **str) { - char *end; + if ((*str)[0] == '0') { + if ((*str)[1] == 'X' || (*str)[1] == 'x') { + *str += 2; + return INTCONV_HEXADECIMAL; + } - errno = 0; - *val = strtoul(str, &end, base); - if (errno != 0 || *end != 0) - return false; + return INTCONV_OCTAL; + } + + return INTCONV_DECIMAL; +} + +bool test_strtoumax(uintmax_t *out, const char *s, uintmax_t limit) +{ + static const char idx[] = "0123456789abcdef0123456789ABCDEF"; + unsigned base = intconv_base(&s); + uintmax_t v; + char *c, d; + + for (v = 0; (d = *s++);) { + if (!(c = strchr(idx, d)) || (d = (c-idx) & 0xf) >= base) + return 0; + + if (!intconv_shift(&v, base, d) || v > limit) + return 0; + } + *out = v; return true; } -- 2.43.2