Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.
 
 
 

300 rader
8.1 KiB

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