home *** CD-ROM | disk | FTP | other *** search
-
- /*********************************************************************
-
- FILENAME
- Exceptions.h
-
- DESCRIPTION
- A collection of routines and macros to handle assertions and
- exceptions.
-
- COPYRIGHT
- Copyright ⌐ Apple Computer, Inc. 1989-1991
- All rights reserved.
-
- ROUTINES
- EXTERNALS
- dprintf
- check_dprintf
- checkpos_dprintf
-
- MACROS
- EXTERNALS
- check
- ncheck
- check_action
- ncheck_action
- require
- nrequire
- require_action
- nrequire_action
- resume
-
- MODIFICATION HISTORY
- Nov 12 95 BKJ Moved to MetroWerks environment & the NSPR
-
- NOTE
- To keep code size down, use these routines and macros with the C
- compiler option -b2 or -b3. This will eliminate duplicate strings
- within a procedure.
-
- *********************************************************************/
-
- #ifndef __MACERRORHANDLING__
- #define __MACERRORHANDLING__
-
- /*********************************************************************
-
- INCLUDES
-
- *********************************************************************/
-
- #include <Types.h>
-
- /*<FF>*/
- /*********************************************************************
-
- CONSTANTS AND CONTROL
-
- *********************************************************************/
-
- /*
- These defines are used to control the amount of information
- displayed when an assertion fails. DEBUGOFF and WARN will run
- silently. MIN will simply break into the debugger. ON will break
- and display the assertion that failed and the exception (for
- require statements). FULL will also display the source file name
- and line number. SYM does a SysBreak and is usefull when using a
- symbolic debugger like SourceBug or SADE. They should be set into
- DEBUGLEVEL. The default LEVEL is OFF.
- */
-
- #define DEBUGOFF 0
- #define DEBUGWARN 1
- #define DEBUGMIN 2
- #define DEBUGON 3
- #define DEBUGFULL 4
- #define DEBUGSYM 6
-
- #ifndef DEBUGLEVEL
- #define DEBUGLEVEL DEBUGOFF
- #endif DEBUGLEVEL
-
- /*
- resumeLabel is used to control the insertion of labels for use with
- the resume macro. If you do not use the resume macro and you wish
- to have multible exceptions per label then you can add the
- following define to you source code.
-
- */
- #define resumeLabel(exception) // Multiple exceptions per label
- // #define resumeLabel(exception) resume_ ## exception: // Single exception per label
-
-
- /*
- traceon and debugon are used to test for options
- */
-
- #define traceon ((DEBUGLEVEL > DEBUGWARN) && defined(TRACEON))
- #define debugon (DEBUGLEVEL > DEBUGWARN)
-
- /*
- Add some macros for DEBUGMIN and DEBUGSYM to keep the size down.
- */
-
- #define __DEBUGSMALL ((DEBUGLEVEL == DEBUGMIN) || \
- (DEBUGLEVEL == DEBUGSYM))
-
- #if DEBUGLEVEL == DEBUGMIN
- #define __DebuggerBreak Debugger()
- #elif DEBUGLEVEL == DEBUGSYM
- #define __DebuggerBreak SysBreak()
- #endif
-
-
- /*<FF>*/
- /*********************************************************************
-
- MACRO
- check(assertion)
-
- DESCRIPTION
- If debugging is on then check will test assertion and if it fails
- break into the debugger. Otherwise check does nothing.
-
- *********************************************************************/
-
- #if __DEBUGSMALL
-
- #define check(assertion) \
- do { \
- if (assertion) ; \
- else __DebuggerBreak; \
- } while (false)
-
- #elif DEBUGLEVEL == DEBUGON
-
- #define check(assertion) \
- do { \
- if (assertion) ; \
- else { \
- dprintf(notrace, "Assertion \"%s\" Failed", #assertion); \
- } \
- } while (false)
-
- #elif DEBUGLEVEL == DEBUGFULL
-
- #define check(assertion) \
- do { \
- if (assertion) ; \
- else { \
- dprintf(notrace, "Assertion \"%s\" Failed\n" \
- "File: %s\n" \
- "Line: %d", \
- #assertion, __FILE__, __LINE__); \
- } \
- } while (false)
-
- #else
-
- #define check(assertion)
-
- #endif
-
- /*<FF>*/
- /*********************************************************************
-
- MACRO
- ncheck(assertion)
-
- DESCRIPTION
- If debugging is on then ncheck will test !assertion and if it fails
- break into the debugger. Otherwise ncheck does nothing.
-
- *********************************************************************/
-
- #if __DEBUGSMALL
-
- #define ncheck(assertion) \
- do { \
- if (assertion) __DebuggerBreak; \
- } while (false)
-
- #elif DEBUGLEVEL == DEBUGON
-
- #define ncheck(assertion) \
- do { \
- void* __privateAssertion = (void*)(assertion); \
- \
- if (__privateAssertion) { \
- dprintf(notrace, "Assertion \"!(%s [= %#08X])\" Failed", \
- #assertion, __privateAssertion); \
- } \
- } while (false)
-
- #elif DEBUGLEVEL == DEBUGFULL
-
- #define ncheck(assertion) \
- do { \
- void* __privateAssertion = (void*)(assertion); \
- \
- if (__privateAssertion) { \
- dprintf(notrace, "Assertion \"!(%s [= %#08X])\" Failed\n" \
- "File: %s\n" \
- "Line: %d", \
- #assertion, __privateAssertion, __FILE__, __LINE__); \
- } \
- } while (false)
-
- #else
-
- #define ncheck(assertion)
-
- #endif
-
- /*<FF>*/
- /*********************************************************************
-
- MACRO
- check_action(assertion, action)
-
- DESCRIPTION
- If debugging is on then check_action will test assertion and if it
- fails break into the debugger then execute action. Otherwise
- check_action does nothing.
-
- *********************************************************************/
-
- #if __DEBUGSMALL
-
- #define check_action(assertion, action) \
- do { \
- if (assertion) ; \
- else { \
- __DebuggerBreak; \
- { action } \
- } while (false)
-
- #elif DEBUGLEVEL == DEBUGON
-
- #define check_action(assertion, action) \
- do { \
- if (assertion) ; \
- else { \
- dprintf(notrace, "Assertion \"%s\" Failed", #assertion); \
- { action } \
- } \
- } while (false)
-
- #elif DEBUGLEVEL == DEBUGFULL
-
- #define check_action(assertion, action) \
- do { \
- if (assertion) ; \
- else { \
- dprintf(notrace, "Assertion \"%s\" Failed\n" \
- "File: %s\n" \
- "Line: %d", \
- #assertion, __FILE__, __LINE__); \
- { action } \
- } \
- } while (false)
-
- #else
-
- #define check_action(assertion, action)
-
- #endif
-
- /*<FF>*/
- /**************************************************************************************
-
- MACRO
- ncheck_action(assertion, action)
-
- DESCRIPTION
- If debugging is on then ncheck_action will test !assertion and if
- it fails break into the debugger then execute action. Otherwise
- ncheck_action does nothing.
-
- *********************************************************************/
-
- #if __DEBUGSMALL
-
- #define ncheck_action(assertion, action) \
- do { \
- if (assertion) { \
- __DebuggerBreak; \
- { action } \
- } \
- } while (false)
-
- #elif DEBUGLEVEL == DEBUGON
-
- #define ncheck_action(assertion, action) \
- do { \
- void* __privateAssertion = (void*)(assertion); \
- \
- if (__privateAssertion) { \
- dprintf(notrace, "Assertion \"!(%s [= %#08X])\" Failed", \
- #assertion, __privateAssertion); \
- { action } \
- } \
- } while (false)
-
- #elif DEBUGLEVEL == DEBUGFULL
-
- #define ncheck_action(assertion, action) \
- do { \
- void* __privateAssertion = (void*)(assertion); \
- \
- if (__privateAssertion) { \
- dprintf(notrace, "Assertion \"!(%s [= %#08X])\" Failed\n" \
- "File: %s\n" \
- "Line: %d", \
- #assertion, __privateAssertion, __FILE__, __LINE__); \
- { action } \
- } \
- } while (false)
-
- #else
-
- #define ncheck_action(assertion, action)
-
- #endif
-
- /*<FF>*/
- /*********************************************************************
-
- MACRO
- require(assertion, exception)
-
- DESCRIPTION
- require will test assertion and if it fails:
- break into the debugger if debugging is on.
- goto exception.
-
- *********************************************************************/
-
- #if __DEBUGSMALL
-
- #define require(assertion, exception) \
- do { \
- if (assertion) ; \
- else { \
- __DebuggerBreak; \
- goto exception; \
- resumeLabel(exception); \
- } \
- } while (false)
-
- #elif DEBUGLEVEL == DEBUGON
-
- #define require(assertion, exception) \
- do { \
- if (assertion) ; \
- else { \
- dprintf(notrace, "Assertion \"%s\" Failed\n" \
- "Exception \"%s\" Raised", \
- #assertion, #exception); \
- goto exception; \
- resumeLabel(exception); \
- } \
- } while (false)
-
- #elif DEBUGLEVEL == DEBUGFULL
-
- #define require(assertion, exception) \
- do { \
- if (assertion) ; \
- else { \
- dprintf(notrace, "Assertion \"%s\" Failed\n" \
- "Exception \"%s\" Raised\n" \
- "File: %s\n" \
- "Line: %d", \
- #assertion, #exception, __FILE__, __LINE__); \
- goto exception; \
- resumeLabel(exception); \
- } \
- } while (false)
-
- #else
-
- #define require(assertion, exception) \
- do { \
- if (assertion) ; \
- else { \
- goto exception; \
- resumeLabel(exception); \
- } \
- } while (false)
-
- #endif
-
- /*<FF>*/
- /*********************************************************************
-
- MACRO
- nrequire(assertion, exception)
-
- DESCRIPTION
- nrequire will test !assertion and if it fails:
- break into the debugger if debugging is on.
- goto exception.
-
- *********************************************************************/
-
- #if __DEBUGSMALL
-
- #define nrequire(assertion, exception) \
- do { \
- if (assertion) { \
- DebugStr(); \
- goto exception; \
- resumeLabel(exception); \
- } \
- } while (false)
-
- #elif DEBUGLEVEL == DEBUGON
-
- #define nrequire(assertion, exception) \
- do { \
- void* __privateAssertion = (void*)(assertion); \
- \
- if (__privateAssertion) { \
- dprintf(notrace, "Assertion \"!(%s [= %#08X])\" Failed\n" \
- "Exception \"%s\" Raised", \
- #assertion, __privateAssertion, #exception); \
- goto exception; \
- resumeLabel(exception); \
- } \
- } while (false)
-
- #elif DEBUGLEVEL == DEBUGFULL
-
- #define nrequire(assertion, exception) \
- do { \
- void* __privateAssertion = (void*)(assertion); \
- \
- if (__privateAssertion) { \
- dprintf(notrace, "Assertion \"!(%s [= %#08X])\" Failed\n" \
- "Exception \"%s\" Raised\n" \
- "File: %s\n" \
- "Line: %d", \
- #assertion, __privateAssertion, #exception, __FILE__, \
- __LINE__); \
- goto exception; \
- resumeLabel(exception); \
- } \
- } while (false)
-
- #else
-
- #define nrequire(assertion, exception) \
- do { \
- if (assertion) { \
- goto exception; \
- resumeLabel(exception); \
- } \
- } while (false)
-
- #endif
-
- /*<FF>*/
- /*********************************************************************
-
- MACRO
- require_action(assertion, exception, action)
-
- DESCRIPTION
- require_action will test assertion and if it fails:
- break into the debugger if debugging is on.
- execute action.
- goto exception.
-
- *********************************************************************/
-
- #if __DEBUGSMALL
-
- #define require_action(assertion, exception, action) \
- do { \
- if (assertion) ; \
- else { \
- __DebuggerBreak; \
- { action } \
- goto exception; \
- resumeLabel(exception); \
- } \
- } while (false)
-
- #elif DEBUGLEVEL == DEBUGON
-
- #define require_action(assertion, exception, action) \
- do { \
- if (assertion) ; \
- else { \
- dprintf(notrace, "Assertion \"%s\" Failed\n" \
- "Exception \"%s\" Raised", \
- #assertion, #exception); \
- { action } \
- goto exception; \
- resumeLabel(exception); \
- } \
- } while (false)
-
- #elif DEBUGLEVEL == DEBUGFULL
-
- #define require_action(assertion, exception, action) \
- do { \
- if (assertion) ; \
- else { \
- dprintf(notrace, "Assertion \"%s\" Failed\n" \
- "Exception \"%s\" Raised\n" \
- "File: %s\n" \
- "Line: %d", \
- #assertion, #exception, __FILE__, __LINE__); \
- { action } \
- goto exception; \
- resumeLabel(exception); \
- } \
- } while (false)
-
- #else
-
- #define require_action(assertion, exception, action) \
- do { \
- if (assertion) ; \
- else { \
- { action } \
- goto exception; \
- resumeLabel(exception); \
- } \
- } while (false)
-
- #endif
-
- /*<FF>*/
- /*********************************************************************
-
- MACRO
- nrequire_action(assertion, exception, action)
-
- DESCRIPTION
- nrequire_action will test !assertion and if it fails:
- break into the debugger if debugging is on.
- execute action.
- goto exception.
-
- *********************************************************************/
-
- #if __DEBUGSMALL
-
- #define nrequire_action(assertion, exception, action) \
- do { \
- if (assertion) { \
- __DebuggerBreak; \
- { action } \
- goto exception; \
- resumeLabel(exception); \
- } \
- } while (false)
-
- #elif DEBUGLEVEL == DEBUGON
-
- #define nrequire_action(assertion, exception, action) \
- do { \
- void* __privateAssertion = (void*)(assertion); \
- \
- if (__privateAssertion) { \
- dprintf(notrace, "Assertion \"!(%s [= %#08X])\" Failed\n" \
- "Exception \"%s\" Raised", \
- #assertion, __privateAssertion, #exception); \
- { action } \
- goto exception; \
- resumeLabel(exception); \
- } \
- } while (false)
-
- #elif DEBUGLEVEL == DEBUGFULL
-
- #define nrequire_action(assertion, exception, action) \
- do { \
- void* __privateAssertion = (void*)(assertion); \
- \
- if (__privateAssertion) { \
- dprintf(notrace, "Assertion \"!(%s [= %#08X])\" Failed\n" \
- "Exception \"%s\" Raised\n" \
- "File: %s\n" \
- "Line: %d", \
- #assertion, __privateAssertion, #exception, __FILE__, \
- __LINE__); \
- { action } \
- goto exception; \
- resumeLabel(exception); \
- } \
- } while (false)
-
- #else
-
- #define nrequire_action(assertion, exception, action) \
- do { \
- if (assertion) { \
- { action } \
- goto exception; \
- resumeLabel(exception); \
- } \
- } while (false)
-
- #endif
-
- /*<FF>*/
- /*********************************************************************
-
- MACRO
- resume(exception)
-
- DESCRIPTION
- resume will resume execution after the n/require/_action statement
- specified by exception. Resume lables must be on (the default) in
- order to use resume. If an action form of require was used then the
- action will not be re-executed.
-
- *********************************************************************/
-
-
- #define resume(exception) \
- do { \
- goto resume_ ## exception; \
- } while (false)
-
-
- /*<FF>*/
- /********************************************************************/
- #endif
-