ALib C++ Framework
by
Library Version: 2511 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
App/sample.cpp
1// #################################################################################################
2// ALib C++ Framework
3// Configuration Sample
4//
5// Copyright 2025 A-Worx GmbH, Germany
6// Published under Boost Software License (a free software license, see LICENSE.txt)
7// #################################################################################################
8#include "ALib.Lang.H"
9#if !DOXYGEN // otherwise this sample would be seen in the ALib dox
10
11#include "sample.hpp"
12
13// Include necessary ALib headers
14#include "ALib.Strings.StdIOStream.H" // Support to write ALib strings and boxes to cout
15#include "ALib.Strings.Calendar.H" // Module ALib Strings, calendar formatting
16#include "ALib.Variables.Plugins.H" // Module ALib Variables, environment and cli-plugins
17#include "ALib.Bootstrap.H" // Module ALib Strings, calendar formatting
18
19#include <filesystem> // C++ filesystem
20#include <chrono> // C++ chrono
21
22
23// namespaces to use locally
24using namespace alib;
25
26void Sample::bsCLIDefine() {
27 AppCli::bsCLIDefine();
28
29 cli.DefineExitCodes <DateExitCodes >();
30 cli.DefineParameters<DateParameters>();
31 cli.DefineCommands <DateCommands >();
32 cli.DefineOptions <DateOptions >();
33}
34
35void Sample::onBsPrepareConfig() {
36 // call parent's implementation. This bulk-loads the resources into the camps.
37 AppCli::onBsPrepareConfig();
38
39 // now, we just add the resources that parent AppCli did not define for us.
40
41 APPCLI_CAMP.GetResourcePool().BootstrapBulk( APPCLI_CAMP.ResourceCategory,
42#define EOS ,
43
44//-------------------- Things required by AppCli --------------------
45"HlpCLIAppName", A_CHAR("sample"),
46"HlpUsage" , A_CHAR("sample [format=\"FORMATSPEC\" [now]|[file FILENAME]"),
47
48
49"HlpGeneral", A_CHAR(
50 "\nABOUT sample\n"
51 "@>>"
52 "This is a sample application provided with C++ library 'ALib'\n"
53 "to demonstrate the use of its module \"ALib App\"."
54 "\n@<<\n" ) EOS
55
56//-------------------- CLI Commands/Options/Parameters/ExitCodes --------------------
57"DateC<", A_CHAR("datesample::Commands::"),
58"DateC", A_CHAR(
59 //enum ident minread Params
60 "1," "now" ",1" "," ","
61 "2," "file" ",1" ",filename" ) EOS
62
63"THlpCmdSht_now", A_CHAR("Reports the actual date/time"),
64"THlpCmdLng_now", A_CHAR("Reports the actual date/time. May be omitted, as this is the\n"
65 "default if no command is given.") EOS
66
67"THlpCmdSht_file", A_CHAR("Returns the date/time of a file. "),
68"THlpCmdLng_file", A_CHAR("Returns the last modification date/time of a file.") EOS
69
70
71"DateO<", A_CHAR("datesample::Options::"),
72"DateO", A_CHAR(
73//enum ident minread identChar in-arg-separ. args to consume ShortcutTo
74 "0," "format" ",1," "f," "=" ",1" "," ) EOS
75
76"TOptUsg_format", A_CHAR("--format[=]\"placeholders\""),
77"TOptHlp_format", A_CHAR("Sets the output format. The format specification is given with\n"
78 "documentation of ALib method CalendarDateTime::Format, found here:\n"
79 "https://alib.dev/classalib_1_1strings_1_1util_1_1CalendarDateTime.html" ) ,
80
81
82"DateP<", A_CHAR("datesample::Parameters::"),
83"DateP", A_CHAR(
84//enum name minIdentLen identifier in-arg-sep delim args to consume isOptional
85// (if empty -> mandatory!)
86"0," "FILENAME" ",1," "" "," "=" "," ",-1" ",0" ) EOS
87
88"THlpParSht_FILENAME", A_CHAR("Mandatory parameter of command 'file."),
89"THlpParLng_FILENAME", A_CHAR("Denotes the file that is used for retrieving the modification date.\n"
90 "This parameter is mandatory to command file and has to be appended\n"
91 "to this command, separated by '='") EOS
92
93"DateE<", A_CHAR("datesample::"),
94"DateE", A_CHAR(
95//enum name assoc. cli exception
96"101," "ErrMissingFilename" ",-1,"
97"102," "ErrFileNotFound" ",-1,"
98"103," "ErrPermissionDenied" ",-1" ) EOS
99
100"TExit101" , A_CHAR("Command 'file' given without a filename argument." ) EOS
101"TExit102" , A_CHAR("File not found." ) EOS
102"TExit103" , A_CHAR("Permission denied." ) EOS
103
104// custom resources
105"FNOTFND" , A_CHAR("The file {!Q} specified with command 'file' was not found.") EOS
106"FNOACC" , A_CHAR("Access denied to file {!Q} specified with command 'file'." ) EOS
107"MSNGFNAME", A_CHAR("Error: no filename given with command 'file'" ) EOS
108
109
110 // end of BootstrapBulk()
111 nullptr );
112
117
118}
119
120bool Sample::cliProcessCmd(alib::cli::Command* cmd ) {
121 if ( AppCli::cliProcessCmd(cmd) )
122 return true;
123
124 if ( cmd == nullptr ) {
125 String128 dateWritten;
126 CalendarDateTime(DateTime()).Format( format, dateWritten );
127 cOut->Add(dateWritten);
128 return true;
129 }
130
131 // Note: Alternatively we could do:
132 // auto actCmdCode= cmd->Declaration->Element();
133 //
134 // if ( actCmdCode == DateCommands::Now ) {
135 // ...
136 // }
137 //
138 // else if ( actCmdCode == DateCommands::File ) {
139 // {
140 // ...
141 //
142 // But the following version lets the compiler assure us that
143 // all custom commands are handled:
144
146 if ( cmd->Declaration->Element().IsEnumType<DateCommands>()) {
147 switch (cmd->Declaration->Element().Get<DateCommands>()) {
148 case DateCommands::Now: {
149 String128 dateWritten;
150 CalendarDateTime(DateTime()).Format( format, dateWritten);
151 cOut->Add(dateWritten);
152 return true;
153 }
154 case DateCommands::File: {
155 // check if filename was given as parameter
156 if(cmd->ParametersMandatory.size() < 1)
157 {
158 cErr->Add(APPCLI_CAMP.GetResource("MSNGFNAME"));
160 CLIUtil::GetHelp( cli, cmd->Declaration->Identifier(), *cOut )
161 ,true)
162 machine.SetExitCode(DateExitCodes::ErrMissingFilename);
163 return true;
164 }
165
166 // get file (or directory) modification date
167 String4K name( cmd->ParametersMandatory.front()->Args.front() );
168 std::filesystem::path stdpath( name.Terminate() );
169 DateTime dt;
170
171 // While class App catches exceptions and provides explicit virtual method
172 // App::exceptionToExitCode() to be overridden, we use the non-throwing version
173 // of std::filesystem::last_write_time. Here is why:
174 // - We have the filename here at hand. No need to pass it over
175 // - while exceptionToExitCode is nice in respect to having all exceptions in
176 // one place, it is also nice to handle an error where it occurs.
177 // So, maybe a matter of taste. And finally we mix it: if we do not handle the
178 // error code here, we then throw!
179 std::error_code errorCode;
180 auto timeValue= std::filesystem::last_write_time( stdpath, errorCode );
181 if ( errorCode.value() != 0 ) {
182 // not found
183 if ( errorCode.value() == int(std::errc::no_such_file_or_directory) ) {
184 cErr->Add( APPCLI_CAMP.GetResource("FNOTFND"), name);
185 machine.SetExitCode( DateExitCodes::ErrFileNotFound );
186 return true;
187 }
188
189 // permission denied
190 if ( errorCode.value() == int(std::errc::permission_denied) ) {
191 cErr->Add( APPCLI_CAMP.GetResource("FNOACC"), name);
192 machine.SetExitCode( DateExitCodes::ErrPermissionDenied );
193 return true;
194 }
195
196 // other errors
198 }
199 dt.Import( std::chrono::clock_cast<std::chrono::system_clock>(timeValue) );
200 String128 dateWritten;
201 CalendarDateTime(dt).Format( format, dateWritten );
202 cOut->Add(dateWritten);
203
204 return true;
205 }
206 }
207 }
208
210
211 return false;
212}
213
214#endif // !DOXYGEN
#define ALIB_ASSERT_RESULT_EQUALS( func, value)
Definition alib.inl:1161
#define ALIB_CALLER_NULLED
Definition alib.inl:1105
#define A_CHAR(STR)
Definition alib.inl:1325
#define ALIB_ALLOW_SWITCH_WITHOUT_DEFAULT
Definition alib.inl:619
#define ALIB_POP_ALLOWANCE
Definition alib.inl:673
static bool GetHelp(CommandLine &cmdLine, const String &topics, Paragraphs &text)
Definition cliutil.cpp:110
const Enum & Element() const
const String & Identifier()
void Import(TTimePoint timePoint)
void Bootstrap(camp::Camp &camp, const NString &name, character innerDelim=',', character outerDelim=',')
Definition camp.inl:265
Exception CreateExceptionFromSystemError(const CallerInfo &ci, std::error_code errorCode)
LocalString< 4096 > String4K
Type alias name for #"TLocalString;TLocalString<character,4096>".
app::AppCliCamp APPCLI_CAMP
The singleton instance of the camp class used by class #"AppCli".
strings::util::CalendarDateTime CalendarDateTime
Type alias in namespace alib.
Definition calendar.inl:512
LocalString< 128 > String128
Type alias name for #"TLocalString;TLocalString<character,128>".
time::DateTime DateTime
Type alias in namespace alib.
Definition datetime.inl:185
bool IsEnumType() const
Definition enum.inl:142
TEnum Get() const
Definition enum.inl:75
A command of a ALib CLI command-line.
CommandDecl * Declaration
The underlying declaration.
ListMA< Parameter *, Recycling::Shared > ParametersMandatory
Mandatory parameters parsed.