WvStreams
wvassert.h
00001 /* -*- Mode: C++ -*-
00002  * Worldvisions Weaver Software:
00003  *   Copyright (C) 2005 Net Integration Technologies, Inc.
00004  *
00005  * Helper classes and functions to add more information to WvCrashes.
00006  */
00007 #ifndef __WVASSERT_H
00008 #define __WVASSERT_H
00009 
00010 #include <assert.h>
00011 
00012 #include "wvcrash.h"
00013 #include "wvstring.h"
00014 
00015 // WvCrash allows you to print a programme's last will and testament.
00016 // That is, a little note about what it was hoping to do before it
00017 // died.
00018 //
00019 // This helper class lets you write a will, and when it gets
00020 // destroyed, it will restore the old will from before.  This lets you
00021 // safely nest them.
00022 class WvCrashWill
00023 {
00024 public:
00025     // Leave a will behind.
00026     WvCrashWill(const char *will);
00027     WvCrashWill(WVSTRING_FORMAT_DECL);
00028 
00029     // Restore the will that was there before you created this object.
00030     ~WvCrashWill();
00031 
00032     // Rewrite the will you're leaving behind.
00033     void rewrite(const char *will);
00034     void rewrite(WVSTRING_FORMAT_DECL);
00035 private:
00036     WvString old_will;
00037 };
00038 
00039 #if !defined(__GLIBC__)
00040 
00041 # define wvassert(expr, args...)            assert(expr)
00042 # define wvassert_perror(errnum)            perror(errnum)
00043 
00044 #elif defined(NDEBUG)
00045 
00046 # define wvassert(expr, args...)        (__ASSERT_VOID_CAST (0))
00047 # define wvassert_perror(errnum)        (__ASSERT_VOID_CAST (0))
00048 
00049 #else // Not NDEBUG
00050 
00051 static inline void __wvcrash_leave_will()
00052 {
00053 }
00054 
00055 static inline void __wvcrash_leave_will(const char *will)
00056 {
00057     wvcrash_leave_will(will);
00058 }
00059 
00060 static inline void __wvcrash_leave_will(WVSTRING_FORMAT_DECL)
00061 {
00062     wvcrash_leave_will(WvFastString(WVSTRING_FORMAT_CALL));
00063 }
00064 
00065 // Use this function instead of assert().  You may also leave parameters
00066 // at the end, which allow you to log messages.  For instance:
00067 //
00068 // wvassert(a == b, "a: '%s'\n b: '%s'", a, b);
00069 # define wvassert(expr, args...) \
00070   (__ASSERT_VOID_CAST ((expr) ? 0 :                                           \
00071                        (__wvcrash_leave_will (args),                          \
00072                         (__assert_fail (__STRING(expr), __FILE__, __LINE__,   \
00073                                         __ASSERT_FUNCTION), 0))))
00074 
00075 // Use this function instead of assert_perror().  You may also leave
00076 // parameters at the end, which allow you to log messages.  For instance:
00077 //
00078 // wvassert(errno, "Error trying to read file: '%s'", filename);
00079 #  define wvassert_perror(errnum, args...) \
00080   (__ASSERT_VOID_CAST (!(errnum) ? 0 :                                        \
00081                        (__wvcrash_leave_will (args),                          \
00082                         (__assert_perror_fail ((errnum), __FILE__, __LINE__,  \
00083                                                __ASSERT_FUNCTION), 0))))
00084 
00085 #endif // NDEBUG
00086 
00087 #endif // WVASSERT_H