/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 *
 * The contents of this file are subject to the Netscape Public License
 * Version 1.0 (the "NPL"); you may not use this file except in
 * compliance with the NPL.  You may obtain a copy of the NPL at
 * http://www.mozilla.org/NPL/
 *
 * Software distributed under the NPL is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
 * for the specific language governing rights and limitations under the
 * NPL.
 *
 * The Initial Developer of this code under the NPL is Netscape
 * Communications Corporation.  Portions created by Netscape are
 * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
 * Reserved.
 */
// errcode.h

#ifndef _ERRCODE_H_
#define _ERRCODE_H_


/* 
**	Error classifications (Database, RPC, Network, etc) 
**
**	Each error classification defines a range of up to 0xffff error codes.
**
**	The top word of an msgERR is the classification, the low byte is an error 
**	offset within that classification.
**
**	For diagnostic purposes, each classification can register it's strings for GetErrorString
**	support.  These are NOT nationalizable strings; the string tables are autogenerated from the 
**	MsgError() macro machinery, not stored in .rc files.  They're intended for use in debugging,
**	logfiles, etc.
*/

typedef uint32 MsgERR;
typedef MsgERR msgErrorClass;

#define msgErrorDb 		0xFF000000	/* DB errors (generic) */
#define msgErrorVw 		0xF8000000	/* View layer */
#define msgErrorMisc	0xF0000000	/* Random miscellaneous errors. */
#define msgErrorOk 		0x00000000

/*
** GetErrorClass(msgERR)
**
**		Returns classification range for an error.
**
**		For example,
**			if (GetErrorClass(err) == msgErrorRp) 
**				Alert("Problem chatting with forum service.");
**
*/
#define GetErrorClass(err)	((err) & ((MsgERR) 0xFFFF0000))

/*
** RegisterErrorClass (msgErrorClass, pFn)
**
**	Register a function to return error-strings in the given class.
**
**	(Note:  this could be best done by automatically building a linked list of 
**			diagnostic routines/classes - by simply using a C++ class for error 
**			classes, and a static constructor to link each class into the queue.
**			However, we've had problems with static constructors within DLL's
**			that use MFC and DLL's on NT - so we're avoiding them for now.)
**
**	See dberror.cpp (in the database) for an example of an auto-generated diagnostic
**	map.  The error-code to string mapping function implementation can be generated 
**	automatically, but the client must register the function manually.
**
**	There is no limit on how many ranges a given diagnostic function might handle.  
**	The function must be registered once for each class, of course.
**
**	Normally there will be a function for every specific .h that defines error codes
**	(whether that .h defines one or more classes of error codes).  For example, 
**	dberror.h defines 3 error class ranges, so the DB registers one diagnostic function 
**	that handles those 3 classes accordingly.
**
*/
//typedef const char * (msgCALLBACK *msgErrorDiagnosticCallback) (msgERR);

//extern void RegisterErrorClass (msgErrorClass, msgErrorDiagnosticCallback pFn);

/*
** NOTE: remainder of this file may be multiply-included  
**		 place all one-shot definitions above this point
*/
#endif // __msgERROR_H__


/*
**	Within an error-class range, the errors are allocated/declared independently. 
**	See, for example, dberror.h, rperror.h, ecerror.h, etc.
*/

/* msgError:  wrapper-macro for an error code definition */
#ifndef MsgError
#define	MsgError(errorclass, name, offset)		const MsgERR name = (MsgERR) (errorclass + offset);
#endif

/* msgErrorDiagnostic:  causes wrapper-macro to generate a diagnostic string */
#ifndef MsgErrorDiagnostic
#define MsgErrorDiagnostic(errorclass, name, offset)	case ((errorclass)+(offset)):	return #name;
#endif

/*
** msgSUCCESS - 	universal no-error indication (zero).  
**				'! msgERR' is guaranteed to mean success.
*/
#ifndef MsgErrorBasic
#define MsgErrorBasic
MsgError	(msgErrorOk, eSUCCESS, 				0x0000)	/*  0   Success */
MsgError	(msgErrorMisc, eUNKNOWN,		    0x0001)	//  1   Something weird
														//  	happened.
#endif

