changed output around

This commit is contained in:
mes5k 2004-11-05 05:07:12 +00:00
parent c0aa4a9042
commit 6f2d4828a8
9 changed files with 535 additions and 144 deletions

View File

@ -507,7 +507,7 @@ inline void Arg::trimFlag(std::string& flag, std::string& value) const
{
int stop = 0;
for ( int i = 0; (unsigned int)i < flag.length(); i++ )
if ( flag[i] == delimiter() )
if ( flag[i] == Arg::delimiter() )
{
stop = i;
break;

View File

@ -32,10 +32,15 @@
#include <tclap/VersionVisitor.h>
#include <tclap/IgnoreRestVisitor.h>
#include <tclap/CmdLineOutput.h>
#include <tclap/StdOutput.h>
#include <string>
#include <vector>
#include <list>
#include <iostream>
#include <ostream>
#include <iomanip>
#include <algorithm>
namespace TCLAP {
@ -101,6 +106,11 @@ class CmdLine : public CmdLineInterface
*/
std::list<Visitor*> _visitorDeleteOnExitList;
/**
* Object that handles all output for the CmdLine.
*/
CmdLineOutput* _output;
/**
* Checks whether a name/flag string matches entirely matches
* the Arg::blankChar. Used when multiple switches are combined
@ -109,19 +119,6 @@ class CmdLine : public CmdLineInterface
*/
bool _emptyCombined(const std::string& s);
/**
* Writes a brief usage message with short args.
* \param os - The stream to write the message to.
*/
void _shortUsage( std::ostream& os );
/**
* Writes a longer usage message with long and short args,
* provides descriptions and prints message.
* \param os - The stream to write the message to.
*/
void _longUsage( std::ostream& os );
private:
/**
@ -202,33 +199,52 @@ class CmdLine : public CmdLineInterface
*/
void xorAdd( std::vector<Arg*>& xors );
/**
* Prints the usage to stdout and exits. Can be overridden to
* produce alternative behavior.
* \param exitVal - Value to exit with.
*/
virtual void usage( int exitVal = 0 );
/**
* Prints the version to stdout and exits. Can be overridden
* to produce alternative behavior.
* \param exitVal - Value to exit with.
*/
virtual void version( int exitVal = 0 );
/**
* Prints (to stderr) an error message, short usage and exits with a
* value of 1. Can be overridden to produce alternative behavior.
* \param e - The ArgException that caused the failure.
*/
virtual void failure( const ArgException& e );
/**
* Parses the command line.
* \param argc - Number of arguments.
* \param argv - Array of arguments.
*/
void parse(int argc, char** argv);
/**
*
*/
CmdLineOutput* getOutput();
/**
*
*/
void setOutput(CmdLineOutput* co);
/**
*
*/
std::string& getVersion();
/**
*
*/
std::string& getProgramName();
/**
*
*/
std::list<Arg*>& getArgList();
/**
*
*/
XorHandler& getXorHandler();
/**
*
*/
char getDelimiter();
/**
*
*/
std::string& getMessage();
};
@ -278,23 +294,25 @@ inline CmdLine::~CmdLine()
inline void CmdLine::_constructor()
{
_output = new StdOutput;
Visitor *v;
Arg::setDelimiter( _delimiter );
v = new HelpVisitor( this );
v = new HelpVisitor( this, _output );
SwitchArg* help = new SwitchArg("h","help",
"Displays usage information and exits.",
false, v);
add( *help );
add( help );
deleteOnExit(help);
deleteOnExit(v);
v = new VersionVisitor( this );
v = new VersionVisitor( this, _output );
SwitchArg* vers = new SwitchArg("v","version",
"Displays version information and exits.",
false, v);
add( *vers );
add( vers );
deleteOnExit(vers);
deleteOnExit(v);
@ -303,7 +321,7 @@ inline void CmdLine::_constructor()
Arg::ignoreNameString(),
"Ignores the rest of the labeled arguments following this flag.",
false, v);
add( *ignore );
add( ignore );
deleteOnExit(ignore);
deleteOnExit(v);
}
@ -344,72 +362,8 @@ inline void CmdLine::add( Arg* a )
a->addToList( _argList );
if ( a->isRequired() ) _numRequired++;
}
inline void CmdLine::version(int exitVal)
{
std::cout << std::endl << _progName << " version: "
<< _version << std::endl << std::endl;
exit( exitVal );
}
inline void CmdLine::_shortUsage( std::ostream& os )
{
std::string s = _progName + " " + _xorHandler.shortUsage();
for (ArgIterator it = _argList.begin(); it != _argList.end(); it++)
if ( !_xorHandler.contains( (*it) ) )
s += " " + (*it)->shortID();
spacePrint( os, s, 75, 3, (int)(_progName.length()) + 2 );
}
inline void CmdLine::_longUsage( std::ostream& os )
{
_xorHandler.printLongUsage( os );
for (ArgIterator it = _argList.begin(); it != _argList.end(); it++)
if ( !_xorHandler.contains( (*it) ) )
{
spacePrint( os, (*it)->longID(), 75, 3, 3 );
spacePrint( os, (*it)->getDescription(), 75, 5, 0 );
os << std::endl;
}
os << std::endl;
spacePrint( os, _message, 75, 3, 0 );
}
inline void CmdLine::usage( int exitVal )
{
std::cout << std::endl << "USAGE: " << std::endl << std::endl;
_shortUsage( std::cout );
std::cout << std::endl << std::endl << "Where: " << std::endl << std::endl;
_longUsage( std::cout );
std::cout << std::endl;
exit( exitVal );
}
inline void CmdLine::failure( const ArgException& e )
{
std::cerr << "PARSE ERROR: " << e.argId() << std::endl
<< " " << e.error() << std::endl << std::endl;
std::cerr << "Brief USAGE: " << std::endl;
_shortUsage( std::cerr );
std::cerr << std::endl << "For complete USAGE and HELP type: "
<< std::endl << " " << _progName << " --help"
<< std::endl << std::endl;
exit(1);
if ( a->isRequired() )
_numRequired++;
}
inline void CmdLine::parse(int argc, char** argv)
@ -454,7 +408,7 @@ inline void CmdLine::parse(int argc, char** argv)
if ( requiredCount > _numRequired )
throw(CmdLineParseException("Too many arguments!"));
} catch ( ArgException& e ) { failure(e); }
} catch ( ArgException e ) { _output->failure(*this,e); exit(1); }
}
inline bool CmdLine::_emptyCombined(const std::string& s)
@ -479,6 +433,46 @@ inline void CmdLine::deleteOnExit(Visitor* ptr)
_visitorDeleteOnExitList.push_back(ptr);
}
inline CmdLineOutput* CmdLine::getOutput()
{
return _output;
}
inline void CmdLine::setOutput(CmdLineOutput* co)
{
_output = co;
}
inline std::string& CmdLine::getVersion()
{
return _version;
}
inline std::string& CmdLine::getProgramName()
{
return _progName;
}
inline std::list<Arg*>& CmdLine::getArgList()
{
return _argList;
}
inline XorHandler& CmdLine::getXorHandler()
{
return _xorHandler;
}
inline char CmdLine::getDelimiter()
{
return _delimiter;
}
inline std::string& CmdLine::getMessage()
{
return _message;
}
///////////////////////////////////////////////////////////////////////////////
//End CmdLine.cpp
///////////////////////////////////////////////////////////////////////////////

