aboutsummaryrefslogtreecommitdiff
path: root/tests/tap/basic.c
diff options
context:
space:
mode:
authorRuss Allbery <eagle@eyrie.org>2020-05-17 17:05:30 -0700
committerRuss Allbery <eagle@eyrie.org>2020-05-17 17:05:30 -0700
commitc138111a3c27863308b6552a5527a9e821a3dc11 (patch)
treefe3c16462bf0213708f20d251a63e5b9bbf2d23f /tests/tap/basic.c
parentccfbd34d597318215b979338c4cb5d7e4a3f0d6f (diff)
Update to rra-c-util 8.2 and C TAP Harness 4.7
Update to rra-c-util 8.2: * Implement explicit_bzero with memset if it is not available. * Reformat all C source using clang-format 10. * Work around Test::Strict not skipping .git directories. * Fix warnings with perltidy 20190601 and Perl::Critic 1.134. * Fix warnings with Clang 10, GCC 10, and the Clang static analyzer. Update to C TAP Harness 4.7: * Fix warnings with GCC 10. * Reformat all C source using clang-format 10. * Fixed malloc error checking in bstrndup.
Diffstat (limited to 'tests/tap/basic.c')
-rw-r--r--tests/tap/basic.c214
1 files changed, 129 insertions, 85 deletions
diff --git a/tests/tap/basic.c b/tests/tap/basic.c
index 8624839..b5f42d0 100644
--- a/tests/tap/basic.c
+++ b/tests/tap/basic.c
@@ -13,7 +13,7 @@
* documentation is at <https://www.eyrie.org/~eagle/software/c-tap-harness/>.
*
* Written by Russ Allbery <eagle@eyrie.org>
- * Copyright 2009-2018 Russ Allbery <eagle@eyrie.org>
+ * Copyright 2009-2019 Russ Allbery <eagle@eyrie.org>
* Copyright 2001-2002, 2004-2008, 2011-2014
* The Board of Trustees of the Leland Stanford Junior University
*
@@ -45,9 +45,9 @@
#include <stdlib.h>
#include <string.h>
#ifdef _WIN32
-# include <direct.h>
+# include <direct.h>
#else
-# include <sys/stat.h>
+# include <sys/stat.h>
#endif
#include <sys/types.h>
#include <unistd.h>
@@ -56,8 +56,8 @@
/* Windows provides mkdir and rmdir under different names. */
#ifdef _WIN32
-# define mkdir(p, m) _mkdir(p)
-# define rmdir(p) _rmdir(p)
+# define mkdir(p, m) _mkdir(p)
+# define rmdir(p) _rmdir(p)
#endif
/*
@@ -72,7 +72,7 @@ unsigned long testnum = 1;
* We can get the highest test count from testnum.
*/
static unsigned long _planned = 0;
-static unsigned long _failed = 0;
+static unsigned long _failed = 0;
/*
* Store the PID of the process that called plan() and only summarize
@@ -101,6 +101,8 @@ static int _aborted = 0;
*/
struct cleanup_func {
test_cleanup_func func;
+ test_cleanup_func_with_data func_with_data;
+ void *data;
struct cleanup_func *next;
};
static struct cleanup_func *cleanup_funcs = NULL;
@@ -126,15 +128,15 @@ static struct diag_file *diag_files = NULL;
* print_desc, which has to be done in a macro. Assumes that format is the
* argument immediately before the variadic arguments.
*/
-#define PRINT_DESC(prefix, format) \
- do { \
- if (format != NULL) { \
- va_list args; \
- printf("%s", prefix); \
- va_start(args, format); \
- vprintf(format, args); \
- va_end(args); \
- } \
+#define PRINT_DESC(prefix, format) \
+ do { \
+ if (format != NULL) { \
+ va_list args; \
+ printf("%s", prefix); \
+ va_start(args, format); \
+ vprintf(format, args); \
+ va_end(args); \
+ } \
} while (0)
@@ -171,7 +173,7 @@ concat(const char *first, ...)
length++;
/* Create the string. */
- result = bmalloc(length);
+ result = bcalloc_type(length, char);
va_start(args, first);
offset = 0;
for (string = first; string != NULL; string = va_arg(args, const char *)) {
@@ -185,6 +187,68 @@ concat(const char *first, ...)
/*
+ * Helper function for check_diag_files to handle a single line in a diag
+ * file.
+ *
+ * The general scheme here used is as follows: read one line of output. If we
+ * get NULL, check for an error. If there was one, bail out of the test
+ * program; otherwise, return, and the enclosing loop will check for EOF.
+ *
+ * If we get some data, see if it ends in a newline. If it doesn't end in a
+ * newline, we have one of two cases: our buffer isn't large enough, in which
+ * case we resize it and try again, or we have incomplete data in the file, in
+ * which case we rewind the file and will try again next time.
+ *
+ * Returns a boolean indicating whether the last line was incomplete.
+ */
+static int
+handle_diag_file_line(struct diag_file *file, fpos_t where)
+{
+ int size;
+ size_t length;
+
+ /* Read the next line from the file. */
+ size = file->bufsize > INT_MAX ? INT_MAX : (int) file->bufsize;
+ if (fgets(file->buffer, size, file->file) == NULL) {
+ if (ferror(file->file))
+ sysbail("cannot read from %s", file->name);
+ return 0;
+ }
+
+ /*
+ * See if the line ends in a newline. If not, see which error case we
+ * have.
+ */
+ length = strlen(file->buffer);
+ if (file->buffer[length - 1] != '\n') {
+ int incomplete = 0;
+
+ /* Check whether we ran out of buffer space and resize if so. */
+ if (length < file->bufsize - 1)
+ incomplete = 1;
+ else {
+ file->bufsize += BUFSIZ;
+ file->buffer =
+ breallocarray_type(file->buffer, file->bufsize, char);
+ }
+
+ /*
+ * On either incomplete lines or too small of a buffer, rewind
+ * and read the file again (on the next pass, if incomplete).
+ * It's simpler than trying to double-buffer the file.
+ */
+ if (fsetpos(file->file, &where) < 0)
+ sysbail("cannot set position in %s", file->name);
+ return incomplete;
+ }
+
+ /* We saw a complete line. Print it out. */
+ printf("# %s", file->buffer);
+ return 0;
+}
+
+
+/*
* Check all registered diag_files for any output. We only print out the
* output if we see a complete line; otherwise, we wait for the next newline.
*/
@@ -193,20 +257,10 @@ check_diag_files(void)
{
struct diag_file *file;
fpos_t where;
- size_t length;
- int size, incomplete;
+ int incomplete;
/*
- * Walk through each file and read each line of output available. The
- * general scheme here used is as follows: try to read a line of output at
- * a time. If we get NULL, check for EOF; on EOF, advance to the next
- * file.
- *
- * If we get some data, see if it ends in a newline. If it doesn't end in
- * a newline, we have one of two cases: our buffer isn't large enough, in
- * which case we resize it and try again, or we have incomplete data in
- * the file, in which case we rewind the file and will try again next
- * time.
+ * Walk through each file and read each line of output available.
*/
for (file = diag_files; file != NULL; file = file->next) {
clearerr(file->file);
@@ -218,41 +272,7 @@ check_diag_files(void)
/* Continue until we get EOF or an incomplete line of data. */
incomplete = 0;
while (!feof(file->file) && !incomplete) {
- size = file->bufsize > INT_MAX ? INT_MAX : (int) file->bufsize;
- if (fgets(file->buffer, size, file->file) == NULL) {
- if (ferror(file->file))
- sysbail("cannot read from %s", file->name);
- continue;
- }
-
- /*
- * See if the line ends in a newline. If not, see which error
- * case we have. Use UINT_MAX as a substitute for SIZE_MAX (see
- * the comment for breallocarray).
- */
- length = strlen(file->buffer);
- if (file->buffer[length - 1] != '\n') {
- if (length < file->bufsize - 1)
- incomplete = 1;
- else {
- if (file->bufsize >= UINT_MAX - BUFSIZ)
- sysbail("line too long in %s", file->name);
- file->bufsize += BUFSIZ;
- file->buffer = brealloc(file->buffer, file->bufsize);
- }
-
- /*
- * On either incomplete lines or too small of a buffer, rewind
- * and read the file again (on the next pass, if incomplete).
- * It's simpler than trying to double-buffer the file.
- */
- if (fsetpos(file->file, &where) < 0)
- sysbail("cannot set position in %s", file->name);
- continue;
- }
-
- /* We saw a complete line. Print it out. */
- printf("# %s", file->buffer);
+ incomplete = handle_diag_file_line(file, where);
}
}
}
@@ -305,7 +325,13 @@ finish(void)
*/
primary = (_process == 0 || getpid() == _process);
while (cleanup_funcs != NULL) {
- cleanup_funcs->func(success, primary);
+ if (cleanup_funcs->func_with_data) {
+ void *data = cleanup_funcs->data;
+
+ cleanup_funcs->func_with_data(success, primary, data);
+ } else {
+ cleanup_funcs->func(success, primary);
+ }
current = cleanup_funcs;
cleanup_funcs = cleanup_funcs->next;
free(current);
@@ -503,7 +529,7 @@ is_bool(int left, int right, const char *format, ...)
if (success)
printf("ok %lu", testnum++);
else {
- diag(" left: %s", !!left ? "true" : "false");
+ diag(" left: %s", !!left ? "true" : "false");
diag("right: %s", !!right ? "true" : "false");
printf("not ok %lu", testnum++);
_failed++;
@@ -563,7 +589,7 @@ is_string(const char *left, const char *right, const char *format, ...)
if (success)
printf("ok %lu", testnum++);
else {
- diag(" left: %s", left == NULL ? "(null)" : left);
+ diag(" left: %s", left == NULL ? "(null)" : left);
diag("right: %s", right == NULL ? "(null)" : right);
printf("not ok %lu", testnum++);
_failed++;
@@ -617,8 +643,8 @@ is_blob(const void *left, const void *right, size_t len, const char *format,
if (success)
printf("ok %lu", testnum++);
else {
- const unsigned char *left_c = left;
- const unsigned char *right_c = right;
+ const unsigned char *left_c = (const unsigned char *) left;
+ const unsigned char *right_c = (const unsigned char *) right;
for (i = 0; i < len; i++) {
if (left_c[i] != right_c[i])
@@ -728,12 +754,12 @@ diag_file_add(const char *name)
{
struct diag_file *file, *prev;
- file = bcalloc(1, sizeof(struct diag_file));
+ file = bcalloc_type(1, struct diag_file);
file->name = bstrdup(name);
file->file = fopen(file->name, "r");
if (file->file == NULL)
sysbail("cannot open %s", name);
- file->buffer = bmalloc(BUFSIZ);
+ file->buffer = bcalloc_type(BUFSIZ, char);
file->bufsize = BUFSIZ;
if (diag_files == NULL)
diag_files = file;
@@ -781,7 +807,7 @@ bcalloc(size_t n, size_t size)
p = calloc(n, size);
if (p == NULL)
- sysbail("failed to calloc %lu", (unsigned long)(n * size));
+ sysbail("failed to calloc %lu", (unsigned long) (n * size));
return p;
}
@@ -852,7 +878,7 @@ bstrdup(const char *s)
size_t len;
len = strlen(s) + 1;
- p = malloc(len);
+ p = (char *) malloc(len);
if (p == NULL)
sysbail("failed to strdup %lu bytes", (unsigned long) len);
memcpy(p, s, len);
@@ -873,11 +899,11 @@ bstrndup(const char *s, size_t n)
size_t length;
/* Don't assume that the source string is nul-terminated. */
- for (p = s; (size_t) (p - s) < n && *p != '\0'; p++)
+ for (p = s; (size_t)(p - s) < n && *p != '\0'; p++)
;
- length = (size_t) (p - s);
- copy = malloc(length + 1);
- if (p == NULL)
+ length = (size_t)(p - s);
+ copy = (char *) malloc(length + 1);
+ if (copy == NULL)
sysbail("failed to strndup %lu bytes", (unsigned long) length);
memcpy(copy, s, length);
copy[length] = '\0';
@@ -896,7 +922,7 @@ test_file_path(const char *file)
{
char *base;
char *path = NULL;
- const char *envs[] = { "C_TAP_BUILD", "C_TAP_SOURCE", NULL };
+ const char *envs[] = {"C_TAP_BUILD", "C_TAP_SOURCE", NULL};
int i;
for (i = 0; envs[i] != NULL; i++) {
@@ -965,21 +991,39 @@ test_tmpdir_free(char *path)
free(path);
}
-
-/*
- * Register a cleanup function that is called when testing ends. All such
- * registered functions will be run by finish.
- */
-void
-test_cleanup_register(test_cleanup_func func)
+static void
+register_cleanup(test_cleanup_func func,
+ test_cleanup_func_with_data func_with_data, void *data)
{
struct cleanup_func *cleanup, **last;
- cleanup = bmalloc(sizeof(struct cleanup_func));
+ cleanup = bcalloc_type(1, struct cleanup_func);
cleanup->func = func;
+ cleanup->func_with_data = func_with_data;
+ cleanup->data = data;
cleanup->next = NULL;
last = &cleanup_funcs;
while (*last != NULL)
last = &(*last)->next;
*last = cleanup;
}
+
+/*
+ * Register a cleanup function that is called when testing ends. All such
+ * registered functions will be run by finish.
+ */
+void
+test_cleanup_register(test_cleanup_func func)
+{
+ register_cleanup(func, NULL, NULL);
+}
+
+/*
+ * Same as above, but also allows an opaque pointer to be passed to the cleanup
+ * function.
+ */
+void
+test_cleanup_register_with_data(test_cleanup_func_with_data func, void *data)
+{
+ register_cleanup(NULL, func, data);
+}