Main Page | Class List | Directories | File List | Class Members | File Members

debug.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2003-2005 by David J. Hardy.  All rights reserved.
00003  *
00004  * debug.h
00005  *
00006  * Note that the use of
00007  *
00008  *   do { ... } while (0)
00009  *
00010  * below forces macro calls to be terminated with a semicolon.
00011  * Best to do this whenever bracket grouping { } is needed within
00012  * a macro definition.
00013  */
00014 
00039 #ifndef DEBUG_H
00040 #define DEBUG_H
00041 
00042 #include <stdio.h>
00043 #include <stdlib.h>
00044 
00045 /*
00046  * ERRMSG(msg) - print nil-terminated msg string to stderr
00047  */
00048 #define ERRMSG(msg) \
00049   fprintf(stderr, "ERROR: %s, line %d: %s\n", __FILE__, __LINE__, msg)
00050 
00051 /*
00052  * BUG(msg) - print nil-terminated msg string to stderr and abort
00053  *
00054  * Use for bug catching, for things that should never go wrong
00055  * (activated whether or not debugging support is on).
00056  */
00057 #define BUG(msg) \
00058   do { ERRMSG(msg); abort(); } while (0)
00059 
00060 
00061 #if defined(DEBUG_SUPPORT) || defined(DEBUG_WATCH)
00062 
00063 #include <string.h>
00064 #include <errno.h>
00065 
00066 /*
00067  * ASSERT(expr) - assert macro, expr is evaluated once as (boolean) integer
00068  *
00069  * Tests to see if asserted condition is true.  If it *is not* true, print
00070  * error diagnostics to stderr and abort.
00071  */
00072 #define ASSERT(expr) \
00073 do { \
00074   if ( !(expr) ) { \
00075     fprintf(stderr, "ASSERTION FAILED: %s, line %d: \"%s\"\n", \
00076         __FILE__, __LINE__, #expr); \
00077     abort(); \
00078   } \
00079 } while (0)
00080 
00081 /*
00082  * COND(expr) - exceptional condition macro, expr is evaluated once as
00083  *   (boolean) integer
00084  *
00085  * Tests to catch an exception.  If condition *is* true, print error
00086  * diagnostics to stderr and abort.  (Opposite behavior of ASSERT().)
00087  */
00088 #define COND(expr) \
00089 do { \
00090   if ( expr ) { \
00091     fprintf(stderr, "EXCEPTIONAL CONDITION: %s, line %d: \"%s\"\n", \
00092         __FILE__, __LINE__, #expr); \
00093     abort(); \
00094   } \
00095 } while (0)
00096 
00097 /*
00098  * ERRCOND(expr) - exceptional condition macro, expr is evaluated once
00099  *   as (boolean) integer, also calls strerror(errno) for diagnostics.
00100  *
00101  * Tests to catch an exception from C system library call.  Same behavior
00102  * as COND() but diagnostics also returns strerror(errno) message.
00103  */
00104 #define ERRCOND(expr) \
00105 do { \
00106   if ( expr ) { \
00107     fprintf(stderr, "EXCEPTIONAL CONDITION: %s, line %d: \"%s\"\n" \
00108         "SYSTEM ERROR: %s\n", __FILE__, __LINE__, #expr, \
00109         (strerror(errno) ? strerror(errno) : "")); \
00110     abort(); \
00111   } \
00112 } while (0)
00113 
00114 #ifdef DEBUG_WATCH
00115 
00116 /* keep count of debug watches (below) */
00117 static int DEBUG_COUNTER = 0;
00118 
00119 /* can customize debug watches by redefining title */
00120 #ifndef DEBUG_TITLE
00121 #define DEBUG_TITLE "DEBUG"
00122 #endif
00123 
00124 /*
00125  * TEXT(msg) - print text message to stderr
00126  *
00127  * Argument should be a nil-terminated string literal.
00128  */
00129 #define TEXT(t) \
00130 fprintf(stderr, DEBUG_TITLE " %d (%s, line %d) text:  %s\n", \
00131     DEBUG_COUNTER++, __FILE__, __LINE__, t)
00132 
00133 /*
00134  * STR(s) - print to stderr value from string variable
00135  *
00136  * Argument should be a variable of type char * that points to a
00137  * nil-terminated string (or pointer could be NULL).
00138  */
00139 #define STR(str) \
00140 do { \
00141   const char *DEBUG_str = (str); \
00142   (DEBUG_str ? \
00143   fprintf(stderr, DEBUG_TITLE " %d (%s, line %d) string:  (%s)=\"%s\"\n", \
00144       DEBUG_COUNTER++, __FILE__, __LINE__, #str, DEBUG_str) : \
00145   fprintf(stderr, DEBUG_TITLE " %d (%s, line %d) string:  (%s)=(nil)\n", \
00146       DEBUG_COUNTER++, __FILE__, __LINE__, #str)); \
00147 } while (0)
00148 
00149 /*
00150  * INT(i) - print to stderr value from an integer expression
00151  */
00152 #define INT(i) \
00153 fprintf(stderr, DEBUG_TITLE " %d (%s, line %d) int expr: (%s)=%d\n", \
00154     DEBUG_COUNTER++, __FILE__, __LINE__, #i, (int)(i))
00155 
00156 /*
00157  * PTR(p) - print to stderr address of pointer (evaluate as hex expression)
00158  */
00159 #define PTR(p) \
00160 fprintf(stderr, DEBUG_TITLE " %d (%s, line %d) hex addr: (%s)=%p\n", \
00161     DEBUG_COUNTER++, __FILE__, __LINE__, #p, (void *)(p))
00162 
00163 /*
00164  * FLT(x) - print to stderr value from a float or double expression
00165  */
00166 #define FLT(x) \
00167 fprintf(stderr, DEBUG_TITLE " %d (%s, line %d) fp expr:  (%s)=%g\n", \
00168           DEBUG_COUNTER++, __FILE__, __LINE__, #x, (double)(x))
00169 
00170 /*
00171  * VEC(v) - print to stderr component values of 3D vector struct
00172  *   (like mdtypes.h Fvec or Dvec)
00173  *
00174  * Note that since the argument is a struct, it does not matter that
00175  * it is evaluated multiple times.
00176  */
00177 #define VEC(v) \
00178 fprintf(stderr, DEBUG_TITLE " %d (%s, line %d) vec var:  (%s)=(%g %g %g)\n", \
00179     DEBUG_COUNTER++, __FILE__, __LINE__, #v, \
00180     (double)((v).x), (double)((v).y), (double)((v).z))
00181 
00182 #else /* DEBUG_WATCH off */
00183 
00184 #define TEXT(t)
00185 #define STR(s)
00186 #define INT(i)
00187 #define PTR(p)
00188 #define FLT(x)
00189 #define VEC(v)
00190 
00191 #endif /* DEBUG_WATCH */
00192 
00193 #else /* DEBUG_SUPPORT off */
00194 
00195 #define ASSERT(expr)
00196 #define COND(expr)
00197 #define ERRCOND(expr)
00198 
00199 #define TEXT(t)
00200 #define STR(s)
00201 #define INT(i)
00202 #define PTR(p)
00203 #define FLT(x)
00204 #define VEC(v)
00205 
00206 #endif /* DEBUG_SUPPORT */
00207 
00208 #endif /* DEBUG_H */

Generated on Mon Sep 26 10:55:18 2005 for MDX by  doxygen 1.4.4