ALib C++ Framework
by
Library Version: 2605 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
app.hpp
Go to the documentation of this file.
1//==================================================================================================
2/// \file
3/// This header-file is part of module \alib_app of the \aliblong.
4///
5/// Copyright 2013-2026 A-Worx GmbH, Germany.
6/// Published under #"mainpage_license".
7//==================================================================================================
8ALIB_EXPORT namespace alib { namespace app {
9
10//==================================================================================================
11/// This is a central class of library module \alib_app_nl.
12///
13/// For information about general use and features of this class consult the
14/// #"alib::app;ALib App User Manual".
15//==================================================================================================
16class App {
17 protected:
18 friend class AppCamp;
19
20 /// Built-in commands used with class #"App".
21 enum class Commands {
22 Help = 1, ///< Show help text.
23 Version = 2, ///< Show version information.
24 Info = 3, ///< Show info and configuration details.
25 };
26
27 /// Built-in options used with class #"App".
28 enum class Options {
29 Help = 1, ///< Alternative to command 'help' as many people are used to
30 ///< pass the help command as an option.
31 Version = 2, ///< Alternative to command 'version' as many people are used to
32 ///< pass the version command as an option.
33 DryRun = 3, ///< Sets the flag #"App::dryrun".
34 Config = 4, ///< Change the configured config file path(s).
35 Verbose = 5, ///< Reserved option for increasing verbosity.
36 };
37
38 /// Built-in parameters of commands and options used with class #"App".
39 enum class Parameters {
40 Topic = 1, ///< Used with command \e help to optionally denote a help topic.
41 };
42
43 /// Built-in exit-codes of the \alib application.
44 /// The codes are mostly generated in the method #".exceptionToExitCode", where
45 /// #"CLIExceptions;exceptions thrown by the CLI implementation" are translated to these
46 /// codes.<br>
47 /// In the case that an application desires to use different exit codes, the latter method has
48 /// to be overridden.
49 ///
50 /// This enumeration gets the according #"alib_enums_records;ALib Enum Records" assigned
51 /// as well as the #"alib_app_cli_candp_defines;resources describing the exit error".
52 enum class ExitCodes {
53 OK = 0, ///< Success.
54 ErrNoCmdGiven = 1, ///< No command given.
55 ErrUnknownCommand = 2, ///< Unknown command.
56 ErrParsingOption = 3, ///< Error when parsing an option.
57 ErrParsingCommand = 4, ///< Error when parsing a command.
58 ErrMissingCmdParam = 5, ///< Missing parameter of a command.
59 ErrMissingOptParam = 6, ///< Missing parameter of an option.
60 ErrBadParamValue = 7, ///< Bad parameter value.
61 ErrConfigFileNotFound = 10, ///< The default configuration file(s), or that (those)
62 ///< specified by option '--config', could not be found
63 ///< or read.
64 ErrConfigFileNotWritable= 11, ///< The configuration file(s) could not be written.
65 ErrUnknown = 127, ///< An unknown exception occurred. This should never happen.
66 };
67
68
69 public:
70 //================================================================================================
71 // App Inner Types
72 //================================================================================================
73
74 //=========================================== Exceptions =========================================
75 /// Generic Exceptions handled by class #"App".
76 /// This enumeration contains only one single entry.
77 enum class Exceptions {
78 /// This exception is used to support the exception/error/exit code paradigm introduced
79 /// by class #"App".
80 /// @see A detailed description on the usage of this exception is given in chapter
81 /// #"alib_app_controlledearlyexit" of the Programmer's Manual of the
82 /// module \alib_app.
84 };
85
86
87 //=========================================== ExitCodes ==========================================
88
89
90 protected:
91 //============================================= Flags ============================================
92 /// Configuration flags used with class #"App".
93 enum class Flags {
94 /// No flags set.
95 NONE = 0 ,
96
97 /// If set, method #"App::onBsSetupALox;*" will create a release #"Lox"
98 /// instance available via field #"App::GetRLox;*", as well as an attached logger
99 /// available via field #"App::GetRLogger;*".
101
102 /// If set, method #"App::onBsSetupALox;*" will create and attach the release
103 /// logger to the debug #"%Lox" #"Lox".
105
106 /// If set, method #"App::onSdExportConfig;*" adds 'ExportAll' and 'writeback' to the
107 /// verbosity variable of the #"App::releaseLogger;*" in the case that this variable
108 /// had not been read from the INI file with #"App::onBsImportConfig;*".
110
111 /// If set, method #"App::onSdExportConfig;*" adds 'ExportAll' and 'writeback' to
112 /// the verbosity variable of the debug-logger in the case that this variable had not been
113 /// read from the INI file with #"App::onBsImportConfig;*".
115 };
116
117
118 //============================================= States ===========================================
119 /// The predefined states of the simple linear state-machine implemented by outer class #"App".
120 /// For each state, a corresponding virtual function exists.
121 /// The pairs of states and the corresponding virtual functions are collected in the field
122 /// #"StateMachine::Program;2".<br>
123 /// Custom applications (derived from class #"%App") define their own enum type in case they
124 /// want to insert additional pairs of state/methods into the program.
125 /// This is possible because the collection of states in the field
126 /// #"StateMachine::Program;2" is implemented as type #"boxing::Enum", which may
127 /// hold enumeration elements of an arbitrary type.
128 ///
129 /// Note that the numbering of the enum elements is \b not of importance. The numbers
130 /// found here were chosen to be quickly identifiable while debugging.
131 /// The simple scheme is:
132 /// - 1x: Bootstrap phase resources. (See also #"BootstrapPhases;2").
133 /// - 2x: Bootstrap phase configuration/variables.
134 /// - 3x: Bootstrap phase finalization.
135 /// - 1xx: running phase.
136 /// - 9xx: shutdown phase. (See also #"ShutdownPhases;2").
137 ///
138 /// Also, the numbers are \b not defining the order of execution, which is solely defined by
139 /// the order in the vector #"StateMachine::Program;2".<br>
140 ///
141 /// The custom enumeration type used for potential custom states may but does not need to
142 /// align. It even may have the same integral values as given here. This flexibility is
143 /// gained by the little magic of class #"boxing::Enum" introduced by module \alib_boxing.
144 enum class States {
145 /// Initial state before starting the App.
146 NOT_STARTED = 0, ///< The starting state not associated with a method.
147
148 //---------------------------------- initialize resources --------------------------------
149 SetCamps =1100 , ///< Invokes the virtual method #"onBsSetCamps".
150 PrepareResources =1200 , ///< Invokes the virtual method #"onBsPrepareResources".
151 SetNameVersionAndInfo=1300 , ///< Invokes the virtual method #"onBsSetNameVersionAndInfo".
152 // 3
153 //------------------------ Initialize camps on configuration level -----------------------
154 PrepareConfig =2100, ///< Invokes the virtual method #"onBsPrepareConfig".
155 PreloadVariables =2200, ///< Invokes the virtual method #"onBsPreloadVariables".
156 CLIDefine =2300, ///< Invokes the virtual method #"onBsCLIDefine".
157 CLIReadOptions =2400, ///< Invokes the virtual method #"onBsCLIReadOptions".
158 ImportConfig =2500, ///< Invokes the virtual method #"onBsImportConfig".
159 ConfigureCLI =2600, ///< Invokes the virtual method #"onBsConfigureCLI".
160 // 9
161
162 //--------------------------- After alib::BootstrapPhases::Final -------------------------
163 FinalizeBootstrap =3100, ///< Invokes the virtual method #"onBsFinalizeBootstrap".
164 ReadDryRunOption =3200, ///< Invokes the virtual method #"onBsReadDryRunOption".
165 SetupALox =3300, ///< Invokes the virtual method #"onBsSetupALox".
166 // 12
167
168 //------------------------------------ The custom code -----------------------------------
169 RunStart =5000, ///< Invokes the virtual method #"onRunStart".
170 Run =5100, ///< Invokes the virtual method #"onRun".
171 RunEnd =5200, ///< Invokes the virtual method #"onRunEnd".
172 // 15
173
174 //---------------------------------------- Shutdown --------------------------------------
175 AnnounceShutdown =9100, ///< Invokes the virtual method #"onSdAnnounceShutdown".
176 CleanALox =9200, ///< Invokes the virtual method #"onSdCleanALox".
177 ExportConfig =9300, ///< Invokes the virtual method #"onSdExportConfig".
178 Output =9400, ///< Invokes the virtual method #"onSdOutput".
179 FinalizeShutdown =9500, ///< Invokes the virtual method #"onSdFinalizeShutdown".
180 // 20
181 };
182
183 //========================================== StateMachine ========================================
184 /// This struct is used a single time with the member #"App::machine" and comprises all
185 /// fields associated with the state of the application and the execution of the 'program'.
187
188 //=================================== StateMachine::Command ==================================
189 /// A struct denoting the next state and the corresponding method to execute.
190 struct Command {
191 /// A union holding either a pointer to a virtual method of class #"%App" or one to
192 /// a non-virtual method of a different type.
194 /// A pointer to a virtual method of class #"%App".
195 void (App::*BuiltIn)();
196
197 /// A pointer to a method of a custom derived type.
198 void (*Custom )(App&);
199
200 /// Constructor accepting a pointer to a virtual method of class #"%App".
201 /// @param method The method to call.
202 MethodPointer( void (App::*method)() ) : BuiltIn(method) {}
203
204 /// Constructor accepting a pointer to a non-virtual method of a derived type.
205 /// @param method The non-virtual method of a derived type.
206 MethodPointer( void ( *method)(App&) ) : Custom (method) {}
207 };
208
209 /// The identifier of the command which is likewise the state of the machine.
210 /// The underlying integral enumeration value determines the order of execution.
211 /// During execution, this identifier will be stored in the member
212 /// #"StateMachine::State" of the outer class #"%StateMachine".
213 /// In case it is a built-in identifier of type #"App::States", it will
214 /// be stored in addition in the field #"App::StateMachine::BuiltInState".
216
217 /// A pointer union to either a built-in virtual method or a method of the custom
218 /// derived type.
220 };
221
222 //================================= StateMachine::CommandList ================================
223 /// A list of pairs of states and corresponding methods to process.
224 /// This struct is used only once, namely with the field #"StateMachine::Program;2".
225 /// The constructor of class #"%App" fills this list with all commands defined in the
226 /// enumeration #"App::States;*".
227 /// While the insertion method #".Add" is provided for convenience, more complex
228 /// manipulation of the list is allowed using the interface inherited from
229 /// <c>std::vector</c>.<br>
230 /// The list will be sorted at the start of method #"App::Main;2".
231 /// Consequently all commands have to be added prior to its invocation.
232 struct CommandList : std::vector<Command> {
233
234 /// Adds a custom execution command to this list.
235 /// Creates a custom command, i.e. a command that is not built-in and as such is not
236 /// executing one of the pre-defined virtual methods of class #"App".<br>
237 /// Instead, it is executing a member of the given type \p{TDerived}, which is usually
238 /// the descendant singleton-type, that implements the custom application.
239 /// \note For technical reasons, the invocation of this static function is a little
240 /// counter-intuitive. The two template parameters have to be explicitly provided,
241 /// where the second is the address of the custom method! (This is C++20 magic).
242 /// The only normal parameter then is the custom enumeration element.
243 /// @see A code sample is provided in chapter #"alib_app_app_statemachine" of the
244 /// Programmer's Manual of this module.
245 /// @tparam TDerived The enclosing type of the method. This usually is the
246 /// custom implementation type of class #"%App".
247 /// @tparam TMethodAddress The address of the member which is to be called with this
248 /// command.
249 /// @param state The enum element (of a custom type) to identify the command
250 /// and define the state of the machine during execution.
251 template<typename TDerived, auto TMethodAddress >
252 void Add(Enum state) {
253
254 struct Helper {
255 static void Wrapper(App& base) {
256 auto& self = static_cast<TDerived&>(base);
257 (self.*TMethodAddress)();
258 }
259 };
260
261 push_back({ state, &Helper::Wrapper });
262 }
263
264 };
265
266 //==================================== StateMachine Fields ===================================
267 protected:
268 /// The exit code. Only the first set is stored and returned later.
270
271 #if ALIB_DEBUG
272 /// This vector collects exit codes which are not used, as they got set
273 /// after a first code was given. This field is available in debug-compilations only.
274 std::vector<Enum> dbgFurtherExitCodes;
275 #endif
276
277 //=================================== StateMachine Interface =================================
278 public:
279 /// The list of commands to execute.
281
282 /// The current state in respect to the built-in program commands. Note that this is
283 /// not of type #"boxing::Enum", but uses the original C++ enum type.
284 /// Consequently, this is only updated when a built-in command is processed.
285 /// With that, methods may check for a more general state without getting "confused"
286 /// by custom insertions which often are not relevant for the decision-making.
288
289 /// The current state. Either a built-in state enumeration or a custom one.
290 /// @see Field #".BuiltInState", which is more appropriate to use in most cases.
292
293 /// Emergency stopper. As soon as this gets set, the execution of the application
294 /// will stop. The only thing that is still performed is the standard
295 /// #"alib::Shutdown;ALib shutdown procedure", but not the shutdown procedure defined
296 /// by this app (or its derived type). I.e., no configuration files are written.
297 bool EmergencyStop =false;
298
299 /// Sets this applications' cli-exit code (the result of the method \c main()).
300 /// If the given \p{pExitCode}'s integral value is \c 0, nothing is done.
301 ///
302 /// Only the value of the first call is used. Later calls will not overwrite the first
303 /// given value. In debug-builds, the method #".DbgDumpFurtherExitCodes" may be used
304 /// to display later given codes, what the default implementation of the method
305 /// #"App::onSdFinalizeShutdown;*" does.
306 /// @param pExitCode The exit code to set.
307 ///
308 void SetExitCode(Enum pExitCode) {
309 if ( pExitCode.Integral() == 0)
310 return;
311
312 if ( exitCode.IsNull() || exitCode.Integral() == 0 )
313 exitCode= pExitCode;
314 #if ALIB_DEBUG
315 else
316 dbgFurtherExitCodes.push_back(pExitCode);
317 #endif
318 }
319
320 /// Returns this applications' cli-exit code (the result of the method \c main()).
321 /// @return The first value given with #".SetExitCode".
323
324 /// Writes exit codes not respected by the method #".SetExitCode" (because an earlier code
325 /// was already set) to the \p{target} string. Then clears the debug-field
326 /// #".dbgFurtherExitCodes".
327 /// This method is called by the default implementations of the methods
328 /// #"App::exceptionDisplay;2" and #"onSdOutput"<br>.
329 /// In release-builds, this method is pruned.
330 /// @param target The target string.
332 #if ALIB_DEBUG
333 for ( auto& ec : dbgFurtherExitCodes )
334 target << "Unused (later) exit-code: " << ec << NEW_LINE;
335 dbgFurtherExitCodes.clear();
336 #else
337 (void) target;
338 #endif
339 }
340 };
341
342 //====================================== ConfigFileDescriptor ====================================
343 /// A record collecting information about configuration files. A vector of this type is
344 /// created by the method #"App::getConfigFilePaths;*".
346 /// The resolved full path to the file.
348
349 /// A comma-separated list of variables (and especially variable tree paths) to be
350 /// explicitly exported to this configuration file.
352
353 /// The files' main comment to set, in case it does not exist, yet.
355
356 /// If set, the file name (and maybe path) came from option '--CONFIG'.
357 bool FromCfgOption =false;
358
359 /// If set, the file did not exist or was empty at the start of the application.
360 bool WasEmpty =false;
361 };
362
363
364 //================================================================================================
365 // App Fields
366 //================================================================================================
367
368 /// The state-machine singleton.
370
371 /// A stop-watch usable for measuring performance of different steps of an application.
372 /// Time is taken in the constructor.
374
375 /// The name of the application.
376 /// If not set from the descendant, it is tried to be loaded from resource <c>"AppName"</c>
377 /// by the default implementation of #".onBsSetNameVersionAndInfo".
378 String appName =nullptr;
379
380 /// A version string of the application.
381 /// If not set from the descendant, it is tried to be loaded from resource <c>"AppVersion"</c>
382 /// by the default implementation of #".onBsSetNameVersionAndInfo".
384
385 /// Some short information and probably copyright message of the application.
386 /// If not set from the descendant, it is tried to be loaded from resource <c>"AppInfo"</c>
387 /// by the default implementation of #".onBsSetNameVersionAndInfo".
388 String appInfo =nullptr;
389
390 /// Used to assemble and collect the output for standard output character stream \c std::cout
391 /// during the run of this application.<br>
392 /// The collected output is scheduled to be written by the method #".onSdOutput". This method,
393 /// may also be "manually" invoked at any time to flush the current buffers to the output
394 /// streams.
395 Paragraphs* cOut =nullptr;
396
397 /// Same as #".cOut", but used for stream \c std::err.
398 Paragraphs* cErr =nullptr;
399
400
401 //============================================== ALox ============================================
402 /// This will be the name of the release #"%Lox".
403 /// The name defaults to <c>"RLOX"</c> and may be changed prior to the call to the method
404 /// #".onBsSetupALox".<br>
406
407 /// This will be the name of the release logger attached to the release #"%Lox".
408 /// The name defaults to <c>"RLOGGER"</c> and may be changed prior to the call to the method
409 /// #".onBsSetupALox".<br>
411
412 /// The release #"%Lox" used by the application.
413 /// @see Method onBsSetupALox.
415
416 /// The release logger used by the application.
417 /// @see Method onBsSetupALox.
419
420 /// Various boolean flags used to configure the application.
422
423 //============================================== CLI =============================================
424 /// The command-line parser.
426
427 /// \brief Flag to stop the CLI processing loop.
428 ///
429 /// When set to \c true, no further commands from the command line are processed.
430 /// Typical usage is the built-in or custom \c help command: once help text has been
431 /// generated and printed, further command processing is not desired.
432 bool cliStop =false;
433
434 /// Set with built-in option <em>"--dryrun"</em>, which is read with
435 /// #"States::ReadDryRunOption;2". Defaults to false.
436 bool dryrun =false;
437
438
439
440 //================================================================================================
441 // Constructors/destructor
442 //================================================================================================
443 /// Constructor.
444 /// Initializes this app. Mainly by filling the vector #".StateMachine::Program;2" with all
445 /// states found in the enumeration #".States" along with the corresponding virtual methods.
447 App();
448
449
450 /// Virtual destructor.
452 virtual ~App();
453
454 //================================================================================================
455 // Public Interface
456 //================================================================================================
457 public:
458 /// Stores cli-parameters and executes this app.
459 /// @param argc The number of command-line arguments.
460 /// @param argv List of command-line arguments, given as single byte character strings.
461 /// @param argvw The CLI arguments on platforms that use wide command-line strings.
462 /// Defaults to \c nullptr. If given, parameter \p{argv} has to be nulled.
463 /// @return The exit code to be returned by C/C++ \c main().
465 virtual int Main( int argc, const char** argv, const wchar_t** argvw= nullptr );
466
467 /// Has to return the #"%Lox" instance used with release-logging.
468 /// @return This implementation returns field #".releaseLox".
469 virtual lox::Lox* GetRLox() { return releaseLox; }
470
471 /// Has to return the #"%detail::Logger" instance used with release-logging.
472 /// @return This implementation returns field #".releaseLogger".
474
475 /// Returns the name of this application.
476 /// This default implementation returns the field #".appName".
477 /// This is not necessarily equal to the process module name which can be received with
478 /// <c>ProcessInfo::Current().ExecFileName</c>.
479 /// @return This application's name.
480 String GetName() { return appName; }
481
482 /// Returns the version of this application.
483 /// This default implementation returns the field #".appVersion".
484 /// @return A string containing version information of this application.
486
487 /// Returns the version of this application.
488 /// This default implementation returns the field #".appVersion".
489 /// @return A usually multi-line string containing information about this application.
490 String GetInfo() { return appInfo; }
491
492 //================================================================================================
493 // Helper Hooks usable by the Program Methods
494 //================================================================================================
495 /// Translates exceptions to exit-codes of the application.
496 /// Implementations should call this method first and, if necessary, perform their own
497 /// conversions then. If they do so, they should check whether this default version returned
498 /// #"ExitCodes::ErrUnknown", perform their own translation in that case, and probably
499 /// debug-assert on failure.
500 /// @param exception The exception that was thrown.
501 /// @return The exit-code resulting from the given \p{exception}. Unknown exceptions are
502 /// translated to <c>BuiltInExitCodes::ErrUnknown</c>.
503 virtual Enum exceptionToExitCode( Exception& exception );
504
505 /// Writes exception information to \c std::cerr<br>.
506 /// @param exception The exception that was thrown.
507 /// @param target The target string to write into. An option is to pass <c>cErr->Buffer</c>
508 /// here. Of course a custom buffer might be passed, i.e. if the text is to be
509 /// logged with \alox.
510 virtual void exceptionDisplay ( Exception& exception, AString& target );
511
512 /// Writes configuration file information into the given \p{target}.
513 /// @param target The target to write into. The common option is to pass #"cOut" here.
514 virtual void printConfigFileInfo( Paragraphs& target );
515
516 /// This default implementation first calls #"getConfigFilePathsFromCLIParam" and,
517 /// if this is unsuccessful, the method #".getConfigFilePathsFromResources". Then, method
518 /// #".getConfigFilePathsMakeAbsolutePaths" is called.<br>
519 /// CLI arguments may affect which configuration files are considered. Descendants can
520 /// override #"getConfigFilePathsFromCLIParam" to implement their own CLI-based selection
521 /// strategy before resource-defined defaults are completed.
522 /// @param files A pointer to an object of type <c>StdVectorMA<ConfigFileDescriptor></c> that
523 /// is to be filled by this method.
526
527 /// If the given vector \p{files} is empty, this method tries resources named
528 /// <c>"CFGF_NAME_1"</c>, <c>"CFGF_NAME_2"</c>, <c>"CFGF_NAME_3"</c> and so forth until
529 /// a first name is not found. For all names found, an entry in vector \p{files} is
530 /// created.
531 ///
532 /// Then, for each entry in the vector (regardless if they were preexisting or created with
533 /// this method), comment information is loaded from resources. The resource name is composed
534 /// from <c>"CFGF_CMT_"</c> and the number of the entry. If found, the resource is assigned
535 /// to the field #"App::ConfigFileDescriptor::Comment;*".
536 ///
537 /// Then for each entry resources named <c>"CFGF_EXP_"</c> and the amount of the entry
538 /// are searched. If found, the field #"App::ConfigFileDescriptor::Exports;*" is set.
539 /// If more resources (with higher numbers) are existing, such additional exports are
540 /// appended to the list of the last config file entry.
541 /// @param files The vector of file paths that is to be filled or modified by this method.
544
545 /// Checks all filenames in the given vector and converts them to an absolute path.
546 /// @param files The vector of file paths that is to be modified by this method.
549
550 /// Adds configuration file paths influenced by a dedicated CLI parameter.
551 /// The default implementation interprets option <em>"--config"</em> and updates or appends
552 /// corresponding #"ConfigFileDescriptor" entries in \p files.
553 /// Descendants may override this to parse different CLI options or search paths.
554 /// @param files Output vector to append file descriptors to.
556
557 /// Used when errors are detected. May be overwritten, for example, to suppress help output
558 /// and/or otherwise change the standard behavior.
559 /// This default implementation
560 /// - calls #"onSdOutput"
561 /// - calls #"CLIUtil::GetHelp(CommandLine&, const String&)"
562 /// - calls #"SetExitCode"
563 /// - throws #"ControlledEarlyExit".
564 /// @param exitCode The exit code to set in field #"App::machine;*". Also used to
565 /// write an error message by retrieving
566 /// #"ExitCodeDecl::FormatString;*".
567 /// @param helpTopic An optional parameter that defines a topic for the help text written
568 /// to #"App::cOut;*".
569 /// @param formatParam1 An optional parameter to be used with the format string.
570 /// @param formatParam2 A second optional parameter to be used with the format string.
572 virtual void exitWithHelpOutput( Enum exitCode, const String& helpTopic= NULL_STRING,
573 Box formatParam1 = EMPTY_STRING,
574 Box formatParam2 = EMPTY_STRING );
575
576 /// Processes a single parsed CLI command.
577 /// The default implementation handles the built-in #"App::Commands".
578 /// @param cmd The command to execute.
579 /// \return \c true if the command was handled successfully; \c false to indicate that
580 /// the command was not recognized or could not be executed. Implementations
581 /// may set #"cliStop" to terminate further processing.
583 virtual bool processCLICmd(Command* cmd );
584
585
586 //================================================================================================
587 // Virtual Methods called by the State-Machine Program - Bootstrap
588 //================================================================================================
589 /// Called on transition to state #"App::States::SetCamps".<br>
590 /// This default implementation just calls the #"alib::BootstrapAddDefaultCamps;2".
592 virtual void onBsSetCamps();
593
594 /// Called on transition to state #"App::States::PrepareResources".<br>
595 /// This default implementation
596 /// - calls the #"alib::Bootstrap(BootstrapPhases);2" passing
597 /// #"BootstrapPhases::PrepareResources;2" as its parameter.
598 /// - creates instances for fields #".cOut" and #".cErr" inside the global allocator.
599 /// - if configuration macro #"ALIB_DEBUG_RESOURCES" is set, then the field
600 /// #"LocalResourcePool::DbgResourceLoadObserver;*" is set to <c>std::cout</c>.
602 virtual void onBsPrepareResources();
603
604 /// Called on transition to state #"App::States::SetNameVersionAndInfo".<br>
605 /// This default implementation tries resources <c>"AppName"</c>, <c>"AppVersion"</c>, and
606 /// <c>"AppInfo"</c> to set fields #appName, #appVersion, and #appInfo.
607 /// The latter is supported with three placeholders: the name, the version, and the current
608 /// year and is created using the method #"Paragraphs::AddMarked(const BoxedObjects& ...);*".
609 ///
610 /// A string that is set before this method is called, is not replaced.
612 virtual void onBsSetNameVersionAndInfo();
613
614
615 /// Called on transition to state #"App::States::PrepareConfig".<br>
616 /// This default implementation just calls the function #"alib::Bootstrap(BootstrapPhases);2"
617 /// passing #"BootstrapPhases::PrepareConfig;2" as the parameter.
619 virtual void onBsPrepareConfig();
620
621 /// Called on transition to state #"App::States::PreloadVariables".<br>
622 /// Preloading variables allows later fetching and exporting those variables into a
623 /// configuration file (if freshly created), even if they have not been read/used in the
624 /// first run of an application.<br>
625 /// This default implementation calls #"Configuration::PreloadVariables;*"
626 /// on the variables found with the enumeration #"lox::Variables".
628 virtual void onBsPreloadVariables();
629
630 /// Define CLI commands, options, parameters, and exit-codes.
631 /// This default implementation initializes field #cli with #"APP" and registers
632 /// the built-in declarations defined by the enum types #"App::Commands", #"App::Options",
633 /// #"App::Parameters" and #"App::ExitCodes".
635 virtual void onBsCLIDefine();
636
637 /// Implements #"States::CLIReadOptions": calls #"CommandLine::ReadOptions;*" on
638 /// member #".cli". This is done quite early in the boot sequence to allow option '--config'
639 /// to change the configuration files used.
641 virtual void onBsCLIReadOptions();
642
643 /// Called on transition to state #"App::States::ImportConfig".<br>
644 /// This default implementation creates the vector of file descriptors using
645 /// #getConfigFilePaths and then uses type #"IniFileFeeder" to import the
646 /// variables from the INI-files.
648 virtual void onBsImportConfig();
649
650 /// Finalizes CLI after configuration import.
651 /// The default implementation forwards ignored option arguments to the
652 /// #"CLIVariablesPlugin" and installs the default shortcut categories \c ALIB and
653 /// \c ALOX.
655 virtual void onBsConfigureCLI();
656
657
658 /// Called on transition to state #"App::States::FinalizeBootstrap".<br>
659 /// This default implementation just calls the function #"alib::Bootstrap(BootstrapPhases);2"
660 /// passing #"BootstrapPhases::Final;2" as the parameter.
662 virtual void onBsFinalizeBootstrap();
663
664 /// Implements #"States::ReadDryRunOption". Reads the option <em>"--dryrun[=yes|no]"</em> from
665 /// the CLI and sets the flag #".dryrun" accordingly. The optional argument is parsed
666 /// as a #"lang::Bool;2" and hence may be specified with various words, defined with the
667 /// according resources.
669 virtual void onBsReadDryRunOption();
670
671 /// Called on transition to state #"App::States::SetupALox".<br>
672 /// If this method returns an error, bootstrapping is aborted.
673 /// This default implementation interprets the flags
674 /// #"App::Flags::CreateReleaseLox" and
675 /// #"App::Flags::UseReleaseLoggerForDebugLogging", and furthermore
676 /// uses the fields #releaseLoxName and #releaseLoggerName
677 /// into account and potentially creates #releaseLox and #releaseLogger.
679 virtual void onBsSetupALox();
680
681 //================================================================================================
682 // Virtual Methods called by the State-Machine Program - Run
683 //================================================================================================
684 /// This method is preceding the main execution method #onRun. When this is called, all
685 /// bootstrapping is done. Final preparations might be performed here to unclutter #onRun.<br>
686 ///
687 /// This default implementation
688 /// - Tries resource <c>"AppStart"</c>. If found its content is printed to the console
689 /// using method #"Paragraphs::AddMarked(const BoxedObjects)" together with the results of the
690 /// methods #".GetName" and #".GetVersion". Hence the resourced application info has to have
691 /// two placeholders for these values.
692 /// - Tests flag #".dryrun". If set, tries resource <c>DryRunStart</c> and prints it to
693 /// the console. Again the result of the method #".GetName" is passed as a placeholder
694 /// parameter.
695 /// - Tests if the built-in #"app::Option" <c>"Help"</c> was given. If so, calls
696 /// #"CLIUtil::GetHelp(Option)" and stops processing.
697 /// - Tests if the built-in #"app::Option" <c>"Version"</c> was given. If so, prints the
698 /// result of #".GetVersion" and stops processing.
700 virtual void onRunStart();
701
702 /// This is the main execution method of the application.
703 /// This default implementation processes CLI commands until #"cliStop" is set or all
704 /// commands are consumed and dispatches each recognized command to #"processCLICmd".
706 virtual void onRun();
707
708 /// This method is following the main execution method #onRun.
709 /// Overwriting this method is useful to collect code which has to be executed at the end
710 /// of all (or most) execution paths of the custom implementation of #onRun.
712 virtual void onRunEnd();
713
714 //================================================================================================
715 // Virtual Methods called by the State-Machine Program - Shutdown
716 //================================================================================================
717 /// Called on transition to state #"App::States::AnnounceShutdown".<br>
718 /// This default implementation just calls the function #"alib::Shutdown(ShutdownPhases);2"
719 /// passing #"ShutdownPhases::Announce;2" as the parameter.
721 virtual void onSdAnnounceShutdown();
722
723 /// Called on transition to state #"App::States::CleanALox".<br>
724 /// This default implementation checks the flags
725 /// #"App::Flags::ALoxVerbosityExportAllAndWriteBackRelLogger", and
726 /// #"App::Flags::ALoxVerbosityExportAllAndWriteBackDbgLogger" and calls
727 /// #"Lox::SetVerbosityExport(detail::Logger*)" if set.<br>
728 /// Then, if set, the release logger and #"%Lox" are deleted.
730 virtual void onSdCleanALox();
731
732 /// Called on transition to state #"App::States::ExportConfig".<br>
733 /// This default implementation creates the vector of file descriptors using
734 /// #getConfigFilePaths and then uses type #"IniFileFeeder" to export
735 /// variables that are either not existing yet, or which have a writeback flag set,
736 /// into the INI-files.<br>
737 /// This is done for all variables (and variable trees) determined by the field
738 /// #"App::ConfigFileDescriptor::Exports;*".
740 virtual void onSdExportConfig();
741
742 /// Flushes what is collected in the fields #cOut and #cErr to their respective streams and
743 /// clears the buffers.
744 /// With that, this method - while named with the prefix <em>onSd</em> and scheduled at
745 /// the end of the #"StateMachine::Program;2" - may be directly called by
746 /// descendants whenever they wish to flush the current collected output stream, for example,
747 /// after important milestones, before long-running operations, or prior to program termination
748 /// when early partial output is desired.
750 virtual void onSdOutput();
751
752 /// Called on transition to state #"App::States::FinalizeShutdown".<br>
753 /// This default implementation calls the function #"alib::Shutdown;2" passing
754 /// #"ShutdownPhases::Destruct;2" as the parameter.<br>
755 /// Prior to that, some memory cleaning and debug exercises are done.
757 virtual void onSdFinalizeShutdown();
758
759
760}; // class App
761
762/// The application singleton-instance. This defaults to \c nullptr and is set by the
763/// constructor of class #"App".
764ALIB_DLL extern App* APP_SINGLETON;
765
766/// Convenience function that returns the singleton instance of an \alib application.
767/// @tparam TApp The app type to cast to.
768/// @return The dereferenced pointer to #"APP_SINGLETON".
769template<typename TApp= App>
770inline TApp& Get() { return *dynamic_cast<TApp*>(app::APP_SINGLETON); }
771
772} // namespace alib[::app]
773
774
775
776} // namespace [alib]
777
779
780// assigning ALib enum records
781// Specifying our custom module to hold resources of our enum records
783ALIB_CAMP_ENUM( alib::app::App::Options , alib::app::EROptionDecl , alib::APP , "Options" )
784ALIB_CAMP_ENUM( alib::app::App::Parameters , alib::app::ERParameterDecl , alib::APP , "Parameters" )
785ALIB_CAMP_ENUM( alib::app::App::ExitCodes , alib::app::ERExitCodeDecl , alib::APP , "ExitCodes" )
#define ALIB_DLL
#define ALIB_EXPORT
#define ALIB_CAMP_ENUM(T, TRecord, Camp, ResName)
virtual void onRunStart()
Definition app.cpp:561
virtual void onBsImportConfig()
Definition app.cpp:377
virtual void onRun()
Definition app.cpp:594
virtual void onBsPreloadVariables()
Definition app.cpp:353
NString releaseLoxName
Definition app.hpp:405
virtual void onBsSetNameVersionAndInfo()
Definition app.cpp:335
@ NOT_STARTED
Initial state before starting the App.
Definition app.hpp:146
@ CleanALox
Invokes the virtual method #"onSdCleanALox".
Definition app.hpp:176
@ ExportConfig
Invokes the virtual method #"onSdExportConfig".
Definition app.hpp:177
@ SetCamps
Invokes the virtual method #"onBsSetCamps".
Definition app.hpp:149
@ FinalizeBootstrap
Invokes the virtual method #"onBsFinalizeBootstrap".
Definition app.hpp:163
@ Output
Invokes the virtual method #"onSdOutput".
Definition app.hpp:178
@ CLIReadOptions
Invokes the virtual method #"onBsCLIReadOptions".
Definition app.hpp:157
@ RunStart
Invokes the virtual method #"onRunStart".
Definition app.hpp:169
@ ConfigureCLI
Invokes the virtual method #"onBsConfigureCLI".
Definition app.hpp:159
@ CLIDefine
Invokes the virtual method #"onBsCLIDefine".
Definition app.hpp:156
@ FinalizeShutdown
Invokes the virtual method #"onSdFinalizeShutdown".
Definition app.hpp:179
@ SetupALox
Invokes the virtual method #"onBsSetupALox".
Definition app.hpp:165
@ AnnounceShutdown
Invokes the virtual method #"onSdAnnounceShutdown".
Definition app.hpp:175
@ PrepareResources
Invokes the virtual method #"onBsPrepareResources".
Definition app.hpp:150
@ PrepareConfig
Invokes the virtual method #"onBsPrepareConfig".
Definition app.hpp:154
@ PreloadVariables
Invokes the virtual method #"onBsPreloadVariables".
Definition app.hpp:155
@ ReadDryRunOption
Invokes the virtual method #"onBsReadDryRunOption".
Definition app.hpp:164
@ Run
Invokes the virtual method #"onRun".
Definition app.hpp:170
@ SetNameVersionAndInfo
Invokes the virtual method #"onBsSetNameVersionAndInfo".
Definition app.hpp:151
@ ImportConfig
Invokes the virtual method #"onBsImportConfig".
Definition app.hpp:158
@ RunEnd
Invokes the virtual method #"onRunEnd".
Definition app.hpp:171
virtual void onSdFinalizeShutdown()
Definition app.cpp:530
String GetName()
Definition app.hpp:480
String appName
Definition app.hpp:378
String appVersion
Definition app.hpp:383
virtual void onBsSetCamps()
Definition app.cpp:318
virtual lox::textlogger::TextLogger * GetRLogger()
Definition app.hpp:473
StateMachine machine
The state-machine singleton.
Definition app.hpp:369
NString releaseLoggerName
Definition app.hpp:410
virtual int Main(int argc, const char **argv, const wchar_t **argvw=nullptr)
Definition app.cpp:45
Paragraphs * cOut
Definition app.hpp:395
String appInfo
Definition app.hpp:388
virtual void onSdOutput()
Definition app.cpp:510
virtual void onBsReadDryRunOption()
Definition app.cpp:403
virtual void getConfigFilePathsFromResources(StdVectorMA< ConfigFileDescriptor > &files)
Definition app.cpp:209
virtual void onBsPrepareConfig()
Definition app.cpp:351
virtual ~App()
Virtual destructor.
Definition app.cpp:43
Parameters
Built-in parameters of commands and options used with class #"App".
Definition app.hpp:39
@ Topic
Used with command help to optionally denote a help topic.
Definition app.hpp:40
Flags
Configuration flags used with class #"App".
Definition app.hpp:93
@ UseReleaseLoggerForDebugLogging
Definition app.hpp:104
@ ALoxVerbosityExportAllAndWriteBackDbgLogger
Definition app.hpp:114
@ NONE
No flags set.
Definition app.hpp:95
@ ALoxVerbosityExportAllAndWriteBackRelLogger
Definition app.hpp:109
virtual void onSdCleanALox()
Definition app.cpp:442
String GetInfo()
Definition app.hpp:490
virtual void onBsPrepareResources()
Definition app.cpp:320
virtual void printConfigFileInfo(Paragraphs &target)
Definition app.cpp:188
@ ErrUnknownCommand
Unknown command.
Definition app.hpp:55
@ ErrUnknown
An unknown exception occurred. This should never happen.
Definition app.hpp:65
@ ErrMissingCmdParam
Missing parameter of a command.
Definition app.hpp:58
@ ErrNoCmdGiven
No command given.
Definition app.hpp:54
@ ErrParsingOption
Error when parsing an option.
Definition app.hpp:56
@ ErrMissingOptParam
Missing parameter of an option.
Definition app.hpp:59
@ ErrBadParamValue
Bad parameter value.
Definition app.hpp:60
@ ErrParsingCommand
Error when parsing a command.
Definition app.hpp:57
@ ErrConfigFileNotWritable
The configuration file(s) could not be written.
Definition app.hpp:64
virtual void exitWithHelpOutput(Enum exitCode, const String &helpTopic=NULL_STRING, Box formatParam1=EMPTY_STRING, Box formatParam2=EMPTY_STRING)
Definition app.cpp:636
lox::Lox * releaseLox
Definition app.hpp:414
virtual void exceptionDisplay(Exception &exception, AString &target)
Definition app.cpp:158
virtual void getConfigFilePathsFromCLIParam(StdVectorMA< ConfigFileDescriptor > &files)
Definition app.cpp:286
bool dryrun
Definition app.hpp:436
virtual void onBsSetupALox()
Definition app.cpp:416
Flags flags
Various boolean flags used to configure the application.
Definition app.hpp:421
virtual lox::Lox * GetRLox()
Definition app.hpp:469
Options
Built-in options used with class #"App".
Definition app.hpp:28
@ DryRun
Sets the flag #"App::dryrun".
Definition app.hpp:33
@ Verbose
Reserved option for increasing verbosity.
Definition app.hpp:35
@ Config
Change the configured config file path(s).
Definition app.hpp:34
virtual void onSdAnnounceShutdown()
Definition app.cpp:439
virtual void getConfigFilePaths(StdVectorMA< ConfigFileDescriptor > &files)
Definition app.cpp:308
virtual void getConfigFilePathsMakeAbsolutePaths(StdVectorMA< ConfigFileDescriptor > &files)
Definition app.cpp:269
virtual bool processCLICmd(Command *cmd)
Definition app.cpp:645
Commands
Built-in commands used with class #"App".
Definition app.hpp:21
@ Version
Show version information.
Definition app.hpp:23
@ Info
Show info and configuration details.
Definition app.hpp:24
@ Help
Show help text.
Definition app.hpp:22
virtual void onRunEnd()
Definition app.cpp:624
virtual void onBsConfigureCLI()
Definition app.cpp:365
virtual void onBsCLIReadOptions()
Definition app.cpp:363
virtual void onBsCLIDefine()
Definition app.cpp:355
CommandLine cli
The command-line parser.
Definition app.hpp:425
String GetVersion()
Definition app.hpp:485
lox::textlogger::TextLogger * releaseLogger
Definition app.hpp:418
virtual Enum exceptionToExitCode(Exception &exception)
Definition app.cpp:131
StopWatch stopWatch
Definition app.hpp:373
bool cliStop
Flag to stop the CLI processing loop.
Definition app.hpp:432
virtual void onBsFinalizeBootstrap()
Definition app.cpp:401
Paragraphs * cErr
Same as #".cOut", but used for stream std::err.
Definition app.hpp:398
virtual void onSdExportConfig()
Definition app.cpp:461
This class acts as a container for Loggers and provides a convenient interface to logging.
Definition lox.hpp:13
#define ALIB_ENUMS_MAKE_BITWISE(TEnum)
TApp & Get()
Definition app.hpp:770
App * APP_SINGLETON
Definition app.cpp:4
Definition alox.cpp:14
strings::TString< nchar > NString
Type alias in namespace #"%alib".
Definition string.hpp:2174
constexpr String NULL_STRING
A nulled string of the default character type.
Definition string.hpp:2247
constexpr CString NEW_LINE
A zero-terminated string containing the new-line character sequence.
Definition cstring.hpp:536
constexpr const String EMPTY_STRING
An empty string of the default character type.
Definition string.hpp:2227
boxing::Box Box
Type alias in namespace #"%alib".
Definition box.hpp:1128
time::StopWatch StopWatch
Type alias in namespace #"%alib".
strings::TString< character > String
Type alias in namespace #"%alib".
Definition string.hpp:2165
system::Path Path
Type alias in namespace #"%alib".
Definition path.hpp:417
exceptions::Exception Exception
Type alias in namespace #"%alib".
app::AppCamp APP
The singleton instance of the camp class used by class #"App".
Definition appcamp.cpp:1
strings::TAString< character, lang::HeapAllocator > AString
Type alias in namespace #"%alib".
format::Paragraphs Paragraphs
Type alias in namespace #"%alib".
std::vector< T, StdMA< T > > StdVectorMA
Type alias in namespace #"%alib".
boxing::Enum Enum
Type alias in namespace #"%alib".
Definition enum.hpp:210
Path Pathname
The resolved full path to the file.
Definition app.hpp:347
bool WasEmpty
If set, the file did not exist or was empty at the start of the application.
Definition app.hpp:360
String Comment
The files' main comment to set, in case it does not exist, yet.
Definition app.hpp:354
bool FromCfgOption
If set, the file name (and maybe path) came from option '–CONFIG'.
Definition app.hpp:357
A struct denoting the next state and the corresponding method to execute.
Definition app.hpp:190
void SetExitCode(Enum pExitCode)
Definition app.hpp:308
CommandList Program
The list of commands to execute.
Definition app.hpp:280
Enum exitCode
The exit code. Only the first set is stored and returned later.
Definition app.hpp:269
void DbgDumpFurtherExitCodes(AString &target)
Definition app.hpp:331
std::vector< Enum > dbgFurtherExitCodes
Definition app.hpp:274
A command argument of the command-line.
#"alib_enums_records;ALib Enum Record" type used by class #"CommandDecl".
TIntegral Integral() const
Definition enum.hpp:87
void(* Custom)(App &)
A pointer to a method of a custom derived type.
Definition app.hpp:198
void(App::* BuiltIn)()
A pointer to a virtual method of class #"%App".
Definition app.hpp:195