source: tests/exceptions/defaults.cfa

Last change on this file was c3b9d639, checked in by Andrew Beach <ajbeach@…>, 5 weeks ago

Clean-up the exception interface. It should be slightly more like the final - non-macro - interface.

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