ALib C++ Framework
by
Library Version: 2605 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
app.cpp
1
2namespace alib::app {
3
4App* APP_SINGLETON= nullptr;
5
7 stopWatch.Reset();
8
10 "A second instance of the App-singleton was created, which is forbidden.")
11 APP_SINGLETON= this;
12
13 machine.Program.reserve( 20 + 10 ); // allow 10 custom states without resizing
14
15 machine.Program.insert( machine.Program.end(), {
16 { States::SetCamps , &App::onBsSetCamps },
17 { States::PrepareResources , &App::onBsPrepareResources },
18 { States::SetNameVersionAndInfo , &App::onBsSetNameVersionAndInfo },
19
20 { States::PrepareConfig , &App::onBsPrepareConfig },
21 { States::PreloadVariables , &App::onBsPreloadVariables },
22 { States::CLIDefine , &App::onBsCLIDefine },
23 { States::CLIReadOptions , &App::onBsCLIReadOptions },
24 { States::ImportConfig , &App::onBsImportConfig },
25 { States::ConfigureCLI , &App::onBsConfigureCLI },
26
27 { States::FinalizeBootstrap , &App::onBsFinalizeBootstrap },
28 { States::ReadDryRunOption , &App::onBsReadDryRunOption },
29 { States::SetupALox , &App::onBsSetupALox },
30
31 { States::RunStart , &App::onRunStart },
32 { States::Run , &App::onRun },
33 { States::RunEnd , &App::onRunEnd },
34
35 { States::AnnounceShutdown , &App::onSdAnnounceShutdown },
36 { States::CleanALox , &App::onSdCleanALox },
37 { States::ExportConfig , &App::onSdExportConfig },
38 { States::Output , &App::onSdOutput },
39 { States::FinalizeShutdown , &App::onSdFinalizeShutdown },
40 });
41}
42
44
45int App::Main( int argc, const char** argv, const wchar_t** argvw ) {
46 ARG_C= argc;
47 ARG_VN= argv;
48 ARG_VW= argvw;
49
50 // sort commands by state
51 std::sort(machine.Program.begin(), machine.Program.end(),
52 [](const StateMachine::Command &a, const StateMachine::Command &b) {
53 return a.State.Integral<int>() < b.State.Integral<int>();
54 });
55 #if ALIB_DEBUG
56 {
57 int lastID= 0;
58 for (StateMachine::Command& cmd : machine.Program ) {
59 if (cmd.State.Integral<int>() == lastID)
60 ALIB_ERROR("APP", "Duplicate command ID {} found in program",
61 cmd.State.Integral<int>() )
62 lastID= cmd.State.Integral<int>();
63 } }
64 #endif
65
66
67 for (StateMachine::Command& cmd : machine.Program )
68 try {
69 // transition the state machine "State"
70 machine.State= cmd.State;
71
72 // built-in step?
73 if ( cmd.State.IsEnumType<App::States>() ) {
74 // transition the state machine "BuiltInState"
75 machine.BuiltInState= cmd.State.Get<States>();
76 (this->*cmd.Method.BuiltIn)();
77 } else {
78 (*cmd.Method.Custom)(*this);
79 }
80
81 // with emergencies, we stop processing
82 if ( machine.EmergencyStop )
83 break;
84
85 // exceptions are converted to exit codes and displayed. A custom conversion implementation
86 // may take the current app-state into account to determine the right exit code.
87 } catch( Exception& e ) {
89 machine.SetExitCode( exceptionToExitCode(e) );
90 #if ALIB_DEBUG
91 else {
92 ALIB_ASSERT_ERROR( int(machine.BuiltInState) >= int(States::RunStart)
93 && int(machine.BuiltInState) <= int(States::RunEnd ), "APP",
94 "Exceptions::ControlledEarlyExit thrown while not in States::RunStart/Run/RunEnd")
95 ALIB_ASSERT_ERROR(machine.GetExitCode().Integral() != 0, "APP",
96 "Exceptions::ControlledEarlyExit thrown without having exit code set")
97 }
98 #endif
99 exceptionDisplay(e, cErr->Buffer);
100 }
101
102 // System exceptions should be handled by the descendant. (prior to ending here)
103 catch( std::runtime_error& e ) {
104 cErr->Add("Unhandled system exception: ", e.what());
105 machine.SetExitCode( App::ExitCodes::ErrUnknown );
106 #if ALIB_DEBUG
107 onSdOutput();
108 ALIB_WARNING("APP", "System exception not handled. "
109 "This should be done by the user of class ALib App.")
110 #endif
111 }
112
113 if (machine.EmergencyStop) {
114 // finish bootstrapping of ALib, to be able to duly shutdown.
115 if ( machine.BuiltInState < States::FinalizeBootstrap )
116 Bootstrap();
117
118 // shutdown ALib
119 if ( machine.BuiltInState < States::FinalizeShutdown)
120 Shutdown();
121 }
122
123 return machine.GetExitCode().Integral<int>();
124}
125
126
127//##################################################################################################
128// Helpers
129//##################################################################################################
130
132 // Exceptions from ALib module Variables -> either read or write of INI-files failed.
133 if ( exception.Type().IsEnumType<variables::Exceptions>() ) {
134 auto ee= exception.Type().Get<variables::Exceptions>();
135
136 if (machine.BuiltInState==States::ImportConfig ) {
139 } }
140
141 // handle cli-exceptions
142 if ( exception.Type().IsEnumType<CLIExceptions>() ) {
143 ExitCodes exitCode;
147 else { ALIB_ASSERT_ERROR( exception.Type().Get<CLIExceptions>()
149 "APP", "Unknown exception") exitCode= ExitCodes::ErrParsingCommand; }
150
151 return exitCode;
152 }
153
154 // We do not know. Overridden methods should know
156}
157
158void App::exceptionDisplay( alib::Exception& exception, AString& target ) {
159 if (exception.Type()== Exceptions::ControlledEarlyExit) {
160 #if ALIB_DEBUG
161 alib::assert::Raise( exception.Back().CI, 1, "APP",
162 "<- Exceptions::ControlledEarlyExit was trown here!" );
163 machine.DbgDumpFurtherExitCodes(target);
164 #endif
165 return;
166 }
167
168 // print unhandled exceptions
169 String512 cmdLine(ProcessInfo::Current().ExecFileName);
170 for( int i= 0; i < alib::ARG_C ; ++i )
171 cmdLine << ' ' << alib::ARG_VN[i];
173 cErr->Add( "Exception occurred when executing command:\n"
174 " {}\n"
175 "Exception details ({} item{}):",
176 cmdLine, exception.Size(), (exception.Size() > 1 ? "s" : "") )
177 .PushIndent(A_CHAR(" "))
178 .Add( exception.Format() )
179 .PopIndent();
180
181 #if ALIB_DEBUG
182 cErr->Add( "Application exit-code will be: ", machine.GetExitCode() );
183 #endif
184
185 machine.DbgDumpFurtherExitCodes(target);
186}
187
189 LocalAllocator2K cfgFilePathAllocator;
190 StdVectorMA<ConfigFileDescriptor> files(cfgFilePathAllocator);
191 getConfigFilePaths(files);
192
193 if ( !files.size() ) {
194 p.Add("None");
195 return;
196 }
197
198 for (ConfigFileDescriptor& fileInfo : files) {
199 p.Add( "Configuration file: {!ATab}:1\n", fileInfo.Pathname );
200 p.Add( " Existed: {!ATab}\n", fileInfo.WasEmpty ? "no" : "yes" );
201
202 if ( fileInfo.Exports.IsNotEmpty() ) {
203 Tokenizer tok(fileInfo.Exports, ',');
204 while ( tok.HasNext() )
205 p.Add(" Exports: {!ATab}\n" , tok.Next() );
206} } }
207
208
210 size_t cnt= 0;
211
212 // read file-names from resource, only if not set, yet.
213 if ( !files.size() )
214 for (;;) {
215 NString128 resourceName("CFGF_NAME_"); resourceName << (cnt+1);
216 String name= APP.TryResource( resourceName );
217 if (name.IsEmpty())
218 break;
219 files.emplace_back();
220 files.at(cnt).Pathname= name;
221 ++cnt;
222 }
223
224 // read comments from resources
225 cnt= 0;
226 for (ConfigFileDescriptor& fInfo : files ) {
227 if ( fInfo.Comment.IsEmpty() ) {
228 NString128 resourceName("CFGF_CMT_"); resourceName << (cnt+1);
229 fInfo.Comment= APP.TryResource( resourceName );
230 }
231 ++cnt;
232 }
233
234 // read exports
235 cnt= 0;
236 for (ConfigFileDescriptor& fInfo : files ) {
237 NString128 resourceName("CFGF_EXP_"); resourceName << (cnt+1);
238 fInfo.Exports= APP.TryResource( resourceName );
239 ++cnt;
240 }
241
242 // read additional exports: if more export values in resources exist than
243 // the number of created config-files, the last ones are added to the last file.
244 String1K additionalExports;
245 for (;;) {
246 NString128 resourceName("CFGF_EXP_"); resourceName << (cnt+1);
247 String exports= APP.TryResource( resourceName );
248 if (exports.IsNull() )
249 break;
250 additionalExports << ',' << exports;
251 ++cnt;
252 }
253
254 if ( additionalExports.IsNotEmpty() ) {
255 ALIB_ASSERT_ERROR(!files.empty(), "APP",
256 "Config-exports {!Q} found, but no config-file is created by the application",
257 additionalExports)
258 ConfigFileDescriptor& last= files.back();
259 if ( last.Exports.IsNotEmpty() ) additionalExports.InsertAt(last.Exports, 0);
260 else additionalExports.DeleteStart(1);
261
262 last.Exports.Allocate(files.get_allocator().GetAllocator(), additionalExports );
263
264 }
265
266 return;
267}
268
270 for (ConfigFileDescriptor& fileInfo : files) {
271 if (fileInfo.Pathname.IsEmpty() || fileInfo.Pathname.IsAbsolute())
272 continue;
273
274 Path backup(fileInfo.Pathname);
275 // some relative addressing?
276 if ( fileInfo.Pathname.StartsWith(A_PATH("./" ))
277 || fileInfo.Pathname.StartsWith(A_PATH("../" ))
278 || fileInfo.Pathname.StartsWith(A_PATH(".\\" ))
279 || fileInfo.Pathname.StartsWith(A_PATH("..\\")) )
280 fileInfo.Pathname.Change( SystemFolders::Current, backup );
281 else {
282 fileInfo.Pathname.Change( SystemFolders::HomeConfig );
283 fileInfo.Pathname._<NC>(DIRECTORY_SEPARATOR)._(backup);
284} } }
285
287
288 auto* optionConfig= cli.GetOption(Options::Config);
289 if( optionConfig == nullptr )
290 return;
291
292 Substring names= optionConfig->Args.front();
293 size_t cnt= 0;
294 while (names.IsNotEmpty()) {
295 Substring name= names.ConsumeToken(',');
296 name.Trim();
297 if (files.size() <= cnt)
298 files.emplace_back();
299 Path& path= files.at(cnt).Pathname;
300 if( !name.IsEmpty()
301 && !String(A_CHAR("Default")).StartsWith<CHK,lang::Case::Ignore>( name ) )
302 path.Reset(name);
303 ++cnt;
304 }
305 return;
306}
307
309 getConfigFilePathsFromCLIParam (files); if (machine.EmergencyStop) return;
310 getConfigFilePathsFromResources (files); if (machine.EmergencyStop) return;
311 getConfigFilePathsMakeAbsolutePaths(files); if (machine.EmergencyStop) return;
312 while (files.size() && files.back().Pathname.IsEmpty())
313 files.pop_back();
314}
315
316
317
319
321 #if ALIB_DEBUG_RESOURCES
323 #endif
324
326
329
330 if( cOut->LineWidth == 0) {
331 cOut->LineWidth=
332 cErr->LineWidth= Console::GetWidth(false, 120);
333} }
334
336 if (appName.IsEmpty())
337 appName= APP.TryResource( "AppName" );
338
339 if (appVersion.IsEmpty())
340 appVersion= APP.TryResource( "AppVersion" );
341
342 if (appInfo.IsEmpty()) {
343 String infoFmtString= APP.TryResource("AppInfo");
344 if ( infoFmtString.IsNotEmpty() ) {
345 StringLengthResetter resetter(cOut->Buffer);
346 cOut->AddMarked(infoFmtString, appName, appVersion, CalendarDateTime(DateTime()).Year);
348 cOut->Buffer.Substring(resetter.OriginalLength()) );
349} } }
350
352
353void App::onBsPreloadVariables() { APP.GetConfig()->PreloadVariables<lox::Variables>(); }
354
356 cli.Init( &APP );
357 cli.DefineExitCodes <ExitCodes >();
358 cli.DefineParameters<Parameters>();
359 cli.DefineCommands <Commands >();
360 cli.DefineOptions <Options >();
361}
362
363void App::onBsCLIReadOptions() { cli.ReadOptions(); }
364
366 // set remaining cli args to configuration and allow shortcuts for cli variables
367 variables::CLIVariablesPlugin* cliParameterPlugin=
368 APP.GetConfig()->GetPluginTypeSafe<variables::CLIVariablesPlugin>();
369 for( auto& arg : cli.OptionArgsIgnored )
370 cliParameterPlugin->AlternativeArgs.emplace_back( arg );
371
372 cliParameterPlugin->DefaultCategories.emplace_back(A_CHAR("ALIB"));
373 cliParameterPlugin->DefaultCategories.emplace_back(A_CHAR("ALOX"));
374}
375
376
378 LocalAllocator2K cfgFilePathAllocator;
379 StdVectorMA<ConfigFileDescriptor> files(cfgFilePathAllocator);
380 getConfigFilePaths(files);
381
382 // loop over cfg files (if opening fails, nothing is imported)
383 for ( size_t fileNo= 0; fileNo < files.size() ; ++fileNo ) {
384 ConfigFileDescriptor& fileInfo= files.at(fileNo);
385 if (fileInfo.Pathname.IsEmpty())
386 continue;
387
388 // import variables
389 IniFileFeeder iniFileFeeder(*APP.GetConfig());
390 try { iniFileFeeder.ImportStart( fileInfo.Pathname ); }
391 catch (Exception& e) {
393 throw;
394 fileInfo.WasEmpty= true;
395 continue;
396 }
397 iniFileFeeder.ImportAll();
398 iniFileFeeder.ImportEnd();
399} }
400
402
404 auto* dryOpt= cli.GetOption( Options::DryRun );
405 if( dryOpt != nullptr ) {
406 dryrun= true;
407 if( dryOpt->Args.IsNotEmpty() ) {
409 Substring arg= dryOpt->Args.front();
410 enumrecords::Parse( arg, val );
411 dryrun= (val == lang::Bool::True);
412} } }
413
414
415
418 "DEBUG_LOGGER already created. Obviously logging was used "
419 "prior to the invocation of bs30SetupALox. This can cause issues" )
420
421 // Create release lox
422 if ( HasBits(flags, Flags::CreateReleaseLox ) ) {
426 Lox_SetVerbosity( releaseLogger, Verbosity::Info , "/" )
427
428 // Set the debug-lox to our release lox
433 } }
434}
435
436//==================================================================================================
437// Shutdown
438//==================================================================================================
440
441
443 #if ALOX_DBG_LOG
445 Log_SetVerbosityExport( "DEBUG_LOGGER", true )
446 #endif
447
448 // set ExportAll and writeback with ALox verbosity-variables which were not in the
449 // INI-file before. We do this regardless if there is a INI-file or not. It might benefit
450 // for custom configurations systems likewise.
452 && releaseLogger ) {
455 Log_Prune( Log::DEBUG_LOGGER= nullptr; )
458 Lox_Prune(delete releaseLogger );
459} }
460
462 LocalAllocator2K cfgFilePathAllocator;
463 StdVectorMA<ConfigFileDescriptor> files(cfgFilePathAllocator);
464 getConfigFilePaths(files);
465
466 // loop over two (possible) files
467 for ( ConfigFileDescriptor& fileInfo : files ) {
468 if (fileInfo.Pathname.IsEmpty())
469 continue;
470
471 // Open INI-file
472 IniFileFeeder iniFileFeeder(*APP.GetConfig());
473 iniFileFeeder.ExportStart( fileInfo.Pathname );
474
475 // export variables that are not existing in the INI-file yet
476 int cntChanges= 0;
477 Tokenizer tknzr(fileInfo.Exports, ',');
478 while (tknzr.HasNext()) {
479 auto& tok= tknzr.Next(); // for root, just the direct children
480 int changes= iniFileFeeder.ExportSubTree( tok, tok.Equals(A_CHAR("/")) );
481 if ( changes > 0)
482 cntChanges+= changes;
483 }
484
485 auto& iniFile= iniFileFeeder.GetIniFile();
486 // If INI-file was empty, set comment
487 if( iniFileFeeder.DidNotExistOrWasEmpty
488 && fileInfo.Comment.IsNotEmpty() ) {
489 String4K buf;
490 Paragraphs p(buf);
491 p.LineWidth= iniFileFeeder.LineWidth;
492 p.AddMarked( fileInfo.Comment )
493 .RemoveLastNewLine();
494 iniFile.FileComments.Allocate(iniFile.Allocator, buf);
495 cntChanges++;
496 }
497
498 // add section comments (if not existing)
499 cntChanges+= iniFileFeeder.AddResourcedSectionComments(BASECAMP , "CFG_SECT_CMT_" );
500 cntChanges+= iniFileFeeder.AddResourcedSectionComments(ALOX , "CFG_SECT_CMT_" );
501 cntChanges+= iniFileFeeder.AddResourcedSectionComments(APP , "CFG_SECT_CMT_" );
502
503 // write INI-file, if changed.
504 if( cntChanges > 0 ) iniFileFeeder.ExportEnd( fileInfo.Pathname );
505 else iniFileFeeder.ExportEnd();
506
507 } // loop over 2 files
508}
509
511 machine.DbgDumpFurtherExitCodes(cOut->Buffer);
512 if ( cOut->Buffer.IsNotEmpty() ) {
513 std::cout << cOut->Buffer;
514 if (!cOut->Buffer.EndsWith(NEW_LINE))
515 std::cout << std::endl;
516 cOut->Buffer.Reset();
517 }
518 std::cout.flush();
519
520 if ( cErr->Buffer.IsNotEmpty() ) {
521 std::cerr << cErr->Buffer;
522 if (!cErr->Buffer.EndsWith(NEW_LINE))
523 std::cerr << std::endl;
524 cErr->Buffer.Reset();
525 }
526 std::cerr.flush();
527}
528
529
531 // Dump resources
532 #if ALIB_DEBUG_RESOURCES
533 std::cout << std::endl;
534 std::cout << "---------------- Resource Pool Dump ----------------" << std::endl;
535 auto resourceList= APP.GetResourcePool().DbgGetList();
536 std::cout << resources::DbgDump( resourceList ) << std::endl;
537 std::cout << "---------------- Resource Pool Dump (end) ----------" << std::endl;
538 #endif
539
540 // Dump Boxing Info
541 #if ALIB_DEBUG_BOXING
542 std::cout << std::endl;
543 std::cout << "---------------- Debug Boxing ----------------" << std::endl;
544 std::cout << alib::boxing::debug::DumpVTables(false);
546 std::cout << alib::boxing::debug::DumpAll();
547 std::cout << "---------------- Debug Boxing (end) ----------" << std::endl;
548 #endif
549
550 if (cOut) cOut->~Paragraphs();
551 if (cErr) cErr->~Paragraphs();
552
553 // finalize ALib shutdown
555}
556
557
558//==================================================================================================
559// Run
560//==================================================================================================
562 if ( cliStop )
563 return;
564
565 String resource= APP.TryResource( "AppStart" );
566 if ( resource.IsNotEmpty() )
567 cOut->AddMarked( resource, GetName(), GetVersion() );
568
569 // if 'dryrun' was recognized, output resource "DryRunStart"
570 if( dryrun ) {
571 resource= APP.TryResource( "DryRunStart" );
572 if ( resource.IsNotEmpty() )
573 cOut->AddMarked( resource, GetName() );
574 }
575
576 //------- check for option 'help' -------
577 Option* option= cli.GetOption( Options::Help);
578 if( option ) {
579 if( !CLIUtil::GetHelp( cli, option, *cOut ) )
581 option->Declaration->Identifier(),
582 option->Args.front(),
583 option->Declaration->Identifier() );
584 cliStop= true;
585 return;
586 }
587
588 //------- check for option 'version' -------
589 if( cli.GetOption( Options::Version ) ) {
590 cOut->Add(GetVersion());
591 cliStop= true;
592} }
593
595 if( cli.ArgsLeft.size() == 0) {
596 if (!processCLICmd(nullptr) )
598 return;
599 }
600
601 while(!cliStop && cli.ArgsLeft.size() > 0) {
602 cli.ReadNextCommands();
603 //------- No command recognized? This is allowed, calls processCLICmd with nullptr -------
604 if( cli.NextCommandIt == cli.CommandsParsed.end() ) {
605 // No command. If derived does not process no-commands, then throw.
606 if (!processCLICmd(nullptr) )
608 else
609 continue;
610 }
611
612 //------- Command loop -------
613 if ( Command* actCmd= cli.NextCommand(); actCmd != nullptr ) {
614 ALIB_DBG( bool processed= )
615 processCLICmd(actCmd);
616 ALIB_ASSERT_ERROR(processed, "APP",
617 "Command \"{}\" recognized but not processed by the App.",
618 actCmd->Declaration->Identifier() )
619 continue;
620 }
621 break;
622} }
623
625 if ( cliStop )
626 return;
627
628 // if 'dryrun' was recognized, output resource "DryRunEnd"
629 if( dryrun ) {
630 String dryRunEnd= APP.TryResource( "DryRunEnd" );
631 if ( dryRunEnd.IsNotEmpty() )
632 cOut->AddMarked( dryRunEnd );
633} }
634
635
636void App::exitWithHelpOutput( Enum exitCode, const String& helpTopic, Box fp1, Box fp2 ) {
637 (void) fp1;
638 (void) fp2;
639 onSdOutput();
640 CLIUtil::GetHelp( cli, helpTopic, *cOut );
641 machine.SetExitCode(exitCode);
643}
644
646 if ( cmd == nullptr )
647 return false;
648
649 if( cmd->Declaration->Element() == Commands::Help ) {
650 if( !CLIUtil::GetHelp( cli, cmd, *cOut ) ) {
651 // Assert that one argument was consumed as the help topic.
652 // No other circumstance could make GetHelp fail.
653 ALIB_ASSERT(cmd->ConsumedArguments== 2, "APP") // 2 means the command and the argument
655 ARG_VN[cmd->Position + 2], cmd->Declaration->Identifier() );
656 }
657 cliStop= true;
658 return true;
659 }
660
661 if( cmd->Declaration->Element() == Commands::Version ) {
662 cOut->Add(GetVersion());
663 return true;
664 }
665
666 if( cmd->Declaration->Element() == Commands::Info ) {
667 if ( GetInfo().IsNotEmpty() )
668 cOut->Add(GetInfo());
669 cOut->Add("Configuration files:\n");
671 return true;
672 }
673
674 return false;
675}
676
677
678
679} // namespace [alib::app]
#define ALIB_CALLER_NULLED
#define A_CHAR(STR)
#define ALIB_ASSERT(cond, domain)
#define ALIB_WARNING(domain,...)
#define ALIB_ERROR(domain,...)
#define ALIB_LOCK_RECURSIVE_WITH(lock)
#define ALIB_DBG(...)
#define ALIB_ASSERT_ERROR(cond, domain,...)
#define Log_SetVerbosityExport(...)
#define Lox_RemoveLogger(logger)
#define Lox_Prune(...)
#define Lox_SetVerbosity(...)
#define Log_Prune(...)
#define Lox_SetVerbosityExport(...)
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
@ FinalizeBootstrap
Invokes the virtual method #"onBsFinalizeBootstrap".
Definition app.hpp:163
@ RunStart
Invokes the virtual method #"onRunStart".
Definition app.hpp:169
@ FinalizeShutdown
Invokes the virtual method #"onSdFinalizeShutdown".
Definition app.hpp:179
@ 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
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
@ UseReleaseLoggerForDebugLogging
Definition app.hpp:104
@ ALoxVerbosityExportAllAndWriteBackDbgLogger
Definition app.hpp:114
@ 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
@ ErrNoCmdGiven
No command given.
Definition app.hpp:54
@ ErrParsingOption
Error when parsing an option.
Definition app.hpp:56
@ 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
Options
Built-in options used with class #"App".
Definition app.hpp:28
@ DryRun
Sets the flag #"App::dryrun".
Definition app.hpp:33
@ 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
static bool GetHelp(CommandLine &cmdLine, const String &topics, Paragraphs &text)
Definition cliutil.cpp:87
const Enum & Element() const
const String & Identifier()
const String & Identifier()
AString & Format(AString &target) const
Message & Back() const
Definition exception.cpp:73
const Enum & Type() const
Definition exception.cpp:92
static threads::RecursiveLock DEFAULT_LOCK
void Add(boxing::TBoxes< TAllocatorArgs > &args)
void AddMarked(boxing::TBoxes< TAllocatorArgs > &args)
integer LineWidth
Used as parameter lineWidth of static method invocations.
static textlogger::TextLogger * DEBUG_LOGGER
The debug logger created by AddDebugLogger.
Definition log.hpp:39
static void SetALibAssertionPlugin(Lox *lox)
Definition alox.cpp:267
static textlogger::TextLogger * CreateConsoleLogger(const NString &name=nullptr)
Definition alox.cpp:101
static std::ostream * DbgResourceLoadObserver
TAString & InsertAt(const TString< TChar > &src, integer pos)
TAString & DeleteStart(integer regionLength)
constexpr bool IsEmpty() const
Definition string.hpp:349
void Allocate(TAllocator &allocator, const TString< TChar > &copy)
Definition string.hpp:1729
constexpr bool IsNotEmpty() const
Definition string.hpp:353
TSubstring & Trim(const TCString< TChar > &whiteSpaces=CStringConstantsTraits< TChar >::DefaultWhitespaces())
TString< TChar > ConsumeToken(TChar separator=',', lang::Inclusion includeSeparator=lang::Inclusion::Include)
TSubstring< TChar > & Next(lang::Whitespaces trimming=lang::Whitespaces::Trim, TChar newDelim='\0')
Definition tokenizer.cpp:4
static int GetWidth(bool forceRedetect=false, int defaultWidth=80)
Definition console.cpp:7
static const ProcessInfo & Current()
int ImportStart(const Path &path)
void ExportEnd()
Closes and deletes the internal iniFile instance without writing an opened INI-file.
int AddResourcedSectionComments(ResourcePool &resourcePool, const NString &resourceCategory, const NString &resourceNamePrefix)
int ExportSubTree(Configuration::Cursor cursor, bool directChildrenOnly=false)
void ImportEnd()
Closes and deletes the internal iniFile instance.
int ExportStart(const Path &path)
App * APP_SINGLETON
Definition app.cpp:4
@ ParsingOptions
General option parse error. Adds option help text.
@ ParsingCommand
General parameter parse error. Adds command help text.
@ NoCommandGiven
Unknown command given.
@ UnknownCommand
Unknown command given.
void Raise(const lang::CallerInfo &ci, int type, std::string_view domain, TArgs &&... args)
Definition assert.hpp:178
std::vector< std::pair< const std::type_info *, uinteger > > GetKnownFunctionTypes()
Definition vtable.cpp:136
AString DumpFunctions(const std::vector< std::pair< const std::type_info *, uinteger > > &input, const String &headline, const String &indent)
AString DumpVTables(bool staticVtables, bool includeFunctions)
bool Parse(strings::TSubstring< TChar > &input, TEnum &result)
@ False
False value.
Lox * DEBUG_LOX
RecursiveLock GLOBAL_ALLOCATOR_LOCK
TMonoAllocator< lang::HeapAllocator > GLOBAL_ALLOCATOR
AString DbgDump(std::vector< std::tuple< NString, NString, String, integer > > &list, const NString &catFilter, const String &format)
Exceptions
Exception codes of namespace #"alib::variables;2".
Definition vmeta.hpp:17
@ ErrorWritingFile
An error occurred writing the file .
Definition vmeta.hpp:22
@ ErrorOpeningFile
File not found when reading.
Definition vmeta.hpp:19
ListMA< camp::Camp * > CAMPS
void BootstrapAddDefaultCamps()
void Bootstrap(BootstrapPhases targetPhase, camp::Camp *targetCamp, int alibVersion, int alibRevision, TCompilationFlags compilationFlags)
strings::util::TTokenizer< character > Tokenizer
Type alias in namespace #"%alib".
constexpr CString NEW_LINE
A zero-terminated string containing the new-line character sequence.
Definition cstring.hpp:536
lox::ALoxCamp ALOX
The singleton instance of ALib Camp class #"ALoxCamp".
Definition aloxcamp.cpp:5
boxing::Box Box
Type alias in namespace #"%alib".
Definition box.hpp:1128
const wchar_t ** ARG_VW
Definition mainargs.cpp:4
monomem::TLocalAllocator< 2 > LocalAllocator2K
Type alias in namespace #"%alib". Allocates 2kB of stack memory.
LocalString< 4096 > String4K
Type alias name for #"TLocalString;TLocalString<character,4096>".
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
strings::TSubstring< character > Substring
Type alias in namespace #"%alib".
camp::Basecamp BASECAMP
The singleton instance of ALib Camp class #"Basecamp".
Definition basecamp.cpp:2
LocalString< 1024 > String1K
Type alias name for #"TLocalString;TLocalString<character,1024>".
exceptions::Exception Exception
Type alias in namespace #"%alib".
strings::util::CalendarDateTime CalendarDateTime
Type alias in namespace #"%alib".
Definition calendar.hpp:509
void Shutdown()
app::AppCamp APP
The singleton instance of the camp class used by class #"App".
Definition appcamp.cpp:1
constexpr PathCharType DIRECTORY_SEPARATOR
The standard path separator character. Defaults to '\' on Windows OS, '/' else.
Definition path.hpp:63
NLocalString< 128 > NString128
Type alias name for #"TLocalString;TLocalString<nchar,128>".
strings::TAString< character, lang::HeapAllocator > AString
Type alias in namespace #"%alib".
format::Paragraphs Paragraphs
Type alias in namespace #"%alib".
int ARG_C
Definition mainargs.cpp:2
std::vector< T, StdMA< T > > StdVectorMA
Type alias in namespace #"%alib".
strings::TStringLengthResetter< character,lang::HeapAllocator > StringLengthResetter
Type alias in namespace #"%alib".
const char ** ARG_VN
Definition mainargs.cpp:3
time::DateTime DateTime
Type alias in namespace #"%alib".
Definition datetime.hpp:188
boxing::Enum Enum
Type alias in namespace #"%alib".
Definition enum.hpp:210
LocalString< 512 > String512
Type alias name for #"TLocalString;TLocalString<character,512>".
variables::IniFileFeeder IniFileFeeder
Type alias in namespace #"%alib".
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
A struct denoting the next state and the corresponding method to execute.
Definition app.hpp:190
A command argument of the command-line.
CommandDecl * Declaration
The underlying declaration.
ListMA< String, Recycling::Shared > Args
Arguments belonging to this option.
OptionDecl * Declaration
The declaration struct.
integer ConsumedArguments
TIntegral Integral() const
Definition enum.hpp:87
bool IsEnumType() const
Definition enum.hpp:141
TEnum Get() const
Definition enum.hpp:74
CallerInfo CI
The source code location that this message relates to.
Definition message.hpp:24
#define A_PATH(literal)
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