View File

@ -1,4 +1,3 @@
/* -*- Mode: CC; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/******************************************************************************
*
@ -30,9 +29,12 @@
#include <iostream>
#include <algorithm>
namespace TCLAP {
class Arg;
class CmdLineOutput;
class XorHandler;
/**
* The base class that manages the command line definition and passes
@ -75,31 +77,52 @@ class CmdLineInterface
*/
virtual void xorAdd( std::vector<Arg*>& xors )=0;
/**
* Prints the usage to stdout and exits.
* \param exitVal - Value to exit with.
*/
virtual void usage( int exitVal = 0 )=0;
/**
* Prints the version to stdout and exits.
* \param exitVal - Value to exit with.
*/
virtual void version( int exitVal = 0 )=0;
/**
* Prints (to stderr) an error message, short usage and exits with a
* value of 1. Can be overridden to produce alternative behavior.
* \param e - The ArgException that caused the failure.
*/
virtual void failure( const ArgException& e )=0;
/**
* Parses the command line.
* \param argc - Number of arguments.
* \param argv - Array of arguments.
*/
virtual void parse(int argc, char** argv)=0;
/**
* Returns the CmdLineOutput object.
*/
virtual CmdLineOutput* getOutput()=0;
/**
* \param co - CmdLineOutput object that we want to use instead.
*/
virtual void setOutput(CmdLineOutput* co)=0;
/**
* Returns the version string.
*/
virtual std::string& getVersion()=0;
/**
* Returns the program name string.
*/
virtual std::string& getProgramName()=0;
/**
* Returns the argList.
*/
virtual std::list<Arg*>& getArgList()=0;
/**
* Returns the XorHandler.
*/
virtual XorHandler& getXorHandler()=0;
/**
* Returns the delimiter string.
*/
virtual char getDelimiter()=0;
/**
* Returns the message string.
*/
virtual std::string& getMessage()=0;
};
} //namespace

