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

Last change on this file since 12717 was 12315, checked in by tbretz, 13 years ago
Make sure that the default option gets touched even it is finally not needed.
File size: 8.6 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
123 std::multimap<std::string, std::string> GetOptions() const;
124
125 // Process command line arguments
126 const po::variables_map &Parse(int argc, const char **argv);
127 bool DoParse(int argc, const char **argv, const std::function<void()> &func=std::function<void()>());
128
129 bool HasVersion()
130 {
131 return Has("version");
132 }
133
134 bool HasHelp()
135 {
136 return Has("help") || Has("help-config") || Has("help-env") || Has("help-database");
137 }
138
139 bool HasPrint()
140 {
141 return Has("print-all") || Has("print") || Has("print-default") ||
142 Has("print-database") || Has("print-config") ||
143 Has("print-environment") || Has("print-unknown") ||
144 Has("print-options") || Has("print-wildcards");
145 }
146
147 // Simplified access to the parsed options
148 template<class T>
149 T Get(const std::string &var) { fWildcardOptions.erase(var); return fVariables[var].as<T>(); }
150 bool Has(const std::string &var) { fWildcardOptions.erase(var); return fVariables.count(var)>0; }
151
152 template<class T>
153 std::vector<T> Vec(const std::string &var) { return Has(var) ? fVariables[var].as<std::vector<T>>() : std::vector<T>(); }
154
155 template<class T, class S>
156 T Get(const std::string &var, const S &val)
157 {
158 std::ostringstream str;
159 str << var << val;
160 return Get<T>(str.str());
161 }
162
163 template<class T>
164 bool Has(const std::string &var, const T &val)
165 {
166 std::ostringstream str;
167 str << var << val;
168 return Has(str.str());
169 }
170
171 template<class T, class S>
172 T GetDef(const std::string &var, const S &val)
173 {
174 return Has(var, val) ? Get<T>(var, val) : Get<T>(var+"default");
175 }
176
177 template<class T>
178 bool HasDef(const std::string &var, const T &val)
179 {
180 // Make sure the .default option is touched
181 const bool rc = Has(var+"default");
182
183 return Has(var, val) ? true : rc;
184 }
185/*
186 template<class T>
187 std::map<std::string, T> GetMap(const std::string &var)
188 {
189 const size_t len = var.length();
190
191 std::map<std::string, T> rc;
192 for (std::map<std::string, boost::program_options::variable_value>::const_iterator it=fVariables.begin();
193 it!=fVariables.end(); it++)
194 if (it->first.substr(0, len)==var)
195 rc[it->first] = it->second.as<T>();
196
197 return rc;
198 }
199
200 template<class T>
201 std::vector<std::string> GetKeys(const std::string &var)
202 {
203 const size_t len = var.length();
204
205 std::vector<std::string> rc;
206 for (std::map<std::string, boost::program_options::variable_value>::const_iterator it=fVariables.begin();
207 it!=fVariables.end(); it++)
208 if (it->first.substr(0, len)==var)
209 rc.push_back(it->first);
210
211 return rc;
212 }
213*/
214 const std::string &GetName() const { return fName; }
215};
216
217template<typename T>
218struct Hex
219{
220 T val;
221 Hex() { }
222 Hex(const T &v) : val(v) { }
223 operator T() const { return val; }
224};
225template<typename T>
226std::istream &operator>>(std::istream &in, Hex<T> &rc)
227{
228 T val;
229 in >> std::hex >> val;
230 rc.val = val;
231 return in;
232}
233
234template<class T>
235inline po::typed_value<T> *var(T *ptr=0)
236{ return po::value<T>(ptr); }
237
238template<class T>
239inline po::typed_value<T> *var(const T &val, T *ptr=0)
240{ return po::value<T>(ptr)->default_value(val); }
241
242template<class T>
243inline po::typed_value<std::vector<T>> *vars()
244{ return po::value<std::vector<T>>(); }
245
246inline po::typed_value<bool> *po_switch()
247{ return po::bool_switch(); }
248
249inline po::typed_value<bool> *po_bool(bool def=false)
250{ return po::value<bool>()->implicit_value(true)->default_value(def); }
251
252#endif
Note: See TracBrowser for help on using the repository browser.