/* UnwindProtect.m * * Copyright Niels Möller 1995 * * Freely distributable under the terms and conditions of the * GNU General Public License. */ #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 UnwindProtect - init { [ [self initDontFree] cleanupBySending: @selector(rawFree) to: self]; return self; } - initDontFree { [super init]; frame = NULL; return self; } - cleanupByCalling: ( void (*)(void)) function { frame_id newFrame = [FRAME_STACK pushCleanupCall: function]; if (!frame) frame = newFrame; return self; } - cleanupByCalling: ( void (*)(void *)) function with: (void *) argument { frame_id newFrame = [FRAME_STACK pushCleanupCall: function with: argument]; if (!frame) frame = newFrame; return self; } - cleanupBySending: (SEL) message to: rec { frame_id newFrame = [FRAME_STACK pushCleanupSending: message to: rec]; if (!frame) frame = newFrame; return self; } - (JMP_BUF *) cleanupByJumpingHere: (frame_id *) framepointer { frame_id newFrame = [FRAME_STACK pushCleanup_jmp]; if (!frame) frame = newFrame; *framepointer = newFrame; return &(( (struct frstack_cleanup_jmp_frame *) newFrame)->where); } - (void) cleanup { /* Will probably send us the free message */ frstack_unwind(frame, 1); } @end /* UnwindProtect */