diff options
| author | Russ Allbery <eagle@eyrie.org> | 2020-05-17 17:05:30 -0700 | 
|---|---|---|
| committer | Russ Allbery <eagle@eyrie.org> | 2020-05-17 17:05:30 -0700 | 
| commit | c138111a3c27863308b6552a5527a9e821a3dc11 (patch) | |
| tree | fe3c16462bf0213708f20d251a63e5b9bbf2d23f /tests/tap/basic.c | |
| parent | ccfbd34d597318215b979338c4cb5d7e4a3f0d6f (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.c | 214 | 
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); +} | 
