/* Error-test.c * * Test Objective-C error facilities */ #include #include #include #include @protocol IntMath + new: (int) n; - init: (int) n; - (int) value; - plus: (id ) number; - times: (id ) number; - divide: (id ) number; @end /* IntMath */ @protocol MathError @end /* MathError */ @interface DivideByZero : Error @end /* DivideByZero */ @implementation DivideByZero - (const char *) message { return "Divide by zero attempted"; } @end /* DivideByZero */ @interface Integer : Object { int value; } @end /* Integer */ @implementation Integer + new: (int) n { return [[super new] init: n]; } - init: (int) n { value = n; return self; } - init { value = 43; return self; } - (int) value { return value; } - plus: (id ) number { value += [number value]; return self; } - times: (id ) number { value *= [number value]; return self; } - divide: (id ) number { if ([number value] == 0) [[DivideByZero new] raise]; value /= [number value]; return self; } @end /* Integer */ void foo(id object, int number); int main(int argc, char **argv) { id tag; id n; id error; int i; n = [Integer new: 17]; for (i=-7; i<3; i++) { CATCH_EXCEPTION(tag, @protocol(AnyError)) printf("foo(%d, %d)...", [n value], i); foo(n, i); CATCH(tag) error = [tag exception]; printf("An error was catched. Class: %s, message: %s.\n", [error name], [error message]); ENDCATCH(tag) } [[DivideByZero new] raise]; return 0; } void foo(id object, int number) { id protect = [UnwindProtect new]; id tmp = [Integer new]; id test = [Catch new]; [protect cleanupBySending: @selector(init) to: object]; [protect cleanupBySending: @selector(free) to: tmp]; /* Dangerous to invoke [test cleanup] from a cleanup * action. But the freeing of the UnwindProtect frame will free * the catch frame too, so rawFree is enough. */ [protect cleanupBySending: @selector(rawFree) to: test]; switch(number) { case 0: [object divide: [tmp init: number]]; break; case -1: [object plus: [tmp init: 5]]; break; case 1: [test throw: object]; break; default: [object times: [tmp init: number]]; } [protect cleanup]; printf("Computed: %d\n", [object value]); }