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