00001 /** @file rutz/debug.h debugging facilities, assertions, 00002 preconditions, postconditions, invariants */ 00003 00004 /////////////////////////////////////////////////////////////////////// 00005 // 00006 // Copyright (c) 1999-2004 California Institute of Technology 00007 // Copyright (c) 2004-2007 University of Southern California 00008 // Rob Peters <rjpeters at usc dot edu> 00009 // 00010 // created: Mon Jan 4 08:00:00 1999 00011 // commit: $Id: debug.h 8249 2007-04-12 06:03:40Z rjpeters $ 00012 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/rutz/debug.h $ 00013 // 00014 // -------------------------------------------------------------------- 00015 // 00016 // This file is part of GroovX. 00017 // [http://ilab.usc.edu/rjpeters/groovx/] 00018 // 00019 // GroovX is free software; you can redistribute it and/or modify it 00020 // under the terms of the GNU General Public License as published by 00021 // the Free Software Foundation; either version 2 of the License, or 00022 // (at your option) any later version. 00023 // 00024 // GroovX is distributed in the hope that it will be useful, but 00025 // WITHOUT ANY WARRANTY; without even the implied warranty of 00026 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00027 // General Public License for more details. 00028 // 00029 // You should have received a copy of the GNU General Public License 00030 // along with GroovX; if not, write to the Free Software Foundation, 00031 // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 00032 // 00033 /////////////////////////////////////////////////////////////////////// 00034 00035 #ifndef GROOVX_RUTZ_DEBUG_H_UTC20050626084020_DEFINED 00036 #define GROOVX_RUTZ_DEBUG_H_UTC20050626084020_DEFINED 00037 00038 namespace rutz {namespace debug 00039 { 00040 void eval (const char* what, int level, const char* where, int line_no, bool nl, bool expr) throw(); 00041 void eval (const char* what, int level, const char* where, int line_no, bool nl, char expr) throw(); 00042 void eval (const char* what, int level, const char* where, int line_no, bool nl, unsigned char expr) throw(); 00043 void eval (const char* what, int level, const char* where, int line_no, bool nl, short expr) throw(); 00044 void eval (const char* what, int level, const char* where, int line_no, bool nl, unsigned short expr) throw(); 00045 void eval (const char* what, int level, const char* where, int line_no, bool nl, int expr) throw(); 00046 void eval (const char* what, int level, const char* where, int line_no, bool nl, unsigned int expr) throw(); 00047 void eval (const char* what, int level, const char* where, int line_no, bool nl, long expr) throw(); 00048 void eval (const char* what, int level, const char* where, int line_no, bool nl, unsigned long expr) throw(); 00049 void eval (const char* what, int level, const char* where, int line_no, bool nl, float expr) throw(); 00050 void eval (const char* what, int level, const char* where, int line_no, bool nl, double expr) throw(); 00051 void eval (const char* what, int level, const char* where, int line_no, bool nl, const char* expr) throw(); 00052 void eval (const char* what, int level, const char* where, int line_no, bool nl, void* expr) throw(); 00053 00054 void dump (const char* what, int level, const char* where, int line_no) throw(); 00055 00056 void start_newline () throw(); 00057 00058 void panic_aux (const char* what, const char* where, int line_no) throw(); 00059 void assert_aux (const char* what, const char* where, int line_no) throw(); 00060 void precondition_aux (const char* what, const char* where, int line_no) throw(); 00061 void postcondition_aux (const char* what, const char* where, int line_no) throw(); 00062 void invariant_aux (const char* what, const char* where, int line_no) throw(); 00063 00064 /// Allocate a debug key for the given filename 00065 int create_key(const char* filename); 00066 00067 /// Query whether the given value is a valid debug key 00068 bool is_valid_key(int key); 00069 00070 /// Get the debug key associated with the given filename. 00071 /** Returns -1 if the filename is not registered. */ 00072 int lookup_key(const char* filename); 00073 00074 /// Get the current debug level associated with the given debug key 00075 int get_level_for_key(int key); 00076 00077 /// Set the current debug level for the given debug key 00078 void set_level_for_key(int key, int level); 00079 00080 /// Get the filename associated with the given debug key 00081 const char* get_filename_for_key(int key); 00082 00083 void set_global_level(int lev); 00084 }} 00085 00086 /// Print a message, followed by a rutz::backtrace (if available), then abort(). 00087 #define GVX_PANIC(message) rutz::debug::panic_aux(message, __FILE__, __LINE__) 00088 00089 /// Abort if the given expression evaluates to true. 00090 /** This is like GVX_ASSERT(), except (1) it has the opposite sense 00091 (GVX_ASSERT() says some expression must be TRUE, GVX_ABORT_IF() 00092 says some expression must be false), and (2) it can't ever be 00093 turned off (whereas GVX_ASSERT() is under the control of the 00094 GVX_NO_DEBUG macro). */ 00095 #define GVX_ABORT_IF(expr) \ 00096 do { if ( expr ) { rutz::debug::panic_aux(#expr, __FILE__, __LINE__); } } while (0) 00097 00098 #define GVX_CONCAT(x, y) x ## y 00099 00100 #define GVX_DO_DBG_REGISTER(ext) \ 00101 static const int GVX_CONCAT(DEBUG_KEY, ext) = \ 00102 rutz::debug::create_key(__FILE__); \ 00103 \ 00104 static inline int GVX_CONCAT(dbg_level_, ext) () \ 00105 { \ 00106 return rutz::debug::get_level_for_key(GVX_CONCAT(DEBUG_KEY, ext)); \ 00107 } 00108 00109 #define GVX_DBG_REGISTER GVX_DO_DBG_REGISTER(1) 00110 #define GVX_DBG_LEVEL dbg_level_1 00111 00112 static const char __attribute__((used)) vcid_groovx_rutz_debug_h_utc20050626084020[] = "$Id: debug.h 8249 2007-04-12 06:03:40Z rjpeters $ $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/rutz/debug.h $"; 00113 00114 #else // DEBUG_H_DEFINED 00115 00116 // 00117 // Everything here gets processed on the second and subsequent times that 00118 // this file is #include'ed. 00119 // 00120 00121 #undef GVX_DBG_REGISTER 00122 #undef GVX_DBG_LEVEL 00123 00124 #if !defined(GVX_DEBUG_H_2) 00125 # define GVX_DEBUG_H_2 00126 # define GVX_DBG_REGISTER GVX_DO_DBG_REGISTER(2) 00127 # define GVX_DBG_LEVEL dbg_level_2 00128 #elif !defined(GVX_DEBUG_H_3) 00129 # define GVX_DEBUG_H_3 00130 # define GVX_DBG_REGISTER GVX_DO_DBG_REGISTER(3) 00131 # define GVX_DBG_LEVEL dbg_level_3 00132 #elif !defined(GVX_DEBUG_H_4) 00133 # define GVX_DEBUG_H_4 00134 # define GVX_DBG_REGISTER GVX_DO_DBG_REGISTER(4) 00135 # define GVX_DBG_LEVEL dbg_level_4 00136 #elif !defined(GVX_DEBUG_H_5) 00137 # define GVX_DEBUG_H_5 00138 # define GVX_DBG_REGISTER GVX_DO_DBG_REGISTER(5) 00139 # define GVX_DBG_LEVEL dbg_level_5 00140 #elif !defined(GVX_DEBUG_H_6) 00141 # define GVX_DEBUG_H_6 00142 # define GVX_DBG_REGISTER GVX_DO_DBG_REGISTER(6) 00143 # define GVX_DBG_LEVEL dbg_level_6 00144 #elif !defined(GVX_DEBUG_H_7) 00145 # define GVX_DEBUG_H_7 00146 # define GVX_DBG_REGISTER GVX_DO_DBG_REGISTER(7) 00147 # define GVX_DBG_LEVEL dbg_level_7 00148 #elif !defined(GVX_DEBUG_H_8) 00149 # define GVX_DEBUG_H_8 00150 # define GVX_DBG_REGISTER GVX_DO_DBG_REGISTER(8) 00151 # define GVX_DBG_LEVEL dbg_level_8 00152 #else 00153 # error "debug.h included too many times!" 00154 #endif 00155 00156 #undef dbg_eval 00157 #undef dbg_eval_nl 00158 #undef dbg_print 00159 #undef dbg_print_nl 00160 00161 #undef GVX_ASSERT 00162 #undef GVX_INVARIANT 00163 #undef GVX_PRECONDITION 00164 #undef GVX_POSTCONDITION 00165 00166 #endif // !GROOVX_RUTZ_DEBUG_H_UTC20050626084020_DEFINED 00167 00168 // 00169 // Everything here gets re-processed every time that this file is #include'ed. 00170 // 00171 00172 #if !defined(GVX_NO_DEBUG) 00173 # define dbg_eval(lev, x) do { if (GVX_DBG_LEVEL() >= lev) rutz::debug::eval(#x, lev, __FILE__, __LINE__, false, x); } while (0) 00174 # define dbg_eval_nl(lev, x) do { if (GVX_DBG_LEVEL() >= lev) rutz::debug::eval(#x, lev, __FILE__, __LINE__, true, x); } while (0) 00175 # define dbg_print(lev, x) do { if (GVX_DBG_LEVEL() >= lev) rutz::debug::eval(0, lev, __FILE__, __LINE__, false, x); } while (0) 00176 # define dbg_print_nl(lev, x) do { if (GVX_DBG_LEVEL() >= lev) rutz::debug::eval(0, lev, __FILE__, __LINE__, true, x); } while (0) 00177 # define dbg_dump(lev, x) do { if (GVX_DBG_LEVEL() >= lev) { rutz::debug::dump(#x, lev, __FILE__, __LINE__); (x).debug_dump(); } } while (0) 00178 # define dbg_nl(lev) do { if (GVX_DBG_LEVEL() >= lev) rutz::debug::start_newline(); } while (0) 00179 00180 # define GVX_ASSERT(expr) do { if ( !(expr) ) rutz::debug::assert_aux(#expr, __FILE__, __LINE__); } while(0) 00181 # define GVX_INVARIANT(expr) do { if ( !(expr) ) rutz::debug::invariant_aux(#expr, __FILE__, __LINE__); } while(0) 00182 # define GVX_PRECONDITION(expr) do { if ( !(expr) ) rutz::debug::precondition_aux(#expr, __FILE__, __LINE__); } while(0) 00183 # define GVX_POSTCONDITION(expr) do { if ( !(expr) ) rutz::debug::postcondition_aux(#expr, __FILE__, __LINE__); } while(0) 00184 00185 #else // defined(GVX_NO_DEBUG) 00186 00187 # define dbg_eval(lev, x) do {} while (0) 00188 # define dbg_eval_nl(lev, x) do {} while (0) 00189 # define dbg_print(lev, x) do {} while (0) 00190 # define dbg_print_nl(lev, x) do {} while (0) 00191 # define dbg_dump(lev, expr) do {} while (0) 00192 # define dbg_nl(lev) do {} while (0) 00193 00194 # define GVX_ASSERT(x) do {} while (0) 00195 # define GVX_INVARIANT(x) do {} while (0) 00196 # define GVX_PRECONDITION(x) do {} while (0) 00197 # define GVX_POSTCONDITION(x) do {} while (0) 00198 00199 #endif