lib/errabort.c

Go to the documentation of this file.
00001 /* ErrAbort.c - our error handler. 
00002  *
00003  * This maintains two stacks - a warning message printer
00004  * stack, and a "abort handler" stack.
00005  *
00006  * By default the warnings will go to stderr, and
00007  * aborts will exit the program.  You can push a
00008  * function on to the appropriate stack to change
00009  * this behavior.  The top function on the stack
00010  * gets called.
00011  *
00012  * This file is copyright 2002 Jim Kent, but license is hereby
00013  * granted for all use - public, private or commercial. */
00014 
00015 #include "common.h"
00016 #include "errabort.h"
00017 
00018 static char const rcsid[] = "$Id: errabort.c,v 1.13 2004/11/10 00:10:50 markd Exp $";
00019 
00020 static void defaultVaWarn(char *format, va_list args)
00021 /* Default error message handler. */
00022 {
00023 if (format != NULL) {
00024     fflush(stdout);
00025     vfprintf(stderr, format, args);
00026     fprintf(stderr, "\n");
00027     }
00028 }
00029 
00030 #define maxWarnHandlers 20
00031 static WarnHandler warnArray[maxWarnHandlers] = {defaultVaWarn,};
00032 static int warnIx = 0;
00033 
00034 void vaWarn(char *format, va_list args)
00035 /* Call top of warning stack to issue warning. */
00036 {
00037 warnArray[warnIx](format, args);
00038 }
00039 
00040 void warn(char *format, ...)
00041 /* Issue a warning message. */
00042 {
00043 va_list args;
00044 va_start(args, format);
00045 vaWarn(format, args);
00046 va_end(args);
00047 }
00048 
00049 void errnoWarn(char *format, ...)
00050 /* Prints error message from UNIX errno first, then does rest of warning. */
00051 {
00052 char fbuf[512];
00053 va_list args;
00054 va_start(args, format);
00055 sprintf(fbuf, "%s\n%s", strerror(errno), format);
00056 vaWarn(fbuf, args);
00057 va_end(args);
00058 }
00059 
00060 
00061 void pushWarnHandler(WarnHandler handler)
00062 /* Set abort handler */
00063 {
00064 if (warnIx >= maxWarnHandlers-1)
00065     errAbort("Too many pushWarnHandlers, can only handle %d\n", maxWarnHandlers-1);
00066 warnArray[++warnIx] = handler;
00067 }
00068 
00069 void popWarnHandler()
00070 /* Revert to old warn handler. */
00071 {
00072 if (warnIx <= 0)
00073     errAbort("Too many popWarnHandlers\n");
00074 --warnIx;
00075 }
00076 
00077 static void defaultAbort()
00078 /* Default error handler exits program. */
00079 {
00080 if ((getenv("ERRASSERT") != NULL) || (getenv("ERRABORT") != NULL))
00081     abort();
00082 else
00083     exit(-1);
00084 }
00085 
00086 #define maxAbortHandlers 12
00087 static AbortHandler abortArray[maxAbortHandlers] = {defaultAbort,};
00088 static int abortIx = 0;
00089 
00090 void noWarnAbort()
00091 /* Abort without message. */
00092 {
00093 abortArray[abortIx]();
00094 exit(-1);               /* This is just to make compiler happy. 
00095                          * We have already exited or longjmped by now. */
00096 }
00097 
00098 void vaErrAbort(char *format, va_list args)
00099 /* Abort function, with optional (vprintf formatted) error message. */
00100 {
00101 vaWarn(format, args);
00102 noWarnAbort();
00103 }
00104 
00105 void errAbort(char *format, ...)
00106 /* Abort function, with optional (printf formatted) error message. */
00107 {
00108 va_list args;
00109 va_start(args, format);
00110 vaErrAbort(format, args);
00111 va_end(args);
00112 }
00113 
00114 void errnoAbort(char *format, ...)
00115 /* Prints error message from UNIX errno first, then does errAbort. */
00116 {
00117 char fbuf[512];
00118 va_list args;
00119 va_start(args, format);
00120 sprintf(fbuf, "%s\n%s", strerror(errno), format);
00121 vaErrAbort(fbuf, args);
00122 va_end(args);
00123 }
00124 
00125 void pushAbortHandler(AbortHandler handler)
00126 /* Set abort handler */
00127 {
00128 if (abortIx >= maxAbortHandlers-1)
00129     errAbort("Too many pushAbortHandlers, can only handle %d\n", maxAbortHandlers-1);
00130 abortArray[++abortIx] = handler;
00131 }
00132 
00133 void popAbortHandler()
00134 /* Revert to old abort handler. */
00135 {
00136 if (abortIx <= 0)
00137     errAbort("Too many popAbortHandlers\n");
00138 --abortIx;
00139 }
00140 
00141 static void debugAbort()
00142 /* Call the debugger. */
00143 {
00144 fflush(stdout);
00145 assert(FALSE);
00146 defaultAbort();
00147 }
00148 
00149 void pushDebugAbort()
00150 /* Push abort handler that will invoke debugger. */
00151 {
00152 pushAbortHandler(debugAbort);
00153 }
00154 
00155 static void warnAbortHandler(char *format, va_list args)
00156 /* warn handler that also aborts. */
00157 {
00158 defaultVaWarn(format, args);
00159 noWarnAbort();
00160 }
00161 
00162 void pushWarnAbort()
00163 /* Push handler that will abort on warnings. */
00164 {
00165 pushWarnHandler(warnAbortHandler);
00166 }

Generated on Tue Dec 25 18:39:30 2007 for blat by  doxygen 1.5.2