xref: /minix3/external/bsd/kyua-cli/dist/utils/cmdline/options.hpp (revision 11be35a165022172ed3cea20f2b5df0307540b0e)
1*11be35a1SLionel Sambuc // Copyright 2010 Google Inc.
2*11be35a1SLionel Sambuc // All rights reserved.
3*11be35a1SLionel Sambuc //
4*11be35a1SLionel Sambuc // Redistribution and use in source and binary forms, with or without
5*11be35a1SLionel Sambuc // modification, are permitted provided that the following conditions are
6*11be35a1SLionel Sambuc // met:
7*11be35a1SLionel Sambuc //
8*11be35a1SLionel Sambuc // * Redistributions of source code must retain the above copyright
9*11be35a1SLionel Sambuc //   notice, this list of conditions and the following disclaimer.
10*11be35a1SLionel Sambuc // * Redistributions in binary form must reproduce the above copyright
11*11be35a1SLionel Sambuc //   notice, this list of conditions and the following disclaimer in the
12*11be35a1SLionel Sambuc //   documentation and/or other materials provided with the distribution.
13*11be35a1SLionel Sambuc // * Neither the name of Google Inc. nor the names of its contributors
14*11be35a1SLionel Sambuc //   may be used to endorse or promote products derived from this software
15*11be35a1SLionel Sambuc //   without specific prior written permission.
16*11be35a1SLionel Sambuc //
17*11be35a1SLionel Sambuc // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18*11be35a1SLionel Sambuc // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19*11be35a1SLionel Sambuc // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20*11be35a1SLionel Sambuc // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21*11be35a1SLionel Sambuc // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22*11be35a1SLionel Sambuc // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23*11be35a1SLionel Sambuc // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24*11be35a1SLionel Sambuc // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25*11be35a1SLionel Sambuc // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26*11be35a1SLionel Sambuc // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27*11be35a1SLionel Sambuc // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*11be35a1SLionel Sambuc 
29*11be35a1SLionel Sambuc /// \file utils/cmdline/options.hpp
30*11be35a1SLionel Sambuc /// Definitions of command-line options.
31*11be35a1SLionel Sambuc 
32*11be35a1SLionel Sambuc #if !defined(UTILS_CMDLINE_OPTIONS_HPP)
33*11be35a1SLionel Sambuc #define UTILS_CMDLINE_OPTIONS_HPP
34*11be35a1SLionel Sambuc 
35*11be35a1SLionel Sambuc #include <string>
36*11be35a1SLionel Sambuc #include <utility>
37*11be35a1SLionel Sambuc #include <vector>
38*11be35a1SLionel Sambuc 
39*11be35a1SLionel Sambuc #include "utils/fs/path.hpp"
40*11be35a1SLionel Sambuc 
41*11be35a1SLionel Sambuc namespace utils {
42*11be35a1SLionel Sambuc namespace cmdline {
43*11be35a1SLionel Sambuc 
44*11be35a1SLionel Sambuc 
45*11be35a1SLionel Sambuc /// Type-less base option class.
46*11be35a1SLionel Sambuc ///
47*11be35a1SLionel Sambuc /// This abstract class provides the most generic representation of options.  It
48*11be35a1SLionel Sambuc /// allows defining options with both short and long names, with and without
49*11be35a1SLionel Sambuc /// arguments and with and without optional values.  These are all the possible
50*11be35a1SLionel Sambuc /// combinations supported by the getopt_long(3) function, on which this is
51*11be35a1SLionel Sambuc /// built.
52*11be35a1SLionel Sambuc ///
53*11be35a1SLionel Sambuc /// The internal values (e.g. the default value) of a generic option are all
54*11be35a1SLionel Sambuc /// represented as strings.  However, from the caller's perspective, this is
55*11be35a1SLionel Sambuc /// suboptimal.  Hence why this class must be specialized: the subclasses
56*11be35a1SLionel Sambuc /// provide type-specific accessors and provide automatic validation of the
57*11be35a1SLionel Sambuc /// types (e.g. a string '3foo' is not passed to an integer option).
58*11be35a1SLionel Sambuc ///
59*11be35a1SLionel Sambuc /// Given that subclasses are used through templatized code, they must provide:
60*11be35a1SLionel Sambuc ///
61*11be35a1SLionel Sambuc /// <ul>
62*11be35a1SLionel Sambuc ///     <li>A public option_type typedef that defines the type of the
63*11be35a1SLionel Sambuc ///     option.</li>
64*11be35a1SLionel Sambuc ///
65*11be35a1SLionel Sambuc ///     <li>A convert() method that takes a string and converts it to
66*11be35a1SLionel Sambuc ///     option_type.  The string can be assumed to be convertible to the
67*11be35a1SLionel Sambuc ///     destination type.  Should not raise exceptions.</li>
68*11be35a1SLionel Sambuc ///
69*11be35a1SLionel Sambuc ///     <li>A validate() method that matches the implementation of convert().
70*11be35a1SLionel Sambuc ///     This method can throw option_argument_value_error if the string cannot
71*11be35a1SLionel Sambuc ///     be converted appropriately.  If validate() does not throw, then
72*11be35a1SLionel Sambuc ///     convert() must execute successfully.</li>
73*11be35a1SLionel Sambuc /// </ul>
74*11be35a1SLionel Sambuc ///
75*11be35a1SLionel Sambuc /// TODO(jmmv): Many methods in this class are split into two parts: has_foo()
76*11be35a1SLionel Sambuc /// and foo(), the former to query if the foo is available and the latter to get
77*11be35a1SLionel Sambuc /// the foo.  It'd be very nice if we'd use something similar Boost.Optional to
78*11be35a1SLionel Sambuc /// simplify this interface altogether.
79*11be35a1SLionel Sambuc class base_option {
80*11be35a1SLionel Sambuc     /// Short name of the option; 0 to indicate that none is available.
81*11be35a1SLionel Sambuc     char _short_name;
82*11be35a1SLionel Sambuc 
83*11be35a1SLionel Sambuc     /// Long name of the option.
84*11be35a1SLionel Sambuc     std::string _long_name;
85*11be35a1SLionel Sambuc 
86*11be35a1SLionel Sambuc     /// Textual description of the purpose of the option.
87*11be35a1SLionel Sambuc     std::string _description;
88*11be35a1SLionel Sambuc 
89*11be35a1SLionel Sambuc     /// Descriptive name of the required argument; empty if not allowed.
90*11be35a1SLionel Sambuc     std::string _arg_name;
91*11be35a1SLionel Sambuc 
92*11be35a1SLionel Sambuc     /// Whether the option has a default value or not.
93*11be35a1SLionel Sambuc     ///
94*11be35a1SLionel Sambuc     /// \todo We should probably be using the optional class here.
95*11be35a1SLionel Sambuc     bool _has_default_value;
96*11be35a1SLionel Sambuc 
97*11be35a1SLionel Sambuc     /// If _has_default_value is true, the default value.
98*11be35a1SLionel Sambuc     std::string _default_value;
99*11be35a1SLionel Sambuc 
100*11be35a1SLionel Sambuc public:
101*11be35a1SLionel Sambuc     base_option(const char, const char*, const char*, const char* = NULL,
102*11be35a1SLionel Sambuc                 const char* = NULL);
103*11be35a1SLionel Sambuc     base_option(const char*, const char*, const char* = NULL,
104*11be35a1SLionel Sambuc                 const char* = NULL);
105*11be35a1SLionel Sambuc     virtual ~base_option(void);
106*11be35a1SLionel Sambuc 
107*11be35a1SLionel Sambuc     bool has_short_name(void) const;
108*11be35a1SLionel Sambuc     char short_name(void) const;
109*11be35a1SLionel Sambuc     const std::string& long_name(void) const;
110*11be35a1SLionel Sambuc     const std::string& description(void) const;
111*11be35a1SLionel Sambuc 
112*11be35a1SLionel Sambuc     bool needs_arg(void) const;
113*11be35a1SLionel Sambuc     const std::string& arg_name(void) const;
114*11be35a1SLionel Sambuc 
115*11be35a1SLionel Sambuc     bool has_default_value(void) const;
116*11be35a1SLionel Sambuc     const std::string& default_value(void) const;
117*11be35a1SLionel Sambuc 
118*11be35a1SLionel Sambuc     std::string format_short_name(void) const;
119*11be35a1SLionel Sambuc     std::string format_long_name(void) const;
120*11be35a1SLionel Sambuc 
121*11be35a1SLionel Sambuc     virtual void validate(const std::string&) const;
122*11be35a1SLionel Sambuc };
123*11be35a1SLionel Sambuc 
124*11be35a1SLionel Sambuc 
125*11be35a1SLionel Sambuc /// Definition of a boolean option.
126*11be35a1SLionel Sambuc ///
127*11be35a1SLionel Sambuc /// A boolean option can be specified once in the command line, at which point
128*11be35a1SLionel Sambuc /// is set to true.  Such an option cannot carry optional arguments.
129*11be35a1SLionel Sambuc class bool_option : public base_option {
130*11be35a1SLionel Sambuc public:
131*11be35a1SLionel Sambuc     bool_option(const char, const char*, const char*);
132*11be35a1SLionel Sambuc     bool_option(const char*, const char*);
~bool_option(void)133*11be35a1SLionel Sambuc     virtual ~bool_option(void) {}
134*11be35a1SLionel Sambuc 
135*11be35a1SLionel Sambuc     /// The data type of this option.
136*11be35a1SLionel Sambuc     typedef bool option_type;
137*11be35a1SLionel Sambuc };
138*11be35a1SLionel Sambuc 
139*11be35a1SLionel Sambuc 
140*11be35a1SLionel Sambuc /// Definition of an integer option.
141*11be35a1SLionel Sambuc class int_option : public base_option {
142*11be35a1SLionel Sambuc public:
143*11be35a1SLionel Sambuc     int_option(const char, const char*, const char*, const char*,
144*11be35a1SLionel Sambuc                const char* = NULL);
145*11be35a1SLionel Sambuc     int_option(const char*, const char*, const char*, const char* = NULL);
~int_option(void)146*11be35a1SLionel Sambuc     virtual ~int_option(void) {}
147*11be35a1SLionel Sambuc 
148*11be35a1SLionel Sambuc     /// The data type of this option.
149*11be35a1SLionel Sambuc     typedef int option_type;
150*11be35a1SLionel Sambuc 
151*11be35a1SLionel Sambuc     virtual void validate(const std::string& str) const;
152*11be35a1SLionel Sambuc     static int convert(const std::string& str);
153*11be35a1SLionel Sambuc };
154*11be35a1SLionel Sambuc 
155*11be35a1SLionel Sambuc 
156*11be35a1SLionel Sambuc /// Definition of a comma-separated list of strings.
157*11be35a1SLionel Sambuc class list_option : public base_option {
158*11be35a1SLionel Sambuc public:
159*11be35a1SLionel Sambuc     list_option(const char, const char*, const char*, const char*,
160*11be35a1SLionel Sambuc                 const char* = NULL);
161*11be35a1SLionel Sambuc     list_option(const char*, const char*, const char*, const char* = NULL);
~list_option(void)162*11be35a1SLionel Sambuc     virtual ~list_option(void) {}
163*11be35a1SLionel Sambuc 
164*11be35a1SLionel Sambuc     /// The data type of this option.
165*11be35a1SLionel Sambuc     typedef std::vector< std::string > option_type;
166*11be35a1SLionel Sambuc 
167*11be35a1SLionel Sambuc     virtual void validate(const std::string&) const;
168*11be35a1SLionel Sambuc     static option_type convert(const std::string&);
169*11be35a1SLionel Sambuc };
170*11be35a1SLionel Sambuc 
171*11be35a1SLionel Sambuc 
172*11be35a1SLionel Sambuc /// Definition of an option representing a path.
173*11be35a1SLionel Sambuc ///
174*11be35a1SLionel Sambuc /// The path pointed to by the option may not exist, but it must be
175*11be35a1SLionel Sambuc /// syntactically valid.
176*11be35a1SLionel Sambuc class path_option : public base_option {
177*11be35a1SLionel Sambuc public:
178*11be35a1SLionel Sambuc     path_option(const char, const char*, const char*, const char*,
179*11be35a1SLionel Sambuc                 const char* = NULL);
180*11be35a1SLionel Sambuc     path_option(const char*, const char*, const char*, const char* = NULL);
~path_option(void)181*11be35a1SLionel Sambuc     virtual ~path_option(void) {}
182*11be35a1SLionel Sambuc 
183*11be35a1SLionel Sambuc     /// The data type of this option.
184*11be35a1SLionel Sambuc     typedef utils::fs::path option_type;
185*11be35a1SLionel Sambuc 
186*11be35a1SLionel Sambuc     virtual void validate(const std::string&) const;
187*11be35a1SLionel Sambuc     static utils::fs::path convert(const std::string&);
188*11be35a1SLionel Sambuc };
189*11be35a1SLionel Sambuc 
190*11be35a1SLionel Sambuc 
191*11be35a1SLionel Sambuc /// Definition of a property option.
192*11be35a1SLionel Sambuc ///
193*11be35a1SLionel Sambuc /// A property option is an option whose required arguments are of the form
194*11be35a1SLionel Sambuc /// 'name=value'.  Both components of the property are treated as free-form
195*11be35a1SLionel Sambuc /// non-empty strings; any other validation must happen on the caller side.
196*11be35a1SLionel Sambuc ///
197*11be35a1SLionel Sambuc /// \todo Would be nice if the delimiter was parametrizable.  With the current
198*11be35a1SLionel Sambuc ///     parser interface (convert() being a static method), the only way to do
199*11be35a1SLionel Sambuc ///     this would be to templatize this class.
200*11be35a1SLionel Sambuc class property_option : public base_option {
201*11be35a1SLionel Sambuc public:
202*11be35a1SLionel Sambuc     property_option(const char, const char*, const char*, const char*);
203*11be35a1SLionel Sambuc     property_option(const char*, const char*, const char*);
~property_option(void)204*11be35a1SLionel Sambuc     virtual ~property_option(void) {}
205*11be35a1SLionel Sambuc 
206*11be35a1SLionel Sambuc     /// The data type of this option.
207*11be35a1SLionel Sambuc     typedef std::pair< std::string, std::string > option_type;
208*11be35a1SLionel Sambuc 
209*11be35a1SLionel Sambuc     virtual void validate(const std::string& str) const;
210*11be35a1SLionel Sambuc     static option_type convert(const std::string& str);
211*11be35a1SLionel Sambuc };
212*11be35a1SLionel Sambuc 
213*11be35a1SLionel Sambuc 
214*11be35a1SLionel Sambuc /// Definition of a free-form string option.
215*11be35a1SLionel Sambuc ///
216*11be35a1SLionel Sambuc /// This class provides no restrictions on the argument passed to the option.
217*11be35a1SLionel Sambuc class string_option : public base_option {
218*11be35a1SLionel Sambuc public:
219*11be35a1SLionel Sambuc     string_option(const char, const char*, const char*, const char*,
220*11be35a1SLionel Sambuc                   const char* = NULL);
221*11be35a1SLionel Sambuc     string_option(const char*, const char*, const char*, const char* = NULL);
~string_option(void)222*11be35a1SLionel Sambuc     virtual ~string_option(void) {}
223*11be35a1SLionel Sambuc 
224*11be35a1SLionel Sambuc     /// The data type of this option.
225*11be35a1SLionel Sambuc     typedef std::string option_type;
226*11be35a1SLionel Sambuc 
227*11be35a1SLionel Sambuc     virtual void validate(const std::string& str) const;
228*11be35a1SLionel Sambuc     static std::string convert(const std::string& str);
229*11be35a1SLionel Sambuc };
230*11be35a1SLionel Sambuc 
231*11be35a1SLionel Sambuc 
232*11be35a1SLionel Sambuc }  // namespace cmdline
233*11be35a1SLionel Sambuc }  // namespace utils
234*11be35a1SLionel Sambuc 
235*11be35a1SLionel Sambuc #endif  // !defined(UTILS_CMDLINE_OPTIONS_HPP)
236