/* Catch.m * * Copyright Niels Möller 1995 * * Freely distributable under the terms and conditions of the * GNU General Public License. */ #include #include /* I'm not sure if I should hardcode StackFrame here or not. */ #ifndef FRAME_STACK #define FRAME_STACK [self class] #endif FRAME_STACK @implementation Catch_common - (catch_buf *) where { return &where; } - (catch_buf *) catch; { if (frame) [self cleanup]; frame = [FRAME_STACK pushCatch: self]; return [self where]; } @end /* Catch_common */ @implementation Catch - value { return result; } - value: newValue { result = newValue; return self; } - (BOOL) matches: tag { return [tag isEqual: self]; } - (void) throw: value { [self throw: value : 17 free: YES]; } - (void) throwInt: (int) value { [self throw: nil : value free: NO]; } - (void) throw: value1 : (int) value2 free: (BOOL) freeFlag { frame_id fr; id catch; fr = [FRAME_STACK findFrameMatching: self]; if (fr) { [FRAME_STACK unwind: fr]; catch = ( (struct frstack_catch_object_frame *) fr)->object; [catch value: value1]; /* If freeFlag is true, and we are not the same object as the one * used in the catch, free. */ if (freeFlag && !(catch == self)) [self free]; longjmp([catch where]->jmp, value2); /* Never returns here */ } /* No matching catch found. Try signalling an error. */ [[[[ErrorNoCatch alloc] value: value1] tag: self] raise]; /* Dead end */ } @end /* Catch */ @implementation CatchError - errorClass { return errorClass; } - errorClass: class { errorClass = class; return self; } - error { return result; } - setError: object { result = object; return self; } - (catch_buf *) catch: class { return [ [self errorClass: class] catch]; } - (BOOL) matches: tag { return [tag isKindOf: errorClass]; } @end /* CatchError */