X-Git-Url: https://git.draconx.ca/gitweb/cdecl99.git/blobdiff_plain/1c3b0c0e6f9339e76e42f6393e554c7dfc58e205..481f693b0400b05586d90f60494e0e661ad8a1c1:/t/testlib.c diff --git a/t/testlib.c b/t/testlib.c index fdb9d3b..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-2022 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,15 +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; -static size_t printbuf_size; -static char *printbuf; + 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) { @@ -47,55 +63,37 @@ void *malloc_nofail(size_t size) return realloc_nofail(NULL, size); } -void test_print_decl(struct cdecl *decl) +static unsigned intconv_base(const char **str) { - size_t rc; - -retry: - rc = cdecl_declare(printbuf, printbuf_size, decl); - if (rc >= printbuf_size) { - printbuf_size = rc + 1; - printbuf = realloc_nofail(printbuf, printbuf_size); - goto retry; - } - - printf("%s\n", printbuf); -} + if ((*str)[0] == '0') { + if ((*str)[1] == 'X' || (*str)[1] == 'x') { + *str += 2; + return INTCONV_HEXADECIMAL; + } -void test_explain_decl(struct cdecl *decl) -{ - size_t rc; - -retry: - rc = cdecl_explain(printbuf, printbuf_size, decl); - if (rc >= printbuf_size) { - printbuf_size = rc + 1; - printbuf = realloc_nofail(printbuf, printbuf_size); - goto retry; + return INTCONV_OCTAL; } - printf("%s\n", printbuf); + return INTCONV_DECIMAL; } -bool strict_strtoul(unsigned long *val, const char *str, int base) +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; - errno = 0; - *val = strtoul(str, &end, base); - if (errno != 0 || *end != 0) - return false; + for (v = 0; (d = *s++);) { + if (!(c = strchr(idx, d)) || (d = (c-idx) & 0xf) >= base) + return 0; - return true; -} + if (!intconv_shift(&v, base, d) || v > limit) + return 0; + } -void test_print_version(const char *program) -{ - printf("%s (%s) %s\n", program, PACKAGE_NAME, PACKAGE_VERSION); - puts("Copyright (C) 2022 Nick Bowler."); - puts("License GPLv3+: GNU GPL version 3 or later ."); - puts("This is free software: you are free to change and redistribute it."); - puts("There is NO WARRANTY, to the extent permitted by law."); + *out = v; + return true; } void test_print_options(const struct option *lopts) @@ -108,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; +}