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
23using Poco::icompare;
24
25
26namespace Poco {
27namespace Util {
28
29
30Option::Option():
31 _required(false),
32 _repeatable(false),
33 _argRequired(false),
34 _pValidator(0),
35 _pCallback(0),
36 _pConfig(0)
37{
38}
39
40
41Option::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
61Option::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
74Option::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
88Option::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
103Option::~Option()
104{
105 if (_pValidator) _pValidator->release();
106 if (_pConfig) _pConfig->release();
107 delete _pCallback;
108}
109
110
111Option& 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
122void 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
139Option& Option::shortName(const std::string& name)
140{
141 _shortName = name;
142 return *this;
143}
144
145
146Option& Option::fullName(const std::string& name)
147{
148 _fullName = name;
149 return *this;
150}
151
152
153Option& Option::description(const std::string& text)
154{
155 _description = text;
156 return *this;
157}
158
159
160Option& Option::required(bool flag)
161{
162 _required = flag;
163 return *this;
164}
165
166
167Option& Option::repeatable(bool flag)
168{
169 _repeatable = flag;
170 return *this;
171}
172
173
174Option& Option::argument(const std::string& name, bool isRequired)
175{
176 _argName = name;
177 _argRequired = isRequired;
178 return *this;
179}
180
181
182Option& Option::noArgument()
183{
184 _argName.clear();
185 _argRequired = false;
186 return *this;
187}
188
189
190Option& Option::group(const std::string& group)
191{
192 _group = group;
193 return *this;
194}
195
196
197Option& Option::binding(const std::string& propertyName)
198{
199 return binding(propertyName, 0);
200}
201
202
203Option& 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
213Option& Option::callback(const AbstractOptionCallback& cb)
214{
215 _pCallback = cb.clone();
216 return *this;
217}
218
219
220Option& Option::validator(Validator* pValidator)
221{
222 if (_pValidator) _pValidator->release();
223 _pValidator = pValidator;
224 return *this;
225}
226
227
228bool 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
235bool 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
244bool 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
253void 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