builtins.match: Improve error message for bad regular expression

Issue #1331.
This commit is contained in:
Eelco Dolstra 2017-05-17 11:58:01 +02:00
parent b01d62285c
commit e46090edb1
No known key found for this signature in database
GPG key ID: 8170B4726D7198DE

View file

@ -1709,26 +1709,33 @@ static void prim_hashString(EvalState & state, const Pos & pos, Value * * args,
null or a list containing substring matches. */ null or a list containing substring matches. */
static void prim_match(EvalState & state, const Pos & pos, Value * * args, Value & v) 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; try {
const std::string str = state.forceString(*args[1], context, pos);
std::regex regex(re, std::regex::extended);
std::smatch match; PathSet context;
if (!std::regex_match(str, match, regex)) { const std::string str = state.forceString(*args[1], context, pos);
mkNull(v);
return;
}
// the first match is the whole string std::smatch match;
const size_t len = match.size() - 1; if (!std::regex_match(str, match, regex)) {
state.mkList(v, len); mkNull(v);
for (size_t i = 0; i < len; ++i) { return;
if (!match[i+1].matched) }
mkNull(*(v.listElems()[i] = state.allocValue()));
else // the first match is the whole string
mkString(*(v.listElems()[i] = state.allocValue()), match[i + 1].str().c_str()); 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);
} }
} }