00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021  
00022 
00023 #ifndef TCLAP_STDCMDLINEOUTPUT_H
00024 #define TCLAP_STDCMDLINEOUTPUT_H
00025 
00026 #include <string>
00027 #include <vector>
00028 #include <list>
00029 #include <iostream>
00030 #include <algorithm>
00031 
00032 #include <tclap/CmdLineInterface.h>
00033 #include <tclap/CmdLineOutput.h>
00034 #include <tclap/XorHandler.h>
00035 #include <tclap/Arg.h>
00036 
00037 namespace TCLAP {
00038 
00043 class StdOutput : public CmdLineOutput
00044 {
00045 
00046     public:
00047 
00053         virtual void usage(CmdLineInterface& c);
00054 
00060         virtual void version(CmdLineInterface& c);
00061 
00068         virtual void failure(CmdLineInterface& c, 
00069                      ArgException& e );
00070 
00071     protected:
00072 
00078         void _shortUsage( CmdLineInterface& c, std::ostream& os ) const;
00079 
00086         void _longUsage( CmdLineInterface& c, std::ostream& os ) const;
00087 
00099         void spacePrint( std::ostream& os, 
00100                          const std::string& s, 
00101                          int maxWidth, 
00102                          int indentSpaces, 
00103                          int secondLineOffset ) const;
00104 
00105 };
00106 
00107 
00108 inline void StdOutput::version(CmdLineInterface& _cmd) 
00109 {
00110     std::string progName = _cmd.getProgramName();
00111     std::string xversion = _cmd.getVersion();
00112 
00113     std::cout << std::endl << progName << "  version: " 
00114               << xversion << std::endl << std::endl;
00115 }
00116 
00117 inline void StdOutput::usage(CmdLineInterface& _cmd ) 
00118 {
00119     std::cout << std::endl << "USAGE: " << std::endl << std::endl; 
00120 
00121     _shortUsage( _cmd, std::cout );
00122 
00123     std::cout << std::endl << std::endl << "Where: " << std::endl << std::endl;
00124 
00125     _longUsage( _cmd, std::cout );
00126 
00127     std::cout << std::endl; 
00128 
00129 }
00130 
00131 inline void StdOutput::failure( CmdLineInterface& _cmd,
00132                                 ArgException& e ) 
00133 {
00134     std::string progName = _cmd.getProgramName();
00135 
00136     std::cerr << "PARSE ERROR: " << e.argId() << std::endl
00137               << "             " << e.error() << std::endl << std::endl;
00138 
00139     if ( _cmd.hasHelpAndVersion() )
00140         {
00141             std::cerr << "Brief USAGE: " << std::endl;
00142 
00143             _shortUsage( _cmd, std::cerr ); 
00144 
00145             std::cerr << std::endl << "For complete USAGE and HELP type: " 
00146                       << std::endl << "   " << progName << " --help" 
00147                       << std::endl << std::endl;
00148         }
00149     else
00150         usage(_cmd);
00151 
00152     throw ExitException(1);
00153 }
00154 
00155 inline void 
00156 StdOutput::_shortUsage( CmdLineInterface& _cmd, 
00157                         std::ostream& os ) const
00158 {
00159     std::list<Arg*> argList = _cmd.getArgList();
00160     std::string progName = _cmd.getProgramName();
00161     XorHandler xorHandler = _cmd.getXorHandler();
00162     std::vector< std::vector<Arg*> > xorList = xorHandler.getXorList();
00163 
00164     std::string s = progName + " ";
00165 
00166     
00167     for ( int i = 0; static_cast<unsigned int>(i) < xorList.size(); i++ )
00168         {
00169             s += " {";
00170             for ( ArgVectorIterator it = xorList[i].begin(); 
00171                   it != xorList[i].end(); it++ )
00172                 s += (*it)->shortID() + "|";
00173 
00174             s[s.length()-1] = '}';
00175         }
00176 
00177     
00178     for (ArgListIterator it = argList.begin(); it != argList.end(); it++)
00179         if ( !xorHandler.contains( (*it) ) )
00180             s += " " + (*it)->shortID();
00181 
00182     
00183     int secondLineOffset = static_cast<int>(progName.length()) + 2;
00184     if ( secondLineOffset > 75/2 )
00185         secondLineOffset = static_cast<int>(75/2);
00186 
00187     spacePrint( os, s, 75, 3, secondLineOffset );
00188 }
00189 
00190 inline void 
00191 StdOutput::_longUsage( CmdLineInterface& _cmd, 
00192                        std::ostream& os ) const
00193 {
00194     std::list<Arg*> argList = _cmd.getArgList();
00195     std::string message = _cmd.getMessage();
00196     XorHandler xorHandler = _cmd.getXorHandler();
00197     std::vector< std::vector<Arg*> > xorList = xorHandler.getXorList();
00198 
00199     
00200     for ( int i = 0; static_cast<unsigned int>(i) < xorList.size(); i++ )
00201         {
00202             for ( ArgVectorIterator it = xorList[i].begin(); 
00203                   it != xorList[i].end(); 
00204                   it++ )
00205                 {
00206                     spacePrint( os, (*it)->longID(), 75, 3, 3 );
00207                     spacePrint( os, (*it)->getDescription(), 75, 5, 0 );
00208 
00209                     if ( it+1 != xorList[i].end() )
00210                         spacePrint(os, "-- OR --", 75, 9, 0);
00211                 }
00212             os << std::endl << std::endl;
00213         }
00214 
00215     
00216     for (ArgListIterator it = argList.begin(); it != argList.end(); it++)
00217         if ( !xorHandler.contains( (*it) ) )
00218             {
00219                 spacePrint( os, (*it)->longID(), 75, 3, 3 ); 
00220                 spacePrint( os, (*it)->getDescription(), 75, 5, 0 ); 
00221                 os << std::endl;
00222             }
00223 
00224     os << std::endl;
00225 
00226     spacePrint( os, message, 75, 3, 0 );
00227 }
00228 
00229 inline void StdOutput::spacePrint( std::ostream& os, 
00230                                    const std::string& s, 
00231                                    int maxWidth, 
00232                                    int indentSpaces, 
00233                                    int secondLineOffset ) const
00234 {
00235     int len = static_cast<int>(s.length());
00236 
00237     if ( (len + indentSpaces > maxWidth) && maxWidth > 0 )
00238         {
00239             int allowedLen = maxWidth - indentSpaces;
00240             int start = 0;
00241             while ( start < len )
00242                 {
00243                     
00244                     
00245                     
00246                     using namespace std; 
00247                     int stringLen = min<int>( len - start, allowedLen );
00248 
00249                     
00250                     if ( stringLen == allowedLen )
00251                         while ( stringLen >= 0 &&
00252                                 s[stringLen+start] != ' ' && 
00253                                 s[stringLen+start] != ',' &&
00254                                 s[stringLen+start] != '|' ) 
00255                             stringLen--;
00256     
00257                     
00258                     
00259                     if ( stringLen <= 0 )
00260                         stringLen = allowedLen;
00261 
00262                     
00263                     for ( int i = 0; i < stringLen; i++ )
00264                         if ( s[start+i] == '\n' )
00265                             stringLen = i+1;
00266 
00267                     
00268                     for ( int i = 0; i < indentSpaces; i++ )
00269                         os << " ";
00270 
00271                     if ( start == 0 )
00272                         {
00273                             
00274                             indentSpaces += secondLineOffset;
00275 
00276                             
00277                             allowedLen -= secondLineOffset;
00278                         }
00279 
00280                     os << s.substr(start,stringLen) << std::endl;
00281 
00282                     
00283                     while ( s[stringLen+start] == ' ' && start < len )
00284                         start++;
00285             
00286                     start += stringLen;
00287                 }
00288         }
00289     else
00290         {
00291             for ( int i = 0; i < indentSpaces; i++ )
00292                 os << " ";
00293             os << s << std::endl;
00294         }
00295 }
00296 
00297 } 
00298 #endif