Procházet zdrojové kódy

Add Libtap as a bundled library (does not change any behaviour without --enable-libtap)

Detects system library as pre-1.4.13 and does not install the built-in library anymore

Tested on:
  - Linux x86_64, with and without local libtap (System libtap installed)
	- Linux x86, with and without local libtap (System libtap NOT installed)
  - Solaris SPARC, with and without local libtap, with and without system libtap installed
Thomas Guyot-Sionnest před 17 roky
rodič
revize
2bbf2e6967
74 změnil soubory, kde provedl 2743 přidání a 64 odebrání
  1. 8 0
      .gitignore
  2. 1 1
      Makefile.am
  3. 1 0
      NEWS
  4. 74 43
      configure.in
  5. 29 20
      lib/tests/Makefile.am
  6. 13 0
      tap/Makefile.am
  7. 11 0
      tap/README
  8. 368 0
      tap/tap.3
  9. 435 0
      tap/tap.c
  10. 89 0
      tap/tap.h
  11. 7 0
      tap/tests/Makefile.am
  12. 12 0
      tap/tests/README
  13. 13 0
      tap/tests/diag/Makefile.am
  14. 46 0
      tap/tests/diag/test.c
  15. 16 0
      tap/tests/diag/test.pl
  16. 29 0
      tap/tests/diag/test.t
  17. 13 0
      tap/tests/fail/Makefile.am
  18. 46 0
      tap/tests/fail/test.c
  19. 17 0
      tap/tests/fail/test.pl
  20. 29 0
      tap/tests/fail/test.t
  21. 3 0
      tap/tests/ok/Makefile.am
  22. 13 0
      tap/tests/ok/ok-hash/Makefile.am
  23. 52 0
      tap/tests/ok/ok-hash/test.c
  24. 24 0
      tap/tests/ok/ok-hash/test.pl
  25. 29 0
      tap/tests/ok/ok-hash/test.t
  26. 13 0
      tap/tests/ok/ok-numeric/Makefile.am
  27. 49 0
      tap/tests/ok/ok-numeric/test.c
  28. 21 0
      tap/tests/ok/ok-numeric/test.pl
  29. 29 0
      tap/tests/ok/ok-numeric/test.t
  30. 13 0
      tap/tests/ok/ok/Makefile.am
  31. 55 0
      tap/tests/ok/ok/test.c
  32. 27 0
      tap/tests/ok/ok/test.pl
  33. 29 0
      tap/tests/ok/ok/test.t
  34. 13 0
      tap/tests/pass/Makefile.am
  35. 46 0
      tap/tests/pass/test.c
  36. 17 0
      tap/tests/pass/test.pl
  37. 29 0
      tap/tests/pass/test.t
  38. 7 0
      tap/tests/plan/Makefile.am
  39. 13 0
      tap/tests/plan/no-tests/Makefile.am
  40. 43 0
      tap/tests/plan/no-tests/test.c
  41. 14 0
      tap/tests/plan/no-tests/test.pl
  42. 29 0
      tap/tests/plan/no-tests/test.t
  43. 13 0
      tap/tests/plan/no_plan/Makefile.am
  44. 43 0
      tap/tests/plan/no_plan/test.c
  45. 14 0
      tap/tests/plan/no_plan/test.pl
  46. 29 0
      tap/tests/plan/no_plan/test.t
  47. 13 0
      tap/tests/plan/not-enough-tests/Makefile.am
  48. 49 0
      tap/tests/plan/not-enough-tests/test.c
  49. 20 0
      tap/tests/plan/not-enough-tests/test.pl
  50. 29 0
      tap/tests/plan/not-enough-tests/test.t
  51. 13 0
      tap/tests/plan/sane/Makefile.am
  52. 43 0
      tap/tests/plan/sane/test.c
  53. 14 0
      tap/tests/plan/sane/test.pl
  54. 29 0
      tap/tests/plan/sane/test.t
  55. 13 0
      tap/tests/plan/skip_all/Makefile.am
  56. 38 0
      tap/tests/plan/skip_all/test.c
  57. 11 0
      tap/tests/plan/skip_all/test.pl
  58. 29 0
      tap/tests/plan/skip_all/test.t
  59. 13 0
      tap/tests/plan/too-many-plans/Makefile.am
  60. 49 0
      tap/tests/plan/too-many-plans/test.c
  61. 20 0
      tap/tests/plan/too-many-plans/test.pl
  62. 29 0
      tap/tests/plan/too-many-plans/test.t
  63. 13 0
      tap/tests/plan/too-many-tests/Makefile.am
  64. 46 0
      tap/tests/plan/too-many-tests/test.c
  65. 17 0
      tap/tests/plan/too-many-tests/test.pl
  66. 29 0
      tap/tests/plan/too-many-tests/test.t
  67. 13 0
      tap/tests/skip/Makefile.am
  68. 69 0
      tap/tests/skip/test.c
  69. 40 0
      tap/tests/skip/test.pl
  70. 29 0
      tap/tests/skip/test.t
  71. 13 0
      tap/tests/todo/Makefile.am
  72. 68 0
      tap/tests/todo/test.c
  73. 41 0
      tap/tests/todo/test.pl
  74. 29 0
      tap/tests/todo/test.t

+ 8 - 0
.gitignore

@@ -96,6 +96,14 @@ NP-VERSION-FILE
 /intl/ref-del.sin
 /intl/ref-del.sin
 /intl/textdomain.c
 /intl/textdomain.c
 
 
+# /tap/
+/tap/.deps
+/tap/.libs
+/tap/Makefile
+/tap/Makefile.in
+/tap/libtap.la
+/tap/tap.lo
+
 # /lib/
 # /lib/
 /lib/.deps
 /lib/.deps
 /lib/getopt.h
 /lib/getopt.h

+ 1 - 1
Makefile.am

@@ -1,6 +1,6 @@
 ## Process this file with automake to produce Makefile.in
 ## Process this file with automake to produce Makefile.in
 
 
-SUBDIRS = gl lib plugins plugins-scripts plugins-root po @PERLMODS_DIR@
+SUBDIRS = gl tap lib plugins plugins-scripts plugins-root po @PERLMODS_DIR@
 
 
 EXTRA_DIST = config.rpath \
 EXTRA_DIST = config.rpath \
 	ABOUT-NLS ACKNOWLEDGEMENTS AUTHORS BUGS CODING FAQ LEGAL NEWS \
 	ABOUT-NLS ACKNOWLEDGEMENTS AUTHORS BUGS CODING FAQ LEGAL NEWS \

+ 1 - 0
NEWS

@@ -17,6 +17,7 @@ This file documents the major additions and syntax changes between releases.
 	Fixed bug where additional headers with redirection caused a segfault (Dieter Van de Walle - 2089159)
 	Fixed bug where additional headers with redirection caused a segfault (Dieter Van de Walle - 2089159)
 	check_disk: make autofs mount paths specified with -p before we determing the mount list (Erik Welch)
 	check_disk: make autofs mount paths specified with -p before we determing the mount list (Erik Welch)
 	Fixed buffer overflow in check_ntp/check_ntp_peer (#1999319, Ubuntu #291265)
 	Fixed buffer overflow in check_ntp/check_ntp_peer (#1999319, Ubuntu #291265)
+	Re-bundled libtap as a built-in library (--enable-libtap): detects system library as pre-1.4.13 and does not install the built-in library anymore
 
 
 1.4.13 25th Sept 2008
 1.4.13 25th Sept 2008
 	Fix Debian bug #460097: check_http --max-age broken (Hilko Bengen)
 	Fix Debian bug #460097: check_http --max-age broken (Hilko Bengen)

+ 74 - 43
configure.in

@@ -118,7 +118,7 @@ AC_SUBST(PERL, $with_perl)
 
 
 dnl openssl/gnutls
 dnl openssl/gnutls
 AC_ARG_WITH(openssl,
 AC_ARG_WITH(openssl,
-            AC_HELP_STRING([--with-openssl=DIR], 
+            AC_HELP_STRING([--with-openssl=DIR],
                            [path to openssl installation]),)
                            [path to openssl installation]),)
 
 
 AC_ARG_WITH(gnutls,
 AC_ARG_WITH(gnutls,
@@ -156,23 +156,41 @@ AC_CHECK_HEADERS(math.h)
 AC_CHECK_LIB(m,floor,MATHLIBS="-lm")
 AC_CHECK_LIB(m,floor,MATHLIBS="-lm")
 AC_SUBST(MATHLIBS)
 AC_SUBST(MATHLIBS)
 
 
-dnl Check for libtap, to run perl-like tests
-AC_CHECK_LIB(tap, plan_tests, 
+dnl Check if we buils local libtap
+AC_ARG_ENABLE(libtap,
+  AC_HELP_STRING([--enable-libtap],
+		[Enable built-in libtap for unit-testing (default: autodetect system library).]),
+	[enable_libtap=$enableval],
+	[enable_libtap=no])
+AM_CONDITIONAL([USE_LIBTAP_LOCAL],[test "$enable_libtap" = "yes"])
+
+# If not local, check if we can use the system one
+if test "$enable_libtap" != "yes" ; then
+	dnl Check for libtap, to run perl-like tests
+	AC_CHECK_LIB(tap, plan_tests,
+		enable_libtap="yes"
+		)
+fi
+
+# Finally, define tests if we use libtap
+if test "$enable_libtap" = "yes" ; then
 	EXTRA_TEST="test_utils test_disk test_tcp test_cmd test_base64"
 	EXTRA_TEST="test_utils test_disk test_tcp test_cmd test_base64"
 	AC_SUBST(EXTRA_TEST)
 	AC_SUBST(EXTRA_TEST)
-	)
+fi
 
 
 dnl INI Parsing
 dnl INI Parsing
 AC_ARG_ENABLE(extra-opts,
 AC_ARG_ENABLE(extra-opts,
-  AC_HELP_STRING([--enable-extra-opts], 
+  AC_HELP_STRING([--enable-extra-opts],
 		[Enables parsing of plugins ini config files for extra options (default: no)]),
 		[Enables parsing of plugins ini config files for extra options (default: no)]),
 	[enable_extra_opts=$enableval],
 	[enable_extra_opts=$enableval],
 	[enable_extra_opts=no])
 	[enable_extra_opts=no])
 AM_CONDITIONAL([USE_PARSE_INI],[test "$enable_extra_opts" = "yes"])
 AM_CONDITIONAL([USE_PARSE_INI],[test "$enable_extra_opts" = "yes"])
 if test "$enable_extra_opts" = "yes" ; then
 if test "$enable_extra_opts" = "yes" ; then
-	EXTRA_TEST="$EXTRA_TEST test_ini test_opts"
-	AC_SUBST(EXTRA_TEST)
 	AC_DEFINE(NP_EXTRA_OPTS,[1],[Enable INI file parsing.])
 	AC_DEFINE(NP_EXTRA_OPTS,[1],[Enable INI file parsing.])
+	if test "$enable_libtap" = "yes"; then
+		EXTRA_TEST="$EXTRA_TEST test_ini test_opts"
+		AC_SUBST(EXTRA_TEST)
+	fi
 fi
 fi
 
 
 dnl Check for PostgreSQL libraries
 dnl Check for PostgreSQL libraries
@@ -272,8 +290,8 @@ fi
 if test "$FOUNDINCLUDE" = "yes" ; then
 if test "$FOUNDINCLUDE" = "yes" ; then
 	EXTRAS="$EXTRAS check_ide_smart"
 	EXTRAS="$EXTRAS check_ide_smart"
 else
 else
-	AC_MSG_WARN([Skipping check_ide_smart plugin.]) 
-	AC_MSG_WARN([check_ide_smart is linux specific. It requires linux/hdreg.h and linux/types.h.]) 
+	AC_MSG_WARN([Skipping check_ide_smart plugin.])
+	AC_MSG_WARN([check_ide_smart is linux specific. It requires linux/hdreg.h and linux/types.h.])
 fi
 fi
 
 
 dnl Check for mysql libraries
 dnl Check for mysql libraries
@@ -467,7 +485,7 @@ ac_cv_HAVE_VA_COPY=yes,
 ac_cv_HAVE_VA_COPY=no)])
 ac_cv_HAVE_VA_COPY=no)])
 if test x"$ac_cv_HAVE_VA_COPY" = x"yes"; then
 if test x"$ac_cv_HAVE_VA_COPY" = x"yes"; then
     AC_DEFINE(HAVE_VA_COPY,1,[Whether va_copy() is available])
     AC_DEFINE(HAVE_VA_COPY,1,[Whether va_copy() is available])
