diff options
author | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2015-06-17T14·20+0200 |
---|---|---|
committer | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2015-06-17T14·20+0200 |
commit | 65f17cd3309e192dcf0d61d3d946a3610420a9d4 (patch) | |
tree | 097a00551e14e44cf6715bcd75996992785d311f | |
parent | 0d4d92fcf92030dbaad0f5251232657be218cc5d (diff) |
Support URLs in $NIX_PATH
This didn't work (despite claims in the manual), because the colon in "http://" was parsed as a element separator. So handle "://" specially.
-rw-r--r-- | src/libexpr/eval.cc | 14 | ||||
-rw-r--r-- | src/libutil/util.cc | 14 | ||||
-rw-r--r-- | src/libutil/util.hh | 5 |
3 files changed, 32 insertions, 1 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 88cf9f45342c..d61ee7e80795 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -234,6 +234,18 @@ void initGC() } +/* Very hacky way to parse $NIX_PATH, which is colon-separated, but + can contain URLs (e.g. "nixpkgs=https://bla...:foo=https://"). */ +static Strings parseNixPath(const string & in) +{ + string marker = "\001//"; + auto res = tokenizeString<Strings>(replaceStrings(in, "://", marker), ":"); + for (auto & s : res) + s = replaceStrings(s, marker, "://"); + return res; +} + + EvalState::EvalState(const Strings & _searchPath) : sWith(symbols.create("<with>")) , sOutPath(symbols.create("outPath")) @@ -266,7 +278,7 @@ EvalState::EvalState(const Strings & _searchPath) assert(gcInitialised); /* Initialise the Nix expression search path. */ - Strings paths = tokenizeString<Strings>(getEnv("NIX_PATH", ""), ":"); + Strings paths = parseNixPath(getEnv("NIX_PATH", "")); for (auto & i : _searchPath) addToSearchPath(i, true); for (auto & i : paths) addToSearchPath(i); addToSearchPath("nix=" + settings.nixDataDir + "/nix/corepkgs"); diff --git a/src/libutil/util.cc b/src/libutil/util.cc index 903b97100b93..596b79e10e69 100644 --- a/src/libutil/util.cc +++ b/src/libutil/util.cc @@ -1095,6 +1095,20 @@ string trim(const string & s, const string & whitespace) } +string replaceStrings(const std::string & s, + const std::string & from, const std::string & to) +{ + if (from.empty()) return s; + string res = s; + size_t pos = 0; + while ((pos = res.find(from, pos)) != std::string::npos) { + res.replace(pos, from.size(), to); + pos += to.size(); + } + return res; +} + + string statusToString(int status) { if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { diff --git a/src/libutil/util.hh b/src/libutil/util.hh index 6e20a22d9da8..187e05ece050 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -341,6 +341,11 @@ string chomp(const string & s); string trim(const string & s, const string & whitespace = " \n\r\t"); +/* Replace all occurrences of a string inside another string. */ +string replaceStrings(const std::string & s, + const std::string & from, const std::string & to); + + /* Convert the exit status of a child as returned by wait() into an error string. */ string statusToString(int status); |