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

Provided by KDAB

Privacy Policy
Start learning QML with our Intro Training
Find out more

source code of qtbase/src/corelib/tools/qcommandlineoption.cpp