tclap 1.2.6
DocBookOutput.h
Go to the documentation of this file.
1// -*- Mode: c++; c-basic-offset: 4; tab-width: 4; -*-
2
3/******************************************************************************
4 *
5 * file: DocBookOutput.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_DOCBOOKOUTPUT_H
25#define TCLAP_DOCBOOKOUTPUT_H
26
27#include <string>
28#include <vector>
29#include <list>
30#include <iostream>
31#include <algorithm>
32
34#include <tclap/CmdLineOutput.h>
35#include <tclap/XorHandler.h>
36#include <tclap/Arg.h>
37
38namespace TCLAP {
39
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
73 protected:
74 // Escape raw data once, at the XML output boundary (text and attributes).
75 static std::string escapeXml(const std::string &text) {
76 std::string result;
77 for (std::string::const_iterator it = text.begin(); it != text.end(); ++it) {
78 switch (*it) {
79 case '&': result += "&amp;"; break;
80 case '<': result += "&lt;"; break;
81 case '>': result += "&gt;"; break;
82 case '\"': result += "&quot;"; break;
83 case '\'': result += "&apos;"; break;
84 default: result += *it; break;
85 }
86 }
87 return result;
88 }
89
90 static std::string valueLabel(const Arg &arg) {
91 const std::string id = arg.shortID();
92 const std::string label = arg.getFlag().empty()
93 ? arg.nameStartString() + arg.getName()
94 : arg.flagStartString() + arg.getFlag();
95 const std::string::size_type labelStart = id.find(label);
96 if (labelStart != std::string::npos) {
97 const std::string::size_type open = labelStart + label.size() + 1;
98 const std::string::size_type close = id.rfind('>');
99 if (open < id.size() && id[open] == '<' &&
100 close != std::string::npos && close > open)
101 return id.substr(open + 1, close - open - 1);
102 }
103 return id; // Custom IDs without the usual value wrapper.
104 }
105
106
113 void substituteSpecialChars( std::string& s, char r, std::string& x );
114 void removeChar( std::string& s, char r);
115 void basename( std::string& s );
116
117 void printShortArg(Arg* it);
118 void printLongArg(Arg* it);
119
121};
122
123
125{
126 std::cout << _cmd.getVersion() << std::endl;
127}
128
130{
131 std::list<Arg*> argList = _cmd.getArgList();
132 std::string progName = _cmd.getProgramName();
133 std::string xversion = _cmd.getVersion();
134 theDelimiter = _cmd.getDelimiter();
135 XorHandler xorHandler = _cmd.getXorHandler();
136 const std::vector< std::vector<Arg*> > xorList = xorHandler.getXorList();
137 basename(progName);
138
139 std::cout << "<?xml version='1.0'?>" << std::endl;
140 std::cout << "<!DOCTYPE refentry PUBLIC \"-//OASIS//DTD DocBook XML V4.2//EN\"" << std::endl;
141 std::cout << "\t\"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd\">" << std::endl << std::endl;
142
143 std::cout << "<refentry>" << std::endl;
144
145 std::cout << "<refmeta>" << std::endl;
146 std::cout << "<refentrytitle>" << escapeXml(progName) << "</refentrytitle>" << std::endl;
147 std::cout << "<manvolnum>1</manvolnum>" << std::endl;
148 std::cout << "</refmeta>" << std::endl;
149
150 std::cout << "<refnamediv>" << std::endl;
151 std::cout << "<refname>" << escapeXml(progName) << "</refname>" << std::endl;
152 std::cout << "<refpurpose>" << escapeXml(_cmd.getMessage()) << "</refpurpose>" << std::endl;
153 std::cout << "</refnamediv>" << std::endl;
154
155 std::cout << "<refsynopsisdiv>" << std::endl;
156 std::cout << "<cmdsynopsis>" << std::endl;
157
158 std::cout << "<command>" << escapeXml(progName) << "</command>" << std::endl;
159
160 // Labeled XOR groups retain their grouping; groups with operands follow
161 // the parser's positional order rather than being moved before operands.
162 for (unsigned int i = 0; i < xorList.size(); ++i) {
163 bool hasOperand = false;
164 for (ArgVectorIterator it = xorList[i].begin(); it != xorList[i].end(); ++it)
165 if (!(*it)->hasLabel()) hasOperand = true;
166 if (hasOperand) continue;
167 std::cout << "<group choice='req'>" << std::endl;
168 for (ArgVectorIterator it = xorList[i].begin(); it != xorList[i].end(); ++it)
169 printShortArg(*it);
170 std::cout << "</group>" << std::endl;
171 }
172 for (ArgListIterator it = argList.begin(); it != argList.end(); ++it)
173 if ((*it)->hasLabel() && !xorHandler.contains(*it)) printShortArg(*it);
174 std::vector<bool> shown(xorList.size(), false);
175 for (ArgListIterator it = argList.begin(); it != argList.end(); ++it) {
176 Arg *arg = *it;
177 if (arg->hasLabel()) continue;
178 unsigned int owner = 0;
179 for (; owner < xorList.size(); ++owner)
180 if (std::find(xorList[owner].begin(), xorList[owner].end(), arg) !=
181 xorList[owner].end()) break;
182 if (owner == xorList.size()) {
183 printShortArg(arg);
184 } else if (!shown[owner]) {
185 std::cout << "<group choice='req'>" << std::endl;
186 for (ArgVectorIterator member = xorList[owner].begin();
187 member != xorList[owner].end(); ++member) printShortArg(*member);
188 std::cout << "</group>" << std::endl;
189 shown[owner] = true;
190 }
191 }
192
193 std::cout << "</cmdsynopsis>" << std::endl;
194 std::cout << "</refsynopsisdiv>" << std::endl;
195
196 std::cout << "<refsect1>" << std::endl;
197 std::cout << "<title>Description</title>" << std::endl;
198 std::cout << "<para>" << std::endl;
199 std::cout << escapeXml(_cmd.getMessage()) << std::endl;
200 std::cout << "</para>" << std::endl;
201 std::cout << "</refsect1>" << std::endl;
202
203 std::cout << "<refsect1>" << std::endl;
204 std::cout << "<title>Options</title>" << std::endl;
205
206 std::cout << "<variablelist>" << std::endl;
207
208 for (ArgListIterator it = argList.begin(); it != argList.end(); it++)
209 printLongArg((*it));
210
211 std::cout << "</variablelist>" << std::endl;
212 std::cout << "</refsect1>" << std::endl;
213
214 std::cout << "<refsect1>" << std::endl;
215 std::cout << "<title>Version</title>" << std::endl;
216 std::cout << "<para>" << std::endl;
217 std::cout << escapeXml(xversion) << std::endl;
218 std::cout << "</para>" << std::endl;
219 std::cout << "</refsect1>" << std::endl;
220
221 std::cout << "</refentry>" << std::endl;
222
223}
224
226 ArgException& e )
227{
228 static_cast<void>(_cmd); // unused
229 std::cout << e.what() << std::endl;
230 throw ExitException(1);
231}
232
233inline void DocBookOutput::substituteSpecialChars( std::string& s,
234 char r,
235 std::string& x )
236{
237 size_t p;
238 while ( (p = s.find_first_of(r)) != std::string::npos )
239 {
240 s.erase(p,1);
241 s.insert(p,x);
242 }
243}
244
245inline void DocBookOutput::removeChar( std::string& s, char r)
246{
247 size_t p;
248 while ( (p = s.find_first_of(r)) != std::string::npos )
249 {
250 s.erase(p,1);
251 }
252}
253
254inline void DocBookOutput::basename( std::string& s )
255{
256 size_t p = s.find_last_of('/');
257 if ( p != std::string::npos )
258 {
259 s.erase(0, p + 1);
260 }
261}
262
264{
265
266
267 std::string choice = "opt";
268 if ( a->isRequired() )
269 choice = "plain";
270
271 std::cout << "<arg choice='" << choice << '\'';
272 if ( a->acceptsMultipleValues() )
273 std::cout << " rep='repeat'";
274
275
276 std::cout << '>';
277 if (!a->hasLabel()) {
278 std::cout << "<replaceable>" << escapeXml(a->getName())
279 << "</replaceable></arg>" << std::endl;
280 return;
281 }
282
283 if ( !a->getFlag().empty() )
284 std::cout << escapeXml(std::string(1, a->flagStartChar()) + a->getFlag());
285 else
286 std::cout << escapeXml(a->nameStartString() + a->getName());
287 if ( a->isValueRequired() )
288 {
289 std::string arg = valueLabel(*a);
290 std::cout << escapeXml(std::string(1, theDelimiter));
291 std::cout << "<replaceable>" << escapeXml(arg) << "</replaceable>";
292 }
293 std::cout << "</arg>" << std::endl;
294
295}
296
298{
299
300
301 std::string desc = a->getDescription();
302
303
304 std::cout << "<varlistentry>" << std::endl;
305 if (!a->hasLabel()) {
306 std::cout << "<term><replaceable>" << escapeXml(a->getName())
307 << "</replaceable></term>\n<listitem><para>"
308 << escapeXml(desc) << "</para></listitem>\n</varlistentry>"
309 << std::endl;
310 return;
311 }
312
313 if ( !a->getFlag().empty() )
314 {
315 std::cout << "<term>" << std::endl;
316 std::cout << "<option>";
317 std::cout << escapeXml(std::string(1, a->flagStartChar()) + a->getFlag());
318 std::cout << "</option>" << std::endl;
319 std::cout << "</term>" << std::endl;
320 }
321
322 std::cout << "<term>" << std::endl;
323 std::cout << "<option>";
324 std::cout << escapeXml(a->nameStartString() + a->getName());
325 if ( a->isValueRequired() )
326 {
327 std::string arg = valueLabel(*a);
328 std::cout << escapeXml(std::string(1, theDelimiter));
329 std::cout << "<replaceable>" << escapeXml(arg) << "</replaceable>";
330 }
331 std::cout << "</option>" << std::endl;
332 std::cout << "</term>" << std::endl;
333
334 std::cout << "<listitem>" << std::endl;
335 std::cout << "<para>" << std::endl;
336 std::cout << escapeXml(desc) << std::endl;
337 std::cout << "</para>" << std::endl;
338 std::cout << "</listitem>" << std::endl;
339
340 std::cout << "</varlistentry>" << std::endl;
341}
342
343} //namespace TCLAP
344#endif
A simple class that defines and argument exception.
const char * what() const
Returns the arg id and error text.
A virtual base class that defines the essential data for all arguments.
Definition Arg.h:56
static const std::string nameStartString()
Definition Arg.h:239
const std::string & getFlag() const
Returns the argument flag.
Definition Arg.h:564
bool isValueRequired() const
Indicates whether a value must be specified for argument.
Definition Arg.h:570
static char flagStartChar()
Definition Arg.h:220
const std::string & getName() const
Returns the argument name.
Definition Arg.h:566
std::string getDescription() const
Returns the argument description.
Definition Arg.h:551
virtual bool acceptsMultipleValues()
Use by output classes to determine whether an Arg accepts multiple values.
Definition Arg.h:671
virtual bool hasLabel() const
Whether this argument has an option label rather than being an operand.
Definition Arg.h:279
virtual bool isRequired() const
Indicates whether the argument is required.
Definition Arg.h:568
virtual std::string shortID(const std::string &valueId="val") const
Returns a short ID for the usage.
Definition Arg.h:502
static const std::string flagStartString()
Definition Arg.h:230
The base class that manages the command line definition and passes along the parsing to the appropria...
virtual XorHandler & getXorHandler()=0
Returns the XorHandler.
virtual std::list< Arg * > & getArgList()=0
Returns the argList.
virtual std::string & getProgramName()=0
Returns the program name string.
virtual char getDelimiter()=0
Returns the delimiter string.
virtual std::string & getVersion()=0
Returns the version string.
virtual std::string & getMessage()=0
Returns the message string.
The interface that any output object must implement.
A class that generates DocBook output for usage() method for the given CmdLine and its Args.
static std::string valueLabel(const Arg &arg)
virtual void version(CmdLineInterface &c)
Prints the version to stdout.
static std::string escapeXml(const std::string &text)
virtual void failure(CmdLineInterface &c, ArgException &e)
Prints (to stderr) an error message, short usage Can be overridden to produce alternative behavior.
void substituteSpecialChars(std::string &s, char r, std::string &x)
Substitutes the char r for string x in string s.
void basename(std::string &s)
void printLongArg(Arg *it)
void printShortArg(Arg *it)
void removeChar(std::string &s, char r)
virtual void usage(CmdLineInterface &c)
Prints the usage to stdout.
Thrown when TCLAP thinks the program should exit.
This class handles lists of Arg's that are to be XOR'd on the command line.
Definition XorHandler.h:41
bool contains(const Arg *a)
Simply checks whether the Arg is contained in one of the arg lists.
Definition XorHandler.h:143
const std::vector< std::vector< Arg * > > & getXorList() const
Definition XorHandler.h:155
Definition Arg.h:48
std::vector< Arg * >::const_iterator ArgVectorIterator
Typedef of an Arg vector iterator.
Definition Arg.h:398
std::list< Arg * >::const_iterator ArgListIterator
Typedef of an Arg list iterator.
Definition Arg.h:393