1 #include "xxl.h"
2
3 #include <stdlib.h>
4
5 #define FAIL(why) \
6 do { \
7 fprintf(stderr, "%s\n", (why)); \
8 exit(1); \
9 } while (0)
10
11 typedef struct {
12 int cleaned;
13 } test_asset_t;
14
15 static void
cleanup_test_asset(void * asset,void * arg)16 cleanup_test_asset(void *asset, void *arg)
17 {
18 ((test_asset_t *)asset)->cleaned = 1;
19 }
20
21 static void
test_catch(void)22 test_catch(void)
23 {
24 int caught, pass;
25
26 for (pass = 0; pass < 3; pass++)
27 {
28 XXL_TRY_BEGIN {
29 caught = 0;
30 switch (pass)
31 {
32 case 0: XXL_THROW_ERROR(0x42174217, NULL);
33 case 1: XXL_THROW_ERROR(0x17421742, NULL);
34 case 2: break;
35 }
36 }
37 XXL_CATCH(0x42174217) { caught = 1; }
38 XXL_EXCEPT { caught = 2; }
39 XXL_TRY_END;
40
41 switch (pass)
42 {
43 case 0:
44 if (caught == 0) FAIL("Did not catch exception 0x42174217\n");
45 if (caught == 2) FAIL("Caught 0x42174217 as 0x17421742\n");
46 if (caught != 1) FAIL("(catch pass 0) 'caught' is totally wrong!\n");
47 break;
48 case 1:
49 if (caught == 0) FAIL("Did not catch exception 0x17421742\n");
50 if (caught == 1) FAIL("Caught 0x17421742 as 0x42174217\n");
51 if (caught != 2) FAIL("(catch pass 1) 'caught' is totally wrong!\n");
52
53 break;
54 default:
55 if (caught != 0) FAIL("Exception caught when none thrown\n");
56 break;
57 }
58 }
59 }
60
61 static void
test_finally(void)62 test_finally(void)
63 {
64 int caught, finally, pass;
65
66 for (pass = 0; pass < 3; pass++)
67 {
68 XXL_TRY_BEGIN
69 {
70 caught = finally = 0;
71 switch (pass)
72 {
73 case 0: break;
74 case 1: XXL_THROW_ERROR(0x42174217, NULL);
75 case 2: XXL_THROW_ERROR(0x17421742, NULL);
76 }
77 }
78 XXL_CATCH(0x42174217) { caught = 1; }
79 XXL_EXCEPT { caught = 2; }
80 XXL_FINALLY { finally = 1; }
81 XXL_TRY_END;
82
83 switch (pass)
84 {
85 case 0:
86 if (caught == 1) FAIL("Caught 0x42174217 when none thrown with finally\n");
87 if (caught == 2) FAIL("Caught 0x17421742 when none thrown with finally\n");
88 if (caught != 0) FAIL("(finally pass 0) 'caught' is totally wrong!\n");
89 if (!finally) FAIL("Finally failed to run when no exception thrown\n");
90 break;
91 case 1:
92 if (caught == 0) FAIL("Did not catch exception 0x42174217 with finally\n");
93 if (caught == 2) FAIL("Caught 0x42174217 as 0x17421742 with finally\n");
94 if (caught != 1) FAIL("(finally pass 1) 'caught' is totally wrong!\n");
95 if (!finally) FAIL("Finally failed to run when specific exception caught\n");
96 break;
97 case 2:
98 if (caught == 0) FAIL("Did not catch exception 0x17421742 with finally\n");
99 if (caught == 1) FAIL("Caught 0x17421742 as 0x42174217 with finally\n");
100 if (caught != 2) FAIL("(finally pass 2) 'caught' is totally wrong!\n");
101 if (!finally) FAIL("Finally failed to run when non-specific exception caught\n");
102 break;
103 }
104 }
105 }
106
107 static void
test_assets(void)108 test_assets(void)
109 {
110 int pass;
111 test_asset_t asset;
112 xxl_assettype_t type;
113
114 for (pass = 0; pass < 8; pass++)
115 {
116 XXL_TRY_BEGIN
117 {
118 asset.cleaned = 0;
119 switch (pass)
120 {
121 case 0: case 4: type = XXL_ASSET_PERMANENT; break;
122 case 1: case 5: type = XXL_ASSET_TEMPORARY; break;
123 case 2: case 6: type = XXL_ASSET_PROMOTE; break;
124 case 3: case 7: type = XXL_ASSET_DEMOTE; break;
125 }
126 XXL_ASSET_SAVE(&asset, cleanup_test_asset, NULL, type);
127 if (pass > 3) XXL_THROW_ERROR(0x42174217, NULL);
128 }
129 XXL_EXCEPT {}
130 XXL_TRY_END;
131
132 switch (pass)
133 {
134 case 0:
135 if (asset.cleaned)
136 FAIL("PERMANENT asset cleaned; no exception thrown\n");
137 break;
138 case 1:
139 if (!asset.cleaned)
140 FAIL("TEMPORARY asset NOT cleaned; no exception thrown\n");
141 break;
142 case 2:
143 if (asset.cleaned)
144 FAIL("PROMOTE asset cleaned; no exception thrown\n");
145 break;
146 case 3:
147 if (!asset.cleaned)
148 FAIL("DEMOTE asset NOT cleaned; no exception thrown\n");
149 break;
150 case 4:
151 if (asset.cleaned)
152 FAIL("PERMANENT asset cleaned; exception thrown\n");
153 break;
154 case 5:
155 if (!asset.cleaned)
156 FAIL("TEMPORARY asset NOT cleaned; exception thrown\n");
157 break;
158 case 6:
159 if (!asset.cleaned)
160 FAIL("PROMOTE asset NOT cleaned; exception thrown\n");
161 break;
162 case 7:
163 if (asset.cleaned)
164 FAIL("DEMOTE asset cleaned; exception thrown\n");
165 break;
166 }
167 }
168 }
169
170 static void
test_nested(void)171 test_nested(void)
172 {
173 int caught, inner_finally, outer_finally, pass;
174
175 for (pass = 0; pass < 2; pass++)
176 {
177 XXL_TRY_BEGIN
178 {
179 caught = inner_finally = outer_finally = 0;
180 XXL_TRY_BEGIN
181 {
182 switch (pass)
183 {
184 case 0: XXL_THROW_ERROR(0x42174217, NULL);
185 case 1: XXL_THROW_ERROR(0x17421742, NULL);
186 }
187 }
188 XXL_CATCH(0x42174217) { XXL_RETHROW_ERROR(); }
189 XXL_FINALLY { inner_finally = 1; }
190 XXL_TRY_END;
191 }
192 XXL_CATCH(0x42174217) { caught = 1; }
193 XXL_CATCH(0x17421742) { caught = 2; }
194 XXL_FINALLY { outer_finally = 1; }
195 XXL_TRY_END;
196
197 switch (pass)
198 {
199 case 0:
200 if (caught == 0) FAIL("Outer try did not catch 0x42174217\n");
201 if (caught == 2) FAIL("Outer try caught 0x42174217 as 0x17421742\n");
202 if (caught != 1) FAIL("(nested pass 0) 'caught' is totally wrong!\n");
203 if (!inner_finally) FAIL("(nested pass 0) Inner finally block did not run\n");
204 if (!outer_finally) FAIL("(nested pass 0) Outer finally block did not run\n");
205 break;
206 case 1:
207 if (caught == 0) FAIL("Outer try did not catch 0x17421742\n");
208 if (caught == 1) FAIL("Outer try caught 0x17421742 as 0x42174217\n");
209 if (caught != 2) FAIL("(nested pass 1) 'caught' is totally wrong!\n");
210 if (!inner_finally) FAIL("(nested pass 1) Inner finally block did not run\n");
211 if (!outer_finally) FAIL("(nested pass 1) Outer finally block did not run\n");
212 break;
213 }
214 }
215 }
216
main(int argc,char * agrv[])217 int main(int argc, char *agrv[])
218 {
219 printf("Testing simple exception catching ...\n");
220 test_catch();
221
222 printf("Testing simple finally block execution ...\n");
223 test_finally();
224
225 printf("Testing simple asset management ...\n");
226 test_assets();
227
228 printf("Testing nested exception handling ...\n");
229 test_nested();
230
231 exit(0);
232 return 0;
233 }
234