DocBookOutput.h 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. // -*- Mode: c++; c-basic-offset: 4; tab-width: 4; -*-
  2. /******************************************************************************
  3. *
  4. * file: DocBookOutput.h
  5. *
  6. * Copyright (c) 2004, Michael E. Smoot
  7. * Copyright (c) 2017, Google LLC
  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. #ifndef TCLAP_DOCBOOKOUTPUT_H
  23. #define TCLAP_DOCBOOKOUTPUT_H
  24. #include <string>
  25. #include <vector>
  26. #include <list>
  27. #include <iostream>
  28. #include <algorithm>
  29. #include <tclap/CmdLineInterface.h>
  30. #include <tclap/CmdLineOutput.h>
  31. #include <tclap/XorHandler.h>
  32. #include <tclap/Arg.h>
  33. namespace TCLAP {
  34. /**
  35. * A class that generates DocBook output for usage() method for the
  36. * given CmdLine and its Args.
  37. */
  38. class DocBookOutput : public CmdLineOutput
  39. {
  40. public:
  41. /**
  42. * Prints the usage to stdout. Can be overridden to
  43. * produce alternative behavior.
  44. * \param c - The CmdLine object the output is generated for.
  45. */
  46. virtual void usage(CmdLineInterface& c);
  47. /**
  48. * Prints the version to stdout. Can be overridden
  49. * to produce alternative behavior.
  50. * \param c - The CmdLine object the output is generated for.
  51. */
  52. virtual void version(CmdLineInterface& c);
  53. /**
  54. * Prints (to stderr) an error message, short usage
  55. * Can be overridden to produce alternative behavior.
  56. * \param c - The CmdLine object the output is generated for.
  57. * \param e - The ArgException that caused the failure.
  58. */
  59. virtual void failure(CmdLineInterface& c,
  60. ArgException& e );
  61. DocBookOutput() : theDelimiter('=') {}
  62. protected:
  63. /**
  64. * Substitutes the char r for string x in string s.
  65. * \param s - The string to operate on.
  66. * \param r - The char to replace.
  67. * \param x - What to replace r with.
  68. */
  69. void substituteSpecialChars( std::string& s, char r, std::string& x );
  70. void removeChar( std::string& s, char r);
  71. void basename( std::string& s );
  72. void printShortArg(Arg* it);
  73. void printLongArg(Arg* it);
  74. char theDelimiter;
  75. };
  76. inline void DocBookOutput::version(CmdLineInterface& _cmd)
  77. {
  78. std::cout << _cmd.getVersion() << std::endl;
  79. }
  80. inline void DocBookOutput::usage(CmdLineInterface& _cmd )
  81. {
  82. std::list<Arg*> argList = _cmd.getArgList();
  83. std::string progName = _cmd.getProgramName();
  84. std::string xversion = _cmd.getVersion();
  85. theDelimiter = _cmd.getDelimiter();
  86. XorHandler xorHandler = _cmd.getXorHandler();
  87. const std::vector< std::vector<Arg*> > xorList = xorHandler.getXorList();
  88. basename(progName);
  89. std::cout << "<?xml version='1.0'?>" << std::endl;
  90. std::cout << "<!DOCTYPE refentry PUBLIC \"-//OASIS//DTD DocBook XML V4.2//EN\"" << std::endl;
  91. std::cout << "\t\"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd\">" << std::endl << std::endl;
  92. std::cout << "<refentry>" << std::endl;
  93. std::cout << "<refmeta>" << std::endl;
  94. std::cout << "<refentrytitle>" << progName << "</refentrytitle>" << std::endl;
  95. std::cout << "<manvolnum>1</manvolnum>" << std::endl;
  96. std::cout << "</refmeta>" << std::endl;
  97. std::cout << "<refnamediv>" << std::endl;
  98. std::cout << "<refname>" << progName << "</refname>" << std::endl;
  99. std::cout << "<refpurpose>" << _cmd.getMessage() << "</refpurpose>" << std::endl;
  100. std::cout << "</refnamediv>" << std::endl;
  101. std::cout << "<refsynopsisdiv>" << std::endl;
  102. std::cout << "<cmdsynopsis>" << std::endl;
  103. std::cout << "<command>" << progName << "</command>" << std::endl;
  104. // xor
  105. for ( int i = 0; (unsigned int)i < xorList.size(); i++ )
  106. {
  107. std::cout << "<group choice='req'>" << std::endl;
  108. for ( ArgVectorIterator it = xorList[i].begin();
  109. it != xorList[i].end(); it++ )
  110. printShortArg((*it));
  111. std::cout << "</group>" << std::endl;
  112. }
  113. // rest of args
  114. for (ArgListIterator it = argList.begin(); it != argList.end(); it++)
  115. if ( !xorHandler.contains( (*it) ) )
  116. printShortArg((*it));
  117. std::cout << "</cmdsynopsis>" << std::endl;
  118. std::cout << "</refsynopsisdiv>" << std::endl;
  119. std::cout << "<refsect1>" << std::endl;
  120. std::cout << "<title>Description</title>" << std::endl;
  121. std::cout << "<para>" << std::endl;
  122. std::cout << _cmd.getMessage() << std::endl;
  123. std::cout << "</para>" << std::endl;
  124. std::cout << "</refsect1>" << std::endl;
  125. std::cout << "<refsect1>" << std::endl;
  126. std::cout << "<title>Options</title>" << std::endl;
  127. std::cout << "<variablelist>" << std::endl;
  128. for (ArgListIterator it = argList.begin(); it != argList.end(); it++)
  129. printLongArg((*it));
  130. std::cout << "</variablelist>" << std::endl;
  131. std::cout << "</refsect1>" << std::endl;
  132. std::cout << "<refsect1>" << std::endl;
  133. std::cout << "<title>Version</title>" << std::endl;
  134. std::cout << "<para>" << std::endl;
  135. std::cout << xversion << std::endl;
  136. std::cout << "</para>" << std::endl;
  137. std::cout << "</refsect1>" << std::endl;
  138. std::cout << "</refentry>" << std::endl;
  139. }
  140. inline void DocBookOutput::failure( CmdLineInterface& _cmd,
  141. ArgException& e )
  142. {
  143. static_cast<void>(_cmd); // unused
  144. std::cout << e.what() << std::endl;
  145. throw ExitException(1);
  146. }
  147. inline void DocBookOutput::substituteSpecialChars( std::string& s,
  148. char r,
  149. std::string& x )
  150. {
  151. size_t p;
  152. while ( (p = s.find_first_of(r)) != std::string::npos )
  153. {
  154. s.erase(p,1);
  155. s.insert(p,x);
  156. }
  157. }
  158. inline void DocBookOutput::removeChar( std::string& s, char r)
  159. {
  160. size_t p;
  161. while ( (p = s.find_first_of(r)) != std::string::npos )
  162. {
  163. s.erase(p,1);
  164. }
  165. }
  166. inline void DocBookOutput::basename( std::string& s )
  167. {
  168. size_t p = s.find_last_of('/');
  169. if ( p != std::string::npos )
  170. {
  171. s.erase(0, p + 1);
  172. }
  173. }
  174. inline void DocBookOutput::printShortArg(Arg* a)
  175. {
  176. std::string lt = "&lt;";
  177. std::string gt = "&gt;";
  178. std::string id = a->shortID();
  179. substituteSpecialChars(id,'<',lt);
  180. substituteSpecialChars(id,'>',gt);
  181. removeChar(id,'[');
  182. removeChar(id,']');
  183. std::string choice = "opt";
  184. if ( a->isRequired() )
  185. choice = "plain";
  186. std::cout << "<arg choice='" << choice << '\'';
  187. if ( a->acceptsMultipleValues() )
  188. std::cout << " rep='repeat'";
  189. std::cout << '>';
  190. if ( !a->getFlag().empty() )
  191. std::cout << a->flagStartChar() << a->getFlag();
  192. else
  193. std::cout << a->nameStartString() << a->getName();
  194. if ( a->isValueRequired() )
  195. {
  196. std::string arg = a->shortID();
  197. removeChar(arg,'[');
  198. removeChar(arg,']');
  199. removeChar(arg,'<');
  200. removeChar(arg,'>');
  201. removeChar(arg,'.');
  202. arg.erase(0, arg.find_last_of(theDelimiter) + 1);
  203. std::cout << theDelimiter;
  204. std::cout << "<replaceable>" << arg << "</replaceable>";
  205. }
  206. std::cout << "</arg>" << std::endl;
  207. }
  208. inline void DocBookOutput::printLongArg(Arg* a)
  209. {
  210. std::string lt = "&lt;";
  211. std::string gt = "&gt;";
  212. std::string desc = a->getDescription();
  213. substituteSpecialChars(desc,'<',lt);
  214. substituteSpecialChars(desc,'>',gt);
  215. std::cout << "<varlistentry>" << std::endl;
  216. if ( !a->getFlag().empty() )
  217. {
  218. std::cout << "<term>" << std::endl;
  219. std::cout << "<option>";
  220. std::cout << a->flagStartChar() << a->getFlag();
  221. std::cout << "</option>" << std::endl;
  222. std::cout << "</term>" << std::endl;
  223. }
  224. std::cout << "<term>" << std::endl;
  225. std::cout << "<option>";
  226. std::cout << a->nameStartString() << a->getName();
  227. if ( a->isValueRequired() )
  228. {
  229. std::string arg = a->shortID();
  230. removeChar(arg,'[');
  231. removeChar(arg,']');
  232. removeChar(arg,'<');
  233. removeChar(arg,'>');
  234. removeChar(arg,'.');
  235. arg.erase(0, arg.find_last_of(theDelimiter) + 1);
  236. std::cout << theDelimiter;
  237. std::cout << "<replaceable>" << arg << "</replaceable>";
  238. }
  239. std::cout << "</option>" << std::endl;
  240. std::cout << "</term>" << std::endl;
  241. std::cout << "<listitem>" << std::endl;
  242. std::cout << "<para>" << std::endl;
  243. std::cout << desc << std::endl;
  244. std::cout << "</para>" << std::endl;
  245. std::cout << "</listitem>" << std::endl;
  246. std::cout << "</varlistentry>" << std::endl;
  247. }
  248. } //namespace TCLAP
  249. #endif