00001
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00033
00034 #ifndef GROOVX_RUTZ_DEBUG_CC_UTC20050626084020_DEFINED
00035 #define GROOVX_RUTZ_DEBUG_CC_UTC20050626084020_DEFINED
00036
00037 #include "rutz/debug.h"
00038 GVX_DBG_REGISTER
00039
00040 #include "rutz/backtrace.h"
00041 #include "rutz/mutex.h"
00042
00043 #include <cstdlib>
00044 #include <cstring>
00045 #include <iomanip>
00046 #include <iostream>
00047
00048 namespace
00049 {
00050 const int MAX_KEYS = 1024;
00051
00052
00053 bool g_debug_line_complete = true;
00054 pthread_mutex_t g_debug_output_mutex = PTHREAD_MUTEX_INITIALIZER;
00055
00056
00057 int g_debug_next_key = 0;
00058 unsigned char g_key_levels[MAX_KEYS];
00059 const char* g_key_filenames[MAX_KEYS];
00060 pthread_mutex_t g_debug_keys_mutex = PTHREAD_MUTEX_INITIALIZER;
00061
00062 void show_position(int level, const char* where, int line_no) throw()
00063 {
00064 std::cerr << "[" << std::setw(2) << level << "] "
00065 << std::setw(20) << where << ":"
00066 << line_no << ": ";
00067 }
00068 }
00069
00070 #define EVAL_IMPL(T) \
00071 void rutz::debug::eval(const char* what, int level, \
00072 const char* where, int line_no, \
00073 bool nl, T expr) throw() \
00074 { \
00075 GVX_MUTEX_LOCK(&g_debug_output_mutex); \
00076 using std::cerr; \
00077 cerr.exceptions(std::ios::goodbit); \
00078 if (g_debug_line_complete) \
00079 { \
00080 show_position(level, where, line_no); \
00081 } \
00082 if (what) \
00083 { \
00084 cerr << "(" << #T << ") " << what << " = "; \
00085 } \
00086 cerr << expr; \
00087 if (nl) \
00088 { \
00089 cerr << "\n"; \
00090 g_debug_line_complete = true; \
00091 } \
00092 else \
00093 { \
00094 cerr << ", "; \
00095 g_debug_line_complete = false; \
00096 } \
00097 }
00098
00099 EVAL_IMPL(bool);
00100 EVAL_IMPL(char);
00101 EVAL_IMPL(unsigned char);
00102 EVAL_IMPL(short);
00103 EVAL_IMPL(unsigned short);
00104 EVAL_IMPL(int);
00105 EVAL_IMPL(unsigned int);
00106 EVAL_IMPL(long);
00107 EVAL_IMPL(unsigned long);
00108 EVAL_IMPL(float);
00109 EVAL_IMPL(double);
00110 EVAL_IMPL(const char*);
00111 EVAL_IMPL(void*);
00112
00113 void rutz::debug::dump(const char* what, int level, const char* where, int line_no) throw()
00114 {
00115 GVX_MUTEX_LOCK(&g_debug_output_mutex);
00116 std::cerr.exceptions(std::ios::goodbit);
00117 show_position(level, where, line_no);
00118 std::cerr << std::setw(15) << what << " := ";
00119 g_debug_line_complete = false;
00120 }
00121
00122 void rutz::debug::start_newline() throw()
00123 {
00124 GVX_MUTEX_LOCK(&g_debug_output_mutex);
00125 std::cerr.exceptions(std::ios::goodbit);
00126 if (!g_debug_line_complete)
00127 {
00128 std::cerr << '\n';
00129 g_debug_line_complete = true;
00130 }
00131 }
00132
00133 void rutz::debug::panic_aux(const char* what, const char* where,
00134 int line_no) throw()
00135 {
00136 fprintf(stderr, "Panic (%s:%d):\n\t%s\n\n",
00137 where, line_no, what);
00138 rutz::backtrace::current().print();
00139 abort();
00140 }
00141
00142 void rutz::debug::assert_aux(const char* what, const char* where,
00143 int line_no) throw()
00144 {
00145 fprintf(stderr, "Assertion failed (%s:%d):\n\texpected '%s'\n\n",
00146 where, line_no, what);
00147 rutz::backtrace::current().print();
00148 abort();
00149 }
00150
00151 void rutz::debug::precondition_aux(const char* what, const char* where,
00152 int line_no) throw()
00153 {
00154 fprintf(stderr, "Precondition failed (%s:%d):\n\texpected '%s'\n\n",
00155 where, line_no, what);
00156 rutz::backtrace::current().print();
00157 abort();
00158 }
00159
00160 void rutz::debug::postcondition_aux(const char* what, const char* where,
00161 int line_no) throw()
00162 {
00163 fprintf(stderr, "Postcondition failed (%s:%d):\n\texpected '%s'\n\n",
00164 where, line_no, what);
00165 rutz::backtrace::current().print();
00166 abort();
00167 }
00168
00169 void rutz::debug::invariant_aux(const char* what, const char* where,
00170 int line_no) throw()
00171 {
00172 fprintf(stderr, "Invariant failed (%s:%d):\n\texpected '%s'\n\n",
00173 where, line_no, what);
00174 rutz::backtrace::current().print();
00175 abort();
00176 }
00177
00178 int rutz::debug::create_key(const char* filename)
00179 {
00180 GVX_MUTEX_LOCK(&g_debug_keys_mutex);
00181 const int key = g_debug_next_key;
00182 g_key_filenames[key] = filename;
00183 if (g_debug_next_key < (MAX_KEYS-1))
00184 ++g_debug_next_key;
00185 return key;
00186 }
00187
00188 bool rutz::debug::is_valid_key(int key)
00189 {
00190 return key >= 0 && key < MAX_KEYS;
00191 }
00192
00193 int rutz::debug::lookup_key(const char* filename)
00194 {
00195 GVX_MUTEX_LOCK(&g_debug_keys_mutex);
00196 for (int i = 0; i < g_debug_next_key; ++i)
00197 {
00198 if (strcmp(g_key_filenames[i], filename) == 0)
00199 return i;
00200 }
00201 return -1;
00202 }
00203
00204 int rutz::debug::get_level_for_key(int key)
00205 {
00206 GVX_MUTEX_LOCK(&g_debug_keys_mutex);
00207 if (key < MAX_KEYS)
00208 return g_key_levels[key];
00209 return 0;
00210 }
00211
00212 void rutz::debug::set_level_for_key(int key, int level)
00213 {
00214 GVX_MUTEX_LOCK(&g_debug_keys_mutex);
00215 if (key <MAX_KEYS)
00216 g_key_levels[key] = level;
00217 }
00218
00219 const char* rutz::debug::get_filename_for_key(int key)
00220 {
00221 GVX_MUTEX_LOCK(&g_debug_keys_mutex);
00222 return g_key_filenames[key];
00223 }
00224
00225 void rutz::debug::set_global_level(int lev)
00226 {
00227 GVX_MUTEX_LOCK(&g_debug_keys_mutex);
00228 for (int i = 0; i < MAX_KEYS; ++i)
00229 g_key_levels[i] = (unsigned char) lev;
00230 }
00231
00232 static const char __attribute__((used)) vcid_groovx_rutz_debug_cc_utc20050626084020[] = "$Id: debug.cc 10139 2008-03-04 18:00:00Z rjpeters $ $HeadURL: file:
00233 #endif // !GROOVX_RUTZ_DEBUG_CC_UTC20050626084020_DEFINED