home *** CD-ROM | disk | FTP | other *** search
- /*==================================================================
- File: MacOS_Exceptions.h
-
- Contains: A collection of routines and macros to handle
- assertions and exceptions.
-
- Written by: Sean Parent, modified extensively by Eric Traut
-
- Copyright:
- 1989-1993, 1997-1998 by Apple Computer, Inc., all rights reserved.
- Published along with article in the Aug. '92 edition
- of "develop" magazine.
- ==================================================================*/
-
- /*********************************************************************
- MACROS
- EXTERNALS
- check
- check_action
- require
- require_action
- resume
-
- *********************************************************************/
-
- #ifndef __EXCEPTIONS__
- #define __EXCEPTIONS__
-
- #ifndef __MACTYPES__
- #include <MacTypes.h>
- #endif
-
-
- /*********************************************************************
- COMPILER SWITCHES
- *********************************************************************/
-
- /*
- 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. They should be set into DEBUGLEVEL. The
- default LEVEL is OFF.
- */
-
- #define DEBUGOFF 0
- #define DEBUGMIN 1
- #define DEBUGON 2
- #define DEBUGFULL 3
-
- #ifndef DEBUGLEVEL
- #define DEBUGLEVEL DEBUGOFF
- #endif
-
-
- /*********************************************************************
- TYPE DEFINITIONS
- *********************************************************************/
-
- typedef void (*ExceptionCallBackProc)(const char * inDebugMessage);
-
-
- /*********************************************************************
- ROUTINES
- *********************************************************************/
-
- #ifdef __cplusplus
- extern "C" {
- #endif
-
- StringPtr AssertionFailed(const char * assertionString);
- StringPtr AssertionFailedFileLine(const char * assertionString, const char * fileString, unsigned int line);
- StringPtr AssertionFailedExceptionRaised(const char * assertionString, const char * exceptionString);
- StringPtr AssertionFailedExceptionRaisedFileLine(const char * assertionString, const char * exceptionString, const char * fileString, unsigned int line);
-
- StringPtr PrintDebugString(const char * debugString);
- StringPtr PrintDebugStringFileLine(const char * debugString, const char * fileString, unsigned int line);
-
- void InstallExceptionCallBack(ExceptionCallBackProc inCallBackProc);
-
- #ifdef __cplusplus
- }
- #endif
-
- /*********************************************************************
-
- MACRO
- debug_str(string)
-
- DESCRIPTION
- If debugging is on then check will print the specified string
- Otherwise it does nothing.
-
- *********************************************************************/
-
- #if (DEBUGLEVEL == DEBUGMIN || DEBUGLEVEL == DEBUGON)
-
- #define debug_str(string) \
- DebugStr(AssertionFailed(string));
-
- #elif (DEBUGLEVEL == DEBUGFULL)
-
- #define debug_str(string) \
- DebugStr(AssertionFailedFileLine(string, __FILE__, __LINE__));
-
- #else
-
- #define debug_str(string)
-
- #endif
-
- #define debug_is_feature_used() debug_str(gFeatureIsUsed)
- #define debug_unexpected_value() debug_str(gUnexpectedValue)
- #define debug_unimplemented() debug_str(gUnimplemented)
- #define debug_untested() debug_str(gUntested)
-
-
- /*********************************************************************
-
- MACRO
- debug_stringstream(string)
-
- DESCRIPTION
- Just like debug_str() above, but allows use of a string stream.
-
- For example:
-
- #include <sstream>
- debug_stringstream( "I eat " << numFruit << " kumquats daily." )
-
- *********************************************************************/
-
- #ifdef __cplusplus
-
- #if (DEBUGLEVEL == DEBUGMIN || DEBUGLEVEL == DEBUGON)
-
- #define debug_stringstream(sstream) \
- do { \
- std::stringstream debugstring; \
- debugstring << sstream; \
- DebugStr(AssertionFailed((debugstring.str()).c_str())); \
- } while(0)
-
- #elif (DEBUGLEVEL == DEBUGFULL)
-
- #define debug_stringstream(sstream) \
- do { \
- std::stringstream debugstring; \
- debugstring << sstream; \
- DebugStr(AssertionFailedFileLine((debugstring.str()).c_str(), __FILE__, __LINE__)); \
- } while(0)
-
- #else
-
- #define debug_stringstream(sstream)
-
- #endif
-
- #endif // __cplusplus
-
- /*********************************************************************
-
- 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 (DEBUGLEVEL == DEBUGMIN)
-
- #define check(assertion) \
- do { \
- if (assertion) {} \
- else Debugger(); \
- } while (false)
-
- #elif DEBUGLEVEL == DEBUGON
-
- #define check(assertion) \
- do { \
- if (assertion) {} \
- else { \
- DebugStr(AssertionFailed(#assertion)); \
- } \
- } while (false)
-
- #elif (DEBUGLEVEL == DEBUGFULL)
-
- #define check(assertion) \
- do { \
- if (assertion) {} \
- else { \
- DebugStr(AssertionFailedFileLine(#assertion, __FILE__, __LINE__)); \
- } \
- } while (false)
-
- #else
-
- #define check(assertion)
-
- #endif
-
- /*********************************************************************
-
- 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 (DEBUGLEVEL == DEBUGMIN)
-
- #define check_action(assertion, action) \
- do { \
- if (assertion) {} \
- else { \
- Debugger(); \
- { action } \
- } while (false)
-
- #elif DEBUGLEVEL == DEBUGON
-
- #define check_action(assertion, action) \
- do { \
- if (assertion) {} \
- else { \
- DebugStr(AssertionFailed(#assertion)); \
- { action } \
- } \
- } while (false)
-
- #elif (DEBUGLEVEL == DEBUGFULL)
-
- #define check_action(assertion, action) \
- do { \
- if (assertion) {} \
- else { \
- DebugStr(AssertionFailedFileLine(#assertion, __FILE__, __LINE__)); \
- { action } \
- } \
- } while (false)
-
- #else
-
- #define check_action(assertion, action)
-
- #endif
-
- /*********************************************************************
-
- MACRO
- require(assertion, exception)
-
- DESCRIPTION
- require will test assertion and if it fails:
- break into the debugger if debugging is on.
- goto exception.
-
- *********************************************************************/
-
- #if (DEBUGLEVEL == DEBUGMIN)
-
- #define require(assertion, exception) \
- do { \
- if (assertion) {} \
- else { \
- Debugger(); \
- goto exception; \
- } \
- } while (false)
-
- #elif DEBUGLEVEL == DEBUGON
-
- #define require(assertion, exception) \
- do { \
- if (assertion) {} \
- else { \
- DebugStr(AssertionFailedExceptionRaised(#assertion, #exception)); \
- goto exception; \
- } \
- } while (false)
-
- #elif (DEBUGLEVEL == DEBUGFULL)
-
- #define require(assertion, exception) \
- do { \
- if (assertion) {} \
- else { \
- DebugStr(AssertionFailedExceptionRaisedFileLine( \
- #assertion, #exception, __FILE__, __LINE__)); \
- goto exception; \
- } \
- } while (false)
-
- #else
-
- #define require(assertion, exception) \
- do { \
- if (assertion) {} \
- else { \
- goto exception; \
- } \
- } while (false)
-
- #endif
-
- /*********************************************************************
-
- MACRO
- debug_throw(assertion, exception)
-
- DESCRIPTION
- debug_throw will test assertion and if it fails:
- break into the debugger if debugging is on.
- throw exception
-
- *********************************************************************/
-
- #if (DEBUGLEVEL == DEBUGMIN)
-
- #define debug_throw(assertion, exception) \
- do { \
- if (assertion) {} \
- else { \
- Debugger(); \
- throw exception; \
- } \
- } while (false) \
-
- #elif (DEBUGLEVEL == DEBUGON)
-
- #define debug_throw(assertion, exception) \
- do { \
- if (assertion) {} \
- else { \
- DebugStr(AssertionFailed(#assertion)); \
- throw exception; \
- } \
- } while (false) \
-
- #elif (DEBUGLEVEL == DEBUGFULL)
-
- #define debug_throw(assertion, exception) \
- do { \
- if (assertion) {} \
- else { \
- DebugStr(AssertionFailedFileLine(#assertion, __FILE__, __LINE__)); \
- throw exception; \
- } \
- } while (false)
-
- #else
-
- #define debug_throw(assertion, exception) \
- do { \
- if (assertion) {} \
- else { \
- throw exception; \
- } \
- } while (false)
-
- #endif
-
- /*********************************************************************
-
- MACRO
- forbid(assertion, exception)
-
- DESCRIPTION
- require will test assertion and if it passes:
- break into the debugger if debugging is on.
- goto exception.
-
- *********************************************************************/
-
- #define forbid(bad_assertion, exception) \
- require((!(bad_assertion)), exception)
-
- /*********************************************************************
-
- 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 (DEBUGLEVEL == DEBUGMIN)
-
- #define require_action(assertion, exception, action) \
- do { \
- if (assertion) {} \
- else { \
- Debugger(); \
- { action } \
- goto exception; \
- } \
- } while (false)
-
- #elif DEBUGLEVEL == DEBUGON
-
- #define require_action(assertion, exception, action) \
- do { \
- if (assertion) {} \
- else { \
- DebugStr(AssertionFailedExceptionRaised(#assertion, #exception)); \
- { action } \
- goto exception; \
- } \
- } while (false)
-
- #elif (DEBUGLEVEL == DEBUGFULL)
-
- #define require_action(assertion, exception, action) \
- do { \
- if (assertion) {} \
- else { \
- DebugStr(AssertionFailedExceptionRaisedFileLine( \
- #assertion, #exception, __FILE__, __LINE__)); \
- { action } \
- goto exception; \
- } \
- } while (false)
-
- #else
-
- #define require_action(assertion, exception, action) \
- do { \
- if (assertion) {} \
- else { \
- { action } \
- goto exception; \
- } \
- } while (false)
-
- #endif
-
- /*********************************************************************
-
- MACRO
- forbid_action(assertion, exception, action)
-
- DESCRIPTION
- forbid_action will test assertion and if it passes:
- break into the debugger if debugging is on.
- execute action.
- goto exception.
-
- *********************************************************************/
-
- #define forbid_action(bad_assertion, exception, action) \
- require_action((!(bad_assertion)), exception, action)
-
- /********************************************************************/
-
-
- /* Exported Globals */
- extern const char * gFeatureIsUsed;
- extern const char * gUnexpectedValue;
- extern const char * gUnimplemented;
- extern const char * gUntested;
-
-
- #endif // __EXCEPTIONS__
-
-
- /*==================================================================
- Change History (most recent first):
-
- $Log: MacOS_Exceptions.h,v $
- ==================================================================*/
-