• 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 // TODO move these declarations into platform directories.
00030 
00031 #if (defined (WIN32) || defined (_WIN32) || defined (_WIN64))
00032 // The 'cool' win32 assert, at least with VC6, corrups memory (probably calling sprintf on
00033 // a static buffer without checking bounds), so we implement our own assert dialog, which
00034 // is even cooler. TF
00035 
00036 #include "ut_types.h"
00037 
00038 #ifdef NDEBUG
00039 #  define UT_ASSERT(x)
00040 #else
00041 // This function is implemented in ut_Win32Misc.cpp. It is not declared in any header file (it is
00042 // only to be referenced from here and we want to reduce the files we include here to a
00043 // bare minimum for performance reasons, as this file gets included from pretty much
00044 // everywhere).
00045 extern int ABI_EXPORT UT_Win32ThrowAssert(const char * pCondition, const char * pFile, int iLine, int iCount);
00046 
00047 // The best way of stepping into debugger is by generating the appropriate interupt
00048 // instruction, so if we are on Intel x86, we will issue int 3.  If we are not on x86, we
00049 // will use the win32 DebugBreak() function (the disadvantage of that is that the
00050 // execution is interupted not in our code, but in one of the system libs, so you have to
00051 // step out of that system function to get into our code; its rather non-intuitive.
00052 
00053 #  undef UT_DEBUG_BREAK
00054 
00055 // I am not sure which is the standard GCC macro for the x86 platform; we are supposed to
00056 // be able to get all the predefined macros by running 'cpp -dM' but it would not work on
00057 // my cygwin
00058 #  if defined(__GNUC__) && (defined(_X86) || defined(__i386) || defined(i386))
00059      // Inline assembly for GCC on x86
00060 #    define UT_DEBUG_BREAK asm("int3");
00061 #  elif defined(__GNUC__) && (defined(__ia64) || defined(ia64))
00062 #    error "This branch has not been tested."
00063      // On Itanium we use the intrinsic function __break(); defined in ia64intrin.h
00064      // I am not sure whether we need to tell the compiler this one is intrinsic (MSVC
00065      // uses a #pragma for this
00066      void __break(int);
00067 #    define UT_DEBUG_BREAK __break(0x80016);
00068 #  elif defined(_MSC_VER) && defined(_M_IX86)
00069      // inline assmebly for MSVC on x86
00070 #    define UT_DEBUG_BREAK _asm {int 3}
00071 #  elif defined(_MSC_VER) && (defined(_M_IA64) || defined(_M_AMD64))
00072 #    error "This branch has not been tested."
00073      // On Itanium we use the intrinsic function __break();
00074      // I assume this will also work for AMD64, but I am not 100% sure
00075      void __break(int);
00076      // this forces __break() to be generated as inline code (see MSDN)
00077 #    pragma intrinsic (__break)
00078 #    define UT_DEBUG_BREAK __break(0x80016);
00079 #  endif
00080 
00081 # ifndef UT_DEBUG_BREAK
00082 // Some compiler/architecture for which we do not know how to generate inline assembly to pass
00083 // control to the debugger; we use win32s DebugBreak().
00084 //
00085 // TODO !!! This currently does not work; if someone one day wants to build AW on non-x86
00086 // win32 architecture, they will need to fix this (including <windows.h> from here, which
00087 // is what would work, screws up things in MS Word importer, because the wv library
00088 // redefines some of the win32 structures; but we probably do not want to include
00089 // windows.h from here anyway because of the overhead -- ut_assert.h gets included in
00090 // almost everything.). Really, we want to do something similar as we do for x86.
00091 #  error "Proper implementation needed for this compiler/architecture"
00092 
00093 #    ifndef _WINBASE_
00094        __declspec(dllimport) void __stdcall DebugBreak(void);
00095 #    endif /* ifdef _WINBASE_ */
00096 
00097 #    define UT_DEBUG_BREAK DebugBreak();
00098 #  endif /* ifndef UT_DEBUG_BREAK */
00099 
00100 // We want to track the number of times we have been through this assert and have the
00101 // option of disabling this assert for the rest of the session; we use the __iCount and
00102 // __bOnceOnly vars for this (this adds a few bytes to the code and footprint, but on
00103 // large scale of things, this is quite negligible for the debug build).
00104 #define UT_ASSERT(x)                                                        \
00105 {                                                                           \
00106     static bool __bOnceOnly = false;                                        \
00107     static long __iCount = 0;                                               \
00108     if(!__bOnceOnly && !(x))                                                \
00109     {                                                                       \
00110         __iCount++;                                                         \
00111         int __iRet = UT_Win32ThrowAssert(#x,__FILE__, __LINE__, __iCount);  \
00112         if(__iRet == 0)                                                     \
00113         {                                                                   \
00114            UT_DEBUG_BREAK                                                   \
00115         }                                                                   \
00116         else if(__iRet < 0)                                                 \
00117         {                                                                   \
00118             __bOnceOnly = true;                                             \
00119         }                                                                   \
00120     }                                                                       \
00121 }
00122 
00123 #endif // ifdef NDEBUG
00124 
00125 #else
00126 
00127     // A Unix variant, possibly Gnome.
00128 
00129 #   ifdef NDEBUG
00130 
00131         // When NDEBUG is defined, assert() does nothing.
00132         // So we let the system header files take care of it.
00133 #       if 0 //defined(TOOLKIT_COCOA)
00134 // Please keep the "/**/" to stop MSVC dependency generator complaining.
00135 #           include  "xap_CocoaAssert.h"
00136 #           define UT_ASSERT(expr)                              \
00137             ((void) ((expr) ||                              \
00138                 (XAP_CocoaAssertMsg(#expr,                  \
00139                                   __FILE__, __LINE__),      \
00140                  0)))
00141 
00142 #       else
00143 #           include <assert.h>
00144 #           define UT_ASSERT assert
00145 #       endif
00146 #   else
00147         // Otherwise, we want a slighly modified behavior.
00148         // We'd like assert() to ask us before crashing.
00149         // We treat asserts as logic flaws, which are sometimes
00150         // recoverable, but that should be noted.
00151 
00152 #       include <assert.h>
00153 // Please keep the "/**/" to stop MSVC dependency generator complaining.
00154 #       include  "ut_unixAssert.h"
00155 #       define UT_ASSERT(expr)                              \
00156         {                                       \
00157             static bool __bOnceOnly = false;                    \
00158             if (!__bOnceOnly && !(expr))                        \
00159                 if (UT_UnixAssertMsg(#expr, __FILE__, __LINE__) == -1)      \
00160                     __bOnceOnly = true;                 \
00161         }
00162 #   endif
00163 
00164 #endif
00165 
00166 
00170 #define UT_NOT_IMPLEMENTED      0
00171 
00175 #define UT_SHOULD_NOT_HAPPEN    0
00176 
00180 #define UT_TODO                 0
00181 
00185 #define UT_NOT_REACHED 0
00186 
00190 #define UT_ASSERT_NOT_REACHED() UT_ASSERT(UT_NOT_REACHED)
00191 
00195 #define UT_ASSERT_HARMLESS(cond) UT_ASSERT(cond)
00196 
00200 #define UT_return_if_fail(cond) if (!(cond)) { UT_ASSERT(cond); return; }
00201 
00205 #define UT_return_val_if_fail(cond, val) if (!(cond)) { UT_ASSERT(cond); return (val); }
00206 
00210 #define UT_throw_if_fail(cond, val) if (!(cond)) { UT_ASSERT(cond); throw val; }
00211 
00215 #define UT_continue_if_fail(cond) if (!(cond)) { UT_ASSERT(cond); continue; }
00216 
00217 #endif /* UT_ASSERT_H */

Generated on Fri May 24 2013 for AbiWord by  doxygen 1.7.1