View File

@ -0,0 +1,69 @@
/******************************************************************************
*
* file: CmdLineOutput.h
*
* Copyright (c) 2004, Michael E. Smoot
* All rights reverved.
*
* See the file COPYING in the top directory of this distribution for
* more information.
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#ifndef TCLAP_CMDLINEOUTPUT_H
#define TCLAP_CMDLINEOUTPUT_H
#include <string>
#include <vector>
#include <list>
#include <iostream>
#include <ostream>
#include <iomanip>
#include <algorithm>
namespace TCLAP {
class CmdLineInterface;
class ArgException;
/**
* The interface that any output object must implement.
*/
class CmdLineOutput
{
public:
/**
* Generates some sort of output for the USAGE.
* \param c - The CmdLine object the output is generated for.
*/
virtual void usage(CmdLineInterface& c)=0;
/**
* Generates some sort of output for the version.
* \param c - The CmdLine object the output is generated for.
*/
virtual void version(CmdLineInterface& c)=0;
/**
* Generates some sort of output for a failure.
* \param c - The CmdLine object the output is generated for.
* \param e - The ArgException that caused the failure.
*/
virtual void failure( CmdLineInterface& c,
ArgException& e )=0;
};
} //namespace TCLAP
#endif

View File

@ -23,34 +23,44 @@
#define TCLAP_HELP_VISITOR_H
#include <tclap/CmdLineInterface.h>
#include <tclap/CmdLineOutput.h>
#include <tclap/Visitor.h>
namespace TCLAP {
/**
* A Visitor object that calls the usage method of a given CmdLine.
* A Visitor object that calls the usage method of the given CmdLineOutput
* object for the specified CmdLine object.
*/
class HelpVisitor: public Visitor
{
protected:
/**
* The CmdLine that will be called for the usage method.
* The CmdLine the output will be generated for.
*/
CmdLineInterface* _cmd;
/**
* The output object.
*/
CmdLineOutput* _out;
public:
/**
* Constructor.
* \param cmd - The CmdLine that will called for usage method.
* \param cmd - The CmdLine the output will be generated for.
* \param out - The type of output.
*/
HelpVisitor(CmdLineInterface* cmd) : Visitor(), _cmd( cmd ) { }
HelpVisitor(CmdLineInterface* cmd, CmdLineOutput* out)
: Visitor(), _cmd( cmd ), _out( out ) { }
/**
* Calls the usage method of the CmdLine.
* Calls the usage method of the CmdLineOutput for the
* specified CmdLine.
*/
void visit() { _cmd->usage(0); }
void visit() { _out->usage(*_cmd); exit(0); }
};

View File

@ -15,5 +15,6 @@ libtclapinclude_HEADERS = \
SwitchArg.h \
VersionVisitor.h \
IgnoreRestVisitor.h \
PrintSensibly.h
CmdLineOutput.h \
StdOutput.h

275
include/tclap/StdOutput.h Normal file
View File

@ -0,0 +1,275 @@
/******************************************************************************
*
* file: StdOutput.h
*
* Copyright (c) 2004, Michael E. Smoot
* All rights reverved.
*
* See the file COPYING in the top directory of this distribution for
* more information.
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#ifndef TCLAP_STDCMDLINEOUTPUT_H
#define TCLAP_STDCMDLINEOUTPUT_H
#include <string>
#include <vector>
#include <list>
#include <iostream>
#include <algorithm>
#include <tclap/CmdLineInterface.h>
#include <tclap/CmdLineOutput.h>
#include <tclap/XorHandler.h>
#include <tclap/Arg.h>
namespace TCLAP {
/**
* A class that isolates any output from the CmdLine object so that it
* may be easily modified.
*/
class StdOutput : public CmdLineOutput
{
public:
/**
* Prints the usage to stdout. Can be overridden to
* produce alternative behavior.
* \param c - The CmdLine object the output is generated for.
*/
virtual void usage(CmdLineInterface& c);
/**
* Prints the version to stdout. Can be overridden
* to produce alternative behavior.
* \param c - The CmdLine object the output is generated for.
*/
virtual void version(CmdLineInterface& c);
/**
* Prints (to stderr) an error message, short usage
* Can be overridden to produce alternative behavior.
* \param c - The CmdLine object the output is generated for.
* \param e - The ArgException that caused the failure.
*/
virtual void failure(CmdLineInterface& c,
ArgException& e );
protected:
/**
* Writes a brief usage message with short args.
* \param c - The CmdLine object the output is generated for.
* \param os - The stream to write the message to.
*/
void _shortUsage( CmdLineInterface& c, std::ostream& os ) const;
/**
* Writes a longer usage message with long and short args,
* provides descriptions and prints message.
* \param c - The CmdLine object the output is generated for.
* \param os - The stream to write the message to.
*/
void _longUsage( CmdLineInterface& c, std::ostream& os ) const;
/**
* This function inserts line breaks and indents long strings
* according the params input. It will only break lines at spaces,
* commas and pipes.
* \param os - The stream to be printed to.
* \param s - The string to be printed.
* \param maxWidth - The maxWidth allowed for the output line.
* \param indentSpaces - The number of spaces to indent the first line.
* \param secondLineOffset - The number of spaces to indent the second
* and all subsequent lines in addition to indentSpaces.
*/
void spacePrint( std::ostream& os,
const std::string& s,
int maxWidth,
int indentSpaces=0,
int secondLineOffset=0 ) const;
};
inline void StdOutput::version(CmdLineInterface& _cmd)
{
std::string progName = _cmd.getProgramName();
std::string version = _cmd.getVersion();
std::cout << std::endl << progName << " version: "
<< version << std::endl << std::endl;
}
inline void StdOutput::usage(CmdLineInterface& _cmd )
{
std::cout << std::endl << "USAGE: " << std::endl << std::endl;
_shortUsage( _cmd, std::cout );
std::cout << std::endl << std::endl << "Where: " << std::endl << std::endl;
_longUsage( _cmd, std::cout );
std::cout << std::endl;
}
inline void StdOutput::failure( CmdLineInterface& _cmd,
ArgException& e )
{
std::string progName = _cmd.getProgramName();
std::cerr << "PARSE ERROR: " << e.argId() << std::endl
<< " " << e.error() << std::endl << std::endl;
std::cerr << "Brief USAGE: " << std::endl;
_shortUsage( _cmd, std::cerr );
std::cerr << std::endl << "For complete USAGE and HELP type: "
<< std::endl << " " << progName << " --help"
<< std::endl << std::endl;
}
inline void StdOutput::_shortUsage( CmdLineInterface& _cmd,
std::ostream& os ) const
{
std::list<Arg*> argList = _cmd.getArgList();
std::string progName = _cmd.getProgramName();
XorHandler xorHandler = _cmd.getXorHandler();
std::vector< std::vector<Arg*> > xorList = xorHandler.getXorList();
std::string s = progName + " ";
// first the xor
for ( int i = 0; (unsigned int)i < xorList.size(); i++ )
{
s += " {";
for ( ArgVectorIterator it = xorList[i].begin();
it != xorList[i].end(); it++ )
s += (*it)->shortID() + "|";
s[s.length()-1] = '}';
}
// then the rest
for (ArgIterator it = argList.begin(); it != argList.end(); it++)
if ( !xorHandler.contains( (*it) ) )
s += " " + (*it)->shortID();
spacePrint( std::cout, s, 75, 3, (int)(progName.length()) + 2 );
}
inline void StdOutput::_longUsage( CmdLineInterface& _cmd,
std::ostream& os ) const
{
std::list<Arg*> argList = _cmd.getArgList();
std::string message = _cmd.getMessage();
XorHandler xorHandler = _cmd.getXorHandler();
std::vector< std::vector<Arg*> > xorList = xorHandler.getXorList();
// first the xor
for ( int i = 0; (unsigned int)i < xorList.size(); i++ )
{
for ( ArgVectorIterator it = xorList[i].begin();
it != xorList[i].end();
it++ )
{
spacePrint( os, (*it)->longID(), 75, 3, 3 );
spacePrint( os, (*it)->getDescription(), 75, 5, 0 );
if ( it+1 != xorList[i].end() )
spacePrint(os, "-- OR --", 75, 9);
}
os << std::endl << std::endl;
}
// then the rest
for (ArgIterator it = argList.begin(); it != argList.end(); it++)
if ( !xorHandler.contains( (*it) ) )
{
spacePrint( os, (*it)->longID(), 75, 3, 3 );
spacePrint( os, (*it)->getDescription(), 75, 5, 0 );
os << std::endl;
}
os << std::endl;
spacePrint( os, message, 75, 3, 0 );
}
inline void StdOutput::spacePrint( std::ostream& os,
const std::string& s,
int maxWidth,
int indentSpaces,
int secondLineOffset ) const
{
int len = (int)(s.length());
if ( (len + indentSpaces > maxWidth) && maxWidth > 0 )
{
int allowedLen = maxWidth - indentSpaces;
int start = 0;
while ( start < len )
{
// find the substring length
int stringLen = std::min( len - start, allowedLen );
// trim the length so it doesn't end in middle of a word
if ( stringLen == allowedLen )
while ( s[stringLen+start] != ' ' &&
s[stringLen+start] != ',' &&
s[stringLen+start] != '|' )
stringLen--;
// check for newlines
for ( int i = 0; i < stringLen; i++ )
if ( s[start+i] == '\n' )
stringLen = i+1;
// print the indent
for ( int i = 0; i < indentSpaces; i++ )
os << " ";
if ( start == 0 )
{
// handle second line offsets
indentSpaces += secondLineOffset;
// adjust allowed len
allowedLen -= secondLineOffset;
}
os << s.substr(start,stringLen) << std::endl;
// so we don't start a line with a space
if ( s[stringLen+start] == ' ' )
start++;
start += stringLen;
}
}
else
{
for ( int i = 0; i < indentSpaces; i++ )
os << " ";
os << s << std::endl;
}
}
} //namespace TCLAP
#endif

