options_description.hpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. // Copyright Vladimir Prus 2002-2004.
  2. // Copyright Bertolt Mildner 2004.
  3. // Distributed under the Boost Software License, Version 1.0.
  4. // (See accompanying file LICENSE_1_0.txt
  5. // or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. #ifndef BOOST_OPTION_DESCRIPTION_VP_2003_05_19
  7. #define BOOST_OPTION_DESCRIPTION_VP_2003_05_19
  8. #include <boost/program_options/config.hpp>
  9. #include <boost/program_options/errors.hpp>
  10. #include <boost/program_options/value_semantic.hpp>
  11. #include <boost/function.hpp>
  12. #include <boost/shared_ptr.hpp>
  13. #include <boost/detail/workaround.hpp>
  14. #include <boost/any.hpp>
  15. #include <string>
  16. #include <vector>
  17. #include <set>
  18. #include <map>
  19. #include <stdexcept>
  20. #include <utility>
  21. #include <iosfwd>
  22. #if defined(BOOST_MSVC)
  23. # pragma warning (push)
  24. # pragma warning (disable:4251) // class 'boost::shared_ptr<T>' needs to have dll-interface to be used by clients of class 'boost::program_options::option_description'
  25. #endif
  26. /** Boost namespace */
  27. namespace boost {
  28. /** Namespace for the library. */
  29. namespace program_options {
  30. /** Describes one possible command line/config file option. There are two
  31. kinds of properties of an option. First describe it syntactically and
  32. are used only to validate input. Second affect interpretation of the
  33. option, for example default value for it or function that should be
  34. called when the value is finally known. Routines which perform parsing
  35. never use second kind of properties \-- they are side effect free.
  36. @sa options_description
  37. */
  38. class BOOST_PROGRAM_OPTIONS_DECL option_description {
  39. public:
  40. option_description();
  41. /** Initializes the object with the passed data.
  42. Note: it would be nice to make the second parameter auto_ptr,
  43. to explicitly pass ownership. Unfortunately, it's often needed to
  44. create objects of types derived from 'value_semantic':
  45. options_description d;
  46. d.add_options()("a", parameter<int>("n")->default_value(1));
  47. Here, the static type returned by 'parameter' should be derived
  48. from value_semantic.
  49. Alas, derived->base conversion for auto_ptr does not really work,
  50. see
  51. http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2000/n1232.pdf
  52. http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#84
  53. So, we have to use plain old pointers. Besides, users are not
  54. expected to use the constructor directly.
  55. The 'name' parameter is interpreted by the following rules:
  56. - if there's no "," character in 'name', it specifies long name
  57. - otherwise, the part before "," specifies long name and the part
  58. after \-- short name.
  59. */
  60. option_description(const char* name,
  61. const value_semantic* s);
  62. /** Initializes the class with the passed data.
  63. */
  64. option_description(const char* name,
  65. const value_semantic* s,
  66. const char* description);
  67. virtual ~option_description();
  68. enum match_result { no_match, full_match, approximate_match };
  69. /** Given 'option', specified in the input source,
  70. returns 'true' if 'option' specifies *this.
  71. */
  72. match_result match(const std::string& option, bool approx,
  73. bool long_ignore_case, bool short_ignore_case) const;
  74. /** Returns the key that should identify the option, in
  75. particular in the variables_map class.
  76. The 'option' parameter is the option spelling from the
  77. input source.
  78. If option name contains '*', returns 'option'.
  79. If long name was specified, it's the long name, otherwise
  80. it's a short name with prepended '-'.
  81. */
  82. const std::string& key(const std::string& option) const;
  83. /** Returns the canonical name for the option description to enable the user to
  84. recognised a matching option.
  85. 1) For short options ('-', '/'), returns the short name prefixed.
  86. 2) For long options ('--' / '-') returns the first long name prefixed
  87. 3) All other cases, returns the first long name (if present) or the short
  88. name, unprefixed.
  89. */
  90. std::string canonical_display_name(int canonical_option_style = 0) const;
  91. const std::string& long_name() const;
  92. const std::pair<const std::string*, std::size_t> long_names() const;
  93. /// Explanation of this option
  94. const std::string& description() const;
  95. /// Semantic of option's value
  96. shared_ptr<const value_semantic> semantic() const;
  97. /// Returns the option name, formatted suitably for usage message.
  98. std::string format_name() const;
  99. /** Returns the parameter name and properties, formatted suitably for
  100. usage message. */
  101. std::string format_parameter() const;
  102. private:
  103. option_description& set_names(const char* name);
  104. /**
  105. * a one-character "switch" name - with its prefix,
  106. * so that this is either empty or has length 2 (e.g. "-c"
  107. */
  108. std::string m_short_name;
  109. /**
  110. * one or more names by which this option may be specified
  111. * on a command-line or in a config file, which are not
  112. * a single-letter switch. The names here are _without_
  113. * any prefix.
  114. */
  115. std::vector<std::string> m_long_names;
  116. std::string m_description;
  117. // shared_ptr is needed to simplify memory management in
  118. // copy ctor and destructor.
  119. shared_ptr<const value_semantic> m_value_semantic;
  120. };
  121. class options_description;
  122. /** Class which provides convenient creation syntax to option_description.
  123. */
  124. class BOOST_PROGRAM_OPTIONS_DECL options_description_easy_init {
  125. public:
  126. options_description_easy_init(options_description* owner);
  127. options_description_easy_init&
  128. operator()(const char* name,
  129. const char* description);
  130. options_description_easy_init&
  131. operator()(const char* name,
  132. const value_semantic* s);
  133. options_description_easy_init&
  134. operator()(const char* name,
  135. const value_semantic* s,
  136. const char* description);
  137. private:
  138. options_description* owner;
  139. };
  140. /** A set of option descriptions. This provides convenient interface for
  141. adding new option (the add_options) method, and facilities to search
  142. for options by name.
  143. See @ref a_adding_options "here" for option adding interface discussion.
  144. @sa option_description
  145. */
  146. class BOOST_PROGRAM_OPTIONS_DECL options_description {
  147. public:
  148. static const unsigned m_default_line_length;
  149. /** Creates the instance. */
  150. options_description(unsigned line_length = m_default_line_length,
  151. unsigned min_description_length = m_default_line_length / 2);
  152. /** Creates the instance. The 'caption' parameter gives the name of
  153. this 'options_description' instance. Primarily useful for output.
  154. The 'description_length' specifies the number of columns that
  155. should be reserved for the description text; if the option text
  156. encroaches into this, then the description will start on the next
  157. line.
  158. */
  159. options_description(const std::string& caption,
  160. unsigned line_length = m_default_line_length,
  161. unsigned min_description_length = m_default_line_length / 2);
  162. /** Adds new variable description. Throws duplicate_variable_error if
  163. either short or long name matches that of already present one.
  164. */
  165. void add(shared_ptr<option_description> desc);
  166. /** Adds a group of option description. This has the same
  167. effect as adding all option_descriptions in 'desc'
  168. individually, except that output operator will show
  169. a separate group.
  170. Returns *this.
  171. */
  172. options_description& add(const options_description& desc);
  173. /** Find the maximum width of the option column, including options
  174. in groups. */
  175. unsigned get_option_column_width() const;
  176. public:
  177. /** Returns an object of implementation-defined type suitable for adding
  178. options to options_description. The returned object will
  179. have overloaded operator() with parameter type matching
  180. 'option_description' constructors. Calling the operator will create
  181. new option_description instance and add it.
  182. */
  183. options_description_easy_init add_options();
  184. const option_description& find(const std::string& name,
  185. bool approx,
  186. bool long_ignore_case = false,
  187. bool short_ignore_case = false) const;
  188. const option_description* find_nothrow(const std::string& name,
  189. bool approx,
  190. bool long_ignore_case = false,
  191. bool short_ignore_case = false) const;
  192. const std::vector< shared_ptr<option_description> >& options() const;
  193. /** Produces a human readable output of 'desc', listing options,
  194. their descriptions and allowed parameters. Other options_description
  195. instances previously passed to add will be output separately. */
  196. friend BOOST_PROGRAM_OPTIONS_DECL std::ostream& operator<<(std::ostream& os,
  197. const options_description& desc);
  198. /** Outputs 'desc' to the specified stream, calling 'f' to output each
  199. option_description element. */
  200. void print(std::ostream& os, unsigned width = 0) const;
  201. private:
  202. #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1800))
  203. // prevent warning C4512: assignment operator could not be generated
  204. options_description& operator=(const options_description&);
  205. #endif
  206. typedef std::map<std::string, int>::const_iterator name2index_iterator;
  207. typedef std::pair<name2index_iterator, name2index_iterator>
  208. approximation_range;
  209. //approximation_range find_approximation(const std::string& prefix) const;
  210. std::string m_caption;
  211. const unsigned m_line_length;
  212. const unsigned m_min_description_length;
  213. // Data organization is chosen because:
  214. // - there could be two names for one option
  215. // - option_add_proxy needs to know the last added option
  216. std::vector< shared_ptr<option_description> > m_options;
  217. // Whether the option comes from one of declared groups.
  218. #if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, BOOST_TESTED_AT(313))
  219. // vector<bool> is buggy there, see
  220. // http://support.microsoft.com/default.aspx?scid=kb;en-us;837698
  221. std::vector<char> belong_to_group;
  222. #else
  223. std::vector<bool> belong_to_group;
  224. #endif
  225. std::vector< shared_ptr<options_description> > groups;
  226. };
  227. /** Class thrown when duplicate option description is found. */
  228. class BOOST_PROGRAM_OPTIONS_DECL duplicate_option_error : public error {
  229. public:
  230. duplicate_option_error(const std::string& xwhat) : error(xwhat) {}
  231. };
  232. }}
  233. #if defined(BOOST_MSVC)
  234. # pragma warning (pop)
  235. #endif
  236. #endif