libexpr: replace Bindings::find by Bindings::get
In preparations for a new representation of bindings that will make it impossible to write an efficient `Bindings::find`. Change-Id: I4e5a25b8d37d01b5728f7fe43978ceda2ab1b9b6 Signed-off-by: Raito Bezarius <raito@lix.systems> Co-authored-by: Sergei Zimmerman <sergei@zimmerman.foo>
This commit is contained in:
co-authored by
Sergei Zimmerman
parent
257e910247
commit
a20a83b0a7
@@ -1299,7 +1299,7 @@ static void opQuery(Globals & globals, Strings opFlags, Strings opArgs)
|
||||
XMLOpenElement m(xml, "meta", attrs2);
|
||||
Bindings & attrs = *v->attrs;
|
||||
for (auto &i : attrs) {
|
||||
const Attr & a(*attrs.find(i.name));
|
||||
const Attr & a(*attrs.get(i.name));
|
||||
if(a.value->type() != nString) continue;
|
||||
XMLAttrs attrs3;
|
||||
attrs3["type"] = globals.state->symbols[i.name];
|
||||
|
||||
@@ -114,9 +114,9 @@ bool createUserEnv(EvalState & state, DrvInfos & elems,
|
||||
debug("evaluating user environment builder");
|
||||
state.forceValue(topLevel, noPos);
|
||||
NixStringContext context;
|
||||
const Attr & aDrvPath(*topLevel.attrs->find(state.ctx.s.drvPath));
|
||||
const Attr & aDrvPath(*topLevel.attrs->get(state.ctx.s.drvPath));
|
||||
auto topLevelDrv = state.coerceToStorePath(aDrvPath.pos, *aDrvPath.value, context, "");
|
||||
const Attr & aOutPath(*topLevel.attrs->find(state.ctx.s.outPath));
|
||||
const Attr & aOutPath(*topLevel.attrs->get(state.ctx.s.outPath));
|
||||
auto topLevelOut = state.coerceToStorePath(aOutPath.pos, *aOutPath.value, context, "");
|
||||
|
||||
/* Realise the resulting store expression. */
|
||||
|
||||
@@ -111,8 +111,8 @@ std::pair<Value *, PosIdx> findAlongAttrPath(EvalState & state, const std::strin
|
||||
.debugThrow();
|
||||
}
|
||||
|
||||
Bindings::iterator a = v->attrs->find(state.ctx.symbols.create(attr));
|
||||
if (a == v->attrs->end()) {
|
||||
auto a = v->attrs->get(state.ctx.symbols.create(attr));
|
||||
if (!a) {
|
||||
std::set<std::string> attrNames;
|
||||
for (auto & attr : *v->attrs)
|
||||
attrNames.emplace(state.ctx.symbols[attr.name]);
|
||||
|
||||
@@ -71,15 +71,7 @@ public:
|
||||
attrs[size_++] = attr;
|
||||
}
|
||||
|
||||
iterator find(Symbol name)
|
||||
{
|
||||
Attr key(name, 0);
|
||||
iterator i = std::lower_bound(begin(), end(), key);
|
||||
if (i != end() && i->name == name) return i;
|
||||
return end();
|
||||
}
|
||||
|
||||
Attr * get(Symbol name)
|
||||
const Attr * get(Symbol name)
|
||||
{
|
||||
Attr key(name, 0);
|
||||
iterator i = std::lower_bound(begin(), end(), key);
|
||||
|
||||
+36
-26
@@ -592,7 +592,7 @@ Value * EvalBuiltins::addPrimOp(PrimOp && primOp)
|
||||
|
||||
Value & EvalBuiltins::get(const std::string & name)
|
||||
{
|
||||
return *env.values[0]->attrs->find(symbols.create(name))->value;
|
||||
return *env.values[0]->attrs->get(symbols.create(name))->value;
|
||||
}
|
||||
|
||||
|
||||
@@ -833,8 +833,8 @@ inline Value * EvalState::lookupVar(Env * env, const ExprVar & var, bool noEval)
|
||||
auto * fromWith = var.fromWith;
|
||||
while (1) {
|
||||
forceAttrs(*env->values[0], fromWith->pos, "while evaluating the first subexpression of a with expression");
|
||||
Bindings::iterator j = env->values[0]->attrs->find(var.name);
|
||||
if (j != env->values[0]->attrs->end()) {
|
||||
auto j = env->values[0]->attrs->get(var.name);
|
||||
if (j) {
|
||||
if (ctx.stats.countCalls) ctx.stats.attrSelects[j->pos]++;
|
||||
return j->value;
|
||||
}
|
||||
@@ -1154,9 +1154,18 @@ void ExprSet::eval(EvalState & state, Env & env, Value & v)
|
||||
continue;
|
||||
state.forceStringNoCtx(nameVal, i.pos, "while evaluating the name of a dynamic attribute");
|
||||
auto nameSym = state.ctx.symbols.create(nameVal.str());
|
||||
Bindings::iterator j = v.attrs->find(nameSym);
|
||||
if (j != v.attrs->end())
|
||||
state.ctx.errors.make<EvalError>("dynamic attribute '%1%' already defined at %2%", state.ctx.symbols[nameSym], state.ctx.positions[j->pos]).atPos(i.pos).withFrame(env, *this).debugThrow();
|
||||
auto j = v.attrs->get(nameSym);
|
||||
if (j) {
|
||||
state.ctx.errors
|
||||
.make<EvalError>(
|
||||
"dynamic attribute '%1%' already defined at %2%",
|
||||
state.ctx.symbols[nameSym],
|
||||
state.ctx.positions[j->pos]
|
||||
)
|
||||
.atPos(i.pos)
|
||||
.withFrame(env, *this)
|
||||
.debugThrow();
|
||||
}
|
||||
|
||||
i.valueExpr->setName(nameSym);
|
||||
/* Keep sorted order so find can catch duplicates */
|
||||
@@ -1315,8 +1324,8 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v)
|
||||
|
||||
// Now that we know this is actually an attrset, try to find an attr
|
||||
// with the selected name.
|
||||
Bindings::iterator attrIt = vCurrent->attrs->find(name);
|
||||
if (attrIt == vCurrent->attrs->end()) {
|
||||
auto attrIt = vCurrent->attrs->get(name);
|
||||
if (!attrIt) {
|
||||
|
||||
// If we have an `or` provided default, then we'll use that.
|
||||
if (def != nullptr) {
|
||||
@@ -1368,11 +1377,9 @@ void ExprOpHasAttr::eval(EvalState & state, Env & env, Value & v)
|
||||
|
||||
for (auto & i : attrPath) {
|
||||
state.forceValue(*vAttrs, getPos());
|
||||
Bindings::iterator j;
|
||||
const Attr * j;
|
||||
auto name = getName(i, state, env);
|
||||
if (vAttrs->type() != nAttrs ||
|
||||
(j = vAttrs->attrs->find(name)) == vAttrs->attrs->end())
|
||||
{
|
||||
if (vAttrs->type() != nAttrs || (j = vAttrs->attrs->get(name)) == nullptr) {
|
||||
v.mkBool(false);
|
||||
return;
|
||||
} else {
|
||||
@@ -1740,8 +1747,8 @@ void EvalState::autoCallFunction(Bindings & args, Value & fun, Value & res, PosI
|
||||
forceValue(fun, pos);
|
||||
|
||||
if (fun.type() == nAttrs) {
|
||||
auto found = fun.attrs->find(ctx.s.functor);
|
||||
if (found != fun.attrs->end()) {
|
||||
auto found = fun.attrs->get(ctx.s.functor);
|
||||
if (found) {
|
||||
Value * v = ctx.mem.allocValue();
|
||||
callFunction(*found->value, fun, *v, pos);
|
||||
forceValue(*v, pos);
|
||||
@@ -1770,8 +1777,8 @@ void EvalState::autoCallFunction(Bindings & args, Value & fun, Value & res, PosI
|
||||
} else {
|
||||
// Otherwise, only pass the arguments that the function accepts
|
||||
for (auto & i : pattern->formals) {
|
||||
Bindings::iterator j = args.find(i.name);
|
||||
if (j != args.end()) {
|
||||
auto j = args.get(i.name);
|
||||
if (j) {
|
||||
attrs.insert(*j);
|
||||
} else if (!i.def) {
|
||||
ctx.errors.make<MissingArgumentError>(R"(cannot evaluate a function that has an argument without a value ('%1%')
|
||||
@@ -2184,7 +2191,7 @@ bool EvalState::forceBool(Value & v, const PosIdx pos, std::string_view errorCtx
|
||||
|
||||
bool EvalState::isFunctor(Value & fun)
|
||||
{
|
||||
return fun.type() == nAttrs && fun.attrs->find(ctx.s.functor) != fun.attrs->end();
|
||||
return fun.type() == nAttrs && fun.attrs->get(ctx.s.functor);
|
||||
}
|
||||
|
||||
|
||||
@@ -2259,8 +2266,10 @@ std::string_view EvalState::forceStringNoCtx(Value & v, const PosIdx pos, std::s
|
||||
bool EvalState::isDerivation(Value & v)
|
||||
{
|
||||
if (v.type() != nAttrs) return false;
|
||||
Bindings::iterator i = v.attrs->find(ctx.s.type);
|
||||
if (i == v.attrs->end()) return false;
|
||||
auto i = v.attrs->get(ctx.s.type);
|
||||
if (!i) {
|
||||
return false;
|
||||
}
|
||||
forceValue(*i->value, i->pos);
|
||||
if (i->value->type() != nString) return false;
|
||||
return i->value->str() == "derivation";
|
||||
@@ -2270,8 +2279,8 @@ bool EvalState::isDerivation(Value & v)
|
||||
std::optional<std::string> EvalState::tryAttrsToString(const PosIdx pos, Value & v,
|
||||
NixStringContext & context, StringCoercionMode mode, bool copyToStore)
|
||||
{
|
||||
auto i = v.attrs->find(ctx.s.toString);
|
||||
if (i != v.attrs->end()) {
|
||||
auto i = v.attrs->get(ctx.s.toString);
|
||||
if (i) {
|
||||
Value v1;
|
||||
try {
|
||||
callFunction(*i->value, v, v1, i->pos);
|
||||
@@ -2319,8 +2328,8 @@ BackedStringView EvalState::coerceToString(
|
||||
auto maybeString = tryAttrsToString(pos, v, context, mode, copyToStore);
|
||||
if (maybeString)
|
||||
return std::move(*maybeString);
|
||||
auto i = v.attrs->find(ctx.s.outPath);
|
||||
if (i == v.attrs->end()) {
|
||||
auto i = v.attrs->get(ctx.s.outPath);
|
||||
if (!i) {
|
||||
ctx.errors.make<TypeError>(
|
||||
"cannot coerce %1% to a string: %2%",
|
||||
showType(v),
|
||||
@@ -2537,10 +2546,11 @@ bool EvalState::eqValues(Value & v1, Value & v2, const PosIdx pos, std::string_v
|
||||
/* If both sets denote a derivation (type = "derivation"),
|
||||
then compare their outPaths. */
|
||||
if (isDerivation(v1) && isDerivation(v2)) {
|
||||
Bindings::iterator i = v1.attrs->find(ctx.s.outPath);
|
||||
Bindings::iterator j = v2.attrs->find(ctx.s.outPath);
|
||||
if (i != v1.attrs->end() && j != v2.attrs->end())
|
||||
auto i = v1.attrs->get(ctx.s.outPath);
|
||||
auto j = v2.attrs->get(ctx.s.outPath);
|
||||
if (i && j) {
|
||||
return eqValues(*i->value, *j->value, pos, errorCtx);
|
||||
}
|
||||
}
|
||||
|
||||
if (v1.attrs->size() != v2.attrs->size()) return false;
|
||||
|
||||
+44
-20
@@ -64,8 +64,10 @@ try {
|
||||
std::string DrvInfo::queryName(EvalState & state)
|
||||
{
|
||||
if (name == "" && attrs) {
|
||||
auto i = attrs->find(state.ctx.s.name);
|
||||
if (i == attrs->end()) state.ctx.errors.make<TypeError>("derivation name missing").debugThrow();
|
||||
auto i = attrs->get(state.ctx.s.name);
|
||||
if (!i) {
|
||||
state.ctx.errors.make<TypeError>("derivation name missing").debugThrow();
|
||||
}
|
||||
name = state.forceStringNoCtx(*i->value, noPos, "while evaluating the 'name' attribute of a derivation");
|
||||
}
|
||||
return name;
|
||||
@@ -75,8 +77,12 @@ std::string DrvInfo::queryName(EvalState & state)
|
||||
std::string DrvInfo::querySystem(EvalState & state)
|
||||
{
|
||||
if (system == "" && attrs) {
|
||||
auto i = attrs->find(state.ctx.s.system);
|
||||
system = i == attrs->end() ? "unknown" : state.forceStringNoCtx(*i->value, i->pos, "while evaluating the 'system' attribute of a derivation");
|
||||
auto i = attrs->get(state.ctx.s.system);
|
||||
system = !i
|
||||
? "unknown"
|
||||
: state.forceStringNoCtx(
|
||||
*i->value, i->pos, "while evaluating the 'system' attribute of a derivation"
|
||||
);
|
||||
}
|
||||
return system;
|
||||
}
|
||||
@@ -85,12 +91,18 @@ std::string DrvInfo::querySystem(EvalState & state)
|
||||
std::optional<StorePath> DrvInfo::queryDrvPath(EvalState & state)
|
||||
{
|
||||
if (!drvPath && attrs) {
|
||||
Bindings::iterator i = attrs->find(state.ctx.s.drvPath);
|
||||
auto i = attrs->get(state.ctx.s.drvPath);
|
||||
NixStringContext context;
|
||||
if (i == attrs->end())
|
||||
if (!i) {
|
||||
drvPath = {std::nullopt};
|
||||
else
|
||||
drvPath = {state.coerceToStorePath(i->pos, *i->value, context, "while evaluating the 'drvPath' attribute of a derivation")};
|
||||
} else {
|
||||
drvPath = {state.coerceToStorePath(
|
||||
i->pos,
|
||||
*i->value,
|
||||
context,
|
||||
"while evaluating the 'drvPath' attribute of a derivation"
|
||||
)};
|
||||
}
|
||||
}
|
||||
return drvPath.value_or(std::nullopt);
|
||||
}
|
||||
@@ -107,10 +119,13 @@ StorePath DrvInfo::requireDrvPath(EvalState & state)
|
||||
StorePath DrvInfo::queryOutPath(EvalState & state)
|
||||
{
|
||||
if (!outPath && attrs) {
|
||||
Bindings::iterator i = attrs->find(state.ctx.s.outPath);
|
||||
auto i = attrs->get(state.ctx.s.outPath);
|
||||
NixStringContext context;
|
||||
if (i != attrs->end())
|
||||
outPath = state.coerceToStorePath(i->pos, *i->value, context, "while evaluating the output path of a derivation");
|
||||
if (i) {
|
||||
outPath = state.coerceToStorePath(
|
||||
i->pos, *i->value, context, "while evaluating the output path of a derivation"
|
||||
);
|
||||
}
|
||||
}
|
||||
if (!outPath)
|
||||
throw UnimplementedError("CA derivations are not yet supported");
|
||||
@@ -257,8 +272,11 @@ DrvInfo::Outputs DrvInfo::queryOutputs(EvalState & state, bool withPaths, bool o
|
||||
std::string DrvInfo::queryOutputName(EvalState & state)
|
||||
{
|
||||
if (outputName == "" && attrs) {
|
||||
Bindings::iterator i = attrs->find(state.ctx.s.outputName);
|
||||
outputName = i != attrs->end() ? state.forceStringNoCtx(*i->value, noPos, "while evaluating the output name of a derivation") : "";
|
||||
auto i = attrs->get(state.ctx.s.outputName);
|
||||
outputName = i ? state.forceStringNoCtx(
|
||||
*i->value, noPos, "while evaluating the output name of a derivation"
|
||||
)
|
||||
: "";
|
||||
}
|
||||
return outputName;
|
||||
}
|
||||
@@ -268,8 +286,10 @@ Bindings * DrvInfo::getMeta(EvalState & state)
|
||||
{
|
||||
if (meta) return meta;
|
||||
if (!attrs) return 0;
|
||||
Bindings::iterator a = attrs->find(state.ctx.s.meta);
|
||||
if (a == attrs->end()) return 0;
|
||||
auto a = attrs->get(state.ctx.s.meta);
|
||||
if (!a) {
|
||||
return 0;
|
||||
}
|
||||
state.forceAttrs(*a->value, a->pos, "while evaluating the 'meta' attribute of a derivation");
|
||||
meta = a->value->attrs;
|
||||
return meta;
|
||||
@@ -295,8 +315,10 @@ bool DrvInfo::checkMeta(EvalState & state, Value & v)
|
||||
return true;
|
||||
}
|
||||
else if (v.type() == nAttrs) {
|
||||
Bindings::iterator i = v.attrs->find(state.ctx.s.outPath);
|
||||
if (i != v.attrs->end()) return false;
|
||||
auto i = v.attrs->get(state.ctx.s.outPath);
|
||||
if (i) {
|
||||
return false;
|
||||
}
|
||||
for (auto & i : *v.attrs)
|
||||
if (!checkMeta(state, *i.value)) return false;
|
||||
return true;
|
||||
@@ -309,8 +331,10 @@ bool DrvInfo::checkMeta(EvalState & state, Value & v)
|
||||
Value * DrvInfo::queryMeta(EvalState & state, const std::string & name)
|
||||
{
|
||||
if (!getMeta(state)) return 0;
|
||||
Bindings::iterator a = meta->find(state.ctx.symbols.create(name));
|
||||
if (a == meta->end() || !checkMeta(state, *a->value)) return 0;
|
||||
auto a = meta->get(state.ctx.symbols.create(name));
|
||||
if (!a || !checkMeta(state, *a->value)) {
|
||||
return 0;
|
||||
}
|
||||
return a->value;
|
||||
}
|
||||
|
||||
@@ -473,7 +497,7 @@ static void getDerivations(EvalState & state, Value & vIn, PosIdx pos,
|
||||
// FIXME: what the fuck???
|
||||
/* !!! undocumented hackery to support combining channels in
|
||||
nix-env.cc. */
|
||||
bool combineChannels = v.attrs->find(state.ctx.symbols.create("_combineChannels")) != v.attrs->end();
|
||||
bool combineChannels = v.attrs->get(state.ctx.symbols.create("_combineChannels"));
|
||||
|
||||
/* Consider the attributes in sorted order to get more
|
||||
deterministic behaviour in nix-env operations (e.g. when
|
||||
|
||||
+74
-35
@@ -486,14 +486,11 @@ using UnsafeValueList = std::list<Value *, gc_allocator<Value *>>;
|
||||
using UnsafeValueList = std::list<Value *>;
|
||||
#endif
|
||||
|
||||
static Bindings::iterator getAttr(
|
||||
EvalState & state,
|
||||
Symbol attrSym,
|
||||
Bindings * attrSet,
|
||||
std::string_view errorCtx)
|
||||
static const Attr *
|
||||
getAttr(EvalState & state, Symbol attrSym, Bindings * attrSet, std::string_view errorCtx)
|
||||
{
|
||||
Bindings::iterator value = attrSet->find(attrSym);
|
||||
if (value == attrSet->end()) {
|
||||
auto value = attrSet->get(attrSym);
|
||||
if (!value) {
|
||||
state.ctx.errors.make<TypeError>("attribute '%s' missing", state.ctx.symbols[attrSym]).withTrace(noPos, errorCtx).debugThrow();
|
||||
}
|
||||
return value;
|
||||
@@ -504,7 +501,12 @@ static void prim_genericClosure(EvalState & state, Value * * args, Value & v)
|
||||
state.forceAttrs(*args[0], noPos, "while evaluating the first argument passed to builtins.genericClosure");
|
||||
|
||||
/* Get the start set. */
|
||||
Bindings::iterator startSet = getAttr(state, state.ctx.s.startSet, args[0]->attrs, "in the attrset passed as argument to builtins.genericClosure");
|
||||
auto startSet = getAttr(
|
||||
state,
|
||||
state.ctx.s.startSet,
|
||||
args[0]->attrs,
|
||||
"in the attrset passed as argument to builtins.genericClosure"
|
||||
);
|
||||
|
||||
state.forceList(*startSet->value, noPos, "while evaluating the 'startSet' attribute passed as argument to builtins.genericClosure");
|
||||
|
||||
@@ -518,7 +520,12 @@ static void prim_genericClosure(EvalState & state, Value * * args, Value & v)
|
||||
}
|
||||
|
||||
/* Get the operator. */
|
||||
Bindings::iterator op = getAttr(state, state.ctx.s.operator_, args[0]->attrs, "in the attrset passed as argument to builtins.genericClosure");
|
||||
auto op = getAttr(
|
||||
state,
|
||||
state.ctx.s.operator_,
|
||||
args[0]->attrs,
|
||||
"in the attrset passed as argument to builtins.genericClosure"
|
||||
);
|
||||
state.forceFunction(*op->value, noPos, "while evaluating the 'operator' attribute passed as argument to builtins.genericClosure");
|
||||
|
||||
/* Construct the closure by applying the operator to elements of
|
||||
@@ -535,7 +542,12 @@ static void prim_genericClosure(EvalState & state, Value * * args, Value & v)
|
||||
|
||||
state.forceAttrs(*e, noPos, "while evaluating one of the elements generated by (or initially passed to) builtins.genericClosure");
|
||||
|
||||
Bindings::iterator key = getAttr(state, state.ctx.s.key, e->attrs, "in one of the attrsets generated by (or initially passed to) builtins.genericClosure");
|
||||
auto key = getAttr(
|
||||
state,
|
||||
state.ctx.s.key,
|
||||
e->attrs,
|
||||
"in one of the attrsets generated by (or initially passed to) builtins.genericClosure"
|
||||
);
|
||||
state.forceValue(*key->value, noPos);
|
||||
|
||||
if (!doneKeys.insert(key->value).second) continue;
|
||||
@@ -738,7 +750,12 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v)
|
||||
Bindings * attrs = args[0]->attrs;
|
||||
|
||||
/* Figure out the name first (for stack backtraces). */
|
||||
Bindings::iterator nameAttr = getAttr(state, state.ctx.s.name, attrs, "in the attrset passed as argument to builtins.derivationStrict");
|
||||
auto nameAttr = getAttr(
|
||||
state,
|
||||
state.ctx.s.name,
|
||||
attrs,
|
||||
"in the attrset passed as argument to builtins.derivationStrict"
|
||||
);
|
||||
|
||||
std::string drvName;
|
||||
try {
|
||||
@@ -782,18 +799,29 @@ drvName, Bindings * attrs, Value & v)
|
||||
{
|
||||
/* Check whether attributes should be passed as a JSON file. */
|
||||
std::optional<JSON> jsonObject;
|
||||
auto attr = attrs->find(state.ctx.s.structuredAttrs);
|
||||
if (attr != attrs->end() &&
|
||||
state.forceBool(*attr->value, attr->pos,
|
||||
"while evaluating the `__structuredAttrs` "
|
||||
"attribute passed to builtins.derivationStrict"))
|
||||
auto attr = attrs->get(state.ctx.s.structuredAttrs);
|
||||
if (attr
|
||||
&& state.forceBool(
|
||||
*attr->value,
|
||||
attr->pos,
|
||||
"while evaluating the `__structuredAttrs` "
|
||||
"attribute passed to builtins.derivationStrict"
|
||||
))
|
||||
{
|
||||
jsonObject = JSON::object();
|
||||
}
|
||||
|
||||
/* Check whether null attributes should be ignored. */
|
||||
bool ignoreNulls = false;
|
||||
attr = attrs->find(state.ctx.s.ignoreNulls);
|
||||
if (attr != attrs->end())
|
||||
ignoreNulls = state.forceBool(*attr->value, attr->pos, "while evaluating the `__ignoreNulls` attribute " "passed to builtins.derivationStrict");
|
||||
attr = attrs->get(state.ctx.s.ignoreNulls);
|
||||
if (attr) {
|
||||
ignoreNulls = state.forceBool(
|
||||
*attr->value,
|
||||
attr->pos,
|
||||
"while evaluating the `__ignoreNulls` attribute "
|
||||
"passed to builtins.derivationStrict"
|
||||
);
|
||||
}
|
||||
|
||||
/* Build the derivation expression by processing the attributes. */
|
||||
Derivation drv;
|
||||
@@ -1277,9 +1305,15 @@ static void prim_findFile(EvalState & state, Value * * args, Value & v)
|
||||
state.forceAttrs(*v2, noPos, "while evaluating an element of the list passed to builtins.findFile");
|
||||
|
||||
std::string prefix;
|
||||
Bindings::iterator i = v2->attrs->find(state.ctx.s.prefix);
|
||||
if (i != v2->attrs->end())
|
||||
prefix = state.forceStringNoCtx(*i->value, noPos, "while evaluating the `prefix` attribute of an element of the list passed to builtins.findFile");
|
||||
auto i = v2->attrs->get(state.ctx.s.prefix);
|
||||
if (i) {
|
||||
prefix = state.forceStringNoCtx(
|
||||
*i->value,
|
||||
noPos,
|
||||
"while evaluating the `prefix` attribute of an element of the list passed to "
|
||||
"builtins.findFile"
|
||||
);
|
||||
}
|
||||
|
||||
i = getAttr(state, state.ctx.s.path, v2->attrs, "in an element of the __nixPath");
|
||||
|
||||
@@ -1650,7 +1684,7 @@ void prim_getAttr(EvalState & state, Value * * args, Value & v)
|
||||
{
|
||||
auto attr = state.forceStringNoCtx(*args[0], noPos, "while evaluating the first argument passed to builtins.getAttr");
|
||||
state.forceAttrs(*args[1], noPos, "while evaluating the second argument passed to builtins.getAttr");
|
||||
Bindings::iterator i = getAttr(
|
||||
auto i = getAttr(
|
||||
state,
|
||||
state.ctx.symbols.create(attr),
|
||||
args[1]->attrs,
|
||||
@@ -1667,11 +1701,12 @@ static void prim_unsafeGetAttrPos(EvalState & state, Value * * args, Value & v)
|
||||
{
|
||||
auto attr = state.forceStringNoCtx(*args[0], noPos, "while evaluating the first argument passed to builtins.unsafeGetAttrPos");
|
||||
state.forceAttrs(*args[1], noPos, "while evaluating the second argument passed to builtins.unsafeGetAttrPos");
|
||||
Bindings::iterator i = args[1]->attrs->find(state.ctx.symbols.create(attr));
|
||||
if (i == args[1]->attrs->end())
|
||||
auto i = args[1]->attrs->get(state.ctx.symbols.create(attr));
|
||||
if (!i) {
|
||||
v.mkNull();
|
||||
else
|
||||
} else {
|
||||
state.mkPos(v, i->pos);
|
||||
}
|
||||
}
|
||||
|
||||
// access to exact position information (ie, line and colum numbers) is deferred
|
||||
@@ -1727,7 +1762,7 @@ static void prim_hasAttr(EvalState & state, Value * * args, Value & v)
|
||||
{
|
||||
auto attr = state.forceStringNoCtx(*args[0], noPos, "while evaluating the first argument passed to builtins.hasAttr");
|
||||
state.forceAttrs(*args[1], noPos, "while evaluating the second argument passed to builtins.hasAttr");
|
||||
v.mkBool(args[1]->attrs->find(state.ctx.symbols.create(attr)) != args[1]->attrs->end());
|
||||
v.mkBool(args[1]->attrs->get(state.ctx.symbols.create(attr)));
|
||||
}
|
||||
|
||||
/* Determine whether the argument is a set. */
|
||||
@@ -1781,13 +1816,14 @@ static void prim_listToAttrs(EvalState & state, Value * * args, Value & v)
|
||||
for (auto v2 : args[0]->listItems()) {
|
||||
state.forceAttrs(*v2, noPos, "while evaluating an element of the list passed to builtins.listToAttrs");
|
||||
|
||||
Bindings::iterator j = getAttr(state, state.ctx.s.name, v2->attrs, "in a {name=...; value=...;} pair");
|
||||
auto j = getAttr(state, state.ctx.s.name, v2->attrs, "in a {name=...; value=...;} pair");
|
||||
|
||||
auto name = state.forceStringNoCtx(*j->value, j->pos, "while evaluating the `name` attribute of an element of the list passed to builtins.listToAttrs");
|
||||
|
||||
auto sym = state.ctx.symbols.create(name);
|
||||
if (seen.insert(sym).second) {
|
||||
Bindings::iterator j2 = getAttr(state, state.ctx.s.value, v2->attrs, "in a {name=...; value=...;} pair");
|
||||
auto j2 =
|
||||
getAttr(state, state.ctx.s.value, v2->attrs, "in a {name=...; value=...;} pair");
|
||||
attrs.insert(sym, j2->value, j2->pos);
|
||||
}
|
||||
}
|
||||
@@ -1845,16 +1881,18 @@ static void prim_intersectAttrs(EvalState & state, Value * * args, Value & v)
|
||||
|
||||
if (left.size() < right.size()) {
|
||||
for (auto & l : left) {
|
||||
Bindings::iterator r = right.find(l.name);
|
||||
if (r != right.end())
|
||||
auto r = right.get(l.name);
|
||||
if (r) {
|
||||
attrs.insert(*r);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (auto & r : right) {
|
||||
Bindings::iterator l = left.find(r.name);
|
||||
if (l != left.end())
|
||||
auto l = left.get(r.name);
|
||||
if (l) {
|
||||
attrs.insert(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1871,9 +1909,10 @@ static void prim_catAttrs(EvalState & state, Value * * args, Value & v)
|
||||
|
||||
for (auto v2 : args[1]->listItems()) {
|
||||
state.forceAttrs(*v2, noPos, "while evaluating an element in the list passed as second argument to builtins.catAttrs");
|
||||
Bindings::iterator i = v2->attrs->find(attrName);
|
||||
if (i != v2->attrs->end())
|
||||
auto i = v2->attrs->get(attrName);
|
||||
if (i) {
|
||||
res[found++] = i->value;
|
||||
}
|
||||
}
|
||||
|
||||
v = state.ctx.mem.newList(found);
|
||||
|
||||
@@ -182,17 +182,26 @@ static void prim_appendContext(EvalState & state, Value * * args, Value & v)
|
||||
if (!settings.readOnlyMode)
|
||||
state.aio.blockOn(state.ctx.store->ensurePath(namePath));
|
||||
state.forceAttrs(*i.value, i.pos, "while evaluating the value of a string context");
|
||||
auto iter = i.value->attrs->find(state.ctx.s.path);
|
||||
if (iter != i.value->attrs->end()) {
|
||||
if (state.forceBool(*iter->value, iter->pos, "while evaluating the `path` attribute of a string context"))
|
||||
context.emplace(NixStringContextElem::Opaque {
|
||||
auto a = i.value->attrs->get(state.ctx.s.path);
|
||||
if (a) {
|
||||
if (state.forceBool(
|
||||
*a->value, a->pos, "while evaluating the `path` attribute of a string context"
|
||||
))
|
||||
{
|
||||
context.emplace(NixStringContextElem::Opaque{
|
||||
.path = namePath,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
iter = i.value->attrs->find(sAllOutputs);
|
||||
if (iter != i.value->attrs->end()) {
|
||||
if (state.forceBool(*iter->value, iter->pos, "while evaluating the `allOutputs` attribute of a string context")) {
|
||||
a = i.value->attrs->get(sAllOutputs);
|
||||
if (a) {
|
||||
if (state.forceBool(
|
||||
*a->value,
|
||||
a->pos,
|
||||
"while evaluating the `allOutputs` attribute of a string context"
|
||||
))
|
||||
{
|
||||
if (!isDerivation(name)) {
|
||||
state.ctx.errors.make<EvalError>(
|
||||
"tried to add all-outputs context of %s, which is not a derivation, to a string",
|
||||
@@ -205,17 +214,21 @@ static void prim_appendContext(EvalState & state, Value * * args, Value & v)
|
||||
}
|
||||
}
|
||||
|
||||
iter = i.value->attrs->find(state.ctx.s.outputs);
|
||||
if (iter != i.value->attrs->end()) {
|
||||
state.forceList(*iter->value, iter->pos, "while evaluating the `outputs` attribute of a string context");
|
||||
if (iter->value->listSize() && !isDerivation(name)) {
|
||||
a = i.value->attrs->get(state.ctx.s.outputs);
|
||||
if (a) {
|
||||
state.forceList(
|
||||
*a->value, a->pos, "while evaluating the `outputs` attribute of a string context"
|
||||
);
|
||||
if (a->value->listSize() && !isDerivation(name)) {
|
||||
state.ctx.errors.make<EvalError>(
|
||||
"tried to add derivation output context of %s, which is not a derivation, to a string",
|
||||
name
|
||||
).atPos(i.pos).debugThrow();
|
||||
}
|
||||
for (auto elem : iter->value->listItems()) {
|
||||
auto outputName = state.forceStringNoCtx(*elem, iter->pos, "while evaluating an output name within a string context");
|
||||
for (auto elem : a->value->listItems()) {
|
||||
auto outputName = state.forceStringNoCtx(
|
||||
*elem, a->pos, "while evaluating an output name within a string context"
|
||||
);
|
||||
context.emplace(NixStringContextElem::Built {
|
||||
.drvPath = makeConstantStorePath(namePath),
|
||||
.output = std::string { outputName },
|
||||
|
||||
@@ -232,11 +232,14 @@ private:
|
||||
|
||||
void printDerivation(Value & v)
|
||||
{
|
||||
Bindings::iterator i = v.attrs->find(state.ctx.s.drvPath);
|
||||
auto i = v.attrs->get(state.ctx.s.drvPath);
|
||||
NixStringContext context;
|
||||
std::string storePath;
|
||||
if (i != v.attrs->end())
|
||||
storePath = state.ctx.store->printStorePath(state.coerceToStorePath(i->pos, *i->value, context, "while evaluating the drvPath of a derivation"));
|
||||
if (i) {
|
||||
storePath = state.ctx.store->printStorePath(state.coerceToStorePath(
|
||||
i->pos, *i->value, context, "while evaluating the drvPath of a derivation"
|
||||
));
|
||||
}
|
||||
|
||||
if (options.ansiColors)
|
||||
output << ANSI_GREEN;
|
||||
|
||||
@@ -51,14 +51,14 @@ JSON printValueAsJSON(EvalState & state, bool strict,
|
||||
out = *maybeString;
|
||||
break;
|
||||
}
|
||||
auto i = v.attrs->find(state.ctx.s.outPath);
|
||||
if (i == v.attrs->end()) {
|
||||
auto i = v.attrs->get(state.ctx.s.outPath);
|
||||
if (!i) {
|
||||
out = JSON::object();
|
||||
StringSet names;
|
||||
for (auto & j : *v.attrs)
|
||||
names.emplace(state.ctx.symbols[j.name]);
|
||||
for (auto & j : names) {
|
||||
const Attr & a(*v.attrs->find(state.ctx.symbols.create(j)));
|
||||
const Attr & a(*v.attrs->get(state.ctx.symbols.create(j)));
|
||||
try {
|
||||
out[j] = printValueAsJSON(state, strict, *a.value, a.pos, context, copyToStore);
|
||||
} catch (Error & e) {
|
||||
@@ -67,8 +67,9 @@ JSON printValueAsJSON(EvalState & state, bool strict,
|
||||
throw;
|
||||
}
|
||||
}
|
||||
} else
|
||||
} else {
|
||||
return printValueAsJSON(state, strict, *i->value, i->pos, context, copyToStore);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ static void showAttrs(EvalState & state, bool strict, bool location,
|
||||
names.emplace(state.ctx.symbols[i.name]);
|
||||
|
||||
for (auto & i : names) {
|
||||
const Attr & a(*attrs.find(state.ctx.symbols.create(i)));
|
||||
const Attr & a(*attrs.get(state.ctx.symbols.create(i)));
|
||||
|
||||
XMLAttrs xmlAttrs;
|
||||
xmlAttrs["name"] = i;
|
||||
@@ -85,18 +85,18 @@ static void printValueAsXML(EvalState & state, bool strict, bool location,
|
||||
if (state.isDerivation(v)) {
|
||||
XMLAttrs xmlAttrs;
|
||||
|
||||
Bindings::iterator a = v.attrs->find(state.ctx.symbols.create("derivation"));
|
||||
auto a = v.attrs->get(state.ctx.symbols.create("derivation"));
|
||||
|
||||
Path drvPath;
|
||||
a = v.attrs->find(state.ctx.s.drvPath);
|
||||
if (a != v.attrs->end()) {
|
||||
a = v.attrs->get(state.ctx.s.drvPath);
|
||||
if (a) {
|
||||
if (strict) state.forceValue(*a->value, a->pos);
|
||||
if (a->value->type() == nString)
|
||||
xmlAttrs["drvPath"] = drvPath = a->value->str();
|
||||
}
|
||||
|
||||
a = v.attrs->find(state.ctx.s.outPath);
|
||||
if (a != v.attrs->end()) {
|
||||
a = v.attrs->get(state.ctx.s.outPath);
|
||||
if (a) {
|
||||
if (strict) state.forceValue(*a->value, a->pos);
|
||||
if (a->value->type() == nString) {
|
||||
xmlAttrs["outPath"] = a->value->str();
|
||||
|
||||
+3
-2
@@ -35,9 +35,10 @@ std::string resolveMirrorUrl(EvalState & state, const std::string & url)
|
||||
vMirrors);
|
||||
state.forceAttrs(vMirrors, noPos, "while evaluating the set of all mirrors");
|
||||
|
||||
auto mirrorList = vMirrors.attrs->find(state.ctx.symbols.create(mirrorName));
|
||||
if (mirrorList == vMirrors.attrs->end())
|
||||
auto mirrorList = vMirrors.attrs->get(state.ctx.symbols.create(mirrorName));
|
||||
if (!mirrorList) {
|
||||
throw Error("unknown mirror name '%s'", mirrorName);
|
||||
}
|
||||
state.forceList(*mirrorList->value, noPos, "while evaluating one mirror configuration");
|
||||
|
||||
if (mirrorList->value->listSize() < 1)
|
||||
|
||||
Reference in New Issue
Block a user