/* error.h: for printing warning/error/fatal error messages */ #ifndef _RPK_ERROR_H_ #define _RPK_ERROR_H_ #ifdef __cplusplus extern "C" { #endif #ifndef __cplusplus #ifndef NULL #define NULL (char *)0 #endif /*NULL*/ #endif #ifndef FALSE #define FALSE 0 #endif /*FALSE*/ #ifndef TRUE #define TRUE 1 #endif /*TRUE*/ #ifdef NAN_CHECKS /* A number of interesting macro's when you get in NaN or Inf trouble... */ #ifndef LINUX /* thus SGI, what about other systems ?? */ #include "ieeefp.h" #define ISINF(d) ((fpclass((double)d) == FP_NINF)||(fpclass((double)d) == FP_PINF)) #else #define ISINF(d) (isinf(d)) #endif #define ISNAN(d) (isnan((double)d)) #define ISNANORINF(d) ((ISNAN(d))||(ISINF(d))) #ifndef KILLFPE /* From nan.h (SGI include files) */ #include "signal.h" #include "unistd.h" #define KILLFPE() (void) kill(getpid(), 8) #endif /* PNAN prints een error message if the (double) argument is NaN */ #define PNAN(d) {if(ISNAN(d)) printf("NaN %s, file %s, line %i, val %f\n", #d, __FILE__, __LINE__, (d));} #define PINF(d) {if(ISINF(d)){printf("Inf %s, file %s, line %i, val %f\n", #d, __FILE__, __LINE__, (d));}} #define PNANORINF(d) {PNAN(d); PINF(d);} /* Some macro's to generate a core dump if a double is NaN of Inf */ #define KILLNAN(d) {if(ISNAN(d)) {KILLFPE();}} #define KILLINF(d) {if(ISINF(d)) {KILLFPE();}} #define KILLNANORINF(d) {KILLNAN(d); KILLINF(d);} #else /* ! NAN_CHECKS */ /* No NaN or Inf checking. Tests return false, prints/kills do nothing */ #define ISINF(d) (FALSE) #define ISNAN(d) (FALSE) #define ISNANORINF(d) (FALSE) #define PNAN(d) #define PINF(d) #define PNANORINF(d) #define KILLNAN(d) #define KILLINF(d) #define KILLNANORINF(d) #endif /* prints an error message. Behaves much like printf. The first argument is the * name of the routine in which the error occurs (optional - can be NULL) */ extern void Error(char *routine, char *text, ...); /* same, but for warning messages */ extern void Warning(char *routine, char *text, ...); /* prints an informational message. Informational message are NOT printed * unless error.c is compiled with -DINFO. */ extern void Info(char *routine, char *text, ...); /* same, but for fatal error messages (also aborts the program). * First argument is a return code. We use negative return codes for * "internal" error messages. */ extern void Fatal(int errcode, char *routine, char *text, ...); /* returns FALSE if no errors have been reported since the last call to this * routine. */ extern int ErrorOccurred(void); /* set state to "no errors occured" */ extern void ErrorReset(void); /* Assert * With assert, tests can be included in the program that will lead to * a core dump (debug) or fatal error message (non debug) if they * are not fulfilled. */ #ifdef DEBUGASSERTS #define Assert(test, message) \ if(!(test)) { Error(NULL, \ message " in file : " __FILE__ " line : %i\n",__LINE__); \ abort(); \ } #else #define Assert(test, message) \ if(!(test)) Fatal(-1, NULL, \ message " in file :" __FILE__ " line : %i\n",__LINE__); #endif #ifdef __cplusplus } #endif #endif /*_RPK_ERROR_H_*/