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