// utf-8

/*	Copyright  (c)	Günter Woigk   1999-2001
  					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 number and error text definitions

this file provides:

	raising, reading and clearing of errors.
	uses the global errno.	
	errors are stored separately for each thread: kio's dispatcher saves and restores errno!
	note: some OS traps set errno directly, some return an error in a parameter, some require 
	you to query the error with a dedicated method. this is not my fault!...


	cstr ErrorText ( OSErr e )				returns the user-readable text for an OS or 
											application defined error

	cstr ErrorText ( )						returns the user-readable text for the current error

	void SetError ( cstr custommessage );	sets an error with an arbitrary error text
	
	void SetError ( OSErr e );				sets an OS or application defined error

	OSErr GetError ( )						gets the current error 

	void ClearError ( )						clears the current error
						

extending the error code list:
	
	(1) simply use SetError(cstr custommessage) to set arbitrary errors.
		disadvantage: you can't use errno to detect which error exactly happened.
	(2) #define CUSTOMERRORS "myownerrors.h" in your options.h to include more own errors.
	(3) extend etoe[] in errors.cp to map more OS errors to error numbers in this file.
	(4) add errors to the list in this header file.
		do not add application specific errors to this general header file!


	--------------------------------------------------------------------------------------
*/


#ifndef	_errors_h_
#define	_errors_h_

	#include "kio.h"

	extern	char	customError[];

// methods:
	inline	void	ClearError		( )								{ errno=noerror; customError[0]=0; }

	inline	OSErr	Error			( )								{ return errno; }
	inline	bool	NoError			( )								{ return errno==ok; }

	inline	void	ForceError		( OSErr e )						{ errno=e; customError[0]=0; }
	extern	void	ForceError		( OSErr e, cstr custom_msg );
	inline	void	ForceError		( cstr custom_msg )				{ ForceError(-1,custom_msg); }

	inline	void	SetError		( OSErr e )						{ if(!errno) errno=e; }
	inline	void	SetError		( OSErr e, cstr custom_msg )	{ if(!errno) ForceError(e, custom_msg); }
	inline	void	SetError		( cstr custom_msg )				{ if(!errno) ForceError(-1,custom_msg); }

	extern	cstr	ErrorStr		( OSErr e );
	extern	cstr	ErrorStr		( );

	extern	void	PushError		( );
	extern	void	PopError		( );

	#undef errno

// base of free range for application error numbers:
	#if defined(_MACINTOSH)
		#define EBAS	128		// os errors all negative
	#elif defined(_MACOSX)||defined(_COCOA)
		#define	EBAS	-29700	// guessed free range
	#elif defined(_BSD)
		#define EBAS	-29700	// guessed free range
	#elif defined(_SOLARIS)
		#define EBAS	-29700	// guessed free range
	#elif defined(_LINUX)
		#define EBAS	-29700	// guessed free range
	#else
		#error    platform not yet supported: add base of free range for application error numbers here!
	#endif


// error parser macro:
// first  #include: return a (error number)
// second #include: return b (error text; provided for error.cp only!)
	#define 	EMAC(a,b)	a
	enum


#endif
#ifdef EMAC


{
  	EMAC( outofmemory=EBAS,	"out of memory"					),
	EMAC( notimplemented,	"not implemented"				),
	EMAC( notyetimplemented,"not yet implemented"			),
	EMAC( permissiondenied,	"permission denied"				),
	EMAC( parametererror,	"parameter error to function"	),

	EMAC( notanumber,		"not a number"					),	// 0.0/0.0 or string is not a number
	EMAC( numbertoobig,		"number too big"				),	// +/-HUGE_VAL
	EMAC( numbertoosmall,	"number too small"				),	// 0.0 for very small non-zero value
	EMAC( notastring,		"not a string"					),	// String::StrVal()
	EMAC( nofinalquotes,	"unterminated text literal"		),	// String::StrVal()

	// device errors
	EMAC( nosuchservice,	"no such service"				),
	EMAC( notadevice,		"not a device"					),
	EMAC( badfilename,		"bad file name"					),
	EMAC( unknownfiletype,	"unknown file type"				),
	EMAC( controlcode,		"control code"					),
	EMAC( inputbufferempty,	"input buffer empty"			),
	EMAC( outputbufferfull,	"output buffer full"			),
	EMAC( inputnotpossible,	"device not open for input"		),
	EMAC( outputnotpossible,"device not open for output"	),
	EMAC( notsupportedbydev,"operation not supported by device"	),
	EMAC( buffertoosmall,	"buffer too small"				),

	EMAC( ioerror,			"general i/o error"				),
	EMAC( endoffile,		"end of file"					),
	EMAC( dupfilename,		"duplicate filename"			),
	EMAC( fileisbusy,		"file still in use"				),
	EMAC( filenotopen,		"file/stream not open"			),
	EMAC( filealreadyopen,	"file/stream already open"		),
	EMAC( filewritelocked,	"file already open for writing"	),
	EMAC( diskfull,			"disk full!"					),
	EMAC( volumenotfound,	"volume not found"				),
	EMAC( directorynotfound,"directory not found"			),
	EMAC( filenotfound,		"file not found"				),
	EMAC( filenotexecutable,"file is not executable"		),
	EMAC( emptyfilehandle,	"empty file handle"				),

	EMAC( diskwriteprot,	"disk is write protected"		), 	// hardware
	EMAC( volumewriteprot,	"volume is write protected"		),	// software
	EMAC( filewriteprot,	"file is write protected"		),	// software

	EMAC( typemismatch,		"type mismatch in operator"		),	// class Var
	EMAC( corrupteddata,	"corrupted data"				),	// melt()

	EMAC( unknownconversion,"unknown conversion type"		), 	// utf-8
	EMAC( truncatedchar,	"truncated character"			),	// utf-8
	EMAC( illegaloverlong,	"illegal overlong encoding"		),	// utf-8
	EMAC( illegalchar,		"illegal character"				),	// utf-8
	EMAC( unexpectedfup,	"utf-8 char started with fup"	),	// utf-8
	EMAC( notindestcharset,	"character not in destination character set" ), // utf-8
	EMAC( missingquotes,	"missing quote(s) '\"'"			),	// utf-8
	EMAC( unmaskedamp,		"unmasked ampercent '&'"		),	// utf-8
	EMAC( endofsource,		"end of source buffer"			),	// utf-8


// custom application error messages
#ifdef CUSTOMERRORS
	#include CUSTOMERRORS
#endif
};


#undef EMAC
#endif











