LCOV - code coverage report
Current view: top level - src - ErrorOutput.cpp (source / functions) Hit Total Coverage
Test: coverage_sk.info Lines: 53 75 70.7 %
Date: 2020-12-16 07:07:30 Functions: 12 18 66.7 %
Branches: 35 70 50.0 %

           Branch data     Line data    Source code
       1                 :            : #include "ErrorOutput.hpp"
       2                 :            : #include "moab/MOABConfig.h"
       3                 :            : 
       4                 :            : #include <iostream>
       5                 :            : #include <string.h>
       6                 :            : #include <algorithm>
       7                 :            : #include <assert.h>
       8                 :            : 
       9                 :            : #ifdef MOAB_HAVE_MPI
      10                 :            : #include "moab_mpi.h"
      11                 :            : #endif
      12                 :            : 
      13                 :            : namespace moab
      14                 :            : {
      15                 :            : 
      16         [ -  + ]:       1328 : class FILEErrorStream : public ErrorOutputStream
      17                 :            : {
      18                 :            :   private:
      19                 :            :     FILE* filePtr;
      20                 :            : 
      21                 :            :   public:
      22                 :        670 :     FILEErrorStream( FILE* filep ) : filePtr( filep ) {}
      23                 :            :     void println( int rank, const char* str );
      24                 :            :     void println( const char* str );
      25                 :            : };
      26                 :            : 
      27                 :         66 : void FILEErrorStream::println( int rank, const char* str )
      28                 :            : {
      29                 :         66 :     fprintf( filePtr, "[%d]MOAB ERROR: %s\n", rank, str );
      30                 :         66 :     fflush( filePtr );
      31                 :         66 : }
      32                 :            : 
      33                 :         30 : void FILEErrorStream::println( const char* str )
      34                 :            : {
      35                 :         30 :     fprintf( filePtr, "MOAB ERROR: %s\n", str );
      36                 :         30 :     fflush( filePtr );
      37                 :         30 : }
      38                 :            : 
      39         [ #  # ]:          0 : class CxxErrorStream : public ErrorOutputStream
      40                 :            : {
      41                 :            :   private:
      42                 :            :     std::ostream& outStr;
      43                 :            : 
      44                 :            :   public:
      45                 :          0 :     CxxErrorStream( std::ostream& str ) : outStr( str ) {}
      46                 :            :     void println( int rank, const char* str );
      47                 :            :     void println( const char* str );
      48                 :            : };
      49                 :            : 
      50                 :          0 : void CxxErrorStream::println( int rank, const char* str )
      51                 :            : {
      52                 :          0 :     outStr << "[" << rank << "]MOAB ERROR: " << str << std::endl;
      53                 :          0 :     outStr.flush();
      54                 :          0 : }
      55                 :            : 
      56                 :          0 : void CxxErrorStream::println( const char* str )
      57                 :            : {
      58                 :          0 :     outStr << "MOAB ERROR: " << str << std::endl;
      59                 :          0 :     outStr.flush();
      60                 :          0 : }
      61                 :            : 
      62         [ +  - ]:        670 : ErrorOutput::ErrorOutput( FILE* impl ) : outputImpl( new FILEErrorStream( impl ) ), mpiRank( -1 )
      63                 :            : {
      64         [ +  - ]:        335 :     lineBuffer.reserve( 1024 );
      65                 :        335 : }
      66                 :            : 
      67         [ #  # ]:          0 : ErrorOutput::ErrorOutput( std::ostream& str ) : outputImpl( new CxxErrorStream( str ) ), mpiRank( -1 )
      68                 :            : {
      69         [ #  # ]:          0 :     lineBuffer.reserve( 1024 );
      70                 :          0 : }
      71                 :            : 
      72                 :        664 : ErrorOutput::~ErrorOutput()
      73                 :            : {
      74         [ -  + ]:        332 :     if( !lineBuffer.empty() )
      75                 :            :     {
      76                 :          0 :         lineBuffer.push_back( '\n' );
      77                 :          0 :         process_line_buffer();
      78                 :            :     }
      79                 :            : 
      80         [ +  - ]:        332 :     if( NULL != outputImpl )
      81                 :            :     {
      82         [ +  - ]:        332 :         delete outputImpl;
      83                 :        332 :         outputImpl = NULL;
      84                 :            :     }
      85                 :        332 : }
      86                 :            : 
      87                 :        335 : void ErrorOutput::use_world_rank()
      88                 :            : {
      89                 :            : #ifdef MOAB_HAVE_MPI
      90                 :            :     int flag1;
      91         [ +  - ]:        335 :     MPI_Initialized( &flag1 );
      92                 :            :     int flag2;
      93         [ +  - ]:        335 :     MPI_Finalized( &flag2 );
      94 [ +  + ][ +  - ]:        335 :     if( flag1 && !flag2 ) MPI_Comm_rank( MPI_COMM_WORLD, &mpiRank );
                 [ +  - ]
      95                 :            : #endif
      96                 :        335 : }
      97                 :            : 
      98                 :         26 : void ErrorOutput::print_real( const char* buffer )
      99                 :            : {
     100                 :         26 :     lineBuffer.insert( lineBuffer.end(), buffer, buffer + strlen( buffer ) );
     101                 :         26 :     process_line_buffer();
     102                 :         26 : }
     103                 :            : 
     104                 :          0 : void ErrorOutput::print_real( const std::string& str )
     105                 :            : {
     106                 :          0 :     lineBuffer.insert( lineBuffer.end(), str.begin(), str.end() );
     107                 :          0 :     process_line_buffer();
     108                 :          0 : }
     109                 :            : 
     110                 :         70 : void ErrorOutput::print_real( const char* fmt, va_list args1, va_list args2 )
     111                 :            : {
     112                 :         70 :     size_t idx = lineBuffer.size();
     113                 :            : #ifdef MOAB_HAVE_VSNPRINTF
     114                 :            :     // try once with remaining space in buffer
     115                 :         70 :     lineBuffer.resize( lineBuffer.capacity() );
     116                 :         70 :     unsigned size = vsnprintf( &lineBuffer[idx], lineBuffer.size() - idx, fmt, args1 );
     117                 :         70 :     ++size;  // trailing null
     118                 :            :     // if necessary, increase buffer size and retry
     119         [ -  + ]:         70 :     if( size > ( lineBuffer.size() - idx ) )
     120                 :            :     {
     121                 :          0 :         lineBuffer.resize( idx + size );
     122                 :          0 :         size = vsnprintf( &lineBuffer[idx], lineBuffer.size() - idx, fmt, args2 );
     123                 :          0 :         ++size;  // trailing null
     124                 :            :     }
     125                 :            : #else
     126                 :            :     // Guess how much space might be required.
     127                 :            :     // If every character is a format code then there are len/3 format codes.
     128                 :            :     // Guess a random large value of num_chars characters per formatted argument.
     129                 :            :     const unsigned num_chars = 180;
     130                 :            :     unsigned exp_size        = ( num_chars / 3 ) * strlen( fmt );
     131                 :            :     lineBuffer.resize( idx + exp_size );
     132                 :            :     unsigned size = vsprintf( &lineBuffer[idx], fmt, args1 );
     133                 :            :     ++size;  // trailing null
     134                 :            :     // check if we overflowed the buffer
     135                 :            :     if( size > exp_size )
     136                 :            :     {
     137                 :            :         // crap!
     138                 :            :         fprintf( stderr, "ERROR: Buffer overflow at %s:%d\n", __FILE__, __LINE__ );
     139                 :            :         lineBuffer.resize( idx + exp_size );
     140                 :            :         size = vsprintf( &lineBuffer[idx], fmt, args2 );
     141                 :            :         ++size;  // trailing null
     142                 :            :     }
     143                 :            : #endif
     144                 :            : 
     145                 :            :     // less one because we don't want the trailing '\0'
     146                 :         70 :     lineBuffer.resize( idx + size - 1 );
     147                 :         70 :     process_line_buffer();
     148                 :         70 : }
     149                 :            : 
     150                 :         96 : void ErrorOutput::process_line_buffer()
     151                 :            : {
     152                 :         96 :     size_t last_idx = 0;
     153                 :         96 :     std::vector< char >::iterator i;
     154 [ +  - ][ +  - ]:        288 :     for( i = std::find( lineBuffer.begin(), lineBuffer.end(), '\n' ); i != lineBuffer.end();
         [ +  - ][ +  + ]
     155                 :        192 :          i = std::find( i, lineBuffer.end(), '\n' ) )
     156                 :            :     {
     157         [ +  - ]:         96 :         *i = '\0';
     158 [ +  - ][ +  + ]:         96 :         if( have_rank() )
     159 [ +  - ][ +  - ]:         66 :             outputImpl->println( get_rank(), &lineBuffer[last_idx] );
                 [ +  - ]
     160                 :            :         else
     161 [ +  - ][ +  - ]:         30 :             outputImpl->println( &lineBuffer[last_idx] );
     162         [ +  - ]:         96 :         ++i;
     163         [ +  - ]:         96 :         last_idx = i - lineBuffer.begin();
     164                 :            :     }
     165                 :            : 
     166         [ +  - ]:         96 :     if( last_idx )
     167                 :            :     {
     168 [ +  - ][ +  - ]:         96 :         i = std::copy( lineBuffer.begin() + last_idx, lineBuffer.end(), lineBuffer.begin() );
     169         [ +  - ]:         96 :         lineBuffer.erase( i, lineBuffer.end() );
     170                 :            :     }
     171                 :         96 : }
     172                 :            : 
     173 [ +  - ][ +  - ]:        228 : }  // namespace moab

Generated by: LCOV version 1.11