home *** CD-ROM | disk | FTP | other *** search
/ AppleScript - The Beta Release / AppleScript - The Beta Release.iso / Documentation / develop / Better Apple Event Coding / Code Samples / Exceptions.h < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-16  |  2.8 KB  |  111 lines  |  [TEXT/MPS ]

  1. /*------------------------------------------------------------------------------------------
  2.  
  3.     Program:    CPlusTESample 2.0
  4.     File:        Exceptions.h
  5.  
  6.     by Andrew Shebanow (original version by Andy Heninger)
  7.     of Apple Macintosh Developer Technical Support
  8.  
  9.     Copyright © 1989-1990 Apple Computer, Inc.
  10.     All rights reserved.
  11.  
  12.     This header defines a way for C++ code to do MacApp style Failure
  13.     handling in a convenient way. In Object Pascal, Failure handlers
  14.     are typically nested procedures which can reference local variables
  15.     and such. In C++, there isn't any such thing as nested procedures,
  16.     so we have to resort to hackery and define some lovely preprocessor
  17.     macros.
  18.  
  19.     You use these macros inside a typical method like this:
  20.  
  21.         TRY
  22.         {
  23.             // stuff which might fail
  24.         }
  25.         RECOVER
  26.         {
  27.             // recovery stuff
  28.         }
  29.         ENDTRY
  30.  
  31.     Because all of the error handling is done inside of the function which
  32.     caused the error, you can access local variables and such just like
  33.     those Pascal guys do.
  34.  
  35.     How does it work? Well, it all depends on the C standard library
  36.     setjmp/longjmp routines, which are explained in depth in the MPW
  37.     C Reference. Basically, what they are is a mechanism for doing a
  38.     non-local goto by saving and restoring the registers and the PC.
  39.  
  40.     How do you recover from an error? Basically, you just do a goto:
  41.  
  42.             TRY
  43.             {
  44.                 // stuff which might fail
  45.             }
  46.             RECOVER
  47.             {
  48.                 // recovery stuff
  49.                 goto recoveredSuccessfully;
  50.             }
  51.             ENDTRY
  52.         recoveredSuccessfully:
  53.             // do some more fun stuff
  54.  
  55.     This will drop you out of the failure mechanism entirely.
  56.  
  57.     For more examples, see the code in TApplication & TDocument.
  58.  
  59. ------------------------------------------------------------------------------------------*/
  60.  
  61. #ifndef __EXCEPTIONS__
  62. #define __EXCEPTIONS__
  63.  
  64. #ifndef __TYPES__
  65. #include <Types.h>
  66. #endif
  67.  
  68. #ifndef __SETJMP__
  69. #include <SetJmp.h>
  70. #endif
  71.  
  72. #include "UMAFailure.h"
  73.  
  74. extern "C" {
  75.     // Since we eat the error code and message that the MacApp failure unit
  76.     // passes us, we need to store them someplace where your failure
  77.     // handling code can get at it. We use global variables (keen, eh?).
  78.     extern long gFailMessage;        // Current failure message
  79.     extern short gFailError;        // Current failure error
  80.  
  81.     pascal void StandardHandler(short e, long m, void* Handler_StaticLink);
  82. };
  83.  
  84. #define TRY \
  85.     { \
  86.         jmp_buf errorBuf; \
  87.         if (! setjmp(errorBuf) ) { \
  88.             FailInfo    fi; \
  89.             CatchFailures(&fi, StandardHandler, errorBuf);
  90.  
  91. #define RECOVER \
  92.             Success(&fi); \
  93.             } \
  94.         else \
  95.             {
  96.  
  97. /*
  98.     The default MacApp/Object Pascal semantics are that returning from
  99.     an error handler will go to the next failure handler on the
  100.     stack.  The way we do this in C++ is that we call failure
  101.     again with the same error information.  We can use a goto out
  102.     of the RECOVER..ENDTRY block to stop the error processing.
  103.  */
  104.  
  105. #define ENDTRY \
  106.             Failure(gFailError, gFailMessage); \
  107.             } \
  108.     }
  109.  
  110. #endif
  111.