From aba6fe8bda05659f70ef0cca07aa02db72f23315 Mon Sep 17 00:00:00 2001 From: Nick Bowler Date: Thu, 4 Jan 2024 23:31:27 -0500 Subject: [PATCH] tests: Consolidate error messaging a bit. Use a wrapper function in the test applications to print error messages similar to the main application. This function automatically prepends the program name and automatically appends a newline. This is in preparation to share some code between the main application and the test suite. But it also allows the RNG initialization to print a properly prefixed error message. --- t/crossparse.c | 25 ++++++++++++------------- t/normalize.c | 6 +++--- t/randomdecl.c | 10 +++++----- t/rendertest.c | 20 +++++++++----------- t/rng-test.c | 3 ++- t/rng.c | 8 ++++++-- t/scantest.c | 6 +++--- t/test.h | 8 +++++++- t/testlib.c | 19 +++++++++++++++++-- testsuite.at | 2 +- 10 files changed, 65 insertions(+), 42 deletions(-) diff --git a/t/crossparse.c b/t/crossparse.c index f66ca62..e77a1cc 100644 --- a/t/crossparse.c +++ b/t/crossparse.c @@ -1,6 +1,6 @@ /* * Test that libcdecl can parse its own output. - * Copyright © 2012, 2020, 2022-2023 Nick Bowler + * Copyright © 2012, 2020, 2022-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 @@ -23,11 +23,12 @@ #include #include #include -#include -#include "test.h" + +#include "cdecl.h" #define PROGNAME "crossparse" -static const char *progname = PROGNAME; +#include "test.h" + static const char sopts[] = "f:ECVH"; static const struct option lopts[] = { { "cdecl", 0, NULL, 'C' }, @@ -67,16 +68,15 @@ char *rerender(const char *str, const char *parse_name, parse_func *parse, decl = parse(str); if (!decl) { - fprintf(stderr, "%s: %s: failed to parse input: %s\n", - progname, parse_name, cdecl_get_error()->str); + print_error("%s: failed to parse input: %s", parse_name, + cdecl_get_error()->str); goto err; } len = render(NULL, 0, decl); buf = malloc_nofail(len+1); if (render(buf, len+1, decl) != len) { - fprintf(stderr, "%s: %s: inconsistent length returned\n", - progname, render_name); + print_error("%s: inconsistent length returned", render_name); goto err; } @@ -86,7 +86,7 @@ err: cdecl_free(decl); free(buf); - fprintf(stderr, "%s: the failed input was: %s\n", progname, str); + print_error("the failed input was: %s", str); return NULL; } #define rerender(str, p, r) (rerender(str, #p, p, #r, r)) @@ -126,8 +126,7 @@ out: free(buf3); if (!ret) { - fprintf(stderr, "%s: failed cross-parse check of: %s\n", - progname, str); + print_error("failed cross-parse check of: %s", str); } return ret; @@ -176,8 +175,8 @@ int main(int argc, char **argv) if (filename) { infile = fopen(filename, "r"); if (!infile) { - fprintf(stderr, "%s: %s: %s\n", progname, - filename, strerror(errno)); + print_error("%s: %s", filename, + strerror(errno)); return EXIT_FAILURE; } } diff --git a/t/normalize.c b/t/normalize.c index 558f556..e11e648 100644 --- a/t/normalize.c +++ b/t/normalize.c @@ -1,6 +1,6 @@ /* * Helper application to test normalization of declaration specifiers. - * Copyright © 2021-2023 Nick Bowler + * Copyright © 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 @@ -24,10 +24,10 @@ #include "cdecl.h" #include "cdecl-internal.h" -#include "test.h" #define PROGNAME "normalize" -static const char *progname = PROGNAME; +#include "test.h" + static const char sopts[] = "f:VH"; static const struct option lopts[] = { { "file", 1, NULL, 'f' }, diff --git a/t/randomdecl.c b/t/randomdecl.c index 177f553..156e51c 100644 --- a/t/randomdecl.c +++ b/t/randomdecl.c @@ -1,6 +1,6 @@ /* * Generate random C declarations for testing. - * Copyright © 2012, 2020, 2022-2023 Nick Bowler + * Copyright © 2012, 2020, 2022-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 @@ -24,13 +24,13 @@ #include #include #include -#include +#include "cdecl.h" #include "declgen.h" -#include "test.h" #define PROGNAME "randomdecl" -static const char *progname = PROGNAME; +#include "test.h" + static const char sopts[] = "s:n:ECVH"; static const struct option lopts[] = { { "seed", 1, NULL, 's' }, @@ -137,7 +137,7 @@ int main(int argc, char **argv) } if (count_str && !test_strtoul(&count, count_str)) { - fprintf(stderr, "%s: invalid count: %s\n", progname, count_str); + print_error("invalid count: %s", count_str); return EXIT_FAILURE; } diff --git a/t/rendertest.c b/t/rendertest.c index 42a2c5e..cd14229 100644 --- a/t/rendertest.c +++ b/t/rendertest.c @@ -1,6 +1,6 @@ /* * Helper to verify the output rendering routines. - * Copyright © 2023 Nick Bowler + * Copyright © 2023-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 @@ -23,11 +23,11 @@ #include #include -#include -#include "test.h" +#include "cdecl.h" #define PROGNAME "rendertest" -static const char *progname = PROGNAME; +#include "test.h" + static const char sopts[] = "n:ECVH"; static const struct option lopts[] = { { "count", 1, NULL, 'n' }, @@ -63,9 +63,8 @@ static int do_test(char *line, unsigned long n, int mode) decl = cdecl_parse_decl(line); if (!decl) { - fprintf(stderr, "%s: %s\n", progname, cdecl_get_error()->str); - fprintf(stderr, "%s: the failed input was: %s\n", - progname, line); + print_error("%s", cdecl_get_error()->str); + print_error("the failed input was: %s", line); return -1; } @@ -76,12 +75,12 @@ static int do_test(char *line, unsigned long n, int mode) rc = cdecl_declare(line, n, decl); if (n && ( rc < n ? line[rc] : line[n-1] ) != '\0') { - fprintf(stderr, "%s: output is not 0-terminated\n", progname); + print_error("output is not 0-terminated"); return -1; } if (line[n] != '\a') { - fprintf(stderr, "%s: output overflow\n", progname); + print_error("output overflow"); return -1; } @@ -110,8 +109,7 @@ int main(int argc, char **argv) break; case 'n': if (!test_strtoul(&n, optarg) || n > (size_t)-2) { - fprintf(stderr, "%s: invalid count: %s\n", - progname, optarg); + print_error("invalid count: %s", optarg); return EXIT_FAILURE; } break; diff --git a/t/rng-test.c b/t/rng-test.c index a4ba6bb..e4173aa 100644 --- a/t/rng-test.c +++ b/t/rng-test.c @@ -1,6 +1,6 @@ /* * Simple random number generator for testing. - * Copyright © 2022-2023 Nick Bowler + * Copyright © 2022-2024 Nick Bowler * * Directly compare the test lib RNG against the reference implementation. * @@ -27,6 +27,7 @@ int main(void) tap_skip_all("cannot compile reference xoshiro256+"); } #else +#define TEST_RNG_NO_EXTERNAL_API 1 #include "rng.c" #include "xos256p.c" diff --git a/t/rng.c b/t/rng.c index 3842d3d..2e2fc09 100644 --- a/t/rng.c +++ b/t/rng.c @@ -28,7 +28,9 @@ #include #include -#include "test.h" +#if !TEST_RNG_NO_EXTERNAL_API +# include "test.h" +#endif #define B64(x) ((x) & 0xffffffffffffffff) @@ -70,6 +72,7 @@ static unsigned long long splitmix64(unsigned long long *state) return z ^ (z >> 31); } +#if !TEST_RNG_NO_EXTERNAL_API struct test_rng *test_rng_alloc(const char *seed_str) { unsigned long long seed; @@ -80,7 +83,7 @@ struct test_rng *test_rng_alloc(const char *seed_str) limit |= (limit << 16 << 16); if (!test_strtoumax(&seed_val, seed_str, limit)) { - fprintf(stderr, "%s: invalid seed\n", seed_str); + print_error("%s: invalid seed", seed_str); return NULL; } seed = seed_val; @@ -124,3 +127,4 @@ unsigned test_rng_uniform_int(struct test_rng *rng, unsigned max) return val; } +#endif diff --git a/t/scantest.c b/t/scantest.c index 093c6ca..0a0be22 100644 --- a/t/scantest.c +++ b/t/scantest.c @@ -1,6 +1,6 @@ /* * Helper to verify scanner output. - * Copyright © 2023 Nick Bowler + * Copyright © 2023-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 @@ -23,6 +23,8 @@ #include "scan.h" #include "cdecl-internal.h" + +#define PROGNAME "scantest" #include "test.h" /* Stubs */ @@ -45,8 +47,6 @@ size_t cdecl__strlcpy(char *dst, const char *src, size_t len) abort(); } -#define PROGNAME "scantest" -static const char *progname = PROGNAME; static const char sopts[] = "ECVH"; static const struct option lopts[] = { { "cdecl", 0, NULL, 'C' }, diff --git a/t/test.h b/t/test.h index a6382e2..9e8ddee 100644 --- a/t/test.h +++ b/t/test.h @@ -1,5 +1,5 @@ /* - * Copyright © 2012, 2020, 2022-2023 Nick Bowler + * Copyright © 2012, 2020, 2022-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 @@ -35,6 +35,8 @@ struct cdecl; struct test_rng; +void print_error(const char *fmt, ...); + void *malloc_nofail(size_t size); void *realloc_nofail(void *ptr, size_t size); @@ -80,6 +82,10 @@ static inline int test_rng_50_50(struct test_rng *rng) #define VERSION_NO_COPYRIGHT_SYMBOL 1 #include "version.h" +#ifdef PROGNAME +const char *progname = PROGNAME; +#endif + #define test_print_version(s) \ do_print_version(s " (" PACKAGE_NAME ") " PACKAGE_VERSION) diff --git a/t/testlib.c b/t/testlib.c index 41ea1fc..10b27ad 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 @@ -22,12 +22,27 @@ #include #include #include -#include + +#include "cdecl.h" #include "help.h" #include "test.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) { void *p; diff --git a/testsuite.at b/testsuite.at index 58fae65..328f427 100644 --- a/testsuite.at +++ b/testsuite.at @@ -1,4 +1,4 @@ -AT_COPYRIGHT([Copyright © 2020-2021, 2023 Nick Bowler]) +AT_COPYRIGHT([Copyright (C) 2020-2021, 2023-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 -- 2.43.2