lib/errCatch.c

Go to the documentation of this file.
00001 /* errCatch - help catch errors so that errAborts aren't
00002  * fatal, and warn's don't necessarily get printed immediately. 
00003  * Note that error conditions caught this way will tend to
00004  * leak resources unless there are additional wrappers. 
00005  *
00006  * Typical usage is
00007  * errCatch = errCatchNew();
00008  * if (errCatchStart(errCatch))
00009  *     doFlakyStuff();
00010  * errCatchEnd(errCatch);
00011  * if (errCatch->gotError)
00012  *     warn(errCatch->message->string);
00013  * errCatchFree(&errCatch); 
00014  * cleanupFlakyStuff();
00015  */
00016 
00017 #include "common.h"
00018 #include "errabort.h"
00019 #include "dystring.h"
00020 #include "errCatch.h"
00021 
00022 static char const rcsid[] = "$Id: errCatch.c,v 1.2 2006/08/10 01:02:47 kent Exp $";
00023 
00024 
00025 struct errCatch *errCatchNew()
00026 /* Return new error catching structure. */
00027 {
00028 struct errCatch *errCatch;
00029 AllocVar(errCatch);
00030 errCatch->message = dyStringNew(0);
00031 return errCatch;
00032 }
00033 
00034 void errCatchFree(struct errCatch **pErrCatch)
00035 /* Free up resources associated with errCatch */
00036 {
00037 struct errCatch *errCatch = *pErrCatch;
00038 if (errCatch != NULL)
00039     {
00040     dyStringFree(&errCatch->message);
00041     freez(pErrCatch);
00042     }
00043 }
00044 
00045 static struct errCatch *errCatchStack = NULL;
00046 
00047 static void errCatchAbortHandler()
00048 /* semiAbort */
00049 {
00050 errCatchStack->gotError = TRUE;
00051 longjmp(errCatchStack->jmpBuf, -1);
00052 }
00053 
00054 static void errCatchWarnHandler(char *format, va_list args)
00055 /* Write an error to top of errCatchStack. */
00056 {
00057 dyStringVaPrintf(errCatchStack->message, format, args);
00058 dyStringAppendC(errCatchStack->message, '\n');
00059 }
00060 
00061 boolean errCatchPushHandlers(struct errCatch *errCatch)
00062 /* Push error handlers.  Not usually called directly. */
00063 {
00064 pushAbortHandler(errCatchAbortHandler);
00065 pushWarnHandler(errCatchWarnHandler);
00066 slAddHead(&errCatchStack, errCatch);
00067 return TRUE;
00068 }
00069 
00070 void errCatchEnd(struct errCatch *errCatch)
00071 /* Restore error handlers and pop self off of catching stack. */
00072 {
00073 popWarnHandler();
00074 popAbortHandler();
00075 if (errCatch != errCatchStack)
00076    errAbort("Mismatch betweene errCatch and errCatchStack");
00077 errCatchStack = errCatch->next;
00078 }
00079 
00080 boolean errCatchFinish(struct errCatch **pErrCatch)
00081 /* Finish up error catching.  Report error if there is a
00082  * problem and return FALSE.  If no problem return TRUE.
00083  * This handles errCatchEnd and errCatchFree. */
00084 {
00085 struct errCatch *errCatch = *pErrCatch;
00086 boolean ok = TRUE;
00087 if (errCatch != NULL)
00088     {
00089     errCatchEnd(errCatch);
00090     if (errCatch->gotError)
00091         {
00092         ok = FALSE;
00093         warn(errCatch->message->string);
00094         }
00095     errCatchFree(pErrCatch);
00096     }
00097 return ok;
00098 }
00099 

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