tclap  1.2.2
StdOutput.h
Go to the documentation of this file.
1 // -*- Mode: c++; c-basic-offset: 4; tab-width: 4; -*-
2 
3 /******************************************************************************
4  *
5  * file: StdOutput.h
6  *
7  * Copyright (c) 2004, Michael E. Smoot
8  * All rights reserved.
9  *
10  * See the file COPYING in the top directory of this distribution for
11  * more information.
12  *
13  * THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
14  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
16  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
19  * DEALINGS IN THE SOFTWARE.
20  *
21  *****************************************************************************/
22 
23 #ifndef TCLAP_STDCMDLINEOUTPUT_H
24 #define TCLAP_STDCMDLINEOUTPUT_H
25 
26 #include <string>
27 #include <vector>
28 #include <list>
29 #include <iostream>
30 #include <algorithm>
31 
32 #include <tclap/CmdLineInterface.h>
33 #include <tclap/CmdLineOutput.h>
34 #include <tclap/XorHandler.h>
35 #include <tclap/Arg.h>
36 
37 namespace TCLAP {
38 
43 class StdOutput : public CmdLineOutput
44 {
45 
46  public:
47 
53  virtual void usage(CmdLineInterface& c);
54 
60  virtual void version(CmdLineInterface& c);
61 
68  virtual void failure(CmdLineInterface& c,
69  ArgException& e );
70 
71  protected:
72 
78  void _shortUsage( CmdLineInterface& c, std::ostream& os ) const;
79 
86  void _longUsage( CmdLineInterface& c, std::ostream& os ) const;
87 
99  void spacePrint( std::ostream& os,
100  const std::string& s,
101  int maxWidth,
102  int indentSpaces,
103  int secondLineOffset ) const;
104 
105 };
106 
107 
109 {
110  std::string progName = _cmd.getProgramName();
111  std::string xversion = _cmd.getVersion();
112 
113  std::cout << std::endl << progName << " version: "
114  << xversion << std::endl << std::endl;
115 }
116 
117 inline void StdOutput::usage(CmdLineInterface& _cmd )
118 {
119  std::cout << std::endl << "USAGE: " << std::endl << std::endl;
120 
121  _shortUsage( _cmd, std::cout );
122 
123  std::cout << std::endl << std::endl << "Where: " << std::endl << std::endl;
124 
125  _longUsage( _cmd, std::cout );
126 
127  std::cout << std::endl;
128 
129 }
130 
132  ArgException& e )
133 {
134  std::string progName = _cmd.getProgramName();
135 
136  std::cerr << "PARSE ERROR: " << e.argId() << std::endl
137  << " " << e.error() << std::endl << std::endl;
138 
139  if ( _cmd.hasHelpAndVersion() )
140  {
141  std::cerr << "Brief USAGE: " << std::endl;
142 
143  _shortUsage( _cmd, std::cerr );
144 
145  std::cerr << std::endl << "For complete USAGE and HELP type: "
146  << std::endl << " " << progName << " "
147  << Arg::nameStartString() << "help"
148  << std::endl << std::endl;
149  }
150  else
151  usage(_cmd);
152 
153  throw ExitException(1);
154 }
155 
156 inline void
158  std::ostream& os ) const
159 {
160  std::list<Arg*> argList = _cmd.getArgList();
161  std::string progName = _cmd.getProgramName();
162  XorHandler xorHandler = _cmd.getXorHandler();
163  std::vector< std::vector<Arg*> > xorList = xorHandler.getXorList();
164 
165  std::string s = progName + " ";
166 
167  // first the xor
168  for ( int i = 0; static_cast<unsigned int>(i) < xorList.size(); i++ )
169  {
170  s += " {";
171  for ( ArgVectorIterator it = xorList[i].begin();
172  it != xorList[i].end(); it++ )
173  s += (*it)->shortID() + "|";
174 
175  s[s.length()-1] = '}';
176  }
177 
178  // then the rest
179  for (ArgListIterator it = argList.begin(); it != argList.end(); it++)
180  if ( !xorHandler.contains( (*it) ) )
181  s += " " + (*it)->shortID();
182 
183  // if the program name is too long, then adjust the second line offset
184  int secondLineOffset = static_cast<int>(progName.length()) + 2;
185  if ( secondLineOffset > 75/2 )
186  secondLineOffset = static_cast<int>(75/2);
187 
188  spacePrint( os, s, 75, 3, secondLineOffset );
189 }
190 
191 inline void
193  std::ostream& os ) const
194 {
195  std::list<Arg*> argList = _cmd.getArgList();
196  std::string message = _cmd.getMessage();
197  XorHandler xorHandler = _cmd.getXorHandler();
198  std::vector< std::vector<Arg*> > xorList = xorHandler.getXorList();
199 
200  // first the xor
201  for ( int i = 0; static_cast<unsigned int>(i) < xorList.size(); i++ )
202  {
203  for ( ArgVectorIterator it = xorList[i].begin();
204  it != xorList[i].end();
205  it++ )
206  {
207  spacePrint( os, (*it)->longID(), 75, 3, 3 );
208  spacePrint( os, (*it)->getDescription(), 75, 5, 0 );
209 
210  if ( it+1 != xorList[i].end() )
211  spacePrint(os, "-- OR --", 75, 9, 0);
212  }
213  os << std::endl << std::endl;
214  }
215 
216  // then the rest
217  for (ArgListIterator it = argList.begin(); it != argList.end(); it++)
218  if ( !xorHandler.contains( (*it) ) )
219  {
220  spacePrint( os, (*it)->longID(), 75, 3, 3 );
221  spacePrint( os, (*it)->getDescription(), 75, 5, 0 );
222  os << std::endl;
223  }
224 
225  os << std::endl;
226 
227  spacePrint( os, message, 75, 3, 0 );
228 }
229 
230 inline void StdOutput::spacePrint( std::ostream& os,
231  const std::string& s,
232  int maxWidth,
233  int indentSpaces,
234  int secondLineOffset ) const
235 {
236  int len = static_cast<int>(s.length());
237 
238  if ( (len + indentSpaces > maxWidth) && maxWidth > 0 )
239  {
240  int allowedLen = maxWidth - indentSpaces;
241  int start = 0;
242  while ( start < len )
243  {
244  // find the substring length
245  // int stringLen = std::min<int>( len - start, allowedLen );
246  // doing it this way to support a VisualC++ 2005 bug
247  using namespace std;
248  int stringLen = min<int>( len - start, allowedLen );
249 
250  // trim the length so it doesn't end in middle of a word
251  if ( stringLen == allowedLen )
252  while ( stringLen >= 0 &&
253  s[stringLen+start] != ' ' &&
254  s[stringLen+start] != ',' &&
255  s[stringLen+start] != '|' )
256  stringLen--;
257 
258  // ok, the word is longer than the line, so just split
259  // wherever the line ends
260  if ( stringLen <= 0 )
261  stringLen = allowedLen;
262 
263  // check for newlines
264  for ( int i = 0; i < stringLen; i++ )
265  if ( s[start+i] == '\n' )
266  stringLen = i+1;
267 
268  // print the indent
269  for ( int i = 0; i < indentSpaces; i++ )
270  os << " ";
271 
272  if ( start == 0 )
273  {
274  // handle second line offsets
275  indentSpaces += secondLineOffset;
276 
277  // adjust allowed len
278  allowedLen -= secondLineOffset;
279  }
280 
281  os << s.substr(start,stringLen) << std::endl;
282 
283  // so we don't start a line with a space
284  while ( s[stringLen+start] == ' ' && start < len )
285  start++;
286 
287  start += stringLen;
288  }
289  }
290  else
291  {
292  for ( int i = 0; i < indentSpaces; i++ )
293  os << " ";
294  os << s << std::endl;
295  }
296 }
297 
298 } //namespace TCLAP
299 #endif
virtual bool hasHelpAndVersion()=0
Indicates whether or not the help and version switches were created automatically.
std::vector< std::vector< Arg * > > & getXorList()
Definition: XorHandler.h:153
A simple class that defines and argument exception.
Definition: ArgException.h:36
virtual std::string & getProgramName()=0
Returns the program name string.
std::string argId() const
Returns the argument id.
Definition: ArgException.h:69
virtual void usage(CmdLineInterface &c)
Prints the usage to stdout.
Definition: StdOutput.h:117
virtual std::list< Arg * > & getArgList()=0
Returns the argList.
virtual void version(CmdLineInterface &c)
Prints the version to stdout.
Definition: StdOutput.h:108
void _longUsage(CmdLineInterface &c, std::ostream &os) const
Writes a longer usage message with long and short args, provides descriptions and prints message.
Definition: StdOutput.h:192
virtual std::string & getVersion()=0
Returns the version string.
virtual XorHandler & getXorHandler()=0
Returns the XorHandler.
static const std::string nameStartString()
Definition: Arg.h:246
std::list< Arg * >::iterator ArgListIterator
Typedef of an Arg list iterator.
Definition: Arg.h:397
The base class that manages the command line definition and passes along the parsing to the appropria...
bool contains(const Arg *a)
Simply checks whether the Arg is contained in one of the arg lists.
Definition: XorHandler.h:141
std::vector< Arg * >::iterator ArgVectorIterator
Typedef of an Arg vector iterator.
Definition: Arg.h:402
A class that isolates any output from the CmdLine object so that it may be easily modified.
Definition: StdOutput.h:43
virtual std::string & getMessage()=0
Returns the message string.
void _shortUsage(CmdLineInterface &c, std::ostream &os) const
Writes a brief usage message with short args.
Definition: StdOutput.h:157
void spacePrint(std::ostream &os, const std::string &s, int maxWidth, int indentSpaces, int secondLineOffset) const
This function inserts line breaks and indents long strings according the params input.
Definition: StdOutput.h:230
Definition: Arg.h:58
virtual void failure(CmdLineInterface &c, ArgException &e)
Prints (to stderr) an error message, short usage Can be overridden to produce alternative behavior.
Definition: StdOutput.h:131
std::string error() const
Returns the error text.
Definition: ArgException.h:64
This class handles lists of Arg's that are to be XOR'd on the command line.
Definition: XorHandler.h:38
The interface that any output object must implement.
Definition: CmdLineOutput.h:41