Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
00001 #ifndef moab_ERROR_OUTPUT_HPP 00002 #define moab_ERROR_OUTPUT_HPP 00003 00004 #include <cstdarg> 00005 #include <cstdio> 00006 #include <vector> 00007 #include <iosfwd> 00008 #include <string> 00009 00010 #include "moab/Compiler.hpp" 00011 00012 namespace moab 00013 { 00014 00015 class ErrorOutputStream; 00016 00017 /**\brief Utility class for printing error output 00018 * 00019 * This class implements line-oriented output. That is, it buffers 00020 * output data until a newline is encountered, at which point it 00021 * sends the output to the output stream followed by an explicit 00022 * flush, and optionally prefixed with the MPI rank. 00023 * 00024 * \Note Any output not terminated with an newline character or 00025 * followed by later output containing a newline character 00026 * will not be flushed until the destructor is invoked. 00027 */ 00028 class ErrorOutput 00029 { 00030 public: 00031 /** 00032 *\param str Output stream to which to flush output 00033 */ 00034 ErrorOutput( FILE* str ); 00035 00036 /** 00037 *\param str Output stream to which to flush output 00038 */ 00039 ErrorOutput( std::ostream& str ); 00040 00041 /** 00042 * Destructor flushes any remaining output that wasn't followed 00043 * by a newline character. 00044 */ 00045 ~ErrorOutput(); 00046 00047 //!\brief Check if MPI rank has been set. 00048 bool have_rank() const 00049 { 00050 return mpiRank >= 0; 00051 } 00052 //!\brief Get MPI rank. 00053 int get_rank() const 00054 { 00055 return mpiRank; 00056 } 00057 //!\brief Set MPI rank. 00058 void set_rank( int rank ) 00059 { 00060 mpiRank = rank; 00061 } 00062 //!\brief Set MPI rank to the rank of this process in MPI_COMM_WORLD, 00063 //! if MOAB is built with MPI and MPI_Init has been called 00064 void use_world_rank(); 00065 00066 //!\brief Output the specified string 00067 void print( const char* str ) 00068 { 00069 print_real( str ); 00070 } 00071 00072 //!\brief Output the specified string 00073 void print( const std::string& str ) 00074 { 00075 print_real( str ); 00076 } 00077 00078 //!\brief Output the specified printf-formatted output 00079 void printf( const char* fmt, ... ) MB_PRINTF( 1 ); 00080 00081 private: 00082 ErrorOutputStream* outputImpl; 00083 int mpiRank; 00084 00085 void print_real( const char* buffer ); 00086 void print_real( const std::string& str ); 00087 00088 // Function must be passed to copies of the same va_list because 00089 // a) it might have to call vs(n)printf twice, b) vs(n)printf modifies 00090 // the va_list such that it cannot be reused, and c) va_copy is not 00091 // (yet) portable (c99, no c++ standard). 00092 void print_real( const char* buffer, va_list args1, va_list args2 ); 00093 void process_line_buffer(); 00094 00095 std::vector< char > lineBuffer; 00096 }; 00097 00098 inline void ErrorOutput::printf( const char* fmt, ... ) 00099 { 00100 va_list args1, args2; 00101 va_start( args1, fmt ); 00102 va_start( args2, fmt ); 00103 print_real( fmt, args1, args2 ); 00104 va_end( args2 ); 00105 va_end( args1 ); 00106 } 00107 00108 class ErrorOutputStream 00109 { 00110 public: 00111 ErrorOutputStream() {} 00112 virtual ~ErrorOutputStream() {} 00113 virtual void println( const char* str ) = 0; 00114 virtual void println( int rank, const char* str ) = 0; 00115 }; 00116 00117 } // namespace moab 00118 00119 #endif