moab
DebugOutput.hpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines