style(3p/nix): Final act in the brace-wrapping saga
This last change set was generated by a full clang-tidy run (including
compilation):
clang-tidy -p ~/projects/nix-build/ \
-checks=-*,readability-braces-around-statements -fix src/*/*.cc
Actually running clang-tidy requires some massaging to make it play
nice with Nix + meson, I'll be adding a wrapper or something for that soon.
This commit is contained in:
parent
cf40d08908
commit
3908732181
84 changed files with 2601 additions and 1554 deletions
21
third_party/nix/src/libexpr/attr-path.cc
vendored
21
third_party/nix/src/libexpr/attr-path.cc
vendored
|
|
@ -16,16 +16,18 @@ static Strings parseAttrPath(const string& s) {
|
|||
} else if (*i == '"') {
|
||||
++i;
|
||||
while (1) {
|
||||
if (i == s.end())
|
||||
if (i == s.end()) {
|
||||
throw Error(format("missing closing quote in selection path '%1%'") %
|
||||
s);
|
||||
}
|
||||
if (*i == '"') {
|
||||
break;
|
||||
}
|
||||
cur.push_back(*i++);
|
||||
}
|
||||
} else
|
||||
} else {
|
||||
cur.push_back(*i);
|
||||
}
|
||||
++i;
|
||||
}
|
||||
if (!cur.empty()) {
|
||||
|
|
@ -62,33 +64,38 @@ Value* findAlongAttrPath(EvalState& state, const string& attrPath,
|
|||
according to what is specified in the attrPath. */
|
||||
|
||||
if (apType == apAttr) {
|
||||
if (v->type != tAttrs)
|
||||
if (v->type != tAttrs) {
|
||||
throw TypeError(format("the expression selected by the selection path "
|
||||
"'%1%' should be a set but is %2%") %
|
||||
attrPath % showType(*v));
|
||||
}
|
||||
|
||||
if (attr.empty())
|
||||
if (attr.empty()) {
|
||||
throw Error(format("empty attribute name in selection path '%1%'") %
|
||||
attrPath);
|
||||
}
|
||||
|
||||
Bindings::iterator a = v->attrs->find(state.symbols.create(attr));
|
||||
if (a == v->attrs->end())
|
||||
if (a == v->attrs->end()) {
|
||||
throw Error(
|
||||
format("attribute '%1%' in selection path '%2%' not found") % attr %
|
||||
attrPath);
|
||||
}
|
||||
v = &*a->value;
|
||||
}
|
||||
|
||||
else if (apType == apIndex) {
|
||||
if (!v->isList())
|
||||
if (!v->isList()) {
|
||||
throw TypeError(format("the expression selected by the selection path "
|
||||
"'%1%' should be a list but is %2%") %
|
||||
attrPath % showType(*v));
|
||||
}
|
||||
|
||||
if (attrIndex >= v->listSize())
|
||||
if (attrIndex >= v->listSize()) {
|
||||
throw Error(
|
||||
format("list index %1% in selection path '%2%' is out of range") %
|
||||
attrIndex % attrPath);
|
||||
}
|
||||
|
||||
v = v->listElems()[attrIndex];
|
||||
}
|
||||
|
|
|
|||
3
third_party/nix/src/libexpr/attr-set.cc
vendored
3
third_party/nix/src/libexpr/attr-set.cc
vendored
|
|
@ -10,8 +10,9 @@ namespace nix {
|
|||
capacity. The space is implicitly reserved after the Bindings
|
||||
structure. */
|
||||
Bindings* EvalState::allocBindings(size_t capacity) {
|
||||
if (capacity > std::numeric_limits<Bindings::size_t>::max())
|
||||
if (capacity > std::numeric_limits<Bindings::size_t>::max()) {
|
||||
throw Error("attribute set of size %d is too big", capacity);
|
||||
}
|
||||
return new (allocBytes(sizeof(Bindings) + sizeof(Attr) * capacity))
|
||||
Bindings((Bindings::size_t)capacity);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,11 +36,12 @@ Bindings* MixEvalArgs::getAutoArgs(EvalState& state) {
|
|||
Bindings* res = state.allocBindings(autoArgs.size());
|
||||
for (auto& i : autoArgs) {
|
||||
Value* v = state.allocValue();
|
||||
if (i.second[0] == 'E')
|
||||
if (i.second[0] == 'E') {
|
||||
state.mkThunk_(
|
||||
*v, state.parseExprFromString(string(i.second, 1), absPath(".")));
|
||||
else
|
||||
} else {
|
||||
mkString(*v, string(i.second, 1));
|
||||
}
|
||||
res->push_back(Attr(state.symbols.create(i.first), v));
|
||||
}
|
||||
res->sort();
|
||||
|
|
@ -55,8 +56,9 @@ Path lookupFileArg(EvalState& state, string s) {
|
|||
} else if (s.size() > 2 && s.at(0) == '<' && s.at(s.size() - 1) == '>') {
|
||||
Path p = s.substr(1, s.size() - 2);
|
||||
return state.findFile(p);
|
||||
} else
|
||||
} else {
|
||||
return absPath(s);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace nix
|
||||
|
|
|
|||
155
third_party/nix/src/libexpr/eval.cc
vendored
155
third_party/nix/src/libexpr/eval.cc
vendored
|
|
@ -62,17 +62,19 @@ static void printValue(std::ostream& str, std::set<const Value*>& active,
|
|||
break;
|
||||
case tString:
|
||||
str << "\"";
|
||||
for (const char* i = v.string.s; *i; i++)
|
||||
if (*i == '\"' || *i == '\\')
|
||||
for (const char* i = v.string.s; *i; i++) {
|
||||
if (*i == '\"' || *i == '\\') {
|
||||
str << "\\" << *i;
|
||||
else if (*i == '\n')
|
||||
} else if (*i == '\n') {
|
||||
str << "\\n";
|
||||
else if (*i == '\r')
|
||||
} else if (*i == '\r') {
|
||||
str << "\\r";
|
||||
else if (*i == '\t')
|
||||
} else if (*i == '\t') {
|
||||
str << "\\t";
|
||||
else
|
||||
} else {
|
||||
str << *i;
|
||||
}
|
||||
}
|
||||
str << "\"";
|
||||
break;
|
||||
case tPath:
|
||||
|
|
@ -281,7 +283,9 @@ static Strings parseNixPath(const string& s) {
|
|||
if (*p == ':') {
|
||||
if (isUri(std::string(start2, s.end()))) {
|
||||
++p;
|
||||
while (p != s.end() && *p != ':') ++p;
|
||||
while (p != s.end() && *p != ':') {
|
||||
++p;
|
||||
}
|
||||
}
|
||||
res.push_back(std::string(start, p));
|
||||
if (p == s.end()) {
|
||||
|
|
@ -361,8 +365,9 @@ EvalState::EvalState(const Strings& _searchPath, ref<Store> store)
|
|||
for (auto& path : closure) {
|
||||
allowedPaths->insert(path);
|
||||
}
|
||||
} else
|
||||
} else {
|
||||
allowedPaths->insert(r.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -400,9 +405,10 @@ Path EvalState::checkSourcePath(const Path& path_) {
|
|||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
if (!found) {
|
||||
throw RestrictedPathError(
|
||||
"access to path '%1%' is forbidden in restricted mode", abspath);
|
||||
}
|
||||
|
||||
/* Resolve symlinks. */
|
||||
DLOG(INFO) << "checking access to '" << abspath << "'";
|
||||
|
|
@ -428,12 +434,14 @@ void EvalState::checkURI(const std::string& uri) {
|
|||
prefix. Thus, the prefix https://github.co does not permit
|
||||
access to https://github.com. Note: this allows 'http://' and
|
||||
'https://' as prefixes for any http/https URI. */
|
||||
for (auto& prefix : evalSettings.allowedUris.get())
|
||||
for (auto& prefix : evalSettings.allowedUris.get()) {
|
||||
if (uri == prefix ||
|
||||
(uri.size() > prefix.size() && prefix.size() > 0 &&
|
||||
hasPrefix(uri, prefix) &&
|
||||
(prefix[prefix.size() - 1] == '/' || uri[prefix.size()] == '/')))
|
||||
(prefix[prefix.size() - 1] == '/' || uri[prefix.size()] == '/'))) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the URI is a path, then check it against allowedPaths as
|
||||
well. */
|
||||
|
|
@ -600,9 +608,10 @@ inline Value* EvalState::lookupVar(Env* env, const ExprVar& var, bool noEval) {
|
|||
}
|
||||
return j->value;
|
||||
}
|
||||
if (!env->prevWith)
|
||||
if (!env->prevWith) {
|
||||
throwUndefinedVarError("undefined variable '%1%' at %2%", var.name,
|
||||
var.pos);
|
||||
}
|
||||
for (size_t l = env->prevWith; l; --l, env = env->up) {
|
||||
;
|
||||
}
|
||||
|
|
@ -622,8 +631,9 @@ Value* EvalState::allocValue() {
|
|||
}
|
||||
|
||||
Env& EvalState::allocEnv(size_t size) {
|
||||
if (size > std::numeric_limits<decltype(Env::size)>::max())
|
||||
if (size > std::numeric_limits<decltype(Env::size)>::max()) {
|
||||
throw Error("environment size %d is too big", size);
|
||||
}
|
||||
|
||||
nrEnvs++;
|
||||
nrValuesInEnvs += size;
|
||||
|
|
@ -669,8 +679,9 @@ void EvalState::mkPos(Value& v, Pos* pos) {
|
|||
mkInt(*allocAttr(v, sLine), pos->line);
|
||||
mkInt(*allocAttr(v, sColumn), pos->column);
|
||||
v.attrs->sort();
|
||||
} else
|
||||
} else {
|
||||
mkNull(v);
|
||||
}
|
||||
}
|
||||
|
||||
/* Create a thunk for the delayed computation of the given expression
|
||||
|
|
@ -823,8 +834,9 @@ void ExprAttrs::eval(EvalState& state, Env& env, Value& v) {
|
|||
if (hasOverrides && !i.second.inherited) {
|
||||
vAttr = state.allocValue();
|
||||
mkThunk(*vAttr, env2, i.second.e);
|
||||
} else
|
||||
} else {
|
||||
vAttr = i.second.e->maybeThunk(state, i.second.inherited ? env : env2);
|
||||
}
|
||||
env2.values[displ++] = vAttr;
|
||||
v.attrs->push_back(Attr(i.first, vAttr, &i.second.pos));
|
||||
}
|
||||
|
|
@ -850,16 +862,18 @@ void ExprAttrs::eval(EvalState& state, Env& env, Value& v) {
|
|||
if (j != attrs.end()) {
|
||||
(*newBnds)[j->second.displ] = i;
|
||||
env2.values[j->second.displ] = i.value;
|
||||
} else
|
||||
} else {
|
||||
newBnds->push_back(i);
|
||||
}
|
||||
}
|
||||
newBnds->sort();
|
||||
v.attrs = newBnds;
|
||||
}
|
||||
} else {
|
||||
for (auto& i : attrs)
|
||||
for (auto& i : attrs) {
|
||||
v.attrs->push_back(
|
||||
Attr(i.first, i.second.e->maybeThunk(state, env), &i.second.pos));
|
||||
}
|
||||
}
|
||||
|
||||
/* Dynamic attrs apply *after* rec and __overrides. */
|
||||
|
|
@ -873,9 +887,10 @@ void ExprAttrs::eval(EvalState& state, Env& env, Value& v) {
|
|||
state.forceStringNoCtx(nameVal);
|
||||
Symbol nameSym = state.symbols.create(nameVal.string.s);
|
||||
Bindings::iterator j = v.attrs->find(nameSym);
|
||||
if (j != v.attrs->end())
|
||||
if (j != v.attrs->end()) {
|
||||
throwEvalError("dynamic attribute '%1%' at %2% already defined at %3%",
|
||||
nameSym, i.pos, *j->pos);
|
||||
}
|
||||
|
||||
i.valueExpr->setName(nameSym);
|
||||
/* Keep sorted order so find can catch duplicates */
|
||||
|
|
@ -895,17 +910,19 @@ void ExprLet::eval(EvalState& state, Env& env, Value& v) {
|
|||
while the inherited attributes are evaluated in the original
|
||||
environment. */
|
||||
size_t displ = 0;
|
||||
for (auto& i : attrs->attrs)
|
||||
for (auto& i : attrs->attrs) {
|
||||
env2.values[displ++] =
|
||||
i.second.e->maybeThunk(state, i.second.inherited ? env : env2);
|
||||
}
|
||||
|
||||
body->eval(state, env2, v);
|
||||
}
|
||||
|
||||
void ExprList::eval(EvalState& state, Env& env, Value& v) {
|
||||
state.mkList(v, elems.size());
|
||||
for (size_t n = 0; n < elems.size(); ++n)
|
||||
for (size_t n = 0; n < elems.size(); ++n) {
|
||||
v.listElems()[n] = elems[n]->maybeThunk(state, env);
|
||||
}
|
||||
}
|
||||
|
||||
void ExprVar::eval(EvalState& state, Env& env, Value& v) {
|
||||
|
|
@ -919,10 +936,11 @@ static string showAttrPath(EvalState& state, Env& env,
|
|||
std::ostringstream out;
|
||||
bool first = true;
|
||||
for (auto& i : attrPath) {
|
||||
if (!first)
|
||||
if (!first) {
|
||||
out << '.';
|
||||
else
|
||||
} else {
|
||||
first = false;
|
||||
}
|
||||
try {
|
||||
out << getName(i, state, env);
|
||||
} catch (Error& e) {
|
||||
|
|
@ -956,8 +974,9 @@ void ExprSelect::eval(EvalState& state, Env& env, Value& v) {
|
|||
}
|
||||
} else {
|
||||
state.forceAttrs(*vAttrs, pos);
|
||||
if ((j = vAttrs->attrs->find(name)) == vAttrs->attrs->end())
|
||||
if ((j = vAttrs->attrs->find(name)) == vAttrs->attrs->end()) {
|
||||
throwEvalError("attribute '%1%' missing, at %2%", name, pos);
|
||||
}
|
||||
}
|
||||
vAttrs = j->value;
|
||||
pos2 = j->pos;
|
||||
|
|
@ -969,9 +988,10 @@ void ExprSelect::eval(EvalState& state, Env& env, Value& v) {
|
|||
state.forceValue(*vAttrs, (pos2 != NULL ? *pos2 : this->pos));
|
||||
|
||||
} catch (Error& e) {
|
||||
if (pos2 && pos2->file != state.sDerivationNix)
|
||||
if (pos2 && pos2->file != state.sDerivationNix) {
|
||||
addErrorPrefix(e, "while evaluating the attribute '%1%' at %2%:\n",
|
||||
showAttrPath(state, env, attrPath), *pos2);
|
||||
}
|
||||
throw;
|
||||
}
|
||||
|
||||
|
|
@ -1112,9 +1132,10 @@ void EvalState::callFunction(Value& fun, Value& arg, Value& v, const Pos& pos) {
|
|||
for (auto& i : lambda.formals->formals) {
|
||||
Bindings::iterator j = arg.attrs->find(i.name);
|
||||
if (j == arg.attrs->end()) {
|
||||
if (!i.def)
|
||||
if (!i.def) {
|
||||
throwTypeError("%1% called without required argument '%2%', at %3%",
|
||||
lambda, i.name, pos);
|
||||
}
|
||||
env2.values[displ++] = i.def->maybeThunk(*this, env2);
|
||||
} else {
|
||||
attrsUsed++;
|
||||
|
|
@ -1127,11 +1148,13 @@ void EvalState::callFunction(Value& fun, Value& arg, Value& v, const Pos& pos) {
|
|||
if (!lambda.formals->ellipsis && attrsUsed != arg.attrs->size()) {
|
||||
/* Nope, so show the first unexpected argument to the
|
||||
user. */
|
||||
for (auto& i : *arg.attrs)
|
||||
for (auto& i : *arg.attrs) {
|
||||
if (lambda.formals->argNames.find(i.name) ==
|
||||
lambda.formals->argNames.end())
|
||||
lambda.formals->argNames.end()) {
|
||||
throwTypeError("%1% called with unexpected argument '%2%', at %3%",
|
||||
lambda, i.name, pos);
|
||||
}
|
||||
}
|
||||
abort(); // can't happen
|
||||
}
|
||||
}
|
||||
|
|
@ -1143,15 +1166,17 @@ void EvalState::callFunction(Value& fun, Value& arg, Value& v, const Pos& pos) {
|
|||
|
||||
/* Evaluate the body. This is conditional on showTrace, because
|
||||
catching exceptions makes this function not tail-recursive. */
|
||||
if (settings.showTrace) try {
|
||||
if (settings.showTrace) {
|
||||
try {
|
||||
lambda.body->eval(*this, env2, v);
|
||||
} catch (Error& e) {
|
||||
addErrorPrefix(e, "while evaluating %1%, called from %2%:\n", lambda,
|
||||
pos);
|
||||
throw;
|
||||
}
|
||||
else
|
||||
} else {
|
||||
fun.lambda.fun->body->eval(*this, env2, v);
|
||||
}
|
||||
}
|
||||
|
||||
// Lifted out of callFunction() because it creates a temporary that
|
||||
|
|
@ -1181,13 +1206,14 @@ void EvalState::autoCallFunction(Bindings& args, Value& fun, Value& res) {
|
|||
|
||||
for (auto& i : fun.lambda.fun->formals->formals) {
|
||||
Bindings::iterator j = args.find(i.name);
|
||||
if (j != args.end())
|
||||
if (j != args.end()) {
|
||||
actualArgs->attrs->push_back(*j);
|
||||
else if (!i.def)
|
||||
} else if (!i.def) {
|
||||
throwTypeError(
|
||||
"cannot auto-call a function that has an argument without a default "
|
||||
"value ('%1%')",
|
||||
i.name);
|
||||
}
|
||||
}
|
||||
|
||||
actualArgs->attrs->sort();
|
||||
|
|
@ -1278,10 +1304,11 @@ void ExprOpUpdate::eval(EvalState& state, Env& env, Value& v) {
|
|||
v.attrs->push_back(*j);
|
||||
++i;
|
||||
++j;
|
||||
} else if (i->name < j->name)
|
||||
} else if (i->name < j->name) {
|
||||
v.attrs->push_back(*i++);
|
||||
else
|
||||
} else {
|
||||
v.attrs->push_back(*j++);
|
||||
}
|
||||
}
|
||||
|
||||
while (i != v1.attrs->end()) {
|
||||
|
|
@ -1364,20 +1391,23 @@ void ExprConcatStrings::eval(EvalState& state, Env& env, Value& v) {
|
|||
firstType = tFloat;
|
||||
nf = n;
|
||||
nf += vTmp.fpoint;
|
||||
} else
|
||||
} else {
|
||||
throwEvalError("cannot add %1% to an integer, at %2%", showType(vTmp),
|
||||
pos);
|
||||
}
|
||||
} else if (firstType == tFloat) {
|
||||
if (vTmp.type == tInt) {
|
||||
nf += vTmp.integer;
|
||||
} else if (vTmp.type == tFloat) {
|
||||
nf += vTmp.fpoint;
|
||||
} else
|
||||
} else {
|
||||
throwEvalError("cannot add %1% to a float, at %2%", showType(vTmp),
|
||||
pos);
|
||||
} else
|
||||
}
|
||||
} else {
|
||||
s << state.coerceToString(pos, vTmp, context, false,
|
||||
firstType == tString);
|
||||
}
|
||||
}
|
||||
|
||||
if (firstType == tInt) {
|
||||
|
|
@ -1385,11 +1415,12 @@ void ExprConcatStrings::eval(EvalState& state, Env& env, Value& v) {
|
|||
} else if (firstType == tFloat) {
|
||||
mkFloat(v, nf);
|
||||
} else if (firstType == tPath) {
|
||||
if (!context.empty())
|
||||
if (!context.empty()) {
|
||||
throwEvalError(
|
||||
"a string that refers to a store path cannot be appended to a path, "
|
||||
"at %1%",
|
||||
pos);
|
||||
}
|
||||
auto path = canonPath(s.str());
|
||||
mkPath(v, path.c_str());
|
||||
} else {
|
||||
|
|
@ -1415,13 +1446,15 @@ void EvalState::forceValueDeep(Value& v) {
|
|||
forceValue(v);
|
||||
|
||||
if (v.type == tAttrs) {
|
||||
for (auto& i : *v.attrs) try {
|
||||
for (auto& i : *v.attrs) {
|
||||
try {
|
||||
recurse(*i.value);
|
||||
} catch (Error& e) {
|
||||
addErrorPrefix(e, "while evaluating the attribute '%1%' at %2%:\n",
|
||||
i.name, *i.pos);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
} else if (v.isList()) {
|
||||
for (size_t n = 0; n < v.listSize(); ++n) {
|
||||
recurse(*v.listElems()[n]);
|
||||
|
|
@ -1486,10 +1519,11 @@ string EvalState::forceString(Value& v, const Pos& pos) {
|
|||
}
|
||||
|
||||
void copyContext(const Value& v, PathSet& context) {
|
||||
if (v.string.context)
|
||||
if (v.string.context) {
|
||||
for (const char** p = v.string.context; *p; ++p) {
|
||||
context.insert(*p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string EvalState::forceString(Value& v, PathSet& context, const Pos& pos) {
|
||||
|
|
@ -1501,16 +1535,17 @@ string EvalState::forceString(Value& v, PathSet& context, const Pos& pos) {
|
|||
string EvalState::forceStringNoCtx(Value& v, const Pos& pos) {
|
||||
string s = forceString(v, pos);
|
||||
if (v.string.context) {
|
||||
if (pos)
|
||||
if (pos) {
|
||||
throwEvalError(
|
||||
"the string '%1%' is not allowed to refer to a store path (such as "
|
||||
"'%2%'), at %3%",
|
||||
v.string.s, v.string.context[0], pos);
|
||||
else
|
||||
} else {
|
||||
throwEvalError(
|
||||
"the string '%1%' is not allowed to refer to a store path (such as "
|
||||
"'%2%')",
|
||||
v.string.s, v.string.context[0]);
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
|
@ -1567,13 +1602,15 @@ string EvalState::coerceToString(const Pos& pos, Value& v, PathSet& context,
|
|||
return *maybeString;
|
||||
}
|
||||
auto i = v.attrs->find(sOutPath);
|
||||
if (i == v.attrs->end())
|
||||
if (i == v.attrs->end()) {
|
||||
throwTypeError("cannot coerce a set to a string, at %1%", pos);
|
||||
}
|
||||
return coerceToString(pos, *i->value, context, coerceMore, copyToStore);
|
||||
}
|
||||
|
||||
if (v.type == tExternal)
|
||||
if (v.type == tExternal) {
|
||||
return v.external->coerceToString(pos, context, coerceMore, copyToStore);
|
||||
}
|
||||
|
||||
if (coerceMore) {
|
||||
/* Note that `false' is represented as an empty string for
|
||||
|
|
@ -1601,9 +1638,10 @@ string EvalState::coerceToString(const Pos& pos, Value& v, PathSet& context,
|
|||
copyToStore);
|
||||
if (n < v.listSize() - 1
|
||||
/* !!! not quite correct */
|
||||
&&
|
||||
(!v.listElems()[n]->isList() || v.listElems()[n]->listSize() != 0))
|
||||
&& (!v.listElems()[n]->isList() ||
|
||||
v.listElems()[n]->listSize() != 0)) {
|
||||
result += " ";
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
@ -1613,13 +1651,14 @@ string EvalState::coerceToString(const Pos& pos, Value& v, PathSet& context,
|
|||
}
|
||||
|
||||
string EvalState::copyPathToStore(PathSet& context, const Path& path) {
|
||||
if (nix::isDerivation(path))
|
||||
if (nix::isDerivation(path)) {
|
||||
throwEvalError("file names are not allowed to end in '%1%'", drvExtension);
|
||||
}
|
||||
|
||||
Path dstPath;
|
||||
if (srcToStore[path] != "")
|
||||
if (srcToStore[path] != "") {
|
||||
dstPath = srcToStore[path];
|
||||
else {
|
||||
} else {
|
||||
dstPath =
|
||||
settings.readOnlyMode
|
||||
? store
|
||||
|
|
@ -1638,9 +1677,10 @@ string EvalState::copyPathToStore(PathSet& context, const Path& path) {
|
|||
|
||||
Path EvalState::coerceToPath(const Pos& pos, Value& v, PathSet& context) {
|
||||
string path = coerceToString(pos, v, context, false, false);
|
||||
if (path == "" || path[0] != '/')
|
||||
if (path == "" || path[0] != '/') {
|
||||
throwEvalError("string '%1%' doesn't represent an absolute path, at %2%",
|
||||
path, pos);
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
|
|
@ -1827,10 +1867,11 @@ void EvalState::printStats() {
|
|||
auto list = topObj.list("functions");
|
||||
for (auto& i : functionCalls) {
|
||||
auto obj = list.object();
|
||||
if (i.first->name.set())
|
||||
if (i.first->name.set()) {
|
||||
obj.attr("name", (const string&)i.first->name);
|
||||
else
|
||||
} else {
|
||||
obj.attr("name", nullptr);
|
||||
}
|
||||
if (i.first->pos) {
|
||||
obj.attr("file", (const string&)i.first->pos.file);
|
||||
obj.attr("line", i.first->pos.line);
|
||||
|
|
@ -1885,10 +1926,11 @@ size_t valueSize(Value& v) {
|
|||
switch (v.type) {
|
||||
case tString:
|
||||
sz += doString(v.string.s);
|
||||
if (v.string.context)
|
||||
if (v.string.context) {
|
||||
for (const char** p = v.string.context; *p; ++p) {
|
||||
sz += doString(*p);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case tPath:
|
||||
sz += doString(v.path);
|
||||
|
|
@ -1908,8 +1950,9 @@ size_t valueSize(Value& v) {
|
|||
if (seen.find(v.listElems()) == seen.end()) {
|
||||
seen.insert(v.listElems());
|
||||
sz += v.listSize() * sizeof(Value*);
|
||||
for (size_t n = 0; n < v.listSize(); ++n)
|
||||
for (size_t n = 0; n < v.listSize(); ++n) {
|
||||
sz += doValue(*v.listElems()[n]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case tThunk:
|
||||
|
|
@ -1947,11 +1990,13 @@ size_t valueSize(Value& v) {
|
|||
|
||||
size_t sz = sizeof(Env) + sizeof(Value*) * env.size;
|
||||
|
||||
if (env.type != Env::HasWithExpr)
|
||||
for (size_t i = 0; i < env.size; ++i)
|
||||
if (env.type != Env::HasWithExpr) {
|
||||
for (size_t i = 0; i < env.size; ++i) {
|
||||
if (env.values[i]) {
|
||||
sz += doValue(*env.values[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (env.up) {
|
||||
sz += doEnv(*env.up);
|
||||
|
|
|
|||
26
third_party/nix/src/libexpr/get-drvs.cc
vendored
26
third_party/nix/src/libexpr/get-drvs.cc
vendored
|
|
@ -25,18 +25,20 @@ DrvInfo::DrvInfo(EvalState& state, ref<Store> store,
|
|||
|
||||
name = storePathToName(drvPath);
|
||||
|
||||
if (spec.second.size() > 1)
|
||||
if (spec.second.size() > 1) {
|
||||
throw Error(
|
||||
"building more than one derivation output is not supported, in '%s'",
|
||||
drvPathWithOutputs);
|
||||
}
|
||||
|
||||
outputName = spec.second.empty() ? get(drv.env, "outputName", "out")
|
||||
: *spec.second.begin();
|
||||
|
||||
auto i = drv.outputs.find(outputName);
|
||||
if (i == drv.outputs.end())
|
||||
if (i == drv.outputs.end()) {
|
||||
throw Error("derivation '%s' does not have output '%s'", drvPath,
|
||||
outputName);
|
||||
}
|
||||
|
||||
outPath = i->second.path;
|
||||
}
|
||||
|
|
@ -110,8 +112,9 @@ DrvInfo::Outputs DrvInfo::queryOutputs(bool onlyOutputsToInstall) {
|
|||
outputs[name] =
|
||||
state->coerceToPath(*outPath->pos, *outPath->value, context);
|
||||
}
|
||||
} else
|
||||
} else {
|
||||
outputs["out"] = queryOutPath();
|
||||
}
|
||||
}
|
||||
if (!onlyOutputsToInstall || !attrs) {
|
||||
return outputs;
|
||||
|
|
@ -363,10 +366,11 @@ static void getDerivations(EvalState& state, Value& vIn,
|
|||
state.autoCallFunction(autoArgs, vIn, v);
|
||||
|
||||
/* Process the expression. */
|
||||
if (!getDerivation(state, v, pathPrefix, drvs, done, ignoreAssertionFailures))
|
||||
if (!getDerivation(state, v, pathPrefix, drvs, done,
|
||||
ignoreAssertionFailures)) {
|
||||
;
|
||||
|
||||
else if (v.type == tAttrs) {
|
||||
} else if (v.type == tAttrs) {
|
||||
/* !!! undocumented hackery to support combining channels in
|
||||
nix-env.cc. */
|
||||
bool combineChannels =
|
||||
|
|
@ -384,11 +388,11 @@ static void getDerivations(EvalState& state, Value& vIn,
|
|||
continue;
|
||||
}
|
||||
string pathPrefix2 = addToPath(pathPrefix, i->name);
|
||||
if (combineChannels)
|
||||
if (combineChannels) {
|
||||
getDerivations(state, *i->value, pathPrefix2, autoArgs, drvs, done,
|
||||
ignoreAssertionFailures);
|
||||
else if (getDerivation(state, *i->value, pathPrefix2, drvs, done,
|
||||
ignoreAssertionFailures)) {
|
||||
} else if (getDerivation(state, *i->value, pathPrefix2, drvs, done,
|
||||
ignoreAssertionFailures)) {
|
||||
/* If the value of this attribute is itself a set,
|
||||
should we recurse into it? => Only if it has a
|
||||
`recurseForDerivations = true' attribute. */
|
||||
|
|
@ -396,9 +400,10 @@ static void getDerivations(EvalState& state, Value& vIn,
|
|||
Bindings::iterator j = i->value->attrs->find(
|
||||
state.symbols.create("recurseForDerivations"));
|
||||
if (j != i->value->attrs->end() &&
|
||||
state.forceBool(*j->value, *j->pos))
|
||||
state.forceBool(*j->value, *j->pos)) {
|
||||
getDerivations(state, *i->value, pathPrefix2, autoArgs, drvs, done,
|
||||
ignoreAssertionFailures);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -408,9 +413,10 @@ static void getDerivations(EvalState& state, Value& vIn,
|
|||
for (unsigned int n = 0; n < v.listSize(); ++n) {
|
||||
string pathPrefix2 = addToPath(pathPrefix, (format("%1%") % n).str());
|
||||
if (getDerivation(state, *v.listElems()[n], pathPrefix2, drvs, done,
|
||||
ignoreAssertionFailures))
|
||||
ignoreAssertionFailures)) {
|
||||
getDerivations(state, *v.listElems()[n], pathPrefix2, autoArgs, drvs,
|
||||
done, ignoreAssertionFailures);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
40
third_party/nix/src/libexpr/json-to-value.cc
vendored
40
third_party/nix/src/libexpr/json-to-value.cc
vendored
|
|
@ -21,29 +21,30 @@ static string parseJSONString(const char*& s) {
|
|||
}
|
||||
if (*s == '\\') {
|
||||
s++;
|
||||
if (*s == '"')
|
||||
if (*s == '"') {
|
||||
res += '"';
|
||||
else if (*s == '\\')
|
||||
} else if (*s == '\\') {
|
||||
res += '\\';
|
||||
else if (*s == '/')
|
||||
} else if (*s == '/') {
|
||||
res += '/';
|
||||
else if (*s == '/')
|
||||
} else if (*s == '/') {
|
||||
res += '/';
|
||||
else if (*s == 'b')
|
||||
} else if (*s == 'b') {
|
||||
res += '\b';
|
||||
else if (*s == 'f')
|
||||
} else if (*s == 'f') {
|
||||
res += '\f';
|
||||
else if (*s == 'n')
|
||||
} else if (*s == 'n') {
|
||||
res += '\n';
|
||||
else if (*s == 'r')
|
||||
} else if (*s == 'r') {
|
||||
res += '\r';
|
||||
else if (*s == 't')
|
||||
} else if (*s == 't') {
|
||||
res += '\t';
|
||||
else if (*s == 'u')
|
||||
} else if (*s == 'u') {
|
||||
throw JSONParseError(
|
||||
"\\u characters in JSON strings are currently not supported");
|
||||
else
|
||||
} else {
|
||||
throw JSONParseError("invalid escaped character in JSON string");
|
||||
}
|
||||
s++;
|
||||
} else {
|
||||
res += *s++;
|
||||
|
|
@ -76,8 +77,9 @@ static void parseJSON(EvalState& state, const char*& s, Value& v) {
|
|||
if (*s == ']') {
|
||||
break;
|
||||
}
|
||||
if (*s != ',')
|
||||
if (*s != ',') {
|
||||
throw JSONParseError("expected ',' or ']' after JSON array element");
|
||||
}
|
||||
s++;
|
||||
}
|
||||
s++;
|
||||
|
|
@ -108,8 +110,9 @@ static void parseJSON(EvalState& state, const char*& s, Value& v) {
|
|||
if (*s == '}') {
|
||||
break;
|
||||
}
|
||||
if (*s != ',')
|
||||
if (*s != ',') {
|
||||
throw JSONParseError("expected ',' or '}' after JSON member");
|
||||
}
|
||||
s++;
|
||||
}
|
||||
state.mkAttrs(v, attrs.size());
|
||||
|
|
@ -137,10 +140,11 @@ static void parseJSON(EvalState& state, const char*& s, Value& v) {
|
|||
}
|
||||
|
||||
try {
|
||||
if (number_type == tFloat)
|
||||
if (number_type == tFloat) {
|
||||
mkFloat(v, stod(tmp_number));
|
||||
else
|
||||
} else {
|
||||
mkInt(v, stol(tmp_number));
|
||||
}
|
||||
} catch (std::invalid_argument& e) {
|
||||
throw JSONParseError("invalid JSON number");
|
||||
} catch (std::out_of_range& e) {
|
||||
|
|
@ -163,17 +167,19 @@ static void parseJSON(EvalState& state, const char*& s, Value& v) {
|
|||
mkNull(v);
|
||||
}
|
||||
|
||||
else
|
||||
else {
|
||||
throw JSONParseError("unrecognised JSON value");
|
||||
}
|
||||
}
|
||||
|
||||
void parseJSON(EvalState& state, const string& s_, Value& v) {
|
||||
const char* s = s_.c_str();
|
||||
parseJSON(state, s, v);
|
||||
skipWhitespace(s);
|
||||
if (*s)
|
||||
if (*s) {
|
||||
throw JSONParseError(
|
||||
format("expected end-of-string while parsing JSON value: %1%") % s);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace nix
|
||||
|
|
|
|||
35
third_party/nix/src/libexpr/names.cc
vendored
35
third_party/nix/src/libexpr/names.cc
vendored
|
|
@ -25,9 +25,10 @@ DrvName::DrvName(const string& s) : hits(0) {
|
|||
|
||||
bool DrvName::matches(DrvName& n) {
|
||||
if (name != "*") {
|
||||
if (!regex)
|
||||
if (!regex) {
|
||||
regex = std::unique_ptr<std::regex>(
|
||||
new std::regex(name, std::regex::extended));
|
||||
}
|
||||
if (!std::regex_match(n.name, *regex)) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -41,7 +42,9 @@ bool DrvName::matches(DrvName& n) {
|
|||
string nextComponent(string::const_iterator& p,
|
||||
const string::const_iterator end) {
|
||||
/* Skip any dots and dashes (component separators). */
|
||||
while (p != end && (*p == '.' || *p == '-')) ++p;
|
||||
while (p != end && (*p == '.' || *p == '-')) {
|
||||
++p;
|
||||
}
|
||||
|
||||
if (p == end) {
|
||||
return "";
|
||||
|
|
@ -51,10 +54,15 @@ string nextComponent(string::const_iterator& p,
|
|||
of digits. Otherwise, consume the longest sequence of
|
||||
non-digit, non-separator characters. */
|
||||
string s;
|
||||
if (isdigit(*p))
|
||||
while (p != end && isdigit(*p)) s += *p++;
|
||||
else
|
||||
while (p != end && (!isdigit(*p) && *p != '.' && *p != '-')) s += *p++;
|
||||
if (isdigit(*p)) {
|
||||
while (p != end && isdigit(*p)) {
|
||||
s += *p++;
|
||||
}
|
||||
} else {
|
||||
while (p != end && (!isdigit(*p) && *p != '.' && *p != '-')) {
|
||||
s += *p++;
|
||||
}
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
|
@ -65,14 +73,14 @@ static bool componentsLT(const string& c1, const string& c2) {
|
|||
|
||||
if (c1Num && c2Num) {
|
||||
return n1 < n2;
|
||||
} else if (c1 == "" && c2Num)
|
||||
} else if (c1 == "" && c2Num) {
|
||||
return true;
|
||||
else if (c1 == "pre" && c2 != "pre")
|
||||
} else if (c1 == "pre" && c2 != "pre") {
|
||||
return true;
|
||||
else if (c2 == "pre")
|
||||
} else if (c2 == "pre") {
|
||||
return false;
|
||||
/* Assume that `2.3a' < `2.3.1'. */
|
||||
else if (c2Num) {
|
||||
/* Assume that `2.3a' < `2.3.1'. */
|
||||
} else if (c2Num) {
|
||||
return true;
|
||||
} else if (c1Num) {
|
||||
return false;
|
||||
|
|
@ -88,10 +96,11 @@ int compareVersions(const string& v1, const string& v2) {
|
|||
while (p1 != v1.end() || p2 != v2.end()) {
|
||||
string c1 = nextComponent(p1, v1.end());
|
||||
string c2 = nextComponent(p2, v2.end());
|
||||
if (componentsLT(c1, c2))
|
||||
if (componentsLT(c1, c2)) {
|
||||
return -1;
|
||||
else if (componentsLT(c2, c1))
|
||||
} else if (componentsLT(c2, c1)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
80
third_party/nix/src/libexpr/nixexpr.cc
vendored
80
third_party/nix/src/libexpr/nixexpr.cc
vendored
|
|
@ -16,37 +16,40 @@ std::ostream& operator<<(std::ostream& str, const Expr& e) {
|
|||
|
||||
static void showString(std::ostream& str, const string& s) {
|
||||
str << '"';
|
||||
for (auto c : (string)s)
|
||||
if (c == '"' || c == '\\' || c == '$')
|
||||
for (auto c : (string)s) {
|
||||
if (c == '"' || c == '\\' || c == '$') {
|
||||
str << "\\" << c;
|
||||
else if (c == '\n')
|
||||
} else if (c == '\n') {
|
||||
str << "\\n";
|
||||
else if (c == '\r')
|
||||
} else if (c == '\r') {
|
||||
str << "\\r";
|
||||
else if (c == '\t')
|
||||
} else if (c == '\t') {
|
||||
str << "\\t";
|
||||
else
|
||||
} else {
|
||||
str << c;
|
||||
}
|
||||
}
|
||||
str << '"';
|
||||
}
|
||||
|
||||
static void showId(std::ostream& str, const string& s) {
|
||||
if (s.empty())
|
||||
if (s.empty()) {
|
||||
str << "\"\"";
|
||||
else if (s == "if") // FIXME: handle other keywords
|
||||
} else if (s == "if") { // FIXME: handle other keywords
|
||||
str << '"' << s << '"';
|
||||
else {
|
||||
} else {
|
||||
char c = s[0];
|
||||
if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_')) {
|
||||
showString(str, s);
|
||||
return;
|
||||
}
|
||||
for (auto c : s)
|
||||
for (auto c : s) {
|
||||
if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
|
||||
(c >= '0' && c <= '9') || c == '_' || c == '\'' || c == '-')) {
|
||||
showString(str, s);
|
||||
return;
|
||||
}
|
||||
}
|
||||
str << s;
|
||||
}
|
||||
}
|
||||
|
|
@ -84,14 +87,17 @@ void ExprAttrs::show(std::ostream& str) const {
|
|||
str << "rec ";
|
||||
}
|
||||
str << "{ ";
|
||||
for (auto& i : attrs)
|
||||
if (i.second.inherited)
|
||||
for (auto& i : attrs) {
|
||||
if (i.second.inherited) {
|
||||
str << "inherit " << i.first << " "
|
||||
<< "; ";
|
||||
else
|
||||
} else {
|
||||
str << i.first << " = " << *i.second.e << "; ";
|
||||
for (auto& i : dynamicAttrs)
|
||||
}
|
||||
}
|
||||
for (auto& i : dynamicAttrs) {
|
||||
str << "\"${" << *i.nameExpr << "}\" = " << *i.valueExpr << "; ";
|
||||
}
|
||||
str << "}";
|
||||
}
|
||||
|
||||
|
|
@ -109,10 +115,11 @@ void ExprLambda::show(std::ostream& str) const {
|
|||
str << "{ ";
|
||||
bool first = true;
|
||||
for (auto& i : formals->formals) {
|
||||
if (first)
|
||||
if (first) {
|
||||
first = false;
|
||||
else
|
||||
} else {
|
||||
str << ", ";
|
||||
}
|
||||
str << i.name;
|
||||
if (i.def) {
|
||||
str << " ? " << *i.def;
|
||||
|
|
@ -137,11 +144,13 @@ void ExprLambda::show(std::ostream& str) const {
|
|||
|
||||
void ExprLet::show(std::ostream& str) const {
|
||||
str << "(let ";
|
||||
for (auto& i : attrs->attrs)
|
||||
for (auto& i : attrs->attrs) {
|
||||
if (i.second.inherited) {
|
||||
str << "inherit " << i.first << "; ";
|
||||
} else
|
||||
} else {
|
||||
str << i.first << " = " << *i.second.e << "; ";
|
||||
}
|
||||
}
|
||||
str << "in " << *body << ")";
|
||||
}
|
||||
|
||||
|
|
@ -163,10 +172,11 @@ void ExprConcatStrings::show(std::ostream& str) const {
|
|||
bool first = true;
|
||||
str << "(";
|
||||
for (auto& i : *es) {
|
||||
if (first)
|
||||
if (first) {
|
||||
first = false;
|
||||
else
|
||||
} else {
|
||||
str << " + ";
|
||||
}
|
||||
str << *i;
|
||||
}
|
||||
str << ")";
|
||||
|
|
@ -175,12 +185,13 @@ void ExprConcatStrings::show(std::ostream& str) const {
|
|||
void ExprPos::show(std::ostream& str) const { str << "__curPos"; }
|
||||
|
||||
std::ostream& operator<<(std::ostream& str, const Pos& pos) {
|
||||
if (!pos)
|
||||
if (!pos) {
|
||||
str << "undefined position";
|
||||
else
|
||||
} else {
|
||||
str << (format(ANSI_BOLD "%1%" ANSI_NORMAL ":%2%:%3%") % (string)pos.file %
|
||||
pos.line % pos.column)
|
||||
.str();
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
|
|
@ -188,14 +199,16 @@ string showAttrPath(const AttrPath& attrPath) {
|
|||
std::ostringstream out;
|
||||
bool first = true;
|
||||
for (auto& i : attrPath) {
|
||||
if (!first)
|
||||
if (!first) {
|
||||
out << '.';
|
||||
else
|
||||
} else {
|
||||
first = false;
|
||||
if (i.symbol.set())
|
||||
}
|
||||
if (i.symbol.set()) {
|
||||
out << i.symbol;
|
||||
else
|
||||
} else {
|
||||
out << "\"${" << *i.expr << "}\"";
|
||||
}
|
||||
}
|
||||
return out.str();
|
||||
}
|
||||
|
|
@ -239,9 +252,10 @@ void ExprVar::bindVars(const StaticEnv& env) {
|
|||
/* Otherwise, the variable must be obtained from the nearest
|
||||
enclosing `with'. If there is no `with', then we can issue an
|
||||
"undefined variable" error now. */
|
||||
if (withLevel == -1)
|
||||
if (withLevel == -1) {
|
||||
throw UndefinedVarError(format("undefined variable '%1%' at %2%") % name %
|
||||
pos);
|
||||
}
|
||||
|
||||
fromWith = true;
|
||||
this->level = withLevel;
|
||||
|
|
@ -252,18 +266,20 @@ void ExprSelect::bindVars(const StaticEnv& env) {
|
|||
if (def) {
|
||||
def->bindVars(env);
|
||||
}
|
||||
for (auto& i : attrPath)
|
||||
for (auto& i : attrPath) {
|
||||
if (!i.symbol.set()) {
|
||||
i.expr->bindVars(env);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ExprOpHasAttr::bindVars(const StaticEnv& env) {
|
||||
e->bindVars(env);
|
||||
for (auto& i : attrPath)
|
||||
for (auto& i : attrPath) {
|
||||
if (!i.symbol.set()) {
|
||||
i.expr->bindVars(env);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ExprAttrs::bindVars(const StaticEnv& env) {
|
||||
|
|
@ -315,10 +331,11 @@ void ExprLambda::bindVars(const StaticEnv& env) {
|
|||
newEnv.vars[i.name] = displ++;
|
||||
}
|
||||
|
||||
for (auto& i : formals->formals)
|
||||
for (auto& i : formals->formals) {
|
||||
if (i.def) {
|
||||
i.def->bindVars(newEnv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
body->bindVars(newEnv);
|
||||
|
|
@ -332,8 +349,9 @@ void ExprLet::bindVars(const StaticEnv& env) {
|
|||
newEnv.vars[i.first] = i.second.displ = displ++;
|
||||
}
|
||||
|
||||
for (auto& i : attrs->attrs)
|
||||
for (auto& i : attrs->attrs) {
|
||||
i.second.e->bindVars(i.second.inherited ? env : newEnv);
|
||||
}
|
||||
|
||||
body->bindVars(newEnv);
|
||||
}
|
||||
|
|
|
|||
227
third_party/nix/src/libexpr/primops.cc
vendored
227
third_party/nix/src/libexpr/primops.cc
vendored
|
|
@ -37,8 +37,9 @@ std::pair<string, string> decodeContext(const string& s) {
|
|||
size_t index = s.find("!", 1);
|
||||
return std::pair<string, string>(string(s, index + 1),
|
||||
string(s, 1, index - 1));
|
||||
} else
|
||||
} else {
|
||||
return std::pair<string, string>(s.at(0) == '/' ? s : string(s, 1), "");
|
||||
}
|
||||
}
|
||||
|
||||
InvalidPathError::InvalidPathError(const Path& path)
|
||||
|
|
@ -62,9 +63,10 @@ void EvalState::realiseContext(const PathSet& context) {
|
|||
if (allowedPaths) {
|
||||
auto drv = store->derivationFromPath(decoded.first);
|
||||
DerivationOutputs::iterator i = drv.outputs.find(decoded.second);
|
||||
if (i == drv.outputs.end())
|
||||
if (i == drv.outputs.end()) {
|
||||
throw Error("derivation '%s' does not have an output named '%s'",
|
||||
decoded.first, decoded.second);
|
||||
}
|
||||
allowedPaths->insert(i->second.path);
|
||||
}
|
||||
}
|
||||
|
|
@ -74,10 +76,11 @@ void EvalState::realiseContext(const PathSet& context) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!evalSettings.enableImportFromDerivation)
|
||||
if (!evalSettings.enableImportFromDerivation) {
|
||||
throw EvalError(format("attempted to realize '%1%' during evaluation but "
|
||||
"'allow-import-from-derivation' is false") %
|
||||
*(drvs.begin()));
|
||||
}
|
||||
|
||||
/* For performance, prefetch all substitute info. */
|
||||
PathSet willBuild, willSubstitute, unknown;
|
||||
|
|
@ -178,20 +181,22 @@ void prim_importNative(EvalState& state, const Pos& pos, Value** args,
|
|||
string sym = state.forceStringNoCtx(*args[1], pos);
|
||||
|
||||
void* handle = dlopen(path.c_str(), RTLD_LAZY | RTLD_LOCAL);
|
||||
if (!handle)
|
||||
if (!handle) {
|
||||
throw EvalError(format("could not open '%1%': %2%") % path % dlerror());
|
||||
}
|
||||
|
||||
dlerror();
|
||||
ValueInitializer func = (ValueInitializer)dlsym(handle, sym.c_str());
|
||||
if (!func) {
|
||||
char* message = dlerror();
|
||||
if (message)
|
||||
if (message) {
|
||||
throw EvalError(format("could not load symbol '%1%' from '%2%': %3%") %
|
||||
sym % path % message);
|
||||
else
|
||||
} else {
|
||||
throw EvalError(format("symbol '%1%' from '%2%' resolved to NULL when a "
|
||||
"function pointer was expected") %
|
||||
sym % path);
|
||||
}
|
||||
}
|
||||
|
||||
(func)(state, v);
|
||||
|
|
@ -356,9 +361,10 @@ struct CompareValues {
|
|||
if (v1->type == tInt && v2->type == tFloat) {
|
||||
return v1->integer < v2->fpoint;
|
||||
}
|
||||
if (v1->type != v2->type)
|
||||
if (v1->type != v2->type) {
|
||||
throw EvalError(format("cannot compare %1% with %2%") % showType(*v1) %
|
||||
showType(*v2));
|
||||
}
|
||||
switch (v1->type) {
|
||||
case tInt:
|
||||
return v1->integer < v2->integer;
|
||||
|
|
@ -388,19 +394,22 @@ static void prim_genericClosure(EvalState& state, const Pos& pos, Value** args,
|
|||
/* Get the start set. */
|
||||
Bindings::iterator startSet =
|
||||
args[0]->attrs->find(state.symbols.create("startSet"));
|
||||
if (startSet == args[0]->attrs->end())
|
||||
if (startSet == args[0]->attrs->end()) {
|
||||
throw EvalError(format("attribute 'startSet' required, at %1%") % pos);
|
||||
}
|
||||
state.forceList(*startSet->value, pos);
|
||||
|
||||
ValueList workSet;
|
||||
for (unsigned int n = 0; n < startSet->value->listSize(); ++n)
|
||||
for (unsigned int n = 0; n < startSet->value->listSize(); ++n) {
|
||||
workSet.push_back(startSet->value->listElems()[n]);
|
||||
}
|
||||
|
||||
/* Get the operator. */
|
||||
Bindings::iterator op =
|
||||
args[0]->attrs->find(state.symbols.create("operator"));
|
||||
if (op == args[0]->attrs->end())
|
||||
if (op == args[0]->attrs->end()) {
|
||||
throw EvalError(format("attribute 'operator' required, at %1%") % pos);
|
||||
}
|
||||
state.forceValue(*op->value);
|
||||
|
||||
/* Construct the closure by applying the operator to element of
|
||||
|
|
@ -417,8 +426,9 @@ static void prim_genericClosure(EvalState& state, const Pos& pos, Value** args,
|
|||
state.forceAttrs(*e, pos);
|
||||
|
||||
Bindings::iterator key = e->attrs->find(state.symbols.create("key"));
|
||||
if (key == e->attrs->end())
|
||||
if (key == e->attrs->end()) {
|
||||
throw EvalError(format("attribute 'key' required, at %1%") % pos);
|
||||
}
|
||||
state.forceValue(*key->value);
|
||||
|
||||
if (doneKeys.find(key->value) != doneKeys.end()) {
|
||||
|
|
@ -551,8 +561,9 @@ static void prim_derivationStrict(EvalState& state, const Pos& pos,
|
|||
|
||||
/* Figure out the name first (for stack backtraces). */
|
||||
Bindings::iterator attr = args[0]->attrs->find(state.sName);
|
||||
if (attr == args[0]->attrs->end())
|
||||
if (attr == args[0]->attrs->end()) {
|
||||
throw EvalError(format("required attribute 'name' missing, at %1%") % pos);
|
||||
}
|
||||
string drvName;
|
||||
Pos& posDrvName(*attr->pos);
|
||||
try {
|
||||
|
|
@ -568,8 +579,9 @@ static void prim_derivationStrict(EvalState& state, const Pos& pos,
|
|||
std::ostringstream jsonBuf;
|
||||
std::unique_ptr<JSONObject> jsonObject;
|
||||
attr = args[0]->attrs->find(state.sStructuredAttrs);
|
||||
if (attr != args[0]->attrs->end() && state.forceBool(*attr->value, pos))
|
||||
if (attr != args[0]->attrs->end() && state.forceBool(*attr->value, pos)) {
|
||||
jsonObject = std::make_unique<JSONObject>(jsonBuf);
|
||||
}
|
||||
|
||||
/* Check whether null attributes should be ignored. */
|
||||
bool ignoreNulls = false;
|
||||
|
|
@ -597,37 +609,41 @@ static void prim_derivationStrict(EvalState& state, const Pos& pos,
|
|||
const string& key = i->name;
|
||||
|
||||
auto handleHashMode = [&](const std::string& s) {
|
||||
if (s == "recursive")
|
||||
if (s == "recursive") {
|
||||
outputHashRecursive = true;
|
||||
else if (s == "flat")
|
||||
} else if (s == "flat") {
|
||||
outputHashRecursive = false;
|
||||
else
|
||||
} else {
|
||||
throw EvalError(
|
||||
"invalid value '%s' for 'outputHashMode' attribute, at %s", s,
|
||||
posDrvName);
|
||||
}
|
||||
};
|
||||
|
||||
auto handleOutputs = [&](const Strings& ss) {
|
||||
outputs.clear();
|
||||
for (auto& j : ss) {
|
||||
if (outputs.find(j) != outputs.end())
|
||||
if (outputs.find(j) != outputs.end()) {
|
||||
throw EvalError(format("duplicate derivation output '%1%', at %2%") %
|
||||
j % posDrvName);
|
||||
}
|
||||
/* !!! Check whether j is a valid attribute
|
||||
name. */
|
||||
/* Derivations cannot be named ‘drv’, because
|
||||
then we'd have an attribute ‘drvPath’ in
|
||||
the resulting set. */
|
||||
if (j == "drv")
|
||||
if (j == "drv") {
|
||||
throw EvalError(
|
||||
format("invalid derivation output name 'drv', at %1%") %
|
||||
posDrvName);
|
||||
}
|
||||
outputs.insert(j);
|
||||
}
|
||||
if (outputs.empty())
|
||||
if (outputs.empty()) {
|
||||
throw EvalError(
|
||||
format("derivation cannot have an empty set of outputs, at %1%") %
|
||||
posDrvName);
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
|
|
@ -660,41 +676,43 @@ static void prim_derivationStrict(EvalState& state, const Pos& pos,
|
|||
auto placeholder(jsonObject->placeholder(key));
|
||||
printValueAsJSON(state, true, *i->value, placeholder, context);
|
||||
|
||||
if (i->name == state.sBuilder)
|
||||
if (i->name == state.sBuilder) {
|
||||
drv.builder = state.forceString(*i->value, context, posDrvName);
|
||||
else if (i->name == state.sSystem)
|
||||
} else if (i->name == state.sSystem) {
|
||||
drv.platform = state.forceStringNoCtx(*i->value, posDrvName);
|
||||
else if (i->name == state.sOutputHash)
|
||||
} else if (i->name == state.sOutputHash) {
|
||||
outputHash = state.forceStringNoCtx(*i->value, posDrvName);
|
||||
else if (i->name == state.sOutputHashAlgo)
|
||||
} else if (i->name == state.sOutputHashAlgo) {
|
||||
outputHashAlgo = state.forceStringNoCtx(*i->value, posDrvName);
|
||||
else if (i->name == state.sOutputHashMode)
|
||||
} else if (i->name == state.sOutputHashMode) {
|
||||
handleHashMode(state.forceStringNoCtx(*i->value, posDrvName));
|
||||
else if (i->name == state.sOutputs) {
|
||||
} else if (i->name == state.sOutputs) {
|
||||
/* Require ‘outputs’ to be a list of strings. */
|
||||
state.forceList(*i->value, posDrvName);
|
||||
Strings ss;
|
||||
for (unsigned int n = 0; n < i->value->listSize(); ++n)
|
||||
for (unsigned int n = 0; n < i->value->listSize(); ++n) {
|
||||
ss.emplace_back(state.forceStringNoCtx(*i->value->listElems()[n],
|
||||
posDrvName));
|
||||
}
|
||||
handleOutputs(ss);
|
||||
}
|
||||
|
||||
} else {
|
||||
auto s = state.coerceToString(posDrvName, *i->value, context, true);
|
||||
drv.env.emplace(key, s);
|
||||
if (i->name == state.sBuilder)
|
||||
if (i->name == state.sBuilder) {
|
||||
drv.builder = s;
|
||||
else if (i->name == state.sSystem)
|
||||
} else if (i->name == state.sSystem) {
|
||||
drv.platform = s;
|
||||
else if (i->name == state.sOutputHash)
|
||||
} else if (i->name == state.sOutputHash) {
|
||||
outputHash = s;
|
||||
else if (i->name == state.sOutputHashAlgo)
|
||||
} else if (i->name == state.sOutputHashAlgo) {
|
||||
outputHashAlgo = s;
|
||||
else if (i->name == state.sOutputHashMode)
|
||||
} else if (i->name == state.sOutputHashMode) {
|
||||
handleHashMode(s);
|
||||
else if (i->name == state.sOutputs)
|
||||
} else if (i->name == state.sOutputs) {
|
||||
handleOutputs(tokenizeString<Strings>(s));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -728,8 +746,9 @@ static void prim_derivationStrict(EvalState& state, const Pos& pos,
|
|||
state.store->computeFSClosure(string(path, 1), refs);
|
||||
for (auto& j : refs) {
|
||||
drv.inputSrcs.insert(j);
|
||||
if (isDerivation(j))
|
||||
if (isDerivation(j)) {
|
||||
drv.inputDrvs[j] = state.store->queryDerivationOutputNames(j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -740,31 +759,36 @@ static void prim_derivationStrict(EvalState& state, const Pos& pos,
|
|||
}
|
||||
|
||||
/* Otherwise it's a source file. */
|
||||
else
|
||||
else {
|
||||
drv.inputSrcs.insert(path);
|
||||
}
|
||||
}
|
||||
|
||||
/* Do we have all required attributes? */
|
||||
if (drv.builder == "")
|
||||
if (drv.builder == "") {
|
||||
throw EvalError(format("required attribute 'builder' missing, at %1%") %
|
||||
posDrvName);
|
||||
if (drv.platform == "")
|
||||
}
|
||||
if (drv.platform == "") {
|
||||
throw EvalError(format("required attribute 'system' missing, at %1%") %
|
||||
posDrvName);
|
||||
}
|
||||
|
||||
/* Check whether the derivation name is valid. */
|
||||
checkStoreName(drvName);
|
||||
if (isDerivation(drvName))
|
||||
if (isDerivation(drvName)) {
|
||||
throw EvalError(
|
||||
format("derivation names are not allowed to end in '%1%', at %2%") %
|
||||
drvExtension % posDrvName);
|
||||
}
|
||||
|
||||
if (outputHash) {
|
||||
/* Handle fixed-output derivations. */
|
||||
if (outputs.size() != 1 || *(outputs.begin()) != "out")
|
||||
if (outputs.size() != 1 || *(outputs.begin()) != "out") {
|
||||
throw Error(format("multiple outputs are not supported in fixed-output "
|
||||
"derivations, at %1%") %
|
||||
posDrvName);
|
||||
}
|
||||
|
||||
HashType ht =
|
||||
outputHashAlgo.empty() ? htUnknown : parseHashType(outputHashAlgo);
|
||||
|
|
@ -797,7 +821,7 @@ static void prim_derivationStrict(EvalState& state, const Pos& pos,
|
|||
path. */
|
||||
Hash h = hashDerivationModulo(*state.store, drv);
|
||||
|
||||
for (auto& i : drv.outputs)
|
||||
for (auto& i : drv.outputs) {
|
||||
if (i.second.path == "") {
|
||||
Path outPath = state.store->makeOutputPath(i.first, h, drvName);
|
||||
if (!jsonObject) {
|
||||
|
|
@ -805,6 +829,7 @@ static void prim_derivationStrict(EvalState& state, const Pos& pos,
|
|||
}
|
||||
i.second.path = outPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Write the resulting term into the Nix store directory. */
|
||||
|
|
@ -868,9 +893,10 @@ static void prim_storePath(EvalState& state, const Pos& pos, Value** args,
|
|||
if (!state.store->isStorePath(path)) {
|
||||
path = canonPath(path, true);
|
||||
}
|
||||
if (!state.store->isInStore(path))
|
||||
if (!state.store->isInStore(path)) {
|
||||
throw EvalError(format("path '%1%' is not in the Nix store, at %2%") %
|
||||
path % pos);
|
||||
}
|
||||
Path path2 = state.store->toStorePath(path);
|
||||
if (!settings.readOnlyMode) {
|
||||
state.store->ensurePath(path2);
|
||||
|
|
@ -939,10 +965,11 @@ static void prim_readFile(EvalState& state, const Pos& pos, Value** args,
|
|||
path % e.path % pos);
|
||||
}
|
||||
string s = readFile(state.checkSourcePath(state.toRealPath(path, context)));
|
||||
if (s.find((char)0) != string::npos)
|
||||
if (s.find((char)0) != string::npos) {
|
||||
throw Error(format("the contents of the file '%1%' cannot be represented "
|
||||
"as a Nix string") %
|
||||
path);
|
||||
}
|
||||
mkString(v, s.c_str());
|
||||
}
|
||||
|
||||
|
|
@ -965,8 +992,9 @@ static void prim_findFile(EvalState& state, const Pos& pos, Value** args,
|
|||
}
|
||||
|
||||
i = v2.attrs->find(state.symbols.create("path"));
|
||||
if (i == v2.attrs->end())
|
||||
if (i == v2.attrs->end()) {
|
||||
throw EvalError(format("attribute 'path' missing, at %1%") % pos);
|
||||
}
|
||||
|
||||
PathSet context;
|
||||
string path = state.coerceToString(pos, *i->value, context, false, false);
|
||||
|
|
@ -993,8 +1021,9 @@ static void prim_hashFile(EvalState& state, const Pos& pos, Value** args,
|
|||
Value& v) {
|
||||
string type = state.forceStringNoCtx(*args[0], pos);
|
||||
HashType ht = parseHashType(type);
|
||||
if (ht == htUnknown)
|
||||
if (ht == htUnknown) {
|
||||
throw Error(format("unknown hash type '%1%', at %2%") % type % pos);
|
||||
}
|
||||
|
||||
PathSet context; // discarded
|
||||
Path p = state.coerceToPath(pos, *args[1], context);
|
||||
|
|
@ -1079,10 +1108,11 @@ static void prim_toFile(EvalState& state, const Pos& pos, Value** args,
|
|||
PathSet refs;
|
||||
|
||||
for (auto path : context) {
|
||||
if (path.at(0) != '/')
|
||||
if (path.at(0) != '/') {
|
||||
throw EvalError(format("in 'toFile': the file '%1%' cannot refer to "
|
||||
"derivation outputs, at %2%") %
|
||||
name % pos);
|
||||
}
|
||||
refs.insert(path);
|
||||
}
|
||||
|
||||
|
|
@ -1150,8 +1180,9 @@ static void addPath(EvalState& state, const Pos& pos, const string& name,
|
|||
"added from '%1%'") %
|
||||
path);
|
||||
}
|
||||
} else
|
||||
} else {
|
||||
dstPath = expectedStorePath;
|
||||
}
|
||||
|
||||
mkString(v, dstPath, {dstPath});
|
||||
}
|
||||
|
|
@ -1160,15 +1191,17 @@ static void prim_filterSource(EvalState& state, const Pos& pos, Value** args,
|
|||
Value& v) {
|
||||
PathSet context;
|
||||
Path path = state.coerceToPath(pos, *args[1], context);
|
||||
if (!context.empty())
|
||||
if (!context.empty()) {
|
||||
throw EvalError(format("string '%1%' cannot refer to other paths, at %2%") %
|
||||
path % pos);
|
||||
}
|
||||
|
||||
state.forceValue(*args[0]);
|
||||
if (args[0]->type != tLambda)
|
||||
if (args[0]->type != tLambda) {
|
||||
throw TypeError(format("first argument in call to 'filterSource' is not a "
|
||||
"function but %1%, at %2%") %
|
||||
showType(*args[0]) % pos);
|
||||
}
|
||||
|
||||
addPath(state, pos, baseNameOf(path), path, args[0], true, Hash(), v);
|
||||
}
|
||||
|
|
@ -1187,24 +1220,26 @@ static void prim_path(EvalState& state, const Pos& pos, Value** args,
|
|||
if (n == "path") {
|
||||
PathSet context;
|
||||
path = state.coerceToPath(*attr.pos, *attr.value, context);
|
||||
if (!context.empty())
|
||||
if (!context.empty()) {
|
||||
throw EvalError(
|
||||
format("string '%1%' cannot refer to other paths, at %2%") % path %
|
||||
*attr.pos);
|
||||
} else if (attr.name == state.sName)
|
||||
}
|
||||
} else if (attr.name == state.sName) {
|
||||
name = state.forceStringNoCtx(*attr.value, *attr.pos);
|
||||
else if (n == "filter") {
|
||||
} else if (n == "filter") {
|
||||
state.forceValue(*attr.value);
|
||||
filterFun = attr.value;
|
||||
} else if (n == "recursive")
|
||||
} else if (n == "recursive") {
|
||||
recursive = state.forceBool(*attr.value, *attr.pos);
|
||||
else if (n == "sha256")
|
||||
} else if (n == "sha256") {
|
||||
expectedHash =
|
||||
Hash(state.forceStringNoCtx(*attr.value, *attr.pos), htSHA256);
|
||||
else
|
||||
} else {
|
||||
throw EvalError(
|
||||
format("unsupported argument '%1%' to 'addPath', at %2%") %
|
||||
attr.name % *attr.pos);
|
||||
}
|
||||
}
|
||||
if (path.empty()) {
|
||||
throw EvalError(format("'path' required, at %1%") % pos);
|
||||
|
|
@ -1229,8 +1264,9 @@ static void prim_attrNames(EvalState& state, const Pos& pos, Value** args,
|
|||
state.mkList(v, args[0]->attrs->size());
|
||||
|
||||
size_t n = 0;
|
||||
for (auto& i : *args[0]->attrs)
|
||||
for (auto& i : *args[0]->attrs) {
|
||||
mkString(*(v.listElems()[n++] = state.allocValue()), i.name);
|
||||
}
|
||||
|
||||
std::sort(v.listElems(), v.listElems() + n, [](Value* v1, Value* v2) {
|
||||
return strcmp(v1->string.s, v2->string.s) < 0;
|
||||
|
|
@ -1265,8 +1301,9 @@ void prim_getAttr(EvalState& state, const Pos& pos, Value** args, Value& v) {
|
|||
state.forceAttrs(*args[1], pos);
|
||||
// !!! Should we create a symbol here or just do a lookup?
|
||||
Bindings::iterator i = args[1]->attrs->find(state.symbols.create(attr));
|
||||
if (i == args[1]->attrs->end())
|
||||
if (i == args[1]->attrs->end()) {
|
||||
throw EvalError(format("attribute '%1%' missing, at %2%") % attr % pos);
|
||||
}
|
||||
// !!! add to stack trace?
|
||||
if (state.countCalls && i->pos) {
|
||||
state.attrSelects[*i->pos]++;
|
||||
|
|
@ -1345,21 +1382,23 @@ static void prim_listToAttrs(EvalState& state, const Pos& pos, Value** args,
|
|||
state.forceAttrs(v2, pos);
|
||||
|
||||
Bindings::iterator j = v2.attrs->find(state.sName);
|
||||
if (j == v2.attrs->end())
|
||||
if (j == v2.attrs->end()) {
|
||||
throw TypeError(
|
||||
format(
|
||||
"'name' attribute missing in a call to 'listToAttrs', at %1%") %
|
||||
pos);
|
||||
}
|
||||
string name = state.forceStringNoCtx(*j->value, pos);
|
||||
|
||||
Symbol sym = state.symbols.create(name);
|
||||
if (seen.find(sym) == seen.end()) {
|
||||
Bindings::iterator j2 =
|
||||
v2.attrs->find(state.symbols.create(state.sValue));
|
||||
if (j2 == v2.attrs->end())
|
||||
if (j2 == v2.attrs->end()) {
|
||||
throw TypeError(format("'value' attribute missing in a call to "
|
||||
"'listToAttrs', at %1%") %
|
||||
pos);
|
||||
}
|
||||
|
||||
v.attrs->push_back(Attr(sym, j2->value, j2->pos));
|
||||
seen.insert(sym);
|
||||
|
|
@ -1434,8 +1473,9 @@ static void prim_catAttrs(EvalState& state, const Pos& pos, Value** args,
|
|||
static void prim_functionArgs(EvalState& state, const Pos& pos, Value** args,
|
||||
Value& v) {
|
||||
state.forceValue(*args[0]);
|
||||
if (args[0]->type != tLambda)
|
||||
if (args[0]->type != tLambda) {
|
||||
throw TypeError(format("'functionArgs' requires a function, at %1%") % pos);
|
||||
}
|
||||
|
||||
if (!args[0]->lambda.fun->matchAttrs) {
|
||||
state.mkAttrs(v, 0);
|
||||
|
|
@ -1443,9 +1483,10 @@ static void prim_functionArgs(EvalState& state, const Pos& pos, Value** args,
|
|||
}
|
||||
|
||||
state.mkAttrs(v, args[0]->lambda.fun->formals->formals.size());
|
||||
for (auto& i : args[0]->lambda.fun->formals->formals)
|
||||
for (auto& i : args[0]->lambda.fun->formals->formals) {
|
||||
// !!! should optimise booleans (allocate only once)
|
||||
mkBool(*state.allocAttr(v, i.name), i.def);
|
||||
}
|
||||
v.attrs->sort();
|
||||
}
|
||||
|
||||
|
|
@ -1479,8 +1520,9 @@ static void prim_isList(EvalState& state, const Pos& pos, Value** args,
|
|||
static void elemAt(EvalState& state, const Pos& pos, Value& list, int n,
|
||||
Value& v) {
|
||||
state.forceList(list, pos);
|
||||
if (n < 0 || (unsigned int)n >= list.listSize())
|
||||
if (n < 0 || (unsigned int)n >= list.listSize()) {
|
||||
throw Error(format("list index %1% is out of bounds, at %2%") % n % pos);
|
||||
}
|
||||
state.forceValue(*list.listElems()[n]);
|
||||
v = *list.listElems()[n];
|
||||
}
|
||||
|
|
@ -1503,8 +1545,9 @@ static void prim_head(EvalState& state, const Pos& pos, Value** args,
|
|||
static void prim_tail(EvalState& state, const Pos& pos, Value** args,
|
||||
Value& v) {
|
||||
state.forceList(*args[0], pos);
|
||||
if (args[0]->listSize() == 0)
|
||||
if (args[0]->listSize() == 0) {
|
||||
throw Error(format("'tail' called on an empty list, at %1%") % pos);
|
||||
}
|
||||
state.mkList(v, args[0]->listSize() - 1);
|
||||
for (unsigned int n = 0; n < v.listSize(); ++n) {
|
||||
v.listElems()[n] = args[0]->listElems()[n + 1];
|
||||
|
|
@ -1637,9 +1680,10 @@ static void prim_genList(EvalState& state, const Pos& pos, Value** args,
|
|||
Value& v) {
|
||||
auto len = state.forceInt(*args[1], pos);
|
||||
|
||||
if (len < 0)
|
||||
if (len < 0) {
|
||||
throw EvalError(format("cannot create list of size %1%, at %2%") % len %
|
||||
pos);
|
||||
}
|
||||
|
||||
state.mkList(v, len);
|
||||
|
||||
|
|
@ -1698,10 +1742,11 @@ static void prim_partition(EvalState& state, const Pos& pos, Value** args,
|
|||
state.forceValue(*vElem);
|
||||
Value res;
|
||||
state.callFunction(*args[0], *vElem, res, pos);
|
||||
if (state.forceBool(res, pos))
|
||||
if (state.forceBool(res, pos)) {
|
||||
right.push_back(vElem);
|
||||
else
|
||||
} else {
|
||||
wrong.push_back(vElem);
|
||||
}
|
||||
}
|
||||
|
||||
state.mkAttrs(v, 2);
|
||||
|
|
@ -1805,8 +1850,9 @@ static void prim_div(EvalState& state, const Pos& pos, Value** args, Value& v) {
|
|||
NixInt i1 = state.forceInt(*args[0], pos);
|
||||
NixInt i2 = state.forceInt(*args[1], pos);
|
||||
/* Avoid division overflow as it might raise SIGFPE. */
|
||||
if (i1 == std::numeric_limits<NixInt>::min() && i2 == -1)
|
||||
if (i1 == std::numeric_limits<NixInt>::min() && i2 == -1) {
|
||||
throw EvalError(format("overflow in integer division, at %1%") % pos);
|
||||
}
|
||||
mkInt(v, i1 / i2);
|
||||
}
|
||||
}
|
||||
|
|
@ -1859,9 +1905,10 @@ static void prim_substring(EvalState& state, const Pos& pos, Value** args,
|
|||
PathSet context;
|
||||
string s = state.coerceToString(pos, *args[2], context);
|
||||
|
||||
if (start < 0)
|
||||
if (start < 0) {
|
||||
throw EvalError(format("negative start position in 'substring', at %1%") %
|
||||
pos);
|
||||
}
|
||||
|
||||
mkString(v, (unsigned int)start >= s.size() ? "" : string(s, start, len),
|
||||
context);
|
||||
|
|
@ -1879,8 +1926,9 @@ static void prim_hashString(EvalState& state, const Pos& pos, Value** args,
|
|||
Value& v) {
|
||||
string type = state.forceStringNoCtx(*args[0], pos);
|
||||
HashType ht = parseHashType(type);
|
||||
if (ht == htUnknown)
|
||||
if (ht == htUnknown) {
|
||||
throw Error(format("unknown hash type '%1%', at %2%") % type % pos);
|
||||
}
|
||||
|
||||
PathSet context; // discarded
|
||||
string s = state.forceString(*args[1], context, pos);
|
||||
|
|
@ -1910,11 +1958,12 @@ static void prim_match(EvalState& state, const Pos& pos, Value** args,
|
|||
const size_t len = match.size() - 1;
|
||||
state.mkList(v, len);
|
||||
for (size_t i = 0; i < len; ++i) {
|
||||
if (!match[i + 1].matched)
|
||||
if (!match[i + 1].matched) {
|
||||
mkNull(*(v.listElems()[i] = state.allocValue()));
|
||||
else
|
||||
} else {
|
||||
mkString(*(v.listElems()[i] = state.allocValue()),
|
||||
match[i + 1].str().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
} catch (std::regex_error& e) {
|
||||
|
|
@ -1969,11 +2018,12 @@ static void prim_split(EvalState& state, const Pos& pos, Value** args,
|
|||
// Start at 1, beacause the first match is the whole string.
|
||||
state.mkList(*elem, slen);
|
||||
for (size_t si = 0; si < slen; ++si) {
|
||||
if (!match[si + 1].matched)
|
||||
if (!match[si + 1].matched) {
|
||||
mkNull(*(elem->listElems()[si] = state.allocValue()));
|
||||
else
|
||||
} else {
|
||||
mkString(*(elem->listElems()[si] = state.allocValue()),
|
||||
match[si + 1].str().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
// Add a string for non-matched suffix characters.
|
||||
|
|
@ -2023,15 +2073,17 @@ static void prim_replaceStrings(EvalState& state, const Pos& pos, Value** args,
|
|||
Value& v) {
|
||||
state.forceList(*args[0], pos);
|
||||
state.forceList(*args[1], pos);
|
||||
if (args[0]->listSize() != args[1]->listSize())
|
||||
if (args[0]->listSize() != args[1]->listSize()) {
|
||||
throw EvalError(format("'from' and 'to' arguments to 'replaceStrings' have "
|
||||
"different lengths, at %1%") %
|
||||
pos);
|
||||
}
|
||||
|
||||
vector<string> from;
|
||||
from.reserve(args[0]->listSize());
|
||||
for (unsigned int n = 0; n < args[0]->listSize(); ++n)
|
||||
for (unsigned int n = 0; n < args[0]->listSize(); ++n) {
|
||||
from.push_back(state.forceString(*args[0]->listElems()[n], pos));
|
||||
}
|
||||
|
||||
vector<std::pair<string, PathSet>> to;
|
||||
to.reserve(args[1]->listSize());
|
||||
|
|
@ -2051,7 +2103,7 @@ static void prim_replaceStrings(EvalState& state, const Pos& pos, Value** args,
|
|||
bool found = false;
|
||||
auto i = from.begin();
|
||||
auto j = to.begin();
|
||||
for (; i != from.end(); ++i, ++j)
|
||||
for (; i != from.end(); ++i, ++j) {
|
||||
if (s.compare(p, i->size(), *i) == 0) {
|
||||
found = true;
|
||||
res += j->first;
|
||||
|
|
@ -2069,6 +2121,7 @@ static void prim_replaceStrings(EvalState& state, const Pos& pos, Value** args,
|
|||
j->second.clear();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
if (p < s.size()) {
|
||||
res += s[p];
|
||||
|
|
@ -2139,20 +2192,22 @@ void fetch(EvalState& state, const Pos& pos, Value** args, Value& v,
|
|||
|
||||
for (auto& attr : *args[0]->attrs) {
|
||||
string n(attr.name);
|
||||
if (n == "url")
|
||||
if (n == "url") {
|
||||
request.uri = state.forceStringNoCtx(*attr.value, *attr.pos);
|
||||
else if (n == "sha256")
|
||||
} else if (n == "sha256") {
|
||||
request.expectedHash =
|
||||
Hash(state.forceStringNoCtx(*attr.value, *attr.pos), htSHA256);
|
||||
else if (n == "name")
|
||||
} else if (n == "name") {
|
||||
request.name = state.forceStringNoCtx(*attr.value, *attr.pos);
|
||||
else
|
||||
} else {
|
||||
throw EvalError(format("unsupported argument '%1%' to '%2%', at %3%") %
|
||||
attr.name % who % attr.pos);
|
||||
}
|
||||
}
|
||||
|
||||
if (request.uri.empty())
|
||||
if (request.uri.empty()) {
|
||||
throw EvalError(format("'url' argument required, at %1%") % pos);
|
||||
}
|
||||
|
||||
} else {
|
||||
request.uri = state.forceStringNoCtx(*args[0], pos);
|
||||
|
|
@ -2160,9 +2215,10 @@ void fetch(EvalState& state, const Pos& pos, Value** args, Value& v,
|
|||
|
||||
state.checkURI(request.uri);
|
||||
|
||||
if (evalSettings.pureEval && !request.expectedHash)
|
||||
if (evalSettings.pureEval && !request.expectedHash) {
|
||||
throw Error("in pure evaluation mode, '%s' requires a 'sha256' argument",
|
||||
who);
|
||||
}
|
||||
|
||||
auto res = getDownloader()->downloadCached(state.store, request);
|
||||
|
||||
|
|
@ -2282,10 +2338,11 @@ void EvalState::createBaseEnv() {
|
|||
|
||||
// Paths
|
||||
addPrimOp("__toPath", 1, prim_toPath);
|
||||
if (evalSettings.pureEval)
|
||||
if (evalSettings.pureEval) {
|
||||
addPurityError("__storePath");
|
||||
else
|
||||
} else {
|
||||
addPrimOp("__storePath", 1, prim_storePath);
|
||||
}
|
||||
addPrimOp("__pathExists", 1, prim_pathExists);
|
||||
addPrimOp("baseNameOf", 1, prim_baseNameOf);
|
||||
addPrimOp("dirOf", 1, prim_dirOf);
|
||||
|
|
@ -2387,9 +2444,11 @@ void EvalState::createBaseEnv() {
|
|||
}
|
||||
addConstant("__nixPath", v);
|
||||
|
||||
if (RegisterPrimOp::primOps)
|
||||
for (auto& primOp : *RegisterPrimOp::primOps)
|
||||
if (RegisterPrimOp::primOps) {
|
||||
for (auto& primOp : *RegisterPrimOp::primOps) {
|
||||
addPrimOp(std::get<0>(primOp), std::get<1>(primOp), std::get<2>(primOp));
|
||||
}
|
||||
}
|
||||
|
||||
/* Now that we've added all primops, sort the `builtins' set,
|
||||
because attribute lookups expect it to be sorted. */
|
||||
|
|
|
|||
3
third_party/nix/src/libexpr/value-to-json.cc
vendored
3
third_party/nix/src/libexpr/value-to-json.cc
vendored
|
|
@ -58,8 +58,9 @@ void printValueAsJSON(EvalState& state, bool strict, Value& v,
|
|||
auto placeholder(obj.placeholder(j));
|
||||
printValueAsJSON(state, strict, *a.value, placeholder, context);
|
||||
}
|
||||
} else
|
||||
} else {
|
||||
printValueAsJSON(state, strict, *i->value, out, context);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
|||
9
third_party/nix/src/libexpr/value-to-xml.cc
vendored
9
third_party/nix/src/libexpr/value-to-xml.cc
vendored
|
|
@ -94,8 +94,9 @@ static void printValueAsXML(EvalState& state, bool strict, bool location,
|
|||
if (strict) {
|
||||
state.forceValue(*a->value);
|
||||
}
|
||||
if (a->value->type == tString)
|
||||
if (a->value->type == tString) {
|
||||
xmlAttrs["drvPath"] = drvPath = a->value->string.s;
|
||||
}
|
||||
}
|
||||
|
||||
a = v.attrs->find(state.sOutPath);
|
||||
|
|
@ -103,8 +104,9 @@ static void printValueAsXML(EvalState& state, bool strict, bool location,
|
|||
if (strict) {
|
||||
state.forceValue(*a->value);
|
||||
}
|
||||
if (a->value->type == tString)
|
||||
if (a->value->type == tString) {
|
||||
xmlAttrs["outPath"] = a->value->string.s;
|
||||
}
|
||||
}
|
||||
|
||||
XMLOpenElement _(doc, "derivation", xmlAttrs);
|
||||
|
|
@ -112,8 +114,9 @@ static void printValueAsXML(EvalState& state, bool strict, bool location,
|
|||
if (drvPath != "" && drvsSeen.find(drvPath) == drvsSeen.end()) {
|
||||
drvsSeen.insert(drvPath);
|
||||
showAttrs(state, strict, location, *v.attrs, doc, context, drvsSeen);
|
||||
} else
|
||||
} else {
|
||||
doc.writeEmptyElement("repeated");
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue