X-Git-Url: https://git.draconx.ca/gitweb/cdecl99.git/blobdiff_plain/1260ac474046e883b8e499a72739c9289097933f..481f693b0400b05586d90f60494e0e661ad8a1c1:/t/testlib.c diff --git a/t/testlib.c b/t/testlib.c index 5c76bb4..5902e7b 100644 --- a/t/testlib.c +++ b/t/testlib.c @@ -1,6 +1,6 @@ /* * Miscellaneous functions used by the cdecl99 test suite. - * Copyright © 2011-2012, 2021-2023 Nick Bowler + * Copyright © 2011-2012, 2021-2024 Nick Bowler * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,12 +19,31 @@ #include #include #include +#include +#include #include #include -#include + +#include "cdecl.h" #include "help.h" #include "test.h" +#include "getline.h" +#include "intconv.h" + +void print_error(const char *fmt, ...) +{ + extern const char *progname; + va_list ap; + + fprintf(stderr, "%s: ", progname); + + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + + fprintf(stderr, "\n"); +} void *realloc_nofail(void *ptr, size_t size) { @@ -44,15 +63,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) +{ + if ((*str)[0] == '0') { + if ((*str)[1] == 'X' || (*str)[1] == 'x') { + *str += 2; + return INTCONV_HEXADECIMAL; + } + + return INTCONV_OCTAL; + } + + return INTCONV_DECIMAL; +} + +bool test_strtoumax(cdecl_uintmax *out, const char *s, cdecl_uintmax limit) { - char *end; + static const char idx[] = "0123456789abcdef0123456789ABCDEF"; + unsigned base = intconv_base(&s); + cdecl_uintmax v; + char *c, d; + + for (v = 0; (d = *s++);) { + if (!(c = strchr(idx, d)) || (d = (c-idx) & 0xf) >= base) + return 0; - errno = 0; - *val = strtoul(str, &end, base); - if (errno != 0 || *end != 0) - return false; + if (!intconv_shift(&v, base, d) || v > limit) + return 0; + } + *out = v; return true; } @@ -66,3 +106,18 @@ void test_print_options(const struct option *lopts) putchar('\n'); } } + +int test_getline(char **linebuf, size_t *n) +{ + int rc; + + if ((rc = dx_getline(linebuf, n, stdin)) < 0) { + if (rc == DX_GETLINE_ENOMEM) + print_error("%s", _("failed to allocate memory")); + else + print_error("%s", strerror(errno)); + abort(); + } + + return rc; +}