diff --git a/lix/legacy/nix-env.cc b/lix/legacy/nix-env.cc index 6c5be67a6..477b7a156 100644 --- a/lix/legacy/nix-env.cc +++ b/lix/legacy/nix-env.cc @@ -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]; diff --git a/lix/legacy/user-env.cc b/lix/legacy/user-env.cc index ed98a32e6..5466244bb 100644 --- a/lix/legacy/user-env.cc +++ b/lix/legacy/user-env.cc @@ -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. */ diff --git a/lix/libexpr/attr-path.cc b/lix/libexpr/attr-path.cc index fda4bb034..a255e701a 100644 --- a/lix/libexpr/attr-path.cc +++ b/lix/libexpr/attr-path.cc @@ -111,8 +111,8 @@ std::pair 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 attrNames; for (auto & attr : *v->attrs) attrNames.emplace(state.ctx.symbols[attr.name]); diff --git a/lix/libexpr/attr-set.hh b/lix/libexpr/attr-set.hh index f1c556a4d..3b3117bb7 100644 --- a/lix/libexpr/attr-set.hh +++ b/lix/libexpr/attr-set.hh @@ -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); diff --git a/lix/libexpr/eval.cc b/lix/libexpr/eval.cc index 1cb396779..22b575d6b 100644 --- a/lix/libexpr/eval.cc +++ b/lix/libexpr/eval.cc @@ -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("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( + "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(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 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( "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; diff --git a/lix/libexpr/get-drvs.cc b/lix/libexpr/get-drvs.cc index 3465c8b58..79fc3745f 100644 --- a/lix/libexpr/get-drvs.cc +++ b/lix/libexpr/get-drvs.cc @@ -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("derivation name missing").debugThrow(); + auto i = attrs->get(state.ctx.s.name); + if (!i) { + state.ctx.errors.make("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 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 diff --git a/lix/libexpr/primops.cc b/lix/libexpr/primops.cc index dd9a0f15d..34c980bdb 100644 --- a/lix/libexpr/primops.cc +++ b/lix/libexpr/primops.cc @@ -486,14 +486,11 @@ using UnsafeValueList = std::list>; using UnsafeValueList = std::list; #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("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 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); diff --git a/lix/libexpr/primops/context.cc b/lix/libexpr/primops/context.cc index 746e3a108..12b26777f 100644 --- a/lix/libexpr/primops/context.cc +++ b/lix/libexpr/primops/context.cc @@ -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( "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( "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 }, diff --git a/lix/libexpr/print.cc b/lix/libexpr/print.cc index 20eaf03f4..6b34405f1 100644 --- a/lix/libexpr/print.cc +++ b/lix/libexpr/print.cc @@ -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; diff --git a/lix/libexpr/value-to-json.cc b/lix/libexpr/value-to-json.cc index a2af9a9b6..a12f44693 100644 --- a/lix/libexpr/value-to-json.cc +++ b/lix/libexpr/value-to-json.cc @@ -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; } diff --git a/lix/libexpr/value-to-xml.cc b/lix/libexpr/value-to-xml.cc index 4f313f23a..421998b56 100644 --- a/lix/libexpr/value-to-xml.cc +++ b/lix/libexpr/value-to-xml.cc @@ -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(); diff --git a/lix/nix/prefetch.cc b/lix/nix/prefetch.cc index f8a365234..6eb2505ff 100644 --- a/lix/nix/prefetch.cc +++ b/lix/nix/prefetch.cc @@ -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)