ALib C++ Library
Library Version: 2412 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
cliutil.hpp
Go to the documentation of this file.
1//==================================================================================================
2/// \file
3/// This header file is part of module \alib_cli of the \aliblong.
4///
5/// \emoji :copyright: 2013-2024 A-Worx GmbH, Germany.
6/// Published under \ref mainpage_license "Boost Software License".
7//==================================================================================================
8#ifndef HPP_ALIB_CLI_CLIUTIL
9#define HPP_ALIB_CLI_CLIUTIL 1
10#pragma once
14
15
16namespace alib { namespace cli {
17
18//==================================================================================================
19/// This is a friend class of \alib{cli;CommandLine} that exposes a collection of utility methods
20/// useful for CLI applications.
21///
22/// The methods found here are static and receive the friend \b %CommandLine object. They have been
23/// gathered in this class to keep \b %CommandLine tidy and more easily understandable as only
24/// needed methods are found there.
25///
26/// \note
27/// The nature of this class is to provide a basic, standard functionality. It was created while
28/// building a CLI application based on this library and provided for convenience.
29///
30/// Methods found here, might be used as a jump start for own implementations.
31/// Their documentation is considered only fundamental.
32/// For details, please consult the source code.
33//==================================================================================================
35{
36 public:
37 //==============================================================================================
38 /// Searches and if found, retrieves the declaration of the option identified by
39 /// \p{identString} which, if it contains a single character is compared to the
40 /// \alib{cli;OptionDecl::IdentifierChar}. Otherwise, matching is done case insensitive and
41 /// with respecting \alib{cli;OptionDecl::MinimumRecognitionLength}.
42 ///
43 /// This method is useful to implement a help command or option, with an optional "topic"
44 /// parameter.
45 ///
46 /// \note
47 /// If parsing of arguments should be (or has to be) customized, of course this method
48 /// can also be used for implementing such custom code. Otherwise, use method
49 /// \alib{cli;CommandLine::ReadOptions}, which parses and collects options in filed
50 /// \alib{cli;CommandLine::Options}.
51 ///
52 /// \see Methods #GetCommandDecl, #GetParameterDecl.
53 ///
54 /// @param cmdLine The friend object we work on.
55 /// @param identString The identifier string of the option to search. If this is a single
56 /// character, the short identifier is searched.
57 /// @return The object of type \alib{cli;OptionDecl}. \c nullptr if not found.
58 //==============================================================================================
59 static ALIB_API
60 OptionDecl* GetOptionDecl( CommandLine& cmdLine, const String& identString );
61
62 //==============================================================================================
63 /// Searches and if found, retrieves the declaration of the command identified by
64 /// \p{identString}. Matching is done case insensitive and with respecting
65 /// \alib{cli;CommandDecl::MinimumRecognitionLength}.
66 ///
67 /// This method is useful to implement a help command or option, with an optional "topic"
68 /// parameter.
69 ///
70 /// \note
71 /// If parsing of arguments should be (or has to be) customized, of course this method
72 /// can also be used for implementing such custom code. Otherwise, use
73 /// \alib{cli;CommandLine::NextCommand} to retrieve command objects (instead of command
74 /// declarations).
75 ///
76 /// \see Methods #GetOptionDecl, #GetParameterDecl.
77 ///
78 /// @param cmdLine The friend object we work on.
79 /// @param identString The identifier of the command to search.
80 /// @return The object of type \alib{cli;CommandDecl}. \c nullptr if not found.
81 //==============================================================================================
82 static ALIB_API
83 CommandDecl* GetCommandDecl( CommandLine& cmdLine, const String& identString );
84
85 //==============================================================================================
86 /// Searches and if found, retrieves the declaration of the parameter identified by
87 /// \p{identString}. Matching is done case insensitive and with respecting
88 /// \alib{cli;CommandDecl::MinimumRecognitionLength}.
89 ///
90 /// This method is useful to implement a help command (or option), with an optional "topic"
91 /// parameter.
92 ///
93 /// \see Methods #GetOptionDecl, #GetCommandDecl.
94 ///
95 /// @param cmdLine The friend object we work on.
96 /// @param identString The identifier of the command to search.
97 /// @return The object of type \alib{cli;CommandDecl}. \c nullptr if not found.
98 //==============================================================================================
99 static ALIB_API
100 ParameterDecl* GetParameterDecl( CommandLine& cmdLine, const String& identString );
101
102
103 //==============================================================================================
104 /// Returns an AString providing a formatted help text on the defined command.
105 /// @param cmdLine The command line instance.
106 /// @param commandDecl The declaration of the command to get help on.
107 /// @return The help text.
108 //==============================================================================================
109 static ALIB_API
110 AString GetCommandUsageFormat( CommandLine& cmdLine, CommandDecl& commandDecl );
111
113 //==============================================================================================
114 /// Translates exceptions thrown by the \alib_cli_nl library to exit codes defined with
115 /// \alib{cli;CommandLine::DefineExitCodes}.
116 ///
117 /// If the code is not found, this indicates an error in the resource data, as an exit
118 /// code corresponding to the \alib_cli_nl exceptions is obviously missing.
119 /// In this case, \c -1 is returned. With debug-builds an \alib assertion is raised.
120 ///
121 /// @param cmdLine The friend object we work on.
122 /// @param exception The cli exception caught.
123 /// @return The exit code to return to the caller. \c -1, if not found.
124 //==============================================================================================
125 static ALIB_API
126 integer GetExitCode( CommandLine& cmdLine, Exception& exception )
127 {
128 auto element= exception.Type().Get<cli::Exceptions>();
129 for( auto exitCodeDecl : cmdLine.ExitCodeDecls )
130 if( exitCodeDecl.second->AssociatedCLIException() == element )
131 return exitCodeDecl.first.Integral();
132 ALIB_ERROR( "CLI", "No exit code associated with {}.", element )
133 return -1;
134 }
136
137 //==============================================================================================
138 /// Creates a help text from the resource strings.
139 ///
140 /// This method accepts either a command object or an option object that the command line
141 /// instance uses to process help requests. Only one of the objects has to be provided, the
142 /// other has to be \c nullptr.
143 ///
144 /// If no argument is set in \p{helpCmd} (respectively \p{helpOpt}), the next argument is peeked
145 /// and checked to be a command, option, parameter or special help topic found in resource
146 /// string "HlpAddnlTopics".
147 ///
148 /// If found, the argument is consumed and stored in \p{helpCmd} (respectively \p{helpOpt}).
149 /// If not, the general help text is generated.
150 ///
151 /// @param cmdLine The command line instance.
152 /// @param helpCmd The command to write the help text for.
153 /// @param helpOpt The option to write the help text for.
154 /// @param text The target text.
155 /// @return \c true on success. \c false if an argument was given that is not recognized or
156 /// if a topic list was found in the next argument where only some of the topics
157 /// could be identified.
158 //==============================================================================================
159 static ALIB_API
160 bool GetHelp( CommandLine& cmdLine, Command* helpCmd, Option* helpOpt, Paragraphs& text );
161
162 //==============================================================================================
163 /// Reads a dry-run options and stores the result in \alib{cli;CommandLine::DryRun}.
164 ///
165 /// Option arguments as defined with records of enumeration \alib{cli;DryRunModes} are
166 /// accepted. These records are resourced and default to:
167 /// \snippet "alib/cli/clicamp.cpp" DOX_CLI_DRYRUN_RESOURCES
168 ///
169 /// If no argument is set in the given \p{dryOpt}, the next unread CLI-argument is checked
170 /// for being parsable as an element of enum \b DryRunModes. If yes, the CLI-argument is
171 /// consumed and duly stored in \p{dryOpt}.<br>
172 /// In case no argument was set (or successfully peeked), \alib{cli;DryRunModes::Application} is
173 /// chosen and stored.
174 ///
175 /// If one of the modes offered by enumeration \b DryRunModes should not be recognizable,
176 /// three ways of implementing this exist:
177 /// 1. Do not use this method but implement a custom version. In case that only
178 /// \alib{cli;DryRunModes::Application} should be accepted, instead calling this util method,
179 /// simply set field \alib{cli;CommandLine::DryRun} to this value.
180 /// 2. Check for the "forbidden" argument type after the invocation of this method and
181 /// exit your cli app
182 /// 3. Modify this module's resource string <b>"CLI/DRM"</b> to not contain the suppressed
183 /// argument's record. (With that, the defaulted argument names can also be modified).
184 ///
185 /// By modifying the resource string, it is also possible to add custom options. Remeber, that
186 /// it is allowed in C++ to have an enum element evaluate to any integral, regardless
187 /// whether it is defined in the C++ definition or not.
188 ///
189 /// @param cmdLine The command line instance.
190 /// @param dryOpt The option object parsed.
191 /// @return \c true on success. \c false if an argument was given that is not recognized.
192 //==============================================================================================
193 static ALIB_API
194 bool GetDryOpt( CommandLine& cmdLine, Option& dryOpt );
195
196 //==============================================================================================
197 /// Dumps the configuration.
198 /// Shows which commands, options, parameters and errors are set with enums and their
199 /// meta info.
200 /// Useful during development.
201 ///
202 /// @param cmdLine The friend object we work on.
203 /// @param text The target text.
204 /// @return An internal \c AString object containing the dump text. (Beware of concurrent
205 /// debugging threads :-)
206 //==============================================================================================
207 static ALIB_API
209
210 //==============================================================================================
211 /// Write in human-readable form, which commands and options have been read from the
212 /// command line.
213 ///
214 /// This is useful for debugging as well as to implement a "dry run" option of the
215 /// CLI application, that offers the user a list of what is parsed with a given set of
216 /// CLI arguments. In this case, method read \alib{cli;CommandLine::ReadNextCommands} should
217 /// be invoked after the provisions of the various definitions.
218 ///
219 /// Probably, depending on the command syntax, not all commands can be parsed prior
220 /// to executing them. However, options can.
221 ///
222 /// @param cmdLine The friend object we work on.
223 /// @param text The target text.
224 /// @returns Returns an internal \c AString object containing the dump text.
225 /// (Beware of concurrent debugging threads :-)
226 //==============================================================================================
227 static ALIB_API
229};
230
231} // namespace alib[::cli]
232
233/// Type alias in namespace \b alib.
235
236
237} // namespace [alib]
238
239
240
241#endif // HPP_ALIB_CLI_CLIUTIL
242
static ALIB_API CommandDecl * GetCommandDecl(CommandLine &cmdLine, const String &identString)
Definition cliutil.cpp:33
static ALIB_API integer GetExitCode(CommandLine &cmdLine, Exception &exception)
Definition cliutil.hpp:126
static ALIB_API ParameterDecl * GetParameterDecl(CommandLine &cmdLine, const String &identString)
Definition cliutil.cpp:42
static ALIB_API OptionDecl * GetOptionDecl(CommandLine &cmdLine, const String &identString)
Definition cliutil.cpp:21
static ALIB_API AString & DumpDeclarations(CommandLine &cmdLine, Paragraphs &text)
Definition cliutil.cpp:331
static ALIB_API bool GetHelp(CommandLine &cmdLine, Command *helpCmd, Option *helpOpt, Paragraphs &text)
Definition cliutil.cpp:75
static ALIB_API AString GetCommandUsageFormat(CommandLine &cmdLine, CommandDecl &commandDecl)
Definition cliutil.cpp:52
static ALIB_API AString & DumpParseResults(CommandLine &cmdLine, Paragraphs &text)
Definition cliutil.cpp:454
static ALIB_API bool GetDryOpt(CommandLine &cmdLine, Option &dryOpt)
Definition cliutil.cpp:293
HashMap< MonoAllocator, Enum, ExitCodeDecl * > ExitCodeDecls
Possible Errors.
ALIB_API const Enum & Type() const
#define ALIB_API
Definition alib.hpp:639
#define ALIB_ERROR(...)
Definition alib.hpp:1267
Definition alib.cpp:69
lang::integer integer
Type alias in namespace alib.
Definition integers.hpp:273
TEnum Get() const
A command of a ALib CLI command line.