|
a/src/utils/conftree.h |
|
b/src/utils/conftree.h |
|
... |
|
... |
40 |
*/
|
40 |
*/
|
41 |
|
41 |
|
42 |
#include <string>
|
42 |
#include <string>
|
43 |
#include <map>
|
43 |
#include <map>
|
44 |
#include <list>
|
44 |
#include <list>
|
|
|
45 |
|
45 |
// rh7.3 likes iostream better...
|
46 |
// rh7.3 likes iostream better...
|
46 |
#if defined(__GNUC__) && __GNUC__ < 3
|
47 |
#if defined(__GNUC__) && __GNUC__ < 3
|
47 |
#include <iostream>
|
48 |
#include <iostream>
|
48 |
#else
|
49 |
#else
|
49 |
#include <istream>
|
50 |
#include <istream>
|
|
... |
|
... |
51 |
|
52 |
|
52 |
#ifndef NO_NAMESPACES
|
53 |
#ifndef NO_NAMESPACES
|
53 |
using std::string;
|
54 |
using std::string;
|
54 |
using std::list;
|
55 |
using std::list;
|
55 |
using std::map;
|
56 |
using std::map;
|
|
|
57 |
using std::istream;
|
56 |
#endif // NO_NAMESPACES
|
58 |
#endif // NO_NAMESPACES
|
|
|
59 |
|
|
|
60 |
#include "pathut.h"
|
57 |
|
61 |
|
58 |
/**
|
62 |
/**
|
59 |
* Manages a simple configuration file with subsections.
|
63 |
* Manages a simple configuration file with subsections.
|
60 |
*/
|
64 |
*/
|
61 |
class ConfSimple {
|
65 |
class ConfSimple {
|
62 |
public:
|
66 |
public:
|
63 |
enum StatusCode {STATUS_ERROR=0, STATUS_RO=1, STATUS_RW=2};
|
67 |
enum StatusCode {STATUS_ERROR=0, STATUS_RO=1, STATUS_RW=2};
|
64 |
|
68 |
|
65 |
/**
|
69 |
/**
|
66 |
* Build the object by reading content from file.
|
70 |
* Build the object by reading content from file.
|
67 |
* @param filename file to open
|
71 |
* @param filename file to open
|
|
... |
|
... |
90 |
/**
|
94 |
/**
|
91 |
* Get value for named parameter, from specified subsection (looks in
|
95 |
* Get value for named parameter, from specified subsection (looks in
|
92 |
* global space if sk is empty).
|
96 |
* global space if sk is empty).
|
93 |
* @return 0 if name not found, 1 else
|
97 |
* @return 0 if name not found, 1 else
|
94 |
*/
|
98 |
*/
|
95 |
virtual int get(const std::string &name, string &value,
|
99 |
virtual int get(const string &name, string &value,
|
96 |
const string &sk = string(""));
|
100 |
const string &sk = string(""));
|
97 |
/* Note: the version returning char* was buggy and has been removed */
|
101 |
/* Note: the version returning char* was buggy and has been removed */
|
98 |
|
102 |
|
99 |
/**
|
103 |
/**
|
100 |
* Set value for named parameter in specified subsection (or global)
|
104 |
* Set value for named parameter in specified subsection (or global)
|
101 |
* @return 0 for error, 1 else
|
105 |
* @return 0 for error, 1 else
|
102 |
*/
|
106 |
*/
|
103 |
virtual int set(const std::string &nm, const std::string &val,
|
107 |
virtual int set(const string &nm, const string &val,
|
104 |
const std::string &sk);
|
108 |
const string &sk);
|
105 |
virtual int set(const char *name, const char *value, const char *sk = 0);
|
109 |
virtual int set(const char *name, const char *value, const char *sk = 0);
|
106 |
|
110 |
|
107 |
/**
|
111 |
/**
|
108 |
* Remove name and value from config
|
112 |
* Remove name and value from config
|
109 |
*/
|
113 |
*/
|
110 |
virtual int erase(const std::string &name, const std::string &sk);
|
114 |
virtual int erase(const string &name, const string &sk);
|
111 |
|
115 |
|
112 |
virtual StatusCode getStatus();
|
116 |
virtual StatusCode getStatus();
|
113 |
virtual bool ok() {return getStatus() != STATUS_ERROR;}
|
117 |
virtual bool ok() {return getStatus() != STATUS_ERROR;}
|
114 |
|
118 |
|
115 |
/**
|
119 |
/**
|
|
... |
|
... |
119 |
* @return WALK_STOP when/if the callback returns WALK_STOP,
|
123 |
* @return WALK_STOP when/if the callback returns WALK_STOP,
|
120 |
* WALK_CONTINUE else (got to end of config)
|
124 |
* WALK_CONTINUE else (got to end of config)
|
121 |
*/
|
125 |
*/
|
122 |
enum WalkerCode {WALK_STOP, WALK_CONTINUE};
|
126 |
enum WalkerCode {WALK_STOP, WALK_CONTINUE};
|
123 |
virtual WalkerCode sortwalk(WalkerCode
|
127 |
virtual WalkerCode sortwalk(WalkerCode
|
124 |
(*wlkr)(void *cldata, const std::string &nm,
|
128 |
(*wlkr)(void *cldata, const string &nm,
|
125 |
const std::string &val),
|
129 |
const string &val),
|
126 |
void *clidata);
|
130 |
void *clidata);
|
127 |
virtual void list();
|
131 |
virtual void listall();
|
128 |
|
132 |
|
129 |
/**
|
133 |
/**
|
130 |
* Return all names in given submap
|
134 |
* Return all names in given submap
|
131 |
*/
|
135 |
*/
|
132 |
virtual std::list<string> getNames(const string &sk);
|
136 |
virtual list<string> getNames(const string &sk);
|
133 |
|
137 |
|
134 |
virtual std::string getFilename() {return filename;}
|
138 |
virtual string getFilename() {return filename;}
|
135 |
|
139 |
|
136 |
/**
|
140 |
/**
|
137 |
* Copy constructor. Expensive but less so than a full rebuild
|
141 |
* Copy constructor. Expensive but less so than a full rebuild
|
138 |
*/
|
142 |
*/
|
139 |
ConfSimple(const ConfSimple &rhs) : data(0) {
|
143 |
ConfSimple(const ConfSimple &rhs) : data(0) {
|
|
... |
|
... |
156 |
submaps = rhs.submaps;
|
160 |
submaps = rhs.submaps;
|
157 |
}
|
161 |
}
|
158 |
return *this;
|
162 |
return *this;
|
159 |
}
|
163 |
}
|
160 |
|
164 |
|
161 |
protected:
|
165 |
protected:
|
162 |
bool dotildexpand;
|
166 |
bool dotildexpand;
|
163 |
StatusCode status;
|
167 |
StatusCode status;
|
164 |
private:
|
168 |
private:
|
165 |
string filename; // set if we're working with a file
|
169 |
string filename; // set if we're working with a file
|
166 |
string *data; // set if we're working with an in-memory string
|
170 |
string *data; // set if we're working with an in-memory string
|
167 |
map<string, map<string, string> > submaps;
|
171 |
map<string, map<string, string> > submaps;
|
168 |
|
172 |
|
169 |
void parseinput(std::istream &input);
|
173 |
void parseinput(istream &input);
|
170 |
};
|
174 |
};
|
171 |
|
175 |
|
172 |
/**
|
176 |
/**
|
173 |
* This is a configuration class which attaches tree-like signification to the
|
177 |
* This is a configuration class which attaches tree-like signification to the
|
174 |
* submap names.
|
178 |
* submap names.
|
|
... |
|
... |
183 |
* designated by '/' but by '' (empty subkey). A '/' subkey will not
|
187 |
* designated by '/' but by '' (empty subkey). A '/' subkey will not
|
184 |
* be searched at all.
|
188 |
* be searched at all.
|
185 |
*/
|
189 |
*/
|
186 |
class ConfTree : public ConfSimple {
|
190 |
class ConfTree : public ConfSimple {
|
187 |
|
191 |
|
188 |
public:
|
192 |
public:
|
189 |
/**
|
193 |
/**
|
190 |
* Build the object by reading content from file.
|
194 |
* Build the object by reading content from file.
|
191 |
*/
|
195 |
*/
|
192 |
ConfTree(const char *fname, int readonly = 0)
|
196 |
ConfTree(const char *fname, int readonly = 0)
|
193 |
: ConfSimple(fname, readonly, true) {}
|
197 |
: ConfSimple(fname, readonly, true) {}
|
|
... |
|
... |
201 |
/**
|
205 |
/**
|
202 |
* Get value for named parameter, from specified subsection, or its
|
206 |
* Get value for named parameter, from specified subsection, or its
|
203 |
* parents.
|
207 |
* parents.
|
204 |
* @return 0 if name not found, 1 else
|
208 |
* @return 0 if name not found, 1 else
|
205 |
*/
|
209 |
*/
|
206 |
virtual int get(const std::string &name, string &value, const string &sk);
|
210 |
virtual int get(const string &name, string &value, const string &sk);
|
207 |
|
211 |
|
208 |
virtual int get(const char *name, string &value, const char *sk) {
|
212 |
virtual int get(const char *name, string &value, const char *sk) {
|
209 |
return get(string(name), value, sk ? string(sk) : string(""));
|
213 |
return get(string(name), value, sk ? string(sk) : string(""));
|
210 |
}
|
214 |
}
|
211 |
};
|
215 |
};
|
|
... |
|
... |
217 |
*
|
221 |
*
|
218 |
* Notes: it's ok for some of the files in the list to not exist, but the last
|
222 |
* Notes: it's ok for some of the files in the list to not exist, but the last
|
219 |
* one must or we generate an error. We open all trees readonly.
|
223 |
* one must or we generate an error. We open all trees readonly.
|
220 |
*/
|
224 |
*/
|
221 |
template <class T> class ConfStack {
|
225 |
template <class T> class ConfStack {
|
222 |
public:
|
226 |
public:
|
|
|
227 |
/// Construct from list of configuration file names
|
223 |
ConfStack(const std::list<string> &fns, bool ro = true) {
|
228 |
ConfStack(const list<string> &fns, bool ro = true) {
|
224 |
construct(fns, ro);
|
229 |
construct(fns, ro);
|
225 |
}
|
230 |
}
|
226 |
|
231 |
// Construct out of one name
|
227 |
ConfStack(const char *nm, bool ro = true) {
|
232 |
// Construct out of name and list of directories
|
|
|
233 |
ConfStack(const string& nm, const list<string>& dirs, bool ro = true) {
|
228 |
std::list<string> fns;
|
234 |
list<string> fns;
|
229 |
fns.push_back(string(nm));
|
235 |
for (list<string>::const_iterator it = dirs.begin();
|
|
|
236 |
it != dirs.end(); it++){
|
|
|
237 |
fns.push_back(path_cat(*it, nm));
|
|
|
238 |
}
|
230 |
construct(fns, ro);
|
239 |
ConfStack::construct(fns, ro);
|
231 |
}
|
240 |
}
|
232 |
|
241 |
|
233 |
~ConfStack() {
|
242 |
~ConfStack() {
|
234 |
erase();
|
243 |
erase();
|
235 |
m_ok = false;
|
244 |
m_ok = false;
|
|
... |
|
... |
247 |
init_from(rhs);
|
256 |
init_from(rhs);
|
248 |
}
|
257 |
}
|
249 |
return *this;
|
258 |
return *this;
|
250 |
}
|
259 |
}
|
251 |
|
260 |
|
252 |
int get(const std::string &name, string &value, const string &sk) {
|
261 |
int get(const string &name, string &value, const string &sk) {
|
253 |
typename std::list<T*>::iterator it;
|
262 |
typename list<T*>::iterator it;
|
254 |
for (it = m_confs.begin();it != m_confs.end();it++) {
|
263 |
for (it = m_confs.begin();it != m_confs.end();it++) {
|
255 |
if ((*it)->get(name, value, sk))
|
264 |
if ((*it)->get(name, value, sk))
|
256 |
return true;
|
265 |
return true;
|
257 |
}
|
266 |
}
|
258 |
return false;
|
267 |
return false;
|
|
... |
|
... |
260 |
|
269 |
|
261 |
int get(const char *name, string &value, const char *sk) {
|
270 |
int get(const char *name, string &value, const char *sk) {
|
262 |
return get(string(name), value, sk ? string(sk) : string(""));
|
271 |
return get(string(name), value, sk ? string(sk) : string(""));
|
263 |
}
|
272 |
}
|
264 |
|
273 |
|
265 |
std::list<string> getNames(const string &sk) {
|
274 |
list<string> getNames(const string &sk) {
|
266 |
std::list<string> nms;
|
275 |
list<string> nms;
|
267 |
typename std::list<T*>::iterator it;
|
276 |
typename list<T*>::iterator it;
|
268 |
for (it = m_confs.begin();it != m_confs.end();it++) {
|
277 |
for (it = m_confs.begin();it != m_confs.end(); it++) {
|
269 |
std::list<string> lst;
|
278 |
list<string> lst;
|
270 |
lst = (*it)->getNames(sk);
|
279 |
lst = (*it)->getNames(sk);
|
271 |
nms.splice(nms.end(), lst);
|
280 |
nms.splice(nms.end(), lst);
|
272 |
}
|
281 |
}
|
|
|
282 |
nms.sort();
|
|
|
283 |
nms.unique();
|
273 |
return nms;
|
284 |
return nms;
|
274 |
}
|
285 |
}
|
275 |
|
286 |
|
276 |
bool ok() {return m_ok;}
|
287 |
bool ok() {return m_ok;}
|
277 |
|
288 |
|
278 |
private:
|
289 |
private:
|
279 |
bool m_ok;
|
290 |
bool m_ok;
|
280 |
std::list<T*> m_confs;
|
291 |
list<T*> m_confs;
|
281 |
|
292 |
|
282 |
void erase() {
|
293 |
void erase() {
|
283 |
typename std::list<T*>::iterator it;
|
294 |
typename list<T*>::iterator it;
|
284 |
for (it = m_confs.begin();it != m_confs.end();it++) {
|
295 |
for (it = m_confs.begin();it != m_confs.end();it++) {
|
285 |
delete (*it);
|
296 |
delete (*it);
|
286 |
}
|
297 |
}
|
287 |
m_confs.clear();
|
298 |
m_confs.clear();
|
288 |
}
|
299 |
}
|
289 |
|
300 |
|
290 |
/// Common code to initialize from existing object
|
301 |
/// Common code to initialize from existing object
|
291 |
void init_from(const ConfStack &rhs) {
|
302 |
void init_from(const ConfStack &rhs) {
|
292 |
if ((m_ok = rhs.m_ok)) {
|
303 |
if ((m_ok = rhs.m_ok)) {
|
293 |
typename std::list<T*>::const_iterator it;
|
304 |
typename list<T*>::const_iterator it;
|
294 |
for (it = rhs.m_confs.begin();it != rhs.m_confs.end();it++) {
|
305 |
for (it = rhs.m_confs.begin();it != rhs.m_confs.end();it++) {
|
295 |
m_confs.push_back(new T(**it));
|
306 |
m_confs.push_back(new T(**it));
|
296 |
}
|
307 |
}
|
297 |
}
|
308 |
}
|
298 |
}
|
309 |
}
|
299 |
|
310 |
|
300 |
/// Common constructor code
|
311 |
/// Common constructor code
|
301 |
void construct(const std::list<string> &fns, bool ro) {
|
312 |
void construct(const list<string> &fns, bool ro) {
|
302 |
if (!ro) {
|
313 |
if (!ro) {
|
303 |
m_ok = false;
|
314 |
m_ok = false;
|
304 |
return;
|
315 |
return;
|
305 |
}
|
316 |
}
|
306 |
std::list<std::string>::const_iterator it;
|
317 |
list<string>::const_iterator it;
|
307 |
bool lastok = false;
|
318 |
bool lastok = false;
|
308 |
for (it = fns.begin();it != fns.end();it++) {
|
319 |
for (it = fns.begin();it != fns.end();it++) {
|
309 |
T* p = new T(it->c_str(), true);
|
320 |
T* p = new T(it->c_str(), true);
|
310 |
if (p && p->ok()) {
|
321 |
if (p && p->ok()) {
|
311 |
m_confs.push_back(p);
|
322 |
m_confs.push_back(p);
|