1 | // |
2 | // Option.cpp |
3 | // |
4 | // Library: Util |
5 | // Package: Options |
6 | // Module: Option |
7 | // |
8 | // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. |
9 | // and Contributors. |
10 | // |
11 | // SPDX-License-Identifier: BSL-1.0 |
12 | // |
13 | |
14 | |
15 | #include "Poco/Util/Option.h" |
16 | #include "Poco/Util/OptionException.h" |
17 | #include "Poco/Util/Validator.h" |
18 | #include "Poco/Util/AbstractConfiguration.h" |
19 | #include "Poco/String.h" |
20 | #include <algorithm> |
21 | |
22 | |
23 | using Poco::icompare; |
24 | |
25 | |
26 | namespace Poco { |
27 | namespace Util { |
28 | |
29 | |
30 | Option::Option(): |
31 | _required(false), |
32 | _repeatable(false), |
33 | _argRequired(false), |
34 | _pValidator(0), |
35 | _pCallback(0), |
36 | _pConfig(0) |
37 | { |
38 | } |
39 | |
40 | |
41 | Option::Option(const Option& option): |
42 | _shortName(option._shortName), |
43 | _fullName(option._fullName), |
44 | _description(option._description), |
45 | _required(option._required), |
46 | _repeatable(option._repeatable), |
47 | _argName(option._argName), |
48 | _argRequired(option._argRequired), |
49 | _group(option._group), |
50 | _binding(option._binding), |
51 | _pValidator(option._pValidator), |
52 | _pCallback(option._pCallback), |
53 | _pConfig(option._pConfig) |
54 | { |
55 | if (_pValidator) _pValidator->duplicate(); |
56 | if (_pCallback) _pCallback = _pCallback->clone(); |
57 | if (_pConfig) _pConfig->duplicate(); |
58 | } |
59 | |
60 | |
61 | Option::Option(const std::string& fullName, const std::string& shortName): |
62 | _shortName(shortName), |
63 | _fullName(fullName), |
64 | _required(false), |
65 | _repeatable(false), |
66 | _argRequired(false), |
67 | _pValidator(0), |
68 | _pCallback(0), |
69 | _pConfig(0) |
70 | { |
71 | } |
72 | |
73 | |
74 | Option::Option(const std::string& fullName, const std::string& shortName, const std::string& description, bool required): |
75 | _shortName(shortName), |
76 | _fullName(fullName), |
77 | _description(description), |
78 | _required(required), |
79 | _repeatable(false), |
80 | _argRequired(false), |
81 | _pValidator(0), |
82 | _pCallback(0), |
83 | _pConfig(0) |
84 | { |
85 | } |
86 | |
87 | |
88 | Option::Option(const std::string& fullName, const std::string& shortName, const std::string& description, bool required, const std::string& argName, bool argRequired): |
89 | _shortName(shortName), |
90 | _fullName(fullName), |
91 | _description(description), |
92 | _required(required), |
93 | _repeatable(false), |
94 | _argName(argName), |
95 | _argRequired(argRequired), |
96 | _pValidator(0), |
97 | _pCallback(0), |
98 | _pConfig(0) |
99 | { |
100 | } |
101 | |
102 | |
103 | Option::~Option() |
104 | { |
105 | if (_pValidator) _pValidator->release(); |
106 | if (_pConfig) _pConfig->release(); |
107 | delete _pCallback; |
108 | } |
109 | |
110 | |
111 | Option& Option::operator = (const Option& option) |
112 | { |
113 | if (&option != this) |
114 | { |
115 | Option tmp(option); |
116 | swap(tmp); |
117 | } |
118 | return *this; |
119 | } |
120 | |
121 | |
122 | void Option::swap(Option& option) |
123 | { |
124 | std::swap(_shortName, option._shortName); |
125 | std::swap(_fullName, option._fullName); |
126 | std::swap(_description, option._description); |
127 | std::swap(_required, option._required); |
128 | std::swap(_repeatable, option._repeatable); |
129 | std::swap(_argName, option._argName); |
130 | std::swap(_argRequired, option._argRequired); |
131 | std::swap(_group, option._group); |
132 | std::swap(_binding, option._binding); |
133 | std::swap(_pValidator, option._pValidator); |
134 | std::swap(_pCallback, option._pCallback); |
135 | std::swap(_pConfig, option._pConfig); |
136 | } |
137 | |
138 | |
139 | Option& Option::shortName(const std::string& name) |
140 | { |
141 | _shortName = name; |
142 | return *this; |
143 | } |
144 | |
145 | |
146 | Option& Option::fullName(const std::string& name) |
147 | { |
148 | _fullName = name; |
149 | return *this; |
150 | } |
151 | |
152 | |
153 | Option& Option::description(const std::string& text) |
154 | { |
155 | _description = text; |
156 | return *this; |
157 | } |
158 | |
159 | |
160 | Option& Option::required(bool flag) |
161 | { |
162 | _required = flag; |
163 | return *this; |
164 | } |
165 | |
166 | |
167 | Option& Option::repeatable(bool flag) |
168 | { |
169 | _repeatable = flag; |
170 | return *this; |
171 | } |
172 | |
173 | |
174 | Option& Option::argument(const std::string& name, bool isRequired) |
175 | { |
176 | _argName = name; |
177 | _argRequired = isRequired; |
178 | return *this; |
179 | } |
180 | |
181 | |
182 | Option& Option::noArgument() |
183 | { |
184 | _argName.clear(); |
185 | _argRequired = false; |
186 | return *this; |
187 | } |
188 | |
189 | |
190 | Option& Option::group(const std::string& group) |
191 | { |
192 | _group = group; |
193 | return *this; |
194 | } |
195 | |
196 | |
197 | Option& Option::binding(const std::string& propertyName) |
198 | { |
199 | return binding(propertyName, 0); |
200 | } |
201 | |
202 | |
203 | Option& Option::binding(const std::string& propertyName, AbstractConfiguration* pConfig) |
204 | { |
205 | _binding = propertyName; |
206 | if (_pConfig) _pConfig->release(); |
207 | _pConfig = pConfig; |
208 | if (_pConfig) _pConfig->duplicate(); |
209 | return *this; |
210 | } |
211 | |
212 | |
213 | Option& Option::callback(const AbstractOptionCallback& cb) |
214 | { |
215 | _pCallback = cb.clone(); |
216 | return *this; |
217 | } |
218 | |
219 | |
220 | Option& Option::validator(Validator* pValidator) |
221 | { |
222 | if (_pValidator) _pValidator->release(); |
223 | _pValidator = pValidator; |
224 | return *this; |
225 | } |
226 | |
227 | |
228 | bool Option::matchesShort(const std::string& option) const |
229 | { |
230 | return option.length() > 0 |
231 | && !_shortName.empty() && option.compare(0, _shortName.length(), _shortName) == 0; |
232 | } |
233 | |
234 | |
235 | bool Option::matchesFull(const std::string& option) const |
236 | { |
237 | std::string::size_type pos = option.find_first_of(":=" ); |
238 | std::string::size_type len = pos == std::string::npos ? option.length() : pos; |
239 | return len == _fullName.length() |
240 | && icompare(option, 0, len, _fullName, 0, len) == 0; |
241 | } |
242 | |
243 | |
244 | bool Option::matchesPartial(const std::string& option) const |
245 | { |
246 | std::string::size_type pos = option.find_first_of(":=" ); |
247 | std::string::size_type len = pos == std::string::npos ? option.length() : pos; |
248 | return option.length() > 0 |
249 | && icompare(option, 0, len, _fullName, 0, len) == 0; |
250 | } |
251 | |
252 | |
253 | void Option::process(const std::string& option, std::string& arg) const |
254 | { |
255 | std::string::size_type pos = option.find_first_of(":=" ); |
256 | std::string::size_type len = pos == std::string::npos ? option.length() : pos; |
257 | if (icompare(option, 0, len, _fullName, 0, len) == 0) |
258 | { |
259 | if (takesArgument()) |
260 | { |
261 | if (argumentRequired() && pos == std::string::npos) |
262 | throw MissingArgumentException(_fullName + " requires " + argumentName()); |
263 | if (pos != std::string::npos) |
264 | arg.assign(option, pos + 1, option.length() - pos - 1); |
265 | else |
266 | arg.clear(); |
267 | } |
268 | else if (pos != std::string::npos) |
269 | { |
270 | throw UnexpectedArgumentException(option); |
271 | } |
272 | else arg.clear(); |
273 | } |
274 | else if (!_shortName.empty() && option.compare(0, _shortName.length(), _shortName) == 0) |
275 | { |
276 | if (takesArgument()) |
277 | { |
278 | if (argumentRequired() && option.length() == _shortName.length()) |
279 | throw MissingArgumentException(_shortName + " requires " + argumentName()); |
280 | arg.assign(option, _shortName.length(), option.length() - _shortName.length()); |
281 | } |
282 | else if (option.length() != _shortName.length()) |
283 | { |
284 | throw UnexpectedArgumentException(option); |
285 | } |
286 | else arg.clear(); |
287 | } |
288 | else throw UnknownOptionException(option); |
289 | } |
290 | |
291 | |
292 | } } // namespace Poco::Util |
293 | |