// New draft of exception tests. #include #include "except-mac.hfa" TRIVIAL_EXCEPTION(yin) TRIVIAL_EXCEPTION(yang) struct num_error; struct num_error_vtable { struct TABLE(BASE_EXCEPT) const * parent; size_t size; void (*copy)(num_error *this, num_error * other); void (*free)(num_error *this); const char * (*msg)(num_error *this); int (*code)(num_error *this); }; extern num_error_vtable INSTANCE(num_error); struct num_error { struct num_error_vtable const * virtual_table; char * msg; int num; }; void num_error_msg(num_error * this) { if ( ! this->msg ) { static const char * base = "Num Error with code: X"; this->msg = malloc(22); for (int i = 0 ; (this->msg[i] = base[i]) ; ++i); } this->msg[21] = '0' + this->num; return this->msg; } void ?{}(num_error * this, int num) { this->virtual_table = &INSTANCE(num_error); this->msg = 0; this->num = num; } void ?{}(num_error * this, num_error * other) { this->virtual_table = other->virtual_table; this->msg = 0; this->num = other->num; } void ^?{}(num_error * this) { if( this->msg ) free( this->msg ); } int num_error_code( num_error * this ) { return this->num; } num_error_vtable _num_error_vtable_instance @= { &INSTANCE(BASE_EXCEPT), sizeof(num_error), ?{}, ^?{}, num_error_msg, num_error_code }; // Test simple throwing, matching and catching. void throw_catch() { try { yin black; THROW(&black); } catch ( yin * error ) { printf("throw yin caught.\n"); } try { yang white; THROW_RESUME(&white); printf("> throwResume returned.\n"); } catchResume ( yang * error ) { printf("throwResume yang caught <"); } try { num_error x = { 2 }; THROW(&x); } catch (num_error * error ; 3 == error->virtual_table->code( error ) ) { printf("exception at %p\n", error ); printf("Should not be printed.\n"); } catch (num_error * error ; 2 == error->virtual_table->code( error ) ) { printf("Should be printed.\n"); } } int main (int argc, char * argv[]) { throw_catch(); return 0; }