-else    
+else
     AC_CACHE_CHECK([for __va_copy],ac_cv_HAVE___VA_COPY,[
     AC_CACHE_CHECK([for __va_copy],ac_cv_HAVE___VA_COPY,[
     AC_TRY_LINK([#include <stdarg.h>
     AC_TRY_LINK([#include <stdarg.h>
     va_list ap1,ap2;], [__va_copy(ap1,ap2);],
     va_list ap1,ap2;], [__va_copy(ap1,ap2);],
@@ -513,7 +531,7 @@ AC_PATH_PROG(PATH_TO_PS,ps)
 
 
 AC_MSG_CHECKING(for ps syntax)
 AC_MSG_CHECKING(for ps syntax)
 AC_ARG_WITH(ps_command,
 AC_ARG_WITH(ps_command,
-            ACX_HELP_STRING([--with-ps-command=PATH], 
+            ACX_HELP_STRING([--with-ps-command=PATH],
                             [Verbatim command to execute for ps]),
                             [Verbatim command to execute for ps]),
             PS_COMMAND=$withval)
             PS_COMMAND=$withval)
 AC_ARG_WITH(ps_format,
 AC_ARG_WITH(ps_format,
@@ -521,7 +539,7 @@ AC_ARG_WITH(ps_format,
                             [Format string for scanning ps output]),
                             [Format string for scanning ps output]),
             PS_FORMAT=$withval)
             PS_FORMAT=$withval)
 AC_ARG_WITH(ps_cols,
 AC_ARG_WITH(ps_cols,
-            ACX_HELP_STRING([--with-ps-cols=NUM], 
+            ACX_HELP_STRING([--with-ps-cols=NUM],
                             [Number of columns in ps command]),
                             [Number of columns in ps command]),
             PS_COLS=$withval)
             PS_COLS=$withval)
 AC_ARG_WITH(ps_varlist,
 AC_ARG_WITH(ps_varlist,
@@ -529,7 +547,7 @@ AC_ARG_WITH(ps_varlist,
                             [Variable list for sscanf of 'ps' output]),
                             [Variable list for sscanf of 'ps' output]),
             PS_VARLIST=$withval)
             PS_VARLIST=$withval)
 
 
-if test -n "$PS_COMMAND" && test -n "$PS_FORMAT" && test -n "$PS_COLS" && test -n "$PS_VARLIST"; then 
+if test -n "$PS_COMMAND" && test -n "$PS_FORMAT" && test -n "$PS_COLS" && test -n "$PS_VARLIST"; then
 	ac_cv_ps_command="$PS_COMMAND"
 	ac_cv_ps_command="$PS_COMMAND"
 	ac_cv_ps_format="$PS_FORMAT"
 	ac_cv_ps_format="$PS_FORMAT"
 	ac_cv_ps_varlist="$PS_VARLIST"
 	ac_cv_ps_varlist="$PS_VARLIST"
@@ -603,7 +621,7 @@ then
 	ac_cv_ps_cols=9
 	ac_cv_ps_cols=9
 	AC_MSG_RESULT([$ac_cv_ps_command])
 	AC_MSG_RESULT([$ac_cv_ps_command])
 
 
-dnl Some *BSDs have different format for ps. This is mainly to catch FreeBSD 4. 
+dnl Some *BSDs have different format for ps. This is mainly to catch FreeBSD 4.
 dnl Limitation: Only first 16 chars returned for ucomm field
 dnl Limitation: Only first 16 chars returned for ucomm field
 dnl Must come before ps -weo
 dnl Must come before ps -weo
 elif ps -axwo 'stat uid pid ppid vsz rss pcpu ucomm command' 2>/dev/null | \
 elif ps -axwo 'stat uid pid ppid vsz rss pcpu ucomm command' 2>/dev/null | \
@@ -680,9 +698,9 @@ then
 	ac_cv_ps_cols=9
 	ac_cv_ps_cols=9
 	AC_MSG_RESULT([$ac_cv_ps_command])
 	AC_MSG_RESULT([$ac_cv_ps_command])
 
 
-dnl Tru64 - needs %*[ +<>] in PS_FORMAT. 
+dnl Tru64 - needs %*[ +<>] in PS_FORMAT.
 dnl Has /usr/bin/ps and /sbin/ps - force sbin version
 dnl Has /usr/bin/ps and /sbin/ps - force sbin version
-dnl Can't use vsize and rssize because comes back with text (eg, 1.5M instead 
+dnl Can't use vsize and rssize because comes back with text (eg, 1.5M instead
 dnl of 1500). Will need big changes to check_procs to support
 dnl of 1500). Will need big changes to check_procs to support
 elif /sbin/ps -eo 'stat uid pid ppid pcpu etime comm args' 2>/dev/null | \
 elif /sbin/ps -eo 'stat uid pid ppid pcpu etime comm args' 2>/dev/null | \
 	egrep -i ["^ *S +[UID]+ +[PID]+ +[PID]+ +[%CPU]+ +[ELAPSD]+ +[COMMAND]+ +[COMMAND]+"] > /dev/null
 	egrep -i ["^ *S +[UID]+ +[PID]+ +[PID]+ +[%CPU]+ +[ELAPSD]+ +[COMMAND]+ +[COMMAND]+"] > /dev/null
@@ -808,7 +826,7 @@ then
 	ac_cv_ps_cols=8
 	ac_cv_ps_cols=8
 	AC_MSG_RESULT([$ac_cv_ps_command])
 	AC_MSG_RESULT([$ac_cv_ps_command])
 
 
-dnl UnixWare 
+dnl UnixWare
 elif ps -Al 2>/dev/null | \
 elif ps -Al 2>/dev/null | \
 	egrep -i ["^ *F +S +UID +PID +PPID +CLS +PRI +NI +C +ADDR +SZ +WCHAN +TTY +TIME +COMD"] >/dev/null
 	egrep -i ["^ *F +S +UID +PID +PPID +CLS +PRI +NI +C +ADDR +SZ +WCHAN +TTY +TIME +COMD"] >/dev/null
 then
 then
@@ -1173,7 +1191,7 @@ fi
 AC_PATH_PROG(PATH_TO_SMBCLIENT,smbclient)
 AC_PATH_PROG(PATH_TO_SMBCLIENT,smbclient)
 AC_ARG_WITH(smbclient_command,
 AC_ARG_WITH(smbclient_command,
             ACX_HELP_STRING([--with-smbclient-command=PATH],
             ACX_HELP_STRING([--with-smbclient-command=PATH],
-                            [sets path to smbclient]), 
+                            [sets path to smbclient]),
             PATH_TO_SMBCLIENT=$withval)
             PATH_TO_SMBCLIENT=$withval)
 if test -n "$PATH_TO_SMBCLIENT"
 if test -n "$PATH_TO_SMBCLIENT"
 then
 then
@@ -1229,7 +1247,7 @@ fi
 AC_PATH_PROG(PATH_TO_QUAKESTAT,quakestat)
 AC_PATH_PROG(PATH_TO_QUAKESTAT,quakestat)
 AC_PATH_PROG(PATH_TO_QSTAT,qstat)
 AC_PATH_PROG(PATH_TO_QSTAT,qstat)
 AC_ARG_WITH(qstat_command,
 AC_ARG_WITH(qstat_command,
-            ACX_HELP_STRING([--with-qstat-command=PATH], 
+            ACX_HELP_STRING([--with-qstat-command=PATH],
                             [Path to qstat command]), PATH_TO_QSTAT=$withval)
                             [Path to qstat command]), PATH_TO_QSTAT=$withval)
 
 
 if test -x "$PATH_TO_QUAKESTAT"
 if test -x "$PATH_TO_QUAKESTAT"
@@ -1245,7 +1263,7 @@ else
 	AC_MSG_WARN([Get qstat from http://www.activesw.com/people/steve/qstat.html in order to make check_game plugin])
 	AC_MSG_WARN([Get qstat from http://www.activesw.com/people/steve/qstat.html in order to make check_game plugin])
 fi
 fi
 
 
-if test $ac_cv_path_to_qstat 
+if test $ac_cv_path_to_qstat
 then
 then
 	AC_DEFINE_UNQUOTED(PATH_TO_QSTAT,"$ac_cv_path_to_qstat",
 	AC_DEFINE_UNQUOTED(PATH_TO_QSTAT,"$ac_cv_path_to_qstat",
 		[path to qstat/quakestat])
 		[path to qstat/quakestat])
@@ -1404,12 +1422,12 @@ AC_CHECK_MEMBERS([struct swapent.se_nblks],,,[
                #include <sys/swap.h>
                #include <sys/swap.h>
                ])
                ])
 
 
-if test "$ac_cv_have_decl_swapctl" = "yes"; 
+if test "$ac_cv_have_decl_swapctl" = "yes";
 then
 then
 	EXTRAS="$EXTRAS check_swap"
 	EXTRAS="$EXTRAS check_swap"
 	AC_MSG_CHECKING([for 2-arg (SVR4) swapctl])
 	AC_MSG_CHECKING([for 2-arg (SVR4) swapctl])
 	if test "$ac_cv_type_swaptbl_t" = "yes" -a \
 	if test "$ac_cv_type_swaptbl_t" = "yes" -a \
-	        "$ac_cv_type_swapent_t" = "yes"; 
+	        "$ac_cv_type_swapent_t" = "yes";
 	then
 	then
 		AC_MSG_RESULT([yes])
 		AC_MSG_RESULT([yes])
 		ac_cv_check_swap_swapctl_svr4="1";
 		ac_cv_check_swap_swapctl_svr4="1";
@@ -1418,7 +1436,7 @@ then
 	else
 	else
 		AC_MSG_RESULT([no])
 		AC_MSG_RESULT([no])
 		AC_MSG_CHECKING([for 3-arg (*BSD) swapctl])
 		AC_MSG_CHECKING([for 3-arg (*BSD) swapctl])
-		if test "$ac_cv_member_struct_swapent_se_nblks" = "yes"; 
+		if test "$ac_cv_member_struct_swapent_se_nblks" = "yes";
 		then
 		then
 			AC_MSG_RESULT([yes])
 			AC_MSG_RESULT([yes])
 			AC_DEFINE([CHECK_SWAP_SWAPCTL_BSD],1,
 			AC_DEFINE([CHECK_SWAP_SWAPCTL_BSD],1,
@@ -1459,12 +1477,12 @@ dnl end tests for the swapctl system calls
 dnl
 dnl
 
 
 
 
-if test "x$ac_cv_have_swap" != "x" 
+if test "x$ac_cv_have_swap" != "x"
 then
 then
 	AC_DEFINE(HAVE_SWAP,1,[Define if swap/swapinfo command is found])
 	AC_DEFINE(HAVE_SWAP,1,[Define if swap/swapinfo command is found])
 	EXTRAS="$EXTRAS check_swap"
 	EXTRAS="$EXTRAS check_swap"
 fi
 fi
-if test "x$ac_cv_swap_command" != "x" 
+if test "x$ac_cv_swap_command" != "x"
 then
 then
 	AC_DEFINE_UNQUOTED(SWAP_COMMAND,"$ac_cv_swap_command",
 	AC_DEFINE_UNQUOTED(SWAP_COMMAND,"$ac_cv_swap_command",
 		[Path to swap/swapinfo binary, with any args])
 		[Path to swap/swapinfo binary, with any args])
@@ -1509,7 +1527,7 @@ fi
 AC_PATH_PROG(PATH_TO_APTGET,apt-get)
 AC_PATH_PROG(PATH_TO_APTGET,apt-get)
 AC_ARG_WITH(apt-get_command,
 AC_ARG_WITH(apt-get_command,
             ACX_HELP_STRING([--with-apt-get-command=PATH],
             ACX_HELP_STRING([--with-apt-get-command=PATH],
-                            [Path to apt-get command]), 
+                            [Path to apt-get command]),
                             with_apt_get_command=$withval,
                             with_apt_get_command=$withval,
                             with_apt_get_command=$PATH_TO_APTGET)
                             with_apt_get_command=$PATH_TO_APTGET)
 AC_DEFINE_UNQUOTED(PATH_TO_APTGET,"$PATH_TO_APTGET",[Path to apt-get command, if present])
 AC_DEFINE_UNQUOTED(PATH_TO_APTGET,"$PATH_TO_APTGET",[Path to apt-get command, if present])
@@ -1538,7 +1556,7 @@ case $host in
 	*sun* | *solaris*)
 	*sun* | *solaris*)
 		AC_DEFINE(__sun__,1,[sun specific code in check_dhcp.c])
 		AC_DEFINE(__sun__,1,[sun specific code in check_dhcp.c])
 	;;
 	;;
-	*hpux*)  
+	*hpux*)
 		AC_DEFINE(__hpux__,1,[hpux specific code in check_dhcp.c])
 		AC_DEFINE(__hpux__,1,[hpux specific code in check_dhcp.c])
 	;;
 	;;
 esac
 esac
@@ -1558,8 +1576,8 @@ dnl 2.6.9-11 (okay in 2.6.9-5). Redhat investigating root cause
 dnl We patch plugins/popen.c
 dnl We patch plugins/popen.c
 dnl Need to add smp because uname different on those
 dnl Need to add smp because uname different on those
 dnl Can force patch to be applied with --enable-redhat-pthread-workaround
 dnl Can force patch to be applied with --enable-redhat-pthread-workaround
-AC_ARG_ENABLE(redhat-pthread-workaround, 
-	AC_HELP_STRING([--enable-redhat-pthread-workaround], 
+AC_ARG_ENABLE(redhat-pthread-workaround,
+	AC_HELP_STRING([--enable-redhat-pthread-workaround],
 		[force Redhat patch to be applied (default: test system)]),
 		[force Redhat patch to be applied (default: test system)]),
 	[ac_cv_enable_redhat_pthread_workaround=$enableval],
 	[ac_cv_enable_redhat_pthread_workaround=$enableval],
 	[ac_cv_enable_redhat_pthread_workaround=test])
 	[ac_cv_enable_redhat_pthread_workaround=test])
@@ -1581,7 +1599,7 @@ fi
 
 
 dnl Perl modules
 dnl Perl modules
 AC_ARG_ENABLE(perl-modules,
 AC_ARG_ENABLE(perl-modules,
-	AC_HELP_STRING([--enable-perl-modules], 
+	AC_HELP_STRING([--enable-perl-modules],
 		[Enables installation of Nagios::Plugin and its dependencies (default: no)]),
 		[Enables installation of Nagios::Plugin and its dependencies (default: no)]),
 	[enable_perl_modules=$enableval],
 	[enable_perl_modules=$enableval],
 	[enable_perl_modules=no])
 	[enable_perl_modules=no])
@@ -1589,6 +1607,18 @@ if test "$enable_perl_modules" = "yes" ; then
   AC_SUBST(PERLMODS_DIR,perlmods)
   AC_SUBST(PERLMODS_DIR,perlmods)
 fi
 fi
 
 
+# From Tap configure
+# Checks for libraries
+case "$host" in
+	*-*-*freebsd4*)
+		LDFLAGS="$LDFLAGS -pthread"
+		HAVE_LIBPTHREAD=1
+		;;
+	*)
+		AC_CHECK_LIB(pthread, main)
+		;;
+esac
+
 dnl External libraries - see ACKNOWLEDGEMENTS
 dnl External libraries - see ACKNOWLEDGEMENTS
 gl_INIT
 gl_INIT
 
 
