source: tests/exceptions/defaults.cfa @ a4e1b09

Last change on this file since a4e1b09 was 3bf9d10, checked in by Peter A. Buhr <pabuhr@…>, 17 months ago

change printf to sout

  • Property mode set to 100644
File size: 2.4 KB
Line 
1// Tests for providing new default operations.
2
3#include <fstream.hfa>
4#include <string.h>
5
6exception log_message {
7        char * msg;
8};
9
10// Manually define the virtual table and helper functions.
11void copy(log_message * this, log_message * that) {
12        *this = *that;
13}
14
15const char * msg(log_message * this) {
16        return this->msg;
17}
18
19const struct log_message_vtable log_vt @= {
20        .__cfavir_typeid : &__cfatid_log_message,
21        .size : sizeof(struct log_message),
22        .copy : copy,
23        .^?{} : ^?{},
24        .msg : msg,
25};
26
27// Logging messages don't have to be handled.
28void defaultResumptionHandler(log_message &) {}
29
30// And should never be used to terminate computation.
31void defaultTerminationHandler(log_message &) = void;
32
33void log_test(void) {
34        // We can catch log:
35        try {
36                throwResume (log_message){&log_vt, "Should be printed.\n"};
37        } catchResume (log_message * this) {
38                sout | this->virtual_table->msg(this) | nonl;
39        }
40        // But we don't have to:
41        throwResume (log_message){&log_vt, "Should not be printed.\n"};
42}
43
44// I don't have a good use case for doing the same with termination.
45exception jump {};
46void defaultTerminationHandler(jump &) {
47        sout | "jump default handler.";
48}
49
50vtable(jump) jump_vt;
51
52void jump_test(void) {
53        try {
54                throw (jump){&jump_vt};
55        } catch (jump * this) {
56                sout | "jump catch handler.";
57        }
58        throw (jump){&jump_vt};
59}
60
61exception first {};
62vtable(first) first_vt;
63
64exception unhandled_exception {};
65vtable(unhandled_exception) unhandled_vt;
66
67void unhandled_test(void) {
68        forall(T &, V & | is_exception(T, V))
69        void defaultTerminationHandler(T &) {
70                throw (unhandled_exception){&unhandled_vt};
71        }
72        void defaultTerminationHandler(unhandled_exception &) {
73                abort();
74        }
75        try {
76                throw (first){&first_vt};
77        } catch (unhandled_exception * t) {
78                sout | "Catch unhandled_exception.";
79        }
80}
81
82exception second {};
83vtable(second) second_vt;
84
85void cross_test(void) {
86        void defaultTerminationHandler(first &) {
87                sout | "cross terminate default";
88                throw (second){&second_vt};
89        }
90        void defaultResumptionHandler(first &) {
91                sout | "cross resume default";
92                throwResume (second){&second_vt};
93        }
94        try {
95                sout | "cross terminate throw";
96                throw (first){&first_vt};
97        } catch (second *) {
98                sout | "cross terminate catch";
99        }
100        try {
101                sout | "cross resume throw";
102                throwResume (first){&first_vt};
103        } catchResume (second *) {
104                sout | "cross resume catch";
105        }
106}
107
108int main(int argc, char * argv[]) {
109        log_test();
110        jump_test();
111        unhandled_test();
112        cross_test();
113}
Note: See TracBrowser for help on using the repository browser.