Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/kyua/utils/cmdline/options.hpp
101184 views
1
// Copyright 2010 The Kyua Authors.
2
// All rights reserved.
3
//
4
// Redistribution and use in source and binary forms, with or without
5
// modification, are permitted provided that the following conditions are
6
// met:
7
//
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.
16
//
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.
28
29
/// \file utils/cmdline/options.hpp
30
/// Definitions of command-line options.
31
32
#if !defined(UTILS_CMDLINE_OPTIONS_HPP)
33
#define UTILS_CMDLINE_OPTIONS_HPP
34
35
#include "utils/cmdline/options_fwd.hpp"
36
37
#include <string>
38
#include <utility>
39
#include <vector>
40
41
#include "utils/fs/path_fwd.hpp"
42
43
namespace utils {
44
namespace cmdline {
45
46
47
/// Type-less base option class.
48
///
49
/// This abstract class provides the most generic representation of options. It
50
/// allows defining options with both short and long names, with and without
51
/// arguments and with and without optional values. These are all the possible
52
/// combinations supported by the getopt_long(3) function, on which this is
53
/// built.
54
///
55
/// The internal values (e.g. the default value) of a generic option are all
56
/// represented as strings. However, from the caller's perspective, this is
57
/// suboptimal. Hence why this class must be specialized: the subclasses
58
/// provide type-specific accessors and provide automatic validation of the
59
/// types (e.g. a string '3foo' is not passed to an integer option).
60
///
61
/// Given that subclasses are used through templatized code, they must provide:
62
///
63
/// <ul>
64
/// <li>A public option_type typedef that defines the type of the
65
/// option.</li>
66
///
67
/// <li>A convert() method that takes a string and converts it to
68
/// option_type. The string can be assumed to be convertible to the
69
/// destination type. Should not raise exceptions.</li>
70
///
71
/// <li>A validate() method that matches the implementation of convert().
72
/// This method can throw option_argument_value_error if the string cannot
73
/// be converted appropriately. If validate() does not throw, then
74
/// convert() must execute successfully.</li>
75
/// </ul>
76
///
77
/// TODO(jmmv): Many methods in this class are split into two parts: has_foo()
78
/// and foo(), the former to query if the foo is available and the latter to get
79
/// the foo. It'd be very nice if we'd use something similar Boost.Optional to
80
/// simplify this interface altogether.
81
class base_option {
82
/// Short name of the option; 0 to indicate that none is available.
83
char _short_name;
84
85
/// Long name of the option.
86
std::string _long_name;
87
88
/// Textual description of the purpose of the option.
89
std::string _description;
90
91
/// Descriptive name of the required argument; empty if not allowed.
92
std::string _arg_name;
93
94
/// If the option can be used without an explicit argument provided.
95
bool _arg_is_optional = false;
96
97
/// Whether the option has a default value or not.
98
///
99
/// \todo We should probably be using the optional class here.
100
bool _has_default_value;
101
102
/// If _has_default_value is true, the default value.
103
std::string _default_value;
104
105
public:
106
base_option(const char, const char*, const char*, const char* = NULL,
107
const char* = NULL, bool = false);
108
base_option(const char*, const char*, const char* = NULL,
109
const char* = NULL);
110
virtual ~base_option(void);
111
112
bool has_short_name(void) const;
113
char short_name(void) const;
114
const std::string& long_name(void) const;
115
const std::string& description(void) const;
116
117
bool needs_arg(void) const;
118
const std::string& arg_name(void) const;
119
bool arg_is_optional(void) const;
120
121
bool has_default_value(void) const;
122
const std::string& default_value(void) const;
123
124
std::string format_short_name(void) const;
125
std::string format_long_name(void) const;
126
127
virtual void validate(const std::string&) const;
128
};
129
130
131
/// Definition of a boolean option.
132
///
133
/// A boolean option can be specified once in the command line, at which point
134
/// is set to true. Such an option cannot carry optional arguments.
135
class bool_option : public base_option {
136
public:
137
bool_option(const char, const char*, const char*);
138
bool_option(const char*, const char*);
139
virtual ~bool_option(void) {}
140
141
/// The data type of this option.
142
typedef bool option_type;
143
};
144
145
146
/// Definition of an integer option.
147
class int_option : public base_option {
148
public:
149
int_option(const char, const char*, const char*, const char*,
150
const char* = NULL);
151
int_option(const char*, const char*, const char*, const char* = NULL);
152
virtual ~int_option(void) {}
153
154
/// The data type of this option.
155
typedef int option_type;
156
157
virtual void validate(const std::string& str) const;
158
static int convert(const std::string& str);
159
};
160
161
162
/// Definition of a comma-separated list of strings.
163
class list_option : public base_option {
164
public:
165
list_option(const char, const char*, const char*, const char*,
166
const char* = NULL);
167
list_option(const char*, const char*, const char*, const char* = NULL);
168
virtual ~list_option(void) {}
169
170
/// The data type of this option.
171
typedef std::vector< std::string > option_type;
172
173
virtual void validate(const std::string&) const;
174
static option_type convert(const std::string&);
175
};
176
177
178
/// Definition of an option representing a path.
179
///
180
/// The path pointed to by the option may not exist, but it must be
181
/// syntactically valid.
182
class path_option : public base_option {
183
public:
184
path_option(const char, const char*, const char*, const char*,
185
const char* = NULL);
186
path_option(const char*, const char*, const char*, const char* = NULL);
187
virtual ~path_option(void) {}
188
189
/// The data type of this option.
190
typedef utils::fs::path option_type;
191
192
virtual void validate(const std::string&) const;
193
static utils::fs::path convert(const std::string&);
194
};
195
196
197
/// Definition of a property option.
198
///
199
/// A property option is an option whose required arguments are of the form
200
/// 'name=value'. Both components of the property are treated as free-form
201
/// non-empty strings; any other validation must happen on the caller side.
202
///
203
/// \todo Would be nice if the delimiter was parametrizable. With the current
204
/// parser interface (convert() being a static method), the only way to do
205
/// this would be to templatize this class.
206
class property_option : public base_option {
207
public:
208
property_option(const char, const char*, const char*, const char*);
209
property_option(const char*, const char*, const char*);
210
virtual ~property_option(void) {}
211
212
/// The data type of this option.
213
typedef std::pair< std::string, std::string > option_type;
214
215
virtual void validate(const std::string& str) const;
216
static option_type convert(const std::string& str);
217
};
218
219
220
/// Definition of a free-form string option.
221
///
222
/// This class provides no restrictions on the argument passed to the option.
223
class string_option : public base_option {
224
public:
225
string_option(const char, const char*, const char*, const char*,
226
const char* = NULL, bool = false);
227
string_option(const char*, const char*, const char*, const char* = NULL);
228
virtual ~string_option(void) {}
229
230
/// The data type of this option.
231
typedef std::string option_type;
232
233
virtual void validate(const std::string& str) const;
234
static std::string convert(const std::string& str);
235
};
236
237
238
} // namespace cmdline
239
} // namespace utils
240
241
#endif // !defined(UTILS_CMDLINE_OPTIONS_HPP)
242
243