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