* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-#define _GNU_SOURCE
+#include "config.h"
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
+#include <unistd.h>
#include "tap.h"
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 <pthread.h>
static pthread_mutex_t M = PTHREAD_MUTEX_INITIALIZER;
# define LOCK pthread_mutex_lock(&M)
}
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);
* 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;
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
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;
}
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;
static void
_cleanup(void)
{
+ /* If we forked, don't do cleanup in child! */
+ if (getpid() != test_pid)
+ return;
LOCK;
_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;
}
if(failures)
- _diag("Looks like you failed %d tests of %d.",
+ _diag("Looks like you failed %d tests of %d.",
failures, test_count);
UNLOCK;
static int run_once = 0;
if(!run_once) {
+ test_pid = getpid();
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;
}
}
* Note that the plan is to skip all tests
*/
void
-plan_skip_all(char *reason)
+plan_skip_all(const char *reason)
{
LOCK;
}
void
-diag(char *fmt, ...)
+diag(const char *fmt, ...)
{
va_list ap;
}
void
-skip(unsigned int n, char *fmt, ...)
+skip(unsigned int n, const char *fmt, ...)
{
va_list ap;
char *skip_msg;
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");
}
}
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;
UNLOCK;
}
-int
-exit_status(void)
+static int
+exit_status_(void)
{
int r;
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;
+}