|
Sierra Toolkit
Version of the Day
|
00001 #ifndef STK_UTIL_SIERRA_TRACE_HPP 00002 #define STK_UTIL_SIERRA_TRACE_HPP 00003 00004 #include <cstring> 00005 #include <vector> 00006 #include <map> 00007 #include <string> 00008 #include <functional> 00009 00010 #include <stk_util/diag/Writer_fwd.hpp> 00011 00012 #include <ostream> 00013 00014 #define SLIB_TRACE_COVERAGE 00015 00016 namespace stk_classic { 00017 namespace diag { 00018 00023 00032 class Tracespec 00033 { 00034 public: 00041 explicit Tracespec(const char *function_spec) 00042 : m_functionSpec(function_spec) 00043 {} 00044 00050 inline const char *getFunctionSpec() const { 00051 return m_functionSpec; 00052 } 00053 00059 std::string getFunctionName() const; 00060 00066 std::string getFunctionShortName() const; 00067 00073 std::string getFunctionClass() const; 00074 00080 std::string getFunctionNamespace() const; 00081 00087 std::string getFunctionShortClass() const; 00088 00089 protected: 00090 const char * m_functionSpec; 00091 }; 00092 00093 typedef std::vector<const char *> TracebackStack; 00094 00102 class Traceback : public Tracespec 00103 { 00104 public: 00114 enum TracebackState{RUNNING, THROWING}; 00115 00116 enum {STACK_SIZE = 2048}; 00117 typedef const char *Stack[STACK_SIZE] ; 00118 typedef const char * const * const_stack_iterator; 00119 typedef const char ** stack_iterator; 00120 00129 typedef std::map<const char *, int> Coverage; 00130 00136 class Preserve 00137 { 00138 public: 00144 Preserve() { 00145 Traceback::preserveStack(); 00146 } 00147 00152 ~Preserve() { 00153 Traceback::releaseStack(); 00154 } 00155 }; 00156 00163 explicit Traceback(const char *function_spec) 00164 : Tracespec(function_spec) 00165 { 00166 if (s_top >= &s_stack[STACK_SIZE - 1] || s_top == 0) 00167 s_top = s_stack; 00168 *s_top++ = function_spec; 00169 00170 if (s_tracebackState == THROWING && !s_tracebackPreserve && !std::uncaught_exception()) 00171 s_tracebackState = RUNNING; 00172 00173 #ifdef SLIB_TRACE_COVERAGE 00174 if (s_coverageEnabled) 00175 ++s_coverage[function_spec]; 00176 #endif 00177 } 00178 00179 00185 ~Traceback() { 00186 if (!s_tracebackPreserve && std::uncaught_exception() && s_tracebackState == RUNNING) { 00187 s_tracebackState = THROWING; 00188 s_storedTop = s_storedStack + (s_top - s_stack); 00189 std::copy(s_stack, s_top, s_storedStack); 00190 } 00191 if (s_top > &s_stack[0]) 00192 --s_top; 00193 } 00194 00195 static TracebackStack snapshot(); 00196 00202 inline static void enableTracebackDisplay() { 00203 --s_tracebackDisplay; 00204 } 00205 00211 inline static void disableTracebackDisplay() { 00212 ++s_tracebackDisplay; 00213 } 00214 00222 inline static bool displayTraceback() { 00223 return s_tracebackDisplay == 0; 00224 } 00225 00231 inline static void preserveStack() { 00232 ++s_tracebackPreserve; 00233 } 00234 00240 inline static void releaseStack() { 00241 --s_tracebackPreserve; 00242 } 00243 00253 inline static void enableCoverage(bool coverage_enabled = true) { 00254 s_coverageEnabled = coverage_enabled; 00255 } 00256 00264 inline static bool coverageEnabled() { 00265 return s_coverageEnabled; 00266 } 00267 00274 inline static TracebackState getTracebackState() { 00275 return s_tracebackState; 00276 } 00277 00282 struct PrintCoverage 00283 {}; 00284 00292 static PrintCoverage printCoverage() { 00293 return PrintCoverage(); 00294 } 00295 00302 static std::ostream &printCoverage(std::ostream &os); 00303 00313 static std::string printTraceback(const TracebackStack &traceback_stack); 00314 00325 Writer &verbose_print(Writer &dout) const; 00326 00327 private: 00328 static TracebackState s_tracebackState; 00329 static int s_tracebackPreserve; 00330 static int s_tracebackDisplay; 00331 static const char ** s_top; 00332 static Stack s_stack; 00333 static const char ** s_storedTop; 00334 static Stack s_storedStack; 00335 static bool s_coverageEnabled; 00336 static Coverage s_coverage; 00337 }; 00338 00339 00351 class Trace : public Traceback 00352 { 00353 public: 00359 typedef Writer & (*ExtraFuncPtr)(Writer &); 00360 00365 struct TraceList : public std::vector<const char *> { 00366 public: 00367 TraceList() { 00368 s_traceListExists = true; 00369 } 00370 00371 ~TraceList() { 00372 s_traceListExists = false; 00373 } 00374 }; 00375 00380 enum { 00381 IN_TRACE_LIST = 0x01 00382 }; 00383 00401 Trace(Writer &dout, const char *function_name, int print_mask = LOG_TRACE, bool do_trace = true); 00402 00408 ~Trace(); 00409 00419 inline static ExtraFuncPtr setExtra(ExtraFuncPtr extra) { 00420 ExtraFuncPtr x = s_extra; 00421 s_extra = extra; 00422 return x; 00423 } 00424 00432 inline static void addTraceFunction(const std::string &function_prefix) { 00433 char *s = std::strcpy(new char[function_prefix.length() + 1], function_prefix.c_str()); 00434 00435 s_traceList.push_back(s); 00436 } 00437 00443 inline static void clearTraceFunctions() { 00444 for (std::vector<const char *>::iterator it = s_traceList.begin(); it != s_traceList.end(); ++it) 00445 delete[] (*it); 00446 00447 s_traceList.clear(); 00448 } 00449 00458 Writer &verbose_print(Writer &dout) const; 00459 00460 private: 00461 Writer & m_diagWriter; 00462 double m_startCpuTime; 00463 size_t m_startMemAlloc; 00464 PrintMask m_lineMask; 00465 bool m_do_trace; 00466 int m_flags; 00467 00468 static ExtraFuncPtr s_extra; 00469 static TraceList s_traceList; 00470 static bool s_traceListExists; 00471 }; 00472 00486 inline Writer &operator<<(Writer &dout, const Trace &diag_trace) { 00487 return diag_trace.verbose_print(dout); 00488 } 00489 00503 inline std::ostream &operator<<(std::ostream &os, const Traceback::PrintCoverage &) { 00504 return Traceback::printCoverage(os); 00505 } 00506 00507 00508 } // namespace diag 00509 } // namespace stk_classic 00510 00511 namespace sierra { 00512 namespace Diag { 00513 00514 typedef stk_classic::diag::Tracespec Tracespec; 00515 typedef stk_classic::diag::Traceback Traceback; 00516 typedef stk_classic::diag::Trace Trace; 00517 00518 } // namespace sierra 00519 } // namespace Diag 00520 00521 00525 00526 #endif // STK_UTIL_SIERRA_TRACE_HPP