171
171
string Configuration::FindFile(const char *Name,const char *Default) const
173
173
const Item *RootItem = Lookup("RootDir");
174
std::string rootDir = (RootItem == 0) ? "" : RootItem->Value;
175
if(rootDir.size() > 0 && rootDir[rootDir.size() - 1] != '/')
176
rootDir.push_back('/');
174
std::string result = (RootItem == 0) ? "" : RootItem->Value;
175
if(result.empty() == false && result[result.size() - 1] != '/')
176
result.push_back('/');
178
178
const Item *Itm = Lookup(Name);
179
179
if (Itm == 0 || Itm->Value.empty() == true)
184
return rootDir + Default;
182
result.append(Default);
187
string val = Itm->Value;
188
while (Itm->Parent != 0)
190
if (Itm->Parent->Value.empty() == true)
186
string val = Itm->Value;
187
while (Itm->Parent != 0)
189
if (Itm->Parent->Value.empty() == true)
196
if (val.length() >= 1 && val[0] == '/')
198
if (val.compare(0, 9, "/dev/null") == 0)
204
if (val.length() >= 2 && (val[0] == '~' || val[0] == '.') && val[1] == '/')
208
if (val.length() >= 3 && val[0] == '.' && val[1] == '.' && val[2] == '/')
211
if (Itm->Parent->Value.end()[-1] != '/')
214
val.insert(0, Itm->Parent->Value);
192
215
Itm = Itm->Parent;
197
if (val.length() >= 1 && val[0] == '/')
201
if (val.length() >= 2 && (val[0] == '~' || val[0] == '.') && val[1] == '/')
205
if (val.length() >= 3 && val[0] == '.' && val[1] == '.' && val[2] == '/')
208
if (Itm->Parent->Value.end()[-1] != '/')
211
val.insert(0, Itm->Parent->Value);
215
return rootDir + val;
220
// do some normalisation by removing // and /./ from the path
221
size_t found = string::npos;
222
while ((found = result.find("/./")) != string::npos)
223
result.replace(found, 3, "/");
224
while ((found = result.find("//")) != string::npos)
225
result.replace(found, 2, "/");
218
230
// Configuration::FindDir - Find a directory name /*{{{*/
223
235
string Res = FindFile(Name,Default);
224
236
if (Res.end()[-1] != '/')
238
size_t const found = Res.rfind("/dev/null");
239
if (found != string::npos && found == Res.size() - 9)
240
return Res; // /dev/null returning
225
241
return Res + '/';
482
499
/* Dump the entire configuration space */
483
500
void Configuration::Dump(ostream& str)
485
/* Write out all of the configuration directives by walking the
502
Dump(str, NULL, "%f \"%v\";\n", true);
504
void Configuration::Dump(ostream& str, char const * const root,
505
char const * const formatstr, bool const emptyValue)
507
const Configuration::Item* Top = Tree(root);
510
const Configuration::Item* const Root = (root == NULL) ? NULL : Top;
511
std::vector<std::string> const format = VectorizeString(formatstr, '%');
513
/* Write out all of the configuration directives by walking the
486
514
configuration tree */
487
const Configuration::Item *Top = Tree(0);
490
str << Top->FullTag() << " \"" << Top->Value << "\";" << endl;
516
if (emptyValue == true || Top->Value.empty() == emptyValue)
518
std::vector<std::string>::const_iterator f = format.begin();
520
for (++f; f != format.end(); ++f)
522
if (f->empty() == true)
528
char const type = (*f)[0];
530
str << Top->FullTag();
531
else if (type == 't')
533
else if (type == 'v')
535
else if (type == 'F')
536
str << QuoteString(Top->FullTag(), "=\"\n");
537
else if (type == 'T')
538
str << QuoteString(Top->Tag, "=\"\n");
539
else if (type == 'V')
540
str << QuoteString(Top->Value, "=\"\n");
541
else if (type == 'n')
543
else if (type == 'N')
547
str << f->c_str() + 1;
492
551
if (Top->Child != 0)
494
553
Top = Top->Child;
498
557
while (Top != 0 && Top->Next == 0)
499
558
Top = Top->Parent;
564
const Configuration::Item* I = Top;