merged shared module (confXml code

This commit is contained in:
Jean-Francois Dockes 2016-06-18 19:38:10 +02:00
parent e85615b5b9
commit ec3adeb702
2 changed files with 75 additions and 14 deletions

View File

@ -52,6 +52,9 @@ using namespace std;
#define LOGDEB(X)
#endif
static const SimpleRegexp varcomment_rx("[ \t]*#[ \t]*([a-zA-Z0-9]+)[ \t]*=",
0, 1);
void ConfSimple::parseinput(istream& input)
{
string submapkey;
@ -100,7 +103,12 @@ void ConfSimple::parseinput(istream& input)
if (eof) {
break;
}
m_order.push_back(ConfLine(ConfLine::CFL_COMMENT, line));
if (varcomment_rx.simpleMatch(line)) {
m_order.push_back(ConfLine(ConfLine::CFL_VARCOMMENT, line,
varcomment_rx.getMatch(line, 1)));
} else {
m_order.push_back(ConfLine(ConfLine::CFL_COMMENT, line));
}
continue;
}
if (line[line.length() - 1] == '\\') {
@ -118,12 +126,7 @@ void ConfSimple::parseinput(istream& input)
submapkey = line;
}
m_subkeys_unsorted.push_back(submapkey);
// No need for adding sk to order, will be done with first
// variable insert. Also means that empty section are
// expandable (won't be output when rewriting)
// Another option would be to add the subsec to m_order here
// and not do it inside i_set() if init is true
m_order.push_back(ConfLine(ConfLine::CFL_SK, submapkey));
continue;
}
@ -371,11 +374,11 @@ int ConfSimple::i_set(const std::string& nm, const std::string& value,
submap[nm] = value;
m_submaps[sk] = submap;
// Maybe add sk entry to m_order data:
// Maybe add sk entry to m_order data, if not already there.
if (!sk.empty()) {
ConfLine nl(ConfLine::CFL_SK, sk);
// Append SK entry only if it's not already there (erase
// does not remove entries from the order data, adn it may
// does not remove entries from the order data, and it may
// be being recreated after deletion)
if (find(m_order.begin(), m_order.end(), nl) == m_order.end()) {
m_order.push_back(nl);
@ -445,8 +448,23 @@ int ConfSimple::i_set(const std::string& nm, const std::string& value,
// It may happen that the order entry already exists because erase doesnt
// update m_order
if (find(start, fin, ConfLine(ConfLine::CFL_VAR, nm)) == fin) {
m_order.insert(fin, ConfLine(ConfLine::CFL_VAR, nm));
// Look for a varcomment line, insert the value right after if
// it's there.
bool inserted(false);
vector<ConfLine>::iterator it;
for (it = start; it != fin; it++) {
if (it->m_kind == ConfLine::CFL_VARCOMMENT && it->m_aux == nm) {
it++;
m_order.insert(it, ConfLine(ConfLine::CFL_VAR, nm));
inserted = true;
break;
}
}
if (!inserted) {
m_order.insert(fin, ConfLine(ConfLine::CFL_VAR, nm));
}
}
return 1;
}
@ -546,6 +564,7 @@ bool ConfSimple::write(ostream& out) const
it != m_order.end(); it++) {
switch (it->m_kind) {
case ConfLine::CFL_COMMENT:
case ConfLine::CFL_VARCOMMENT:
out << it->m_data << endl;
if (!out.good()) {
return false;
@ -644,6 +663,35 @@ bool ConfSimple::hasNameAnywhere(const string& nm) const
return false;
}
bool ConfSimple::commentsAsXML(ostream& out)
{
const vector<ConfLine>& lines = getlines();
out << "<confcomments>\n";
string sk;
for (vector<ConfLine>::const_iterator it = lines.begin();
it != lines.end(); it++) {
switch (it->m_kind) {
case ConfLine::CFL_COMMENT:
case ConfLine::CFL_VARCOMMENT:
{
string::size_type pos = it->m_data.find_first_not_of("# ");
if (pos != string::npos) {
out << it->m_data.substr(pos) << endl;
}
break;
}
default:
break;
}
}
out << "</confcomments>\n";
return true;
}
// //////////////////////////////////////////////////////////////////////////
// ConfTree Methods: conftree interpret keys like a hierarchical file tree
// //////////////////////////////////////////////////////////////////////////

View File

@ -74,11 +74,12 @@ using std::ostream;
/** Internal class used for storing presentation information */
class ConfLine {
public:
enum Kind {CFL_COMMENT, CFL_SK, CFL_VAR};
enum Kind {CFL_COMMENT, CFL_SK, CFL_VAR, CFL_VARCOMMENT};
Kind m_kind;
string m_data;
ConfLine(Kind k, const string& d)
: m_kind(k), m_data(d) {
string m_aux;
ConfLine(Kind k, const string& d, string a = string())
: m_kind(k), m_data(d), m_aux(a) {
}
bool operator==(const ConfLine& o) {
return o.m_kind == m_kind && o.m_data == m_data;
@ -239,10 +240,14 @@ public:
virtual vector<string> getSubKeys(bool) const {
return getSubKeys();
}
virtual vector<string> getSubKeys() const;
/** Return subkeys in file order. BEWARE: only for the original from the
* file: the data is not duplicated to further copies */
virtual vector<string> getSubKeys_unsorted(bool = false) const {
return m_subkeys_unsorted;
}
virtual vector<string> getSubKeys() const;
/** Test for subkey existence */
virtual bool hasSubKey(const string& sk) const {
return m_submaps.find(sk) != m_submaps.end();
@ -252,6 +257,13 @@ public:
return m_filename;
}
/** Used with config files with specially formatted, xml-like comments.
* Extract the comments as text */
virtual bool commentsAsXML(ostream& out);
/** !! Note that assignment and copy constructor do not copy the
auxiliary data (m_order and subkeys_unsorted). */
/**
* Copy constructor. Expensive but less so than a full rebuild
*/
@ -352,6 +364,7 @@ public:
* @return 0 if name not found, 1 else
*/
virtual int get(const string& name, string& value, const string& sk) const;
using ConfSimple::get;
};
/**