Mesh Oriented datABase  (version 5.5.1)
An array-based unstructured mesh library
ErrorOutput.hpp
Go to the documentation of this file.
1 #ifndef moab_ERROR_OUTPUT_HPP
2 #define moab_ERROR_OUTPUT_HPP
3 
4 #include <cstdarg>
5 #include <cstdio>
6 #include <vector>
7 #include <iosfwd>
8 #include <string>
9 
10 #include "moab/Compiler.hpp"
11 
12 namespace moab
13 {
14 
15 class ErrorOutputStream;
16 
17 /**\brief Utility class for printing error output
18  *
19  * This class implements line-oriented output. That is, it buffers
20  * output data until a newline is encountered, at which point it
21  * sends the output to the output stream followed by an explicit
22  * flush, and optionally prefixed with the MPI rank.
23  *
24  * \Note Any output not terminated with an newline character or
25  * followed by later output containing a newline character
26  * will not be flushed until the destructor is invoked.
27  */
29 {
30  public:
31  /**
32  *\param str Output stream to which to flush output
33  */
34  ErrorOutput( FILE* str );
35 
36  /**
37  *\param str Output stream to which to flush output
38  */
39  ErrorOutput( std::ostream& str );
40 
41  /**
42  * Destructor flushes any remaining output that wasn't followed
43  * by a newline character.
44  */
45  ~ErrorOutput();
46 
47  //!\brief Check if MPI rank has been set.
48  bool have_rank() const
49  {
50  return mpiRank >= 0;
51  }
52  //!\brief Get MPI rank.
53  int get_rank() const
54  {
55  return mpiRank;
56  }
57  //!\brief Set MPI rank.
58  void set_rank( int rank )
59  {
60  mpiRank = rank;
61  }
62  //!\brief Set MPI rank to the rank of this process in MPI_COMM_WORLD,
63  //! if MOAB is built with MPI and MPI_Init has been called
64  void use_world_rank();
65 
66  //!\brief Output the specified string
67  void print( const char* str )
68  {
69  print_real( str );
70  }
71 
72  //!\brief Output the specified string
73  void print( const std::string& str )
74  {
75  print_real( str );
76  }
77 
78  //!\brief Output the specified printf-formatted output
79  void printf( const char* fmt, ... ) MB_PRINTF( 1 );
80 
81  private:
83  int mpiRank;
84 
85  void print_real( const char* buffer );
86  void print_real( const std::string& str );
87 
88  // Function must be passed to copies of the same va_list because
89  // a) it might have to call vs(n)printf twice, b) vs(n)printf modifies
90  // the va_list such that it cannot be reused, and c) va_copy is not
91  // (yet) portable (c99, no c++ standard).
92  void print_real( const char* buffer, va_list args1, va_list args2 );
93  void process_line_buffer();
94 
95  std::vector< char > lineBuffer;
96 };
97 
98 inline void ErrorOutput::printf( const char* fmt, ... )
99 {
100  va_list args1, args2;
101  va_start( args1, fmt );
102  va_start( args2, fmt );
103  print_real( fmt, args1, args2 );
104  va_end( args2 );
105  va_end( args1 );
106 }
107 
109 {
110  public:
112  virtual ~ErrorOutputStream() {}
113  virtual void println( const char* str ) = 0;
114  virtual void println( int rank, const char* str ) = 0;
115 };
116 
117 } // namespace moab
118 
119 #endif