Scarab  v2.2.3
Project 8 C++ Utility Library
application.cc
Go to the documentation of this file.
1 /*
2  * application.cc
3  *
4  * Created on: Jul 20, 2018
5  * Author: N.S. Oblath
6  */
7 
8 #include "application.hh"
9 
10 #include "logger.hh"
11 #include "nonoption_parser.hh"
12 #include "param_codec.hh"
13 #include "version_wrapper.hh"
14 
15 using std::string;
16 
17 namespace scarab
18 {
19  LOGGER( applog, "application" );
20 
22  app(),
23  f_master_config(),
24  f_default_config(),
25  f_config_filename(),
26  f_global_verbosity( 1 ),
27  f_nonoption_kw_args(),
28  f_nonoption_ord_args(),
29  f_app_options()
30  {
31  allow_extras(); // allow unrecognized options, which are parsed into the nonoption args
32 
33  add_option( "-c,--config", f_config_filename, "Config file filename" )->check(CLI::ExistingFile);
34  add_option( "--verbosity", f_global_verbosity, "Global logger verosity" );
35 
36  auto t_version_callback = [](int)
37  {
38  LPROG( applog, '\n' << version_wrapper::get_instance()->version_info_string() );
39  throw CLI::Success();
40  };
41  add_flag_function( "-V,--version", t_version_callback, "Print the version message and exit" );
42  }
43 
45  {
46  }
47 
49  {
51  }
52 
54  {
55  // first configuration stage: defaults
56  f_master_config.merge( f_default_config );
57 
58  applog.SetGlobalLevel( (logger::ELevel)f_global_verbosity );
59 
60  // second configuration stage: config file
61  if( ! f_config_filename.empty() )
62  {
63  path t_config_filepath = scarab::expand_path( f_config_filename );
64  LDEBUG( applog, "Loading config file <" << t_config_filepath << "> from filename <" << f_config_filename << ">" );
65  param_translator t_translator;
66  std::unique_ptr< param > t_config_from_file( t_translator.read_file( t_config_filepath.native() ));
67  if( t_config_from_file == NULL )
68  {
69  throw error() << "[application] error parsing config file";
70  }
71  if( ! t_config_from_file->is_node() )
72  {
73  throw error() << "[application] configuration file must consist of an object/node";
74  }
75  f_master_config.merge( t_config_from_file->as_node() );
76  }
77 
78  try
79  {
80  nonoption_parser t_no_parser( remaining() );
81  f_nonoption_kw_args = t_no_parser.kw_args();
82  f_nonoption_ord_args = t_no_parser.ord_args();
83  }
84  catch( error& e )
85  {
86  LERROR( applog, "Unable to parse remaining arguments: " << e.what() );
87  throw CLI::ParseError( std::string("Unable to parse remaining arguments due to parse error or unknown option: ") + e.what(), CLI::ExitCodes::ArgumentMismatch );
88  }
89 
90  // third configuration stage: keyword args
91  //LDEBUG( applog, "adding command-line parser:\n" << t_parser << *f_master_config );
92  f_master_config.merge( f_nonoption_kw_args );
93 
94  // fourth configuration stage: application options
95  f_master_config.merge( f_app_options );
96 
97  LPROG( applog, "Final configuration:\n" << f_master_config );
98  LPROG( applog, "Ordered args:\n" << f_nonoption_ord_args );
99  }
100 
101 } /* namespace scarab */
fs::path path
Definition: path.hh:25
path expand_path(const string &a_path)
Definition: path.cc:19
static version_wrapper * get_instance()
CLI::App app
Definition: application.hh:18
#define LPROG(...)
Definition: logger.hh:363
#define LERROR(...)
Definition: logger.hh:365
virtual const char * what() const
Definition: error.cc:25
Contains the logger class and macros, based on Kasper&#39;s KLogger class.
virtual void pre_callback()
Definition: application.cc:53
#define LDEBUG(...)
Definition: logger.hh:360
void set_imp(scarab::version_semantic *a_imp)
param_ptr_t read_file(const std::string &a_filename, const param_node &a_options=param_node())
Definition: param_codec.cc:47
void set_version(version_semantic *a_ver)
Definition: application.cc:48
This is a successful completion on parsing, supposed to exit.
Definition: CLI11.hpp:541
virtual ~main_app()
Definition: application.cc:44
Anything that can error in Parse.
Definition: CLI11.hpp:534
LOGGER(mtlog,"authentication")