View File

@ -24,13 +24,14 @@
#define TCLAP_VERSION_VISITOR_H
#include <tclap/CmdLineInterface.h>
#include <tclap/CmdLineOutput.h>
#include <tclap/Visitor.h>
namespace TCLAP {
/**
* A Vistor that will call the version method of the given CmdLine and
* then exit.
* A Vistor that will call the version method of the given CmdLineOutput
* for the specified CmdLine object and then exit.
*/
class VersionVisitor: public Visitor
{
@ -41,18 +42,26 @@ class VersionVisitor: public Visitor
*/
CmdLineInterface* _cmd;
/**
* The output object.
*/
CmdLineOutput* _out;
public:
/**
* Constructor.
* \param cmd - The CmdLine whose version method will be called.
* \param cmd - The CmdLine the output is generated for.
* \param out - The type of output.
*/
VersionVisitor(CmdLineInterface* cmd) : Visitor(), _cmd( cmd ) { }
VersionVisitor( CmdLineInterface* cmd, CmdLineOutput* out )
: Visitor(), _cmd( cmd ), _out( out ) { }
/**
* Prints the version to stdout.
* Calls the version method of the output object using the
* specified CmdLine.
*/
void visit() { _cmd->version(0); }
void visit() { _out->version(*_cmd); exit(0); }
};
}

View File

@ -24,7 +24,6 @@
#define TCLAP_XORHANDLER_H
#include <tclap/Arg.h>
#include <tclap/PrintSensibly.h>
#include <string>
#include <vector>
#include <algorithm>
@ -85,6 +84,8 @@ class XorHandler
*/
bool contains( const Arg* a );
std::vector< std::vector<Arg*> >& getXorList();
};
@ -96,6 +97,7 @@ inline void XorHandler::add( std::vector<Arg*>& ors )
_orList.push_back( ors );
}
/*
inline std::string XorHandler::shortUsage()
{
std::string out = "";
@ -129,7 +131,7 @@ inline void XorHandler::printLongUsage( std::ostream& os )
os << std::endl << std::endl;
}
}
*/
inline int XorHandler::check( const Arg* a )
{
// iterate over each XOR list
@ -168,6 +170,14 @@ inline bool XorHandler::contains( const Arg* a )
return false;
}
inline std::vector< std::vector<Arg*> >& XorHandler::getXorList()
{
return _orList;
}
//////////////////////////////////////////////////////////////////////
//END XOR.cpp
//////////////////////////////////////////////////////////////////////