Browse Source

add default and override handling for Cnf::FindVector

Automatically handle the override of list options via its parent value
which can even be a comma-separated list of values. It also adds an easy
way of providing a default for the list.
David Kalnischkies 10 years ago
parent
commit
a5414e5640

+ 11 - 61
apt-pkg/aptconfiguration.cc

@@ -49,11 +49,6 @@ const Configuration::getCompressionTypes(bool const &Cached) {
 	setDefaultConfigurationForCompressors();
 	std::vector<APT::Configuration::Compressor> const compressors = getCompressors();
 
-	// accept non-list order as override setting for config settings on commandline
-	std::string const overrideOrder = _config->Find("Acquire::CompressionTypes::Order","");
-	if (overrideOrder.empty() == false)
-		types.push_back(overrideOrder);
-
 	// load the order setting into our vector
 	std::vector<std::string> const order = _config->FindVector("Acquire::CompressionTypes::Order");
 	for (std::vector<std::string>::const_iterator o = order.begin();
@@ -227,61 +222,11 @@ std::vector<std::string> const Configuration::getLanguages(bool const &All,
 			}
 		}
 	} else {
+		// cornercase: LANG=C, so we use only "en" Translation
 		environment.push_back("en");
 	}
 
-	// Support settings like Acquire::Languages=none on the command line to
-	// override the configuration settings vector of languages.
-	string const forceLang = _config->Find("Acquire::Languages","");
-	if (forceLang.empty() == false) {
-		if (forceLang == "none") {
-			codes.clear();
-			allCodes.clear();
-			allCodes.push_back("none");
-		} else {
-			if (forceLang == "environment")
-				codes = environment;
-			else
-				codes.push_back(forceLang);
-			allCodes = codes;
-			for (std::vector<string>::const_iterator b = builtin.begin();
-			     b != builtin.end(); ++b)
-				if (std::find(allCodes.begin(), allCodes.end(), *b) == allCodes.end())
-					allCodes.push_back(*b);
-		}
-		if (All == true)
-			return allCodes;
-		else
-			return codes;
-	}
-
-	// cornercase: LANG=C, so we use only "en" Translation
-	if (envShort == "C") {
-		allCodes = codes = environment;
-		allCodes.insert(allCodes.end(), builtin.begin(), builtin.end());
-		if (All == true)
-			return allCodes;
-		else
-			return codes;
-	}
-
-	std::vector<string> const lang = _config->FindVector("Acquire::Languages");
-	// the default setting -> "environment, en"
-	if (lang.empty() == true) {
-		codes = environment;
-		if (envShort != "en")
-			codes.push_back("en");
-		allCodes = codes;
-		for (std::vector<string>::const_iterator b = builtin.begin();
-		     b != builtin.end(); ++b)
-			if (std::find(allCodes.begin(), allCodes.end(), *b) == allCodes.end())
-				allCodes.push_back(*b);
-		if (All == true)
-			return allCodes;
-		else
-			return codes;
-	}
-
+	std::vector<string> const lang = _config->FindVector("Acquire::Languages", "environment,en");
 	// the configs define the order, so add the environment
 	// then needed and ensure the codes are not listed twice.
 	bool noneSeen = false;
@@ -308,10 +253,15 @@ std::vector<std::string> const Configuration::getLanguages(bool const &All,
 		allCodes.push_back(*l);
 	}
 
-	for (std::vector<string>::const_iterator b = builtin.begin();
-	     b != builtin.end(); ++b)
-		if (std::find(allCodes.begin(), allCodes.end(), *b) == allCodes.end())
-			allCodes.push_back(*b);
+	if (allCodes.empty() == false) {
+		for (std::vector<string>::const_iterator b = builtin.begin();
+		     b != builtin.end(); ++b)
+			if (std::find(allCodes.begin(), allCodes.end(), *b) == allCodes.end())
+				allCodes.push_back(*b);
+	} else {
+		// "none" was forced
+		allCodes.push_back("none");
+	}
 
 	if (All == true)
 		return allCodes;

+ 12 - 2
apt-pkg/contrib/configuration.cc

@@ -21,6 +21,7 @@
 #include <apt-pkg/error.h>
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/fileutl.h>
+#include <apt-pkg/init.h>
 
 #include <vector>
 #include <fstream>
@@ -246,12 +247,18 @@ string Configuration::FindDir(const char *Name,const char *Default) const
 // Configuration::FindVector - Find a vector of values			/*{{{*/
 // ---------------------------------------------------------------------
 /* Returns a vector of config values under the given item */
-vector<string> Configuration::FindVector(const char *Name) const
+#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR < 13)
+vector<string> Configuration::FindVector(const char *Name) const { return FindVector(Name, ""); }
+#endif
+vector<string> Configuration::FindVector(const char *Name, std::string const &Default) const
 {
    vector<string> Vec;
    const Item *Top = Lookup(Name);
    if (Top == NULL)
-      return Vec;
+      return VectorizeString(Default, ',');
+
+   if (Top->Value.empty() == false)
+      return VectorizeString(Top->Value, ',');
 
    Item *I = Top->Child;
    while(I != NULL)
@@ -259,6 +266,9 @@ vector<string> Configuration::FindVector(const char *Name) const
       Vec.push_back(I->Value);
       I = I->Next;
    }
