Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
Exceptions.h
/*------------------------------------------------------------------------------------------ |
Program: CPlusTESample 2.0 |
File: Exceptions.h |
by Andrew Shebanow (original version by Andy Heninger) |
of Apple Macintosh Developer Technical Support |
Copyright © 1989-1990 Apple Computer, Inc. |
All rights reserved. |
This header defines a way for C++ code to do MacApp style Failure |
handling in a convenient way. In Object Pascal, Failure handlers |
are typically nested procedures which can reference local variables |
and such. In C++, there isn't any such thing as nested procedures, |
so we have to resort to hackery and define some lovely preprocessor |
macros. |
You use these macros inside a typical method like this: |
TRY |
{ |
// stuff which might fail |
} |
RECOVER |
{ |
// recovery stuff |
} |
ENDTRY |
Because all of the error handling is done inside of the function which |
caused the error, you can access local variables and such just like |
those Pascal guys do. |
How does it work? Well, it all depends on the C standard library |
setjmp/longjmp routines, which are explained in depth in the MPW |
C Reference. Basically, what they are is a mechanism for doing a |
non-local goto by saving and restoring the registers and the PC. |
How do you recover from an error? Basically, you just do a goto: |
TRY |
{ |
// stuff which might fail |
} |
RECOVER |
{ |
// recovery stuff |
goto recoveredSuccessfully; |
} |
ENDTRY |
recoveredSuccessfully: |
// do some more fun stuff |
This will drop you out of the failure mechanism entirely. |
For more examples, see the code in TApplication & TDocument. |
------------------------------------------------------------------------------------------*/ |
#ifndef __EXCEPTIONS__ |
#define __EXCEPTIONS__ |
#ifndef __TYPES__ |
#include <Types.h> |
#endif |
#ifndef __SETJMP__ |
#include <SetJmp.h> |
#endif |
#include "UMAFailure.h" |
extern "C" { |
// Since we eat the error code and message that the MacApp failure unit |
// passes us, we need to store them someplace where your failure |
// handling code can get at it. We use global variables (keen, eh?). |
extern long gFailMessage; // Current failure message |
extern short gFailError; // Current failure error |
pascal void StandardHandler(short e, long m, void* Handler_StaticLink); |
}; |
#define TRY \ |
{ \ |
jmp_buf errorBuf; \ |
if (! setjmp(errorBuf) ) { \ |
FailInfo fi; \ |
CatchFailures(&fi, StandardHandler, errorBuf); |
#define RECOVER \ |
Success(&fi); \ |
} \ |
else \ |
{ |
/* |
The default MacApp/Object Pascal semantics are that returning from |
an error handler will go to the next failure handler on the |
stack. The way we do this in C++ is that we call failure |
again with the same error information. We can use a goto out |
of the RECOVER..ENDTRY block to stop the error processing. |
*/ |
#define ENDTRY \ |
Failure(gFailError, gFailMessage); \ |
} \ |
} |
#endif |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14