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