Lely core libraries 1.9.2
tap.c
Go to the documentation of this file.
1
24#include "tap.h"
25#include <lely/libc/stdio.h>
26#include <lely/tap/tap.h>
27
28#include <assert.h>
29#include <stdarg.h>
30#include <stdlib.h>
31
32#ifdef __MINGW32__
33#include <fcntl.h>
34#include <io.h>
35#endif
36
37static int tap_num;
38
39static void tap_vprintf(const char *format, va_list ap);
40
41void
42tap_plan_impl(int n, const char *format, ...)
43{
44 if (tap_num)
45 return;
46
47#ifdef __MINGW32__
48 // Set the stdout translation mode to binary to prevent printf() from
49 // changing '\n' to '\r\n', as this trips up tap-driver.sh.
50 fflush(stdout);
51 _setmode(1, _O_BINARY);
52#endif
53
54 printf("1..%d", n);
55 if (!n) {
56 printf(" # SKIP");
57 if (format && *format) {
58 fputc(' ', stdout);
59 va_list ap;
60 va_start(ap, format);
61 tap_vprintf(format, ap);
62 va_end(ap);
63 }
64 }
65 fputc('\n', stdout);
66
67#ifdef __MINGW32__
68 // Revert back to text mode, since the problem only occurs when parsing
69 // the test plan.
70 fflush(stdout);
71 _setmode(1, _O_TEXT);
72#endif
73}
74
75int
76tap_test_impl(int test, const char *expr, const char *file, int line,
77 const char *format, ...)
78{
79 assert(expr);
80 assert(file);
81 assert(format);
82
83 printf(test ? "ok %d" : "not ok %d", ++tap_num);
84 if (*format) {
85 fputc(' ', stdout);
86 va_list ap;
87 va_start(ap, format);
88 tap_vprintf(format, ap);
89 va_end(ap);
90 }
91 fputc('\n', stdout);
92
93 if (!test && *expr)
94 printf("# %s:%d: Test `%s' failed.\n", file, line, expr);
95
96 return test;
97}
98
99void
100tap_diag_impl(const char *format, ...)
101{
102 assert(format);
103
104 va_list ap;
105 va_start(ap, format);
106 tap_vprintf(format, ap);
107 va_end(ap);
108 fputc('\n', stdout);
109}
110
111_Noreturn void
112tap_abort_impl(const char *format, ...)
113{
114 assert(format);
115
116 printf("Bail out!");
117 if (*format) {
118 fputc(' ', stdout);
119 va_list ap;
120 va_start(ap, format);
121 tap_vprintf(format, ap);
122 va_end(ap);
123 }
124 fputc('\n', stdout);
125
126 exit(EXIT_FAILURE);
127}
128
129static void
130tap_vprintf(const char *format, va_list ap)
131{
132 assert(format);
133
134 char *s = NULL;
135 int n = vasprintf(&s, format, ap);
136 if (n < 0)
137 return;
138
139 for (char *cp = s; cp < s + n; cp++) {
140 switch (*cp) {
141 case '\r':
142 if (cp + 1 < s + n && cp[1] == '\n')
143 cp++;
144 // ... falls through ...
145 case '\n':
146 fputc('\n', stdout);
147 fputc('#', stdout);
148 fputc(' ', stdout);
149 break;
150 default: fputc(*cp, stdout);
151 }
152 }
153
154 free(s);
155}
#define _Noreturn
A function declared with a _Noreturn function specifier SHALL not return to its caller.
Definition: features.h:214
This is the public header file of the Test Anything Protocol (TAP) library.
This is the internal header file of the Test Anything Protocol (TAP) library.
This header file is part of the C11 and POSIX compatibility library; it includes <stdio....
int vasprintf(char **strp, const char *fmt, va_list ap)
Equivalent to vsprintf(), except that it allocates a string large enough to hold the output,...
Definition: stdio.c:113
This header file is part of the C11 and POSIX compatibility library; it includes <stdlib....
A regular file handle.
Definition: file.c:39