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