// ===========================================================================
//	UException.h
//
// Exception handling macros based on header from Metrowerks CodeWarrior 
// Copyright 1994-1996 Metrowerks 
// NOT_FOR_OPEN_SOURCE <to be reevaluated at a later time>
// ===========================================================================
//	Exception Codes
//
//		The exception handling macros all used type ExceptionCode
//		when throwing. An ExceptionCode is a signed 32-bit integer.



#ifndef __UException_H__
#define __UException_H__	1
#pragma once

// Exception codes

typedef long	ExceptionCode;

enum {
	err_NilPointer		= 'nilP',
	err_AssertFailed	= 'asrt'
};


#define Try_				try
#define Catch_(err)			catch(ExceptionCode err)
#define CatchAll_()			catch( ... )
#define EndCatch_

#define Throw_(err)		throw (ExceptionCode) (err)


// Useful macros for signaling common failures
	
	
// This macro avoids evaluating "err" twice by assigning
// its value to a local variable.
// This is used frequently
#define ThrowIfOSErr_(err)											\
	do {															\
		OSErr	__theErr = err;										\
		if (__theErr != kNoErr) {									\
			Throw_(__theErr);										\
		}															\
	} while (false)
	

// This one does not seem to be used in ASIP Project
#define ThrowIfError_(err)											\
	do {															\
		ExceptionCode	__theErr = err;								\
		if (__theErr != 0) {										\
			Throw_(__theErr);										\
		}															\
	} while (false)

// used in Routing and Utitilities subprojects
#define ThrowOSErr_(err)	Throw_(err)

// Does not seem to be used in ASIP Project
#define	ThrowIfNil_(ptr)											\
	do {															\
		if ((ptr) == nil) Throw_(err_NilPointer);					\
	} while (false)


// Yep, used a lot 
#define	ThrowIfNULL_(ptr)											\
	do {															\
		if ((ptr) == NULL) Throw_(err_NilPointer);					\
	} while (false)

// Not used
#define	ThrowIfResError_()	ThrowIfOSErr_(ResError())
// Not used
//#define	ThrowIfMemError_()	ThrowIfOSErr_(MemError())
// Not used
#define	ThrowIfResFail_(h)											\
	do {															\
		if ((h) == nil) {											\
			OSErr	__theErr = ResError();							\
			if (__theErr == kNoErr) {								\
				__theErr = resNotFound;								\
			}														\
			Throw_(__theErr);										\
		}															\
	} while (false)
	
// Used quite a  bit in Utilities, Messaging, Protocols, Routing
#define ThrowIfMemFail_(p)	ThrowIfNULL_(p)
/*#define	ThrowIfMemFail_(p)											\
	do {															\
		if ((p) == nil) {											\
			OSErr	__theErr = MemError();							\
			if (__theErr == kNoErr) __theErr = kMemFullErr;			\
			Throw_(__theErr);										\
		}															\
	} while (false)
*/ 
// Used in Utilities, Networking, Protocols
#define	ThrowIf_(test)												\
	do {															\
		if (test) Throw_(err_AssertFailed);							\
	} while (false)


// Used in Utilities, Protocols, Routing
#define	ThrowIfNot_(test)											\
	do {															\
		if (!(test)) Throw_(err_AssertFailed);						\
	} while (false)

// Not used
#define	FailOSErr_(err)		ThrowIfOSErr_(err)

// Not used
#define FailNIL_(ptr)		ThrowIfNil_(ptr)

#define Assert_(test)	\
		do {										\
			if (!(test)) Throw_(err_AssertFailed);	\
		} while (false)



#endif // __UException_H__
