| [6d43cdde] | 1 | // Conditional Catch Test | 
|---|
|  | 2 |  | 
|---|
|  | 3 | // I may fold this back into terminate.cfa and resume.cfa once setting | 
|---|
|  | 4 | // up the non-trivial exception is reasonable to do. | 
|---|
|  | 5 |  | 
|---|
| [e68d092] | 6 | #include <exception.hfa> | 
|---|
| [6d43cdde] | 7 | #include <stdio.h> | 
|---|
|  | 8 |  | 
|---|
| [e68d092] | 9 | VTABLE_DECLARATION(num_error)( | 
|---|
| [6d43cdde] | 10 | int (*code)(num_error *this); | 
|---|
|  | 11 | ); | 
|---|
|  | 12 |  | 
|---|
|  | 13 | struct num_error { | 
|---|
|  | 14 | VTABLE_FIELD(num_error); | 
|---|
|  | 15 | char * msg; | 
|---|
|  | 16 | int num; | 
|---|
|  | 17 | }; | 
|---|
|  | 18 |  | 
|---|
|  | 19 | void num_error_msg(num_error * this) { | 
|---|
|  | 20 | if ( ! this->msg ) { | 
|---|
|  | 21 | static const char * base = "Num Error with code: X"; | 
|---|
|  | 22 | this->msg = (char *)malloc(22); | 
|---|
|  | 23 | for (int i = 0 ; (this->msg[i] = base[i]) ; ++i); | 
|---|
|  | 24 | } | 
|---|
|  | 25 | this->msg[21] = '0' + this->num; | 
|---|
|  | 26 | return this->msg; | 
|---|
|  | 27 | } | 
|---|
|  | 28 | void ?{}(num_error & this, int num) { | 
|---|
|  | 29 | VTABLE_INIT(this, num_error); | 
|---|
|  | 30 | this.msg = 0; | 
|---|
|  | 31 | this.num = num; | 
|---|
|  | 32 | } | 
|---|
|  | 33 | void ?{}(num_error & this, num_error & other) { | 
|---|
|  | 34 | this.virtual_table = other.virtual_table; | 
|---|
|  | 35 | this.msg = 0; | 
|---|
|  | 36 | this.num = other.num; | 
|---|
|  | 37 | } | 
|---|
|  | 38 | void ^?{}(num_error & this) { | 
|---|
|  | 39 | if( this.msg ) free( this.msg ); | 
|---|
|  | 40 | } | 
|---|
|  | 41 | int num_error_code( num_error * this ) { | 
|---|
|  | 42 | return this->num; | 
|---|
|  | 43 | } | 
|---|
|  | 44 |  | 
|---|
| [e68d092] | 45 | VTABLE_INSTANCE(num_error)( | 
|---|
|  | 46 | num_error_msg, | 
|---|
|  | 47 | num_error_code, | 
|---|
| [6d43cdde] | 48 | ); | 
|---|
|  | 49 |  | 
|---|
|  | 50 | void caught_num_error(int expect, num_error * actual) { | 
|---|
|  | 51 | printf("Caught num_error: expected=%d actual=%d.\n", expect, actual->num); | 
|---|
|  | 52 | } | 
|---|
|  | 53 |  | 
|---|
|  | 54 | int main(int argc, char * argv[]) { | 
|---|
|  | 55 | num_error exc = 2; | 
|---|
|  | 56 |  | 
|---|
|  | 57 | try { | 
|---|
| [046a890] | 58 | throw exc; | 
|---|
| [6d43cdde] | 59 | } catch (num_error * error ; 3 == error->virtual_table->code( error )) { | 
|---|
|  | 60 | caught_num_error(3, error); | 
|---|
|  | 61 | } catch (num_error * error ; 2 == error->virtual_table->code( error )) { | 
|---|
|  | 62 | caught_num_error(2, error); | 
|---|
|  | 63 | } | 
|---|
|  | 64 |  | 
|---|
|  | 65 | try { | 
|---|
| [046a890] | 66 | throwResume exc; | 
|---|
| [6d43cdde] | 67 | } catchResume (num_error * error ; 3 == error->virtual_table->code( error )) { | 
|---|
|  | 68 | caught_num_error(3, error); | 
|---|
|  | 69 | } catchResume (num_error * error ; 2 == error->virtual_table->code( error )) { | 
|---|
|  | 70 | caught_num_error(2, error); | 
|---|
|  | 71 | } | 
|---|
|  | 72 | } | 
|---|