X-Git-Url: http://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Ftap%2Ftap.c;h=bf8a276c7926a3cad99618cce1eaafbaf9d61582;hp=6e268324446b7d1e33a7953005306b971ba1cf4b;hb=c438ec17d7b2efe76e56e5fc5ab88bd4a02735e8;hpb=30d3e635ecef7961777a1aa98b1bde23712d6547 diff --git a/ccan/tap/tap.c b/ccan/tap/tap.c index 6e268324..bf8a276c 100644 --- a/ccan/tap/tap.c +++ b/ccan/tap/tap.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#define _GNU_SOURCE +#include "config.h" #include #include #include @@ -39,14 +39,19 @@ static unsigned int test_count = 0; /* Number of tests that have been run */ static unsigned int e_tests = 0; /* Expected number of tests to run */ static unsigned int failures = 0; /* Number of tests that failed */ static char *todo_msg = NULL; -static char *todo_msg_fixed = "libtap malloc issue"; +static const char *todo_msg_fixed = "libtap malloc issue"; static int todo = 0; static int test_died = 0; static int test_pid; /* Encapsulate the pthread code in a conditional. In the absence of - libpthread the code does nothing */ -#ifdef HAVE_LIBPTHREAD + libpthread the code does nothing. + + If you have multiple threads calling ok() etc. at the same time you would + need this, but in that case your test numbers will be random and I'm not + sure it makes sense. --RR +*/ +#ifdef WANT_PTHREAD #include static pthread_mutex_t M = PTHREAD_MUTEX_INITIALIZER; # define LOCK pthread_mutex_lock(&M) @@ -65,15 +70,15 @@ _expected_tests(unsigned int tests) } static void -diagv(char *fmt, va_list ap) +diagv(const char *fmt, va_list ap) { - fputs("# ", stderr); - vfprintf(stderr, fmt, ap); - fputs("\n", stderr); + fputs("# ", stdout); + vfprintf(stdout, fmt, ap); + fputs("\n", stdout); } static void -_diag(char *fmt, ...) +_diag(const char *fmt, ...) { va_list ap; va_start(ap, fmt); @@ -89,8 +94,8 @@ _diag(char *fmt, ...) * test_comment -- a comment to print afterwards, may be NULL */ unsigned int -_gen_result(int ok, const char *func, char *file, unsigned int line, - char *test_name, ...) +_gen_result(int ok, const char *func, const char *file, unsigned int line, + const char *test_name, ...) { va_list ap; char *local_test_name = NULL; @@ -105,7 +110,8 @@ _gen_result(int ok, const char *func, char *file, unsigned int line, expansions on it */ if(test_name != NULL) { va_start(ap, test_name); - vasprintf(&local_test_name, test_name, ap); + if (vasprintf(&local_test_name, test_name, ap) < 0) + local_test_name = NULL; va_end(ap); /* Make sure the test name contains more than digits @@ -114,7 +120,8 @@ _gen_result(int ok, const char *func, char *file, unsigned int line, if(local_test_name) { name_is_digits = 1; for(c = local_test_name; *c != '\0'; c++) { - if(!isdigit(*c) && !isspace(*c)) { + if(!isdigit((unsigned char)*c) + && !isspace((unsigned char)*c)) { name_is_digits = 0; break; } @@ -168,13 +175,16 @@ _gen_result(int ok, const char *func, char *file, unsigned int line, printf("\n"); if(!ok) - _diag(" Failed %stest (%s:%s() at line %d)", + _diag(" Failed %stest (%s:%s() at line %d)", todo ? "(TODO) " : "", file, func, line); free(local_test_name); UNLOCK; + if (!ok && tap_fail_callback) + tap_fail_callback(); + /* We only care (when testing) that ok is positive, but here we specifically only want to return 1 or 0 */ return ok ? 1 : 0; @@ -226,7 +236,7 @@ _cleanup(void) _diag("Looks like you planned %d tests but only ran %d.", e_tests, test_count); if(failures) { - _diag("Looks like you failed %d tests of %d run.", + _diag("Looks like you failed %d tests of %d run.", failures, test_count); } UNLOCK; @@ -234,7 +244,7 @@ _cleanup(void) } if(failures) - _diag("Looks like you failed %d tests of %d.", + _diag("Looks like you failed %d tests of %d.", failures, test_count); UNLOCK; @@ -254,9 +264,9 @@ _tap_init(void) atexit(_cleanup); /* stdout needs to be unbuffered so that the output appears - in the same place relative to stderr output as it does + in the same place relative to stderr output as it does with Test::Harness */ - setbuf(stdout, 0); +// setbuf(stdout, 0); run_once = 1; } } @@ -289,7 +299,7 @@ plan_no_plan(void) * Note that the plan is to skip all tests */ void -plan_skip_all(char *reason) +plan_skip_all(const char *reason) { LOCK; @@ -341,7 +351,7 @@ plan_tests(unsigned int tests) } void -diag(char *fmt, ...) +diag(const char *fmt, ...) { va_list ap; @@ -355,7 +365,7 @@ diag(char *fmt, ...) } void -skip(unsigned int n, char *fmt, ...) +skip(unsigned int n, const char *fmt, ...) { va_list ap; char *skip_msg; @@ -363,13 +373,14 @@ skip(unsigned int n, char *fmt, ...) LOCK; va_start(ap, fmt); - vasprintf(&skip_msg, fmt, ap); + if (vasprintf(&skip_msg, fmt, ap) < 0) + skip_msg = NULL; va_end(ap); while(n-- > 0) { test_count++; - printf("ok %d # skip %s\n", test_count, - skip_msg != NULL ? + printf("ok %d # skip %s\n", test_count, + skip_msg != NULL ? skip_msg : "libtap():malloc() failed"); } @@ -379,14 +390,15 @@ skip(unsigned int n, char *fmt, ...) } void -todo_start(char *fmt, ...) +todo_start(const char *fmt, ...) { va_list ap; LOCK; va_start(ap, fmt); - vasprintf(&todo_msg, fmt, ap); + if (vasprintf(&todo_msg, fmt, ap) < 0) + todo_msg = NULL; va_end(ap); todo = 1; @@ -406,8 +418,8 @@ todo_end(void) UNLOCK; } -int -exit_status(void) +static int +exit_status_(void) { int r; @@ -427,10 +439,19 @@ exit_status(void) return r; } - /* Return the number of tests that failed + the number of tests + /* Return the number of tests that failed + the number of tests that weren't run */ r = failures + e_tests - test_count; UNLOCK; return r; } + +int +exit_status(void) +{ + int r = exit_status_(); + if (r > 255) + r = 255; + return r; +}