$search
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