summary refs log tree commit diff
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2011-08-06 17:48:57 +0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2011-08-06 17:48:57 +0000
commitc7101dac0bd2631e50846194fc841ef5ef77461f (patch)
tree597a2058c70f6000ade9f2f48ef9e998f70ce762
parent1578b2261d28003c8c1459041302e1f3c1921c43 (diff)
downloadguix-c7101dac0bd2631e50846194fc841ef5ef77461f.tar.gz
* Allow redirections in search path entries. E.g. if you have a
  directory

    /home/eelco/src/stdenv-updates

  that you want to use as the directory for import such as

    with (import <nixpkgs> { });

  then you can say

    $ nix-build -I nixpkgs=/home/eelco/src/stdenv-updates

-rw-r--r--src/libexpr/eval.hh5
-rw-r--r--src/libexpr/parser.y26
-rw-r--r--tests/lang/eval-okay-search-path.exp2
-rw-r--r--tests/lang/eval-okay-search-path.flags2
-rw-r--r--tests/lang/eval-okay-search-path.nix2
5 files changed, 28 insertions, 9 deletions
diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh
index 1583665bad..413234f2bf 100644
--- a/src/libexpr/eval.hh
+++ b/src/libexpr/eval.hh
@@ -213,8 +213,9 @@ private:
 
     std::map<Path, Expr *> parseTrees;
 
-    Paths searchPath;
-    Paths::iterator searchPathInsertionPoint;
+    typedef list<std::pair<string, Path> > SearchPath;
+    SearchPath searchPath;
+    SearchPath::iterator searchPathInsertionPoint;
 
 public:
     
diff --git a/src/libexpr/parser.y b/src/libexpr/parser.y
index cd63666dc5..e54f6fe0a7 100644
--- a/src/libexpr/parser.y
+++ b/src/libexpr/parser.y
@@ -530,18 +530,36 @@ Expr * EvalState::parseExprFromString(const string & s, const Path & basePath)
 
 void EvalState::addToSearchPath(const string & s)
 {
-    Path path = absPath(s);
+    size_t pos = s.find('=');
+    string prefix;
+    Path path;
+    if (pos == string::npos) {
+        path = s;
+    } else {
+        prefix = string(s, 0, pos);
+        path = string(s, pos + 1);
+    }
+    
+    path = absPath(path);
     if (pathExists(path)) {
         debug(format("adding path `%1%' to the search path") % path);
-        searchPath.insert(searchPathInsertionPoint, path);
+        searchPath.insert(searchPathInsertionPoint, std::pair<string, Path>(prefix, path));
     }
 }
 
 
 Path EvalState::findFile(const string & path)
 {
-    foreach (Paths::iterator, i, searchPath) {
-        Path res = *i + "/" + path;
+    foreach (SearchPath::iterator, i, searchPath) {
+        Path res;
+        if (i->first.empty()) 
+            res = i->second + "/" + path;
+        else {
+            if (path.compare(0, i->first.size(), i->first) != 0 ||
+                (path.size() > i->first.size() && path[i->first.size()] != '/'))
+                continue;
+            res = i->second + "/" + string(path, i->first.size());
+        }
         if (pathExists(res)) return canonPath(res);
     }
     return "";
diff --git a/tests/lang/eval-okay-search-path.exp b/tests/lang/eval-okay-search-path.exp
index d1cc1b4e52..d0bc8c5e86 100644
--- a/tests/lang/eval-okay-search-path.exp
+++ b/tests/lang/eval-okay-search-path.exp
@@ -1 +1 @@
-"abc"
+"abcc"
diff --git a/tests/lang/eval-okay-search-path.flags b/tests/lang/eval-okay-search-path.flags
index d7feb29e12..a28e682100 100644
--- a/tests/lang/eval-okay-search-path.flags
+++ b/tests/lang/eval-okay-search-path.flags
@@ -1 +1 @@
--I lang/dir1 -I lang/dir2
\ No newline at end of file
+-I lang/dir1 -I lang/dir2 -I dir5=lang/dir3
\ No newline at end of file
diff --git a/tests/lang/eval-okay-search-path.nix b/tests/lang/eval-okay-search-path.nix
index cc1df08f01..02920149b5 100644
--- a/tests/lang/eval-okay-search-path.nix
+++ b/tests/lang/eval-okay-search-path.nix
@@ -1,3 +1,3 @@
-import <a.nix> + import <b.nix> + import <c.nix>
+import <a.nix> + import <b.nix> + import <c.nix> + import <dir5/c.nix>