forked from lix-project/lix
* Parse multi-valued options.
This commit is contained in:
parent
fbedf6056e
commit
4578a490ce
|
@ -77,4 +77,4 @@ build-allow-root = true
|
||||||
#
|
#
|
||||||
# Example:
|
# Example:
|
||||||
# build-users = nix-builder-1 nix-builder-2 nix-builder-3
|
# build-users = nix-builder-1 nix-builder-2 nix-builder-3
|
||||||
#build-users =
|
build-users =
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "globals.hh"
|
#include "globals.hh"
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
|
||||||
string nixStore = "/UNINIT";
|
string nixStore = "/UNINIT";
|
||||||
|
@ -22,7 +23,15 @@ list<string> buildUsers;
|
||||||
|
|
||||||
static bool settingsRead = false;
|
static bool settingsRead = false;
|
||||||
|
|
||||||
static map<string, string> settings;
|
static map<string, Strings> settings;
|
||||||
|
|
||||||
|
|
||||||
|
template<class T, class A> A & genericAt(T & container, unsigned int n)
|
||||||
|
{
|
||||||
|
class T::iterator i = container.begin();
|
||||||
|
advance(i, n);
|
||||||
|
return *i;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void readSettings()
|
static void readSettings()
|
||||||
|
@ -43,34 +52,44 @@ static void readSettings()
|
||||||
if (hash != string::npos)
|
if (hash != string::npos)
|
||||||
line = string(line, 0, hash);
|
line = string(line, 0, hash);
|
||||||
|
|
||||||
if (line.find_first_not_of(" ") == string::npos) continue;
|
Strings tokens = tokenizeString(line);
|
||||||
|
if (tokens.empty()) continue;
|
||||||
|
|
||||||
istringstream is(line);
|
if (tokens.size() < 2 || genericAt<Strings, string>(tokens, 1) != "=")
|
||||||
string name, sep, value;
|
|
||||||
is >> name >> sep >> value;
|
|
||||||
if (sep != "=" || !is)
|
|
||||||
throw Error(format("illegal configuration line `%1%' in `%2%'") % line % settingsFile);
|
throw Error(format("illegal configuration line `%1%' in `%2%'") % line % settingsFile);
|
||||||
|
|
||||||
settings[name] = value;
|
string name = genericAt<Strings, string>(tokens, 0);
|
||||||
|
|
||||||
|
Strings::iterator i = tokens.begin();
|
||||||
|
advance(i, 2);
|
||||||
|
settings[name] = Strings(i, tokens.end());
|
||||||
};
|
};
|
||||||
|
|
||||||
settingsRead = true;
|
settingsRead = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
string querySetting(const string & name, const string & def)
|
Strings querySetting(const string & name, const Strings & def)
|
||||||
{
|
{
|
||||||
if (!settingsRead) readSettings();
|
if (!settingsRead) readSettings();
|
||||||
map<string, string>::iterator i = settings.find(name);
|
map<string, Strings>::iterator i = settings.find(name);
|
||||||
return i == settings.end() ? def : i->second;
|
return i == settings.end() ? def : i->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool queryBoolSetting(const string & name, bool def)
|
bool queryBoolSetting(const string & name, bool def)
|
||||||
{
|
{
|
||||||
string value = querySetting(name, def ? "true" : "false");
|
Strings defs;
|
||||||
if (value == "true") return true;
|
if (def) defs.push_back("true"); else defs.push_back("false");
|
||||||
else if (value == "false") return false;
|
|
||||||
|
Strings value = querySetting(name, defs);
|
||||||
|
if (value.size() != 1)
|
||||||
|
throw Error(format("configuration option `%1%' should be either `true' or `false', not a list")
|
||||||
|
% name);
|
||||||
|
|
||||||
|
string v = value.front();
|
||||||
|
if (v == "true") return true;
|
||||||
|
else if (v == "false") return false;
|
||||||
else throw Error(format("configuration option `%1%' should be either `true' or `false', not `%2%'")
|
else throw Error(format("configuration option `%1%' should be either `true' or `false', not `%2%'")
|
||||||
% name % value);
|
% name % v);
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,7 @@ extern bool buildAllowRoot;
|
||||||
extern list<string> buildUsers;
|
extern list<string> buildUsers;
|
||||||
|
|
||||||
|
|
||||||
string querySetting(const string & name, const string & def);
|
Strings querySetting(const string & name, const Strings & def);
|
||||||
|
|
||||||
bool queryBoolSetting(const string & name, bool def);
|
bool queryBoolSetting(const string & name, bool def);
|
||||||
|
|
||||||
|
|
|
@ -665,6 +665,21 @@ Strings unpackStrings(const string & s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Strings tokenizeString(const string & s, const string & separators)
|
||||||
|
{
|
||||||
|
Strings result;
|
||||||
|
string::size_type pos = s.find_first_not_of(separators, 0);
|
||||||
|
while (pos != string::npos) {
|
||||||
|
string::size_type end = s.find_first_of(separators, pos + 1);
|
||||||
|
if (end == string::npos) end = s.size();
|
||||||
|
string token(s, pos, end - pos);
|
||||||
|
result.push_back(token);
|
||||||
|
pos = s.find_first_not_of(separators, end);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
string statusToString(int status)
|
string statusToString(int status)
|
||||||
{
|
{
|
||||||
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
|
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
|
||||||
|
|
|
@ -261,6 +261,10 @@ string packStrings(const Strings & strings);
|
||||||
Strings unpackStrings(const string & s);
|
Strings unpackStrings(const string & s);
|
||||||
|
|
||||||
|
|
||||||
|
/* String tokenizer. */
|
||||||
|
Strings tokenizeString(const string & s, const string & separators = " \t\n\r");
|
||||||
|
|
||||||
|
|
||||||
/* Convert the exit status of a child as returned by wait() into an
|
/* Convert the exit status of a child as returned by wait() into an
|
||||||
error string. */
|
error string. */
|
||||||
string statusToString(int status);
|
string statusToString(int status);
|
||||||
|
|
Loading…
Reference in a new issue