mxlib
c++ tools for analyzing astronomical data and other tasks by Jared R. Males. [git repo]
Loading...
Searching...
No Matches
application.cpp
Go to the documentation of this file.
1/** \file application.cpp
2 * \author Jared R. Males
3 * \brief Implementation of a class for managing applications
4 *
5 */
6
7//***********************************************************************//
8// Copyright 2021 Jared R. Males (jaredmales@gmail.com)
9//
10// This file is part of mxlib.
11//
12// mxlib is free software: you can redistribute it and/or modify
13// it under the terms of the GNU General Public License as published by
14// the Free Software Foundation, either version 3 of the License, or
15// (at your option) any later version.
16//
17// mxlib is distributed in the hope that it will be useful,
18// but WITHOUT ANY WARRANTY; without even the implied warranty of
19// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20// GNU General Public License for more details.
21//
22// You should have received a copy of the GNU General Public License
23// along with mxlib. If not, see <http://www.gnu.org/licenses/>.
24//***********************************************************************//
25
26#include "app/application.hpp"
27#include "sys/environment.hpp"
28
29namespace mx
30{
31namespace app
32{
33
34application::~application()
35{
36 return;
37}
38
39int application::main( int argc, char **argv )
40{
41 m_argc = argc;
42 m_argv = argv;
43
44 setup( argc, argv );
45
46 if(m_configOnly)
47 {
48 return 1;
49 }
50
51 if( doHelp )
52 {
53 help();
54 return 1;
55 }
56
57 if( !m_preserveConfig )
58 {
59 config.clear();
60 }
61
62 return execute();
63}
64
65void application::setConfigPathGlobal( const std::string &s )
66{
68}
69
70void application::setConfigPathUser( const std::string &s )
71{
73}
74
75void application::setConfigPathLocal( const std::string &s )
76{
78}
79
80void application::setupConfig() // virtual
81{
82 return;
83}
84
85void application::loadConfig() // virtual
86{
87 return;
88}
89
90int application::execute() // virtual
91{
92 return 0;
93}
94
95void application::setup( int argc, char **argv )
96{
97 invokedName = argv[0];
98
102 setupConfig();
103
104 setDefaults( argc, argv );
105
106 //------------------------------------
107 // First check if help is requested.
108 // This short circuits everything else
109 //------------------------------------
110 config.parseCommandLine( argc, argv, "help" );
111
113
114 if(doHelp)
115 {
116 return;
117 }
118
119 //------------------------------------
120 // Now start reading config files
121 //------------------------------------
123 {
124 doHelp = true;
125 return;
126 }
127
129 {
130 doHelp = true;
131 return;
132 }
133
135 {
136 doHelp = true;
137 return;
138 }
139
140 // Parse CL just to get the CL config.
141 config.parseCommandLine( argc, argv, "config" );
142
143 // And now get the value of it and parse it.
146
147 // Now parse the command line for real.
148 config.parseCommandLine( argc, argv );
149
150 loadStandardHelp(); //Check one more time, could have been config-filed
151
152 if(doHelp)
153 {
154 return;
155 }
156
158 loadConfig();
159
160 checkConfig();
161}
162
164{
168
170
171 // Now parse the command line for real.
173
174 return 0;
175}
176
177void application::setDefaults( int argc, char **argv )
178{
179 static_cast<void>( argc );
180 static_cast<void>( argv );
181
182 std::string tmp;
183
184 if( m_configPathGlobal_env != "" )
185 {
187 }
188
189 if( m_configPathUser_env != "" )
190 {
192 }
193
194 if( m_configPathUser != "" )
195 {
196 // If it's a relative path, add it to the HOME directory
197 if( m_configPathUser[0] != '/' && m_configPathUser[0] != '~' )
198 {
199 tmp = sys::getEnv( "HOME" );
200 tmp += "/" + m_configPathUser;
201 m_configPathUser = tmp;
202 }
203 }
204
205 if( m_configPathLocal_env != "" )
206 {
207 std::string cpl = sys::getEnv( m_configPathLocal_env.c_str() );
208 if(cpl.size() > 0)
209 {
210 m_configPathLocal = cpl;
211 if( m_configPathLocal.back() != '/' )
212 {
213 m_configPathLocal += '/';
214 }
215 }
216 }
217
218 if( m_configPathCLBase_env != "" )
219 {
220 std::string cpclbase = sys::getEnv( m_configPathCLBase_env.c_str() );
221
222 if( cpclbase.size() > 0 )
223 {
224 m_configPathCLBase = cpclbase;
225 if( m_configPathCLBase.back() != '/' )
226 {
227 m_configPathCLBase += '/';
228 }
229 }
230 }
231
232 return;
233}
234
236{
237 config.add( "config", "c", "config", argType::Required, "", "config", false, "string", "A local config file" );
238}
239
241{
242 config.add( "help", "h", "help", argType::True, "", "", false, "none", "Print this message and exit" );
243}
244
250
252{
253 config( doHelp, "help" );
254}
255
257{
258 return;
259}
260
262{
263 return;
264}
265
267{
268 return;
269}
270
272 ioutils::textTable &tt ) // virtual
273{
274 std::string tmp;
275 int row = tgt.orderAdded;
276
277 if( tgt.shortOpt != "" )
278 {
279 tmp = "-" + tgt.shortOpt;
280 tt.addCell( row, 0, tmp );
281 }
282
283 if( tgt.longOpt != "" )
284 {
285 tmp = "--" + tgt.longOpt;
286 tt.addCell( row, 1, tmp );
287 }
288
289 tmp = "";
290 if( tgt.section != "" )
291 {
292 tmp = tgt.section + ".";
293 }
294
295 if( tgt.keyword != "" )
296 {
297 tmp += tgt.keyword;
298 tt.addCell( row, 2, tmp );
299 }
300
301 if( tgt.helpType != "" )
302 {
303 tmp = "<" + tgt.helpType + "> ";
304 tt.addCell( row, 3, tmp );
305 }
306
307 tt.addCell( row, 4, tgt.helpExplanation );
308}
309
310void application::help() // virtual
311{
314
316
318
319 tt.m_colWidths = {
321 tt.m_lineStart = " ";
322 tt.m_colSep = " ";
323 tt.m_rowSep = "";
324
325 std::cerr << "usage: " << invokedName << " [options] " << m_nonOptionHelp << "\n";
326 std::cerr << "\n";
327 std::cerr << " Required arguments:\n";
328
329 for( clOnlyTargIt = config.clOnlyTargets.begin(); clOnlyTargIt != config.clOnlyTargets.end(); ++clOnlyTargIt )
330 {
331 if( clOnlyTargIt->isRequired == true )
332 {
333 optionHelp( *clOnlyTargIt, tt );
334 }
335 }
336
337 for( targIt = config.m_targets.begin(); targIt != config.m_targets.end(); ++targIt )
338 {
339 if( targIt->second.isRequired == true )
340 {
341 optionHelp( targIt->second, tt );
342 }
343 }
344
345 tt.outPut( std::cerr );
346 tt.m_rows.clear();
347
348 // row = 0;
349 std::cerr << "\n Optional arguments:\n";
350
351 for( clOnlyTargIt = config.clOnlyTargets.begin(); clOnlyTargIt != config.clOnlyTargets.end(); ++clOnlyTargIt )
352 {
353 if( clOnlyTargIt->isRequired == false )
354 {
355 optionHelp( *clOnlyTargIt, tt );
356 }
357 }
358
359 for( targIt = config.m_targets.begin(); targIt != config.m_targets.end(); ++targIt )
360 {
361 if( targIt->second.isRequired == false )
362 {
363 optionHelp( targIt->second, tt );
364 }
365 }
366
367 tt.outPut( std::cerr );
368}
369
370} // namespace app
371} // namespace mx
A class for managing application configuration and execution.
virtual void setup(int argc, char **argv)
Sets up the application by executing the configuration steps.
std::string invokedName
The name used to invoke this application.
std::string m_configPathCLBase
A base path to add to the CL path. Set in constructor to use.
virtual void setupStandardConfig()
Set up the command-line config option in a standard way.
std::string m_configPathUser
bool m_requireConfigPathUser
Flag controlling whether lack of a user configuration file should be reported.
std::string m_configPathUser_env
Environment variable to check fo the user config path. Set in constructor to use.
virtual void checkConfig()
Check the config. This is called at the end of setup, before the configuration is cleared.
virtual void setupStandardHelp()
Set up the help an options in a standard way.
virtual void loadBasicConfig()
int reReadConfig()
Re-read the config stack.
virtual void loadStandardConfig()
Loads the values of "config".
int main(int argc, char **argv)
The application main function.
char ** m_argv
Store argv for later use. E.g. in reReadConfig().
virtual void loadConfig()
Override this function to extract the configured values and set up the application.
int m_argc
Store argc for later use. E.g. in reReadConfig().
void setConfigPathUser(const std::string &s)
Set the user configuration path.
std::string m_configPathLocal_env
Environment variable to check for the local config path. Set in constructor to use.
int m_helpLOColWidth
The width of the long option (–option) column in the help message.
int m_helpCFColWidth
The width of the config file option column in the help message.
int m_helpTypeColWidth
The width of the argument type column in the help message.
appConfigurator config
The structure used for parsing and storing the configuration.
bool m_requireConfigPathLocal
Flag controlling whether lack of a local configuration file should be reported.
int m_helpWidth
The total text width available for the help message.
virtual void optionHelp(configTarget &tgt, ioutils::textTable &tt)
Format a configTarget for the help message.
virtual void setDefaults(int argc, char **argv)
Set the default search paths for config files.
virtual void help()
Print a formatted help message, based on the config target inputs.
virtual void setupBasicConfig()
virtual int execute()
This function is where the derived class should do its work.
std::string m_configPathCL
The path to a configuration file specified on the command line.
std::string m_configPathGlobal
The path to the gobal configuration file. Set in constructor to use.
virtual void loadStandardHelp()
Loads the value of "help" into m_doHelp.
std::string m_configPathGlobal_env
void setConfigPathGlobal(const std::string &s)
Set the global configuration path.
virtual void setupConfig()
In derived classes this is where the config targets are added to config.
int m_helpSOColWidth
The width of the short option (-o) column in the help message.
std::string m_configPathLocal
The path to a local configuration file. Set in constructor to use.
std::string m_configPathCLBase_env
Environment variable to check for the CL base path. Set in constructor to use.
std::string m_nonOptionHelp
String to print to describe non-option arguments.
void setConfigPathLocal(const std::string &s)
Set the local configuration path.
bool m_requireConfigPathGlobal
Flag controlling whether lack of a global configuration file should be reported.
Utilities for working with the environment.
void outPut(iosT &ios)
Output the table to a stream.
std::string getEnv(const std::string &estr)
Return the value of an environment variable.
The mxlib c++ namespace.
Definition mxlib.hpp:37
std::unordered_map< std::string, configTarget > m_targets
The targets are stored in an unordered_map for fast access by key.
int readConfig(const std::string &fname, bool reportFileNotFound=true)
Read and parse a config/ini file, updating the targets.
void add(const configTarget &tgt)
Add a configTarget.
std::unordered_map< std::string, configTarget >::iterator targetIterator
Iterator for the targets unordered_map.
void clear()
Clear the containers and free up the associated memory.
std::list< configTarget > clOnlyTargets
Targets which are only for the command line are stored separately in a list.
void parseCommandLine(int argc, char **argv, const std::string &oneTarget="")
Parse the command line, updating the targets.
std::list< configTarget >::iterator clOnlyTargetIterator
Iterator for the clOnlyTargets list.
A configuration target.
std::string helpExplanation
The explanation to display in the help message.
std::string keyword
The config file keyword, read in a "keyword=value" pair.
int orderAdded
The order in which this was added. Useful for displaying help messages.
std::string section
The config file section name, can be empty "".
std::string helpType
The type to display in the help message.
std::string shortOpt
The command-line short option (e.g. "f" for -f)
std::string longOpt
The command-line long option (e.g. "file" for –file)
An ascii table formatter.
Definition textTable.hpp:61
std::string m_lineStart
Text to print at the beginning of the line.
Definition textTable.hpp:69
std::vector< int > m_colWidths
The widths of each column, not including the separator.
Definition textTable.hpp:62
std::string m_rowSep
Text to print between each row.
Definition textTable.hpp:75
void addCell(size_t row, size_t col, const std::string &cell)
Add one cell to the table, overwriting if it already exists.
Definition textTable.cpp:36
std::string m_colSep
Text to print between each column.
Definition textTable.hpp:73
std::vector< std::vector< std::vector< std::string > > > m_rows
The table cells.
Definition textTable.hpp:67