+   if (Vec.empty() == true)
+      return VectorizeString(Default, ',');
+
    return Vec;
 }
 									/*}}}*/

+ 15 - 1
apt-pkg/contrib/configuration.h

@@ -74,8 +74,22 @@ class Configuration
    std::string Find(std::string const &Name, std::string const &Default) const {return Find(Name.c_str(),Default.c_str());};
    std::string FindFile(const char *Name,const char *Default = 0) const;
    std::string FindDir(const char *Name,const char *Default = 0) const;
+   /** return a list of child options
+    *
+    * Options like Acquire::Languages are handled as lists which
+    * can be overridden and have a default. For the later two a comma
+    * separated list of values is supported.
+    *
+    * \param Name of the parent node
+    * \param Default list of values separated by commas */
+   std::vector<std::string> FindVector(const char *Name, std::string const &Default) const;
+   std::vector<std::string> FindVector(std::string const &Name, std::string const &Default) const { return FindVector(Name.c_str(), Default); };
+#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13)
+   std::vector<std::string> FindVector(const char *Name) const { return FindVector(Name, ""); };
+#else
    std::vector<std::string> FindVector(const char *Name) const;
-   std::vector<std::string> FindVector(std::string const &Name) const { return FindVector(Name.c_str()); };
+#endif
+   std::vector<std::string> FindVector(std::string const &Name) const { return FindVector(Name.c_str(), ""); };
    int FindI(const char *Name,int const &Default = 0) const;
    int FindI(std::string const &Name,int const &Default = 0) const {return FindI(Name.c_str(),Default);};
    bool FindB(const char *Name,bool const &Default = false) const;

+ 3 - 1
apt-pkg/contrib/strutl.cc

@@ -1130,9 +1130,11 @@ bool TokSplitString(char Tok,char *Input,char **List,
    also, but the advantage is that we have an iteratable vector */
 vector<string> VectorizeString(string const &haystack, char const &split)
 {
+   vector<string> exploded;
+   if (haystack.empty() == true)
+      return exploded;
    string::const_iterator start = haystack.begin();
    string::const_iterator end = start;
-   vector<string> exploded;
    do {
       for (; end != haystack.end() && *end != split; ++end);
       exploded.push_back(string(start, end));

+ 1 - 0
prepare-release

@@ -1,6 +1,7 @@
 #!/bin/sh
 set -e
 
+cd "$(readlink -f $(dirname $0))"
 dpkg-checkbuilddeps -d 'libxml2-utils'
 
 if [ -n "${GBP_BUILD_DIR}" ]; then

+ 31 - 3
test/libapt/configuration_test.cc

@@ -98,9 +98,37 @@ int main(int argc,const char *argv[]) {
 	equals(Cnf.FindDir("Dir::State"), "/rootdir/dev/null");
 	equals(Cnf.FindDir("Dir::State::lists"), "/rootdir/dev/null");
 
-        Cnf.Set("Moo::Bar", "1");
-        Cnf.Clear();
-        equals(Cnf.Find("Moo::Bar"), "");
+	Cnf.Set("Moo::Bar", "1");
+	Cnf.Clear();
+	equals(Cnf.Find("Moo::Bar"), "");
+
+	std::vector<std::string> vec = Cnf.FindVector("Test::Vector", "");
+	equals(vec.size(), 0);
+	vec = Cnf.FindVector("Test::Vector", "foo");
+	equals(vec.size(), 1);
+	equals(vec[0], "foo");
+	vec = Cnf.FindVector("Test::Vector", "foo,bar");
+	equals(vec.size(), 2);
+	equals(vec[0], "foo");
+	equals(vec[1], "bar");
+	Cnf.Set("Test::Vector::", "baz");
+	Cnf.Set("Test::Vector::", "bob");
+	Cnf.Set("Test::Vector::", "dob");
+	vec = Cnf.FindVector("Test::Vector");
+	equals(vec.size(), 3);
+	equals(vec[0], "baz");
+	equals(vec[1], "bob");
+	equals(vec[2], "dob");
+	vec = Cnf.FindVector("Test::Vector", "foo,bar");
+	equals(vec.size(), 3);
+	equals(vec[0], "baz");
+	equals(vec[1], "bob");
+	equals(vec[2], "dob");
+	Cnf.Set("Test::Vector", "abel,bravo");
+	vec = Cnf.FindVector("Test::Vector", "foo,bar");
+	equals(vec.size(), 2);
+	equals(vec[0], "abel");
+	equals(vec[1], "bravo");
 
 	//FIXME: Test for configuration file parsing;
 	// currently only integration/ tests test them implicitly

+ 8 - 0
test/libapt/getlanguages_test.cc

@@ -105,6 +105,14 @@ int main(int argc,char *argv[])
 	vec = APT::Configuration::getLanguages(false, false, env);
 	equals(vec.size(), 1);
 	equals(vec[0], "fr");
+
+	_config->Set("Acquire::Languages", "environment,en");
+	env[0] = "de_DE.UTF-8";
+	vec = APT::Configuration::getLanguages(false, false, env);
+	equals(vec.size(), 3);
+	equals(vec[0], "de_DE");
+	equals(vec[1], "de");
+	equals(vec[2], "en");
 	_config->Set("Acquire::Languages", "");
 
 	_config->Set("Acquire::Languages::1", "environment");