• Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

ut_assert.h

Go to the documentation of this file.
00001 /* -*- mode: C++; tab-width: 4; c-basic-offset: 4; -*- */
00002 
00003 /* AbiSource Program Utilities
00004  * Copyright (C) 1998 AbiSource, Inc.
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License
00008  * as published by the Free Software Foundation; either version 2
00009  * of the License, or (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00019  * 02110-1301 USA.
00020  */
00021 
00022 #ifndef UT_ASSERT_H
00023 #define UT_ASSERT_H
00024 
00025 #ifdef HAVE_CONFIG_H
00026 #include "config.h"
00027 #endif
00028 
00029 #include "ut_debugmsg.h"
00030 
00031 // TODO move these declarations into platform directories.
00032 
00033 #if (defined (WIN32) || defined (_WIN32) || defined (_WIN64))
00034 // The 'cool' win32 assert, at least with VC6, corrups memory (probably calling sprintf on
00035 // a static buffer without checking bounds), so we implement our own assert dialog, which
00036 // is even cooler. TF
00037 
00038 #include "ut_types.h"
00039 
00040 #ifdef NDEBUG
00041 #  define UT_ASSERT(x)
00042 #else
00043 // This function is implemented in ut_Win32Misc.cpp. It is not declared in any header file (it is
00044 // only to be referenced from here and we want to reduce the files we include here to a
00045 // bare minimum for performance reasons, as this file gets included from pretty much
00046 // everywhere).
00047 extern int ABI_EXPORT UT_Win32ThrowAssert(const char * pCondition, const char * pFile, int iLine, int iCount);
00048 
00049 // The best way of stepping into debugger is by generating the appropriate interupt
00050 // instruction, so if we are on Intel x86, we will issue int 3.  If we are not on x86, we
00051 // will use the win32 DebugBreak() function (the disadvantage of that is that the
00052 // execution is interupted not in our code, but in one of the system libs, so you have to
00053 // step out of that system function to get into our code; its rather non-intuitive.
00054 
00055 #  undef UT_DEBUG_BREAK
00056 
00057 // I am not sure which is the standard GCC macro for the x86 platform; we are supposed to
00058 // be able to get all the predefined macros by running 'cpp -dM' but it would not work on
00059 // my cygwin
00060 #  if defined(__GNUC__) && (defined(_X86) || defined(__i386) || defined(i386))
00061      // Inline assembly for GCC on x86
00062 #    define UT_DEBUG_BREAK asm("int3");
00063 #  elif defined(__GNUC__) && (defined(__ia64) || defined(ia64))
00064 #    error "This branch has not been tested."
00065      // On Itanium we use the intrinsic function __break(); defined in ia64intrin.h
00066      // I am not sure whether we need to tell the compiler this one is intrinsic (MSVC
00067      // uses a #pragma for this
00068      void __break(int);
00069 #    define UT_DEBUG_BREAK __break(0x80016);
00070 #  elif defined(_MSC_VER) && defined(_M_IX86)
00071      // inline assmebly for MSVC on x86
00072 #    define UT_DEBUG_BREAK _asm {int 3}
00073 #  elif defined(_MSC_VER) && (defined(_M_IA64) || defined(_M_AMD64))
00074 #    error "This branch has not been tested."
00075      // On Itanium we use the intrinsic function __break();
00076      // I assume this will also work for AMD64, but I am not 100% sure
00077      void __break(int);
00078      // this forces __break() to be generated as inline code (see MSDN)
00079 #    pragma intrinsic (__break)
00080 #    define UT_DEBUG_BREAK __break(0x80016);
00081 #  endif
00082 
00083 # ifndef UT_DEBUG_BREAK
00084 // Some compiler/architecture for which we do not know how to generate inline assembly to pass
00085 // control to the debugger; we use win32s DebugBreak().
00086 //
00087 // TODO !!! This currently does not work; if someone one day wants to build AW on non-x86
00088 // win32 architecture, they will need to fix this (including <windows.h> from here, which
00089 // is what would work, screws up things in MS Word importer, because the wv library
00090 // redefines some of the win32 structures; but we probably do not want to include
00091 // windows.h from here anyway because of the overhead -- ut_assert.h gets included in
00092 // almost everything.). Really, we want to do something similar as we do for x86.
00093 #  error "Proper implementation needed for this compiler/architecture"
00094 
00095 #    ifndef _WINBASE_
00096        __declspec(dllimport) void __stdcall DebugBreak(void);
00097 #    endif /* ifdef _WINBASE_ */
00098 
00099 #    define UT_DEBUG_BREAK DebugBreak();
00100 #  endif /* ifndef UT_DEBUG_BREAK */
00101 
00102 // We want to track the number of times we have been through this assert and have the
00103 // option of disabling this assert for the rest of the session; we use the __iCount and
00104 // __bOnceOnly vars for this (this adds a few bytes to the code and footprint, but on
00105 // large scale of things, this is quite negligible for the debug build).
00106 #define UT_ASSERT(x)                                                        \
00107 {                                                                           \
00108     static bool __bOnceOnly = false;                                        \
00109     static long __iCount = 0;                                               \
00110     if(!__bOnceOnly && !(x))                                                \
00111     {                                                                       \
00112         __iCount++;                                                         \
00113         int __iRet = UT_Win32ThrowAssert(#x,__FILE__, __LINE__, __iCount);  \
00114         if(__iRet == 0)                                                     \
00115         {                                                                   \
00116            UT_DEBUG_BREAK                                                   \
00117         }                                                                   \
00118         else if(__iRet < 0)                                                 \
00119         {                                                                   \
00120             __bOnceOnly = true;                                             \
00121         }                                                                   \
00122     }                                                                       \
00123 }
00124 
00125 #endif // ifdef NDEBUG
00126 
00127 #else
00128 
00129     // A Unix variant, possibly Gnome.
00130 
00131 #   ifdef NDEBUG
00132 
00133         // When NDEBUG is defined, assert() does nothing.
00134         // So we let the system header files take care of it.
00135 #       if 0 //defined(TOOLKIT_COCOA)
00136 // Please keep the "/**/" to stop MSVC dependency generator complaining.
00137 #           include  "xap_CocoaAssert.h"
00138 #           define UT_ASSERT(expr)                              \
00139             ((void) ((expr) ||                              \
00140                 (XAP_CocoaAssertMsg(#expr,                  \
00141                                   __FILE__, __LINE__),      \
00142                  0)))
00143 
00144 #       else
00145 #           include <assert.h>
00146 #           define UT_ASSERT assert
00147 #       endif
00148 #   else
00149         // Otherwise, we want a slighly modified behavior.
00150         // We'd like assert() to ask us before crashing.
00151         // We treat asserts as logic flaws, which are sometimes
00152         // recoverable, but that should be noted.
00153 
00154 #       include <assert.h>
00155 // Please keep the "/**/" to stop MSVC dependency generator complaining.
00156 #       include  "ut_unixAssert.h"
00157 #       define UT_ASSERT(expr)                              \
00158         {                                       \
00159             if (!ut_g_silent) { \
00160                 static bool __bOnceOnly = false;                \
00161                 if (!__bOnceOnly && !(expr)) {                        \
00162                     if (UT_UnixAssertMsg(#expr, __FILE__, __LINE__) == -1) { \
00163                         __bOnceOnly = true;                             \
00164                     } \
00165                 }     \
00166             } \
00167         }
00168 #   endif
00169 
00170 #endif
00171 
00172 
00176 #define UT_NOT_IMPLEMENTED      0
00177 
00181 #define UT_SHOULD_NOT_HAPPEN    0
00182 
00186 #define UT_TODO                 0
00187 
00191 #define UT_NOT_REACHED 0
00192 
00196 #define UT_ASSERT_NOT_REACHED() UT_ASSERT(UT_NOT_REACHED)
00197 
00201 #define UT_ASSERT_HARMLESS(cond) UT_ASSERT(cond)
00202 
00206 #define UT_return_if_fail(cond) if (!(cond)) { UT_ASSERT(cond); return; }
00207 
00211 #define UT_return_val_if_fail(cond, val) if (!(cond)) { UT_ASSERT(cond); return (val); }
00212 
00216 #define UT_throw_if_fail(cond, val) if (!(cond)) { UT_ASSERT(cond); throw val; }
00217 
00221 #define UT_continue_if_fail(cond) if (!(cond)) { UT_ASSERT(cond); continue; }
00222 
00223 #endif /* UT_ASSERT_H */

Generated on Sun Feb 14 2021 for AbiWord by  doxygen 1.7.1