conftree: astyle + merge with upmpdcli version

This commit is contained in:
Jean-Francois Dockes 2016-02-22 17:27:06 +01:00
parent 111dd7a7e5
commit 3f3b3a15c7
2 changed files with 828 additions and 763 deletions

File diff suppressed because it is too large Load diff

View file

@ -49,10 +49,10 @@
* (useful to have central/personal config files) * (useful to have central/personal config files)
*/ */
#include <string>
#include <map>
#include <vector>
#include <algorithm> #include <algorithm>
#include <map>
#include <string>
#include <vector>
// rh7.3 likes iostream better... // rh7.3 likes iostream better...
#if defined(__GNUC__) && __GNUC__ < 3 #if defined(__GNUC__) && __GNUC__ < 3
@ -62,15 +62,13 @@
#include <ostream> #include <ostream>
#endif #endif
#ifndef NO_NAMESPACES #include "pathut.h"
using std::string; using std::string;
using std::vector; using std::vector;
using std::map; using std::map;
using std::istream; using std::istream;
using std::ostream; using std::ostream;
#endif // NO_NAMESPACES
#include "pathut.h"
/** Internal class used for storing presentation information */ /** Internal class used for storing presentation information */
class ConfLine { class ConfLine {
@ -79,12 +77,10 @@ public:
Kind m_kind; Kind m_kind;
string m_data; string m_data;
ConfLine(Kind k, const string& d) ConfLine(Kind k, const string& d)
: m_kind(k), m_data(d) : m_kind(k), m_data(d) {
{
} }
bool operator==(const ConfLine& o) bool operator==(const ConfLine& o) {
{ return o.m_kind == m_kind && o.m_data == m_data;
return o.m_kind == m_kind && o.m_data == m_data;
} }
}; };
@ -93,17 +89,17 @@ public:
*/ */
class ConfNull { class ConfNull {
public: public:
enum StatusCode {STATUS_ERROR=0, STATUS_RO=1, STATUS_RW=2}; enum StatusCode {STATUS_ERROR = 0, STATUS_RO = 1, STATUS_RW = 2};
virtual ~ConfNull() {}; virtual ~ConfNull() {};
virtual int get(const string &name, string &value, virtual int get(const string& name, string& value,
const string &sk = string()) const = 0; const string& sk = string()) const = 0;
virtual bool hasNameAnywhere(const string& nm) const = 0; virtual bool hasNameAnywhere(const string& nm) const = 0;
virtual int set(const string &nm, const string &val, virtual int set(const string& nm, const string& val,
const string &sk = string()) = 0; const string& sk = string()) = 0;
virtual bool ok() const = 0; virtual bool ok() const = 0;
virtual vector<string> getNames(const string &sk, const char* = 0)const = 0; virtual vector<string> getNames(const string& sk, const char* = 0)const = 0;
virtual int erase(const string &, const string &) = 0; virtual int erase(const string&, const string&) = 0;
virtual int eraseKey(const string &) = 0; virtual int eraseKey(const string&) = 0;
virtual void showall() const {}; virtual void showall() const {};
virtual vector<string> getSubKeys() const = 0; virtual vector<string> getSubKeys() const = 0;
virtual vector<string> getSubKeys(bool) const = 0; virtual vector<string> getSubKeys(bool) const = 0;
@ -149,23 +145,22 @@ public:
* Decide if we actually rewrite the backing-store after modifying the * Decide if we actually rewrite the backing-store after modifying the
* tree. * tree.
*/ */
virtual bool holdWrites(bool on) virtual bool holdWrites(bool on) {
{ m_holdWrites = on;
m_holdWrites = on; if (on == false) {
if (on == false) { return write();
return write(); } else {
} else return true;
return true; }
} }
/** Clear, then reparse from string */ /** Clear, then reparse from string */
void reparse(const string& in); void reparse(const string& in);
/** Clear all content */ /** Clear all content */
void clear() void clear() {
{ m_submaps.clear();
m_submaps.clear(); m_order.clear();
m_order.clear();
} }
/** /**
@ -173,28 +168,30 @@ public:
* global space if sk is empty). * global space if sk is empty).
* @return 0 if name not found, 1 else * @return 0 if name not found, 1 else
*/ */
virtual int get(const string &name, string &value, virtual int get(const string& name, string& value,
const string &sk = string()) const; const string& sk = string()) const;
/** /**
* Set value for named parameter in specified subsection (or global) * Set value for named parameter in specified subsection (or global)
* @return 0 for error, 1 else * @return 0 for error, 1 else
*/ */
virtual int set(const string &nm, const string &val, virtual int set(const string& nm, const string& val,
const string &sk = string()); const string& sk = string());
/** /**
* Remove name and value from config * Remove name and value from config
*/ */
virtual int erase(const string &name, const string &sk); virtual int erase(const string& name, const string& sk);
/** /**
* Erase all names under given subkey (and subkey itself) * Erase all names under given subkey (and subkey itself)
*/ */
virtual int eraseKey(const string &sk); virtual int eraseKey(const string& sk);
virtual StatusCode getStatus() const; virtual StatusCode getStatus() const;
virtual bool ok() const {return getStatus() != STATUS_ERROR;} virtual bool ok() const {
return getStatus() != STATUS_ERROR;
}
/** /**
* Walk the configuration values, calling function for each. * Walk the configuration values, calling function for each.
@ -205,16 +202,16 @@ public:
*/ */
enum WalkerCode {WALK_STOP, WALK_CONTINUE}; enum WalkerCode {WALK_STOP, WALK_CONTINUE};
virtual WalkerCode sortwalk(WalkerCode virtual WalkerCode sortwalk(WalkerCode
(*wlkr)(void *cldata, const string &nm, (*wlkr)(void *cldata, const string& nm,
const string &val), const string& val),
void *clidata) const; void *clidata) const;
/** Print all values to stdout */ /** Print all values to stdout */
virtual void showall() const; virtual void showall() const;
/** Return all names in given submap. */ /** Return all names in given submap. */
virtual vector<string> getNames(const string &sk, const char *pattern = 0) virtual vector<string> getNames(const string& sk, const char *pattern = 0)
const; const;
/** Check if name is present in any submap. This is relatively expensive /** Check if name is present in any submap. This is relatively expensive
* but useful for saving further processing sometimes */ * but useful for saving further processing sometimes */
@ -223,42 +220,43 @@ public:
/** /**
* Return all subkeys * Return all subkeys
*/ */
virtual vector<string> getSubKeys(bool) const virtual vector<string> getSubKeys(bool) const {
{ return getSubKeys();
return getSubKeys(); }
virtual vector<string> getSubKeys_unsorted(bool = false) const {
return m_subkeys_unsorted;
} }
virtual vector<string> getSubKeys() const; virtual vector<string> getSubKeys() const;
/** Test for subkey existence */ /** Test for subkey existence */
virtual bool hasSubKey(const string& sk) const virtual bool hasSubKey(const string& sk) const {
{ return m_submaps.find(sk) != m_submaps.end();
return m_submaps.find(sk) != m_submaps.end();
} }
virtual string getFilename() const virtual string getFilename() const {
{return m_filename;} return m_filename;
}
/** /**
* Copy constructor. Expensive but less so than a full rebuild * Copy constructor. Expensive but less so than a full rebuild
*/ */
ConfSimple(const ConfSimple &rhs) ConfSimple(const ConfSimple& rhs)
: ConfNull() : ConfNull() {
{ if ((status = rhs.status) == STATUS_ERROR) {
if ((status = rhs.status) == STATUS_ERROR) return;
return; }
m_filename = rhs.m_filename; m_filename = rhs.m_filename;
m_submaps = rhs.m_submaps; m_submaps = rhs.m_submaps;
} }
/** /**
* Assignement. This is expensive * Assignement. This is expensive
*/ */
ConfSimple& operator=(const ConfSimple &rhs) ConfSimple& operator=(const ConfSimple& rhs) {
{ if (this != &rhs && (status = rhs.status) != STATUS_ERROR) {
if (this != &rhs && (status = rhs.status) != STATUS_ERROR) { m_filename = rhs.m_filename;
m_filename = rhs.m_filename; m_submaps = rhs.m_submaps;
m_submaps = rhs.m_submaps; }
} return *this;
return *this;
} }
/** /**
@ -276,6 +274,7 @@ private:
// Configuration data submaps (one per subkey, the main data has a // Configuration data submaps (one per subkey, the main data has a
// null subkey) // null subkey)
map<string, map<string, string> > m_submaps; map<string, map<string, string> > m_submaps;
vector<string> m_subkeys_unsorted;
// Presentation data. We keep the comments, empty lines and // Presentation data. We keep the comments, empty lines and
// variable and subkey ordering information in there (for // variable and subkey ordering information in there (for
// rewriting the file while keeping hand-edited information) // rewriting the file while keeping hand-edited information)
@ -286,8 +285,8 @@ private:
void parseinput(istream& input); void parseinput(istream& input);
bool write(); bool write();
// Internal version of set: no RW checking // Internal version of set: no RW checking
virtual int i_set(const string &nm, const string &val, virtual int i_set(const string& nm, const string& val,
const string &sk, bool init = false); const string& sk, bool init = false);
bool i_changed(bool upd); bool i_changed(bool upd);
}; };
@ -314,17 +313,16 @@ public:
/* The constructors just call ConfSimple's, asking for key tilde /* The constructors just call ConfSimple's, asking for key tilde
* expansion */ * expansion */
ConfTree(const char *fname, int readonly = 0) ConfTree(const char *fname, int readonly = 0)
: ConfSimple(fname, readonly, true) {} : ConfSimple(fname, readonly, true) {}
ConfTree(const string &data, int readonly = 0) ConfTree(const string& data, int readonly = 0)
: ConfSimple(data, readonly, true) {} : ConfSimple(data, readonly, true) {}
ConfTree(int readonly = 0) ConfTree(int readonly = 0)
: ConfSimple(readonly, true) {} : ConfSimple(readonly, true) {}
virtual ~ConfTree() {}; virtual ~ConfTree() {};
ConfTree(const ConfTree& r) : ConfSimple(r) {}; ConfTree(const ConfTree& r) : ConfSimple(r) {};
ConfTree& operator=(const ConfTree& r) ConfTree& operator=(const ConfTree& r) {
{ ConfSimple::operator=(r);
ConfSimple::operator=(r); return *this;
return *this;
} }
/** /**
@ -332,7 +330,7 @@ public:
* parents. * parents.
* @return 0 if name not found, 1 else * @return 0 if name not found, 1 else
*/ */
virtual int get(const string &name, string &value, const string &sk) const; virtual int get(const string& name, string& value, const string& sk) const;
}; };
/** /**
@ -351,178 +349,171 @@ public:
/// Construct from configuration file names. The earler /// Construct from configuration file names. The earler
/// files in have priority when fetching values. Only the first /// files in have priority when fetching values. Only the first
/// file will be updated if ro is false and set() is used. /// file will be updated if ro is false and set() is used.
ConfStack(const vector<string> &fns, bool ro = true) ConfStack(const vector<string>& fns, bool ro = true) {
{ construct(fns, ro);
construct(fns, ro);
} }
/// Construct out of single file name and multiple directories /// Construct out of single file name and multiple directories
ConfStack(const string& nm, const vector<string>& dirs, bool ro = true) ConfStack(const string& nm, const vector<string>& dirs, bool ro = true) {
{ vector<string> fns;
vector<string> fns; for (vector<string>::const_iterator it = dirs.begin();
for (vector<string>::const_iterator it = dirs.begin(); it != dirs.end(); it++) {
it != dirs.end(); it++){ fns.push_back(path_cat(*it, nm));
fns.push_back(path_cat(*it, nm)); }
} ConfStack::construct(fns, ro);
ConfStack::construct(fns, ro);
} }
ConfStack(const ConfStack &rhs) ConfStack(const ConfStack& rhs)
: ConfNull() : ConfNull() {
{ init_from(rhs);
init_from(rhs);
} }
virtual ~ConfStack() virtual ~ConfStack() {
{ clear();
clear(); m_ok = false;
m_ok = false;
} }
ConfStack& operator=(const ConfStack &rhs) ConfStack& operator=(const ConfStack& rhs) {
{ if (this != &rhs) {
if (this != &rhs){ clear();
clear(); m_ok = rhs.m_ok;
m_ok = rhs.m_ok; if (m_ok) {
if (m_ok) init_from(rhs);
init_from(rhs); }
} }
return *this; return *this;
} }
virtual bool sourceChanged() const virtual bool sourceChanged() const {
{ typename vector<T*>::const_iterator it;
typename vector<T*>::const_iterator it; for (it = m_confs.begin(); it != m_confs.end(); it++) {
for (it = m_confs.begin();it != m_confs.end();it++) { if ((*it)->sourceChanged()) {
if ((*it)->sourceChanged()) return true;
return true; }
} }
return false; return false;
} }
virtual int get(const string &name, string &value, const string &sk, virtual int get(const string& name, string& value, const string& sk,
bool shallow) const bool shallow) const {
{ typename vector<T*>::const_iterator it;
typename vector<T*>::const_iterator it; for (it = m_confs.begin(); it != m_confs.end(); it++) {
for (it = m_confs.begin();it != m_confs.end();it++) { if ((*it)->get(name, value, sk)) {
if ((*it)->get(name, value, sk)) return true;
return true; }
if (shallow) if (shallow) {
break; break;
} }
return false; }
return false;
} }
virtual int get(const string &name, string &value, const string &sk) const { virtual int get(const string& name, string& value, const string& sk) const {
return get(name, value, sk, false); return get(name, value, sk, false);
} }
virtual bool hasNameAnywhere(const string& nm) const virtual bool hasNameAnywhere(const string& nm) const {
{ typename vector<T*>::const_iterator it;
typename vector<T*>::const_iterator it; for (it = m_confs.begin(); it != m_confs.end(); it++) {
for (it = m_confs.begin();it != m_confs.end();it++) { if ((*it)->hasNameAnywhere(nm)) {
if ((*it)->hasNameAnywhere(nm)) return true;
return true; }
} }
return false; return false;
} }
virtual int set(const string &nm, const string &val, virtual int set(const string& nm, const string& val,
const string &sk = string()) const string& sk = string()) {
{ if (!m_ok) {
if (!m_ok) return 0;
return 0; }
//LOGDEB2(("ConfStack::set [%s]:[%s] -> [%s]\n", sk.c_str(), //LOGDEB2(("ConfStack::set [%s]:[%s] -> [%s]\n", sk.c_str(),
//nm.c_str(), val.c_str())); //nm.c_str(), val.c_str()));
// Avoid adding unneeded entries: if the new value matches the // Avoid adding unneeded entries: if the new value matches the
// one out from the deeper configs, erase or dont add it // one out from the deeper configs, erase or dont add it
// from/to the topmost file // from/to the topmost file
typename vector<T*>::iterator it = m_confs.begin(); typename vector<T*>::iterator it = m_confs.begin();
it++; it++;
while (it != m_confs.end()) { while (it != m_confs.end()) {
string value; string value;
if ((*it)->get(nm, value, sk)) { if ((*it)->get(nm, value, sk)) {
// This file has value for nm/sk. If it is the same as the new // This file has value for nm/sk. If it is the same as the new
// one, no need for an entry in the topmost file. Else, stop // one, no need for an entry in the topmost file. Else, stop
// looking and add the new entry // looking and add the new entry
if (value == val) { if (value == val) {
m_confs.front()->erase(nm, sk); m_confs.front()->erase(nm, sk);
return true; return true;
} else { } else {
break; break;
} }
} }
it++; it++;
} }
return m_confs.front()->set(nm, val, sk); return m_confs.front()->set(nm, val, sk);
} }
virtual int erase(const string &nm, const string &sk) virtual int erase(const string& nm, const string& sk) {
{ return m_confs.front()->erase(nm, sk);
return m_confs.front()->erase(nm, sk);
} }
virtual int eraseKey(const string &sk) virtual int eraseKey(const string& sk) {
{ return m_confs.front()->eraseKey(sk);
return m_confs.front()->eraseKey(sk);
} }
virtual bool holdWrites(bool on) virtual bool holdWrites(bool on) {
{ return m_confs.front()->holdWrites(on);
return m_confs.front()->holdWrites(on);
} }
virtual vector<string> getNames(const string &sk, const char *pattern = 0) virtual vector<string> getNames(const string& sk, const char *pattern = 0)
const const {
{ return getNames1(sk, pattern, false);
return getNames1(sk, pattern, false);
} }
virtual vector<string> getNamesShallow(const string &sk, virtual vector<string> getNamesShallow(const string& sk,
const char *patt = 0) const const char *patt = 0) const {
{ return getNames1(sk, patt, true);
return getNames1(sk, patt, true);
} }
virtual vector<string> getNames1(const string &sk, const char *pattern, virtual vector<string> getNames1(const string& sk, const char *pattern,
bool shallow) const bool shallow) const {
{ vector<string> nms;
vector<string> nms; typename vector<T*>::const_iterator it;
typename vector<T*>::const_iterator it; bool skfound = false;
bool skfound = false; for (it = m_confs.begin(); it != m_confs.end(); it++) {
for (it = m_confs.begin(); it != m_confs.end(); it++) { if ((*it)->hasSubKey(sk)) {
if ((*it)->hasSubKey(sk)) { skfound = true;
skfound = true; vector<string> lst = (*it)->getNames(sk, pattern);
vector<string> lst = (*it)->getNames(sk, pattern); nms.insert(nms.end(), lst.begin(), lst.end());
nms.insert(nms.end(), lst.begin(), lst.end()); }
} if (shallow && skfound) {
if (shallow && skfound) break;
break; }
} }
sort(nms.begin(), nms.end()); sort(nms.begin(), nms.end());
vector<string>::iterator uit = unique(nms.begin(), nms.end()); vector<string>::iterator uit = unique(nms.begin(), nms.end());
nms.resize(uit - nms.begin()); nms.resize(uit - nms.begin());
return nms; return nms;
} }
virtual vector<string> getSubKeys() const virtual vector<string> getSubKeys() const {
{ return getSubKeys(false);
return getSubKeys(false);
} }
virtual vector<string> getSubKeys(bool shallow) const virtual vector<string> getSubKeys(bool shallow) const {
{ vector<string> sks;
vector<string> sks; typename vector<T*>::const_iterator it;
typename vector<T*>::const_iterator it; for (it = m_confs.begin(); it != m_confs.end(); it++) {
for (it = m_confs.begin(); it != m_confs.end(); it++) { vector<string> lst;
vector<string> lst; lst = (*it)->getSubKeys();
lst = (*it)->getSubKeys(); sks.insert(sks.end(), lst.begin(), lst.end());
sks.insert(sks.end(), lst.begin(), lst.end()); if (shallow) {
if (shallow) break;
break; }
} }
sort(sks.begin(), sks.end()); sort(sks.begin(), sks.end());
vector<string>::iterator uit = unique(sks.begin(), sks.end()); vector<string>::iterator uit = unique(sks.begin(), sks.end());
sks.resize(uit - sks.begin()); sks.resize(uit - sks.begin());
return sks; return sks;
} }
virtual bool ok() const {return m_ok;} virtual bool ok() const {
return m_ok;
}
private: private:
bool m_ok; bool m_ok;
@ -530,44 +521,44 @@ private:
/// Reset to pristine /// Reset to pristine
void clear() { void clear() {
typename vector<T*>::iterator it; typename vector<T*>::iterator it;
for (it = m_confs.begin();it != m_confs.end();it++) { for (it = m_confs.begin(); it != m_confs.end(); it++) {
delete (*it); delete(*it);
} }
m_confs.clear(); m_confs.clear();
} }
/// Common code to initialize from existing object /// Common code to initialize from existing object
void init_from(const ConfStack &rhs) { void init_from(const ConfStack& rhs) {
if ((m_ok = rhs.m_ok)) { if ((m_ok = rhs.m_ok)) {
typename vector<T*>::const_iterator it; typename vector<T*>::const_iterator it;
for (it = rhs.m_confs.begin();it != rhs.m_confs.end();it++) { for (it = rhs.m_confs.begin(); it != rhs.m_confs.end(); it++) {
m_confs.push_back(new T(**it)); m_confs.push_back(new T(**it));
} }
} }
} }
/// Common construct from file names code /// Common construct from file names code
void construct(const vector<string> &fns, bool ro) { void construct(const vector<string>& fns, bool ro) {
vector<string>::const_iterator it; vector<string>::const_iterator it;
bool lastok = false; bool lastok = false;
for (it = fns.begin(); it != fns.end(); it++) { for (it = fns.begin(); it != fns.end(); it++) {
T* p = new T(it->c_str(), ro); T* p = new T(it->c_str(), ro);
if (p && p->ok()) { if (p && p->ok()) {
m_confs.push_back(p); m_confs.push_back(p);
lastok = true; lastok = true;
} else { } else {
delete p; delete p;
lastok = false; lastok = false;
if (!ro) { if (!ro) {
// For rw acccess, the topmost file needs to be ok // For rw acccess, the topmost file needs to be ok
// (ro is set to true after the first file) // (ro is set to true after the first file)
break; break;
} }
} }
ro = true; ro = true;
} }
m_ok = lastok; m_ok = lastok;
} }
}; };