args-parser 6.3.6
Loading...
Searching...
No Matches
arg.hpp
Go to the documentation of this file.
1
2/*
3 SPDX-FileCopyrightText: 2026 Igor Mironchik <igor.mironchik@gmail.com>
4 SPDX-License-Identifier: MIT
5*/
6
7#ifndef ARGS__ARG_HPP__INCLUDED
8#define ARGS__ARG_HPP__INCLUDED
9
10// Args include.
11#include "arg_iface.hpp"
12#include "context.hpp"
13#include "exceptions.hpp"
14#include "types.hpp"
15#include "utils.hpp"
16#include "value_utils.hpp"
17
18// C++ include.
19#include <algorithm>
20
21namespace Args
22{
23
24//
25// Arg
26//
27
32class Arg : public ArgIface
33{
34public:
36 template<typename T>
37 Arg(
39 Char flag,
41 T &&name,
43 bool isWithValue = false,
45 bool isRequired = false);
46
48 explicit Arg(
50 Char flag,
52 bool isWithValue = false,
54 bool isRequired = false);
55
57 template<typename T>
58 explicit Arg(
60 T &&name,
62 bool isWithValue = false,
64 bool isRequired = false);
65
66 virtual ~Arg();
67
69 ArgType type() const override
70 {
71 return ArgType::Arg;
72 }
73
80 String name() const override;
81
83 bool isWithValue() const override;
85 Arg &setWithValue(bool on = true);
86
88 bool isRequired() const override;
90 Arg &setRequired(bool on = true);
91
93 bool isDefined() const override;
95 Arg &setDefined(bool on = true);
96
98 virtual const String &value() const;
100 virtual Arg &setValue(const String &v);
101
103 const String &flag() const override;
105 Arg &setFlag(Char f);
106
108 const String &argumentName() const override;
111
113 const String &valueSpecifier() const override;
115 Arg &setValueSpecifier(const String &vs);
116
118 const String &description() const override;
120 Arg &setDescription(const String &desc);
121
123 const String &longDescription() const override;
125 Arg &setLongDescription(const String &desc);
126
128 const String &defaultValue() const override
129 {
130 return m_defaultValue;
131 }
132
134 virtual Arg &setDefaultValue(const String &v)
135 {
136 m_defaultValue = v;
137 return *this;
138 }
139
143 const String &name,
145 StringList &possibleNames) const override
146 {
147 if (!argumentName().empty()) {
148 if (details::isMisspelledName(name, String(SL("--")) + argumentName())) {
149 possibleNames.push_back(String(SL("--")) + argumentName());
150
151 return true;
152 }
153 }
154
155 return false;
156 }
157
159 void clear() override
160 {
161 setDefined(false);
162
163 m_value.clear();
164 }
165
166protected:
180 const String &name) override
181 {
182 if (details::isArgument(name) && name.substr(2) == m_name) {
183 return this;
184 } else if (details::isFlag(name) && name.substr(1) == m_flag) {
185 return this;
186 } else {
187 return nullptr;
188 }
189 }
190
196 void process(
198 Context &context) override;
199
208 StringList &flags,
210 StringList &names) const override;
211
213 void checkCorrectnessAfterParsing() const override;
214
215private:
217
218
219 bool m_isWithValue;
221 bool m_isRequired;
223 bool m_isDefined;
225 String m_value;
227 String m_flag;
229 String m_name;
231 String m_valueSpecifier;
233 String m_description;
235 String m_longDescription;
237 String m_defaultValue;
238}; // class Arg
239
240//
241// Arg
242//
243
244template<typename T>
246 T &&name,
247 bool isWithValue,
248 bool isRequired)
249 : m_isWithValue(isWithValue)
250 , m_isRequired(isRequired)
251 , m_isDefined(false)
252 , m_flag(1,
253 flag)
254 , m_name(std::forward<T>(name))
255 , m_valueSpecifier(SL("arg"))
256{
257}
258
260 bool isWithValue,
261 bool isRequired)
262 : m_isWithValue(isWithValue)
263 , m_isRequired(isRequired)
264 , m_isDefined(false)
265 , m_flag(1,
266 flag)
267 , m_valueSpecifier(SL("arg"))
268{
269}
270
271template<typename T>
273 bool isWithValue,
274 bool isRequired)
275 : m_isWithValue(isWithValue)
276 , m_isRequired(isRequired)
277 , m_isDefined(false)
278 , m_name(std::forward<T>(name))
279 , m_valueSpecifier(SL("arg"))
280{
281}
282
283inline Arg::~Arg()
284{
285}
286
287inline void Arg::process(Context &context)
288{
289 if (!isDefined()) {
290 if (!isWithValue()) {
291 setDefined(true);
292 } else {
293 setValue(eatOneValue(context,
294 String(SL("Argument \"")) + name() + SL("\" requires value that wasn't presented."),
295 cmdLine()));
296
297 setDefined(true);
298 }
299 } else {
300 throw BaseException(String(SL("Argument \"")) + name() + SL("\" already defined."));
301 }
302}
303
304inline String Arg::name() const
305{
306 if (!m_name.empty()) {
307 return SL("--") + m_name;
308 } else {
309 return SL("-") + m_flag;
310 }
311}
312
314 StringList &names) const
315{
316 if (!m_flag.empty()) {
317 if (details::isCorrectFlag(m_flag)) {
318 const String flag = String(SL("-")) + m_flag;
319
320 auto it = std::find(flags.begin(), flags.end(), flag);
321
322 if (it != flags.end()) {
323 throw BaseException(String(SL("Redefinition of argument "
324 "with flag \""))
325 + flag
326 + SL("\"."));
327 } else {
328 flags.push_back(flag);
329 }
330 } else {
331 throw BaseException(String(SL("Disallowed flag \"-")) + m_flag + SL("\"."));
332 }
333 }
334
335 if (!m_name.empty()) {
336 if (details::isCorrectName(m_name)) {
337 const String name = String(SL("--")) + m_name;
338
339 auto it = std::find(names.begin(), names.end(), name);
340
341 if (it != names.end()) {
342 throw BaseException(String(SL("Redefinition of argument "
343 "with name \""))
344 + name
345 + SL("\"."));
346 } else {
347 names.push_back(name);
348 }
349 } else {
350 throw BaseException(String(SL("Disallowed name \"--")) + m_name + SL("\"."));
351 }
352 }
353
354 if (m_flag.empty() && m_name.empty()) {
355 throw BaseException(
356 String(SL("Arguments with empty flag and name "
357 "are disallowed.")));
358 }
359}
360
362{
363 if (isRequired() && !isDefined()) {
364 throw BaseException(String(SL("Undefined required argument \"")) + name() + SL("\"."));
365 }
366}
367
368inline bool Arg::isWithValue() const
369{
370 return m_isWithValue;
371}
372
373inline Arg &Arg::setWithValue(bool on)
374{
375 m_isWithValue = on;
376 return *this;
377}
378
379inline bool Arg::isRequired() const
380{
381 return m_isRequired;
382}
383
384inline Arg &Arg::setRequired(bool on)
385{
386 m_isRequired = on;
387 return *this;
388}
389
390inline bool Arg::isDefined() const
391{
392 return m_isDefined;
393}
394
395inline Arg &Arg::setDefined(bool on)
396{
397 m_isDefined = on;
398 return *this;
399}
400
401inline const String &Arg::value() const
402{
403 if (!m_value.empty()) {
404 return m_value;
405 } else {
406 return m_defaultValue;
407 }
408}
409
410inline Arg &Arg::setValue(const String &v)
411{
412 m_value = v;
413 return *this;
414}
415
416inline const String &Arg::flag() const
417{
418 return m_flag;
419}
420
422{
423 m_flag = String(1, f);
424 return *this;
425}
426
427inline const String &Arg::argumentName() const
428{
429 return m_name;
430}
431
433{
434 m_name = name;
435 return *this;
436}
437
438inline const String &Arg::valueSpecifier() const
439{
440 return m_valueSpecifier;
441}
442
444{
445 m_valueSpecifier = vs;
446 return *this;
447}
448
449inline const String &Arg::description() const
450{
451 return m_description;
452}
453
454inline Arg &Arg::setDescription(const String &desc)
455{
456 m_description = desc;
457 return *this;
458}
459
460inline const String &Arg::longDescription() const
461{
462 if (!m_longDescription.empty()) {
463 return m_longDescription;
464 } else {
465 return m_description;
466 }
467}
468
470{
471 m_longDescription = desc;
472 return *this;
473}
474
475} /* namespace Args */
476
477#endif // ARGS__ARG_HPP__INCLUDED
Argument with one value that can be present only once in the command line.
Definition arg.hpp:33
const String & flag() const override
Definition arg.hpp:416
Arg & setLongDescription(const String &desc)
Set long description.
Definition arg.hpp:469
virtual const String & value() const
Definition arg.hpp:401
ArgType type() const override
Definition arg.hpp:69
const String & valueSpecifier() const override
Definition arg.hpp:438
String name() const override
Definition arg.hpp:304
bool isDefined() const override
Definition arg.hpp:390
Arg & setValueSpecifier(const String &vs)
Set value specifier.
Definition arg.hpp:443
bool isRequired() const override
Definition arg.hpp:379
void checkCorrectnessBeforeParsing(StringList &flags, StringList &names) const override
Check correctness of the argument before parsing.
Definition arg.hpp:313
Arg & setDefined(bool on=true)
Set defined.
Definition arg.hpp:395
Arg & setWithValue(bool on=true)
Set is this argument with value.
Definition arg.hpp:373
bool isMisspelledName(const String &name, StringList &possibleNames) const override
Definition arg.hpp:141
virtual Arg & setDefaultValue(const String &v)
Set default value.
Definition arg.hpp:134
void process(Context &context) override
Process argument's staff, for example take values from context.
Definition arg.hpp:287
bool isWithValue() const override
Definition arg.hpp:368
Arg & setFlag(Char f)
Set flag.
Definition arg.hpp:421
Arg & setArgumentName(const String &name)
Set argument name.
Definition arg.hpp:432
Arg(Char flag, T &&name, bool isWithValue=false, bool isRequired=false)
Construct argument with flag and name.
Definition arg.hpp:245
virtual Arg & setValue(const String &v)
Set value.
Definition arg.hpp:410
const String & argumentName() const override
Definition arg.hpp:427
Arg & setDescription(const String &desc)
Set description.
Definition arg.hpp:454
const String & longDescription() const override
Definition arg.hpp:460
void clear() override
Clear state of the argument.
Definition arg.hpp:159
void checkCorrectnessAfterParsing() const override
Check correctness of the argument after parsing.
Definition arg.hpp:361
const String & description() const override
Definition arg.hpp:449
ArgIface * findArgument(const String &name) override
Definition arg.hpp:175
const String & defaultValue() const override
Definition arg.hpp:128
Arg & setRequired(bool on=true)
Set required.
Definition arg.hpp:384
virtual ~Arg()
Definition arg.hpp:283
CmdLine * cmdLine() const
Definition arg_iface.hpp:86
Base exception of the library.
Context is a list of words in the command line that user presented with interface for interacting wit...
Definition context.hpp:36
Definition api.hpp:18
String eatOneValue(Ctx &context, const String &errorDescription, Cmd *cmdLine)
Eat one value.
std::string String
String type.
Definition types.hpp:314
ArgType
Type of the argument.
Definition enums.hpp:32
@ Arg
Argument.
Definition enums.hpp:36
String::value_type Char
Char type.
Definition types.hpp:317
std::vector< String > StringList
List of strings.
Definition types.hpp:336
#define SL(str)
Definition types.hpp:328
#define DISABLE_COPY(Class)
Macro for disabling copy.
Definition utils.hpp:25