cmtkConsole.cxx

Go to the documentation of this file.
00001 /*
00002 //
00003 //  Copyright 1997-2009 Torsten Rohlfing
00004 //
00005 //  Copyright 2004-2010 SRI International
00006 //
00007 //  This file is part of the Computational Morphometry Toolkit.
00008 //
00009 //  http://www.nitrc.org/projects/cmtk/
00010 //
00011 //  The Computational Morphometry Toolkit is free software: you can
00012 //  redistribute it and/or modify it under the terms of the GNU General Public
00013 //  License as published by the Free Software Foundation, either version 3 of
00014 //  the License, or (at your option) any later version.
00015 //
00016 //  The Computational Morphometry Toolkit is distributed in the hope that it
00017 //  will be useful, but WITHOUT ANY WARRANTY; without even the implied
00018 //  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019 //  GNU General Public License for more details.
00020 //
00021 //  You should have received a copy of the GNU General Public License along
00022 //  with the Computational Morphometry Toolkit.  If not, see
00023 //  <http://www.gnu.org/licenses/>.
00024 //
00025 //  $Revision: 2152 $
00026 //
00027 //  $LastChangedDate: 2010-08-04 10:19:33 -0700 (Wed, 04 Aug 2010) $
00028 //
00029 //  $LastChangedBy: torstenrohlfing $
00030 //
00031 */
00032 
00033 #include "cmtkConsole.h"
00034 
00035 #ifdef HAVE_UNISTD_H
00036 #  include <unistd.h>
00037 #endif
00038 
00039 #ifdef HAVE_SYS_IOCTL_H
00040 #  include <sys/ioctl.h>
00041 #endif
00042 
00043 #ifdef HAVE_TERMIOS_H
00044 #  include <termios.h>
00045 #endif
00046 
00047 #include <algorithm>
00048 #include <cstdarg>
00049 #include <stdio.h>
00050 
00051 namespace
00052 cmtk
00053 {
00054 
00057 Console StdErr( std::cerr );
00058 Console StdOut( std::cout );
00059 
00060 size_t
00061 Console::GetLineWidth() const
00062 {
00063 #if defined(HAVE_SYS_IOCTL_H) && defined(TIOCGWINSZ)
00064   struct winsize sz;
00065   if ( ioctl(0, TIOCGWINSZ, &sz) >= 0 )
00066     return sz.ws_col;
00067 #endif
00068   // default to 80
00069   return 80;
00070 }
00071 
00072 Console& 
00073 Console::FormatText( const std::string& text, const size_t margin, const size_t width, const int firstLine )
00074 {
00075   // Set current indentation to first line.
00076   size_t currentIndent = static_cast<size_t>( std::max<int>( 0, margin + firstLine ) );
00077 
00078   // set the actual width
00079   const size_t actualWidth = width ? width : this->GetLineWidth();
00080 
00081   // the effective length of a line
00082   size_t length = static_cast<size_t>( std::max<int>( 1, actualWidth - currentIndent ) ) - 1;
00083 
00084   // loop while text left to write
00085   std::string remaining = text;
00086   while ( remaining.length() > length )
00087     {
00088     // first, see if we have forced line breaks within the first "length" characters.
00089     size_t breakAt = remaining.find_first_of( "\n\r", 0 );
00090 
00091     // nothing forced in range, check for available spaces before max length
00092     if ( (breakAt == std::string::npos) || (breakAt >= length) )
00093       breakAt = remaining.find_last_of( " ", length+1 );
00094 
00095     // if no more spaces within available length, look for first available
00096     if ( breakAt == std::string::npos )
00097       breakAt = remaining.find_first_of( " ", length+1 );
00098 
00099     // if no more spaces at all, bail
00100     if ( breakAt == std::string::npos )
00101       break;
00102 
00103     this->Indent( currentIndent );
00104     (*this) << remaining.substr( 0, breakAt ) << "\n";
00105     remaining.erase( 0, breakAt+1 );
00106     currentIndent = margin;
00107     length = static_cast<size_t>( std::max<int>( 1, actualWidth - currentIndent ) ) - 1;
00108     }
00109   
00110   size_t breakAt = remaining.find_first_of( "\n\r", 0 );
00111   while ( breakAt != std::string::npos )
00112     {
00113     this->Indent( currentIndent );
00114     (*this) << remaining.substr( 0, breakAt ) << "\n";
00115     remaining.erase( 0, breakAt+1 );
00116     breakAt = remaining.find_first_of( "\n\r", 0 );
00117     currentIndent = margin;
00118     }
00119 
00120   this->Indent( currentIndent );
00121   return (*this) << remaining << "\n";
00122 }
00123 
00124 void 
00125 Console::printf( const char* format, ... )
00126 {
00127 #ifdef CMTK_BUILD_MPI
00128     // for now, skip the output entirely if this is not the root process.
00129   if ( this->m_RankMPI < 0 ) this->m_RankMPI = MPI::COMM_WORLD.Get_rank();
00130     if ( this->m_RankMPI ) return;
00131 #endif
00132   char buffer[1024];
00133 
00134   va_list args;
00135   va_start(args, format);
00136   vsnprintf( buffer, sizeof( buffer ), format, args );
00137   va_end(args);
00138 
00139   this->Indent();
00140 
00141   LockingPtr<std::ostream> pStream( this->m_Stream, this->m_MutexLock );
00142   *pStream << buffer;
00143 }
00144 
00145 void 
00146 Console::Indent
00147 ( size_t level )
00148 {
00149   if ( ! level )
00150     level = this->IndentLevel;
00151   
00152   for ( size_t i = 0; i < level; ++i ) 
00153     (*this) << " ";
00154 }
00155 
00156 } // namespace cmtk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines