1 /* Standalone program to test functionality of exceptions.
2 *
3 * Copyright (c) 2004 MX Telecom Ltd. <richardv@mxtelecom.com>
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 *
7 */
8
9 #include <config.h>
10
11 #include <stdio.h>
12 #include <glib.h>
13 #include "exceptions.h"
14
15 gboolean failed = FALSE;
16
17 static void
finally_called_uncaught_exception(volatile unsigned int * called)18 finally_called_uncaught_exception(volatile unsigned int* called)
19 {
20 TRY {
21 THROW(BoundsError);
22 }
23 FINALLY {
24 (*called)++;
25 }
26 ENDTRY;
27 }
28
29 static void
finally_called_rethrown_exception(volatile unsigned int * thrown,volatile unsigned int * called)30 finally_called_rethrown_exception(volatile unsigned int* thrown, volatile unsigned int* called)
31 {
32 TRY {
33 THROW(BoundsError);
34 }
35 CATCH_ALL {
36 (*thrown) += 10;
37 RETHROW;
38 }
39 FINALLY {
40 (*called) += 10;
41 }
42 ENDTRY;
43 }
44
45 static void
finally_called_exception_from_catch(volatile unsigned int * thrown,volatile unsigned int * called)46 finally_called_exception_from_catch(volatile unsigned int* thrown, volatile unsigned int* called)
47 {
48 TRY {
49 THROW(BoundsError);
50 }
51 CATCH_ALL {
52 if((*thrown) > 0) {
53 printf("05: Looping exception\n");
54 failed = TRUE;
55 } else {
56 (*thrown) += 10;
57 THROW(BoundsError);
58 }
59 }
60 FINALLY {
61 (*called) += 10;
62 }
63 ENDTRY;
64 }
65
66 static void
run_tests(void)67 run_tests(void)
68 {
69 volatile unsigned int ex_thrown, finally_called;
70
71 /* check that the right catch, and the finally, are called, on exception */
72 ex_thrown = finally_called = 0;
73 TRY {
74 THROW(BoundsError);
75 }
76 CATCH(BoundsError) {
77 ex_thrown++;
78 }
79 CATCH(FragmentBoundsError) {
80 printf("01: Caught wrong exception: FragmentBoundsError\n");
81 failed = TRUE;
82 }
83 CATCH(ReportedBoundsError) {
84 printf("01: Caught wrong exception: ReportedBoundsError\n");
85 failed = TRUE;
86 }
87 CATCH_ALL {
88 printf("01: Caught wrong exception: %lu\n", exc->except_id.except_code);
89 failed = TRUE;
90 }
91 FINALLY {
92 finally_called ++;
93 }
94 ENDTRY;
95
96 if (ex_thrown != 1) {
97 printf("01: %u BoundsErrors (not 1) on caught exception\n", ex_thrown);
98 failed = TRUE;
99 }
100
101 if (finally_called != 1) {
102 printf("01: FINALLY called %u times (not 1) on caught exception\n", finally_called);
103 failed = TRUE;
104 }
105
106
107 /* check that no catch at all is called when there is no exn */
108 ex_thrown = finally_called = 0;
109 TRY {
110 }
111 CATCH(BoundsError) {
112 printf("02: Caught wrong exception: BoundsError\n");
113 failed = TRUE;
114 }
115 CATCH(FragmentBoundsError) {
116 printf("02: Caught wrong exception: FragmentBoundsError\n");
117 failed = TRUE;
118 }
119 CATCH(ReportedBoundsError) {
120 printf("02: Caught wrong exception: ReportedBoundsError\n");
121 failed = TRUE;
122 }
123 CATCH_ALL {
124 printf("02: Caught wrong exception: %lu\n", exc->except_id.except_code);
125 failed = TRUE;
126 }
127 FINALLY {
128 finally_called ++;
129 }
130 ENDTRY;
131
132 if (finally_called != 1) {
133 printf("02: FINALLY called %u times (not 1) on no exception\n", finally_called);
134 failed = TRUE;
135 }
136
137 /* check that finally is called on an uncaught exception */
138 ex_thrown = finally_called = 0;
139 TRY {
140 finally_called_uncaught_exception(&finally_called);
141 }
142 CATCH(BoundsError) {
143 ex_thrown++;
144 }
145 ENDTRY;
146
147 if (finally_called != 1) {
148 printf("03: FINALLY called %u times (not 1) on uncaught exception\n", finally_called);
149 failed = TRUE;
150 }
151
152 if (ex_thrown != 1) {
153 printf("03: %u BoundsErrors (not 1) on uncaught exception\n", ex_thrown);
154 failed = TRUE;
155 }
156
157
158 /* check that finally is called on an rethrown exception */
159 ex_thrown = finally_called = 0;
160 TRY {
161 finally_called_rethrown_exception(&ex_thrown, &finally_called);
162 }
163 CATCH(BoundsError) {
164 ex_thrown ++;
165 }
166 FINALLY {
167 finally_called ++;
168 }
169 ENDTRY;
170
171 if (finally_called != 11) {
172 printf("04: finally_called = %u (not 11) on rethrown exception\n", finally_called);
173 failed = TRUE;
174 }
175
176 if (ex_thrown != 11) {
177 printf("04: %u BoundsErrors (not 11) on rethrown exception\n", ex_thrown);
178 failed = TRUE;
179 }
180
181
182 /* check that finally is called on an exception thrown from a CATCH block */
183 ex_thrown = finally_called = 0;
184 TRY {
185 finally_called_exception_from_catch(&ex_thrown, &finally_called);
186 }
187 CATCH(BoundsError) {
188 ex_thrown ++;
189 }
190 FINALLY {
191 finally_called ++;
192 }
193 ENDTRY;
194
195 if (finally_called != 11) {
196 printf("05: finally_called = %u (not 11) on exception thrown from CATCH\n", finally_called);
197 failed = TRUE;
198 }
199
200 if (ex_thrown != 11) {
201 printf("05: %u BoundsErrors (not 11) on exception thrown from CATCH\n", ex_thrown);
202 failed = TRUE;
203 }
204
205 if(failed == FALSE )
206 printf("success\n");
207 }
208
main(void)209 int main(void)
210 {
211 except_init();
212 run_tests();
213 except_deinit();
214 exit(failed?1:0);
215 }
216
217 /*
218 * Editor modelines - https://www.wireshark.org/tools/modelines.html
219 *
220 * Local variables:
221 * c-basic-offset: 4
222 * tab-width: 8
223 * indent-tabs-mode: nil
224 * End:
225 *
226 * vi: set shiftwidth=4 tabstop=8 expandtab:
227 * :indentSize=4:tabSize=8:noTabs=true:
228 */
229