about summary refs log tree commit diff
path: root/src/libexpr/primops.cc
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2017-05-17T09·58+0200
committerEelco Dolstra <edolstra@gmail.com>2017-05-17T09·58+0200
commite46090edb101acac20ab1e6260a0ba98c177206a (patch)
treec327e2c08b594b55cb950f9e1f9e37fbce1f38fd /src/libexpr/primops.cc
parentb01d62285cdcd376a8db1863049c68d8c7238837 (diff)
builtins.match: Improve error message for bad regular expression
Issue #1331.
Diffstat (limited to 'src/libexpr/primops.cc')
-rw-r--r--src/libexpr/primops.cc39
1 files changed, 23 insertions, 16 deletions
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index 93b66269dd..99ffddaeb8 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -1709,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);
     }
 }