Lely core libraries  2.2.5
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 
37 static int tap_num;
38 
39 static void tap_vprintf(const char *format, va_list ap);
40 
41 void
42 tap_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 
75 int
76 tap_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 
99 void
100 tap_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
112 tap_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 
129 static void
130 tap_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