Add half-hearted support for Clang, because its `blocks' are deficient.
[finally] / test-guts.c
CommitLineData
d58b8198
MW
1/* -*-c-*-
2 *
3 * Main test machinery
4 *
5 * (c) 2023 Mark Wooding
6 */
7
8/*----- Licensing notice --------------------------------------------------*
9 *
10 * This file is part of the `Finally' package.
11 *
12 * Finally is free software: you can redistribute it and/or modify it
13 * under the terms of the GNU Library General Public License as published
14 * by the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * Finally is distributed in the hope that it will be useful, but WITHOUT
18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
20 * License for more details.
21 *
22 * You should have received a copy of the GNU Library General Public
23 * License along with Finally. If not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
25 * USA.
26 */
27
28/*----- Header files ------------------------------------------------------*/
29
30#include <stdio.h>
31#include <stdlib.h>
32#include <string.h>
33
34#include "finally-test.h"
35
36/*----- Global variables --------------------------------------------------*/
37
38const int secretly_true = 1;
39
40/*----- Static variables --------------------------------------------------*/
41
42static const char *curr;
43static unsigned nrun = 0, nskip = 0, nlose = 0;
44static unsigned flags = 0;
45enum { HUMAN, TAP }; static unsigned outform = HUMAN;
46#define f_failthis 1u
47
48static int step;
49
50/*----- Main code ---------------------------------------------------------*/
51
52void init_test(void)
53{
54 const char *p;
55
56 p = getenv("TEST_OUTFORM");
57 if (!p || strcmp(p, "human") == 0) outform = HUMAN;
58 else if (strcmp(p, "tap") == 0) outform = TAP;
59 else { fprintf(stderr, "unknown output format `%s'\n", p); exit(2); }
60}
61
62void begin_test(const char *name)
63 { step = 0; flags &= ~f_failthis; curr = name; }
64
65void check_step(int s, const char *where)
66{
67 FILE *fp;
68
69 if (step != s) {
70 switch (outform) {
71 case HUMAN: fp = stderr; break;
72 case TAP: fp = stdout; fputs("# ", stdout); break;
73 default: abort();
74 }
75 fprintf(fp, "%s (%s): misstep: expected %d but found %d\n",
76 where, curr, step, s);
77 flags |= f_failthis;
78 }
79 step++;
80}
81
82void end_test(void)
83{
84 nrun++; if (flags&f_failthis) nlose++;
85
86 switch (outform) {
87 case HUMAN:
88 printf("%s: %s\n", curr, flags&f_failthis ? "FAILED" : "ok");
89 break;
90 case TAP:
91 printf("%s %u %s\n", flags&f_failthis ? "not ok" : "ok", nrun, curr);
92 break;
93 default:
94 abort();
95 }
96}
97
98void skip_test(const char *name, const char *excuse)
99{
100 nrun++; nskip++;
101
102 switch (outform) {
103 case HUMAN: printf("%s: (skipped: %s)\n", name, excuse); break;
104 case TAP: printf("ok %u %s # skip (%s)\n", nrun, name, excuse); break;
105 default: abort();
106 }
107}
108
109int test_report(void)
110{
111#define TESTS(n) ((n) == 1 ? "test" : "tests")
112
113 switch (outform) {
114 case HUMAN:
115 if (nlose)
116 printf("FAILED %u out of %u %s", nlose, nrun, TESTS(nrun));
117 else if (nskip)
118 printf("passed %u out of %u %s",
119 nrun - nlose - nskip, nrun, TESTS(nrun));
120 else
121 printf("passed all %u %s", nrun, TESTS(nrun));
122 if (nskip) printf(" (skipped %u %s)", nskip, TESTS(nskip));
123 putchar('\n');
124 return (nlose ? 2 : 0);
125 case TAP:
126 printf("1..%u\n", nrun);
127 return (0);
128 default:
129 abort();
130 }
131
132#undef TESTS
133}
134
135/*----- That's all, folks -------------------------------------------------*/