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 }
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 is the public header file of the Test Anything Protocol (TAP) library.
This header file is part of the C11 and POSIX compatibility library; it includes <stdio.h> and defines any missing functionality.
This header file is part of the C11 and POSIX compatibility library; it includes <stdlib.h> and defines any missing functionality.
#define _Noreturn
A function declared with a _Noreturn function specifier SHALL not return to its caller.
Definition: features.h:214
A regular file handle.
Definition: file.c:39