1/****************************************************************************
2**
3** Copyright (C) 2013 Laszlo Papp <lpapp@kde.org>
4** Copyright (C) 2013 David Faure <faure@kde.org>
5** Contact: https://www.qt.io/licensing/
6**
7** This file is part of the QtCore module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial License Usage
11** Licensees holding valid commercial Qt licenses may use this file in
12** accordance with the commercial license agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and The Qt Company. For licensing terms
15** and conditions see https://www.qt.io/terms-conditions. For further
16** information use the contact form at https://www.qt.io/contact-us.
17**
18** GNU Lesser General Public License Usage
19** Alternatively, this file may be used under the terms of the GNU Lesser
20** General Public License version 3 as published by the Free Software
21** Foundation and appearing in the file LICENSE.LGPL3 included in the
22** packaging of this file. Please review the following information to
23** ensure the GNU Lesser General Public License version 3 requirements
24** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
25**
26** GNU General Public License Usage
27** Alternatively, this file may be used under the terms of the GNU
28** General Public License version 2.0 or (at your option) the GNU General
29** Public license version 3 or any later version approved by the KDE Free
30** Qt Foundation. The licenses are as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
32** included in the packaging of this file. Please review the following
33** information to ensure the GNU General Public License requirements will
34** be met: https://www.gnu.org/licenses/gpl-2.0.html and
35** https://www.gnu.org/licenses/gpl-3.0.html.
36**
37** $QT_END_LICENSE$
38**
39****************************************************************************/
40
41#include "qcommandlineoption.h"
42
43#include "qset.h"
44
45QT_BEGIN_NAMESPACE
46
47class QCommandLineOptionPrivate : public QSharedData
48{
49public:
50 Q_NEVER_INLINE
51 explicit QCommandLineOptionPrivate(const QString &name)
52 : names(removeInvalidNames(QStringList(name)))
53 { }
54
55 Q_NEVER_INLINE
56 explicit QCommandLineOptionPrivate(const QStringList &names)
57 : names(removeInvalidNames(names))
58 { }
59
60 static QStringList removeInvalidNames(QStringList nameList);
61
62 //! The list of names used for this option.
63 QStringList names;
64
65 //! The documentation name for the value, if one is expected
66 //! Example: "-o <file>" means valueName == "file"
67 QString valueName;
68
69 //! The description used for this option.
70 QString description;
71
72 //! The list of default values used for this option.
73 QStringList defaultValues;
74
75 QCommandLineOption::Flags flags;
76};
77
78/*!
79 \since 5.2
80 \class QCommandLineOption
81 \brief The QCommandLineOption class defines a possible command-line option.
82 \inmodule QtCore
83 \ingroup shared
84 \ingroup tools
85
86 This class is used to describe an option on the command line. It allows
87 different ways of defining the same option with multiple aliases possible.
88 It is also used to describe how the option is used - it may be a flag (e.g. \c{-v})
89 or take a value (e.g. \c{-o file}).
90
91 Examples:
92 \snippet code/src_corelib_tools_qcommandlineoption.cpp 0
93
94 \sa QCommandLineParser
95*/
96
97/*!
98 \fn QCommandLineOption &QCommandLineOption::operator=(QCommandLineOption &&other)
99
100 Move-assigns \a other to this QCommandLineOption instance.
101
102 \since 5.2
103*/
104
105/*!
106 Constructs a command line option object with the name \a name.
107
108 The name can be either short or long. If the name is one character in
109 length, it is considered a short name. Option names must not be empty,
110 must not start with a dash or a slash character, must not contain a \c{=}
111 and cannot be repeated.
112
113 \sa setDescription(), setValueName(), setDefaultValues()
114*/
115QCommandLineOption::QCommandLineOption(const QString &name)
116 : d(new QCommandLineOptionPrivate(name))
117{
118}
119
120/*!
121 Constructs a command line option object with the names \a names.
122
123 This overload allows to set multiple names for the option, for instance
124 \c{o} and \c{output}.
125
126 The names can be either short or long. Any name in the list that is one
127 character in length is a short name. Option names must not be empty,
128 must not start with a dash or a slash character, must not contain a \c{=}
129 and cannot be repeated.
130
131 \sa setDescription(), setValueName(), setDefaultValues()
132*/
133QCommandLineOption::QCommandLineOption(const QStringList &names)
134 : d(new QCommandLineOptionPrivate(names))
135{
136}
137
138/*!
139 Constructs a command line option object with the given arguments.
140
141 The name of the option is set to \a name.
142 The name can be either short or long. If the name is one character in
143 length, it is considered a short name. Option names must not be empty,
144 must not start with a dash or a slash character, must not contain a \c{=}
145 and cannot be repeated.
146
147 The description is set to \a description. It is customary to add a "."
148 at the end of the description.
149
150 In addition, the \a valueName needs to be set if the option expects a value.
151 The default value for the option is set to \a defaultValue.
152
153 In Qt versions before 5.4, this constructor was \c explicit. In Qt 5.4
154 and later, it no longer is and can be used for C++11-style uniform
155 initialization:
156
157 \snippet code/src_corelib_tools_qcommandlineoption.cpp cxx11-init
158
159 \sa setDescription(), setValueName(), setDefaultValues()
160*/
161QCommandLineOption::QCommandLineOption(const QString &name, const QString &description,
162 const QString &valueName,
163 const QString &defaultValue)
164 : d(new QCommandLineOptionPrivate(name))
165{
166 setValueName(valueName);
167 setDescription(description);
168 setDefaultValue(defaultValue);
169}
170
171/*!
172 Constructs a command line option object with the given arguments.
173
174 This overload allows to set multiple names for the option, for instance
175 \c{o} and \c{output}.
176
177 The names of the option are set to \a names.
178 The names can be either short or long. Any name in the list that is one
179 character in length is a short name. Option names must not be empty,
180 must not start with a dash or a slash character, must not contain a \c{=}
181 and cannot be repeated.
182
183 The description is set to \a description. It is customary to add a "."
184 at the end of the description.
185
186 In addition, the \a valueName needs to be set if the option expects a value.
187 The default value for the option is set to \a defaultValue.
188
189 In Qt versions before 5.4, this constructor was \c explicit. In Qt 5.4
190 and later, it no longer is and can be used for C++11-style uniform
191 initialization:
192
193 \snippet code/src_corelib_tools_qcommandlineoption.cpp cxx11-init-list
194
195 \sa setDescription(), setValueName(), setDefaultValues()
196*/
197QCommandLineOption::QCommandLineOption(const QStringList &names, const QString &description,
198 const QString &valueName,
199 const QString &defaultValue)
200 : d(new QCommandLineOptionPrivate(names))
201{
202 setValueName(valueName);
203 setDescription(description);
204 setDefaultValue(defaultValue);
205}
206
207/*!
208 Constructs a QCommandLineOption object that is a copy of the QCommandLineOption
209 object \a other.
210
211 \sa operator=()
212*/
213QCommandLineOption::QCommandLineOption(const QCommandLineOption &other)
214 : d(other.d)
215{
216}
217
218/*!
219 Destroys the command line option object.
220*/
221QCommandLineOption::~QCommandLineOption()
222{
223}
224
225/*!
226 Makes a copy of the \a other object and assigns it to this QCommandLineOption
227 object.
228*/
229QCommandLineOption &QCommandLineOption::operator=(const QCommandLineOption &other)
230{
231 d = other.d;
232 return *this;
233}
234
235/*!
236 \fn void QCommandLineOption::swap(QCommandLineOption &other)
237
238 Swaps option \a other with this option. This operation is very
239 fast and never fails.
240*/
241
242/*!
243 Returns the names set for this option.
244 */
245QStringList QCommandLineOption::names() const
246{
247 return d->names;
248}
249
250namespace {
251 struct IsInvalidName
252 {
253 typedef bool result_type;
254 typedef QString argument_type;
255
256 Q_NEVER_INLINE
257 result_type operator()(const QString &name) const noexcept
258 {
259 if (Q_UNLIKELY(name.isEmpty()))
260 return warn("be empty");
261
262 const QChar c = name.at(0);
263 if (Q_UNLIKELY(c == QLatin1Char('-')))
264 return warn("start with a '-'");
265 if (Q_UNLIKELY(c == QLatin1Char('/')))
266 return warn("start with a '/'");
267 if (Q_UNLIKELY(name.contains(QLatin1Char('='))))
268 return warn("contain a '='");
269
270 return false;
271 }
272
273 Q_NEVER_INLINE
274 static bool warn(const char *what) noexcept
275 {
276 qWarning("QCommandLineOption: Option names cannot %s", what);
277 return true;
278 }
279 };
280} // unnamed namespace
281
282// static
283QStringList QCommandLineOptionPrivate::removeInvalidNames(QStringList nameList)
284{
285 if (Q_UNLIKELY(nameList.isEmpty()))
286 qWarning("QCommandLineOption: Options must have at least one name");
287 else
288 nameList.erase(std::remove_if(nameList.begin(), nameList.end(), IsInvalidName()),
289 nameList.end());
290 return nameList;
291}
292
293/*!
294 Sets the name of the expected value, for the documentation, to \a valueName.
295
296 Options without a value assigned have a boolean-like behavior:
297 either the user specifies --option or they don't.
298
299 Options with a value assigned need to set a name for the expected value,
300 for the documentation of the option in the help output. An option with names \c{o} and \c{output},
301 and a value name of \c{file} will appear as \c{-o, --output <file>}.
302
303 Call QCommandLineParser::value() if you expect the option to be present
304 only once, and QCommandLineParser::values() if you expect that option
305 to be present multiple times.
306
307 \sa valueName()
308 */
309void QCommandLineOption::setValueName(const QString &valueName)
310{
311 d->valueName = valueName;
312}
313
314/*!
315 Returns the name of the expected value.
316
317 If empty, the option doesn't take a value.
318
319 \sa setValueName()
320 */
321QString QCommandLineOption::valueName() const
322{
323 return d->valueName;
324}
325
326/*!
327 Sets the description used for this option to \a description.
328
329 It is customary to add a "." at the end of the description.
330
331 The description is used by QCommandLineParser::showHelp().
332
333 \sa description()
334 */
335void QCommandLineOption::setDescription(const QString &description)
336{
337 d->description = description;
338}
339
340/*!
341 Returns the description set for this option.
342
343 \sa setDescription()
344 */
345QString QCommandLineOption::description() const
346{
347 return d->description;
348}
349
350/*!
351 Sets the default value used for this option to \a defaultValue.
352
353 The default value is used if the user of the application does not specify
354 the option on the command line.
355
356 If \a defaultValue is empty, the option has no default values.
357
358 \sa defaultValues() setDefaultValues()
359 */
360void QCommandLineOption::setDefaultValue(const QString &defaultValue)
361{
362 QStringList newDefaultValues;
363 if (!defaultValue.isEmpty()) {
364 newDefaultValues.reserve(1);
365 newDefaultValues << defaultValue;
366 }
367 // commit:
368 d->defaultValues.swap(newDefaultValues);
369}
370
371/*!
372 Sets the list of default values used for this option to \a defaultValues.
373
374 The default values are used if the user of the application does not specify
375 the option on the command line.
376
377 \sa defaultValues() setDefaultValue()
378 */
379void QCommandLineOption::setDefaultValues(const QStringList &defaultValues)
380{
381 d->defaultValues = defaultValues;
382}
383
384/*!
385 Returns the default values set for this option.
386
387 \sa setDefaultValues()
388 */
389QStringList QCommandLineOption::defaultValues() const
390{
391 return d->defaultValues;
392}
393
394#if QT_DEPRECATED_SINCE(5, 8)
395/*!
396 Sets whether to hide this option in the user-visible help output.
397
398 All options are visible by default. Setting \a hide to true for
399 a particular option makes it internal, i.e. not listed in the help output.
400
401 \since 5.6
402 \obsolete Use setFlags(QCommandLineOption::HiddenFromHelp), QCommandLineOption::HiddenFromHelp
403 \sa isHidden
404 */
405void QCommandLineOption::setHidden(bool hide)
406{
407 d->flags.setFlag(HiddenFromHelp, hide);
408}
409
410/*!
411 Returns true if this option is omitted from the help output,
412 false if the option is listed.
413
414 \since 5.6
415 \obsolete Use flags() & QCommandLineOption::HiddenFromHelp
416 \sa setHidden(), QCommandLineOption::HiddenFromHelp
417 */
418bool QCommandLineOption::isHidden() const
419{
420 return d->flags & HiddenFromHelp;
421}
422#endif
423
424/*!
425 Returns a set of flags that affect this command-line option.
426
427 \since 5.8
428 \sa setFlags(), QCommandLineOption::Flags
429 */
430QCommandLineOption::Flags QCommandLineOption::flags() const
431{
432 return d->flags;
433}
434
435/*!
436 Set the set of flags that affect this command-line option to \a flags.
437
438 \since 5.8
439 \sa flags(), QCommandLineOption::Flags
440 */
441void QCommandLineOption::setFlags(Flags flags)
442{
443 d->flags = flags;
444}
445
446/*!
447 \enum QCommandLineOption::Flag
448
449 \value HiddenFromHelp Hide this option in the user-visible help output. All
450 options are visible by default. Setting this flag for a particular
451 option makes it internal, i.e. not listed in the help output.
452
453 \value ShortOptionStyle The option will always be understood as a short
454 option, regardless of what was set by
455 QCommandLineParser::setSingleDashWordOptionMode.
456 This allows flags such as \c{-DDEFINE=VALUE} or \c{-I/include/path} to be
457 interpreted as short flags even when the parser is in
458 QCommandLineParser::ParseAsLongOptions mode.
459
460 \sa QCommandLineOption::setFlags(), QCommandLineOption::flags()
461*/
462
463QT_END_NAMESPACE
464