1 | // Draft of tests for exception handling.
|
---|
2 | // Outdated: The integer constant exceptions need to be replaced with virtual
|
---|
3 | // exceptions for the new system.
|
---|
4 |
|
---|
5 | // ERROR: exceptions do not interact with ^?{} properly.
|
---|
6 |
|
---|
7 | #include <stdio.h>
|
---|
8 | #include <stdbool.h>
|
---|
9 |
|
---|
10 | #include "except-mac.h"
|
---|
11 | TRIVIAL_EXCEPTION(yin)
|
---|
12 | TRIVIAL_EXCEPTION(yang)
|
---|
13 | TRIVIAL_EXCEPTION(zen)
|
---|
14 |
|
---|
15 |
|
---|
16 | // Local type to mark exits from scopes. (see ERROR)
|
---|
17 | struct signal_exit {
|
---|
18 | const char * area;
|
---|
19 | };
|
---|
20 |
|
---|
21 | void ?{}(signal_exit * this, const char * area) {
|
---|
22 | this->area = area;
|
---|
23 | }
|
---|
24 |
|
---|
25 | void ^?{}(signal_exit * this) {
|
---|
26 | printf("Exiting: %s\n", this->area);
|
---|
27 | // sout | "Exiting:" | this->area | endl;
|
---|
28 | }
|
---|
29 |
|
---|
30 |
|
---|
31 | // Mark throws: make sure to only pass in exception types.
|
---|
32 | forall(dtype T)
|
---|
33 | void terminate(T * except_value) {
|
---|
34 | signal_exit a = {"terminate function"};
|
---|
35 | THROW(except_value);
|
---|
36 | printf("terminate returned\n");
|
---|
37 | }
|
---|
38 |
|
---|
39 | forall(dtype T)
|
---|
40 | void resume(T * except_value) {
|
---|
41 | signal_exit a = {"resume function"};
|
---|
42 | THROW_RESUME(except_value);
|
---|
43 | printf("resume returned\n");
|
---|
44 | }
|
---|
45 |
|
---|
46 | // Termination Test: Two handlers: no catch, catch
|
---|
47 | void bar() {
|
---|
48 | signal_exit a = {"bar function"};
|
---|
49 | try {
|
---|
50 | terminate(&(zen){});
|
---|
51 | } catch (yin * error) {
|
---|
52 | printf("bar caught exception yin.\n");
|
---|
53 | }
|
---|
54 | }
|
---|
55 |
|
---|
56 | void foo() {
|
---|
57 | signal_exit a = {"foo function"};
|
---|
58 | try {
|
---|
59 | bar();
|
---|
60 | } catch (yang * error) {
|
---|
61 | printf("foo caught exception yang.\n");
|
---|
62 | } catch (zen * error) {
|
---|
63 | printf("foo caught exception zen.\n");
|
---|
64 | }
|
---|
65 | }
|
---|
66 |
|
---|
67 | // Resumption Two Handler Test: no catch, catch.
|
---|
68 | void beta() {
|
---|
69 | signal_exit a = {"beta function"};
|
---|
70 | try {
|
---|
71 | zen x;
|
---|
72 | resume(&x);
|
---|
73 | } catchResume (yin * error) {
|
---|
74 | printf("beta caught exception yin\n");
|
---|
75 | }
|
---|
76 | }
|
---|
77 |
|
---|
78 | void alpha() {
|
---|
79 | signal_exit a = {"alpha function"};
|
---|
80 | try {
|
---|
81 | beta();
|
---|
82 | } catchResume (yang * error) {
|
---|
83 | printf("alpha caught exception yang\n");
|
---|
84 | } catchResume (zen * error) {
|
---|
85 | printf("alpha caught exception zen\n");
|
---|
86 | }
|
---|
87 | }
|
---|
88 |
|
---|
89 | // Finally Test:
|
---|
90 | void farewell(bool jump) {
|
---|
91 | try {
|
---|
92 | if (jump) {
|
---|
93 | printf("jump out of farewell\n");
|
---|
94 | goto endoffunction;
|
---|
95 | } else {
|
---|
96 | printf("walk out of farewell\n");
|
---|
97 | }
|
---|
98 | } finally {
|
---|
99 | printf("See you next time\n");
|
---|
100 | }
|
---|
101 | endoffunction:
|
---|
102 | printf("leaving farewell\n");
|
---|
103 | }
|
---|
104 |
|
---|
105 | // Resume-to-Terminate Test:
|
---|
106 | void fallback() {
|
---|
107 | try {
|
---|
108 | zen x;
|
---|
109 | resume(&x);
|
---|
110 | } catch (zen * error) {
|
---|
111 | printf("fallback caught termination zen\n");
|
---|
112 | }
|
---|
113 | }
|
---|
114 |
|
---|
115 | // Terminate Throw New Exception:
|
---|
116 | void terminate_swap() {
|
---|
117 | signal_exit a = {"terminate_swap"};
|
---|
118 | try {
|
---|
119 | yin x;
|
---|
120 | terminate(&x);
|
---|
121 | } catch (yin * error) {
|
---|
122 | yang y;
|
---|
123 | terminate(&y);
|
---|
124 | }
|
---|
125 | }
|
---|
126 |
|
---|
127 | void terminate_swapped() {
|
---|
128 | signal_exit a = {"terminate_swapped"};
|
---|
129 | try {
|
---|
130 | terminate_swap();
|
---|
131 | } catch (yang * error) {
|
---|
132 | printf("terminate_swapped caught exception yang\n");
|
---|
133 | }
|
---|
134 | }
|
---|
135 |
|
---|
136 | // Resume Throw New Exception:
|
---|
137 | void resume_swap() {
|
---|
138 | signal_exit a = {"resume_swap"};
|
---|
139 | try {
|
---|
140 | yin x;
|
---|
141 | resume(&x);
|
---|
142 | } catchResume (yin * error) {
|
---|
143 | yang y;
|
---|
144 | resume(&y);
|
---|
145 | }
|
---|
146 | }
|
---|
147 |
|
---|
148 | void resume_swapped() {
|
---|
149 | try {
|
---|
150 | resume_swap();
|
---|
151 | } catchResume (yang * error) {
|
---|
152 | printf("resume_swapped caught exception yang\n");
|
---|
153 | }
|
---|
154 | }
|
---|
155 |
|
---|
156 | // Terminate Rethrow:
|
---|
157 | void reterminate() {
|
---|
158 | try {
|
---|
159 | try {
|
---|
160 | zen x;
|
---|
161 | terminate(&x);
|
---|
162 | } catch (zen * error) {
|
---|
163 | printf("reterminate zen caught and "
|
---|
164 | "will rethrow exception zen\n");
|
---|
165 | throw;
|
---|
166 | }
|
---|
167 | } catch (zen * error) {
|
---|
168 | printf("reterminate 1 caught exception zen\n");
|
---|
169 | }
|
---|
170 | }
|
---|
171 |
|
---|
172 | // Resume Rethrow:
|
---|
173 | void reresume() {
|
---|
174 | try {
|
---|
175 | try {
|
---|
176 | zen x;
|
---|
177 | resume(&x);
|
---|
178 | } catchResume (zen * error) {
|
---|
179 | printf("reresume zen caught and rethrows exception zen\n");
|
---|
180 | throwResume;
|
---|
181 | }
|
---|
182 | } catchResume (zen * error) {
|
---|
183 | printf("reresume 1 caught exception zen\n");
|
---|
184 | }
|
---|
185 | }
|
---|
186 |
|
---|
187 | // Terminate-Resume interaction:
|
---|
188 | void fum() {
|
---|
189 | // terminate block, call resume
|
---|
190 | try {
|
---|
191 | zen x;
|
---|
192 | resume(&x);
|
---|
193 | } catch (zen * error) {
|
---|
194 | printf("fum caught exception zen\n");
|
---|
195 | }
|
---|
196 | }
|
---|
197 |
|
---|
198 | void foe() {
|
---|
199 | // resume block, call terminate
|
---|
200 | try {
|
---|
201 | zen y;
|
---|
202 | terminate(&y);
|
---|
203 | } catchResume (zen * error) {
|
---|
204 | printf("foe caught exception zen\n");
|
---|
205 | }
|
---|
206 | }
|
---|
207 |
|
---|
208 | void fy() {
|
---|
209 | // terminate block calls fum, call foe
|
---|
210 | try {
|
---|
211 | foe();
|
---|
212 | } catch (zen * error) {
|
---|
213 | printf("fy caught exception zen\n");
|
---|
214 | fum();
|
---|
215 | }
|
---|
216 | }
|
---|
217 |
|
---|
218 | void fee() {
|
---|
219 | // resume block, call fy
|
---|
220 | try {
|
---|
221 | fy();
|
---|
222 | } catchResume (zen * error) {
|
---|
223 | printf("fee caught exception zen\n");
|
---|
224 | }
|
---|
225 | }
|
---|
226 |
|
---|
227 |
|
---|
228 | // main: choose which tests to run
|
---|
229 | int main(int argc, char * argv[]) {
|
---|
230 | signal_exit a = {"main function"};
|
---|
231 |
|
---|
232 | foo(); printf("\n");
|
---|
233 | alpha(); printf("\n");
|
---|
234 | farewell(false); printf("\n");
|
---|
235 | farewell(true); printf("\n");
|
---|
236 | fallback(); printf("\n");
|
---|
237 | terminate_swapped(); printf("\n");
|
---|
238 | resume_swapped(); printf("\n");
|
---|
239 | reterminate(); printf("\n");
|
---|
240 | reresume(); printf("\n");
|
---|
241 | fee(); printf("\n");
|
---|
242 |
|
---|
243 | // Uncaught termination test.
|
---|
244 | printf("Throw uncaught.\n");
|
---|
245 | yang z;
|
---|
246 | terminate(&z);
|
---|
247 | }
|
---|