about summary refs log tree commit diff
path: root/src/libexpr/primops.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/libexpr/primops.cc')
-rw-r--r--src/libexpr/primops.cc56
1 files changed, 30 insertions, 26 deletions
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index 615cc8138433..99ffddaeb80c 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -127,7 +127,7 @@ static void prim_scopedImport(EvalState & state, const Pos & pos, Value * * args
                 env->values[displ++] = attr.value;
             }
 
-            Activity act(*logger, lvlTalkative, format("evaluating file ‘%1%’") % path);
+            printTalkative("evaluating file ‘%1%’", path);
             Expr * e = state.parseExprFromFile(resolveExprPath(path), staticEnv);
 
             e->eval(state, *env, v);
@@ -326,8 +326,6 @@ typedef list<Value *> ValueList;
 
 static void prim_genericClosure(EvalState & state, const Pos & pos, Value * * args, Value & v)
 {
-    Activity act(*logger, lvlDebug, "finding dependencies");
-
     state.forceAttrs(*args[0], pos);
 
     /* Get the start set. */
@@ -499,8 +497,6 @@ void prim_valueSize(EvalState & state, const Pos & pos, Value * * args, Value &
    derivation. */
 static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * * args, Value & v)
 {
-    Activity act(*logger, lvlVomit, "evaluating derivation");
-
     state.forceAttrs(*args[0], pos);
 
     /* Figure out the name first (for stack backtraces). */
@@ -534,7 +530,8 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
 
     PathSet context;
 
-    string outputHash, outputHashAlgo;
+    std::experimental::optional<std::string> outputHash;
+    std::string outputHashAlgo;
     bool outputHashRecursive = false;
 
     StringSet outputs;
@@ -543,7 +540,7 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
     for (auto & i : args[0]->attrs->lexicographicOrder()) {
         if (i->name == state.sIgnoreNulls) continue;
         string key = i->name;
-        Activity act(*logger, lvlVomit, format("processing attribute ‘%1%’") % key);
+        vomit("processing attribute ‘%1%’", key);
 
         auto handleHashMode = [&](const std::string & s) {
             if (s == "recursive") outputHashRecursive = true;
@@ -703,7 +700,7 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
         throw EvalError(format("derivation names are not allowed to end in ‘%1%’, at %2%")
             % drvExtension % posDrvName);
 
-    if (outputHash != "") {
+    if (outputHash) {
         /* Handle fixed-output derivations. */
         if (outputs.size() != 1 || *(outputs.begin()) != "out")
             throw Error(format("multiple outputs are not supported in fixed-output derivations, at %1%") % posDrvName);
@@ -711,13 +708,13 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
         HashType ht = parseHashType(outputHashAlgo);
         if (ht == htUnknown)
             throw EvalError(format("unknown hash algorithm ‘%1%’, at %2%") % outputHashAlgo % posDrvName);
-        Hash h = parseHash16or32(ht, outputHash);
+        Hash h = parseHash16or32(ht, *outputHash);
         outputHash = printHash(h);
         if (outputHashRecursive) outputHashAlgo = "r:" + outputHashAlgo;
 
         Path outPath = state.store->makeFixedOutputPath(outputHashRecursive, h, drvName);
         drv.env["out"] = outPath;
-        drv.outputs["out"] = DerivationOutput(outPath, outputHashAlgo, outputHash);
+        drv.outputs["out"] = DerivationOutput(outPath, outputHashAlgo, *outputHash);
     }
 
     else {
@@ -1712,26 +1709,33 @@ static void prim_hashString(EvalState & state, const Pos & pos, Value * * args,
    ‘null’ or a list containing substring matches. */
 static void prim_match(EvalState & state, const Pos & pos, Value * * args, Value & v)
 {
-    std::regex regex(state.forceStringNoCtx(*args[0], pos), std::regex::extended);
+    auto re = state.forceStringNoCtx(*args[0], pos);
 
-    PathSet context;
-    const std::string str = state.forceString(*args[1], context, pos);
+    try {
 
+        std::regex regex(re, std::regex::extended);
 
-    std::smatch match;
-    if (!std::regex_match(str, match, regex)) {
-        mkNull(v);
-        return;
-    }
+        PathSet context;
+        const std::string str = state.forceString(*args[1], context, pos);
 
-    // the first match is the whole string
-    const size_t len = match.size() - 1;
-    state.mkList(v, len);
-    for (size_t i = 0; i < len; ++i) {
-        if (!match[i+1].matched)
-            mkNull(*(v.listElems()[i] = state.allocValue()));
-        else
-            mkString(*(v.listElems()[i] = state.allocValue()), match[i + 1].str().c_str());
+        std::smatch match;
+        if (!std::regex_match(str, match, regex)) {
+            mkNull(v);
+            return;
+        }
+
+        // the first match is the whole string
+        const size_t len = match.size() - 1;
+        state.mkList(v, len);
+        for (size_t i = 0; i < len; ++i) {
+            if (!match[i+1].matched)
+                mkNull(*(v.listElems()[i] = state.allocValue()));
+            else
+                mkString(*(v.listElems()[i] = state.allocValue()), match[i + 1].str().c_str());
+        }
+
+    } catch (std::regex_error &) {
+        throw EvalError("invalid regular expression ‘%s’, at %s", re, pos);
     }
 }