1 //  (C) Copyright Gennadiy Rozental 2005-2014.
2 //  Use, modification, and distribution are subject to the
3 //  Boost Software License, Version 1.0. (See accompanying file
4 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 
6 //  See http://www.boost.org/libs/test for the library home page.
7 //
8 //  File        : $RCSfile$
9 //
10 //  Version     : $Revision$
11 //
12 //  Description : defines parser - public interface for CLA parsing and accessing
13 // ***************************************************************************
14 
15 #ifndef BOOST_TEST_UTILS_RUNTIME_CLA_PARSER_HPP
16 #define BOOST_TEST_UTILS_RUNTIME_CLA_PARSER_HPP
17 
18 // Boost.Runtime.Parameter
19 #include <boost/test/utils/runtime/config.hpp>
20 #include <boost/test/utils/runtime/fwd.hpp>
21 #include <boost/test/utils/runtime/argument.hpp>
22 
23 #include <boost/test/utils/runtime/cla/fwd.hpp>
24 #include <boost/test/utils/runtime/cla/modifier.hpp>
25 #include <boost/test/utils/runtime/cla/argv_traverser.hpp>
26 
27 // Boost
28 #include <boost/optional.hpp>
29 
30 // STL
31 #include <list>
32 
33 namespace boost {
34 
35 namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE {
36 
37 namespace cla {
38 
39 // ************************************************************************** //
40 // **************             runtime::cla::parser             ************** //
41 // ************************************************************************** //
42 
43 namespace cla_detail {
44 
45 template<typename Modifier>
46 class global_mod_parser {
47 public:
global_mod_parser(parser & p,Modifier const & m)48     global_mod_parser( parser& p, Modifier const& m )
49     : m_parser( p )
50     , m_modifiers( m )
51     {}
52 
53     template<typename Param>
54     global_mod_parser const&
operator <<(shared_ptr<Param> param) const55     operator<<( shared_ptr<Param> param ) const
56     {
57         param->accept_modifier( m_modifiers );
58 
59         m_parser << param;
60 
61         return *this;
62     }
63 
64 private:
65     // Data members;
66     parser&             m_parser;
67     Modifier const&     m_modifiers;
68 };
69 
70 }
71 
72 // ************************************************************************** //
73 // **************             runtime::cla::parser             ************** //
74 // ************************************************************************** //
75 
76 class parser {
77 public:
78     typedef std::list<parameter_ptr>::const_iterator param_iterator;
79     typedef std::list<parameter_ptr>::size_type param_size_type;
80 
81     // Constructor
82     explicit            parser( cstring program_name = cstring() );
83 
84     // parameter list construction interface
85     parser&             operator<<( parameter_ptr param );
86 
87     // parser and global parameters modifiers
88     template<typename Modifier>
89     cla_detail::global_mod_parser<Modifier>
operator -(Modifier const & m)90     operator-( Modifier const& m )
91     {
92         nfp::optionally_assign( m_traverser.p_separator.value, m, input_separator );
93         nfp::optionally_assign( m_traverser.p_ignore_mismatch.value, m, ignore_mismatch_m );
94 
95         return cla_detail::global_mod_parser<Modifier>( *this, m );
96     }
97 
98     // input processing method
99     void                parse( int& argc, char_type** argv );
100 
101     // parameters access
102     param_iterator      first_param() const;
103     param_iterator      last_param() const;
num_params() const104     param_size_type     num_params() const  { return m_parameters.size(); }
105     void                reset();
106 
107     // arguments access
108     const_argument_ptr  operator[]( cstring string_id ) const;
109     cstring             get( cstring string_id ) const;
110 
111     template<typename T>
get(cstring string_id) const112     T const&            get( cstring string_id ) const
113     {
114         return arg_value<T>( valid_argument( string_id ) );
115     }
116 
117     template<typename T>
get(cstring string_id,boost::optional<T> & res) const118     void                get( cstring string_id, boost::optional<T>& res ) const
119     {
120         const_argument_ptr actual_arg = (*this)[string_id];
121 
122         if( actual_arg )
123             res = arg_value<T>( *actual_arg );
124         else
125             res.reset();
126     }
127 
128     // help/usage
129     void                usage( out_stream& ostr );
130     void                help(  out_stream& ostr );
131 
132 private:
133     argument const&     valid_argument( cstring string_id ) const;
134 
135     // Data members
136     argv_traverser              m_traverser;
137     std::list<parameter_ptr>    m_parameters;
138     dstring                     m_program_name;
139 };
140 
141 //____________________________________________________________________________//
142 
143 } // namespace cla
144 
145 } // namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE
146 
147 } // namespace boost
148 
149 #ifndef BOOST_TEST_UTILS_RUNTIME_PARAM_OFFLINE
150 
151 #ifndef BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE
152 #   define BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE inline
153 #endif
154 # include <boost/test/utils/runtime/cla/parser.ipp>
155 
156 #endif
157 
158 #endif // BOOST_TEST_UTILS_RUNTIME_CLA_PARSER_HPP
159