MOAB: Mesh Oriented datABase  (version 5.4.1)
ErrorOutput.hpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines