Main MRPT website > C++ reference
MRPT logo
StdOutput.h
Go to the documentation of this file.
1 
2 /******************************************************************************
3  *
4  * file: StdOutput.h
5  *
6  * Copyright (c) 2004, Michael E. Smoot
7  * All rights reverved.
8  *
9  * See the file COPYING in the top directory of this distribution for
10  * more information.
11  *
12  * THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
13  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
15  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
17  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
18  * DEALINGS IN THE SOFTWARE.
19  *
20  *****************************************************************************/
21 
22 #ifndef TCLAP_STDCMDLINEOUTPUT_H
23 #define TCLAP_STDCMDLINEOUTPUT_H
24 
25 #include <string>
26 #include <vector>
27 #include <list>
28 #include <iostream>
29 #include <algorithm>
30 
35 
36 namespace TCLAP {
37 
38 /**
39  * A class that isolates any output from the CmdLine object so that it
40  * may be easily modified.
41  */
42 class StdOutput : public CmdLineOutput
43 {
44  protected:
45  std::ostream &m_my_output; //!< By JLBC for MRPT
46 
47  public:
48  /**
49  * Prints the usage to stdout. Can be overridden to
50  * produce alternative behavior.
51  * \param c - The CmdLine object the output is generated for.
52  */
53  StdOutput( std::ostream &desired_out = std::cout ) :
54  m_my_output(desired_out)
55  {
56  }
57 
58  /**
59  * Prints the usage to stdout. Can be overridden to
60  * produce alternative behavior.
61  * \param c - The CmdLine object the output is generated for.
62  */
63  virtual void usage(CmdLineInterface& c);
64 
65  /**
66  * Prints the version to stdout. Can be overridden
67  * to produce alternative behavior.
68  * \param c - The CmdLine object the output is generated for.
69  */
70  virtual void version(CmdLineInterface& c);
71 
72  /**
73  * Prints (to stderr) an error message, short usage
74  * Can be overridden to produce alternative behavior.
75  * \param c - The CmdLine object the output is generated for.
76  * \param e - The ArgException that caused the failure.
77  */
78  virtual void failure(CmdLineInterface& c,
79  ArgException& e );
80 
81  protected:
82 
83  /**
84  * Writes a brief usage message with short args.
85  * \param c - The CmdLine object the output is generated for.
86  * \param os - The stream to write the message to.
87  */
88  void _shortUsage( CmdLineInterface& c, std::ostream& os ) const;
89 
90  /**
91  * Writes a longer usage message with long and short args,
92  * provides descriptions and prints message.
93  * \param c - The CmdLine object the output is generated for.
94  * \param os - The stream to write the message to.
95  */
96  void _longUsage( CmdLineInterface& c, std::ostream& os ) const;
97 
98  /**
99  * This function inserts line breaks and indents long strings
100  * according the params input. It will only break lines at spaces,
101  * commas and pipes.
102  * \param os - The stream to be printed to.
103  * \param s - The string to be printed.
104  * \param maxWidth - The maxWidth allowed for the output line.
105  * \param indentSpaces - The number of spaces to indent the first line.
106  * \param secondLineOffset - The number of spaces to indent the second
107  * and all subsequent lines in addition to indentSpaces.
108  */
109  void spacePrint( std::ostream& os,
110  const std::string& s,
111  int maxWidth,
112  int indentSpaces,
113  int secondLineOffset ) const;
114 
115 };
116 
117 
119 {
120  std::string progName = _cmd.getProgramName();
121  std::string version = _cmd.getVersion();
122 
123  m_my_output << std::endl << progName << " version: "
124  << version << std::endl << std::endl;
125 }
126 
127 inline void StdOutput::usage(CmdLineInterface& _cmd )
128 {
129  m_my_output << std::endl << "USAGE: " << std::endl << std::endl;
130 
131  _shortUsage( _cmd, m_my_output );
132 
133  m_my_output << std::endl << std::endl << "Where: " << std::endl << std::endl;
134 
135  _longUsage( _cmd, m_my_output );
136 
137  m_my_output << std::endl;
138 
139 }
140 
142  ArgException& e )
143 {
144  std::string progName = _cmd.getProgramName();
145 
146  std::cerr << "PARSE ERROR: " << e.argId() << std::endl
147  << " " << e.error() << std::endl << std::endl;
148 
149  if ( _cmd.hasHelpAndVersion() )
150  {
151  std::cerr << "Brief USAGE: " << std::endl;
152 
153  _shortUsage( _cmd, std::cerr );
154 
155  std::cerr << std::endl << "For complete USAGE and HELP type: "
156  << std::endl << " " << progName << " --help"
157  << std::endl << std::endl;
158  }
159  else
160  usage(_cmd);
161 
162 }
163 
165  std::ostream& os ) const
166 {
167  std::list<Arg*> argList = _cmd.getArgList();
168  std::string progName = _cmd.getProgramName();
169  XorHandler xorHandler = _cmd.getXorHandler();
170  std::vector< std::vector<Arg*> > xorList = xorHandler.getXorList();
171 
172  std::string s = progName + " ";
173 
174  // first the xor
175  for ( int i = 0; static_cast<unsigned int>(i) < xorList.size(); i++ )
176  {
177  s += " {";
178  for ( ArgVectorIterator it = xorList[i].begin();
179  it != xorList[i].end(); it++ )
180  s += (*it)->shortID() + "|";
181 
182  s[s.length()-1] = '}';
183  }
184 
185  // then the rest
186  for (ArgListIterator it = argList.begin(); it != argList.end(); it++)
187  if ( !xorHandler.contains( (*it) ) )
188  s += " " + (*it)->shortID();
189 
190  // if the program name is too long, then adjust the second line offset
191  int secondLineOffset = static_cast<int>(progName.length()) + 2;
192  if ( secondLineOffset > 75/2 )
193  secondLineOffset = static_cast<int>(75/2);
194 
195  spacePrint( m_my_output, s, 75, 3, secondLineOffset );
196 }
197 
199  std::ostream& os ) const
200 {
201  std::list<Arg*> argList = _cmd.getArgList();
202  std::string message = _cmd.getMessage();
203  XorHandler xorHandler = _cmd.getXorHandler();
204  std::vector< std::vector<Arg*> > xorList = xorHandler.getXorList();
205 
206  // first the xor
207  for ( int i = 0; static_cast<unsigned int>(i) < xorList.size(); i++ )
208  {
209  for ( ArgVectorIterator it = xorList[i].begin();
210  it != xorList[i].end();
211  it++ )
212  {
213  spacePrint( os, (*it)->longID(), 75, 3, 3 );
214  spacePrint( os, (*it)->getDescription(), 75, 5, 0 );
215 
216  if ( it+1 != xorList[i].end() )
217  spacePrint(os, "-- OR --", 75, 9, 0);
218  }
219  os << std::endl << std::endl;
220  }
221 
222  // then the rest
223  for (ArgListIterator it = argList.begin(); it != argList.end(); it++)
224  if ( !xorHandler.contains( (*it) ) )
225  {
226  spacePrint( os, (*it)->longID(), 75, 3, 3 );
227  spacePrint( os, (*it)->getDescription(), 75, 5, 0 );
228  os << std::endl;
229  }
230 
231  os << std::endl;
232 
233  spacePrint( os, message, 75, 3, 0 );
234 }
235 
236 inline void StdOutput::spacePrint( std::ostream& os,
237  const std::string& s,
238  int maxWidth,
239  int indentSpaces,
240  int secondLineOffset ) const
241 {
242  int len = static_cast<int>(s.length());
243 
244  if ( (len + indentSpaces > maxWidth) && maxWidth > 0 )
245  {
246  int allowedLen = maxWidth - indentSpaces;
247  int start = 0;
248  while ( start < len )
249  {
250  // find the substring length
251  int stringLen = std::min( len - start, allowedLen );
252 
253  // trim the length so it doesn't end in middle of a word
254  if ( stringLen == allowedLen )
255  while ( s[stringLen+start] != ' ' &&
256  s[stringLen+start] != ',' &&
257  s[stringLen+start] != '|' &&
258  stringLen >= 0 )
259  stringLen--;
260 
261  // ok, the word is longer than the line, so just split
262  // wherever the line ends
263  if ( stringLen <= 0 )
264  stringLen = allowedLen;
265 
266  // check for newlines
267  for ( int i = 0; i < stringLen; i++ )
268  if ( s[start+i] == '\n' )
269  stringLen = i+1;
270 
271  // print the indent
272  for ( int i = 0; i < indentSpaces; i++ )
273  os << " ";
274 
275  if ( start == 0 )
276  {
277  // handle second line offsets
278  indentSpaces += secondLineOffset;
279 
280  // adjust allowed len
281  allowedLen -= secondLineOffset;
282  }
283 
284  os << s.substr(start,stringLen) << std::endl;
285 
286  // so we don't start a line with a space
287  while ( s[stringLen+start] == ' ' && start < len )
288  start++;
289 
290  start += stringLen;
291  }
292  }
293  else
294  {
295  for ( int i = 0; i < indentSpaces; i++ )
296  os << " ";
297  os << s << std::endl;
298  }
299 }
300 
301 } //namespace TCLAP
302 #endif



Page generated by Doxygen 1.8.3 for MRPT 0.9.6 SVN: at Fri Feb 15 22:05:02 EST 2013