threed-beam-fea/ext/tclap-1.2.1/include/tclap/StdOutput.h

283 lines
9.7 KiB
C++

// -*- Mode: c++; c-basic-offset: 4; tab-width: 4; -*-
/******************************************************************************
*
* 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,
int secondLineOffset) const;
};
inline void StdOutput::version(CmdLineInterface &_cmd) {
std::string progName = _cmd.getProgramName();
std::string xversion = _cmd.getVersion();
std::cout << std::endl << progName << " version: "
<< xversion << 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;
if (_cmd.hasHelpAndVersion()) {
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;
}
else
usage(_cmd);
throw ExitException(1);
}
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; static_cast<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 (ArgListIterator it = argList.begin(); it != argList.end(); it++)
if (!xorHandler.contains((*it)))
s += " " + (*it)->shortID();
// if the program name is too long, then adjust the second line offset
int secondLineOffset = static_cast<int>(progName.length()) + 2;
if (secondLineOffset > 75 / 2)
secondLineOffset = static_cast<int>(75 / 2);
spacePrint(os, s, 75, 3, secondLineOffset);
}
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; static_cast<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, 0);
}
os << std::endl << std::endl;
}
// then the rest
for (ArgListIterator 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 = static_cast<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<int>( len - start, allowedLen );
// doing it this way to support a VisualC++ 2005 bug
using namespace std;
int stringLen = min<int>(len - start, allowedLen);
// trim the length so it doesn't end in middle of a word
if (stringLen == allowedLen)
while (stringLen >= 0 &&
s[stringLen + start] != ' ' &&
s[stringLen + start] != ',' &&
s[stringLen + start] != '|')
stringLen--;
// ok, the word is longer than the line, so just split
// wherever the line ends
if (stringLen <= 0)
stringLen = allowedLen;
// 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
while (s[stringLen + start] == ' ' && start < len)
start++;
start += stringLen;
}
}
else {
for (int i = 0; i < indentSpaces; i++)
os << " ";
os << s << std::endl;
}
}
} //namespace TCLAP
#endif