chiark / gitweb /
Add half-hearted support for Clang, because its `blocks' are deficient.
[finally] / finally-test.c
1 /* -*-c-*-
2  *
3  * Test program for using `finally.h'
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 /* Attention!
29  *
30  * This file is also compiled as C++, so we must be careful to keep it in the
31  * common subset of C and C++.  Anything language-specific needs to be split
32  * off into its own separate source file.
33  */
34
35 /*----- Header files ------------------------------------------------------*/
36
37 #include <stdio.h>
38
39 #define FINALLY_TOLERATE_BUG_CAPTURE_COPIES 1
40 #include "finally.h"
41 #include "finally-test.h"
42
43 /*----- Main code ---------------------------------------------------------*/
44
45 static int test_softball(void)
46 {
47   FINALLY({ STEP(1); });
48
49   STEP(0);
50   return (2);
51 }
52
53 static int test_ordering(void)
54 {
55   FINALLY({ STEP(2); });
56   FINALLY({ STEP(1); });
57
58   STEP(0);
59
60   return (3);
61 }
62
63 #ifndef FINALLY_BUG_CAPTURE_COPIES
64 static int test_capture(void)
65 {
66   int n = -1; FINALLY({ STEP(n); });
67
68   STEP(0);
69   n = 1; return (2);
70 }
71 #endif
72
73 static int test_internal_block(void)
74 {
75   int i;
76   FINALLY({ STEP(10); });
77
78   for (i = 0; i < 5; i++) {
79     FINALLY({ STEP(2*i + 1); });
80     STEP(2*i);
81   }
82   return (11);
83 }
84
85 static int test_local_xfer(void)
86 {
87   int i, j;
88
89   STEP(0);
90
91   { FINALLY({ STEP(2); }); STEP(1); }
92
93   do {
94     FINALLY({ STEP(4); });
95     STEP(3);
96     if (secretly_true) break;
97     MISSTEP;
98   } while (0);
99
100   for (i = 0; i < 5; i++) {
101     FINALLY({
102       if (i == 3) STEP(46);
103       else STEP(12*i + 16);
104     });
105     STEP(12*i + 5);
106     for (j = 0; j < 5; j++) {
107       FINALLY({ STEP(12*i + 2*j + 7); });
108       if (i == 3 && j == 1) { STEP(44); goto escape; }
109       else if (j != 3) STEP(12*i + 2*j + 6);
110       else { FINALLY({ STEP(12*i + 2*j + 6); }); continue; }
111     }
112   }
113 escape:
114   STEP(47);
115
116   return (48);
117 }
118
119 #if defined(HAVE_FEXCEPTIONS)
120 void try_catch_filling(unsigned f)
121 {
122   int outstep = f&TCF_THROW ? 12 : 5; FINALLY({ STEP(outstep); });
123
124   if (f&TCF_THROW) STEP(10);
125   else STEP(2);
126
127   try_catch_inner(f);
128   STEP(4);
129 }
130
131 static int test_try_catch(void)
132 {
133   STEP(0);
134   try_catch_outer(0);
135   STEP(8);
136   try_catch_outer(TCF_THROW);
137   return (15);
138 }
139 #endif
140
141 int main(void)
142 {
143   init_test();
144
145 #define RUNTEST(name)                                                   \
146         do { begin_test(#name); STEP(test_##name()); end_test(); } while (0)
147 #define SKIPTEST(name, excuse) skip_test(#name, excuse)
148
149   RUNTEST(softball);
150   RUNTEST(ordering);
151   RUNTEST(local_xfer);
152 #ifndef FINALLY_BUG_CAPTURE_COPIES
153   RUNTEST(capture);
154 #else
155   SKIPTEST(capture, "selected flavour captures copies");
156 #endif
157   RUNTEST(internal_block);
158 #if defined(HAVE_FEXCEPTIONS)
159   RUNTEST(try_catch);
160 #else
161   SKIPTEST(try_catch, "no C++ compiler or no exception-handling support");
162 #endif
163
164 #undef RUNTEST
165 #undef SKIPTEST
166
167   return (test_report());
168 }
169
170 /*----- That's all, folks -------------------------------------------------*/