bugfix: if last line ended with backslash, entry was ignored.

new function: filter by wildcard expr in getNames()
This commit is contained in:
dockes 2009-10-29 18:08:31 +00:00
parent 999a405cd9
commit 8ae29d219b
2 changed files with 41 additions and 18 deletions

View File

@ -25,6 +25,7 @@ static char rcsid [] = "@(#$Id: conftree.cpp,v 1.16 2008-07-01 11:51:51 dockes E
#include <unistd.h> // for access(2) #include <unistd.h> // for access(2)
#include <ctype.h> #include <ctype.h>
#include <fnmatch.h>
#include <fstream> #include <fstream>
#include <sstream> #include <sstream>
@ -59,6 +60,7 @@ void ConfSimple::parseinput(istream &input)
char cline[LL]; char cline[LL];
bool appending = false; bool appending = false;
string line; string line;
bool eof = false;
for (;;) { for (;;) {
input.getline(cline, LL-1); input.getline(cline, LL-1);
@ -68,21 +70,31 @@ void ConfSimple::parseinput(istream &input)
status = STATUS_ERROR; status = STATUS_ERROR;
return; return;
} }
// Must be eof ? // Must be eof ? But maybe we have a partial line which
// must be processed. This happens if the last line before
// eof ends with a backslash
if (appending) {
eof = true;
goto processline;
}
break; break;
} }
int ll = strlen(cline); {
while (ll > 0 && (cline[ll-1] == '\n' || cline[ll-1] == '\r')) { int ll = strlen(cline);
cline[ll-1] = 0; while (ll > 0 && (cline[ll-1] == '\n' || cline[ll-1] == '\r')) {
ll--; cline[ll-1] = 0;
} ll--;
}
}
if (appending) if (appending)
line += cline; line += cline;
else else
line = cline; line = cline;
processline:
// Note that we trim whitespace before checking for backslash-eol // Note that we trim whitespace before checking for backslash-eol
// This avoids invisible problems. // This avoids invisible problems.
trimstring(line); trimstring(line);
@ -130,6 +142,8 @@ void ConfSimple::parseinput(istream &input)
continue; continue;
} }
i_set(nm, val, submapkey, true); i_set(nm, val, submapkey, true);
if (eof == true)
break;
} }
} }
@ -483,7 +497,7 @@ void ConfSimple::listall()
write(std::cout); write(std::cout);
} }
list<string> ConfSimple::getNames(const string &sk) list<string> ConfSimple::getNames(const string &sk, const char *pattern)
{ {
std::list<string> mylist; std::list<string> mylist;
if (!ok()) if (!ok())
@ -494,6 +508,8 @@ list<string> ConfSimple::getNames(const string &sk)
} }
map<string, string>::const_iterator it; map<string, string>::const_iterator it;
for (it = ss->second.begin();it != ss->second.end();it++) { for (it = ss->second.begin();it != ss->second.end();it++) {
if (pattern && FNM_NOMATCH == fnmatch(pattern, it->first.c_str(), 0))
continue;
mylist.push_back(it->first); mylist.push_back(it->first);
} }
mylist.sort(); mylist.sort();
@ -992,10 +1008,16 @@ int main(int argc, char **argv)
//printf("WALK\n");conf->sortwalk(mywalker, 0); //printf("WALK\n");conf->sortwalk(mywalker, 0);
printf("\nNAMES in global space:\n"); printf("\nNAMES in global space:\n");
list<string> names = conf->getNames(""); list<string> names = conf->getNames("");
for (list<string>::iterator it = names.begin();it!=names.end(); for (list<string>::iterator it = names.begin();
it++) it!=names.end(); it++)
printf("%s\n", (*it).c_str()); cout << *it << " ";
cout << endl;
printf("\nNAMES in global space matching t* \n");
names = conf->getNames("", "t*");
for (list<string>::iterator it = names.begin();
it!=names.end(); it++)
cout << *it << " ";
cout << endl;
} }
} }

View File

@ -99,7 +99,7 @@ public:
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() = 0; virtual bool ok() = 0;
virtual list<string> getNames(const string &sk) = 0; virtual list<string> getNames(const string &sk, const char* = 0) = 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 listall() {}; virtual void listall() {};
@ -193,10 +193,8 @@ public:
/** List all values to stdout */ /** List all values to stdout */
virtual void listall(); virtual void listall();
/** /** Return all names in given submap. */
* Return all names in given submap virtual list<string> getNames(const string &sk, const char *pattern = 0);
*/
virtual list<string> getNames(const string &sk);
/** /**
* Return all subkeys * Return all subkeys
@ -272,6 +270,9 @@ private:
* NOTE: contrary to common behaviour, the global or root space is NOT * NOTE: contrary to common behaviour, the global or root space is NOT
* designated by '/' but by '' (empty subkey). A '/' subkey will not * designated by '/' but by '' (empty subkey). A '/' subkey will not
* be searched at all. * be searched at all.
*
* Note: getNames() : uses ConfSimple method, this does *not* inherit
* names from englobing submaps.
*/ */
class ConfTree : public ConfSimple { class ConfTree : public ConfSimple {
@ -405,13 +406,13 @@ public:
return m_confs.front()->holdWrites(on); return m_confs.front()->holdWrites(on);
} }
virtual list<string> getNames(const string &sk) virtual list<string> getNames(const string &sk, const char *pattern = 0)
{ {
list<string> nms; list<string> nms;
typename list<T*>::iterator it; typename list<T*>::iterator it;
for (it = m_confs.begin();it != m_confs.end(); it++) { for (it = m_confs.begin();it != m_confs.end(); it++) {
list<string> lst; list<string> lst;
lst = (*it)->getNames(sk); lst = (*it)->getNames(sk, pattern);
nms.insert(nms.end(), lst.begin(), lst.end()); nms.insert(nms.end(), lst.begin(), lst.end());
} }
nms.sort(); nms.sort();