Main MRPT website > C++ reference
MRPT logo

StdOutput.h

Go to the documentation of this file.
00001 
00002 /****************************************************************************** 
00003  * 
00004  *  file:  StdOutput.h
00005  * 
00006  *  Copyright (c) 2004, Michael E. Smoot
00007  *  All rights reverved.
00008  * 
00009  *  See the file COPYING in the top directory of this distribution for
00010  *  more information.
00011  *  
00012  *  THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS 
00013  *  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
00014  *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
00015  *  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
00016  *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
00017  *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
00018  *  DEALINGS IN THE SOFTWARE.  
00019  *  
00020  *****************************************************************************/ 
00021 
00022 #ifndef TCLAP_STDCMDLINEOUTPUT_H
00023 #define TCLAP_STDCMDLINEOUTPUT_H
00024 
00025 #include <string>
00026 #include <vector>
00027 #include <list>
00028 #include <iostream>
00029 #include <algorithm>
00030 
00031 #include <mrpt/otherlibs/tclap/CmdLineInterface.h>
00032 #include <mrpt/otherlibs/tclap/CmdLineOutput.h>
00033 #include <mrpt/otherlibs/tclap/XorHandler.h>
00034 #include <mrpt/otherlibs/tclap/Arg.h>
00035 
00036 namespace TCLAP {
00037 
00038 /**
00039  * A class that isolates any output from the CmdLine object so that it
00040  * may be easily modified.
00041  */
00042 class StdOutput : public CmdLineOutput
00043 {
00044         protected:
00045                 std::ostream &m_my_output; //!< By JLBC for MRPT
00046 
00047         public:
00048                 /**
00049                  * Prints the usage to stdout.  Can be overridden to 
00050                  * produce alternative behavior.
00051                  * \param c - The CmdLine object the output is generated for. 
00052                  */
00053                 StdOutput( std::ostream &desired_out = std::cout ) : 
00054                   m_my_output(desired_out)
00055                 {
00056                 }
00057 
00058                 /**
00059                  * Prints the usage to stdout.  Can be overridden to 
00060                  * produce alternative behavior.
00061                  * \param c - The CmdLine object the output is generated for. 
00062                  */
00063                 virtual void usage(CmdLineInterface& c);
00064 
00065                 /**
00066                  * Prints the version to stdout. Can be overridden 
00067                  * to produce alternative behavior.
00068                  * \param c - The CmdLine object the output is generated for. 
00069                  */
00070                 virtual void version(CmdLineInterface& c);
00071 
00072                 /**
00073                  * Prints (to stderr) an error message, short usage 
00074                  * Can be overridden to produce alternative behavior.
00075                  * \param c - The CmdLine object the output is generated for. 
00076                  * \param e - The ArgException that caused the failure. 
00077                  */
00078                 virtual void failure(CmdLineInterface& c, 
00079                                                      ArgException& e );
00080 
00081         protected:
00082 
00083         /**
00084          * Writes a brief usage message with short args.
00085                  * \param c - The CmdLine object the output is generated for. 
00086          * \param os - The stream to write the message to.
00087          */
00088         void _shortUsage( CmdLineInterface& c, std::ostream& os ) const;
00089 
00090         /**
00091                  * Writes a longer usage message with long and short args, 
00092                  * provides descriptions and prints message.
00093                  * \param c - The CmdLine object the output is generated for. 
00094                  * \param os - The stream to write the message to.
00095                  */
00096                 void _longUsage( CmdLineInterface& c, std::ostream& os ) const;
00097 
00098                 /**
00099                  * This function inserts line breaks and indents long strings 
00100                  * according the  params input. It will only break lines at spaces, 
00101                  * commas and pipes.
00102                  * \param os - The stream to be printed to.
00103                  * \param s - The string to be printed.
00104                  * \param maxWidth - The maxWidth allowed for the output line. 
00105                  * \param indentSpaces - The number of spaces to indent the first line. 
00106                  * \param secondLineOffset - The number of spaces to indent the second
00107                  * and all subsequent lines in addition to indentSpaces.
00108                  */
00109                 void spacePrint( std::ostream& os, 
00110                                                  const std::string& s, 
00111                                                  int maxWidth, 
00112                                                  int indentSpaces, 
00113                                                  int secondLineOffset ) const;
00114 
00115 };
00116 
00117 
00118 inline void StdOutput::version(CmdLineInterface& _cmd) 
00119 {
00120         std::string progName = _cmd.getProgramName();
00121         std::string version = _cmd.getVersion();
00122 
00123         m_my_output << std::endl << progName << "  version: " 
00124                           << version << std::endl << std::endl;
00125 }
00126 
00127 inline void StdOutput::usage(CmdLineInterface& _cmd ) 
00128 {
00129         m_my_output << std::endl << "USAGE: " << std::endl << std::endl; 
00130 
00131         _shortUsage( _cmd, m_my_output );
00132 
00133         m_my_output << std::endl << std::endl << "Where: " << std::endl << std::endl;
00134 
00135         _longUsage( _cmd, m_my_output );
00136 
00137         m_my_output << std::endl; 
00138 
00139 }
00140 
00141 inline void StdOutput::failure( CmdLineInterface& _cmd,
00142                                                 ArgException& e ) 
00143 {
00144         std::string progName = _cmd.getProgramName();
00145 
00146         std::cerr << "PARSE ERROR: " << e.argId() << std::endl
00147                       << "             " << e.error() << std::endl << std::endl;
00148 
00149         if ( _cmd.hasHelpAndVersion() )
00150         {
00151                 std::cerr << "Brief USAGE: " << std::endl;
00152 
00153                 _shortUsage( _cmd, std::cerr ); 
00154 
00155                 std::cerr << std::endl << "For complete USAGE and HELP type: " 
00156                               << std::endl << "   " << progName << " --help" 
00157                                   << std::endl << std::endl;
00158         }
00159         else
00160                 usage(_cmd);
00161 
00162 }
00163 
00164 inline void StdOutput::_shortUsage( CmdLineInterface& _cmd, 
00165                                                     std::ostream& os ) const
00166 {
00167         std::list<Arg*> argList = _cmd.getArgList();
00168         std::string progName = _cmd.getProgramName();
00169         XorHandler xorHandler = _cmd.getXorHandler();
00170         std::vector< std::vector<Arg*> > xorList = xorHandler.getXorList();
00171 
00172         std::string s = progName + " ";
00173 
00174         // first the xor
00175         for ( int i = 0; static_cast<unsigned int>(i) < xorList.size(); i++ )
00176         {
00177                 s += " {";
00178                 for ( ArgVectorIterator it = xorList[i].begin(); 
00179                                                 it != xorList[i].end(); it++ )
00180                         s += (*it)->shortID() + "|";
00181 
00182                 s[s.length()-1] = '}';
00183         }
00184 
00185         // then the rest
00186         for (ArgListIterator it = argList.begin(); it != argList.end(); it++)
00187                 if ( !xorHandler.contains( (*it) ) )
00188                         s += " " + (*it)->shortID();
00189 
00190         // if the program name is too long, then adjust the second line offset 
00191         int secondLineOffset = static_cast<int>(progName.length()) + 2;
00192         if ( secondLineOffset > 75/2 )
00193                         secondLineOffset = static_cast<int>(75/2);
00194 
00195         spacePrint( m_my_output, s, 75, 3, secondLineOffset );
00196 }
00197 
00198 inline void StdOutput::_longUsage( CmdLineInterface& _cmd, 
00199                                                std::ostream& os ) const
00200 {
00201         std::list<Arg*> argList = _cmd.getArgList();
00202         std::string message = _cmd.getMessage();
00203         XorHandler xorHandler = _cmd.getXorHandler();
00204         std::vector< std::vector<Arg*> > xorList = xorHandler.getXorList();
00205 
00206         // first the xor 
00207         for ( int i = 0; static_cast<unsigned int>(i) < xorList.size(); i++ )
00208         {
00209                 for ( ArgVectorIterator it = xorList[i].begin(); 
00210                           it != xorList[i].end(); 
00211                           it++ )
00212                 {
00213                         spacePrint( os, (*it)->longID(), 75, 3, 3 );
00214                         spacePrint( os, (*it)->getDescription(), 75, 5, 0 );
00215 
00216                         if ( it+1 != xorList[i].end() )
00217                                 spacePrint(os, "-- OR --", 75, 9, 0);
00218                 }
00219                 os << std::endl << std::endl;
00220         }
00221 
00222         // then the rest
00223         for (ArgListIterator it = argList.begin(); it != argList.end(); it++)
00224                 if ( !xorHandler.contains( (*it) ) )
00225                 {
00226                         spacePrint( os, (*it)->longID(), 75, 3, 3 ); 
00227                         spacePrint( os, (*it)->getDescription(), 75, 5, 0 ); 
00228                         os << std::endl;
00229                 }
00230 
00231         os << std::endl;
00232 
00233         spacePrint( os, message, 75, 3, 0 );
00234 }
00235 
00236 inline void StdOutput::spacePrint( std::ostream& os, 
00237                                                            const std::string& s, 
00238                                                            int maxWidth, 
00239                                                            int indentSpaces, 
00240                                                            int secondLineOffset ) const
00241 {
00242         int len = static_cast<int>(s.length());
00243 
00244         if ( (len + indentSpaces > maxWidth) && maxWidth > 0 )
00245         {
00246                 int allowedLen = maxWidth - indentSpaces;
00247                 int start = 0;
00248                 while ( start < len )
00249                 {
00250                         // find the substring length
00251                         int stringLen = std::min( len - start, allowedLen );
00252 
00253                         // trim the length so it doesn't end in middle of a word
00254                         if ( stringLen == allowedLen )
00255                                 while ( s[stringLen+start] != ' ' && 
00256                                         s[stringLen+start] != ',' &&
00257                                         s[stringLen+start] != '|' &&
00258                                                 stringLen >= 0 )
00259                                         stringLen--;
00260         
00261                         // ok, the word is longer than the line, so just split 
00262                         // wherever the line ends
00263                         if ( stringLen <= 0 )
00264                                 stringLen = allowedLen;
00265 
00266                         // check for newlines
00267                         for ( int i = 0; i < stringLen; i++ )
00268                                 if ( s[start+i] == '\n' )
00269                                         stringLen = i+1;
00270 
00271                         // print the indent     
00272                         for ( int i = 0; i < indentSpaces; i++ )
00273                                 os << " ";
00274 
00275                         if ( start == 0 )
00276                         {
00277                                 // handle second line offsets
00278                                 indentSpaces += secondLineOffset;
00279 
00280                                 // adjust allowed len
00281                                 allowedLen -= secondLineOffset;
00282                         }
00283 
00284                         os << s.substr(start,stringLen) << std::endl;
00285 
00286                         // so we don't start a line with a space
00287                         while ( s[stringLen+start] == ' ' && start < len )
00288                                 start++;
00289                         
00290                         start += stringLen;
00291                 }
00292         }
00293         else
00294         {
00295                 for ( int i = 0; i < indentSpaces; i++ )
00296                                 os << " ";
00297                 os << s << std::endl;
00298         }
00299 }
00300 
00301 } //namespace TCLAP
00302 #endif 



Page generated by Doxygen 1.7.3 for MRPT 0.9.4 SVN:exported at Tue Jan 25 21:56:31 UTC 2011