Switch to unified view

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);