1 // Copyright Vladimir Prus 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 #ifndef BOOST_PARSERS_HPP_VP_2004_05_06
7 #define BOOST_PARSERS_HPP_VP_2004_05_06
8 
9 #include <boost/program_options/detail/convert.hpp>
10 
11 #include <iterator>
12 
13 namespace boost { namespace program_options {
14 
15     namespace detail {
16         template<class charT, class Iterator>
17         std::vector<std::basic_string<charT> >
make_vector(Iterator i,Iterator e)18         make_vector(Iterator i, Iterator e)
19         {
20             std::vector<std::basic_string<charT> > result;
21             // Some compilers don't have templated constructor for
22             // vector, so we can't create vector from (argv+1, argv+argc) range
23             for(; i != e; ++i)
24                 result.push_back(*i);
25             return result;
26         }
27     }
28 
29     template<class charT>
30     basic_command_line_parser<charT>::
basic_command_line_parser(const std::vector<std::basic_string<charT>> & xargs)31     basic_command_line_parser(const std::vector<
32                               std::basic_string<charT> >& xargs)
33        : detail::cmdline(to_internal(xargs))
34     {}
35 
36 
37     template<class charT>
38     basic_command_line_parser<charT>::
basic_command_line_parser(int argc,const charT * const argv[])39     basic_command_line_parser(int argc, const charT* const argv[])
40     : detail::cmdline(
41         // Explicit template arguments are required by gcc 3.3.1
42         // (at least mingw version), and do no harm on other compilers.
43         to_internal(detail::make_vector<charT, const charT* const*>(argv+1, argv+argc+!argc))),
44         m_desc()
45     {}
46 
47 
48     template<class charT>
49     basic_command_line_parser<charT>&
options(const options_description & desc)50     basic_command_line_parser<charT>::options(const options_description& desc)
51     {
52        detail::cmdline::set_options_description(desc);
53         m_desc = &desc;
54         return *this;
55     }
56 
57     template<class charT>
58     basic_command_line_parser<charT>&
positional(const positional_options_description & desc)59     basic_command_line_parser<charT>::positional(
60         const positional_options_description& desc)
61     {
62         detail::cmdline::set_positional_options(desc);
63         return *this;
64     }
65 
66     template<class charT>
67     basic_command_line_parser<charT>&
style(int xstyle)68     basic_command_line_parser<charT>::style(int xstyle)
69     {
70         detail::cmdline::style(xstyle);
71         return *this;
72     }
73 
74     template<class charT>
75     basic_command_line_parser<charT>&
extra_parser(ext_parser ext)76     basic_command_line_parser<charT>::extra_parser(ext_parser ext)
77     {
78         detail::cmdline::set_additional_parser(ext);
79         return *this;
80     }
81 
82     template<class charT>
83     basic_command_line_parser<charT>&
allow_unregistered()84     basic_command_line_parser<charT>::allow_unregistered()
85     {
86         detail::cmdline::allow_unregistered();
87         return *this;
88     }
89 
90     template<class charT>
91     basic_command_line_parser<charT>&
extra_style_parser(style_parser s)92     basic_command_line_parser<charT>::extra_style_parser(style_parser s)
93     {
94         detail::cmdline::extra_style_parser(s);
95         return *this;
96     }
97 
98 
99 
100     template<class charT>
101     basic_parsed_options<charT>
run()102     basic_command_line_parser<charT>::run()
103     {
104         // save the canonical prefixes which were used by this cmdline parser
105         //    eventually inside the parsed results
106         //    This will be handy to format recognisable options
107         //    for diagnostic messages if everything blows up much later on
108         parsed_options result(m_desc, detail::cmdline::get_canonical_option_prefix());
109         result.options = detail::cmdline::run();
110 
111         // Presense of parsed_options -> wparsed_options conversion
112         // does the trick.
113         return basic_parsed_options<charT>(result);
114     }
115 
116 
117     template<class charT>
118     basic_parsed_options<charT>
parse_command_line(int argc,const charT * const argv[],const options_description & desc,int style,function1<std::pair<std::string,std::string>,const std::string &> ext)119     parse_command_line(int argc, const charT* const argv[],
120                        const options_description& desc,
121                        int style,
122                        function1<std::pair<std::string, std::string>,
123                                  const std::string&> ext)
124     {
125         return basic_command_line_parser<charT>(argc, argv).options(desc).
126             style(style).extra_parser(ext).run();
127     }
128 
129     template<class charT>
130     std::vector< std::basic_string<charT> >
collect_unrecognized(const std::vector<basic_option<charT>> & options,enum collect_unrecognized_mode mode)131     collect_unrecognized(const std::vector< basic_option<charT> >& options,
132                          enum collect_unrecognized_mode mode)
133     {
134         std::vector< std::basic_string<charT> >  result;
135         for(unsigned i = 0; i < options.size(); ++i)
136         {
137             if (options[i].unregistered ||
138                 (mode == include_positional && options[i].position_key != -1))
139             {
140                 copy(options[i].original_tokens.begin(),
141                      options[i].original_tokens.end(),
142                      back_inserter(result));
143             }
144         }
145         return result;
146     }
147 
148 
149 }}
150 
151 #endif
152