@@ -1598,24 +1628,25 @@ if test "$ac_cv_uname_s" = 'SunOS' -a \( "x$ac_cv_prog_ac_ct_AR" = "x" -o "$ac_c
 fi
 fi
 
 
 AC_OUTPUT(
 AC_OUTPUT(
-  Makefile 
-  lib/Makefile 
-  plugins/Makefile 
+  Makefile
+  tap/Makefile
+  lib/Makefile
+  plugins/Makefile
   lib/tests/Makefile
   lib/tests/Makefile
   plugins-root/Makefile
   plugins-root/Makefile
-  plugins-scripts/Makefile 
-  plugins-scripts/subst 
-  plugins-scripts/utils.pm 
-  plugins-scripts/utils.sh 
+  plugins-scripts/Makefile
+  plugins-scripts/subst
+  plugins-scripts/utils.pm
+  plugins-scripts/utils.sh
   perlmods/Makefile
   perlmods/Makefile
-  command.cfg 
-  test.pl 
-  pkg/solaris/pkginfo 
-  po/Makefile.in 
+  command.cfg
+  test.pl
+  pkg/solaris/pkginfo
+  po/Makefile.in
 )
 )
 
 
 
 
-dnl the ones below that are commented out need to be cleaned up 
+dnl the ones below that are commented out need to be cleaned up
 dnl in the configure code above to use with_foo instead of ac_cv_foo
 dnl in the configure code above to use with_foo instead of ac_cv_foo
 dnl if we want them to show up here.  it'd also make the code cleaner.
 dnl if we want them to show up here.  it'd also make the code cleaner.
 dnl i'll get to that on another rainy day :) -sf
 dnl i'll get to that on another rainy day :) -sf
@@ -1649,5 +1680,5 @@ ACX_FEATURE([with],[perl])
 ACX_FEATURE([enable],[perl-modules])
 ACX_FEATURE([enable],[perl-modules])
 ACX_FEATURE([with],[cgiurl])
 ACX_FEATURE([with],[cgiurl])
 ACX_FEATURE([with],[trusted-path])
 ACX_FEATURE([with],[trusted-path])
-
+ACX_FEATURE([enable],[libtap])
 
 

+ 29 - 20
lib/tests/Makefile.am

@@ -15,40 +15,49 @@ EXTRA_DIST = $(np_test_scripts) $(np_test_files)
 
 
 LIBS = @LIBINTL@
 LIBS = @LIBINTL@
 
 
+if USE_LIBTAP_LOCAL
+tap_cflags = -I$(top_srcdir)/tap
+tap_ldflags = -L$(top_srcdir)/tap
+tap_ldadd = $(top_srcdir)/gl/libgnu.a
+else
+## Shouldn't we detect that??
+tap_ldflags = -L/usr/local/lib
+endif
+
 test_utils_SOURCES = test_utils.c
 test_utils_SOURCES = test_utils.c
-test_utils_CFLAGS = -g -I..
-test_utils_LDFLAGS = -L/usr/local/lib -ltap
-test_utils_LDADD = ../utils_base.o
+test_utils_CFLAGS = -g -I.. $(tap_cflags)
+test_utils_LDFLAGS = $(tap_ldflags) -ltap
+test_utils_LDADD = ../utils_base.o $(tap_ldadd)
 
 
 test_disk_SOURCES = test_disk.c
 test_disk_SOURCES = test_disk.c
-test_disk_CFLAGS = -g -I..
-test_disk_LDFLAGS = -L/usr/local/lib -ltap
+test_disk_CFLAGS = -g -I.. $(tap_cflags)
+test_disk_LDFLAGS = $(tap_ldflags) -ltap
 test_disk_LDADD = ../utils_disk.o $(top_srcdir)/gl/libgnu.a
 test_disk_LDADD = ../utils_disk.o $(top_srcdir)/gl/libgnu.a
 
 
 test_tcp_SOURCES = test_tcp.c
 test_tcp_SOURCES = test_tcp.c
-test_tcp_CFLAGS = -g -I..
-test_tcp_LDFLAGS = -L/usr/local/lib -ltap
-test_tcp_LDADD = ../utils_tcp.o 
+test_tcp_CFLAGS = -g -I.. $(tap_cflags)
+test_tcp_LDFLAGS = $(tap_ldflags) -ltap
+test_tcp_LDADD = ../utils_tcp.o $(tap_ldadd)
 
 
 test_cmd_SOURCES = test_cmd.c
 test_cmd_SOURCES = test_cmd.c
-test_cmd_CFLAGS = -g -I..
-test_cmd_LDFLAGS = -L/usr/local/lib -ltap
-test_cmd_LDADD = ../utils_cmd.o ../utils_base.o
+test_cmd_CFLAGS = -g -I.. $(tap_cflags)
+test_cmd_LDFLAGS = $(tap_ldflags) -ltap
+test_cmd_LDADD = ../utils_cmd.o ../utils_base.o $(tap_ldadd)
 
 
 test_base64_SOURCES = test_base64.c
 test_base64_SOURCES = test_base64.c
-test_base64_CFLAGS = -g -I..
-test_base64_LDFLAGS = -L/usr/local/lib -ltap
-test_base64_LDADD = $(top_srcdir)/gl/base64.o 
+test_base64_CFLAGS = -g -I.. $(tap_cflags)
+test_base64_LDFLAGS = $(tap_ldflags) -ltap
+test_base64_LDADD = $(top_srcdir)/gl/base64.o $(tap_ldadd)
 
 
 test_ini_SOURCES = test_ini.c
 test_ini_SOURCES = test_ini.c
-test_ini_CFLAGS = -g -I..
-test_ini_LDFLAGS = -L/usr/local/lib -ltap
-test_ini_LDADD = ../utils_base.o ../parse_ini.o
+test_ini_CFLAGS = -g -I.. $(tap_cflags)
+test_ini_LDFLAGS = $(tap_ldflags) -ltap
+test_ini_LDADD = ../utils_base.o ../parse_ini.o $(tap_ldadd)
 
 
 test_opts_SOURCES = test_opts.c
 test_opts_SOURCES = test_opts.c
-test_opts_CFLAGS = -g -I..
-test_opts_LDFLAGS = -L/usr/local/lib -ltap
-test_opts_LDADD = ../utils_base.o ../parse_ini.o ../extra_opts.o
+test_opts_CFLAGS = -g -I.. $(tap_cflags)
+test_opts_LDFLAGS = $(tap_ldflags) -ltap
+test_opts_LDADD = ../utils_base.o ../parse_ini.o ../extra_opts.o $(tap_ldadd)
 
 
 test: ${noinst_PROGRAMS}
 test: ${noinst_PROGRAMS}
 	perl -MTest::Harness -e '$$Test::Harness::switches=""; runtests(map {$$_ .= ".t"} @ARGV)' $(EXTRA_PROGRAMS)
 	perl -MTest::Harness -e '$$Test::Harness::switches=""; runtests(map {$$_ .= ".t"} @ARGV)' $(EXTRA_PROGRAMS)

+ 13 - 0
tap/Makefile.am

@@ -0,0 +1,13 @@
+# Tap self-tests are not implemented (yet?)
+# SUBDIRS = tests
+
+if USE_LIBTAP_LOCAL
+noinst_LTLIBRARIES = libtap.la
+libtap_la_SOURCES = tap.c tap.h
+include_HEADERS = tap.h
+endif USE_LIBTAP_LOCAL
+
+# see top comment
+#prove:
+#	prove -v -r
+

+ 11 - 0
tap/README

@@ -0,0 +1,11 @@
+NAME
+     tap -- write tests that implement the Test Anything Protocol
+
+SYNOPSIS
+     #include <tap.h>
+
+DESCRIPTION
+     The tap library provides functions for writing test scripts that produce
+     output consistent with the Test Anything Protocol.  A test harness that
+     parses this protocol can run these tests and produce useful reports indi-
+     cating their success or failure.

+ 368 - 0
tap/tap.3

@@ -0,0 +1,368 @@
+.Dd December 20, 2004
+.Os
+.Dt TAP 3
+.Sh NAME
+.Nm tap
+.Nd write tests that implement the Test Anything Protocol
+.Sh SYNOPSIS
+.In tap.h
+.Sh DESCRIPTION
+The
+.Nm
+library provides functions for writing test scripts that produce output
+consistent with the Test Anything Protocol.  A test harness that parses
+this protocol can run these tests and produce useful reports indicating
+their success or failure.
+.Ss PRINTF STRINGS
+In the descriptions that follow, for any function that takes as the
+last two parameters
+.Dq Fa char * , Fa ...
+it can be assumed that the
+.Fa char *
+is a
+.Fn printf
+-like format string, and the optional arguments are values to be placed
+in that string.
+.Ss TEST PLANS
+.Bl -tag -width indent
+.It Xo
+.Ft int
+.Fn plan_tests "unsigned int"
+.Xc
+.It Xo
+.Ft int
+.Fn plan_no_plan "void"
+.Xc
+.It Xo
+.Ft int
+.Fn plan_skip_all "char *" "..."
+.Xc
+.El
+.Pp
+You must first specify a test plan.  This indicates how many tests you
+intend to run, and allows the test harness to notice if any tests were
+missed, or if the test program exited prematurely.
+.Pp
+To do this, use
+.Fn plan_tests ,
+which always returns 0.  The function will cause your program to exit
+prematurely if you specify 0 tests.
+.Pp
+In some situations you may not know how many tests you will be running, or
+you are developing your test program, and do not want to update the
+.Fn plan_tests
+parameter every time you make a change.  For those situations use
+.Fn plan_no_plan .
+It returns 0, and indicates to the test harness that an indeterminate number
+of tests will be run.
+.Pp
+Both
+.Fn plan_tests
+and
+.Fn plan_no_plan
+will cause your test program to exit prematurely with a diagnostic
+message if they are called more than once.
+.Pp
+If your test program detects at run time that some required functionality
+is missing (for example, it relies on a database connection which is not
+present, or a particular configuration option that has not been included
+in the running kernel) use
+.Fn plan_skip_all ,
+passing as parameters a string to display indicating the reason for skipping
+the tests.
+.Ss SIMPLE TESTS
+.Bl -tag -width indent
+.It Xo
+.Ft unsigned int
+.Fn ok "expression" "char *" "..."
+.Xc
+.It Xo
+.Ft unsigned int
+.Fn ok1 "expression"
+.Xc
+.It Xo
+.Ft unsigned int
+.Fn pass "char *" "..."
+.Xc
+.It Xo
+.Ft unsigned int
+.Fn fail "char *" "..."
+.Xc
+.El
+.Pp
+Tests are implemented as expressions checked by calls to the
+.Fn ok
+and
+.Fn ok1
+macros.  In both cases
+.Fa expression
+should evaluate to true if the test succeeded.
+.Pp
+.Fn ok
+allows you to specify a name, or comment, describing the test which will
+be included in the output.
+.Fn ok1
+is for those times when the expression to be tested is self
+explanatory and does not need an associated comment.  In those cases
+the test expression becomes the comment.
+.Pp
+These four calls are equivalent:
+.Bd -literal -offset indent
+int i = 5;
+
+ok(i == 5, "i equals 5");      /* Overly verbose */
+ok(i == 5, "i equals %d", i);  /* Just to demonstrate printf-like
+                                  behaviour of the test name */
+ok(i == 5, "i == 5");          /* Needless repetition */
+ok1(i == 5);                   /* Just right */
+.Ed
+.Pp
+It is good practice to ensure that the test name describes the meaning
+behind the test rather than what you are testing.  Viz
+.Bd -literal -offset indent
+ok(db != NULL, "db is not NULL");            /* Not bad, but */
+ok(db != NULL, "Database conn. succeeded");  /* this is better */
+.Ed
+.Pp
+.Fn ok
+and
+.Fn ok1
+return 1 if the expression evaluated to true, and 0 if it evaluated to
+false.  This lets you chain calls from
+.Fn ok
+to
+.Fn diag
+to only produce diagnostic output if the test failed.  For example, this
+code will include diagnostic information about why the database connection
+failed, but only if the test failed.
+.Bd -literal -offset indent
+ok(db != NULL, "Database conn. succeeded") ||
+    diag("Database error code: %d", dberrno);
+.Ed
+.Pp
+You also have
+.Fn pass
+and
+.Fn fail .
+From the Test::More documentation:
+.Bd -literal -offset indent
+Sometimes you just want to say that the tests have passed.
+Usually the case is you've got some complicated condition
+that is difficult to wedge into an ok().  In this case,
+you can simply use pass() (to declare the test ok) or fail
+(for not ok).
+
+Use these very, very, very sparingly.
+.Ed
+.Pp
+These are synonyms for ok(1, ...) and ok(0, ...).
+.Ss SKIPPING TESTS
+.Bl -tag -width indent
+.It Xo
+.Ft int
+.Fn skip "unsigned int" "char *" "..."
+.Xc
+.It Xo
+.Fn skip_start "expression" "unsigned int" "char *" "..."
+.Xc
+.It Xo
+.Sy skip_end
+.Xc
+.El
+.Pp
+Sets of tests can be skipped.  Ordinarily you would do this because
+the test can't be run in this particular testing environment.
+.Pp
+For example, suppose some tests should be run as root.  If the test is
+not being run as root then the tests should be skipped.  In this 
+implementation, skipped tests are flagged as being ok, with a special
+message indicating that they were skipped.  It is your responsibility
+to ensure that the number of tests skipped (the first parameter to
+.Fn skip )
+is correct for the number of tests to skip.
+.Pp
+One way of implementing this is with a
+.Dq do { } while(0);
+loop, or an
+.Dq if( ) { } else { }
+construct, to ensure that there are no additional side effects from the
+skipped tests.
+.Bd -literal -offset indent
+if(getuid() != 0) {
+        skip(1, "because test only works as root");
+} else {
+        ok(do_something_as_root() == 0, "Did something as root");
+}
+.Ed
+.Pp
+Two macros are provided to assist with this.  The previous example could
+be re-written as follows.
+.Bd -literal -offset indent
+skip_start(getuid() != 0, 1, "because test only works as root");
+
+ok(do_something_as_root() == 0, "Did something as root");
+
+skip_end;    /* It's a macro, no parentheses */
+.Ed
+.Ss MARKING TESTS AS Dq TODO
+.Bl -tag -width indent
+.It Xo
+.Ft void
+.Fn todo_start "char *" "..."
+.Xc
+.It Xo
+.Ft void
+.Fn todo_end "void"
+.Xc
+.El
+.Pp
+Sets of tests can be flagged as being
+.Dq TODO .
+These are tests that you expect to fail, probably because you haven't
+fixed a bug, or finished a new feature yet.  These tests will still be
+run, but with additional output that indicates that they are expected
+to fail.  Should a test start to succeed unexpectedly, tools like
+.Xr prove 1
+will indicate this, and you can move the test out of the todo
+block.  This is much more useful than simply commenting out (or
+.Dq #ifdef 0 ... #endif )
+the tests.
+.Bd -literal -offset indent
+todo_start("dwim() not returning true yet");
+
+ok(dwim(), "Did what the user wanted");
+
+todo_end();
+.Ed
+.Pp
+Should
+.Fn dwim
+ever start succeeding you will know about it as soon as you run the
+tests.  Note that
+.Em unlike
+the
+.Fn skip_*
+family, additional code between
+.Fn todo_start
+and
+.Fn todo_end
+.Em is
+executed.
+.Ss SKIP vs. TODO
+From the Test::More documentation;
+.Bd -literal -offset indent
+If it's something the user might not be able to do, use SKIP.
+This includes optional modules that aren't installed, running
+under an OS that doesn't have some feature (like fork() or
+symlinks), or maybe you need an Internet connection and one
+isn't available.
+
+If it's something the programmer hasn't done yet, use TODO.
+This is for any code you haven't written yet, or bugs you have
+yet to fix, but want to put tests in your testing script 
+(always a good idea).
+.Ed
+.Ss DIAGNOSTIC OUTPUT
+.Bl -tag -width indent
+.It Xo
+.Fr unsigned int
+.Fn diag "char *" "..."
+.Xc
+.El
+.Pp
+If your tests need to produce diagnostic output, use
+.Fn diag .
+It ensures that the output will not be considered by the TAP test harness.
+.Fn diag
+adds the necessary trailing
+.Dq \en
+for you.
+.Bd -literal -offset indent
+diag("Expected return code 0, got return code %d", rcode);
+.Ed
+.Pp
+.Fn diag
+always returns 0.
+.Ss EXIT STATUS
+.Bl -tag -width indent
+.It Xo
+.Fr int
+.Fn exit_status void
+.Xc
+.El
+.Pp
+For maximum compatability your test program should return a particular
+exit code.  This is calculated by
+.Fn exit_status
+so it is sufficient to always return from
+.Fn main
+with either
+.Dq return exit_status();
+or
+.Dq exit(exit_status());
+as appropriate.
+.Sh EXAMPLES
+The
+.Pa tests
+directory in the source distribution contains numerous tests of
+.Nm
+functionality, written using
+.Nm .
+Examine them for examples of how to construct test suites.
+.Sh COMPATABILITY
+.Nm
+strives to be compatible with the Perl Test::More and Test::Harness 
+modules.  The test suite verifies that
+.Nm
+is bug-for-bug compatible with their behaviour.  This is why some
+functions which would more naturally return nothing return constant
+values.
+.Pp
+If the
+.Lb libpthread
+is found at compile time,
+.Nm
+.Em should
+be thread safe.  Indications to the contrary (and test cases that expose
+incorrect behaviour) are very welcome.
+.Sh SEE ALSO
+.Xr Test::More 1 ,
+.Xr Test::Harness 1 ,
+.Xr prove 1
+.Sh STANDARDS
+.Nm
+requires a
+.St -isoC-99
+compiler.  Some of the
+.Nm
+functionality is implemented as variadic macros, and that functionality
+was not formally codified until C99.  Patches to use
+.Nm
+with earlier compilers that have their own implementation of variadic
+macros will be gratefully received.
+.Sh HISTORY
+.Nm
+was written to help improve the quality and coverage of the FreeBSD
+regression test suite, and released in the hope that others find it
+a useful tool to help improve the quality of their code.
+.Sh AUTHORS
+.An "Nik Clayton" Aq nik@ngo.org.uk ,
+.Aq nik@FreeBSD.org
+.Pp
+.Nm
+would not exist without the efforts of
+.An "Michael G Schwern" Aq schqern@pobox.com ,
+.An "Andy Lester" Aq andy@petdance.com ,
+and the countless others who have worked on the Perl QA programme.
+.Sh BUGS
+Ideally, running the tests would have no side effects on the behaviour
+of the application you are testing.  However, it is not always possible
+to avoid them.  The following side effects of using
+.Nm
+are known.
+.Bl -bullet -offset indent
+.It
+stdout is set to unbuffered mode after calling any of the
+.Fn plan_*
+functions.
+.El

+ 435 - 0
tap/tap.c

@@ -0,0 +1,435 @@
+/*-
+ * Copyright (c) 2004 Nik Clayton
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <ctype.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "tap.h"
+
+static int no_plan = 0;
+static int skip_all = 0;
+static int have_plan = 0;
+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 int todo = 0;
+static int test_died = 0;
+
+/* Encapsulate the pthread code in a conditional.  In the absence of
+   libpthread the code does nothing */
+#ifdef HAVE_LIBPTHREAD
+#include <pthread.h>
+static pthread_mutex_t M = PTHREAD_MUTEX_INITIALIZER;
+# define LOCK pthread_mutex_lock(&M);
+# define UNLOCK pthread_mutex_unlock(&M);
+#else
+# define LOCK
+# define UNLOCK
+#endif
+
+static void _expected_tests(unsigned int);
+static void _tap_init(void);
+static void _cleanup(void);
+
+/*
+ * Generate a test result.
+ *
+ * ok -- boolean, indicates whether or not the test passed.
+ * test_name -- the name of the test, may be NULL
+ * 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, ...)
+{
+	va_list ap;
+	char *local_test_name = NULL;
+	char *c;
+	int name_is_digits;
+
+	LOCK;
+
+	test_count++;
+
+	/* Start by taking the test name and performing any printf()
+	   expansions on it */
+	if(test_name != NULL) {
+		va_start(ap, test_name);
+		vasprintf(&local_test_name, test_name, ap);
+		va_end(ap);
+
+		/* Make sure the test name contains more than digits
+		   and spaces.  Emit an error message and exit if it
+		   does */
+		if(local_test_name) {
+			name_is_digits = 1;
+			for(c = local_test_name; *c != '\0'; c++) {
+				if(!isdigit(*c) && !isspace(*c)) {
+					name_is_digits = 0;
+					break;
+				}
+			}
+
+			if(name_is_digits) {
+				diag("    You named your test '%s'.  You shouldn't use numbers for your test names.", local_test_name);
+				diag("    Very confusing.");
+			}
+		}
+	}
+
+	if(!ok) {
+		printf("not ");
+		failures++;
+	}
+
+	printf("ok %d", test_count);
+
+	if(test_name != NULL) {
+		printf(" - ");
+
+		/* Print the test name, escaping any '#' characters it
+		   might contain */
+		if(local_test_name != NULL) {
+			flockfile(stdout);
+			for(c = local_test_name; *c != '\0'; c++) {
+				if(*c == '#')
+					fputc('\\', stdout);
+				fputc((int)*c, stdout);
+			}
+			funlockfile(stdout);
+		} else {	/* vasprintf() failed, use a fixed message */
+			printf("%s", todo_msg_fixed);
+		}
+	}
+
+	/* If we're in a todo_start() block then flag the test as being
+	   TODO.  todo_msg should contain the message to print at this
+	   point.  If it's NULL then asprintf() failed, and we should
+	   use the fixed message.
+
+	   This is not counted as a failure, so decrement the counter if
+	   the test failed. */
+	if(todo) {
+		printf(" # TODO %s", todo_msg ? todo_msg : todo_msg_fixed);
+		if(!ok)
+			failures--;
+	}
+
+	printf("\n");
+
+	if(!ok)
+		diag("    Failed %stest (%s:%s() at line %d)", 
+		     todo ? "(TODO) " : "", file, func, line);
+
+	free(local_test_name);
+
+	UNLOCK;
+
+	/* We only care (when testing) that ok is positive, but here we
+	   specifically only want to return 1 or 0 */
+	return ok ? 1 : 0;
+}
+
+/*
+ * Initialise the TAP library.  Will only do so once, however many times it's
+ * called.
+ */
+void
+_tap_init(void)
+{
+	static int run_once = 0;
+
+	LOCK;
+
+	if(!run_once) {
+		atexit(_cleanup);
+
+		/* stdout needs to be unbuffered so that the output appears
+		   in the same place relative to stderr output as it does 
+		   with Test::Harness */
+		setbuf(stdout, 0);
+		run_once = 1;
+	}
+
+	UNLOCK;
+}
+
+/*
+ * Note that there's no plan.
+ */
+int
+plan_no_plan(void)
+{
+
+	LOCK;
+
+	_tap_init();
+
+	if(have_plan != 0) {
+		fprintf(stderr, "You tried to plan twice!\n");
+		test_died = 1;
+		UNLOCK;
+		exit(255);
+	}
+
+	have_plan = 1;
+	no_plan = 1;
+
+	UNLOCK;
+
+	return 0;
+}
+
+/*
+ * Note that the plan is to skip all tests
+ */
+int
+plan_skip_all(char *reason)
+{
+
+	LOCK;
+
+	_tap_init();
+
+	skip_all = 1;
+
+	printf("1..0");
+
+	if(reason != NULL)
+		printf(" # Skip %s", reason);
+
+	printf("\n");
+
+	UNLOCK;
+
+	exit(0);
+}
+
+/*
+ * Note the number of tests that will be run.
+ */
+int
+plan_tests(unsigned int tests)
+{
+
+	LOCK;
+
+	_tap_init();
+
+	if(have_plan != 0) {
+		fprintf(stderr, "You tried to plan twice!\n");
+		test_died = 1;
+		UNLOCK;
+		exit(255);
+	}
+
+	if(tests == 0) {
+		fprintf(stderr, "You said to run 0 tests!  You've got to run something.\n");
+		test_died = 1;
+		UNLOCK;
+		exit(255);
+	}
+
+	have_plan = 1;
+
+	_expected_tests(tests);
+
+	UNLOCK;
+
+	return 0;
+}
+
+unsigned int
+diag(char *fmt, ...)
+{
+	va_list ap;
+
+	LOCK;
+
+	fputs("# ", stderr);
+
+	va_start(ap, fmt);
+	vfprintf(stderr, fmt, ap);
+	va_end(ap);
+
+	fputs("\n", stderr);
+
+	UNLOCK;
+
+	return 0;
+}
+
+void
+_expected_tests(unsigned int tests)
+{
+
+	LOCK;
+
+	printf("1..%d\n", tests);
+	e_tests = tests;
+
+	UNLOCK;
+}
+
+int
+skip(unsigned int n, char *fmt, ...)
+{
+	va_list ap;
+	char *skip_msg;
+
+	LOCK;
+
+	va_start(ap, fmt);
+	asprintf(&skip_msg, fmt, ap);
+	va_end(ap);
+
+	while(n-- > 0) {
+		test_count++;
+		printf("ok %d # skip %s\n", test_count, 
+		       skip_msg != NULL ? 
+		       skip_msg : "libtap():malloc() failed");
+	}
+
+	free(skip_msg);
+
+	UNLOCK;
+
+	return 1;
+}
+
+void
+todo_start(char *fmt, ...)
+{
+	va_list ap;
+
+	LOCK;
+
+	va_start(ap, fmt);
+	vasprintf(&todo_msg, fmt, ap);
+	va_end(ap);
+
+	todo = 1;
+
+	UNLOCK;
+}
+
+void
+todo_end(void)
+{
+
+	LOCK;
+
+	todo = 0;
+	free(todo_msg);
+
+	UNLOCK;
+}
+
+int
+exit_status(void)
+{
+	int r;
+
+	LOCK;
+
+	/* If there's no plan, just return the number of failures */
+	if(no_plan || !have_plan) {
+		UNLOCK;
+		return failures;
+	}
+
+	/* Ran too many tests?  Return the number of tests that were run
+	   that shouldn't have been */
+	if(e_tests < test_count) {
+		r = test_count - e_tests;
+		UNLOCK;
+		return r;
+	}
+
+	/* Return the number of tests that failed + the number of tests 
+	   that weren't run */
+	r = failures + e_tests - test_count;
+	UNLOCK;
+
+	return r;
+}
+
+/*
+ * Cleanup at the end of the run, produce any final output that might be
+ * required.
+ */
+void
+_cleanup(void)
+{
+
+	LOCK;
+
+	/* If plan_no_plan() wasn't called, and we don't have a plan,
+	   and we're not skipping everything, then something happened
+	   before we could produce any output */
+	if(!no_plan && !have_plan && !skip_all) {
+		diag("Looks like your test died before it could output anything.");
+		UNLOCK;
+		return;
+	}
+
+	if(test_died) {
+		diag("Looks like your test died just after %d.", test_count);
+		UNLOCK;
+		return;
+	}
+
+
+	/* No plan provided, but now we know how many tests were run, and can
+	   print the header at the end */
+	if(!skip_all && (no_plan || !have_plan)) {
+		printf("1..%d\n", test_count);
+	}
+
+	if((have_plan && !no_plan) && e_tests < test_count) {
+		diag("Looks like you planned %d tests but ran %d extra.",
+		     e_tests, test_count - e_tests);
+		UNLOCK;
+		return;
+	}
+
+	if((have_plan || !no_plan) && e_tests > test_count) {
+		diag("Looks like you planned %d tests but only ran %d.",
+		     e_tests, test_count);
+		UNLOCK;
+		return;
+	}
+
+	if(failures)
+		diag("Looks like you failed %d tests of %d.", 
+		     failures, test_count);
+
+	UNLOCK;
+}

