#ifndef _ERROR
#define _ERROR

#include <sys/types.h>
#include "machine.h"
#ifndef MAXERROR
#include "errtbl.h"
#endif

/*
 * Let's get annoying...
 */
typedef struct _Errer
{
  Card32 error;
  caddr_t description;
} Errer;

#define ERRORDEPTH 50
extern Errer Errur[ERRORDEPTH];
extern int Error_StackTop;
extern char *errtbl[MAXERROR+1];

/*
 * Error type coding
 *
 *    ldssmccccciiiiiieeeeeeeeeeeeeeee
 *     \\\\   \    \          \____________ error
 *      \\\\   \    \______________________ instance
 *       \\\\   \__________________________ class
 *        \\\\_____________________________ description is malloced
 *         \\\_____________________________ severity
 *          \\_____________________________ debug
 *           \_____________________________ log
 */

#define LMASK 0x80000000
#define DMASK 0x40000000
#define SMASK 0x30000000
#define MMASK 0x08000000
#define CLMASK 0x07C00000
#define IMASK 0x003F0000
#define EMASK 0x0000FFFF

#define LBITS 28
#define S_TRIVIA (0<<LBITS)
#define S_INFO (1<<LBITS)
#define S_WARNING (2<<LBITS)
#define S_FATAL (3<<LBITS)

typedef int Trap;
#define OK (Trap)0
#define CHECK (Trap)-1

#define Error_Severity (Errur[Error_StackTop].error & SMASK)
#define Error_InfoMalloced (Errur[Error_StackTop].error & MMASK)
#define Error_Class (Errur[Error_StackTop].error & CLMASK)
#define Error_Instance (Errur[Error_StackTop].error & (CLMASK | IMASK))
#define Error (Errur[Error_StackTop].error & ~MMASK)
#define Error_Info (Errur[Error_StackTop].description)

#define Error_Exists (Error_StackTop == 0 ? OK : CHECK)
/*
#define Error_Pop() (Error_StackTop ? --Error_StackTop : 0)
#define Error_Push(e, d) ((Error_StackTop == ERRORDEPTH - 1) ? \
			  0 : Error_StackTop++), \
  Errur[Error_StackTop].error = e, \
  Errur[Error_StackTop].description = (caddr_t)d
*/
#define Return(e, d) { Error_Push(e, d); return CHECK; }
#define ReturnF(e, d) { Error_Push(e | MMASK, d); return CHECK; }

#define Error_String(e) (((e) & EMASK) < MAXERROR ? errtbl[(e) & EMASK] : errtbl[MAXERROR])

typedef Trap (*Method)();

#endif /* _ERROR */
