args-parser 6.3.6
Loading...
Searching...
No Matches
command.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__COMMAND_HPP__INCLUDED
8#define ARGS__COMMAND_HPP__INCLUDED
9
10// Args include.
11#include "api.hpp"
12#include "context.hpp"
13#include "enums.hpp"
14#include "group_iface.hpp"
15#include "types.hpp"
16#include "utils.hpp"
17#include "value_utils.hpp"
18
19namespace Args
20{
21
22//
23// Command
24//
25
27class Command : public GroupIface
28{
29 friend class CmdLine;
30 friend class HelpPrinter;
31 friend class Help;
32
33public:
34 template<typename T>
35 explicit Command(T &&nm,
37 bool isSubCommandRequired = false)
38 : GroupIface(std::forward<T>(nm))
39 , m_opt(opt)
40 , m_isDefined(false)
41 , m_isSubCommandRequired(isSubCommandRequired)
42 , m_subCommand(nullptr)
43 {
44 if (details::isArgument(name()) || details::isFlag(name())) {
45 throw BaseException(String(SL("Command's name can't "
46 "start with \"-\" whereas you are trying to set name to \""))
47 + name()
48 + SL("\"."));
49 }
50
51 if (name().empty()) {
52 throw BaseException(String(SL("Command can't be with empty name.")));
53 }
54
55 switch (m_opt) {
57 m_valueSpecifier = SL("arg");
58 } break;
59
61 m_valueSpecifier = SL("args");
62 } break;
63
64 default:
65 break;
66 }
67 }
68
69 virtual ~Command()
70 {
71 }
72
74 ArgType type() const override
75 {
76 return ArgType::Command;
77 }
78
80 bool isDefined() const override
81 {
82 return m_isDefined;
83 }
84
86 bool isWithValue() const override
87 {
88 return (m_opt == ValueOptions::OneValue || m_opt == ValueOptions::ManyValues);
89 }
90
92 Command &setRequired(bool on = true) override
93 {
94 UNUSED(on)
95 return *this;
96 }
97
99 const String &valueSpecifier() const override
100 {
101 return m_valueSpecifier;
102 }
103
105 {
106 m_valueSpecifier = vs;
107 return *this;
108 }
109
111 const String &description() const override
112 {
113 return m_description;
114 }
115
117 {
118 m_description = desc;
119 return *this;
120 }
121
123 const String &longDescription() const override
124 {
125 if (!m_longDescription.empty()) {
126 return m_longDescription;
127 } else {
128 return m_description;
129 }
130 }
131
133 {
134 m_longDescription = desc;
135 return *this;
136 }
137
139 const String &value() const
140 {
141 if (!m_values.empty()) {
142 return m_values.front();
143 } else if (!m_defaultValues.empty()) {
144 return m_defaultValues.front();
145 } else {
147 }
148 }
149
151 const StringList &values() const
152 {
153 if (!m_values.empty()) {
154 return m_values;
155 } else {
156 return m_defaultValues;
157 }
158 }
159
161 const String &defaultValue() const override
162 {
163 if (!m_defaultValues.empty()) {
164 return m_defaultValues.front();
165 } else {
167 }
168 }
169
173 {
174 m_defaultValues.push_back(v);
175 return *this;
176 }
177
180 {
181 return m_defaultValues;
182 }
183
186 {
187 m_defaultValues = v;
188 return *this;
189 }
190
194 const String &nm,
196 StringList &possibleNames) const override
197 {
198 bool ret = false;
199
200 if (details::isMisspelledName(nm, name())) {
201 possibleNames.push_back(name());
202
203 ret = true;
204 }
205
206 if (GroupIface::isMisspelledName(nm, possibleNames)) {
207 return true;
208 } else {
209 return ret;
210 }
211 }
212
216 const String &nm,
218 StringList &possibleNames) const
219 {
220 if (details::isMisspelledName(nm, name())) {
221 possibleNames.push_back(name());
222
223 return true;
224 } else {
225 return false;
226 }
227 }
228
230 void clear() override
231 {
232 m_isDefined = false;
233
234 m_values.clear();
235
237 }
238
239 using GroupIface::addArg;
240
242 Command &addArg(ArgPtr arg) override
243 {
244 if (arg->type() == ArgType::Command && m_opt != ValueOptions::NoValue) {
245 throw BaseException(
246 String(SL("Addition of commands to command with "
247 "value is disallowed.")));
248 }
249
250 if (std::find(m_children.cbegin(), m_children.cend(), arg) == m_children.cend()) {
251 if (cmdLine()) {
252 arg->setCmdLine(cmdLine());
253 }
254
255 m_children.push_back(std::move(arg));
256 }
257 return *this;
258 }
259
260protected:
273 const String &n) override
274 {
275 if (name() == n) {
276 return this;
277 } else {
278 return nullptr;
279 }
280 }
281
297 const String &name)
298 {
299 auto *arg = GroupIface::findArgument(name);
300
301 if (!arg && m_subCommand) {
302 return m_subCommand->findChild(name);
303 }
304
305 return arg;
306 }
307
315 Context &ctx) override
316 {
317 m_isDefined = true;
318
319 switch (m_opt) {
321 eatValues(ctx,
322 m_values,
323 String(SL("Command \"")) + name() + SL("\" requires value that wasn't presented."),
324 cmdLine());
325 } break;
326
328 m_values.push_back(
329 eatOneValue(ctx,
330 String(SL("Command \"")) + name() + SL("\" requires value that wasn't presented."),
331 cmdLine()));
332 } break;
333
334 default:
335 break;
336 }
337 }
338
347 StringList &flags,
349 StringList &names) const override
350 {
351 if (details::isCorrectName(name())) {
352 auto it = std::find(names.begin(), names.end(), name());
353
354 if (it != names.end()) {
355 throw BaseException(String(SL("Redefinition of command "
356 "with name \""))
357 + name()
358 + SL("\"."));
359 } else {
360 names.push_back(name());
361 }
362 } else {
363 throw BaseException(String(SL("Disallowed name \"")) + name() + SL("\" for the command."));
364 }
365
366 StringList ftmp = flags;
367 StringList ntmp = names;
368
370 }
371
373 void checkCorrectnessAfterParsing() const override
374 {
375 if (isDefined()) {
377 }
378
379 if (isDefined() && m_isSubCommandRequired && !m_subCommand) {
380 throw BaseException(String(SL("Wasn't defined required sub-command of command \"")) + name() + SL("\"."));
381 }
382 }
383
386 {
387 m_subCommand = sub;
388 }
389
390private:
392
393
394 ValueOptions m_opt;
396 String m_valueSpecifier;
398 String m_description;
400 String m_longDescription;
402 bool m_isDefined;
404 bool m_isSubCommandRequired;
406 StringList m_values;
408 StringList m_defaultValues;
410 Command *m_subCommand;
411}; // class Command
412
413} /* namespace Args */
414
415#endif // ARGS__COMMAND_HPP__INCLUDED
Interface for arguments.
Definition arg_iface.hpp:29
CmdLine * cmdLine() const
Definition arg_iface.hpp:86
Base exception of the library.
Command in the command line interface.
Definition command.hpp:28
ArgIface * findArgument(const String &n) override
Definition command.hpp:268
friend class CmdLine
Definition command.hpp:29
bool isMisspelledCommand(const String &nm, StringList &possibleNames) const
Definition command.hpp:214
Command & setRequired(bool on=true) override
Set required flag.
Definition command.hpp:92
void process(Context &ctx) override
Process argument's staff, for example take values from context.
Definition command.hpp:313
Command & setDescription(const String &desc)
Set description.
Definition command.hpp:116
Command & setLongDescription(const String &desc)
Set long description.
Definition command.hpp:132
ArgIface * findChild(const String &name)
Definition command.hpp:292
bool isDefined() const override
Definition command.hpp:80
void checkCorrectnessBeforeParsing(StringList &flags, StringList &names) const override
Check correctness of the argument before parsing.
Definition command.hpp:345
bool isWithValue() const override
Definition command.hpp:86
ArgType type() const override
Definition command.hpp:74
Command(T &&nm, ValueOptions opt=ValueOptions::NoValue, bool isSubCommandRequired=false)
Definition command.hpp:35
const String & value() const
Definition command.hpp:139
void checkCorrectnessAfterParsing() const override
Check correctness of the argument after parsing.
Definition command.hpp:373
void clear() override
Clear state of the argument.
Definition command.hpp:230
const String & longDescription() const override
Definition command.hpp:123
const StringList & values() const
Definition command.hpp:151
const String & description() const override
Definition command.hpp:111
const StringList & defaultValues() const
Definition command.hpp:179
Command & setValueSpecifier(const String &vs)
Set value specifier.
Definition command.hpp:104
Command & setDefaultValues(const StringList &v)
Set default values.
Definition command.hpp:185
const String & valueSpecifier() const override
Definition command.hpp:99
Command & addArg(ArgPtr arg) override
Add argument.
Definition command.hpp:242
const String & defaultValue() const override
Definition command.hpp:161
friend class Help
Definition command.hpp:31
virtual ~Command()
Definition command.hpp:69
friend class HelpPrinter
Definition command.hpp:30
Command & setDefaultValue(const String &v)
Set default value.
Definition command.hpp:172
bool isMisspelledName(const String &nm, StringList &possibleNames) const override
Definition command.hpp:192
void setCurrentSubCommand(Command *sub)
Set current subcommand.
Definition command.hpp:385
Context is a list of words in the command line that user presented with interface for interacting wit...
Definition context.hpp:36
String name() const override
GroupIface & addArg(ArgIface &arg)
Add argument.
void clear() override
Clear state of the argument.
Arguments m_children
List of children.
bool isMisspelledName(const String &name, StringList &possibleNames) const override
std::unique_ptr< ArgIface, details::Deleter< ArgIface > > ArgPtr
Smart pointer to the argument.
void checkCorrectnessBeforeParsing(StringList &flags, StringList &names) const override
Check correctness of the argument before parsing.
GroupIface(T &&name, bool required=false)
ArgIface * findArgument(const String &name) override
void checkCorrectnessAfterParsing() const override
Check correctness of the argument after parsing.
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
@ Command
Command.
Definition enums.hpp:34
ValueOptions
Options for value property.
Definition enums.hpp:18
@ OneValue
One value.
Definition enums.hpp:22
@ ManyValues
Many values.
Definition enums.hpp:24
@ NoValue
No values.
Definition enums.hpp:20
bool eatValues(Ctx &context, Container &container, const String &errorDescription, Cmd *cmdLine)
Eat values in context.
std::vector< String > StringList
List of strings.
Definition types.hpp:336
static const String c_string
Definition utils.hpp:146
#define SL(str)
Definition types.hpp:328
#define UNUSED(Var)
Macro to supress warning about unused argument.
Definition utils.hpp:34
#define DISABLE_COPY(Class)
Macro for disabling copy.
Definition utils.hpp:25