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 }
file
A regular file handle.
Definition: file.c:43
_Noreturn
#define _Noreturn
A function declared with a _Noreturn function specifier SHALL not return to its caller.
Definition: features.h:224
vasprintf
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
stdio.h
stdlib.h
tap.h