Go to the documentation of this file. 1 #include "ErrorOutput.hpp"
2 #include "moab/MOABConfig.h"
3
4 #include <iostream>
5 #include <cstring>
6 #include <algorithm>
7 #include <cassert>
8
9 #ifdef MOAB_HAVE_MPI
10 #include "moab_mpi.h"
11 #endif
12
13 namespace moab
14 {
15
16 class FILEErrorStream : public ErrorOutputStream
17 {
18 private:
19 FILE* filePtr;
20
21 public:
22 FILEErrorStream( FILE* filep ) : filePtr( filep ) {}
23 void println( int rank, const char* str );
24 void println( const char* str );
25 };
26
27 void FILEErrorStream::println( int rank, const char* str )
28 {
29 fprintf( filePtr, "[%d]MOAB ERROR: %s\n", rank, str );
30 fflush( filePtr );
31 }
32
33 void FILEErrorStream::println( const char* str )
34 {
35 fprintf( filePtr, "MOAB ERROR: %s\n", str );
36 fflush( filePtr );
37 }
38
39 class CxxErrorStream : public ErrorOutputStream
40 {
41 private:
42 std::ostream& outStr;
43
44 public:
45 CxxErrorStream( std::ostream& str ) : outStr( str ) {}
46 void println( int rank, const char* str );
47 void println( const char* str );
48 };
49
50 void CxxErrorStream::println( int rank, const char* str )
51 {
52 outStr << "[" << rank << "]MOAB ERROR: " << str << std::endl;
53 outStr.flush();
54 }
55
56 void CxxErrorStream::println( const char* str )
57 {
58 outStr << "MOAB ERROR: " << str << std::endl;
59 outStr.flush();
60 }
61
62 ErrorOutput::ErrorOutput( FILE* impl ) : outputImpl( new FILEErrorStream( impl ) ), mpiRank( -1 )
63 {
64 lineBuffer.reserve( 1024 );
65 }
66
67 ErrorOutput::ErrorOutput( std::ostream& str ) : outputImpl( new CxxErrorStream( str ) ), mpiRank( -1 )
68 {
69 lineBuffer.reserve( 1024 );
70 }
71
72 ErrorOutput::~ErrorOutput()
73 {
74 if( !lineBuffer.empty() )
75 {
76 lineBuffer.push_back( '\n' );
77 process_line_buffer();
78 }
79
80 if( NULL != outputImpl )
81 {
82 delete outputImpl;
83 outputImpl = NULL;
84 }
85 }
86
87 void ErrorOutput::use_world_rank()
88 {
89 #ifdef MOAB_HAVE_MPI
90 int flag1;
91 MPI_Initialized( &flag1 );
92 int flag2;
93 MPI_Finalized( &flag2 );
94 if( flag1 && !flag2 ) MPI_Comm_rank( MPI_COMM_WORLD, &mpiRank );
95 #endif
96 }
97
98 void ErrorOutput::print_real( const char* buffer )
99 {
100 lineBuffer.insert( lineBuffer.end(), buffer, buffer + strlen( buffer ) );
101 process_line_buffer();
102 }
103
104 void ErrorOutput::print_real( const std::string& str )
105 {
106 lineBuffer.insert( lineBuffer.end(), str.begin(), str.end() );
107 process_line_buffer();
108 }
109
110 void ErrorOutput::print_real( const char* fmt, va_list args1, va_list args2 )
111 {
112 size_t idx = lineBuffer.size();
113
114 lineBuffer.resize( lineBuffer.capacity() );
115 unsigned size = vsnprintf( &lineBuffer[idx], lineBuffer.size() - idx, fmt, args1 );
116 ++size;
117
118 if( size > ( lineBuffer.size() - idx ) )
119 {
120 lineBuffer.resize( idx + size );
121 size = vsnprintf( &lineBuffer[idx], lineBuffer.size() - idx, fmt, args2 );
122 ++size;
123 }
124
125
126 lineBuffer.resize( idx + size - 1 );
127 process_line_buffer();
128 }
129
130 void ErrorOutput::process_line_buffer()
131 {
132 size_t last_idx = 0;
133 std::vector< char >::iterator i;
134 for( i = std::find( lineBuffer.begin(), lineBuffer.end(), '\n' ); i != lineBuffer.end();
135 i = std::find( i, lineBuffer.end(), '\n' ) )
136 {
137 *i = '\0';
138 if( have_rank() )
139 outputImpl->println( get_rank(), &lineBuffer[last_idx] );
140 else
141 outputImpl->println( &lineBuffer[last_idx] );
142 ++i;
143 last_idx = i - lineBuffer.begin();
144 }
145
146 if( last_idx )
147 {
148 i = std::copy( lineBuffer.begin() + last_idx, lineBuffer.end(), lineBuffer.begin() );
149 lineBuffer.erase( i, lineBuffer.end() );
150 }
151 }
152
153 }