synced conftree
This commit is contained in:
parent
37b75d7558
commit
3e3cd7ccec
@ -14,8 +14,6 @@
|
|||||||
* Free Software Foundation, Inc.,
|
* Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
#ifndef TEST_CONFTREE
|
|
||||||
|
|
||||||
#ifdef BUILDING_RECOLL
|
#ifdef BUILDING_RECOLL
|
||||||
#include "autoconfig.h"
|
#include "autoconfig.h"
|
||||||
#else
|
#else
|
||||||
@ -671,462 +669,3 @@ const
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else // TEST_CONFTREE
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <sstream>
|
|
||||||
#include <iostream>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include "conftree.h"
|
|
||||||
#include "smallut.h"
|
|
||||||
#include "readfile.h"
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
static char *thisprog;
|
|
||||||
|
|
||||||
bool complex_updates(const string& fn)
|
|
||||||
{
|
|
||||||
int fd;
|
|
||||||
if ((fd = open(fn.c_str(), O_RDWR | O_TRUNC | O_CREAT, 0666)) < 0) {
|
|
||||||
perror("open/create");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
close(fd);
|
|
||||||
|
|
||||||
ConfTree conf(fn.c_str());
|
|
||||||
if (!conf.ok()) {
|
|
||||||
cerr << "Config init failed" << endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
conf.set("nm-1", "val-1", "");
|
|
||||||
conf.set("nm-2", "val-2", "");
|
|
||||||
|
|
||||||
conf.set("nm-1", "val1-1", "/dir1");
|
|
||||||
conf.set("nm-2", "val1-2", "/dir1");
|
|
||||||
|
|
||||||
conf.set("nm-1", "val2-1", "/dir2");
|
|
||||||
conf.set("nm-2", "val2-2", "/dir2");
|
|
||||||
|
|
||||||
conf.set("nm-1", "val11-1", "/dir1/dir1");
|
|
||||||
conf.set("nm-2", "val11-2", "/dir1/dir1");
|
|
||||||
|
|
||||||
conf.eraseKey("/dir2");
|
|
||||||
conf.set("nm-1", "val2-1", "/dir2");
|
|
||||||
conf.set("nm-2", "val2-2", "/dir2");
|
|
||||||
|
|
||||||
conf.erase("nm-1", "");
|
|
||||||
conf.erase("nm-2", "");
|
|
||||||
conf.eraseKey("/dir1");
|
|
||||||
conf.eraseKey("/dir2");
|
|
||||||
conf.eraseKey("/dir1/dir1");
|
|
||||||
|
|
||||||
conf.set("nm-1", "val1-1", "/dir1");
|
|
||||||
conf.set("nm-2", "val1-2", "/dir1");
|
|
||||||
conf.set("nm-1", "val-1", "");
|
|
||||||
|
|
||||||
conf.set("nm-1", "val2-1", "/dir2");
|
|
||||||
conf.set("nm-2", "val2-2", "/dir2");
|
|
||||||
|
|
||||||
conf.set("nm-1", "val11-1", "/dir1/dir1");
|
|
||||||
conf.set("nm-2", "val11-2", "/dir1/dir1");
|
|
||||||
|
|
||||||
conf.erase("nm-1", "/dir2");
|
|
||||||
conf.erase("nm-2", "/dir2");
|
|
||||||
conf.erase("nm-1", "/dir1/dir1");
|
|
||||||
conf.erase("nm-2", "/dir1/dir1");
|
|
||||||
|
|
||||||
string data;
|
|
||||||
file_to_string(fn, data, 0);
|
|
||||||
const string ref =
|
|
||||||
"nm-1 = val-1\n"
|
|
||||||
"[/dir1]\n"
|
|
||||||
"nm-1 = val1-1\n"
|
|
||||||
"nm-2 = val1-2\n"
|
|
||||||
;
|
|
||||||
if (data.compare(ref)) {
|
|
||||||
cerr << "Final file:" << endl << data << endl << "Differs from ref:" <<
|
|
||||||
endl << ref << endl;
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
cout << "Updates test Ok" << endl;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
ConfSimple::WalkerCode mywalker(void *, const string& nm, const string& value)
|
|
||||||
{
|
|
||||||
if (nm.empty()) {
|
|
||||||
printf("\n[%s]\n", value.c_str());
|
|
||||||
} else {
|
|
||||||
printf("'%s' -> '%s'\n", nm.c_str(), value.c_str());
|
|
||||||
}
|
|
||||||
return ConfSimple::WALK_CONTINUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *longvalue =
|
|
||||||
"Donnees012345678901234567890123456789012345678901234567890123456789AA"
|
|
||||||
"0123456789012345678901234567890123456789012345678901234567890123456789FIN"
|
|
||||||
;
|
|
||||||
|
|
||||||
void memtest(ConfSimple& c)
|
|
||||||
{
|
|
||||||
cout << "Initial:" << endl;
|
|
||||||
c.showall();
|
|
||||||
if (c.set("nom", "avec nl \n 2eme ligne", "")) {
|
|
||||||
fprintf(stderr, "set with embedded nl succeeded !\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
if (!c.set(string("parm1"), string("1"), string("subkey1"))) {
|
|
||||||
fprintf(stderr, "Set error");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
if (!c.set("sparm", "Parametre \"string\" bla", "s2")) {
|
|
||||||
fprintf(stderr, "Set error");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
if (!c.set("long", longvalue, "")) {
|
|
||||||
fprintf(stderr, "Set error");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
cout << "Final:" << endl;
|
|
||||||
c.showall();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool readwrite(ConfNull *conf)
|
|
||||||
{
|
|
||||||
if (conf->ok()) {
|
|
||||||
// It's ok for the file to not exist here
|
|
||||||
string value;
|
|
||||||
|
|
||||||
if (conf->get("mypid", value)) {
|
|
||||||
cout << "Value for mypid is [" << value << "]" << endl;
|
|
||||||
} else {
|
|
||||||
cout << "mypid not set" << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (conf->get("unstring", value)) {
|
|
||||||
cout << "Value for unstring is [" << value << "]" << endl;
|
|
||||||
} else {
|
|
||||||
cout << "unstring not set" << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
char spid[100];
|
|
||||||
sprintf(spid, "%d", getpid());
|
|
||||||
if (!conf->set("mypid", spid)) {
|
|
||||||
cerr << "Set mypid failed" << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
ostringstream ost;
|
|
||||||
ost << "mypid" << getpid();
|
|
||||||
if (!conf->set(ost.str(), spid, "")) {
|
|
||||||
cerr << "Set mypid failed (2)" << endl;
|
|
||||||
}
|
|
||||||
if (!conf->set("unstring", "Une jolie phrase pour essayer")) {
|
|
||||||
cerr << "Set unstring failed" << endl;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool query(ConfNull *conf, const string& nm, const string& sub)
|
|
||||||
{
|
|
||||||
if (!conf->ok()) {
|
|
||||||
cerr << "Error opening or parsing file\n" << endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
string value;
|
|
||||||
if (!conf->get(nm, value, sub)) {
|
|
||||||
cerr << "name [" << nm << "] not found in [" << sub << "]" << endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
cout << "[" << sub << "] " << nm << " " << value << endl;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool erase(ConfNull *conf, const string& nm, const string& sub)
|
|
||||||
{
|
|
||||||
if (!conf->ok()) {
|
|
||||||
cerr << "Error opening or parsing file\n" << endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!conf->erase(nm, sub)) {
|
|
||||||
cerr << "delete name [" << nm << "] in [" << sub << "] failed" << endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool eraseKey(ConfNull *conf, const string& sub)
|
|
||||||
{
|
|
||||||
if (!conf->ok()) {
|
|
||||||
cerr << "Error opening or parsing file\n" << endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!conf->eraseKey(sub)) {
|
|
||||||
cerr << "delete key [" << sub << "] failed" << endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool setvar(ConfNull *conf, const string& nm, const string& value,
|
|
||||||
const string& sub)
|
|
||||||
{
|
|
||||||
if (!conf->ok()) {
|
|
||||||
cerr << "Error opening or parsing file\n" << endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!conf->set(nm, value, sub)) {
|
|
||||||
cerr << "Set error\n" << endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char usage [] =
|
|
||||||
"testconftree [opts] filename\n"
|
|
||||||
"[-w] : read/write test.\n"
|
|
||||||
"[-s] : string parsing test. Filename must hold parm 'strings'\n"
|
|
||||||
"-a nm value sect : add/set nm,value in 'sect' which can be ''\n"
|
|
||||||
"-q nm sect : subsection test: look for nm in 'sect' which can be ''\n"
|
|
||||||
"-d nm sect : delete nm in 'sect' which can be ''\n"
|
|
||||||
"-E sect : erase key (and all its names)\n"
|
|
||||||
"-S : string io test. No filename in this case\n"
|
|
||||||
"-V : volatile config test. No filename in this case\n"
|
|
||||||
"-U : complex update test. Will erase the named file parameter\n"
|
|
||||||
;
|
|
||||||
|
|
||||||
void Usage()
|
|
||||||
{
|
|
||||||
fprintf(stderr, "%s:%s\n", thisprog, usage);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
static int op_flags;
|
|
||||||
#define OPT_MOINS 0x1
|
|
||||||
#define OPT_w 0x2
|
|
||||||
#define OPT_q 0x4
|
|
||||||
#define OPT_s 0x8
|
|
||||||
#define OPT_S 0x10
|
|
||||||
#define OPT_d 0x20
|
|
||||||
#define OPT_V 0x40
|
|
||||||
#define OPT_a 0x80
|
|
||||||
#define OPT_k 0x100
|
|
||||||
#define OPT_E 0x200
|
|
||||||
#define OPT_U 0x400
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
const char *nm = 0;
|
|
||||||
const char *sub = 0;
|
|
||||||
const char *value = 0;
|
|
||||||
|
|
||||||
thisprog = argv[0];
|
|
||||||
argc--;
|
|
||||||
argv++;
|
|
||||||
|
|
||||||
while (argc > 0 && **argv == '-') {
|
|
||||||
(*argv)++;
|
|
||||||
if (!(**argv))
|
|
||||||
/* Cas du "adb - core" */
|
|
||||||
{
|
|
||||||
Usage();
|
|
||||||
}
|
|
||||||
while (**argv)
|
|
||||||
switch (*(*argv)++) {
|
|
||||||
case 'a':
|
|
||||||
op_flags |= OPT_a;
|
|
||||||
if (argc < 4) {
|
|
||||||
Usage();
|
|
||||||
}
|
|
||||||
nm = *(++argv);
|
|
||||||
argc--;
|
|
||||||
value = *(++argv);
|
|
||||||
argc--;
|
|
||||||
sub = *(++argv);
|
|
||||||
argc--;
|
|
||||||
goto b1;
|
|
||||||
case 'd':
|
|
||||||
op_flags |= OPT_d;
|
|
||||||
if (argc < 3) {
|
|
||||||
Usage();
|
|
||||||
}
|
|
||||||
nm = *(++argv);
|
|
||||||
argc--;
|
|
||||||
sub = *(++argv);
|
|
||||||
argc--;
|
|
||||||
goto b1;
|
|
||||||
case 'E':
|
|
||||||
op_flags |= OPT_E;
|
|
||||||
if (argc < 2) {
|
|
||||||
Usage();
|
|
||||||
}
|
|
||||||
sub = *(++argv);
|
|
||||||
argc--;
|
|
||||||
goto b1;
|
|
||||||
case 'k':
|
|
||||||
op_flags |= OPT_k;
|
|
||||||
break;
|
|
||||||
case 'q':
|
|
||||||
op_flags |= OPT_q;
|
|
||||||
if (argc < 3) {
|
|
||||||
Usage();
|
|
||||||
}
|
|
||||||
nm = *(++argv);
|
|
||||||
argc--;
|
|
||||||
sub = *(++argv);
|
|
||||||
argc--;
|
|
||||||
goto b1;
|
|
||||||
case 's':
|
|
||||||
op_flags |= OPT_s;
|
|
||||||
break;
|
|
||||||
case 'S':
|
|
||||||
op_flags |= OPT_S;
|
|
||||||
break;
|
|
||||||
case 'V':
|
|
||||||
op_flags |= OPT_V;
|
|
||||||
break;
|
|
||||||
case 'U':
|
|
||||||
op_flags |= OPT_U;
|
|
||||||
break;
|
|
||||||
case 'w':
|
|
||||||
op_flags |= OPT_w;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
Usage();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
b1:
|
|
||||||
argc--;
|
|
||||||
argv++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((op_flags & OPT_S)) {
|
|
||||||
// String storage test
|
|
||||||
if (argc != 0) {
|
|
||||||
Usage();
|
|
||||||
}
|
|
||||||
string s;
|
|
||||||
ConfSimple c(s);
|
|
||||||
memtest(c);
|
|
||||||
exit(0);
|
|
||||||
} else if ((op_flags & OPT_V)) {
|
|
||||||
// No storage test
|
|
||||||
if (argc != 0) {
|
|
||||||
Usage();
|
|
||||||
}
|
|
||||||
ConfSimple c;
|
|
||||||
memtest(c);
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Other tests use file(s) as backing store
|
|
||||||
if (argc < 1) {
|
|
||||||
Usage();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (op_flags & OPT_U) {
|
|
||||||
exit(!complex_updates(argv[0]));
|
|
||||||
}
|
|
||||||
vector<string> flist;
|
|
||||||
while (argc--) {
|
|
||||||
flist.push_back(*argv++);
|
|
||||||
}
|
|
||||||
bool ro = !(op_flags & (OPT_w | OPT_a | OPT_d | OPT_E));
|
|
||||||
ConfNull *conf = 0;
|
|
||||||
switch (flist.size()) {
|
|
||||||
case 0:
|
|
||||||
Usage();
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
conf = new ConfTree(flist.front().c_str(), ro);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
conf = new ConfStack<ConfTree>(flist, ro);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (op_flags & OPT_w) {
|
|
||||||
exit(!readwrite(conf));
|
|
||||||
} else if (op_flags & OPT_q) {
|
|
||||||
exit(!query(conf, nm, sub));
|
|
||||||
} else if (op_flags & OPT_k) {
|
|
||||||
if (!conf->ok()) {
|
|
||||||
cerr << "conf init error" << endl;
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
vector<string>lst = conf->getSubKeys();
|
|
||||||
for (vector<string>::const_iterator it = lst.begin();
|
|
||||||
it != lst.end(); it++) {
|
|
||||||
cout << *it << endl;
|
|
||||||
}
|
|
||||||
exit(0);
|
|
||||||
} else if (op_flags & OPT_a) {
|
|
||||||
exit(!setvar(conf, nm, value, sub));
|
|
||||||
} else if (op_flags & OPT_d) {
|
|
||||||
exit(!erase(conf, nm, sub));
|
|
||||||
} else if (op_flags & OPT_E) {
|
|
||||||
exit(!eraseKey(conf, sub));
|
|
||||||
} else if (op_flags & OPT_s) {
|
|
||||||
if (!conf->ok()) {
|
|
||||||
cerr << "Cant open /parse conf file " << endl;
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
string source;
|
|
||||||
if (!conf->get(string("strings"), source, "")) {
|
|
||||||
cerr << "Cant get param 'strings'" << endl;
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
cout << "source: [" << source << "]" << endl;
|
|
||||||
vector<string> strings;
|
|
||||||
if (!stringToStrings(source, strings)) {
|
|
||||||
cerr << "parse failed" << endl;
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (vector<string>::iterator it = strings.begin();
|
|
||||||
it != strings.end(); it++) {
|
|
||||||
cout << "[" << *it << "]" << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
if (!conf->ok()) {
|
|
||||||
fprintf(stderr, "Open failed\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
printf("LIST\n");
|
|
||||||
conf->showall();
|
|
||||||
//printf("WALK\n");conf->sortwalk(mywalker, 0);
|
|
||||||
printf("\nNAMES in global space:\n");
|
|
||||||
vector<string> names = conf->getNames("");
|
|
||||||
for (vector<string>::iterator it = names.begin();
|
|
||||||
it != names.end(); it++) {
|
|
||||||
cout << *it << " ";
|
|
||||||
}
|
|
||||||
cout << endl;
|
|
||||||
printf("\nNAMES in global space matching t* \n");
|
|
||||||
names = conf->getNames("", "t*");
|
|
||||||
for (vector<string>::iterator it = names.begin();
|
|
||||||
it != names.end(); it++) {
|
|
||||||
cout << *it << " ";
|
|
||||||
}
|
|
||||||
cout << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|||||||
@ -265,6 +265,11 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool write(ostream& out) const;
|
bool write(ostream& out) const;
|
||||||
|
|
||||||
|
/** Give access to semi-parsed file contents */
|
||||||
|
const vector<ConfLine>& getlines() const {
|
||||||
|
return m_order;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool dotildexpand;
|
bool dotildexpand;
|
||||||
StatusCode status;
|
StatusCode status;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user