diff options
Diffstat (limited to 'tests/runtests.c')
-rw-r--r-- | tests/runtests.c | 187 |
1 files changed, 93 insertions, 94 deletions
diff --git a/tests/runtests.c b/tests/runtests.c index af15a5c..1050120 100644 --- a/tests/runtests.c +++ b/tests/runtests.c @@ -8,7 +8,7 @@ * should be sent to the e-mail address below. This program is part of C TAP * Harness <https://www.eyrie.org/~eagle/software/c-tap-harness/>. * - * Copyright 2000-2001, 2004, 2006-2018 Russ Allbery <eagle@eyrie.org> + * Copyright 2000-2001, 2004, 2006-2019 Russ Allbery <eagle@eyrie.org> * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -93,9 +93,9 @@ /* Required for fdopen(), getopt(), and putenv(). */ #if defined(__STRICT_ANSI__) || defined(PEDANTIC) -# ifndef _XOPEN_SOURCE -# define _XOPEN_SOURCE 500 -# endif +# ifndef _XOPEN_SOURCE +# define _XOPEN_SOURCE 500 +# endif #endif #include <ctype.h> @@ -120,7 +120,7 @@ /* AIX 6.1 (and possibly later) doesn't have WCOREDUMP. */ #ifndef WCOREDUMP -# define WCOREDUMP(status) ((unsigned)(status) & 0x80) +# define WCOREDUMP(status) ((unsigned) (status) &0x80) #endif /* @@ -129,9 +129,9 @@ * have. */ #ifndef STDIN_FILENO -# define STDIN_FILENO 0 -# define STDOUT_FILENO 1 -# define STDERR_FILENO 2 +# define STDIN_FILENO 0 +# define STDOUT_FILENO 1 +# define STDERR_FILENO 2 #endif /* @@ -149,58 +149,50 @@ * $(abs_top_builddir) respectively. */ #ifndef C_TAP_SOURCE -# define C_TAP_SOURCE NULL +# define C_TAP_SOURCE NULL #endif #ifndef C_TAP_BUILD -# define C_TAP_BUILD NULL +# define C_TAP_BUILD NULL #endif /* Test status codes. */ -enum test_status { - TEST_FAIL, - TEST_PASS, - TEST_SKIP, - TEST_INVALID -}; +enum test_status { TEST_FAIL, TEST_PASS, TEST_SKIP, TEST_INVALID }; /* Really, just a boolean, but this is more self-documenting. */ -enum test_verbose { - CONCISE = 0, - VERBOSE = 1 -}; +enum test_verbose { CONCISE = 0, VERBOSE = 1 }; /* Indicates the state of our plan. */ enum plan_status { - PLAN_INIT, /* Nothing seen yet. */ - PLAN_FIRST, /* Plan seen before any tests. */ - PLAN_PENDING, /* Test seen and no plan yet. */ - PLAN_FINAL /* Plan seen after some tests. */ + PLAN_INIT, /* Nothing seen yet. */ + PLAN_FIRST, /* Plan seen before any tests. */ + PLAN_PENDING, /* Test seen and no plan yet. */ + PLAN_FINAL /* Plan seen after some tests. */ }; /* Error exit statuses for test processes. */ -#define CHILDERR_DUP 100 /* Couldn't redirect stderr or stdout. */ -#define CHILDERR_EXEC 101 /* Couldn't exec child process. */ -#define CHILDERR_STDIN 102 /* Couldn't open stdin file. */ -#define CHILDERR_STDERR 103 /* Couldn't open stderr file. */ +#define CHILDERR_DUP 100 /* Couldn't redirect stderr or stdout. */ +#define CHILDERR_EXEC 101 /* Couldn't exec child process. */ +#define CHILDERR_STDIN 102 /* Couldn't open stdin file. */ +#define CHILDERR_STDERR 103 /* Couldn't open stderr file. */ /* Structure to hold data for a set of tests. */ struct testset { - char *file; /* The file name of the test. */ - char **command; /* The argv vector to run the command. */ - enum plan_status plan; /* The status of our plan. */ - unsigned long count; /* Expected count of tests. */ - unsigned long current; /* The last seen test number. */ - unsigned int length; /* The length of the last status message. */ - unsigned long passed; /* Count of passing tests. */ - unsigned long failed; /* Count of failing lists. */ - unsigned long skipped; /* Count of skipped tests (passed). */ - unsigned long allocated; /* The size of the results table. */ - enum test_status *results; /* Table of results by test number. */ - unsigned int aborted; /* Whether the set was aborted. */ - unsigned int reported; /* Whether the results were reported. */ - int status; /* The exit status of the test. */ - unsigned int all_skipped; /* Whether all tests were skipped. */ - char *reason; /* Why all tests were skipped. */ + char *file; /* The file name of the test. */ + char **command; /* The argv vector to run the command. */ + enum plan_status plan; /* The status of our plan. */ + unsigned long count; /* Expected count of tests. */ + unsigned long current; /* The last seen test number. */ + unsigned int length; /* The length of the last status message. */ + unsigned long passed; /* Count of passing tests. */ + unsigned long failed; /* Count of failing lists. */ + unsigned long skipped; /* Count of skipped tests (passed). */ + unsigned long allocated; /* The size of the results table. */ + enum test_status *results; /* Table of results by test number. */ + unsigned int aborted; /* Whether the set was aborted. */ + unsigned int reported; /* Whether the results were reported. */ + int status; /* The exit status of the test. */ + unsigned int all_skipped; /* Whether all tests were skipped. */ + char *reason; /* Why all tests were skipped. */ }; /* Structure to hold a linked list of test sets. */ @@ -246,12 +238,13 @@ Failed Set Fail/Total (%) Skip Stat Failing Tests\n\ -------------------------- -------------- ---- ---- ------------------------"; /* Include the file name and line number in malloc failures. */ -#define xcalloc(n, size) x_calloc((n), (size), __FILE__, __LINE__) -#define xmalloc(size) x_malloc((size), __FILE__, __LINE__) -#define xstrdup(p) x_strdup((p), __FILE__, __LINE__) -#define xstrndup(p, size) x_strndup((p), (size), __FILE__, __LINE__) -#define xreallocarray(p, n, size) \ - x_reallocarray((p), (n), (size), __FILE__, __LINE__) +#define xcalloc(n, type) \ + ((type *) x_calloc((n), sizeof(type), __FILE__, __LINE__)) +#define xmalloc(size) ((char *) x_malloc((size), __FILE__, __LINE__)) +#define xstrdup(p) x_strdup((p), __FILE__, __LINE__) +#define xstrndup(p, size) x_strndup((p), (size), __FILE__, __LINE__) +#define xreallocarray(p, n, type) \ + ((type *) x_reallocarray((p), (n), sizeof(type), __FILE__, __LINE__)) /* * __attribute__ is available in gcc 2.5 and later, but only with gcc 2.7 @@ -259,9 +252,9 @@ Failed Set Fail/Total (%) Skip Stat Failing Tests\n\ * (to avoid confusion with other macros). */ #ifndef __attribute__ -# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) -# define __attribute__(spec) /* empty */ -# endif +# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) +# define __attribute__(spec) /* empty */ +# endif #endif /* @@ -272,11 +265,11 @@ Failed Set Fail/Total (%) Skip Stat Failing Tests\n\ * variadic macro support. */ #if !defined(__attribute__) && !defined(__alloc_size__) -# if defined(__GNUC__) && !defined(__clang__) -# if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 3) -# define __alloc_size__(spec, args...) /* empty */ -# endif -# endif +# if defined(__GNUC__) && !defined(__clang__) +# if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 3) +# define __alloc_size__(spec, args...) /* empty */ +# endif +# endif #endif /* @@ -286,7 +279,7 @@ Failed Set Fail/Total (%) Skip Stat Failing Tests\n\ * compilation context, but there's no push and pop available. */ #if !defined(__attribute__) && (defined(__llvm__) || defined(__clang__)) -# pragma GCC diagnostic ignored "-Wattributes" +# pragma GCC diagnostic ignored "-Wattributes" #endif /* Declare internal functions that benefit from compiler attributes. */ @@ -394,6 +387,9 @@ x_malloc(size_t size, const char *file, int line) static void * x_reallocarray(void *p, size_t n, size_t size, const char *file, int line) { + n = (n > 0) ? n : 1; + size = (size > 0) ? size : 1; + if (n > 0 && UINT_MAX / n <= size) sysdie("realloc too large at %s line %d", file, line); p = realloc(p, n * size); @@ -414,10 +410,10 @@ x_strdup(const char *s, const char *file, int line) size_t len; len = strlen(s) + 1; - p = malloc(len); + p = (char *) malloc(len); if (p == NULL) - sysdie("failed to strdup %lu bytes at %s line %d", - (unsigned long) len, file, line); + sysdie("failed to strdup %lu bytes at %s line %d", (unsigned long) len, + file, line); memcpy(p, s, len); return p; } @@ -439,10 +435,10 @@ x_strndup(const char *s, size_t size, const char *file, int line) char *copy; /* Don't assume that the source string is nul-terminated. */ - for (p = s; (size_t) (p - s) < size && *p != '\0'; p++) + for (p = s; (size_t)(p - s) < size && *p != '\0'; p++) ; - len = (size_t) (p - s); - copy = malloc(len + 1); + len = (size_t)(p - s); + copy = (char *) malloc(len + 1); if (copy == NULL) sysdie("failed to strndup %lu bytes at %s line %d", (unsigned long) len, file, line); @@ -539,7 +535,7 @@ tv_sum(const struct timeval *tv1, const struct timeval *tv2) static const char * skip_whitespace(const char *p) { - while (isspace((unsigned char)(*p))) + while (isspace((unsigned char) (*p))) p++; return p; } @@ -552,7 +548,7 @@ skip_whitespace(const char *p) static const char * skip_non_whitespace(const char *p) { - while (*p != '\0' && !isspace((unsigned char)(*p))) + while (*p != '\0' && !isspace((unsigned char) (*p))) p++; return p; } @@ -670,10 +666,10 @@ resize_results(struct testset *ts, unsigned long n) */ if (ts->allocated == 0) { s = (n > 32) ? n : 32; - ts->results = xcalloc(s, sizeof(enum test_status)); + ts->results = xcalloc(s, enum test_status); } else { s = (n > ts->allocated + 1024) ? n : ts->allocated + 1024; - ts->results = xreallocarray(ts->results, s, sizeof(enum test_status)); + ts->results = xreallocarray(ts->results, s, enum test_status); } /* Set the results for the newly-allocated test array. */ @@ -787,8 +783,7 @@ test_plan(const char *line, struct testset *ts, enum test_verbose verbose) * reported status. */ static void -test_checkline(const char *line, struct testset *ts, - enum test_verbose verbose) +test_checkline(const char *line, struct testset *ts, enum test_verbose verbose) { enum test_status status = TEST_PASS; const char *bail; @@ -828,7 +823,7 @@ test_checkline(const char *line, struct testset *ts, return; /* If we haven't yet seen a plan, look for one. */ - if (ts->plan == PLAN_INIT && isdigit((unsigned char)(*line))) { + if (ts->plan == PLAN_INIT && isdigit((unsigned char) (*line))) { if (!test_plan(line, ts, verbose)) return; } else if (strncmp(line, "1..", 3) == 0) { @@ -879,7 +874,7 @@ test_checkline(const char *line, struct testset *ts, * Handle directives. We should probably do something more interesting * with unexpected passes of todo tests. */ - while (isdigit((unsigned char)(*line))) + while (isdigit((unsigned char) (*line))) line++; line = skip_whitespace(line); if (*line == '#') { @@ -902,10 +897,17 @@ test_checkline(const char *line, struct testset *ts, /* Good results. Increment our various counters. */ switch (status) { - case TEST_PASS: ts->passed++; break; - case TEST_FAIL: ts->failed++; break; - case TEST_SKIP: ts->skipped++; break; - case TEST_INVALID: break; + case TEST_PASS: + ts->passed++; + break; + case TEST_FAIL: + ts->failed++; + break; + case TEST_SKIP: + ts->skipped++; + break; + case TEST_INVALID: + break; } ts->current = current; ts->results[current - 1] = status; @@ -1252,7 +1254,7 @@ find_test(const char *name, const char *source, const char *build) char *path = NULL; const char *bases[3], *suffix, *base; unsigned int i, j; - const char *suffixes[3] = { "-t", ".t", "" }; + const char *suffixes[3] = {"-t", ".t", ""}; /* Possible base directories. */ bases[0] = "."; @@ -1321,11 +1323,9 @@ parse_test_list_line(const char *line, struct testset *ts, const char *source, end = skip_non_whitespace(p); if (strncmp(p, "libtool", end - p) == 0) { use_libtool = 1; - p = end; } else if (strncmp(p, "valgrind", end - p) == 0) { valgrind = getenv("C_TAP_VALGRIND"); use_valgrind = (valgrind != NULL); - p = end; } else { option = xstrndup(p, end - p); die("unknown test list option %s", option); @@ -1346,7 +1346,7 @@ parse_test_list_line(const char *line, struct testset *ts, const char *source, } /* Now, build the command. */ - ts->command = xcalloc(len + 1, sizeof(char *)); + ts->command = xcalloc(len + 1, char *); i = 0; if (use_valgrind && valgrind != NULL) { if (use_libtool) { @@ -1388,7 +1388,7 @@ read_test_list(const char *filename, const char *source, const char *build) struct testlist *listhead, *current; /* Create the initial container list that will hold our results. */ - listhead = xcalloc(1, sizeof(struct testlist)); + listhead = xcalloc(1, struct testlist); current = NULL; /* @@ -1419,10 +1419,10 @@ read_test_list(const char *filename, const char *source, const char *build) if (current == NULL) current = listhead; else { - current->next = xcalloc(1, sizeof(struct testlist)); + current->next = xcalloc(1, struct testlist); current = current->next; } - current->ts = xcalloc(1, sizeof(struct testset)); + current->ts = xcalloc(1, struct testset); current->ts->plan = PLAN_INIT; /* Parse the line and store the results in the testset struct. */ @@ -1454,7 +1454,7 @@ build_test_list(char *argv[], int argc, const char *source, const char *build) struct testlist *listhead, *current; /* Create the initial container list that will hold our results. */ - listhead = xcalloc(1, sizeof(struct testlist)); + listhead = xcalloc(1, struct testlist); current = NULL; /* Walk the list of arguments and create test sets for them. */ @@ -1462,13 +1462,13 @@ build_test_list(char *argv[], int argc, const char *source, const char *build) if (current == NULL) current = listhead; else { - current->next = xcalloc(1, sizeof(struct testlist)); + current->next = xcalloc(1, struct testlist); current = current->next; } - current->ts = xcalloc(1, sizeof(struct testset)); + current->ts = xcalloc(1, struct testset); current->ts->plan = PLAN_INIT; current->ts->file = xstrdup(argv[i]); - current->ts->command = xcalloc(2, sizeof(char *)); + current->ts->command = xcalloc(2, char *); current->ts->command[0] = find_test(current->ts->file, source, build); current->ts->command[1] = NULL; } @@ -1575,10 +1575,10 @@ test_batch(struct testlist *tests, enum test_verbose verbose) /* If the test fails, we shuffle it over to the fail list. */ if (!succeeded) { if (failhead == NULL) { - failhead = xmalloc(sizeof(struct testset)); + failhead = xcalloc(1, struct testlist); failtail = failhead; } else { - failtail->next = xmalloc(sizeof(struct testset)); + failtail->next = xcalloc(1, struct testlist); failtail = failtail->next; } failtail->ts = ts; @@ -1617,8 +1617,7 @@ test_batch(struct testlist *tests, enum test_verbose verbose) else printf("Aborted %lu test sets", aborted); printf(", passed %lu/%lu tests", passed, total); - } - else if (failed == 0) + } else if (failed == 0) fputs("All tests successful", stdout); else printf("Failed %lu/%lu tests, %.2f%% okay", failed, total, @@ -1632,8 +1631,8 @@ test_batch(struct testlist *tests, enum test_verbose verbose) puts("."); printf("Files=%u, Tests=%lu", count, total); printf(", %.2f seconds", tv_diff(&end, &start)); - printf(" (%.2f usr + %.2f sys = %.2f CPU)\n", - tv_seconds(&stats.ru_utime), tv_seconds(&stats.ru_stime), + printf(" (%.2f usr + %.2f sys = %.2f CPU)\n", tv_seconds(&stats.ru_utime), + tv_seconds(&stats.ru_stime), tv_sum(&stats.ru_utime, &stats.ru_stime)); return (failed == 0 && aborted == 0); } |