about summary refs log tree commit diff
path: root/src/libexpr/eval.cc
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2010-03-30T09·22+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2010-03-30T09·22+0000
commitd78a05ab4014d75fd1e394961376f02cff20ed88 (patch)
tree69aa8ef7d829b11bd5ff9c8aa6558b23cb95143b /src/libexpr/eval.cc
parent31428c3a0675f7223470af726bc697dc7a228927 (diff)
* Make `import' work.
Diffstat (limited to 'src/libexpr/eval.cc')
-rw-r--r--src/libexpr/eval.cc138
1 files changed, 105 insertions, 33 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index 794e3966029f..86484031b1e5 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -29,6 +29,9 @@ std::ostream & operator << (std::ostream & str, Value & v)
     case tString:
         str << "\"" << v.string.s << "\""; // !!! escaping
         break;
+    case tPath:
+        str << v.path; // !!! escaping?
+        break;
     case tNull:
         str << "true";
         break;
@@ -209,6 +212,20 @@ Env & EvalState::allocEnv()
 }
 
 
+void EvalState::evalFile(const Path & path, Value & v)
+{
+    startNest(nest, lvlTalkative, format("evaluating file `%1%'") % path);
+    Expr e = parseExprFromFile(*this, path);
+    try {
+        eval(e, v);
+    } catch (Error & e) {
+        e.addPrefix(format("while evaluating the file `%1%':\n")
+            % path);
+        throw;
+    }
+}
+
+
 static char * deepestStack = (char *) -1; /* for measuring stack usage */
 
 
@@ -241,7 +258,12 @@ void EvalState::eval(Env & env, Expr e, Value & v)
     ATerm s; ATermList context;
     if (matchStr(e, s, context)) {
         assert(context == ATempty);
-        mkString(v, ATgetName(ATgetAFun(s)));
+        mkString(v, strdup(ATgetName(ATgetAFun(s))));
+        return;
+    }
+
+    if (matchPath(e, s)) {
+        mkPath(v, strdup(ATgetName(ATgetAFun(s))));
         return;
     }
 
@@ -282,8 +304,14 @@ void EvalState::eval(Env & env, Expr e, Value & v)
         eval(env, e2, v);
         forceAttrs(v); // !!! eval followed by force is slightly inefficient
         Bindings::iterator i = v.attrs->find(name);
-        if (i == v.attrs->end()) throw TypeError("attribute not found");
-        forceValue(i->second);
+        if (i == v.attrs->end())
+            throwEvalError("attribute `%1%' missing", aterm2String(name));
+        try {            
+            forceValue(i->second);
+        } catch (Error & e) {
+            addErrorPrefix(e, "while evaluating the attribute `%1%':\n", aterm2String(name));
+            throw;
+        }
         v = i->second;
         return;
     }
@@ -569,6 +597,80 @@ void EvalState::forceList(Value & v)
 }
 
 
+string EvalState::coerceToString(Value & v, PathSet & context,
+    bool coerceMore, bool copyToStore)
+{
+    forceValue(v);
+
+    string s;
+
+    if (v.type == tString) return v.string.s;
+
+    if (v.type == tPath) {
+        Path path(canonPath(v.path));
+
+        if (!copyToStore) return path;
+        
+        if (isDerivation(path))
+            throw EvalError(format("file names are not allowed to end in `%1%'")
+                % drvExtension);
+
+        Path dstPath;
+        if (srcToStore[path] != "")
+            dstPath = srcToStore[path];
+        else {
+            dstPath = readOnlyMode
+                ? computeStorePathForPath(path).first
+                : store->addToStore(path);
+            srcToStore[path] = dstPath;
+            printMsg(lvlChatty, format("copied source `%1%' -> `%2%'")
+                % path % dstPath);
+        }
+
+        context.insert(dstPath);
+        return dstPath;
+    }
+
+    if (v.type == tAttrs) {
+        Bindings::iterator i = v.attrs->find(toATerm("outPath"));
+        if (i == v.attrs->end())
+            throwTypeError("cannot coerce an attribute set (except a derivation) to a string");
+        return coerceToString(i->second, context, coerceMore, copyToStore);
+    }
+
+    if (coerceMore) {
+
+        /* Note that `false' is represented as an empty string for
+           shell scripting convenience, just like `null'. */
+        if (v.type == tBool && v.boolean) return "1";
+        if (v.type == tBool && !v.boolean) return "";
+        if (v.type == tInt) return int2String(v.integer);
+        if (v.type == tNull) return "";
+
+        if (v.type == tList) {
+            string result;
+            for (unsigned int n = 0; n < v.list.length; ++n) {
+                if (n) result += " ";
+                result += coerceToString(v.list.elems[n],
+                    context, coerceMore, copyToStore);
+            }
+            return result;
+        }
+    }
+    
+    throwTypeError("cannot coerce %1% to a string", showType(v));
+}
+
+
+Path EvalState::coerceToPath(Value & v, PathSet & context)
+{
+    string path = coerceToString(v, context, false, false);
+    if (path == "" || path[0] != '/')
+        throw EvalError(format("string `%1%' doesn't represent an absolute path") % path);
+    return path;
+}
+
+
 bool EvalState::eqValues(Value & v1, Value & v2)
 {
     forceValue(v1);
@@ -1046,22 +1148,6 @@ LocalNoInline(Expr evalCall(EvalState & state, Expr fun, Expr arg))
 }
 
 
-LocalNoInline(Expr evalSelect(EvalState & state, Expr e, ATerm name))
-{
-    ATerm pos;
-    string s = aterm2String(name);
-    Expr a = queryAttr(evalExpr(state, e), s, pos);
-    if (!a) throwEvalError("attribute `%1%' missing", s);
-    try {
-        return evalExpr(state, a);
-    } catch (Error & e) {
-        addErrorPrefix(e, "while evaluating the attribute `%1%' at %2%:\n",
-            s, showPos(pos));
-        throw;
-    }
-}
-
-
 LocalNoInline(Expr evalAssert(EvalState & state, Expr cond, Expr body, ATerm pos))
 {
     if (!evalBool(state, cond))
@@ -1352,20 +1438,6 @@ Expr evalExpr(EvalState & state, Expr e)
 }
 
 
-Expr evalFile(EvalState & state, const Path & path)
-{
-    startNest(nest, lvlTalkative, format("evaluating file `%1%'") % path);
-    Expr e = parseExprFromFile(state, path);
-    try {
-        return evalExpr(state, e);
-    } catch (Error & e) {
-        e.addPrefix(format("while evaluating the file `%1%':\n")
-            % path);
-        throw;
-    }
-}
-
-
 static Expr strictEvalExpr(EvalState & state, Expr e, ATermMap & nfs);