aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2007-03-04 13:50:42 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2007-03-04 13:50:42 +0000
commit45cea1df648c2ed71f21cd0055600e76c846fda3 (patch)
treea5699fa7eebaa46d2742d9c6bb47e8fdc5b0e774
parent314dd70be55550665051fe0d5a73987053c9d148 (diff)
downloadpaludis-45cea1df648c2ed71f21cd0055600e76c846fda3.tar.gz
paludis-45cea1df648c2ed71f21cd0055600e76c846fda3.tar.xz
Supererer ConfigFile
-rw-r--r--paludis/config_file.cc40
-rw-r--r--paludis/config_file.hh3
-rw-r--r--paludis/config_file_TEST.cc23
3 files changed, 59 insertions, 7 deletions
diff --git a/paludis/config_file.cc b/paludis/config_file.cc
index fad4741..87ba131 100644
--- a/paludis/config_file.cc
+++ b/paludis/config_file.cc
@@ -25,10 +25,12 @@
#include <paludis/util/stringify.hh>
#include <paludis/util/strip.hh>
#include <paludis/util/tokeniser.hh>
+#include <paludis/util/join.hh>
#include <fstream>
#include <istream>
#include <list>
+#include <set>
#include <map>
/** \file
@@ -322,9 +324,11 @@ namespace paludis
KeyValueConfigFile::Defaults defaults;
std::map<std::string, std::string> keys;
std::string filename;
+ bool (* is_incremental) (const std::string &, const KeyValueConfigFile &);
- Implementation(const KeyValueConfigFile::Defaults & d) :
- defaults(d)
+ Implementation(const KeyValueConfigFile::Defaults & d, bool (* i) (const std::string &, const KeyValueConfigFile &)) :
+ defaults(d),
+ is_incremental(i)
{
}
};
@@ -523,9 +527,10 @@ namespace
}
}
-KeyValueConfigFile::KeyValueConfigFile(const Source & s, const Defaults & d) :
+KeyValueConfigFile::KeyValueConfigFile(const Source & s, const Defaults & d,
+ bool (* i) (const std::string &, const KeyValueConfigFile &)) :
ConfigFile(s),
- PrivateImplementationPattern<KeyValueConfigFile>(new Implementation<KeyValueConfigFile>(d))
+ PrivateImplementationPattern<KeyValueConfigFile>(new Implementation<KeyValueConfigFile>(d, i))
{
Context context("When parsing key/value configuration file" + (s.filename().empty() ? ":" :
"'" + s.filename() + "':"));
@@ -576,8 +581,31 @@ KeyValueConfigFile::KeyValueConfigFile(const Source & s, const Defaults & d) :
std::string value(grab_value(c, c_end, *this, s.filename()));
- _imp->keys.erase(key);
- _imp->keys.insert(std::make_pair(key, value));
+ if (_imp->is_incremental && (*_imp->is_incremental)(key, *this))
+ {
+ std::list<std::string> values;
+ std::set<std::string> new_values;
+ WhitespaceTokeniser::get_instance()->tokenise(get(key), std::back_inserter(values));
+ WhitespaceTokeniser::get_instance()->tokenise(value, std::back_inserter(values));
+ for (std::list<std::string>::const_iterator v(values.begin()), v_end(values.end()) ;
+ v != v_end ; ++v)
+ if (v->empty())
+ continue;
+ else if ("-*" == *v)
+ new_values.clear();
+ else if ('-' == v->at(0))
+ new_values.erase(v->substr(1));
+ else
+ new_values.insert(*v);
+
+ _imp->keys.erase(key);
+ _imp->keys.insert(std::make_pair(key, join(new_values.begin(), new_values.end(), " ")));
+ }
+ else
+ {
+ _imp->keys.erase(key);
+ _imp->keys.insert(std::make_pair(key, value));
+ }
}
}
}
diff --git a/paludis/config_file.hh b/paludis/config_file.hh
index 1682235..9abea8a 100644
--- a/paludis/config_file.hh
+++ b/paludis/config_file.hh
@@ -121,7 +121,8 @@ namespace paludis
Iterator end() const;
};
- KeyValueConfigFile(const Source &, const Defaults & = Defaults());
+ KeyValueConfigFile(const Source &, const Defaults & = Defaults(),
+ bool (* is_incremental) (const std::string &, const KeyValueConfigFile &) = 0);
~KeyValueConfigFile();
typedef libwrapiter::ForwardIterator<KeyValueConfigFile, const std::pair<const std::string, std::string> > Iterator;
diff --git a/paludis/config_file_TEST.cc b/paludis/config_file_TEST.cc
index 9093629..46f4bc7 100644
--- a/paludis/config_file_TEST.cc
+++ b/paludis/config_file_TEST.cc
@@ -20,6 +20,7 @@
#include <paludis/config_file.hh>
#include <paludis/util/fs_entry.hh>
#include <paludis/util/stringify.hh>
+#include <paludis/util/system.hh>
#include <paludis/util/collection_concrete.hh>
#include <sstream>
#include <test/test_framework.hh>
@@ -225,6 +226,28 @@ namespace test_cases
}
} test_key_value_config_file_vars;
+ struct KeyValueConfigFileDefaultsTest : TestCase
+ {
+ KeyValueConfigFileDefaultsTest() : TestCase("key value config file with defaults") { }
+
+ void run()
+ {
+ setenv("moo", "cow", 1);
+
+ std::stringstream d_s;
+ d_s << "foo=oink" << std::endl;
+ std::tr1::shared_ptr<KeyValueConfigFile> d_ff(new KeyValueConfigFile(d_s, &getenv_with_default));
+
+ std::stringstream s;
+ s << "x=${foo}" << std::endl;
+ s << "y=${moo}" << std::endl;
+ KeyValueConfigFile ff(s, d_ff);
+
+ TEST_CHECK_EQUAL(ff.get("x"), "oink");
+ TEST_CHECK_EQUAL(ff.get("y"), "cow");
+ }
+ } test_key_value_config_file_defaults;
+
/**
* \test Test KeyValueConfigFile errors.
*