1 #include <stdio.h>
2
3 #include <string>
4
5 #include "exceptions.h"
6
7 using std::string;
8
9 static const char *kCaughtNothing = "nothing";
10 static const char *kCaughtGeneric = "generic";
11 static const char *kCaughtBase = "ExceptionBase";
12 static const char *kCaughtA = "ExceptionA";
13 static const char *kCaughtB = "ExceptionB";
14 static const char *kCaughtVirtualBase = "VirtualExceptionBase";
15 static const char *kCaughtVirtualA = "VirtualExceptionA";
16 static const char *kCaughtVirtualB = "VirtualExceptionB";
17 static const char *kCaughtInt = "VirtualInt";
18
19
20 static string
catchBase(void (* function)())21 catchBase(void (*function)())
22 {
23 try {
24 (*function)();
25 } catch (ExceptionBase exception) {
26 return kCaughtBase;
27 } catch (...) {
28 return kCaughtGeneric;
29 }
30 return kCaughtNothing;
31 }
32
33
34 static string
catchA(void (* function)())35 catchA(void (*function)())
36 {
37 try {
38 (*function)();
39 } catch (ExceptionA exception) {
40 return kCaughtA;
41 } catch (...) {
42 return kCaughtGeneric;
43 }
44 return kCaughtNothing;
45 }
46
47
48 static string
catchB(void (* function)())49 catchB(void (*function)())
50 {
51 try {
52 (*function)();
53 } catch (ExceptionB exception) {
54 return kCaughtB;
55 } catch (...) {
56 return kCaughtGeneric;
57 }
58 return kCaughtNothing;
59 }
60
61
62 static string
catchVirtualBase(void (* function)())63 catchVirtualBase(void (*function)())
64 {
65 try {
66 (*function)();
67 } catch (VirtualExceptionBase exception) {
68 return kCaughtVirtualBase;
69 } catch (...) {
70 return kCaughtGeneric;
71 }
72 return kCaughtNothing;
73 }
74
75
76 static string
catchVirtualA(void (* function)())77 catchVirtualA(void (*function)())
78 {
79 try {
80 (*function)();
81 } catch (VirtualExceptionA exception) {
82 return kCaughtVirtualA;
83 } catch (...) {
84 return kCaughtGeneric;
85 }
86 return kCaughtNothing;
87 }
88
89
90 static string
catchVirtualB(void (* function)())91 catchVirtualB(void (*function)())
92 {
93 try {
94 (*function)();
95 } catch (VirtualExceptionB exception) {
96 return kCaughtVirtualB;
97 } catch (...) {
98 return kCaughtGeneric;
99 }
100 return kCaughtNothing;
101 }
102
103
104 static string
catchInt(void (* function)())105 catchInt(void (*function)())
106 {
107 try {
108 (*function)();
109 } catch (int exception) {
110 return kCaughtInt;
111 } catch (...) {
112 return kCaughtGeneric;
113 }
114 return kCaughtNothing;
115 }
116
117 static string
catchAny(void (* function)())118 catchAny(void (*function)())
119 {
120 try {
121 (*function)();
122 } catch (int exception) {
123 return kCaughtInt;
124 } catch (VirtualExceptionA exception) {
125 return kCaughtVirtualA;
126 } catch (VirtualExceptionB exception) {
127 return kCaughtVirtualB;
128 } catch (VirtualExceptionBase exception) {
129 return kCaughtVirtualBase;
130 } catch (ExceptionA exception) {
131 return kCaughtA;
132 } catch (ExceptionB exception) {
133 return kCaughtB;
134 } catch (ExceptionBase exception) {
135 return kCaughtBase;
136 } catch (...) {
137 return kCaughtGeneric;
138 }
139 return kCaughtNothing;
140 }
141
142 static void
test(string (* catcher)(void (*)()),void (* thrower)(),const char * expected)143 test(string (*catcher)(void (*)()), void (*thrower)(), const char *expected)
144 {
145 string caught((*catcher)(thrower));
146 if (caught != expected) {
147 printf("ERROR: expected exception: %s, but caught: %s\n", expected,
148 caught.c_str());
149 }
150 }
151
152 int
main()153 main()
154 {
155 test(catchBase, throwBase, kCaughtBase);
156 test(catchBase, throwA, kCaughtBase);
157 test(catchBase, throwB, kCaughtBase);
158 test(catchBase, throwVirtualBase, kCaughtBase);
159 test(catchBase, throwVirtualA, kCaughtBase);
160 test(catchBase, throwVirtualB, kCaughtBase);
161 test(catchBase, throwInt, kCaughtGeneric);
162
163 test(catchA, throwBase, kCaughtGeneric);
164 test(catchA, throwA, kCaughtA);
165 test(catchA, throwB, kCaughtGeneric);
166 test(catchA, throwVirtualBase, kCaughtGeneric);
167 test(catchA, throwVirtualA, kCaughtGeneric);
168 test(catchA, throwVirtualB, kCaughtGeneric);
169 test(catchA, throwInt, kCaughtGeneric);
170
171 test(catchVirtualBase, throwBase, kCaughtGeneric);
172 test(catchVirtualBase, throwA, kCaughtGeneric);
173 test(catchVirtualBase, throwB, kCaughtGeneric);
174 test(catchVirtualBase, throwVirtualBase, kCaughtVirtualBase);
175 test(catchVirtualBase, throwVirtualA, kCaughtVirtualBase);
176 test(catchVirtualBase, throwVirtualB, kCaughtVirtualBase);
177 test(catchVirtualBase, throwInt, kCaughtGeneric);
178
179 test(catchVirtualA, throwBase, kCaughtGeneric);
180 test(catchVirtualA, throwA, kCaughtGeneric);
181 test(catchVirtualA, throwB, kCaughtGeneric);
182 test(catchVirtualA, throwVirtualBase, kCaughtGeneric);
183 test(catchVirtualA, throwVirtualA, kCaughtVirtualA);
184 test(catchVirtualA, throwVirtualB, kCaughtGeneric);
185 test(catchVirtualA, throwInt, kCaughtGeneric);
186
187 test(catchInt, throwBase, kCaughtGeneric);
188 test(catchInt, throwA, kCaughtGeneric);
189 test(catchInt, throwB, kCaughtGeneric);
190 test(catchInt, throwVirtualBase, kCaughtGeneric);
191 test(catchInt, throwVirtualA, kCaughtGeneric);
192 test(catchInt, throwVirtualB, kCaughtGeneric);
193 test(catchInt, throwInt, kCaughtInt);
194
195 test(catchAny, throwBase, kCaughtBase);
196 test(catchAny, throwA, kCaughtA);
197 test(catchAny, throwB, kCaughtB);
198 test(catchAny, throwVirtualBase, kCaughtVirtualBase);
199 test(catchAny, throwVirtualA, kCaughtVirtualA);
200 test(catchAny, throwVirtualB, kCaughtVirtualB);
201 test(catchAny, throwInt, kCaughtInt);
202
203 return 0;
204 }
205