Loading [MathJax]/extensions/tex2jax.js
Mesh Oriented datABase  (version 5.5.1)
An array-based unstructured mesh library
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ErrorOutput.cpp
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  // try once with remaining space in buffer 114  lineBuffer.resize( lineBuffer.capacity() ); 115  unsigned size = vsnprintf( &lineBuffer[idx], lineBuffer.size() - idx, fmt, args1 ); 116  ++size; // trailing null 117  // if necessary, increase buffer size and retry 118  if( size > ( lineBuffer.size() - idx ) ) 119  { 120  lineBuffer.resize( idx + size ); 121  size = vsnprintf( &lineBuffer[idx], lineBuffer.size() - idx, fmt, args2 ); 122  ++size; // trailing null 123  } 124  125  // less one because we don't want the trailing '\0' 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 } // namespace moab