std_output.hpp
Go to the documentation of this file.
00001 
00011 /*****************************************************************************
00012 ** Ifdefs
00013 *****************************************************************************/
00014 
00015 #ifndef TCLAP_STDCMDLINEOUTPUT_H
00016 #define TCLAP_STDCMDLINEOUTPUT_H
00017 
00018 #include <string>
00019 #include <vector>
00020 #include <list>
00021 #include <iostream>
00022 #include <algorithm>
00023 #include <cmath>
00024 
00025 #include "cmd_line_interface.hpp"
00026 #include "cmd_line_output.hpp"
00027 #include "xor_handler.hpp"
00028 #include "arg.hpp"
00029 
00030 namespace ecl {
00031 
00038 class StdOutput : public CmdLineOutput
00039 {
00040 
00041         public:
00042 
00048                 virtual void usage(CmdLineInterface& c);
00049 
00055                 virtual void version(CmdLineInterface& c);
00056 
00063                 virtual void failure(CmdLineInterface& c,
00064                                                      ArgException& e );
00065 
00066         protected:
00067 
00073         void _shortUsage( CmdLineInterface& c, std::ostream& os ) const;
00074 
00081                 void _longUsage( CmdLineInterface& c, std::ostream& os ) const;
00082 
00094                 void spacePrint( std::ostream& os,
00095                                                  const std::string& s,
00096                                                  int maxWidth,
00097                                                  int indentSpaces,
00098                                                  int secondLineOffset ) const;
00099 
00100 };
00101 
00102 
00103 inline void StdOutput::version(CmdLineInterface& _cmd)
00104 {
00105         std::string progName = _cmd.getProgramName();
00106         std::string interface_version = _cmd.getVersion();
00107 
00108         std::cout << std::endl << progName << "  version: "
00109                           << interface_version << std::endl << std::endl;
00110 }
00111 
00112 inline void StdOutput::usage(CmdLineInterface& _cmd )
00113 {
00114         std::cout << std::endl << "USAGE: " << std::endl << std::endl;
00115 
00116         _shortUsage( _cmd, std::cout );
00117 
00118         std::cout << std::endl << std::endl << "Where: " << std::endl << std::endl;
00119 
00120         _longUsage( _cmd, std::cout );
00121 
00122         std::cout << std::endl;
00123 
00124 }
00125 
00126 inline void StdOutput::failure( CmdLineInterface& _cmd,
00127                                                 ArgException& e )
00128 {
00129         std::string progName = _cmd.getProgramName();
00130 
00131         std::cerr << "PARSE ERROR: " << e.argId() << std::endl
00132                       << "             " << e.error() << std::endl << std::endl;
00133 
00134         if ( _cmd.hasHelpAndVersion() )
00135         {
00136                 std::cerr << "Brief USAGE: " << std::endl;
00137 
00138                 _shortUsage( _cmd, std::cerr );
00139 
00140                 std::cerr << std::endl << "For complete USAGE and HELP type: "
00141                               << std::endl << "   " << progName << " --help"
00142                                   << std::endl << std::endl;
00143         }
00144         else
00145                 usage(_cmd);
00146 
00147 }
00148 
00149 inline void StdOutput::_shortUsage( CmdLineInterface& _cmd,
00150                                                     std::ostream& os ) const
00151 {
00152         std::list<Arg*> argList = _cmd.getArgList();
00153         std::string progName = _cmd.getProgramName();
00154         XorHandler xorHandler = _cmd.getXorHandler();
00155         std::vector< std::vector<Arg*> > xorList = xorHandler.getXorList();
00156 
00157         std::string s = progName + " ";
00158 
00159         // first the xor
00160         for ( int i = 0; static_cast<unsigned int>(i) < xorList.size(); i++ )
00161         {
00162                 s += " {";
00163                 for ( ArgVectorIterator it = xorList[i].begin();
00164                                                 it != xorList[i].end(); it++ )
00165                         s += (*it)->shortID() + "|";
00166 
00167                 s[s.length()-1] = '}';
00168         }
00169 
00170         // then the rest
00171         for (ArgListIterator it = argList.begin(); it != argList.end(); it++)
00172                 if ( !xorHandler.contains( (*it) ) )
00173                         s += " " + (*it)->shortID();
00174 
00175         // if the program name is too long, then adjust the second line offset
00176         int secondLineOffset = static_cast<int>(progName.length()) + 2;
00177         if ( secondLineOffset > 75/2 )
00178                         secondLineOffset = static_cast<int>(75/2);
00179 
00180     spacePrint( os, s, 75, 3, secondLineOffset );
00181         //spacePrint( std::cout, s, 75, 3, secondLineOffset );
00182 }
00183 
00184 inline void StdOutput::_longUsage( CmdLineInterface& _cmd,
00185                                                std::ostream& os ) const
00186 {
00187         std::list<Arg*> argList = _cmd.getArgList();
00188         std::string message = _cmd.getMessage();
00189         XorHandler xorHandler = _cmd.getXorHandler();
00190         std::vector< std::vector<Arg*> > xorList = xorHandler.getXorList();
00191 
00192         // first the xor
00193         for ( int i = 0; static_cast<unsigned int>(i) < xorList.size(); i++ )
00194         {
00195                 for ( ArgVectorIterator it = xorList[i].begin();
00196                           it != xorList[i].end();
00197                           it++ )
00198                 {
00199                         spacePrint( os, (*it)->longID(), 75, 3, 3 );
00200                         spacePrint( os, (*it)->getDescription(), 75, 5, 0 );
00201 
00202                         if ( it+1 != xorList[i].end() )
00203                                 spacePrint(os, "-- OR --", 75, 9, 0);
00204                 }
00205                 os << std::endl << std::endl;
00206         }
00207 
00208         // then the rest
00209         for (ArgListIterator it = argList.begin(); it != argList.end(); it++)
00210                 if ( !xorHandler.contains( (*it) ) )
00211                 {
00212                         spacePrint( os, (*it)->longID(), 75, 3, 3 );
00213                         spacePrint( os, (*it)->getDescription(), 75, 5, 0 );
00214                         os << std::endl;
00215                 }
00216 
00217         os << std::endl;
00218 
00219         spacePrint( os, message, 75, 3, 0 );
00220 }
00221 
00222 inline void StdOutput::spacePrint( std::ostream& os,
00223                                                            const std::string& s,
00224                                                            int maxWidth,
00225                                                            int indentSpaces,
00226                                                            int secondLineOffset ) const
00227 {
00228         int len = static_cast<int>(s.length());
00229 
00230         if ( (len + indentSpaces > maxWidth) && maxWidth > 0 )
00231         {
00232                 int allowedLen = maxWidth - indentSpaces;
00233                 int start = 0;
00234                 while ( start < len )
00235                 {
00236                         // find the substring length
00237                   int stringLen = std::min<int>( len - start, allowedLen );
00238 
00239                         // trim the length so it doesn't end in middle of a word
00240                         if ( stringLen == allowedLen )
00241                                 while ( s[stringLen+start] != ' ' &&
00242                                         s[stringLen+start] != ',' &&
00243                                         s[stringLen+start] != '|' &&
00244                                                 stringLen >= 0 )
00245                                         stringLen--;
00246 
00247                         // ok, the word is longer than the line, so just split
00248                         // wherever the line ends
00249                         if ( stringLen <= 0 )
00250                                 stringLen = allowedLen;
00251 
00252                         // check for newlines
00253                         for ( int i = 0; i < stringLen; i++ )
00254                                 if ( s[start+i] == '\n' )
00255                                         stringLen = i+1;
00256 
00257                         // print the indent
00258                         for ( int i = 0; i < indentSpaces; i++ )
00259                                 os << " ";
00260 
00261                         if ( start == 0 )
00262                         {
00263                                 // handle second line offsets
00264                                 indentSpaces += secondLineOffset;
00265 
00266                                 // adjust allowed len
00267                                 allowedLen -= secondLineOffset;
00268                         }
00269 
00270                         os << s.substr(start,stringLen) << std::endl;
00271 
00272                         // so we don't start a line with a space
00273                         while ( s[stringLen+start] == ' ' && start < len )
00274                                 start++;
00275 
00276                         start += stringLen;
00277                 }
00278         }
00279         else
00280         {
00281                 for ( int i = 0; i < indentSpaces; i++ )
00282                                 os << " ";
00283                 os << s << std::endl;
00284         }
00285 }
00286 }; // namespace ecl
00287 
00288 #endif


ecl_command_line
Author(s): Daniel Stonier (d.stonier@gmail.com)
autogenerated on Thu Jan 2 2014 11:12:37