source: trunk/FACT++/src/Configuration.h@ 14098

Last change on this file since 14098 was 13669, checked in by tbretz, 13 years ago
Added GetWildcardOptions and GetOptions to be able to access all available wildcard options of one kind at once; replaced some iterator defintions with the auto keyword for conevenience
File size: 9.1 KB
Line 
1#ifndef FACT_Configuration
2#define FACT_Configuration
3
4#include <iostream>
5#include <boost/program_options.hpp>
6
7namespace po = boost::program_options;
8
9class Configuration
10{
11private:
12 /// Convienience enum to access the fOption* data memebers more verbosely.
13 enum
14 {
15 kHidden = 0, ///< Index for hidden options (not shown in PrintParsed)
16 kVisible = 1 ///< Index for options visible in PrintParsed
17 };
18
19 const std::string fName; /// argv[0]
20
21 std::map<std::string, std::string> fEnvMap;
22
23 po::options_description fOptionsCommandline[2]; /// Description of the command-line options
24 po::options_description fOptionsConfigfile[2]; /// Description of the options in the configuration file
25 po::options_description fOptionsDatabase[2]; /// Description of options from the database
26 po::options_description fOptionsEnvironment[2]; /// Description of options from the environment
27
28 po::positional_options_description fArgumentPositions; /// Description of positional command-line options (arguments)
29
30 std::vector<std::string> fUnknownCommandline; /// Storage container for unrecognized commandline options
31 std::vector<std::string> fUnknownConfigfile; /// Storage container for unrecognized options from configuration files
32 std::vector<std::string> fUnknownEnvironment; /// Storage container for unrecognized options from the environment
33 std::vector<std::string> fUnknownDatabase; /// Storage container for unrecognized options retrieved from the database
34
35 std::map<std::string, std::string> fWildcardOptions; /// Options which were registered using wildcards
36
37 std::string fPriorityFile; /// File name of the priority configuration file (overwrites option from the databse)
38 std::string fDefaultFile; /// File name of the default configuration file (usually {program}.rc)
39 std::string fDatabase; /// URL for database connection (see Configuration::parse_database)
40
41 po::variables_map fVariables; /// Variables as compiled by the Parse-function, which will be passed to the program
42
43 /// A default mapper for environment variables skipping all of them
44 std::string DefaultMapper(const std::string env)
45 {
46 return fEnvMap[env];
47 }
48
49 /// Pointer to the mapper function for environment variables
50 std::function<std::string(std::string)> fNameMapper;
51 std::function<void()> fPrintUsage;
52 std::function<void(const std::string&)> fPrintVersion;
53
54 /// Helper function which return the max of the two arguments in the first argument
55 static void Max(int &val, const int &comp)
56 {
57 if (comp>val)
58 val=comp;
59 }
60
61 /// Helper for Parse to create list of used wildcard options
62 void CreateWildcardOptions();
63
64 // Helper functions for PrintOptions and GetOptions
65 template<class T>
66 std::string VecAsStr(const po::variable_value &v) const;
67 std::string VarAsStr(const po::variable_value &v) const;
68
69 /// Print all options from a list of already parsed options
70 void PrintParsed(const po::parsed_options &parsed) const;
71 /// Print a list of all unkown options within the given vector
72 void PrintUnknown(const std::vector<std::string> &vec, int steps=1) const;
73
74 virtual void PrintUsage() const { }
75 virtual void PrintVersion() const;
76
77 std::string UnLibToolize(const std::string &src) const;
78
79public:
80 Configuration(const std::string &prgname="");
81 virtual ~Configuration() { }
82
83 /// Retrieve data from a database and return them as options
84 static po::basic_parsed_options<char>
85 parse_database(const std::string &prgname, const std::string &database, const po::options_description& desc, bool allow_unregistered=false);
86
87 // Setup
88 void AddOptionsCommandline(const po::options_description &cl, bool visible=true);
89 void AddOptionsConfigfile(const po::options_description &cf, bool visible=true);
90 void AddOptionsEnvironment(const po::options_description &env, bool visible=true);
91 void AddOptionsDatabase(const po::options_description &db, bool visible=true);
92 void AddOptions(const po::options_description &opt, bool visible=true)
93 {
94 AddOptionsCommandline(opt, visible);
95 AddOptionsConfigfile(opt, visible);
96 AddOptionsEnvironment(opt, visible);
97 AddOptionsDatabase(opt, visible);
98 }
99
100 void SetArgumentPositions(const po::positional_options_description &desc);
101
102 void SetNameMapper(const std::function<std::string(std::string)> &func);
103 void SetNameMapper();
104
105 void SetPrintUsage(const std::function<void(void)> &func);
106 void SetPrintUsage();
107
108 void SetPrintVersion(const std::function<void(const std::string &)> &func);
109 void SetPrintVersion();
110
111 void AddEnv(const std::string &conf, const std::string &env)
112 {
113 fEnvMap[env] = conf;
114 }
115
116 // Output
117 void PrintOptions() const;
118 void PrintUnknown() const;
119 void PrintWildcardOptions() const;
120
121 const std::map<std::string,std::string> &GetWildcardOptions() const { return fWildcardOptions; }
122 const std::vector<std::string> GetWildcardOptions(const std::string &opt) const;
123
124 template<class T>
125 const std::map<std::string,T> GetOptions(const std::string &opt)
126 {
127 const std::vector<std::string> rc = GetWildcardOptions(opt+'*');
128
129 std::map<std::string,T> map;
130 for (auto it=rc.begin(); it!=rc.end(); it++)
131 map[it->substr(opt.length())] = Get<T>(*it);
132
133 return map;
134 }
135
136 std::multimap<std::string, std::string> GetOptions() const;
137
138 // Process command line arguments
139 const po::variables_map &Parse(int argc, const char **argv, const std::function<void()> &func=std::function<void()>());
140 bool DoParse(int argc, const char **argv, const std::function<void()> &func=std::function<void()>());
141
142 bool HasVersion()
143 {
144 return Has("version");
145 }
146
147 bool HasHelp()
148 {
149 return Has("help") || Has("help-config") || Has("help-env") || Has("help-database");
150 }
151
152 bool HasPrint()
153 {
154 return Has("print-all") || Has("print") || Has("print-default") ||
155 Has("print-database") || Has("print-config") ||
156 Has("print-environment") || Has("print-unknown") ||
157 Has("print-options") || Has("print-wildcards");
158 }
159
160 // Simplified access to the parsed options
161 template<class T>
162 T Get(const std::string &var) { fWildcardOptions.erase(var); return fVariables[var].as<T>(); }
163 bool Has(const std::string &var) { fWildcardOptions.erase(var); return fVariables.count(var)>0; }
164
165 template<class T>
166 std::vector<T> Vec(const std::string &var) { return Has(var) ? fVariables[var].as<std::vector<T>>() : std::vector<T>(); }
167
168 template<class T, class S>
169 T Get(const std::string &var, const S &val)
170 {
171 std::ostringstream str;
172 str << var << val;
173 return Get<T>(str.str());
174 }
175
176 template<class T>
177 bool Has(const std::string &var, const T &val)
178 {
179 std::ostringstream str;
180 str << var << val;
181 return Has(str.str());
182 }
183
184 template<class T, class S>
185 T GetDef(const std::string &var, const S &val)
186 {
187 return Has(var, val) ? Get<T>(var, val) : Get<T>(var+"default");
188 }
189
190 template<class T>
191 bool HasDef(const std::string &var, const T &val)
192 {
193 // Make sure the .default option is touched
194 const bool rc = Has(var+"default");
195
196 return Has(var, val) ? true : rc;
197 }
198/*
199 template<class T>
200 std::map<std::string, T> GetMap(const std::string &var)
201 {
202 const size_t len = var.length();
203
204 std::map<std::string, T> rc;
205 for (std::map<std::string, boost::program_options::variable_value>::const_iterator it=fVariables.begin();
206 it!=fVariables.end(); it++)
207 if (it->first.substr(0, len)==var)
208 rc[it->first] = it->second.as<T>();
209
210 return rc;
211 }
212
213 template<class T>
214 std::vector<std::string> GetKeys(const std::string &var)
215 {
216 const size_t len = var.length();
217
218 std::vector<std::string> rc;
219 for (std::map<std::string, boost::program_options::variable_value>::const_iterator it=fVariables.begin();
220 it!=fVariables.end(); it++)
221 if (it->first.substr(0, len)==var)
222 rc.push_back(it->first);
223
224 return rc;
225 }
226*/
227 const std::string &GetName() const { return fName; }
228};
229
230template<typename T>
231struct Hex
232{
233 T val;
234 Hex() { }
235 Hex(const T &v) : val(v) { }
236 operator T() const { return val; }
237};
238template<typename T>
239std::istream &operator>>(std::istream &in, Hex<T> &rc)
240{
241 T val;
242 in >> std::hex >> val;
243 rc.val = val;
244 return in;
245}
246
247template<class T>
248inline po::typed_value<T> *var(T *ptr=0)
249{ return po::value<T>(ptr); }
250
251template<class T>
252inline po::typed_value<T> *var(const T &val, T *ptr=0)
253{ return po::value<T>(ptr)->default_value(val); }
254
255template<class T>
256inline po::typed_value<std::vector<T>> *vars()
257{ return po::value<std::vector<T>>(); }
258
259inline po::typed_value<bool> *po_switch()
260{ return po::bool_switch(); }
261
262inline po::typed_value<bool> *po_bool(bool def=false)
263{ return po::value<bool>()->implicit_value(true)->default_value(def); }
264
265#endif
Note: See TracBrowser for help on using the repository browser.