moab
|
00001 #ifndef moab_DEBUG_OUTPUT_HPP 00002 #define moab_DEBUG_OUTPUT_HPP 00003 00004 #include <stdarg.h> 00005 #include <stdio.h> 00006 #include <vector> 00007 #include <iosfwd> 00008 #include <string> 00009 00010 #include "moab/Compiler.hpp" 00011 00012 namespace moab { 00013 00014 class Range; 00015 class DebugOutputStream; 00016 00041 class DebugOutput { 00042 00043 public: 00044 00049 DebugOutput( DebugOutputStream* str, unsigned verbosity = 0 ); 00055 DebugOutput( DebugOutputStream* str, int rank, unsigned verbosity = 0 ); 00060 DebugOutput( FILE* str, unsigned verbosity = 0 ); 00066 DebugOutput( FILE* str, int rank, unsigned verbosity = 0 ); 00071 DebugOutput( std::ostream& str, unsigned verbosity = 0 ); 00077 DebugOutput( std::ostream& str, int rank, unsigned verbosity = 0 ); 00078 00084 DebugOutput( const char* pfx, DebugOutputStream* str, unsigned verbosity = 0 ); 00091 DebugOutput( const char* pfx, DebugOutputStream* str, int rank, unsigned verbosity = 0 ); 00097 DebugOutput( const char* pfx, FILE* str, unsigned verbosity = 0 ); 00104 DebugOutput( const char* pfx, FILE* str, int rank, unsigned verbosity = 0 ); 00110 DebugOutput( const char* pfx, std::ostream& str, unsigned verbosity = 0 ); 00117 DebugOutput( const char* pfx, std::ostream& str, int rank, unsigned verbosity = 0 ); 00118 00119 DebugOutput( const DebugOutput& copy ); 00120 DebugOutput& operator=( const DebugOutput& copy ); 00121 00126 ~DebugOutput(); 00127 00129 bool have_rank() const { return mpiRank >= 0; } 00131 int get_rank() const { return mpiRank; } 00133 void set_rank( int rank ) { mpiRank = rank; } 00136 void use_world_rank(); 00137 00139 void limit_output_to_first_N_procs( int N ) 00140 { if (mpiRank >= N) verbosityLimit = 0; } 00141 00143 unsigned get_verbosity() const { return verbosityLimit; } 00145 void set_verbosity( unsigned val ) { verbosityLimit = val; } 00146 00148 const std::string& get_prefix() const { return linePfx; } 00150 void set_prefix(const std::string& str) { linePfx = str; } 00151 00153 void print( int verbosity, const char* str ) 00154 { if (check(verbosity)) print_real(str); } 00155 00157 void print( int verbosity, const std::string& str ) 00158 { if (check(verbosity)) print_real(str); } 00159 00161 inline void printf( int verbosity, const char* fmt, ... ) MB_PRINTF(2); 00162 00166 void tprint( int verbosity, const char* str ) 00167 { if (check(verbosity)) tprint_real(str); } 00168 00172 void tprint( int verbosity, const std::string& str ) 00173 { if (check(verbosity)) tprint_real(str); } 00174 00178 inline void tprintf( int verbosity, const char* fmt, ... ) MB_PRINTF(2); 00179 00180 00183 void print( int verbosity, const char* pfx, const Range& range ) 00184 { if (check(verbosity)) list_range_real( pfx, range ); } 00186 void print( int verbosity, const Range& range ) 00187 { if (check(verbosity)) list_range_real( 0, range ); } 00188 00191 void print_ints( int verbosity, const char* pfx, const Range& range ) 00192 { if (check(verbosity)) list_ints_real( pfx, range ); } 00194 void print_ints( int verbosity, const Range& range ) 00195 { if (check(verbosity)) list_ints_real( 0, range ); } 00196 00197 private: 00198 00199 std::string linePfx; 00200 DebugOutputStream *outputImpl; 00201 int mpiRank; 00202 unsigned verbosityLimit; 00203 double initTime; 00204 00205 void tprint(); 00206 00207 void list_range_real( const char* pfx, const Range& range ); 00208 void list_ints_real( const char* pfx, const Range& range ); 00209 void print_real( const char* buffer ); 00210 void print_real( const std::string& str ); 00211 void tprint_real( const char* buffer ); 00212 void tprint_real( const std::string& str ); 00213 00214 // Function must be passed to copies of the same va_list because 00215 // a) it might have to call vs(n)printf twice, b) vs(n)printf modifies 00216 // the va_list such that it cannot be reused, and c) va_copy is not 00217 // (yet) portable (c99, no c++ standard). 00218 void print_real( const char* buffer, va_list args1, va_list args2 ); 00219 void tprint_real( const char* buffer, va_list args1, va_list args2 ); 00220 void process_line_buffer(); 00221 00222 std::vector<char> lineBuffer; 00223 00224 inline bool check(unsigned verbosity) 00225 { return verbosity <= verbosityLimit; } 00226 }; 00227 00228 00229 class DebugOutputStream { 00230 protected: 00231 friend class DebugOutput; 00232 int referenceCount; 00233 public: 00234 DebugOutputStream() : referenceCount(1) {} 00235 virtual ~DebugOutputStream(); 00236 virtual void println( const char* pfx, const char* str ) = 0; 00237 virtual void println( int rank, const char* pfx, const char* str ) = 0; 00238 }; 00239 00240 void DebugOutput::printf( int verbosity, const char* fmt, ... ) 00241 { 00242 if (check(verbosity)) { 00243 va_list args1, args2; 00244 va_start(args1, fmt); 00245 va_start(args2, fmt); 00246 print_real(fmt, args1, args2); 00247 va_end(args2); 00248 va_end(args1); 00249 } 00250 } 00251 00252 void DebugOutput::tprintf( int verbosity, const char* fmt, ... ) 00253 { 00254 if (check(verbosity)) { 00255 va_list args1, args2; 00256 va_start(args1, fmt); 00257 va_start(args2, fmt); 00258 tprint_real(fmt, args1, args2); 00259 va_end(args2); 00260 va_end(args1); 00261 } 00262 } 00263 00264 } // namespace moab 00265 00266 #endif