source: tests/exceptions/defaults.cfa @ 8463136

ast-experimental
Last change on this file since 8463136 was c3b9d639, checked in by Andrew Beach <ajbeach@…>, 2 years 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
RevLine 
[8ad5752]1// Tests for providing new default operations.
2
3#include <string.h>
4
[d00d581]5exception log_message {
[8ad5752]6        char * msg;
[d00d581]7};
[8ad5752]8
[c3b9d639]9// Manually define the virtual table and helper functions.
[c715e5f]10void copy(log_message * this, log_message * that) {
11        *this = *that;
12}
13
[ecfd758]14const char * msg(log_message * this) {
[8ad5752]15        return this->msg;
16}
[c715e5f]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};
[8ad5752]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 {
[ecfd758]35                throwResume (log_message){&log_vt, "Should be printed.\n"};
[8ad5752]36        } catchResume (log_message * this) {
[381132b]37                printf("%s", this->virtual_table->msg(this));
[8ad5752]38        }
39        // But we don't have to:
[ecfd758]40        throwResume (log_message){&log_vt, "Should not be printed.\n"};
[8ad5752]41}
42
43// I don't have a good use case for doing the same with termination.
[d00d581]44exception jump {};
[8ad5752]45void defaultTerminationHandler(jump &) {
46        printf("jump default handler.\n");
47}
48
[d00d581]49vtable(jump) jump_vt;
[ecfd758]50
[8ad5752]51void jump_test(void) {
52        try {
[ecfd758]53                throw (jump){&jump_vt};
[8ad5752]54        } catch (jump * this) {
55                printf("jump catch handler.\n");
56        }
[ecfd758]57        throw (jump){&jump_vt};
[8ad5752]58}
59
[d00d581]60exception first {};
61vtable(first) first_vt;
[ecfd758]62
[d00d581]63exception unhandled_exception {};
64vtable(unhandled_exception) unhandled_vt;
[8ad5752]65
66void unhandled_test(void) {
[fd54fef]67        forall(T &, V & | is_exception(T, V))
[8ad5752]68        void defaultTerminationHandler(T &) {
[ecfd758]69                throw (unhandled_exception){&unhandled_vt};
[8ad5752]70        }
71        void defaultTerminationHandler(unhandled_exception &) {
72                abort();
73        }
74        try {
[ecfd758]75                throw (first){&first_vt};
[8ad5752]76        } catch (unhandled_exception * t) {
77                printf("Catch unhandled_exception.\n");
78        }
79}
80
[d00d581]81exception second {};
82vtable(second) second_vt;
[381132b]83
84void cross_test(void) {
85        void defaultTerminationHandler(first &) {
86                printf("cross terminate default\n");
[ecfd758]87                throw (second){&second_vt};
[381132b]88        }
89        void defaultResumptionHandler(first &) {
90                printf("cross resume default\n");
[ecfd758]91                throwResume (second){&second_vt};
[381132b]92        }
93        try {
94                printf("cross terminate throw\n");
[ecfd758]95                throw (first){&first_vt};
[381132b]96        } catch (second *) {
97                printf("cross terminate catch\n");
98        }
99        try {
100                printf("cross resume throw\n");
[ecfd758]101                throwResume (first){&first_vt};
[381132b]102        } catchResume (second *) {
103                printf("cross resume catch\n");
104        }
105}
106
[8ad5752]107int main(int argc, char * argv[]) {
108        log_test();
109        jump_test();
110        unhandled_test();
[381132b]111        cross_test();
[8ad5752]112}
Note: See TracBrowser for help on using the repository browser.