about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2010-03-31T19·52+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2010-03-31T19·52+0000
commit979f163615745db74f3a94a71818e66c75baf9ac (patch)
tree6351f54bc055ce988ab3d916d0cd162895518cf4 /src
parentd8cd3115d8e1acc9e866c67265668d5268f2c1ec (diff)
* Handle string contexts. `nix-instantiate' can now correctly compute
  the `firefoxWrapper' attribute in Nixpkgs, and it's about 3 times
  faster than the trunk :-)

Diffstat (limited to 'src')
-rw-r--r--src/libexpr/eval.cc88
-rw-r--r--src/libexpr/eval.hh1
-rw-r--r--src/libexpr/primops.cc4
3 files changed, 28 insertions, 65 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index b4156ffec101..6e504f879edc 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -178,7 +178,13 @@ void mkString(Value & v, const char * s)
 void mkString(Value & v, const string & s, const PathSet & context)
 {
     mkString(v, s.c_str());
-    // !!! context
+    if (!context.empty()) {
+        unsigned int len = 0, n = 0;
+        v.string.context = new const char *[context.size() + 1];
+        foreach (PathSet::const_iterator, i, context) 
+            v.string.context[n++] = strdup(i->c_str());
+        v.string.context[n] = 0;
+    }
 }
 
 
@@ -471,7 +477,7 @@ void EvalState::eval(Env & env, Expr e, Value & v)
         if (isPath)
             mkPath(v, s.str().c_str());
         else
-            mkString(v, s.str().c_str()); // !!! context
+            mkString(v, s.str(), context);
     }
 
     /* Conditionals. */
@@ -727,6 +733,17 @@ string EvalState::forceString(Value & v)
 }
 
 
+string EvalState::forceString(Value & v, PathSet & context)
+{
+    string s = forceString(v);
+    if (v.string.context) {
+        for (const char * * p = v.string.context; *p; ++p) 
+            context.insert(*p);
+    }
+    return s;
+}
+
+
 string EvalState::forceStringNoCtx(Value & v)
 {
     string s = forceString(v);
@@ -744,7 +761,12 @@ string EvalState::coerceToString(Value & v, PathSet & context,
 
     string s;
 
-    if (v.type == tString) return v.string.s;
+    if (v.type == tString) {
+        if (v.string.context) 
+            for (const char * * p = v.string.context; *p; ++p) 
+                context.insert(*p);
+        return v.string.s;
+    }
 
     if (v.type == tPath) {
         Path path(canonPath(v.path));
@@ -1142,66 +1164,6 @@ LocalNoInline(Expr evalWith(EvalState & state, Expr defs, Expr body, ATerm pos))
 }
 
 
-LocalNoInline(Expr evalPlusConcat(EvalState & state, Expr e))
-{
-    Expr e1, e2;
-    ATermList es;
-    
-    ATermVector args;
-    
-    if (matchOpPlus(e, e1, e2)) {
-
-        /* !!! Awful compatibility hack for `drv + /path'.
-           According to regular concatenation, /path should be
-           copied to the store and its store path should be
-           appended to the string.  However, in Nix <= 0.10, /path
-           was concatenated.  So handle that case separately, but
-           do print out a warning.  This code can go in Nix 0.12,
-           maybe. */
-        e1 = evalExpr(state, e1);
-        e2 = evalExpr(state, e2);
-
-        ATermList as;
-        ATerm p;
-        if (matchAttrs(e1, as) && matchPath(e2, p)) {
-            static bool haveWarned = false;
-            warnOnce(haveWarned, format(
-                    "concatenation of a derivation and a path is deprecated; "
-                    "you should write `drv + \"%1%\"' instead of `drv + %1%'")
-                % aterm2String(p));
-            PathSet context;
-            return makeStr(
-                coerceToString(state, makeSelect(e1, toATerm("outPath")), context)
-                + aterm2String(p), context);
-        }
-
-        args.push_back(e1);
-        args.push_back(e2);
-    }
-
-    else if (matchConcatStrings(e, es))
-        for (ATermIterator i(es); i; ++i) args.push_back(*i);
-        
-    try {
-        return concatStrings(state, args);
-    } catch (Error & e) {
-        addErrorPrefix(e, "in a string concatenation:\n");
-        throw;
-    }
-}
-
-
-LocalNoInline(Expr evalSubPath(EvalState & state, Expr e1, Expr e2))
-{
-    static bool haveWarned = false;
-    warnOnce(haveWarned, "the subpath operator (~) is deprecated, use string concatenation (+) instead");
-    ATermVector args;
-    args.push_back(e1);
-    args.push_back(e2);
-    return concatStrings(state, args, "/");
-}
-
-
 /* Implementation of the `==' and `!=' operators. */
 LocalNoInline(bool areEqual(EvalState & state, Expr e1, Expr e2))
 {
diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh
index 7369892fbccd..13ea269fc69d 100644
--- a/src/libexpr/eval.hh
+++ b/src/libexpr/eval.hh
@@ -172,6 +172,7 @@ public:
     void forceList(Value & v);
     void forceFunction(Value & v); // either lambda or primop
     string forceString(Value & v);
+    string forceString(Value & v, PathSet & context);
     string forceStringNoCtx(Value & v);
 
     /* String coercion.  Converts strings, paths and derivations to a
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index 31914a65dd18..e16cd2419c9f 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -588,7 +588,7 @@ static void prim_toFile(EvalState & state, Value * * args, Value & v)
 {
     PathSet context;
     string name = state.forceStringNoCtx(*args[0]);
-    string contents = state.forceString(*args[1]); // !!! context
+    string contents = state.forceString(*args[1], context);
 
     PathSet refs;
 
@@ -928,7 +928,7 @@ static void prim_toString(EvalState & state, Value * * args, Value & v)
 {
     PathSet context;
     string s = state.coerceToString(*args[0], context, true, false);
-    mkString(v, s.c_str()); // !!! context
+    mkString(v, s, context);
 }