1 // Copyright Vladimir Prus 2002-2004.
2 // Distributed under the Boost Software License, Version 1.0.
3 // (See accompanying file LICENSE_1_0.txt
4 // or copy at http://www.boost.org/LICENSE_1_0.txt)
5 
6 
7 #ifndef BOOST_CMDLINE_VP_2003_05_19
8 #define BOOST_CMDLINE_VP_2003_05_19
9 
10 #include <boost/program_options/config.hpp>
11 #include <boost/program_options/errors.hpp>
12 #include <boost/program_options/cmdline.hpp>
13 #include <boost/program_options/option.hpp>
14 #include <boost/program_options/options_description.hpp>
15 #include <boost/program_options/positional_options.hpp>
16 
17 
18 #include <boost/detail/workaround.hpp>
19 
20 #include <boost/function.hpp>
21 
22 #include <string>
23 #include <vector>
24 
25 #if defined(BOOST_MSVC)
26 #   pragma warning (push)
27 #   pragma warning (disable:4251) // class 'std::vector<_Ty>' needs to have dll-interface to be used by clients of class 'boost::program_options::positional_options_description'
28 #endif
29 
30 namespace boost { namespace program_options { namespace detail {
31 
32     /** Command line parser class. Main requirements were:
33         - Powerful enough to support all common uses.
34         - Simple and easy to learn/use.
35         - Minimal code size and external dependencies.
36         - Extensible for custom syntaxes.
37 
38         First all options are registered. After that, elements of command line
39         are extracted using operator++.
40 
41         For each element, user can find
42         - if it's an option or an argument
43         - name of the option
44         - index of the option
45         - option value(s), if any
46 
47         Sometimes the registered option name is not equal to the encountered
48         one, for example, because name abbreviation is supported.  Therefore
49         two option names can be obtained:
50         - the registered one
51         - the one found at the command line
52 
53         There are lot of style options, which can be used to tune the command
54         line parsing. In addition, it's possible to install additional parser
55         which will process custom option styles.
56 
57         @todo mininal match length for guessing?
58     */
59     class BOOST_PROGRAM_OPTIONS_DECL cmdline {
60     public:
61 
62         typedef ::boost::program_options::command_line_style::style_t style_t;
63 
64         typedef function1<std::pair<std::string, std::string>,
65                           const std::string&>
66             additional_parser;
67 
68         typedef function1<std::vector<option>, std::vector<std::string>&>
69             style_parser;
70 
71         /** Constructs a command line parser for (argc, argv) pair. Uses
72             style options passed in 'style', which should be binary or'ed values
73             of style_t enum. It can also be zero, in which case a "default"
74             style will be used. If 'allow_unregistered' is true, then allows
75             unregistered options. They will be assigned index 1 and are
76             assumed to have optional parameter.
77         */
78         cmdline(const std::vector<std::string>& args);
79 
80         /** @overload */
81         cmdline(int argc, const char*const * argv);
82 
83         void style(int style);
84 
85         /** returns the canonical option prefix associated with the command_line_style
86          *  In order of precedence:
87          *      allow_long           : allow_long
88          *      allow_long_disguise  : allow_long_disguise
89          *      allow_dash_for_short : allow_short | allow_dash_for_short
90          *      allow_slash_for_short: allow_short | allow_slash_for_short
91          *
92          *      This is mainly used for the diagnostic messages in exceptions
93         */
94         int         get_canonical_option_prefix();
95 
96         void allow_unregistered();
97 
98         void set_options_description(const options_description& desc);
99         void set_positional_options(
100             const positional_options_description& m_positional);
101 
102         std::vector<option> run();
103 
104         std::vector<option> parse_long_option(std::vector<std::string>& args);
105         std::vector<option> parse_short_option(std::vector<std::string>& args);
106         std::vector<option> parse_dos_option(std::vector<std::string>& args);
107         std::vector<option> parse_disguised_long_option(
108             std::vector<std::string>& args);
109         std::vector<option> parse_terminator(
110             std::vector<std::string>& args);
111         std::vector<option> handle_additional_parser(
112             std::vector<std::string>& args);
113 
114 
115         /** Set additional parser. This will be called for each token
116             of command line. If first string in pair is not empty,
117             then the token is considered matched by this parser,
118             and the first string will be considered an option name
119             (which can be long or short), while the second will be
120             option's parameter (if not empty).
121             Note that additional parser can match only one token.
122         */
123         void set_additional_parser(additional_parser p);
124 
125         void extra_style_parser(style_parser s);
126 
127         void check_style(int style) const;
128 
129         bool is_style_active(style_t style) const;
130 
131         void init(const std::vector<std::string>& args);
132 
133         void
134         finish_option(option& opt,
135                       std::vector<std::string>& other_tokens,
136                       const std::vector<style_parser>& style_parsers);
137 
138         // Copies of input.
139         std::vector<std::string> m_args;
140         style_t m_style;
141         bool m_allow_unregistered;
142 
143         const options_description* m_desc;
144         const positional_options_description* m_positional;
145 
146         additional_parser m_additional_parser;
147         style_parser m_style_parser;
148     };
149 
150     void test_cmdline_detail();
151 
152 }}}
153 
154 #if defined(BOOST_MSVC)
155 #   pragma warning (pop)
156 #endif
157 
158 #endif
159 
160