// utf-8

/*	Copyright  (c)	Günter Woigk   1999-2003
  					mailto:kio@little-bat.de

	This file is free software

 	This program is distributed in the hope that it will be useful,
 	but WITHOUT ANY WARRANTY; without even the implied warranty of
 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  

 	Permission to use, copy, modify, distribute, and sell this software and
 	its documentation for any purpose is hereby granted without fee, provided
 	that the above copyright notice appear in all copies and that both that
 	copyright notice and this permission notice appear in supporting
 	documentation, and that the name of the copyright holder not be used
 	in advertising or publicity pertaining to distribution of the software
 	without specific, written prior permission. The copyright holder makes no
 	representations about the suitability of this software for any purpose.
 	It is provided "as is" without express or implied warranty.

 	THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 	INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 	EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 	CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 	DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 	TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 	PERFORMANCE OF THIS SOFTWARE.


	error exits & security levels
	-----------------------------

	1999-01-01 kio	first work on this file
	1999-03-19 kio	added license
	2002-02-05 kio	cocoa version
	2002-03-02 kio	classic/unix/cocoa stuff
	2003-05-24 kio	added some docs


HOWTO:

	Each source file should start with a "#define SAFE .." for the current
	debugging level of the file before including this header.
	This file should be the first to be (implicitely) included.
	Typically this is done by (implicitely) including "kio.h" as first file.
	Note: this works just like setting the log level with "#define LOG ..".


There are 5 suggested security levels:

	#define SAFE=4		debugging:		hunting a bug
	#define	SAFE=3		alpha state:	module-internal sanity checks enabled
	#define SAFE=2		beta state: 	cross-module sanity checkings enabled
	#define SAFE=1		stable release:	data based on externally supplied data still doublechecked
	#define	SAFE=0		proven bugfree:	rare!

	better be too cautious!


	These states are not meant to trap expectable illegal data
	but to trap forbidden, impossible, unexpectable conditions!

	e.g.:
	1) *NOT* to test for new() returning NULL (don't kill me, macro OMEM() just does this..)
	2) *BUT* for testing preconditions of functions which are expected and required.


These are the basic test macros:

	XSAFE          et.al.:	tests the value of SAFE
	XTRAP(<test>)  et.al.:	perform <test> and abort if result is true (just opposed to "assert")
	XCheck(<proc>) et.al.:	call test procedure <proc>

	These macros have variants which differ in the amount of X's:
	Each test is only enabled and compiled into the code if the current safety level of SAFE
	is at least as high as the amount of X's. Otherwise the whole test will not generate any code.


Examples:

	source:							printed:

	ABORT("too tired");			--> sorry, a fatal error occured: main.cc in line 123: too tired
	NIMP();						--> sorry, a fatal error occured: main.cc in line 123: not implemented
	IERR();						--> sorry, a fatal error occured: main.cc in line 123: internal error
	a=OMEM(sizeof(*a));			--> sorry, a fatal error occured: main.cc in line 123: out of memory
	TRAP(0<0);					--> sorry, a fatal error occured: main.cc in line 123: internal error
	if (XXSAFE) TRAP(s==NULL);
	XXTRAP(s==NULL);

	void Check(int a);
	void Check(int a, int b);
	XCHECK(arg1,arg2);
	XXCHECK(anton);


Global override and default:

	If the file "config.h" (#included by kio.h) #defines GLOB_SAFE then this value overrides the
	value #defined for SAFE in all files.

	If neither SAFE nor GLOB_SAFE are defined for a file, SAFE is #defined to 1 in kio.h.
*/



#ifndef _abort_h_
#define _abort_h_


#include	"kio.h"


	#define	DEBUGGING		4
	#define	ALPHASTATE		3
	#define	BETASTATE		2
	#define	STABLESTATE		1
	#define	PROVENBUGFREE	0


	#define	ABORT(X)	Abort ( __FILE__, __LINE__, X )
	#define	NIMP()		Abort ( __FILE__, __LINE__, "not implemented" )
	#define	IERR()		Abort ( __FILE__, __LINE__, "internal error" )
	#define	OMEM(X)		if ( (X) ) 	{} else Abort ( __FILE__, __LINE__, "out of memory" )
	#define	TRAP(X)		if ( !(X) )	{} else IERR()


	#define	XSAFE		(SAFE>=1)
	#define	XXSAFE		(SAFE>=2)
	#define	XXXSAFE		(SAFE>=3)
	#define	XXXXSAFE	(SAFE>=4)


	#define	XTRAP(X)	if ( !XSAFE )	{} else TRAP(X)
	#define	XXTRAP(X)	if ( !XXSAFE ) 	{} else TRAP(X)
	#define	XXXTRAP(X)	if ( !XXXSAFE ) {} else TRAP(X)
	#define	XXXXTRAP(X)	if ( !XXXXSAFE ){} else TRAP(X)


	#define	XCheck		if ( !XSAFE )	{} else Check
	#define	XXCheck		if ( !XXSAFE )	{} else Check
	#define	XXXCheck	if ( !XXXSAFE )	{} else Check
	#define	XXXXCheck	if ( !XXXXSAFE ){} else Check


#if defined(_MACINTOSH)
	#define	alrt_alert		666
	#define	alrt_inform		667
	#define	alrt_warn		668
	#define	alrt_yesno		669
	#define	alrt_yesnocan	670
	#define alrt_susquit	671
	extern int	ShowAlert 	( short n, cstr s=0, cstr t=0, cstr u=0, cstr v=0 );
	inline int	ShowAlert 	( cstr s, cstr t=0, cstr u=0, cstr v=0 )		{ return ShowAlert(alrt_alert, s,t,u,v); }
	inline int	ShowInfo 	( cstr s, cstr t=0, cstr u=0, cstr v=0 )		{ return ShowAlert(alrt_inform,s,t,u,v); }
	inline int	ShowWarning	( cstr s, cstr t=0, cstr u=0, cstr v=0 )		{ return ShowAlert(alrt_warn,  s,t,u,v); }
	inline bool Confirm 	( cstr s, cstr t=0, cstr u=0, cstr v=0 )		{ return ShowAlert(alrt_yesno,s,t,u,v)==1 ? yes : no; }
#endif

	extern void	Abort		( cstr s, cstr t=0, cstr u=0  );		// => abort()
	extern void	Abort		( cstr file, long line,  cstr text );	// => abort()
	inline void Abort		( cstr file, long line,  OSErr err )	{ Abort(file,line,strerror(err));   }
	inline void	Abort		( cstr file, long line )				{ Abort(file,line,strerror(errno)); }


#endif








