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