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 <tclap/CmdLineInterface.h>
00032 #include <tclap/CmdLineOutput.h>
00033 #include <tclap/XorHandler.h>
00034 #include <tclap/Arg.h>
00035 
00036 namespace TCLAP {
00037 
00042 class StdOutput : public CmdLineOutput
00043 {
00044 
00045     public:
00046 
00052         virtual void usage(CmdLineInterface& c);
00053 
00059         virtual void version(CmdLineInterface& c);
00060 
00067         virtual void failure(CmdLineInterface& c, 
00068                              ArgException& e );
00069 
00070     protected:
00071 
00077         void _shortUsage( CmdLineInterface& c, std::ostream& os ) const;
00078 
00085         void _longUsage( CmdLineInterface& c, std::ostream& os ) const;
00086 
00098         void spacePrint( std::ostream& os, 
00099                          const std::string& s, 
00100                          int maxWidth, 
00101                          int indentSpaces, 
00102                          int secondLineOffset ) const;
00103 
00104 };
00105 
00106 
00107 inline void StdOutput::version(CmdLineInterface& _cmd) 
00108 {
00109     std::string progName = _cmd.getProgramName();
00110     std::string version = _cmd.getVersion();
00111 
00112     std::cout << std::endl << progName << "  version: " 
00113               << version << std::endl << std::endl;
00114 }
00115 
00116 inline void StdOutput::usage(CmdLineInterface& _cmd ) 
00117 {
00118     std::cout << std::endl << "USAGE: " << std::endl << std::endl; 
00119 
00120     _shortUsage( _cmd, std::cout );
00121 
00122     std::cout << std::endl << std::endl << "Where: " << std::endl << std::endl;
00123 
00124     _longUsage( _cmd, std::cout );
00125 
00126     std::cout << std::endl; 
00127 
00128 }
00129 
00130 inline void StdOutput::failure( CmdLineInterface& _cmd,
00131                                 ArgException& e ) 
00132 {
00133     std::string progName = _cmd.getProgramName();
00134 
00135     std::cerr << "PARSE ERROR: " << e.argId() << std::endl
00136               << "             " << e.error() << std::endl << std::endl;
00137 
00138     if ( _cmd.hasHelpAndVersion() )
00139     {
00140         std::cerr << "Brief USAGE: " << std::endl;
00141 
00142         _shortUsage( _cmd, std::cerr ); 
00143 
00144         std::cerr << std::endl << "For complete USAGE and HELP type: " 
00145                   << std::endl << "   " << progName << " --help" 
00146                   << std::endl << std::endl;
00147     }
00148     else
00149         usage(_cmd);
00150 
00151 }
00152 
00153 inline void StdOutput::_shortUsage( CmdLineInterface& _cmd, 
00154                                     std::ostream& os ) const
00155 {
00156     std::list<Arg*> argList = _cmd.getArgList();
00157     std::string progName = _cmd.getProgramName();
00158     XorHandler xorHandler = _cmd.getXorHandler();
00159     std::vector< std::vector<Arg*> > xorList = xorHandler.getXorList();
00160 
00161     std::string s = progName + " ";
00162 
00163     // first the xor
00164     for ( int i = 0; static_cast<unsigned int>(i) < xorList.size(); i++ )
00165     {
00166         s += " {";
00167         for ( ArgVectorIterator it = xorList[i].begin(); 
00168                         it != xorList[i].end(); it++ )
00169             s += (*it)->shortID() + "|";
00170 
00171         s[s.length()-1] = '}';
00172     }
00173 
00174     // then the rest
00175     for (ArgListIterator it = argList.begin(); it != argList.end(); it++)
00176         if ( !xorHandler.contains( (*it) ) )
00177             s += " " + (*it)->shortID();
00178 
00179     // if the program name is too long, then adjust the second line offset 
00180     int secondLineOffset = static_cast<int>(progName.length()) + 2;
00181     if ( secondLineOffset > 75/2 )
00182             secondLineOffset = static_cast<int>(75/2);
00183 
00184     spacePrint( std::cout, s, 75, 3, secondLineOffset );
00185 }
00186 
00187 inline void StdOutput::_longUsage( CmdLineInterface& _cmd, 
00188                                    std::ostream& os ) const
00189 {
00190     std::list<Arg*> argList = _cmd.getArgList();
00191     std::string message = _cmd.getMessage();
00192     XorHandler xorHandler = _cmd.getXorHandler();
00193     std::vector< std::vector<Arg*> > xorList = xorHandler.getXorList();
00194 
00195     // first the xor 
00196     for ( int i = 0; static_cast<unsigned int>(i) < xorList.size(); i++ )
00197     {
00198         for ( ArgVectorIterator it = xorList[i].begin(); 
00199               it != xorList[i].end(); 
00200               it++ )
00201         {
00202             spacePrint( os, (*it)->longID(), 75, 3, 3 );
00203             spacePrint( os, (*it)->getDescription(), 75, 5, 0 );
00204 
00205             if ( it+1 != xorList[i].end() )
00206                 spacePrint(os, "-- OR --", 75, 9, 0);
00207         }
00208         os << std::endl << std::endl;
00209     }
00210 
00211     // then the rest
00212     for (ArgListIterator it = argList.begin(); it != argList.end(); it++)
00213         if ( !xorHandler.contains( (*it) ) )
00214         {
00215             spacePrint( os, (*it)->longID(), 75, 3, 3 ); 
00216             spacePrint( os, (*it)->getDescription(), 75, 5, 0 ); 
00217             os << std::endl;
00218         }
00219 
00220     os << std::endl;
00221 
00222     spacePrint( os, message, 75, 3, 0 );
00223 }
00224 
00225 inline void StdOutput::spacePrint( std::ostream& os, 
00226                                    const std::string& s, 
00227                                    int maxWidth, 
00228                                    int indentSpaces, 
00229                                    int secondLineOffset ) const
00230 {
00231     int len = static_cast<int>(s.length());
00232 
00233     if ( (len + indentSpaces > maxWidth) && maxWidth > 0 )
00234     {
00235         int allowedLen = maxWidth - indentSpaces;
00236         int start = 0;
00237         while ( start < len )
00238         {
00239             // find the substring length
00240             int stringLen = std::min( len - start, allowedLen );
00241 
00242             // trim the length so it doesn't end in middle of a word
00243             if ( stringLen == allowedLen )
00244                 while ( s[stringLen+start] != ' ' && 
00245                         s[stringLen+start] != ',' &&
00246                         s[stringLen+start] != '|' &&
00247                         stringLen >= 0 )
00248                     stringLen--;
00249     
00250             // ok, the word is longer than the line, so just split 
00251             // wherever the line ends
00252             if ( stringLen <= 0 )
00253                 stringLen = allowedLen;
00254 
00255             // check for newlines
00256             for ( int i = 0; i < stringLen; i++ )
00257                 if ( s[start+i] == '\n' )
00258                     stringLen = i+1;
00259 
00260             // print the indent 
00261             for ( int i = 0; i < indentSpaces; i++ )
00262                 os << " ";
00263 
00264             if ( start == 0 )
00265             {
00266                 // handle second line offsets
00267                 indentSpaces += secondLineOffset;
00268 
00269                 // adjust allowed len
00270                 allowedLen -= secondLineOffset;
00271             }
00272 
00273             os << s.substr(start,stringLen) << std::endl;
00274 
00275             // so we don't start a line with a space
00276             while ( s[stringLen+start] == ' ' && start < len )
00277                 start++;
00278             
00279             start += stringLen;
00280         }
00281     }
00282     else
00283     {
00284         for ( int i = 0; i < indentSpaces; i++ )
00285                 os << " ";
00286         os << s << std::endl;
00287     }
00288 }
00289 
00290 } //namespace TCLAP
00291 #endif 

Generated on Thu Dec 14 23:01:53 2006 for tclap by  doxygen 1.5.1