diff --git a/src/CmdLine.cpp b/src/CmdLine.cpp index 030889a..607b6da 100644 --- a/src/CmdLine.cpp +++ b/src/CmdLine.cpp @@ -113,27 +113,45 @@ void CmdLine::version(int exitVal) exit( exitVal ); } +void CmdLine::_shortUsage( ostream& os ) +{ + 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, _progName.length() + 2 ); +} + +void CmdLine::_longUsage( 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 << endl; + } + + os << endl; + spacePrint( os, _message, 75, 3, 0 ); +} void CmdLine::usage( int exitVal ) { - cout << endl << "USAGE: " << endl << endl << " " << _progName ; + cout << endl << "USAGE: " << endl << endl; - _xorHandler.shortUsage(); - - for (ArgIterator it = _argList.begin(); it != _argList.end(); it++) - if ( !_xorHandler.contains( (*it) ) ) - cout << " " << (*it)->shortID(); + _shortUsage( cout ); cout << endl << endl << "Where: " << endl << endl; - _xorHandler.longUsage(); + _longUsage( cout ); - for (ArgIterator it = _argList.begin(); it != _argList.end(); it++) - if ( !_xorHandler.contains( (*it) ) ) - cout << " " << (*it)->longID() << endl << " " - << (*it)->getDescription() << endl << endl; + cout << endl; - cout << endl << endl << _message << endl << endl; exit( exitVal ); } @@ -183,7 +201,14 @@ void CmdLine::parse(int argc, char** argv) cerr << "PARSE ERROR: " << e.argId() << endl << " " << e.error() << endl << endl; - usage(1); + cerr << "Brief USAGE: " << endl; + + _shortUsage( cerr ); + + cerr << endl << "For complete USAGE and HELP type: " + << endl << " " << _progName << " --help" << endl << endl; + + exit(1); } } diff --git a/src/Makefile.am b/src/Makefile.am index 80e7e0f..aa137e1 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,7 +1,11 @@ lib_LIBRARIES = libtclap.a -libtclap_a_SOURCES = Arg.cpp CmdLine.cpp SwitchArg.cpp XorHandler.cpp +libtclap_a_SOURCES = Arg.cpp \ + CmdLine.cpp \ + SwitchArg.cpp \ + XorHandler.cpp \ + PrintSensibly.cpp INCLUDES = -I$(top_srcdir)/include diff --git a/src/PrintSensibly.cpp b/src/PrintSensibly.cpp new file mode 100644 index 0000000..c9e35b2 --- /dev/null +++ b/src/PrintSensibly.cpp @@ -0,0 +1,76 @@ + +/****************************************************************************** + * + * file: PrintSensibly.cpp + * + * 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. + * + *****************************************************************************/ + + +#include + +namespace TCLAP { + + +void spacePrint( ostream& os, + const string& s, + int maxWidth, + int indentSpaces, + int secondLineOffset ) +{ + if ( (s.length() + indentSpaces > (unsigned int) maxWidth) && + maxWidth > 0 ) + { + int allowedLen = maxWidth - indentSpaces; + int start = 0; + while ( (unsigned int)start < s.length() ) + { + // find the substring length + int stringLen = min( s.length() - start, (unsigned int)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--; + + // print the indent + for ( int i = 0; i < indentSpaces; i++ ) + os << " "; + + // handle second line offsets + if ( start == 0 ) + indentSpaces += secondLineOffset; + + os << s.substr(start,stringLen) << 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 << endl; + } +} + +} diff --git a/src/XorHandler.cpp b/src/XorHandler.cpp index e7cc11e..b72dd6e 100644 --- a/src/XorHandler.cpp +++ b/src/XorHandler.cpp @@ -32,7 +32,7 @@ void XorHandler::add( vector& ors ) _orList.push_back( ors ); } -void XorHandler::shortUsage() +string XorHandler::shortUsage() { string out = ""; for ( int i = 0; (unsigned int)i < _orList.size(); i++ ) @@ -45,10 +45,10 @@ void XorHandler::shortUsage() out[out.length()-1] = '}'; } - cout << out; + return out; } -void XorHandler::longUsage() +void XorHandler::printLongUsage( ostream& os ) { for ( int i = 0; (unsigned int)i < _orList.size(); i++ ) { @@ -56,13 +56,13 @@ void XorHandler::longUsage() it != _orList[i].end(); it++ ) { - cout << " " << (*it)->longID() << endl - << " " << (*it)->getDescription() << endl; + spacePrint( os, (*it)->longID(), 75, 3, 3 ); + spacePrint( os, (*it)->getDescription(), 75, 5, 0 ); if ( it+1 != _orList[i].end() ) - cout << " -- OR -- " << endl; + spacePrint(os, "-- OR --", 75, 9); } - cout << endl << endl; + os << endl << endl; } }