+ 89 - 0
tap/tap.h

@@ -0,0 +1,89 @@
+/*-
+ * Copyright (c) 2004 Nik Clayton
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* '## __VA_ARGS__' is a gcc'ism. C99 doesn't allow the token pasting
+   and requires the caller to add the final comma if they've ommitted
+   the optional arguments */
+#ifdef __GNUC__
+# define ok(e, test, ...) ((e) ?					\
+			   _gen_result(1, __func__, __FILE__, __LINE__,	\
+				       test, ## __VA_ARGS__) :		\
+			   _gen_result(0, __func__, __FILE__, __LINE__,	\
+				       test, ## __VA_ARGS__))
+
+# define ok1(e) ((e) ?							\
+		 _gen_result(1, __func__, __FILE__, __LINE__, "%s", #e) : \
+		 _gen_result(0, __func__, __FILE__, __LINE__, "%s", #e))
+
+# define pass(test, ...) ok(1, test, ## __VA_ARGS__);
+# define fail(test, ...) ok(0, test, ## __VA_ARGS__);
+
+# define skip_start(test, n, fmt, ...)			\
+	do {						\
+		if((test)) {				\
+			skip(n, fmt, ## __VA_ARGS__);	\
+			continue;			\
+		}
+#elif __STDC_VERSION__ >= 199901L /* __GNUC__ */
+# define ok(e, ...) ((e) ?						\
+		     _gen_result(1, __func__, __FILE__, __LINE__,	\
+				 __VA_ARGS__) :				\
+		     _gen_result(0, __func__, __FILE__, __LINE__,	\
+				 __VA_ARGS__))
+
+# define ok1(e) ((e) ?							\
+		 _gen_result(1, __func__, __FILE__, __LINE__, "%s", #e) : \
+		 _gen_result(0, __func__, __FILE__, __LINE__, "%s", #e))
+
+# define pass(...) ok(1, __VA_ARGS__);
+# define fail(...) ok(0, __VA_ARGS__);
+
+# define skip_start(test, n, ...)			\
+	do {						\
+		if((test)) {				\
+			skip(n,  __VA_ARGS__);		\
+			continue;			\
+		}
+#else /* __STDC_VERSION__ */
+# error "Needs gcc or C99 compiler for variadic macros."
+#endif /* __STDC_VERSION__ */
+
+# define skip_end } while(0);
+
+unsigned int _gen_result(int, const char *, char *, unsigned int, char *, ...);
+
+int plan_no_plan(void);
+int plan_skip_all(char *);
+int plan_tests(unsigned int);
+
+unsigned int diag(char *, ...);
+
+int skip(unsigned int, char *, ...);
+
+void todo_start(char *, ...);
+void todo_end(void);
+
+int exit_status(void);

+ 7 - 0
tap/tests/Makefile.am

@@ -0,0 +1,7 @@
+SUBDIRS=	diag
+SUBDIRS+=	fail
+SUBDIRS+=	ok
+SUBDIRS+=	pass
+SUBDIRS+=	plan
+SUBDIRS+=	skip
+SUBDIRS+=	todo

+ 12 - 0
tap/tests/README

@@ -0,0 +1,12 @@
+Most of the tests follow the same pattern.
+
+ * test.pl that uses Test::More, and demonstrates whatever functionality 
+   that we're trying to test.  This is the reference code.
+
+ * test.c, which tests the libtap reimplementation of the same functionality.
+
+ * test.t, which compiles the .c program, runs both test scripts, and then 
+   diffs their output to make sure it's identical.
+
+   Right now, test.t is identical in every directory.  This sucks somewhat.
+   It should either be a symlink to a common script

+ 13 - 0
tap/tests/diag/Makefile.am

@@ -0,0 +1,13 @@
+
+TESTS = 		test.t
+TESTS_ENVIRONMENT =	$(SHELL)
+
+EXTRA_DIST = 		$(TESTS) test.pl
+
+check_PROGRAMS = 	test
+
+test_CFLAGS = 		-g -I../../src
+test_LDFLAGS = 		-L../../src
+test_LDADD = 		-ltap
+
+CLEANFILES =	test.o test.c.out test.pl.out

+ 46 - 0
tap/tests/diag/test.c

@@ -0,0 +1,46 @@
+/*-
+ * Copyright (c) 2004 Nik Clayton
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+
+#include "tap.h"
+
+int
+main(int argc, char *argv[])
+{
+	unsigned int rc = 0;
+
+	plan_tests(2);
+
+	rc = diag("A diagnostic message");
+	diag("Returned: %d", rc);
+
+	/* Make sure the failure is passed through */
+	ok(1, "test 1") || diag("ok() failed, and shouldn't");
+	ok(0, "test 2") || diag("ok() passed, and shouldn't");
+
+	return exit_status();
+}

+ 16 - 0
tap/tests/diag/test.pl

@@ -0,0 +1,16 @@
+#!/usr/bin/perl
+
+use warnings;
+use strict;
+
+use Test::More;
+
+my $rc = 0;
+
+plan tests => 2;
+
+$rc = diag("A diagnostic message");
+diag("Returned: $rc");
+
+ok(1, 'test 1') or diag "ok() failed, and shouldn't";
+ok(0, 'test 2') or diag "ok() passed, and shouldn't";

+ 29 - 0
tap/tests/diag/test.t

@@ -0,0 +1,29 @@
+#!/bin/sh
+
+cd `dirname $0`
+
+echo '1..2'
+
+make 2>&1 > /dev/null
+
+perl ./test.pl 2>&1 | sed -e 's/#     Failed test \(.*\)/#     Failed test ()/' > test.pl.out
+perlstatus=$?
+
+./test 2>&1 | sed -e 's/#     Failed test \(.*\)/#     Failed test ()/' > test.c.out
+cstatus=$?
+
+diff -u test.pl.out test.c.out
+
+if [ $? -eq 0 ]; then
+	echo 'ok 1 - output is identical'
+else
+	echo 'not ok 1 - output is identical'
+fi
+
+if [ $perlstatus -eq $cstatus ]; then
+	echo 'ok 2 - status code'
+else
+	echo 'not ok 2 - status code'
+	echo "# perlstatus = $perlstatus"
+	echo "#    cstatus = $cstatus"
+fi

+ 13 - 0
tap/tests/fail/Makefile.am

@@ -0,0 +1,13 @@
+
+TESTS = 		test.t
+TESTS_ENVIRONMENT =	$(SHELL)
+
+EXTRA_DIST = 		$(TESTS) test.pl
+
+check_PROGRAMS = 	test
+
+test_CFLAGS = 		-g -I../../src
+test_LDFLAGS = 		-L../../src
+test_LDADD = 		-ltap
+
+CLEANFILES =	test.o test.c.out test.pl.out

+ 46 - 0
tap/tests/fail/test.c

@@ -0,0 +1,46 @@
+/*-
+ * Copyright (c) 2004 Nik Clayton
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+
+#include "tap.h"
+
+int
+main(int argc, char *argv[])
+{
+	unsigned int rc = 0;
+
+	rc = plan_tests(2);
+	diag("Returned: %d", rc);
+
+	rc = fail("test to fail");
+	diag("Returned: %d", rc);
+
+	rc = fail("test to fail %s", "with extra string");
+	diag("Returned: %d", rc);
+
+	return exit_status();
+}

+ 17 - 0
tap/tests/fail/test.pl

@@ -0,0 +1,17 @@
+#!/usr/bin/perl
+
+use warnings;
+use strict;
+
+use Test::More;
+
+my $rc = 0;
+
+$rc = plan tests => 2;
+diag("Returned: " . sprintf('%d', $rc));
+
+$rc = fail('test to fail');
+diag("Returned: $rc");
+
+$rc = fail('test to fail with extra string');
+diag("Returned: $rc");

+ 29 - 0
tap/tests/fail/test.t

@@ -0,0 +1,29 @@
+#!/bin/sh
+
+cd `dirname $0`
+
+echo '1..2'
+
+make 2>&1 > /dev/null
+
+perl ./test.pl 2>&1 | sed -e 's/#     Failed test \(.*\)/#     Failed test ()/' > test.pl.out
+perlstatus=$?
+
+./test 2>&1 | sed -e 's/#     Failed test \(.*\)/#     Failed test ()/' > test.c.out
+cstatus=$?
+
+diff -u test.pl.out test.c.out
+
+if [ $? -eq 0 ]; then
+	echo 'ok 1 - output is identical'
+else
+	echo 'not ok 1 - output is identical'
+fi
+
+if [ $perlstatus -eq $cstatus ]; then
+	echo 'ok 2 - status code'
+else
+	echo 'not ok 2 - status code'
+	echo "# perlstatus = $perlstatus"
+	echo "#    cstatus = $cstatus"
+fi

+ 3 - 0
tap/tests/ok/Makefile.am

@@ -0,0 +1,3 @@
+SUBDIRS  =	ok
+SUBDIRS +=	ok-hash
+SUBDIRS +=	ok-numeric

+ 13 - 0
tap/tests/ok/ok-hash/Makefile.am

@@ -0,0 +1,13 @@
+
+TESTS = 		test.t
+TESTS_ENVIRONMENT =	$(SHELL)
+
+EXTRA_DIST = 		$(TESTS) test.pl
+
+check_PROGRAMS = 	test
+
+test_CFLAGS = 		-g -I../../../src
+test_LDFLAGS = 		-L../../../src
+test_LDADD = 		-ltap
+
+CLEANFILES =	test.o test.c.out test.pl.out

+ 52 - 0
tap/tests/ok/ok-hash/test.c

@@ -0,0 +1,52 @@
+/*-
+ * Copyright (c) 2004 Nik Clayton
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+
+#include "tap.h"
+
+int
+main(int argc, char *argv[])
+{
+	unsigned int rc = 0;
+
+	rc = plan_tests(4);
+	diag("Returned: %d", rc);
+
+	rc = ok(1, "Test with no hash");
+	diag("Returned: %d", rc);
+
+	rc = ok(1, "Test with one # hash");
+	diag("Returned: %d", rc);
+
+        rc = ok(1, "Test with # two # hashes");
+	diag("Returned: %d", rc);
+
+	rc = ok(1, "Test with ## back to back hashes");
+	diag("Returned: %d", rc);
+	
+	return exit_status();
+}

+ 24 - 0
tap/tests/ok/ok-hash/test.pl

@@ -0,0 +1,24 @@
+#!/usr/bin/perl
+
+use warnings;
+use strict;
+
+use Test::More;
+
+my $rc = 0;
+
+$rc = plan tests => 4;
+diag("Returned: " . sprintf("%d", $rc));
+
+
+$rc = ok(1, 'Test with no hash');
+diag("Returned: $rc");
+
+$rc = ok(1, 'Test with one # hash');
+diag("Returned: $rc");
+
+$rc = ok(1, 'Test with # two # hashes');
+diag("Returned: $rc");
+
+$rc = ok(1, 'Test with ## back to back hashes');
+diag("Returned: $rc");

+ 29 - 0
tap/tests/ok/ok-hash/test.t

@@ -0,0 +1,29 @@
+#!/bin/sh
+
+cd `dirname $0`
+
+echo '1..2'
+
+make 2>&1 > /dev/null
+
+perl ./test.pl 2>&1 | sed -e 's/#     Failed test \(.*\)/#     Failed test ()/' > test.pl.out
+perlstatus=$?
+
+./test 2>&1 | sed -e 's/#     Failed test \(.*\)/#     Failed test ()/' > test.c.out
+cstatus=$?
+
+diff -u test.pl.out test.c.out
+
+if [ $? -eq 0 ]; then
+	echo 'ok 1 - output is identical'
+else
+	echo 'not ok 1 - output is identical'
+fi
+
+if [ $perlstatus -eq $cstatus ]; then
+	echo 'ok 2 - status code'
+else
+	echo 'not ok 2 - status code'
+	echo "# perlstatus = $perlstatus"
+	echo "#    cstatus = $cstatus"
+fi

+ 13 - 0
tap/tests/ok/ok-numeric/Makefile.am

@@ -0,0 +1,13 @@
+
+TESTS = 		test.t
+TESTS_ENVIRONMENT =	$(SHELL)
+
+EXTRA_DIST = 		$(TESTS) test.pl
+
+check_PROGRAMS = 	test
+
+test_CFLAGS = 		-g -I../../../src
+test_LDFLAGS = 		-L../../../src
+test_LDADD = 		-ltap
+
+CLEANFILES =	test.o test.c.out test.pl.out

+ 49 - 0
tap/tests/ok/ok-numeric/test.c

@@ -0,0 +1,49 @@
+/*-
+ * Copyright (c) 2004 Nik Clayton
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+
+#include "tap.h"
+
+int
+main(int argc, char *argv[])
+{
+	unsigned int rc = 0;
+
+	rc = plan_tests(3);
+	diag("Returned: %d", rc);
+
+	rc = ok(1, "First test");
+	diag("Returned: %d", rc);
+
+	rc = ok(1, "1");
+	diag("Returned: %d", rc);
+
+	rc = ok(1, "Third test");
+	diag("Returned: %d", rc);
+
+	return exit_status();
+}

+ 21 - 0
tap/tests/ok/ok-numeric/test.pl

@@ -0,0 +1,21 @@
+#!/usr/bin/perl
+
+use warnings;
+use strict;
+
+use Test::More;
+
+my $rc = 0;
+
+$rc = plan tests => 3;
+diag("Returned: " . sprintf("%d", $rc));
+
+
+$rc = ok(1, 'First test');
+diag("Returned: $rc");
+
+$rc = ok(1, '1');
+diag("Returned: $rc");
+
+$rc = ok(1, 'Third test');
+diag("Returned: $rc");

+ 29 - 0
tap/tests/ok/ok-numeric/test.t

@@ -0,0 +1,29 @@
+#!/bin/sh
+
+cd `dirname $0`
+
+echo '1..2'
+
+make 2>&1 > /dev/null
+
+perl ./test.pl 2>&1 | sed -e 's/#     Failed test \(.*\)/#     Failed test ()/' > test.pl.out
+perlstatus=$?
+
+./test 2>&1 | sed -e 's/#     Failed test \(.*\)/#     Failed test ()/' > test.c.out
+cstatus=$?
+
+diff -u test.pl.out test.c.out
+
+if [ $? -eq 0 ]; then
+	echo 'ok 1 - output is identical'
+else
+	echo 'not ok 1 - output is identical'
+fi
+
+if [ $perlstatus -eq $cstatus ]; then
+	echo 'ok 2 - status code'
+else
+	echo 'not ok 2 - status code'
+	echo "# perlstatus = $perlstatus"
+	echo "#    cstatus = $cstatus"
+fi

+ 13 - 0
tap/tests/ok/ok/Makefile.am

@@ -0,0 +1,13 @@
+
+TESTS = 		test.t
+TESTS_ENVIRONMENT =	$(SHELL)
+
+EXTRA_DIST = 		$(TESTS) test.pl
+
+check_PROGRAMS = 	test
+
+test_CFLAGS = 		-g -I../../../src
+test_LDFLAGS = 		-L../../../src
+test_LDADD = 		-ltap
+
+CLEANFILES =	test.o test.c.out test.pl.out

+ 55 - 0
tap/tests/ok/ok/test.c

@@ -0,0 +1,55 @@
+/*-
+ * Copyright (c) 2004 Nik Clayton
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+
+#include "tap.h"
+
+int
+main(int argc, char *argv[])
+{
+	unsigned int rc = 0;
+
+	rc = plan_tests(5);
+	diag("Returned: %d", rc);
+
+	rc = ok(1 == 1, "1 equals 1");
+	diag("Returned: %d", rc);
+
+	rc = ok(1 == 1, "1 equals %d", 1);
+	diag("Returned: %d", rc);
+
+	rc = ok1(1 == 1);
+	diag("Returned: %d", rc);
+
+	rc = ok(1 == 2, "1 equals 2");
+	diag("Returned: %d", rc);
+
+	rc = ok1(1 == 2);
+	diag("Returned: %d", rc);
+
+	return exit_status();
+}

+ 27 - 0
tap/tests/ok/ok/test.pl

@@ -0,0 +1,27 @@
+#!/usr/bin/perl
+
+use warnings;
+use strict;
+
+use Test::More;
+
+my $rc = 0;
+
+$rc = plan tests => 5;
+diag("Returned: " . sprintf("%d", $rc));
+
+
+$rc = ok(1 == 1, '1 equals 1');	# Test ok() passes when it should
+diag("Returned: $rc");
+
+$rc = ok(1 == 1, '1 equals 1'); # Used for %d testing in test.c
+diag("Returned: $rc");
+
+$rc = ok(1 == 1, '1 == 1');	# Test ok1() passes when it should
+diag("Returned: $rc");
+
+$rc = ok(1 == 2, '1 equals 2');	# Test ok() fails when it should
+diag("Returned: $rc");
+
+$rc = ok(1 == 2, '1 == 2');	# Test ok1() fails when it should
+diag("Returned: $rc");

+ 29 - 0
tap/tests/ok/ok/test.t

@@ -0,0 +1,29 @@
+#!/bin/sh
+
+cd `dirname $0`
+
+echo '1..2'
+
+make 2>&1 > /dev/null
+
+perl ./test.pl 2>&1 | sed -e 's/#     Failed test \(.*\)/#     Failed test ()/' > test.pl.out
+perlstatus=$?
+
+./test 2>&1 | sed -e 's/#     Failed test \(.*\)/#     Failed test ()/' > test.c.out
+cstatus=$?
+
+diff -u test.pl.out test.c.out
+
+if [ $? -eq 0 ]; then
+	echo 'ok 1 - output is identical'
+else
+	echo 'not ok 1 - output is identical'
+fi
+
+if [ $perlstatus -eq $cstatus ]; then
+	echo 'ok 2 - status code'
+else
+	echo 'not ok 2 - status code'
+	echo "# perlstatus = $perlstatus"
+	echo "#    cstatus = $cstatus"
+fi

+ 13 - 0
tap/tests/pass/Makefile.am

@@ -0,0 +1,13 @@
+
+TESTS = 		test.t
+TESTS_ENVIRONMENT =	$(SHELL)
+
+EXTRA_DIST = 		$(TESTS) test.pl
+
+check_PROGRAMS = 	test
+
+test_CFLAGS = 		-g -I../../src
+test_LDFLAGS = 		-L../../src
+test_LDADD = 		-ltap
+
+CLEANFILES =	test.o test.c.out test.pl.out

+ 46 - 0
tap/tests/pass/test.c

@@ -0,0 +1,46 @@
+/*-
+ * Copyright (c) 2004 Nik Clayton
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+
+#include "tap.h"
+
+int
+main(int argc, char *argv[])
+{
+	unsigned int rc = 0;
+
+	rc = plan_tests(2);
+	diag("Returned: %d", rc);
+
+	rc = pass("test to pass");
+	diag("Returned: %d", rc);
+
+	rc = pass("test to pass %s", "with extra string");
+	diag("Returned: %d", rc);
+
+	return exit_status();
+}

+ 17 - 0
tap/tests/pass/test.pl

@@ -0,0 +1,17 @@
+#!/usr/bin/perl
+
+use warnings;
+use strict;
+
+use Test::More;
+
+my $rc = 0;
+
+$rc = plan tests => 2;
+diag("Returned: " . sprintf('%d', $rc));
+
+$rc = pass('test to pass');
+diag("Returned: $rc");
+
+$rc = pass('test to pass with extra string');
+diag("Returned: $rc");

+ 29 - 0
tap/tests/pass/test.t

@@ -0,0 +1,29 @@
+#!/bin/sh
+
+cd `dirname $0`
+
+echo '1..2'
+
+make 2>&1 > /dev/null
+
+perl ./test.pl 2>&1 | sed -e 's/#     Failed test \(.*\)/#     Failed test ()/' > test.pl.out
+perlstatus=$?
+
+./test 2>&1 | sed -e 's/#     Failed test \(.*\)/#     Failed test ()/' > test.c.out
+cstatus=$?
+
+diff -u test.pl.out test.c.out
+
+if [ $? -eq 0 ]; then
+	echo 'ok 1 - output is identical'
+else
+	echo 'not ok 1 - output is identical'
+fi
+
+if [ $perlstatus -eq $cstatus ]; then
+	echo 'ok 2 - status code'
+else
+	echo 'not ok 2 - status code'
+	echo "# perlstatus = $perlstatus"
+	echo "#    cstatus = $cstatus"
+fi

+ 7 - 0
tap/tests/plan/Makefile.am

@@ -0,0 +1,7 @@
+SUBDIRS  =	no-tests
+SUBDIRS +=	no_plan
+SUBDIRS +=	not-enough-tests
+SUBDIRS +=	too-many-plans
+SUBDIRS +=	too-many-tests
+SUBDIRS +=	sane
+SUBDIRS +=	skip_all

+ 13 - 0
tap/tests/plan/no-tests/Makefile.am

@@ -0,0 +1,13 @@
+
+TESTS = 		test.t
+TESTS_ENVIRONMENT =	$(SHELL)
+
+EXTRA_DIST = 		$(TESTS) test.pl
+
+check_PROGRAMS = 	test
+
+test_CFLAGS = 		-g -I../../../src
+test_LDFLAGS = 		-L../../../src
+test_LDADD = 		-ltap
+
+CLEANFILES =	test.o test.c.out test.pl.out

+ 43 - 0
tap/tests/plan/no-tests/test.c

@@ -0,0 +1,43 @@
+/*-
+ * Copyright (c) 2004 Nik Clayton
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+
+#include "tap.h"
+
+int
+main(int argc, char *argv[])
+{
+	unsigned int rc = 0;
+
+	rc = plan_tests(0);
+	diag("Returned: %d", rc);
+
+	rc = ok(1, NULL);
+	diag("Returned: %d", rc);
+
+	return exit_status();
+}

+ 14 - 0
tap/tests/plan/no-tests/test.pl

@@ -0,0 +1,14 @@
+#!/usr/bin/perl
+
+use warnings;
+use strict;
+
+use Test::More;
+
+my $rc = 0;
+
+$rc = plan tests => 0;
+diag("Returned: " . sprintf("%d", $rc));
+
+$rc = ok(1);
+diag("Returned: $rc");

+ 29 - 0
tap/tests/plan/no-tests/test.t

@@ -0,0 +1,29 @@
+#!/bin/sh
+
+cd `dirname $0`
+
+echo '1..2'
+
+make 2>&1 > /dev/null
+
+perl ./test.pl 2>&1 | sed -e 's/#     Failed test \(.*\)/#     Failed test ()/' > test.pl.out
+perlstatus=$?
+
+./test 2>&1 | sed -e 's/#     Failed test \(.*\)/#     Failed test ()/' > test.c.out
+cstatus=$?
+
+diff -u test.pl.out test.c.out
+
+if [ $? -eq 0 ]; then
+	echo 'ok 1 - output is identical'
+else
+	echo 'not ok 1 - output is identical'
+fi
+
+if [ $perlstatus -eq $cstatus ]; then
+	echo 'ok 2 - status code'
+else
+	echo 'not ok 2 - status code'
+	echo "# perlstatus = $perlstatus"
+	echo "#    cstatus = $cstatus"
+fi

+ 13 - 0
tap/tests/plan/no_plan/Makefile.am

@@ -0,0 +1,13 @@
+
+TESTS = 		test.t
+TESTS_ENVIRONMENT =	$(SHELL)
+
+EXTRA_DIST = 		$(TESTS) test.pl
+
+check_PROGRAMS = 	test
+
+test_CFLAGS = 		-g -I../../../src
+test_LDFLAGS = 		-L../../../src
+test_LDADD = 		-ltap
+
+CLEANFILES =	test.o test.c.out test.pl.out

+ 43 - 0
tap/tests/plan/no_plan/test.c

@@ -0,0 +1,43 @@
+/*-
+ * Copyright (c) 2004 Nik Clayton
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+
+#include "tap.h"
+
+int
+main(int argc, char *argv[])
+{
+	unsigned int rc = 0;
+
+	rc = plan_no_plan();
+	diag("Returned: %d", rc);
+
+	rc = ok(1, NULL);
+	diag("Returned: %d", rc);
+
+	return exit_status();
+}

+ 14 - 0
tap/tests/plan/no_plan/test.pl

@@ -0,0 +1,14 @@
+#!/usr/bin/perl
+
+use warnings;
+use strict;
+
+my $rc = 0;
+
+use Test::More;
+
+$rc = plan qw(no_plan);
+diag("Returned: " . sprintf("%d", $rc));
+
+$rc = ok(1);
+diag("Returned: $rc");

+ 29 - 0
tap/tests/plan/no_plan/test.t

@@ -0,0 +1,29 @@
+#!/bin/sh
+
+cd `dirname $0`
+
+echo '1..2'
+
+make 2>&1 > /dev/null
+
+perl ./test.pl 2>&1 | sed -e 's/#     Failed test \(.*\)/#     Failed test ()/' > test.pl.out
+perlstatus=$?
+
+./test 2>&1 | sed -e 's/#     Failed test \(.*\)/#     Failed test ()/' > test.c.out
+cstatus=$?
+
+diff -u test.pl.out test.c.out
+
+if [ $? -eq 0 ]; then
+	echo 'ok 1 - output is identical'
+else
+	echo 'not ok 1 - output is identical'
+fi
+
+if [ $perlstatus -eq $cstatus ]; then
+	echo 'ok 2 - status code'
+else
+	echo 'not ok 2 - status code'
+	echo "# perlstatus = $perlstatus"
+	echo "#    cstatus = $cstatus"
+fi

+ 13 - 0
tap/tests/plan/not-enough-tests/Makefile.am

@@ -0,0 +1,13 @@
+
+TESTS = 		test.t
+TESTS_ENVIRONMENT =	$(SHELL)
+
+EXTRA_DIST = 		$(TESTS) test.pl
+
+check_PROGRAMS = 	test
+
+test_CFLAGS = 		-g -I../../../src
+test_LDFLAGS = 		-L../../../src
+test_LDADD = 		-ltap
+
+CLEANFILES =	test.o test.c.out test.pl.out

+ 49 - 0
tap/tests/plan/not-enough-tests/test.c

@@ -0,0 +1,49 @@
+/*-
+ * Copyright (c) 2004 Nik Clayton
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+
+#include "tap.h"
+
+int
+main(int argc, char *argv[])
+{
+	unsigned int rc = 0;
+
+	rc = plan_tests(1);
+	diag("Returned: %d", rc);
+
+	rc = ok(1, NULL);
+	diag("Returned: %d", rc);
+
+	rc = ok(1, NULL);
+	diag("Returned: %d", rc);
+
+	rc = ok(1, NULL);
+	diag("Returned: %d", rc);
+
+	return exit_status();
+}

+ 20 - 0
tap/tests/plan/not-enough-tests/test.pl

@@ -0,0 +1,20 @@
+#!/usr/bin/perl
+
+use warnings;
+use strict;
+
+use Test::More;
+
+my $rc = 0;
+
+$rc = plan tests => 1;
+diag("Returned: " . sprintf("%d", $rc));
+
+$rc = ok(1);
+diag("Returned: $rc");
+
+$rc = ok(1);
+diag("Returned: $rc");
+
+$rc = ok(1);
+diag("Returned: $rc");

+ 29 - 0
tap/tests/plan/not-enough-tests/test.t

@@ -0,0 +1,29 @@
+#!/bin/sh
+
+cd `dirname $0`
+
+echo '1..2'
+
+make 2>&1 > /dev/null
+
+perl ./test.pl 2>&1 | sed -e 's/#     Failed test \(.*\)/#     Failed test ()/' > test.pl.out
+perlstatus=$?
+
+./test 2>&1 | sed -e 's/#     Failed test \(.*\)/#     Failed test ()/' > test.c.out
+cstatus=$?
+
+diff -u test.pl.out test.c.out
+
+if [ $? -eq 0 ]; then
+	echo 'ok 1 - output is identical'
+else
+	echo 'not ok 1 - output is identical'
+fi
+
+if [ $perlstatus -eq $cstatus ]; then
+	echo 'ok 2 - status code'
+else
+	echo 'not ok 2 - status code'
+	echo "# perlstatus = $perlstatus"
+	echo "#    cstatus = $cstatus"
+fi

+ 13 - 0
tap/tests/plan/sane/Makefile.am

@@ -0,0 +1,13 @@
+
+TESTS = 		test.t
+TESTS_ENVIRONMENT =	$(SHELL)
+
+EXTRA_DIST = 		$(TESTS) test.pl
+
+check_PROGRAMS = 	test
+
+test_CFLAGS = 		-g -I../../../src
+test_LDFLAGS = 		-L../../../src
+test_LDADD = 		-ltap
+
+CLEANFILES =	test.o test.c.out test.pl.out

+ 43 - 0
tap/tests/plan/sane/test.c

@@ -0,0 +1,43 @@
+/*-
+ * Copyright (c) 2004 Nik Clayton
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+
+#include "tap.h"
+
+int
+main(int argc, char *argv[])
+{
+	unsigned int rc = 0;
+
+	rc = plan_tests(1);
+	diag("Returned: %d", rc);
+
+	rc = ok(1, NULL);
+	diag("Returned: %d", rc);
+
+	return exit_status();
+}

+ 14 - 0
tap/tests/plan/sane/test.pl

@@ -0,0 +1,14 @@
+#!/usr/bin/perl
+
+use warnings;
+use strict;
+
+use Test::More;
+
+my $rc = 0;
+
+$rc = plan tests => 1;
+diag("Returned: " . sprintf("%d", $rc));
+
+$rc = ok(1);
+diag("Returned: $rc");

+ 29 - 0
tap/tests/plan/sane/test.t

@@ -0,0 +1,29 @@
+#!/bin/sh
+
+cd `dirname $0`
+
+echo '1..2'
+
+make 2>&1 > /dev/null
+
+perl ./test.pl 2>&1 | sed -e 's/#     Failed test \(.*\)/#     Failed test ()/' > test.pl.out
+perlstatus=$?
+
+./test 2>&1 | sed -e 's/#     Failed test \(.*\)/#     Failed test ()/' > test.c.out
+cstatus=$?
+
+diff -u test.pl.out test.c.out
+
+if [ $? -eq 0 ]; then
+	echo 'ok 1 - output is identical'
+else
+	echo 'not ok 1 - output is identical'
+fi
+
+if [ $perlstatus -eq $cstatus ]; then
+	echo 'ok 2 - status code'
+else
+	echo 'not ok 2 - status code'
+	echo "# perlstatus = $perlstatus"
+	echo "#    cstatus = $cstatus"
+fi

+ 13 - 0
tap/tests/plan/skip_all/Makefile.am

@@ -0,0 +1,13 @@
+
+TESTS = 		test.t
+TESTS_ENVIRONMENT =	$(SHELL)
+
+EXTRA_DIST = 		$(TESTS) test.pl
+
+check_PROGRAMS = 	test
+
+test_CFLAGS = 		-g -I../../../src
+test_LDFLAGS = 		-L../../../src
+test_LDADD = 		-ltap
+
+CLEANFILES =	test.o test.c.out test.pl.out

+ 38 - 0
tap/tests/plan/skip_all/test.c

@@ -0,0 +1,38 @@
+/*-
+ * Copyright (c) 2004 Nik Clayton
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "tap.h"
+
+int
+main(int argc, char *argv[])
+{
+	unsigned int rc = 0;
+
+	rc = plan_skip_all("No good reason");
+	diag("Returned: %d", rc);
+
+	return exit_status();
+}

+ 11 - 0
tap/tests/plan/skip_all/test.pl

@@ -0,0 +1,11 @@
+#!/usr/bin/perl
+
+use warnings;
+use strict;
+
+use Test::More;
+
+my $rc = 0;
+
+$rc = plan skip_all => "No good reason";
+diag("Returned: " . sprintf("%d", $rc));

+ 29 - 0
tap/tests/plan/skip_all/test.t

@@ -0,0 +1,29 @@
+#!/bin/sh
+
+cd `dirname $0`
+
+echo '1..2'
+
+make 2>&1 > /dev/null
+
+perl ./test.pl 2>&1 | sed -e 's/#     Failed test \(.*\)/#     Failed test ()/' > test.pl.out
+perlstatus=$?
+
+./test 2>&1 | sed -e 's/#     Failed test \(.*\)/#     Failed test ()/' > test.c.out
+cstatus=$?
+
+diff -u test.pl.out test.c.out
+
+if [ $? -eq 0 ]; then
+	echo 'ok 1 - output is identical'
+else
+	echo 'not ok 1 - output is identical'
+fi
+
+if [ $perlstatus -eq $cstatus ]; then
+	echo 'ok 2 - status code'
+else
+	echo 'not ok 2 - status code'
+	echo "# perlstatus = $perlstatus"
+	echo "#    cstatus = $cstatus"
+fi

+ 13 - 0
tap/tests/plan/too-many-plans/Makefile.am

@@ -0,0 +1,13 @@
+
+TESTS = 		test.t
+TESTS_ENVIRONMENT =	$(SHELL)
+
+EXTRA_DIST = 		$(TESTS) test.pl
+
+check_PROGRAMS = 	test
+
+test_CFLAGS = 		-g -I../../../src
+test_LDFLAGS = 		-L../../../src
+test_LDADD = 		-ltap
+
+CLEANFILES =	test.o test.c.out test.pl.out

+ 49 - 0
tap/tests/plan/too-many-plans/test.c

@@ -0,0 +1,49 @@
+/*-
+ * Copyright (c) 2004 Nik Clayton
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+
+#include "tap.h"
+
+int
+main(int argc, char *argv[])
+{
+	unsigned int rc = 0;
+
+	rc = plan_tests(1);
+	diag("Returned: %d", rc);
+
+	rc = ok(1, NULL);
+	diag("Returned: %d", rc);
+
+	rc = plan_tests(1);
+	diag("Returned: %d", rc);
+
+	rc = ok(0, NULL);
+	diag("Returned: %d", rc);
+
+	return exit_status();
+}

+ 20 - 0
tap/tests/plan/too-many-plans/test.pl

@@ -0,0 +1,20 @@
+#!/usr/bin/perl
+
+use warnings;
+use strict;
+
+use Test::More;
+
+my $rc = 0;
+
+$rc = plan tests => 1;
+diag("Returned: " . sprintf("%d", $rc));
+
+$rc = ok(1);
+diag("Returned: $rc");
+
+$rc = plan tests => 1;
+diag("Returned: $rc");
+
+$rc = ok(0);
+diag("Returned: $rc");

+ 29 - 0
tap/tests/plan/too-many-plans/test.t

@@ -0,0 +1,29 @@
+#!/bin/sh
+
+cd `dirname $0`
+
+echo '1..2'
+
+make 2>&1 > /dev/null
+
+perl ./test.pl 2>&1 | sed -e 's/twice!.*$/twice!/' > test.pl.out
+perlstatus=$?
+
+./test 2>&1 | sed -e 's/twice!.*$/twice!/' > test.c.out
+cstatus=$?
+
+diff -u test.pl.out test.c.out
+
+if [ $? -eq 0 ]; then
+	echo 'ok 1 - output is identical'
+else
+	echo 'not ok 1 - output is identical'
+fi
+
+if [ $perlstatus -eq $cstatus ]; then
+	echo 'ok 2 - status code'
+else
+	echo 'not ok 2 - status code'
+	echo "# perlstatus = $perlstatus"
+	echo "#    cstatus = $cstatus"
+fi

+ 13 - 0
tap/tests/plan/too-many-tests/Makefile.am

@@ -0,0 +1,13 @@
+
+TESTS = 		test.t
+TESTS_ENVIRONMENT =	$(SHELL)
+
+EXTRA_DIST = 		$(TESTS) test.pl
+
+check_PROGRAMS = 	test
+
+test_CFLAGS = 		-g -I../../../src
+test_LDFLAGS = 		-L../../../src
+test_LDADD = 		-ltap
+
+CLEANFILES =	test.o test.c.out test.pl.out

+ 46 - 0
tap/tests/plan/too-many-tests/test.c

@@ -0,0 +1,46 @@
+/*-
+ * Copyright (c) 2004 Nik Clayton
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+
+#include "tap.h"
+
+int
+main(int argc, char *argv[])
+{
+	unsigned int rc = 0;
+
+	rc = plan_tests(5);
+	diag("Returned: %d", rc);
+
+	rc = ok(1, NULL);
+	diag("Returned: %d", rc);
+
+	rc = ok(0, NULL);
+	diag("Returned: %d", rc);
+
+	return exit_status();
+}

+ 17 - 0
tap/tests/plan/too-many-tests/test.pl

@@ -0,0 +1,17 @@
+#!/usr/bin/perl
+
+use warnings;
+use strict;
+
+use Test::More;
+
+my $rc = 0;
+
+$rc = plan tests => 5;
+diag("Returned: " . sprintf("%d", $rc));
+
+$rc = ok(1);
+diag("Returned: $rc");
+
+$rc = ok(0);
+diag("Returned: $rc");

+ 29 - 0
tap/tests/plan/too-many-tests/test.t

@@ -0,0 +1,29 @@
+#!/bin/sh
+
+cd `dirname $0`
+
+echo '1..2'
+
+make 2>&1 > /dev/null
+
+perl ./test.pl 2>&1 | sed -e 's/#     Failed test \(.*\)/#     Failed test ()/' > test.pl.out
+perlstatus=$?
+
+./test 2>&1 | sed -e 's/#     Failed test \(.*\)/#     Failed test ()/' > test.c.out
+cstatus=$?
+
+diff -u test.pl.out test.c.out
+
+if [ $? -eq 0 ]; then
+	echo 'ok 1 - output is identical'
+else
+	echo 'not ok 1 - output is identical'
+fi
+
+if [ $perlstatus -eq $cstatus ]; then
+	echo 'ok 2 - status code'
+else
+	echo 'not ok 2 - status code'
+	echo "# perlstatus = $perlstatus"
+	echo "#    cstatus = $cstatus"
+fi

+ 13 - 0
tap/tests/skip/Makefile.am

@@ -0,0 +1,13 @@
+
+TESTS = 		test.t
+TESTS_ENVIRONMENT =	$(SHELL)
+
+EXTRA_DIST = 		$(TESTS) test.pl
+
+check_PROGRAMS = 	test
+
+test_CFLAGS = 		-g -I../../src
+test_LDFLAGS = 		-L../../src
+test_LDADD = 		-ltap
+
+CLEANFILES =	test.o test.c.out test.pl.out

+ 69 - 0
tap/tests/skip/test.c

@@ -0,0 +1,69 @@
+/*-
+ * Copyright (c) 2004 Nik Clayton
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+
+#include "tap.h"
+
+int
+main(int argc, char *argv[])
+{
+	unsigned int rc = 0;
+	unsigned int side_effect = 0;
+
+	rc = plan_tests(4);
+	diag("Returned: %d", rc);
+
+	rc = ok(1 == 1, "1 equals 1");	/* Should always work */
+	diag("Returned: %d", rc);
+
+	do {
+		if(1) {
+			rc = skip(1, "Testing skipping");
+			continue;
+		}
+		
+		side_effect++;
+
+		ok(side_effect == 1, "side_effect checked out");
+
+	} while(0);
+
+	diag("Returned: %d", rc);
+
+	skip_start(1 == 1, 1, "Testing skipping #2");
+
+	side_effect++;
+	rc = ok(side_effect == 1, "side_effect checked out");
+	diag("Returned: %d", rc);
+
+	skip_end;
+
+	rc = ok(side_effect == 0, "side_effect is %d", side_effect);
+	diag("Returned: %d", rc);
+
+	return exit_status();
+}

+ 40 - 0
tap/tests/skip/test.pl

@@ -0,0 +1,40 @@
+#!/usr/bin/perl
+
+use warnings;
+use strict;
+
+use Test::More;
+
+my $rc = 0;
+
+$rc = plan tests => 4;
+diag("Returned: " . sprintf("%d", $rc));
+
+my $side_effect = 0;		# Check whether skipping has side effects
+
+$rc = ok(1 == 1, '1 equals 1');	# Test ok() passes when it should
+diag("Returned: $rc");
+
+# Start skipping
+SKIP: {
+	$rc = skip "Testing skipping", 1;
+
+	$side_effect++;
+
+	$rc = ok($side_effect == 1, '$side_effect checked out');
+}
+
+diag("Returned: $rc");
+
+SKIP: {
+	$rc = skip "Testing skipping #2", 1;
+	diag("Returned: $rc");
+
+	$side_effect++;
+
+	$rc = ok($side_effect == 1, '$side_effect checked out');
+	diag("Returned: $rc");
+}
+
+$rc = ok($side_effect == 0, "side_effect is $side_effect");
+diag("Returned: $rc");

+ 29 - 0
tap/tests/skip/test.t

@@ -0,0 +1,29 @@
+#!/bin/sh
+
+cd `dirname $0`
+
+echo '1..2'
+
+make 2>&1 > /dev/null
+
+perl ./test.pl 2>&1 | sed -e 's/#     Failed test \(.*\)/#     Failed test ()/' > test.pl.out
+perlstatus=$?
+
+./test 2>&1 | sed -e 's/#     Failed test \(.*\)/#     Failed test ()/' > test.c.out
+cstatus=$?
+
+diff -u test.pl.out test.c.out
+
+if [ $? -eq 0 ]; then
+	echo 'ok 1 - output is identical'
+else
+	echo 'not ok 1 - output is identical'
+fi
+
+if [ $perlstatus -eq $cstatus ]; then
+	echo 'ok 2 - status code'
+else
+	echo 'not ok 2 - status code'
+	echo "# perlstatus = $perlstatus"
+	echo "#    cstatus = $cstatus"
+fi

+ 13 - 0
tap/tests/todo/Makefile.am

@@ -0,0 +1,13 @@
+
+TESTS = 		test.t
+TESTS_ENVIRONMENT =	$(SHELL)
+
+EXTRA_DIST = 		$(TESTS) test.pl
+
+check_PROGRAMS = 	test
+
+test_CFLAGS = 		-g -I../../src
+test_LDFLAGS = 		-L../../src
+test_LDADD = 		-ltap
+
+CLEANFILES =	test.o test.c.out test.pl.out

+ 68 - 0
tap/tests/todo/test.c

@@ -0,0 +1,68 @@
+/*-
+ * Copyright (c) 2004 Nik Clayton
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+
+#include "tap.h"
+
+int
+main(int argc, char *argv[])
+{
+	unsigned int rc = 0;
+	unsigned int side_effect = 0;
+
+	rc = plan_tests(5);
+	diag("Returned: %d", rc);
+
+	rc = ok(1 == 1, "1 equals 1");	/* Should always work */
+	diag("Returned: %d", rc);
+
+	todo_start("For testing purposes");
+
+	side_effect++;
+
+	/* This test should fail */
+	rc = ok(side_effect == 0, "side_effect checked out");
+	diag("Returned: %d", rc);
+
+	/* This test should unexpectedly succeed */
+	rc = ok(side_effect == 1, "side_effect checked out");
+	diag("Returned: %d", rc);
+
+	todo_end();
+
+	todo_start("Testing printf() %s in todo_start()", "expansion");
+
+	rc = ok(0, "dummy test");
+	diag("Returned: %d", rc);
+
+	todo_end();
+
+	rc = ok(side_effect == 1, "side_effect is %d", side_effect);
+	diag("Returned: %d", rc);
+
+	return exit_status();
+}

+ 41 - 0
tap/tests/todo/test.pl

@@ -0,0 +1,41 @@
+#!/usr/bin/perl
+
+use warnings;
+use strict;
+
+use Test::More;
+
+my $rc = 0;
+
+$rc = plan tests => 5;
+diag("Returned: " . sprintf("%d", $rc));
+
+my $side_effect = 0;		# Check whether TODO has side effects
+
+$rc = ok(1 == 1, '1 equals 1');	# Test ok() passes when it should
+diag("Returned: $rc");
+
+# Start TODO tests
+TODO: {
+	local $TODO = 'For testing purposes';
+
+	$side_effect++;
+
+	# This test should fail
+	$rc = ok($side_effect == 0, 'side_effect checked out');
+	diag("Returned: $rc");
+
+	# This test should unexpectedly succeed
+	$rc = ok($side_effect == 1, 'side_effect checked out');
+	diag("Returned: $rc");
+}
+
+TODO: {
+	local $TODO = 'Testing printf() expansion in todo_start()';
+
+	$rc = ok(0, 'dummy test');
+	diag("Returned: $rc");
+}
+
+$rc = ok($side_effect == 1, "side_effect is $side_effect");
+diag("Returned: $rc");

+ 29 - 0
tap/tests/todo/test.t

@@ -0,0 +1,29 @@
+#!/bin/sh
+
+cd `dirname $0`
+
+echo '1..2'
+
+make 2>&1 > /dev/null
+
+perl ./test.pl 2>&1 | sed -e 's/#     Failed (TODO) test \(.*\)/#     Failed (TODO) test ()/' > test.pl.out
+perlstatus=$?
+
+./test 2>&1 | sed -e 's/#     Failed (TODO) test \(.*\)/#     Failed (TODO) test ()/' > test.c.out
+cstatus=$?
+
+diff -u test.pl.out test.c.out
+
+if [ $? -eq 0 ]; then
+	echo 'ok 1 - output is identical'
+else
+	echo 'not ok 1 - output is identical'
+fi
+
+if [ $perlstatus -eq $cstatus ]; then
+	echo 'ok 2 - status code'
+else
+	echo 'not ok 2 - status code'
+	echo "# perlstatus = $perlstatus"
+	echo "#    cstatus = $cstatus"
+fi