![]() |
VR-Link API Documentation for HLA 1.3
|
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 DtCmdLine_STDCMDLINEOUTPUT_H 00023 #define DtCmdLine_STDCMDLINEOUTPUT_H 00024 00028 00029 #include <string> 00030 #include <vector> 00031 #include <list> 00032 #include <iostream> 00033 #include <algorithm> 00034 #include <vlutil/vlPrint.h> 00035 #include <vlutil/vlProcessControl.h> 00036 00037 #include "cmdLineInterface.h" 00038 #include "cmdLineOutput.h" 00039 #include "cmdXorHandler.h" 00040 #include "cmdArg.h" 00041 00042 #ifdef DtUSE_UTILITIES_NAMESPACE 00043 namespace DtUSE_UTILITIES_NAMESPACE 00044 { 00045 #endif 00046 00047 namespace DtCmdLine { 00048 00053 00054 class StdOutput : public CmdLineOutput 00055 { 00056 00057 public: 00058 00059 virtual ~StdOutput() { } 00060 00066 virtual void usage(CmdLineInterface& c); 00067 00073 virtual void version(CmdLineInterface& c); 00074 00081 virtual void failure(CmdLineInterface& c, 00082 ArgException& e ); 00083 00084 protected: 00085 00091 void _shortUsage( CmdLineInterface& c, std::ostream& os ) const; 00092 00099 void _longUsage( CmdLineInterface& c, std::ostream& os ) const; 00100 00112 void spacePrint( std::ostream& os, 00113 const std::string& s, 00114 int maxWidth, 00115 int indentSpaces, 00116 int secondLineOffset ) const; 00117 00118 }; 00119 00120 00121 inline void StdOutput::version(CmdLineInterface& _cmd) 00122 { 00123 std::string progName = _cmd.getProgramName(); 00124 std::string version = _cmd.getVersion(); 00125 00126 int oldNotifyLevel = DtNotifyLevel; 00127 DtNotifyLevel = 3; 00128 DtInfo 00129 << '\n' << progName << " version: " 00130 << version << "\n\n"; 00131 DtNotifyLevel = oldNotifyLevel; 00132 } 00133 00134 inline void StdOutput::usage(CmdLineInterface& _cmd ) 00135 { 00136 int oldNotifyLevel = DtNotifyLevel; 00137 DtNotifyLevel = 3; 00138 DtInfo << '\n' << "USAGE: " << '\n' << '\n'; 00139 00140 _shortUsage( _cmd, DtInfo ); 00141 00142 DtInfo << '\n' << "Where: " << '\n'; 00143 00144 _longUsage( _cmd, DtInfo ); 00145 00146 DtInfo << std::endl; 00147 DtNotifyLevel = oldNotifyLevel; 00148 00149 } 00150 00151 inline void StdOutput::failure( CmdLineInterface& _cmd, ArgException& e ) 00152 { 00154 int oldNotifyLevel = DtNotifyLevel; 00155 DtNotifyLevel = 4; 00156 std::string progName = _cmd.getProgramName(); 00157 00158 DtWarn 00159 << "PARSE ERROR: " << e.argId() << '\n' 00160 << " " << e.error() << "\n\n" 00161 << "Brief USAGE: " << '\n'; 00162 00163 _shortUsage( _cmd, DtWarn ); 00164 00165 DtWarn 00166 << '\n' << "For complete USAGE and HELP type: " 00167 << '\n' << " " << progName << " --help" 00168 << '\n' << std::endl; 00169 DtNotifyLevel = oldNotifyLevel; 00170 00171 } 00172 00173 inline void StdOutput::_shortUsage( CmdLineInterface& _cmd, 00174 std::ostream& os ) const 00175 { 00176 std::list<Arg*> argList = _cmd.getArgList(); 00177 std::string progName = _cmd.getProgramName(); 00178 XorHandler xorHandler = _cmd.getXorHandler(); 00179 std::vector< std::vector<Arg*> > xorList = xorHandler.getXorList(); 00180 00181 std::string s = progName + " "; 00182 00184 for ( int i = 0; (unsigned int)i < xorList.size(); i++ ) 00185 { 00186 s += " {"; 00187 for ( ArgVectorIterator it = xorList[i].begin(); 00188 it != xorList[i].end(); it++ ) 00189 s += (*it)->shortID() + "|"; 00190 00191 s[s.length()-1] = '}'; 00192 } 00193 00195 for (ArgListIterator it = argList.begin(); it != argList.end(); it++) 00196 if ( !xorHandler.contains( (*it) ) ) 00197 s += " " + (*it)->shortID(); 00198 00200 int secondLineOffset = (int)(progName.length()) + 2; 00201 if ( secondLineOffset > 80/2 ) 00202 secondLineOffset = (int)(80/2); 00203 00204 spacePrint( os, s, 80, 3, secondLineOffset ); 00205 } 00206 00207 inline void StdOutput::_longUsage( CmdLineInterface& _cmd, 00208 std::ostream& os ) const 00209 { 00210 std::list<Arg*> argList = _cmd.getArgList(); 00211 std::string message = _cmd.getMessage(); 00212 XorHandler xorHandler = _cmd.getXorHandler(); 00213 std::vector< std::vector<Arg*> > xorList = xorHandler.getXorList(); 00214 00216 for ( int i = 0; (unsigned int)i < xorList.size(); i++ ) 00217 { 00218 for ( ArgVectorIterator it = xorList[i].begin(); 00219 it != xorList[i].end(); 00220 it++ ) 00221 { 00222 spacePrint( os, (*it)->longID(), 80, 3, 3 ); 00223 spacePrint( os, (*it)->getDescription(), 80, 12, 0 ); 00224 00225 if ( it+1 != xorList[i].end() ) 00226 spacePrint(os, "-- OR --", 80, 25, 0); 00227 } 00228 } 00229 00231 for (ArgListIterator it = argList.begin(); it != argList.end(); it++) 00232 { 00233 if ( !xorHandler.contains( (*it) ) ) 00234 { 00235 spacePrint( os, (*it)->longID(), 80, 3, 3 ); 00236 spacePrint( os, (*it)->getDescription(), 80, 12, 0 ); 00237 } 00238 } 00239 os << '\n'; 00240 spacePrint( os, message, 80, 3, 0 ); 00241 } 00242 00243 inline void StdOutput::spacePrint( std::ostream& os, 00244 const std::string& s, 00245 int maxWidth, 00246 int indentSpaces, 00247 int secondLineOffset ) const 00248 { 00249 int len = (int)(s.length()); 00250 00251 if ( (len + indentSpaces > maxWidth) && maxWidth > 0 ) 00252 { 00253 int allowedLen = maxWidth - indentSpaces; 00254 int start = 0; 00255 while ( start < len ) 00256 { 00258 #ifdef _WIN32 00259 int stringLen = ( len - start < allowedLen ? len - start : allowedLen); 00260 #else 00261 int stringLen = std::min( len - start, allowedLen ); 00262 #endif 00263 00265 if ( stringLen == allowedLen ) 00266 while ( s[stringLen+start] != ' ' && 00267 s[stringLen+start] != ',' && 00268 s[stringLen+start] != '|' && 00269 stringLen >= 0 ) 00270 stringLen--; 00271 00274 if ( stringLen <= 0 ) 00275 stringLen = allowedLen; 00276 00278 int i = 0; 00279 for (i = 0; i < stringLen; i++ ) 00280 if ( s[start+i] == '\n' ) 00281 stringLen = i+1; 00282 00284 for (i = 0; i < indentSpaces; i++ ) 00285 os << " "; 00286 00287 if ( start == 0 ) 00288 { 00290 indentSpaces += secondLineOffset; 00291 00293 allowedLen -= secondLineOffset; 00294 } 00295 00296 os << s.substr(start,stringLen) << std::endl; 00297 00299 while ( s[stringLen+start] == ' ' && start < len ) 00300 start++; 00301 00302 start += stringLen; 00303 } 00304 } 00305 else 00306 { 00307 for ( int i = 0; i < indentSpaces; i++ ) 00308 os << " "; 00309 os << s << std::endl; 00310 } 00311 } 00312 00313 } //namespace DtCmdLine 00314 00315 #ifdef DtUSE_UTILITIES_NAMESPACE 00316 } 00317 #endif 00318 00319 #endif