mxlib
c++ tools for analyzing astronomical data and other tasks by Jared R. Males. [git repo]
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 
29 namespace mx
30 {
31 namespace app
32 {
33 
34 application::~application()
35 {
36  return;
37 }
38 
39 int application::main( int argc,
40  char **argv
41  )
42 {
43  m_argc = argc;
44  m_argv = argv;
45 
46  setup(argc, argv);
47 
48  if(doHelp)
49  {
50  help();
51  return 1;
52  }
53 
54  if(!m_preserveConfig)
55  {
56  config.clear();
57  }
58 
59  return execute();
60 }
61 
62 void application::setConfigPathGlobal(const std::string & s)
63 {
65 }
66 
67 void application::setConfigPathUser(const std::string & s)
68 {
69  m_configPathUser = s;
70 }
71 
72 void application::setConfigPathLocal( const std::string & s )
73 {
75 }
76 
77 void application::setupConfig() //virtual
78 {
79  return;
80 }
81 
82 void application::loadConfig() //virtual
83 {
84  return;
85 }
86 
87 int application::execute() //virtual
88 {
89  return 0;
90 }
91 
92 void application::setup( int argc,
93  char ** argv
94  )
95 {
96  invokedName = argv[0];
97 
100 
102  setupConfig();
103 
104  setDefaults(argc, argv);
105 
109 
110  //Parse CL just to get the CL config.
111  config.parseCommandLine(argc, argv, "config");
112 
113  //And now get the value of it and parse it.
116 
117  //Now parse the command line for real.
118  config.parseCommandLine(argc, argv);
119 
121 
122  loadBasicConfig();
123  loadConfig();
124 
125  checkConfig();
126 }
127 
129 {
133 
135 
136  //Now parse the command line for real.
138 
139  return 0;
140 }
141 
142 void application::setDefaults( int argc,
143  char ** argv
144  )
145 {
146  static_cast<void>(argc);
147  static_cast<void>(argv);
148 
149  std::string tmp;
150 
151  if(m_configPathGlobal_env != "")
152  {
154  }
155 
156  if( m_configPathUser_env != "")
157  {
159  }
160 
161  if(m_configPathUser != "")
162  {
163  //If it's a relative path, add it to the HOME directory
164  if(m_configPathUser[0] != '/' && m_configPathUser[0] != '~')
165  {
166  tmp = sys::getEnv("HOME");
167  tmp += "/" + m_configPathUser;
168  m_configPathUser = tmp;
169  }
170  }
171 
172  if(m_configPathLocal_env != "")
173  {
175  }
176 
177  if(m_configPathCLBase_env != "")
178  {
180 
181  if(m_configPathCLBase.size()>0)
182  if(m_configPathCLBase[m_configPathCLBase.size()-1] != '/')
183  m_configPathCLBase += '/';
184  }
185 
186  return;
187 
188 }
189 
191 {
192  config.add("config","c", "config",argType::Required, "", "config", false, "string", "A local config file");
193 }
194 
196 {
197  config.add("help", "h", "help", argType::True, "", "", false, "none", "Print this message and exit");
198 }
199 
201 {
202  config(m_configPathCL, "config");
204 }
205 
207 {
208  config(doHelp, "help");
209 }
210 
212 {
213  return;
214 }
215 
217 {
218  return;
219 }
220 
221 void application::checkConfig() //virtual
222 {
223  return;
224 }
225 
227  ioutils::textTable & tt
228  ) //virtual
229 {
230  std::string tmp;
231  int row = tgt.orderAdded;
232 
233  if(tgt.shortOpt != "")
234  {
235  tmp = "-" + tgt.shortOpt;
236  tt.addCell(row, 0, tmp);
237  }
238 
239  if(tgt.longOpt != "")
240  {
241  tmp = "--" + tgt.longOpt;
242  tt.addCell(row, 1, tmp);
243  }
244 
245  tmp = "";
246  if(tgt.section != "")
247  {
248  tmp = tgt.section + ".";
249  }
250 
251  if(tgt.keyword !="")
252  {
253  tmp += tgt.keyword;
254  tt.addCell(row, 2, tmp);
255  }
256 
257  if(tgt.helpType != "")
258  {
259  tmp = "<" + tgt.helpType + "> ";
260  tt.addCell(row, 3, tmp);
261  }
262 
263  tt.addCell(row, 4, tgt.helpExplanation);
264 
265 
266 }
267 
268 void application::help() //virtual
269 {
272 
274 
276 
278  tt.m_lineStart = " ";
279  tt.m_colSep = " ";
280  tt.m_rowSep = "";
281 
282  std::cerr << "usage: " << invokedName << " [options] \n";
283  std::cerr << "\n";
284  std::cerr << " Required arguments:\n";
285 
286  for( clOnlyTargIt = config.clOnlyTargets.begin(); clOnlyTargIt != config.clOnlyTargets.end(); ++clOnlyTargIt)
287  {
288  if( clOnlyTargIt->isRequired == true)
289  {
290  optionHelp(*clOnlyTargIt, tt);
291  }
292  }
293 
294  for( targIt = config.m_targets.begin(); targIt != config.m_targets.end(); ++targIt)
295  {
296  if( targIt->second.isRequired == true)
297  {
298  optionHelp(targIt->second, tt);
299  }
300  }
301 
302  tt.outPut(std::cerr);
303  tt.m_rows.clear();
304 
305  //row = 0;
306  std::cerr << "\n Optional arguments:\n";
307 
308  for( clOnlyTargIt = config.clOnlyTargets.begin(); clOnlyTargIt != config.clOnlyTargets.end(); ++clOnlyTargIt)
309  {
310  if( clOnlyTargIt->isRequired == false)
311  {
312  optionHelp(*clOnlyTargIt, tt);
313  }
314  }
315 
316  for( targIt = config.m_targets.begin(); targIt != config.m_targets.end(); ++targIt)
317  {
318  if( targIt->second.isRequired == false)
319  {
320  optionHelp(targIt->second, tt);
321  }
322  }
323 
324  tt.outPut(std::cerr);
325 
326 }
327 
328 } //namespace app
329 } //namespace mx
330 
A class for managing application configuration and execution.
virtual void setup(int argc, char **argv)
Sets up the application by executing the configuration steps.
Definition: application.cpp:92
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
The path to the user's configuration file. If the first character is not '/' or '~',...
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.
bool doHelp
Flag to control whether the help message is printed or not.
virtual void loadBasicConfig()
Load a basic configuration. Can be used in an intermediate derived class to allow its children to use...
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.
Definition: application.cpp:39
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.
Definition: application.cpp:82
int m_argc
Store argc for later use. E.g. in reReadConfig().
void setConfigPathUser(const std::string &s)
Set the user configuration path.
Definition: application.cpp:67
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.
bool m_preserveConfig
Flag controlling whether the configuration is cleared before execution. Set in derived constructor.
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()
Setup a basic configuration. Can be used in an intermediate derived class to allow its children to us...
virtual int execute()
This function is where the derived class should do its work.
Definition: application.cpp:87
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 doHelp.
std::string m_configPathGlobal_env
Environment variable to check for the global config path. Set in constructor to use.
void setConfigPathGlobal(const std::string &s)
Set the global configuration path.
Definition: application.cpp:62
virtual void setupConfig()
In derived classes this is where the config targets are added to config.
Definition: application.cpp:77
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.
void setConfigPathLocal(const std::string &s)
Set the local configuration path.
Definition: application.cpp:72
Utilities for working with the environment.
void outPut(iosT &ios)
Output the table to a stream.
Definition: textTable.hpp:117
std::string getEnv(const std::string &estr)
Return the value of an environment variable.
Definition: environment.cpp:33
The mxlib c++ namespace.
Definition: mxError.hpp:107
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.
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::unordered_map< std::string, configTarget >::iterator targetIterator
Iterator for the targets unordered_map.
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