Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/kyua/utils/cmdline/options.hpp
48179 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
/// Whether the option has a default value or not.
95
///
96
/// \todo We should probably be using the optional class here.
97
bool _has_default_value;
98
99
/// If _has_default_value is true, the default value.
100
std::string _default_value;
101
102
public:
103
base_option(const char, const char*, const char*, const char* = NULL,
104
const char* = NULL);
105
base_option(const char*, const char*, const char* = NULL,
106
const char* = NULL);
107
virtual ~base_option(void);
108
109
bool has_short_name(void) const;
110
char short_name(void) const;
111
const std::string& long_name(void) const;
112
const std::string& description(void) const;
113
114
bool needs_arg(void) const;
115
const std::string& arg_name(void) const;
116
117
bool has_default_value(void) const;
118
const std::string& default_value(void) const;
119
120
std::string format_short_name(void) const;
121
std::string format_long_name(void) const;
122
123
virtual void validate(const std::string&) const;
124
};
125
126
127
/// Definition of a boolean option.
128
///
129
/// A boolean option can be specified once in the command line, at which point
130
/// is set to true. Such an option cannot carry optional arguments.
131
class bool_option : public base_option {
132
public:
133
bool_option(const char, const char*, const char*);
134
bool_option(const char*, const char*);
135
virtual ~bool_option(void) {}
136
137
/// The data type of this option.
138
typedef bool option_type;
139
};
140
141
142
/// Definition of an integer option.
143
class int_option : public base_option {
144
public:
145
int_option(const char, const char*, const char*, const char*,
146
const char* = NULL);
147
int_option(const char*, const char*, const char*, const char* = NULL);
148
virtual ~int_option(void) {}
149
150
/// The data type of this option.
151
typedef int option_type;
152
153
virtual void validate(const std::string& str) const;
154
static int convert(const std::string& str);
155
};
156
157
158
/// Definition of a comma-separated list of strings.
159
class list_option : public base_option {
160
public:
161
list_option(const char, const char*, const char*, const char*,
162
const char* = NULL);
163
list_option(const char*, const char*, const char*, const char* = NULL);
164
virtual ~list_option(void) {}
165
166
/// The data type of this option.
167
typedef std::vector< std::string > option_type;
168
169
virtual void validate(const std::string&) const;
170
static option_type convert(const std::string&);
171
};
172
173
174
/// Definition of an option representing a path.
175
///
176
/// The path pointed to by the option may not exist, but it must be
177
/// syntactically valid.
178
class path_option : public base_option {
179
public:
180
path_option(const char, const char*, const char*, const char*,
181
const char* = NULL);
182
path_option(const char*, const char*, const char*, const char* = NULL);
183
virtual ~path_option(void) {}
184
185
/// The data type of this option.
186
typedef utils::fs::path option_type;
187
188
virtual void validate(const std::string&) const;
189
static utils::fs::path convert(const std::string&);
190
};
191
192
193
/// Definition of a property option.
194
///
195
/// A property option is an option whose required arguments are of the form
196
/// 'name=value'. Both components of the property are treated as free-form
197
/// non-empty strings; any other validation must happen on the caller side.
198
///
199
/// \todo Would be nice if the delimiter was parametrizable. With the current
200
/// parser interface (convert() being a static method), the only way to do
201
/// this would be to templatize this class.
202
class property_option : public base_option {
203
public:
204
property_option(const char, const char*, const char*, const char*);
205
property_option(const char*, const char*, const char*);
206
virtual ~property_option(void) {}
207
208
/// The data type of this option.
209
typedef std::pair< std::string, std::string > option_type;
210
211
virtual void validate(const std::string& str) const;
212
static option_type convert(const std::string& str);
213
};
214
215
216
/// Definition of a free-form string option.
217
///
218
/// This class provides no restrictions on the argument passed to the option.
219
class string_option : public base_option {
220
public:
221
string_option(const char, const char*, const char*, const char*,
222
const char* = NULL);
223
string_option(const char*, const char*, const char*, const char* = NULL);
224
virtual ~string_option(void) {}
225
226
/// The data type of this option.
227
typedef std::string option_type;
228
229
virtual void validate(const std::string& str) const;
230
static std::string convert(const std::string& str);
231
};
232
233
234
} // namespace cmdline
235
} // namespace utils
236
237
#endif // !defined(UTILS_CMDLINE_OPTIONS_HPP)
238
239