fix(3p/nix): Update for usage of new attribute set API
The new attribute set API uses the iterators of the btree_map directly. This requires changes in various files because the internals of libexpr are very entangled. This code runs and compiles, but there is a bug causing empty attribute sets to be assigned incorrectly.
This commit is contained in:
parent
42205f27fc
commit
986a8f6b75
14 changed files with 187 additions and 176 deletions
8
third_party/nix/src/libexpr/attr-set.cc
vendored
8
third_party/nix/src/libexpr/attr-set.cc
vendored
|
@ -34,13 +34,9 @@ Bindings::iterator Bindings::find(const Symbol& name) {
|
|||
return attributes_.find(name);
|
||||
}
|
||||
|
||||
Bindings::iterator Bindings::begin() {
|
||||
return attributes_.begin();
|
||||
}
|
||||
Bindings::iterator Bindings::begin() { return attributes_.begin(); }
|
||||
|
||||
Bindings::iterator Bindings::end() {
|
||||
return attributes_.end();
|
||||
}
|
||||
Bindings::iterator Bindings::end() { return attributes_.end(); }
|
||||
|
||||
void Bindings::merge(Bindings* other) {
|
||||
// We want the values from the other attribute set to take
|
||||
|
|
64
third_party/nix/src/libexpr/eval.cc
vendored
64
third_party/nix/src/libexpr/eval.cc
vendored
|
@ -493,7 +493,7 @@ Value* EvalState::addPrimOp(const std::string& name, size_t arity,
|
|||
}
|
||||
|
||||
Value& EvalState::getBuiltin(const std::string& name) {
|
||||
return *baseEnv.values[0]->attrs->find(symbols.Create(name))->value;
|
||||
return *baseEnv.values[0]->attrs->find(symbols.Create(name))->second.value;
|
||||
}
|
||||
|
||||
/* Every "format" object (even temporary) takes up a few hundred bytes
|
||||
|
@ -607,10 +607,10 @@ inline Value* EvalState::lookupVar(Env* env, const ExprVar& var, bool noEval) {
|
|||
}
|
||||
Bindings::iterator j = env->values[0]->attrs->find(var.name);
|
||||
if (j != env->values[0]->attrs->end()) {
|
||||
if (countCalls && (j->pos != nullptr)) {
|
||||
attrSelects[*j->pos]++;
|
||||
if (countCalls && (j->second.pos != nullptr)) {
|
||||
attrSelects[*j->second.pos]++;
|
||||
}
|
||||
return j->value;
|
||||
return j->second.value;
|
||||
}
|
||||
if (env->prevWith == 0u) {
|
||||
throwUndefinedVarError("undefined variable '%1%' at %2%", var.name,
|
||||
|
@ -857,21 +857,21 @@ void ExprAttrs::eval(EvalState& state, Env& env, Value& v) {
|
|||
Hence we need __overrides.) */
|
||||
if (hasOverrides) {
|
||||
Value* vOverrides =
|
||||
v.attrs->find(overrides->first)
|
||||
->value; //(*v.attrs)[overrides->second.displ].value;
|
||||
//(*v.attrs)[overrides->second.displ].value;
|
||||
v.attrs->find(overrides->first)->second.value;
|
||||
state.forceAttrs(*vOverrides);
|
||||
Bindings* newBnds = state.allocBindings(/* capacity = */ 0);
|
||||
for (auto& i : *v.attrs) { // TODO(tazjin): copy constructor?
|
||||
newBnds->push_back(i);
|
||||
newBnds->push_back(i.second);
|
||||
}
|
||||
for (auto& i : *vOverrides->attrs) {
|
||||
auto j = attrs.find(i.name);
|
||||
auto j = attrs.find(i.second.name);
|
||||
if (j != attrs.end()) {
|
||||
newBnds->push_back(i);
|
||||
newBnds->push_back(i.second);
|
||||
// (*newBnds)[j->second.displ] = i;
|
||||
env2.values[j->second.displ] = i.value;
|
||||
env2.values[j->second.displ] = i.second.value;
|
||||
} else {
|
||||
newBnds->push_back(i);
|
||||
newBnds->push_back(i.second);
|
||||
}
|
||||
}
|
||||
newBnds->sort();
|
||||
|
@ -898,7 +898,7 @@ void ExprAttrs::eval(EvalState& state, Env& env, Value& v) {
|
|||
Bindings::iterator j = v.attrs->find(nameSym);
|
||||
if (j != v.attrs->end()) {
|
||||
throwEvalError("dynamic attribute '%1%' at %2% already defined at %3%",
|
||||
nameSym, i.pos, *j->pos);
|
||||
nameSym, i.pos, *j->second.pos);
|
||||
}
|
||||
|
||||
i.valueExpr->setName(nameSym);
|
||||
|
@ -987,8 +987,8 @@ void ExprSelect::eval(EvalState& state, Env& env, Value& v) {
|
|||
throwEvalError("attribute '%1%' missing, at %2%", name, pos);
|
||||
}
|
||||
}
|
||||
vAttrs = j->value;
|
||||
pos2 = j->pos;
|
||||
vAttrs = j->second.value;
|
||||
pos2 = j->second.pos;
|
||||
if (state.countCalls && (pos2 != nullptr)) {
|
||||
state.attrSelects[*pos2]++;
|
||||
}
|
||||
|
@ -1022,7 +1022,7 @@ void ExprOpHasAttr::eval(EvalState& state, Env& env, Value& v) {
|
|||
mkBool(v, false);
|
||||
return;
|
||||
}
|
||||
vAttrs = j->value;
|
||||
vAttrs = j->second.value;
|
||||
}
|
||||
|
||||
mkBool(v, true);
|
||||
|
@ -1103,7 +1103,7 @@ void EvalState::callFunction(Value& fun, Value& arg, Value& v, const Pos& pos) {
|
|||
fun2 = fun;
|
||||
/* !!! Should we use the attr pos here? */
|
||||
Value v2;
|
||||
callFunction(*found->value, fun2, v2, pos);
|
||||
callFunction(*found->second.value, fun2, v2, pos);
|
||||
return callFunction(v2, arg, v, pos);
|
||||
}
|
||||
}
|
||||
|
@ -1147,7 +1147,7 @@ void EvalState::callFunction(Value& fun, Value& arg, Value& v, const Pos& pos) {
|
|||
env2.values[displ++] = i.def->maybeThunk(*this, env2);
|
||||
} else {
|
||||
attrsUsed++;
|
||||
env2.values[displ++] = j->value;
|
||||
env2.values[displ++] = j->second.value;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1157,10 +1157,10 @@ void EvalState::callFunction(Value& fun, Value& arg, Value& v, const Pos& pos) {
|
|||
/* Nope, so show the first unexpected argument to the
|
||||
user. */
|
||||
for (auto& i : *arg.attrs) {
|
||||
if (lambda.formals->argNames.find(i.name) ==
|
||||
if (lambda.formals->argNames.find(i.second.name) ==
|
||||
lambda.formals->argNames.end()) {
|
||||
throwTypeError("%1% called with unexpected argument '%2%', at %3%",
|
||||
lambda, i.name, pos);
|
||||
lambda, i.second.name, pos);
|
||||
}
|
||||
}
|
||||
abort(); // can't happen
|
||||
|
@ -1198,7 +1198,7 @@ void EvalState::autoCallFunction(Bindings& args, Value& fun, Value& res) {
|
|||
auto found = fun.attrs->find(sFunctor);
|
||||
if (found != fun.attrs->end()) {
|
||||
Value* v = allocValue();
|
||||
callFunction(*found->value, fun, *v, noPos);
|
||||
callFunction(*found->second.value, fun, *v, noPos);
|
||||
forceValue(*v);
|
||||
return autoCallFunction(args, *v, res);
|
||||
}
|
||||
|
@ -1215,7 +1215,7 @@ 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()) {
|
||||
actualArgs->attrs->push_back(*j);
|
||||
actualArgs->attrs->push_back(j->second);
|
||||
} else if (i.def == nullptr) {
|
||||
throwTypeError(
|
||||
"cannot auto-call a function that has an argument without a default "
|
||||
|
@ -1438,10 +1438,10 @@ void EvalState::forceValueDeep(Value& v) {
|
|||
if (v.type == tAttrs) {
|
||||
for (auto& i : *v.attrs) {
|
||||
try {
|
||||
recurse(*i.value);
|
||||
recurse(*i.second.value);
|
||||
} catch (Error& e) {
|
||||
addErrorPrefix(e, "while evaluating the attribute '%1%' at %2%:\n",
|
||||
i.name, *i.pos);
|
||||
i.second.name, *i.second.pos);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
@ -1549,11 +1549,11 @@ bool EvalState::isDerivation(Value& v) {
|
|||
if (i == v.attrs->end()) {
|
||||
return false;
|
||||
}
|
||||
forceValue(*i->value);
|
||||
if (i->value->type != tString) {
|
||||
forceValue(*i->second.value);
|
||||
if (i->second.value->type != tString) {
|
||||
return false;
|
||||
}
|
||||
return strcmp(i->value->string.s, "derivation") == 0;
|
||||
return strcmp(i->second.value->string.s, "derivation") == 0;
|
||||
}
|
||||
|
||||
std::optional<string> EvalState::tryAttrsToString(const Pos& pos, Value& v,
|
||||
|
@ -1563,7 +1563,7 @@ std::optional<string> EvalState::tryAttrsToString(const Pos& pos, Value& v,
|
|||
auto i = v.attrs->find(sToString);
|
||||
if (i != v.attrs->end()) {
|
||||
Value v1;
|
||||
callFunction(*i->value, v, v1, pos);
|
||||
callFunction(*i->second.value, v, v1, pos);
|
||||
return coerceToString(pos, v1, context, coerceMore, copyToStore);
|
||||
}
|
||||
|
||||
|
@ -1596,7 +1596,8 @@ string EvalState::coerceToString(const Pos& pos, Value& v, PathSet& context,
|
|||
if (i == v.attrs->end()) {
|
||||
throwTypeError("cannot coerce a set to a string, at %1%", pos);
|
||||
}
|
||||
return coerceToString(pos, *i->value, context, coerceMore, copyToStore);
|
||||
return coerceToString(pos, *i->second.value, context, coerceMore,
|
||||
copyToStore);
|
||||
}
|
||||
|
||||
if (v.type == tExternal) {
|
||||
|
@ -1735,7 +1736,7 @@ bool EvalState::eqValues(Value& v1, Value& v2) {
|
|||
Bindings::iterator i = v1.attrs->find(sOutPath);
|
||||
Bindings::iterator j = v2.attrs->find(sOutPath);
|
||||
if (i != v1.attrs->end() && j != v2.attrs->end()) {
|
||||
return eqValues(*i->value, *j->value);
|
||||
return eqValues(*i->second.value, *j->second.value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1748,7 +1749,8 @@ bool EvalState::eqValues(Value& v1, Value& v2) {
|
|||
Bindings::iterator j;
|
||||
for (i = v1.attrs->begin(), j = v2.attrs->begin(); i != v1.attrs->end();
|
||||
++i, ++j) {
|
||||
if (i->name != j->name || !eqValues(*i->value, *j->value)) {
|
||||
if (i->second.name != j->second.name ||
|
||||
!eqValues(*i->second.value, *j->second.value)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1934,7 +1936,7 @@ size_t valueSize(Value& v) {
|
|||
seen.insert(v.attrs);
|
||||
sz += sizeof(Bindings) + sizeof(Attr) * v.attrs->capacity();
|
||||
for (auto& i : *v.attrs) {
|
||||
sz += doValue(*i.value);
|
||||
sz += doValue(*i.second.value);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
59
third_party/nix/src/libexpr/get-drvs.cc
vendored
59
third_party/nix/src/libexpr/get-drvs.cc
vendored
|
@ -50,7 +50,7 @@ string DrvInfo::queryName() const {
|
|||
if (i == attrs->end()) {
|
||||
throw TypeError("derivation name missing");
|
||||
}
|
||||
name = state->forceStringNoCtx(*i->value);
|
||||
name = state->forceStringNoCtx(*i->second.value);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
@ -58,8 +58,9 @@ string DrvInfo::queryName() const {
|
|||
string DrvInfo::querySystem() const {
|
||||
if (system.empty() && (attrs != nullptr)) {
|
||||
auto i = attrs->find(state->sSystem);
|
||||
system = i == attrs->end() ? "unknown"
|
||||
: state->forceStringNoCtx(*i->value, *i->pos);
|
||||
system = i == attrs->end()
|
||||
? "unknown"
|
||||
: state->forceStringNoCtx(*i->second.value, *i->second.pos);
|
||||
}
|
||||
return system;
|
||||
}
|
||||
|
@ -68,9 +69,9 @@ string DrvInfo::queryDrvPath() const {
|
|||
if (drvPath.empty() && (attrs != nullptr)) {
|
||||
Bindings::iterator i = attrs->find(state->sDrvPath);
|
||||
PathSet context;
|
||||
drvPath = i != attrs->end()
|
||||
? state->coerceToPath(*i->pos, *i->value, context)
|
||||
: "";
|
||||
drvPath = i != attrs->end() ? state->coerceToPath(*i->second.pos,
|
||||
*i->second.value, context)
|
||||
: "";
|
||||
}
|
||||
return drvPath;
|
||||
}
|
||||
|
@ -79,9 +80,9 @@ string DrvInfo::queryOutPath() const {
|
|||
if (outPath.empty() && (attrs != nullptr)) {
|
||||
Bindings::iterator i = attrs->find(state->sOutPath);
|
||||
PathSet context;
|
||||
outPath = i != attrs->end()
|
||||
? state->coerceToPath(*i->pos, *i->value, context)
|
||||
: "";
|
||||
outPath = i != attrs->end() ? state->coerceToPath(*i->second.pos,
|
||||
*i->second.value, context)
|
||||
: "";
|
||||
}
|
||||
return outPath;
|
||||
}
|
||||
|
@ -92,27 +93,28 @@ DrvInfo::Outputs DrvInfo::queryOutputs(bool onlyOutputsToInstall) {
|
|||
Bindings::iterator i;
|
||||
if ((attrs != nullptr) &&
|
||||
(i = attrs->find(state->sOutputs)) != attrs->end()) {
|
||||
state->forceList(*i->value, *i->pos);
|
||||
state->forceList(*i->second.value, *i->second.pos);
|
||||
|
||||
/* For each output... */
|
||||
for (unsigned int j = 0; j < i->value->listSize(); ++j) {
|
||||
for (unsigned int j = 0; j < i->second.value->listSize(); ++j) {
|
||||
/* Evaluate the corresponding set. */
|
||||
std::string name =
|
||||
state->forceStringNoCtx(*i->value->listElems()[j], *i->pos);
|
||||
std::string name = state->forceStringNoCtx(
|
||||
*i->second.value->listElems()[j], *i->second.pos);
|
||||
Bindings::iterator out = attrs->find(state->symbols.Create(name));
|
||||
if (out == attrs->end()) {
|
||||
continue; // FIXME: throw error?
|
||||
}
|
||||
state->forceAttrs(*out->value);
|
||||
state->forceAttrs(*out->second.value);
|
||||
|
||||
/* And evaluate its ‘outPath’ attribute. */
|
||||
Bindings::iterator outPath = out->value->attrs->find(state->sOutPath);
|
||||
if (outPath == out->value->attrs->end()) {
|
||||
Bindings::iterator outPath =
|
||||
out->second.value->attrs->find(state->sOutPath);
|
||||
if (outPath == out->second.value->attrs->end()) {
|
||||
continue; // FIXME: throw error?
|
||||
}
|
||||
PathSet context;
|
||||
outputs[name] =
|
||||
state->coerceToPath(*outPath->pos, *outPath->value, context);
|
||||
outputs[name] = state->coerceToPath(*outPath->second.pos,
|
||||
*outPath->second.value, context);
|
||||
}
|
||||
} else {
|
||||
outputs["out"] = queryOutPath();
|
||||
|
@ -150,7 +152,8 @@ DrvInfo::Outputs DrvInfo::queryOutputs(bool onlyOutputsToInstall) {
|
|||
string DrvInfo::queryOutputName() const {
|
||||
if (outputName.empty() && (attrs != nullptr)) {
|
||||
Bindings::iterator i = attrs->find(state->sOutputName);
|
||||
outputName = i != attrs->end() ? state->forceStringNoCtx(*i->value) : "";
|
||||
outputName =
|
||||
i != attrs->end() ? state->forceStringNoCtx(*i->second.value) : "";
|
||||
}
|
||||
return outputName;
|
||||
}
|
||||
|
@ -166,8 +169,8 @@ Bindings* DrvInfo::getMeta() {
|
|||
if (a == attrs->end()) {
|
||||
return nullptr;
|
||||
}
|
||||
state->forceAttrs(*a->value, *a->pos);
|
||||
meta = a->value->attrs;
|
||||
state->forceAttrs(*a->second.value, *a->second.pos);
|
||||
meta = a->second.value->attrs;
|
||||
return meta;
|
||||
}
|
||||
|
||||
|
@ -177,7 +180,7 @@ StringSet DrvInfo::queryMetaNames() {
|
|||
return res;
|
||||
}
|
||||
for (auto& i : *meta) {
|
||||
res.insert(i.name);
|
||||
res.insert(i.second.name);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
@ -198,7 +201,7 @@ bool DrvInfo::checkMeta(Value& v) {
|
|||
return false;
|
||||
}
|
||||
for (auto& i : *v.attrs) {
|
||||
if (!checkMeta(*i.value)) {
|
||||
if (!checkMeta(*i.second.value)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -214,10 +217,10 @@ Value* DrvInfo::queryMeta(const std::string& name) {
|
|||
return nullptr;
|
||||
}
|
||||
Bindings::iterator a = meta->find(state->symbols.Create(name));
|
||||
if (a == meta->end() || !checkMeta(*a->value)) {
|
||||
if (a == meta->end() || !checkMeta(*a->second.value)) {
|
||||
return nullptr;
|
||||
}
|
||||
return a->value;
|
||||
return a->second.value;
|
||||
}
|
||||
|
||||
string DrvInfo::queryMetaString(const std::string& name) {
|
||||
|
@ -294,8 +297,8 @@ void DrvInfo::setMeta(const std::string& name, Value* v) {
|
|||
Symbol sym = state->symbols.Create(name);
|
||||
if (old != nullptr) {
|
||||
for (auto i : *old) {
|
||||
if (i.name != sym) {
|
||||
meta->push_back(i);
|
||||
if (i.second.name != sym) {
|
||||
meta->push_back(i.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -403,7 +406,7 @@ 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->second.value, *j->second.pos)) {
|
||||
getDerivations(state, *i->value, pathPrefix2, autoArgs, drvs, done,
|
||||
ignoreAssertionFailures);
|
||||
}
|
||||
|
|
97
third_party/nix/src/libexpr/primops.cc
vendored
97
third_party/nix/src/libexpr/primops.cc
vendored
|
@ -148,8 +148,8 @@ static void prim_scopedImport(EvalState& state, const Pos& pos, Value** args,
|
|||
|
||||
unsigned int displ = 0;
|
||||
for (auto& attr : *args[0]->attrs) {
|
||||
staticEnv.vars[attr.name] = displ;
|
||||
env->values[displ++] = attr.value;
|
||||
staticEnv.vars[attr.second.name] = displ;
|
||||
env->values[displ++] = attr.second.value;
|
||||
}
|
||||
|
||||
DLOG(INFO) << "evaluating file '" << realPath << "'";
|
||||
|
@ -398,11 +398,11 @@ static void prim_genericClosure(EvalState& state, const Pos& pos, Value** args,
|
|||
if (startSet == args[0]->attrs->end()) {
|
||||
throw EvalError(format("attribute 'startSet' required, at %1%") % pos);
|
||||
}
|
||||
state.forceList(*startSet->value, pos);
|
||||
state.forceList(*startSet->second.value, pos);
|
||||
|
||||
ValueList workSet;
|
||||
for (unsigned int n = 0; n < startSet->value->listSize(); ++n) {
|
||||
workSet.push_back(startSet->value->listElems()[n]);
|
||||
for (unsigned int n = 0; n < startSet->second.value->listSize(); ++n) {
|
||||
workSet.push_back(startSet->second.value->listElems()[n]);
|
||||
}
|
||||
|
||||
/* Get the operator. */
|
||||
|
@ -411,7 +411,7 @@ static void prim_genericClosure(EvalState& state, const Pos& pos, Value** args,
|
|||
if (op == args[0]->attrs->end()) {
|
||||
throw EvalError(format("attribute 'operator' required, at %1%") % pos);
|
||||
}
|
||||
state.forceValue(*op->value);
|
||||
state.forceValue(*op->second.value);
|
||||
|
||||
/* Construct the closure by applying the operator to element of
|
||||
`workSet', adding the result to `workSet', continuing until
|
||||
|
@ -430,17 +430,17 @@ static void prim_genericClosure(EvalState& state, const Pos& pos, Value** args,
|
|||
if (key == e->attrs->end()) {
|
||||
throw EvalError(format("attribute 'key' required, at %1%") % pos);
|
||||
}
|
||||
state.forceValue(*key->value);
|
||||
state.forceValue(*key->second.value);
|
||||
|
||||
if (doneKeys.find(key->value) != doneKeys.end()) {
|
||||
if (doneKeys.find(key->second.value) != doneKeys.end()) {
|
||||
continue;
|
||||
}
|
||||
doneKeys.insert(key->value);
|
||||
doneKeys.insert(key->second.value);
|
||||
res.push_back(e);
|
||||
|
||||
/* Call the `operator' function with `e' as argument. */
|
||||
Value call;
|
||||
mkApp(call, *op->value, *e);
|
||||
mkApp(call, *op->second.value, *e);
|
||||
state.forceList(call, pos);
|
||||
|
||||
/* Add the values returned by the operator to the work set. */
|
||||
|
@ -566,9 +566,9 @@ static void prim_derivationStrict(EvalState& state, const Pos& pos,
|
|||
throw EvalError(format("required attribute 'name' missing, at %1%") % pos);
|
||||
}
|
||||
std::string drvName;
|
||||
Pos& posDrvName(*attr->pos);
|
||||
Pos& posDrvName(*attr->second.pos);
|
||||
try {
|
||||
drvName = state.forceStringNoCtx(*attr->value, pos);
|
||||
drvName = state.forceStringNoCtx(*attr->second.value, pos);
|
||||
} catch (Error& e) {
|
||||
e.addPrefix(
|
||||
format("while evaluating the derivation attribute 'name' at %1%:\n") %
|
||||
|
@ -580,7 +580,8 @@ 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->second.value, pos)) {
|
||||
jsonObject = std::make_unique<JSONObject>(jsonBuf);
|
||||
}
|
||||
|
||||
|
@ -588,7 +589,7 @@ static void prim_derivationStrict(EvalState& state, const Pos& pos,
|
|||
bool ignoreNulls = false;
|
||||
attr = args[0]->attrs->find(state.sIgnoreNulls);
|
||||
if (attr != args[0]->attrs->end()) {
|
||||
ignoreNulls = state.forceBool(*attr->value, pos);
|
||||
ignoreNulls = state.forceBool(*attr->second.value, pos);
|
||||
}
|
||||
|
||||
/* Build the derivation expression by processing the attributes. */
|
||||
|
@ -990,7 +991,7 @@ static void prim_findFile(EvalState& state, const Pos& pos, Value** args,
|
|||
std::string prefix;
|
||||
Bindings::iterator i = v2.attrs->find(state.symbols.Create("prefix"));
|
||||
if (i != v2.attrs->end()) {
|
||||
prefix = state.forceStringNoCtx(*i->value, pos);
|
||||
prefix = state.forceStringNoCtx(*i->second.value, pos);
|
||||
}
|
||||
|
||||
i = v2.attrs->find(state.symbols.Create("path"));
|
||||
|
@ -1000,7 +1001,7 @@ static void prim_findFile(EvalState& state, const Pos& pos, Value** args,
|
|||
|
||||
PathSet context;
|
||||
std::string path =
|
||||
state.coerceToString(pos, *i->value, context, false, false);
|
||||
state.coerceToString(pos, *i->second.value, context, false, false);
|
||||
|
||||
try {
|
||||
state.realiseContext(context);
|
||||
|
@ -1219,29 +1220,30 @@ static void prim_path(EvalState& state, const Pos& pos, Value** args,
|
|||
Hash expectedHash;
|
||||
|
||||
for (auto& attr : *args[0]->attrs) {
|
||||
const std::string& n(attr.name);
|
||||
const std::string& n(attr.second.name);
|
||||
if (n == "path") {
|
||||
PathSet context;
|
||||
path = state.coerceToPath(*attr.pos, *attr.value, context);
|
||||
path = state.coerceToPath(*attr.second.pos, *attr.second.value, context);
|
||||
if (!context.empty()) {
|
||||
throw EvalError(
|
||||
format("string '%1%' cannot refer to other paths, at %2%") % path %
|
||||
*attr.pos);
|
||||
*attr.second.pos);
|
||||
}
|
||||
} else if (attr.name == state.sName) {
|
||||
name = state.forceStringNoCtx(*attr.value, *attr.pos);
|
||||
} else if (attr.second.name == state.sName) {
|
||||
name = state.forceStringNoCtx(*attr.second.value, *attr.second.pos);
|
||||
} else if (n == "filter") {
|
||||
state.forceValue(*attr.value);
|
||||
filterFun = attr.value;
|
||||
state.forceValue(*attr.second.value);
|
||||
filterFun = attr.second.value;
|
||||
} else if (n == "recursive") {
|
||||
recursive = state.forceBool(*attr.value, *attr.pos);
|
||||
recursive = state.forceBool(*attr.second.value, *attr.second.pos);
|
||||
} else if (n == "sha256") {
|
||||
expectedHash =
|
||||
Hash(state.forceStringNoCtx(*attr.value, *attr.pos), htSHA256);
|
||||
Hash(state.forceStringNoCtx(*attr.second.value, *attr.second.pos),
|
||||
htSHA256);
|
||||
} else {
|
||||
throw EvalError(
|
||||
format("unsupported argument '%1%' to 'addPath', at %2%") %
|
||||
attr.name % *attr.pos);
|
||||
attr.second.name % *attr.second.pos);
|
||||
}
|
||||
}
|
||||
if (path.empty()) {
|
||||
|
@ -1268,7 +1270,7 @@ static void prim_attrNames(EvalState& state, const Pos& pos, Value** args,
|
|||
|
||||
size_t n = 0;
|
||||
for (auto& i : *args[0]->attrs) {
|
||||
mkString(*(v.listElems()[n++] = state.allocValue()), i.name);
|
||||
mkString(*(v.listElems()[n++] = state.allocValue()), i.second.name);
|
||||
}
|
||||
|
||||
std::sort(v.listElems(), v.listElems() + n, [](Value* v1, Value* v2) {
|
||||
|
@ -1308,11 +1310,11 @@ void prim_getAttr(EvalState& state, const Pos& pos, Value** args, Value& v) {
|
|||
throw EvalError(format("attribute '%1%' missing, at %2%") % attr % pos);
|
||||
}
|
||||
// !!! add to stack trace?
|
||||
if (state.countCalls && (i->pos != nullptr)) {
|
||||
state.attrSelects[*i->pos]++;
|
||||
if (state.countCalls && (i->second.pos != nullptr)) {
|
||||
state.attrSelects[*i->second.pos]++;
|
||||
}
|
||||
state.forceValue(*i->value);
|
||||
v = *i->value;
|
||||
state.forceValue(*i->second.value);
|
||||
v = *i->second.value;
|
||||
}
|
||||
|
||||
/* Return position information of the specified attribute. */
|
||||
|
@ -1324,7 +1326,7 @@ void prim_unsafeGetAttrPos(EvalState& state, const Pos& pos, Value** args,
|
|||
if (i == args[1]->attrs->end()) {
|
||||
mkNull(v);
|
||||
} else {
|
||||
state.mkPos(v, i->pos);
|
||||
state.mkPos(v, i->second.pos);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1361,8 +1363,8 @@ static void prim_removeAttrs(EvalState& state, const Pos& pos, Value** args,
|
|||
vector. */
|
||||
state.mkAttrs(v, args[0]->attrs->size());
|
||||
for (auto& i : *args[0]->attrs) {
|
||||
if (names.find(i.name) == names.end()) {
|
||||
v.attrs->push_back(i);
|
||||
if (names.find(i.second.name) == names.end()) {
|
||||
v.attrs->push_back(i.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1391,7 +1393,7 @@ static void prim_listToAttrs(EvalState& state, const Pos& pos, Value** args,
|
|||
"'name' attribute missing in a call to 'listToAttrs', at %1%") %
|
||||
pos);
|
||||
}
|
||||
std::string name = state.forceStringNoCtx(*j->value, pos);
|
||||
std::string name = state.forceStringNoCtx(*j->second.value, pos);
|
||||
|
||||
Symbol sym = state.symbols.Create(name);
|
||||
if (seen.find(sym) == seen.end()) {
|
||||
|
@ -1406,7 +1408,7 @@ static void prim_listToAttrs(EvalState& state, const Pos& pos, Value** args,
|
|||
pos);
|
||||
}
|
||||
|
||||
v.attrs->push_back(Attr(sym, j2->value, j2->pos));
|
||||
v.attrs->push_back(Attr(sym, j2->second.value, j2->second.pos));
|
||||
seen.insert(sym);
|
||||
}
|
||||
}
|
||||
|
@ -1425,9 +1427,9 @@ static void prim_intersectAttrs(EvalState& state, const Pos& pos, Value** args,
|
|||
state.mkAttrs(v, std::min(args[0]->attrs->size(), args[1]->attrs->size()));
|
||||
|
||||
for (auto& i : *args[0]->attrs) {
|
||||
Bindings::iterator j = args[1]->attrs->find(i.name);
|
||||
Bindings::iterator j = args[1]->attrs->find(i.second.name);
|
||||
if (j != args[1]->attrs->end()) {
|
||||
v.attrs->push_back(*j);
|
||||
v.attrs->push_back(j->second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1452,7 +1454,7 @@ static void prim_catAttrs(EvalState& state, const Pos& pos, Value** args,
|
|||
state.forceAttrs(v2, pos);
|
||||
Bindings::iterator i = v2.attrs->find(attrName);
|
||||
if (i != v2.attrs->end()) {
|
||||
res[found++] = i->value;
|
||||
res[found++] = i->second.value;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1506,9 +1508,9 @@ static void prim_mapAttrs(EvalState& state, const Pos& pos, Value** args,
|
|||
for (auto& i : *args[1]->attrs) {
|
||||
Value* vName = state.allocValue();
|
||||
Value* vFun2 = state.allocValue();
|
||||
mkString(*vName, i.name);
|
||||
mkString(*vName, i.second.name);
|
||||
mkApp(*vFun2, *args[0], *vName);
|
||||
mkApp(*state.allocAttr(v, i.name), *vFun2, *i.value);
|
||||
mkApp(*state.allocAttr(v, i.second.name), *vFun2, *i.second.value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2198,17 +2200,20 @@ void fetch(EvalState& state, const Pos& pos, Value** args, Value& v,
|
|||
state.forceAttrs(*args[0], pos);
|
||||
|
||||
for (auto& attr : *args[0]->attrs) {
|
||||
std::string n(attr.name);
|
||||
std::string n(attr.second.name);
|
||||
if (n == "url") {
|
||||
request.uri = state.forceStringNoCtx(*attr.value, *attr.pos);
|
||||
request.uri =
|
||||
state.forceStringNoCtx(*attr.second.value, *attr.second.pos);
|
||||
} else if (n == "sha256") {
|
||||
request.expectedHash =
|
||||
Hash(state.forceStringNoCtx(*attr.value, *attr.pos), htSHA256);
|
||||
Hash(state.forceStringNoCtx(*attr.second.value, *attr.second.pos),
|
||||
htSHA256);
|
||||
} else if (n == "name") {
|
||||
request.name = state.forceStringNoCtx(*attr.value, *attr.pos);
|
||||
request.name =
|
||||
state.forceStringNoCtx(*attr.second.value, *attr.second.pos);
|
||||
} else {
|
||||
throw EvalError(format("unsupported argument '%1%' to '%2%', at %3%") %
|
||||
attr.name % who % attr.pos);
|
||||
attr.second.name % who % attr.second.pos);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
51
third_party/nix/src/libexpr/primops/context.cc
vendored
51
third_party/nix/src/libexpr/primops/context.cc
vendored
|
@ -147,47 +147,48 @@ static void prim_appendContext(EvalState& state, const Pos& pos, Value** args,
|
|||
|
||||
auto sPath = state.symbols.Create("path");
|
||||
auto sAllOutputs = state.symbols.Create("allOutputs");
|
||||
for (auto& i : *args[1]->attrs) {
|
||||
if (!state.store->isStorePath(i.name))
|
||||
throw EvalError("Context key '%s' is not a store path, at %s", i.name,
|
||||
i.pos);
|
||||
for (const auto& attr_iter : *args[1]->attrs) {
|
||||
const Attr* i = &attr_iter.second; // TODO(tazjin): get rid of this
|
||||
if (!state.store->isStorePath(i->name))
|
||||
throw EvalError("Context key '%s' is not a store path, at %s", i->name,
|
||||
i->pos);
|
||||
if (!settings.readOnlyMode) {
|
||||
state.store->ensurePath(i.name);
|
||||
state.store->ensurePath(i->name);
|
||||
}
|
||||
state.forceAttrs(*i.value, *i.pos);
|
||||
auto iter = i.value->attrs->find(sPath);
|
||||
if (iter != i.value->attrs->end()) {
|
||||
if (state.forceBool(*iter->value, *iter->pos)) {
|
||||
context.insert(i.name);
|
||||
state.forceAttrs(*i->value, *i->pos);
|
||||
auto iter = i->value->attrs->find(sPath);
|
||||
if (iter != i->value->attrs->end()) {
|
||||
if (state.forceBool(*iter->second.value, *iter->second.pos)) {
|
||||
context.insert(i->name);
|
||||
}
|
||||
}
|
||||
|
||||
iter = i.value->attrs->find(sAllOutputs);
|
||||
if (iter != i.value->attrs->end()) {
|
||||
if (state.forceBool(*iter->value, *iter->pos)) {
|
||||
if (!isDerivation(i.name)) {
|
||||
iter = i->value->attrs->find(sAllOutputs);
|
||||
if (iter != i->value->attrs->end()) {
|
||||
if (state.forceBool(*iter->second.value, *iter->second.pos)) {
|
||||
if (!isDerivation(i->name)) {
|
||||
throw EvalError(
|
||||
"Tried to add all-outputs context of %s, which is not a "
|
||||
"derivation, to a string, at %s",
|
||||
i.name, i.pos);
|
||||
i->name, i->pos);
|
||||
}
|
||||
context.insert("=" + string(i.name));
|
||||
context.insert("=" + string(i->name));
|
||||
}
|
||||
}
|
||||
|
||||
iter = i.value->attrs->find(state.sOutputs);
|
||||
if (iter != i.value->attrs->end()) {
|
||||
state.forceList(*iter->value, *iter->pos);
|
||||
if (iter->value->listSize() && !isDerivation(i.name)) {
|
||||
iter = i->value->attrs->find(state.sOutputs);
|
||||
if (iter != i->value->attrs->end()) {
|
||||
state.forceList(*iter->second.value, *iter->second.pos);
|
||||
if (iter->second.value->listSize() && !isDerivation(i->name)) {
|
||||
throw EvalError(
|
||||
"Tried to add derivation output context of %s, which is not a "
|
||||
"derivation, to a string, at %s",
|
||||
i.name, i.pos);
|
||||
i->name, i->pos);
|
||||
}
|
||||
for (unsigned int n = 0; n < iter->value->listSize(); ++n) {
|
||||
auto name =
|
||||
state.forceStringNoCtx(*iter->value->listElems()[n], *iter->pos);
|
||||
context.insert("!" + name + "!" + string(i.name));
|
||||
for (unsigned int n = 0; n < iter->second.value->listSize(); ++n) {
|
||||
auto name = state.forceStringNoCtx(*iter->second.value->listElems()[n],
|
||||
*iter->second.pos);
|
||||
context.insert("!" + name + "!" + string(i->name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -214,7 +214,8 @@ static void prim_fetchGit(EvalState& state, const Pos& pos, Value** args,
|
|||
if (args[0]->type == tAttrs) {
|
||||
state.forceAttrs(*args[0], pos);
|
||||
|
||||
for (auto& attr : *args[0]->attrs) {
|
||||
for (auto& attr_iter : *args[0]->attrs) {
|
||||
auto& attr = attr_iter.second;
|
||||
std::string n(attr.name);
|
||||
if (n == "url")
|
||||
url =
|
||||
|
|
|
@ -190,7 +190,8 @@ static void prim_fetchMercurial(EvalState& state, const Pos& pos, Value** args,
|
|||
if (args[0]->type == tAttrs) {
|
||||
state.forceAttrs(*args[0], pos);
|
||||
|
||||
for (auto& attr : *args[0]->attrs) {
|
||||
for (auto& attr_iter : *args[0]->attrs) {
|
||||
auto& attr = attr_iter.second;
|
||||
std::string n(attr.name);
|
||||
if (n == "url")
|
||||
url =
|
||||
|
|
6
third_party/nix/src/libexpr/value-to-json.cc
vendored
6
third_party/nix/src/libexpr/value-to-json.cc
vendored
|
@ -51,15 +51,15 @@ void printValueAsJSON(EvalState& state, bool strict, Value& v,
|
|||
auto obj(out.object());
|
||||
StringSet names;
|
||||
for (auto& j : *v.attrs) {
|
||||
names.insert(j.name);
|
||||
names.insert(j.second.name);
|
||||
}
|
||||
for (auto& j : names) {
|
||||
Attr& a(*v.attrs->find(state.symbols.Create(j)));
|
||||
auto [_, a] = *v.attrs->find(state.symbols.Create(j));
|
||||
auto placeholder(obj.placeholder(j));
|
||||
printValueAsJSON(state, strict, *a.value, placeholder, context);
|
||||
}
|
||||
} else {
|
||||
printValueAsJSON(state, strict, *i->value, out, context);
|
||||
printValueAsJSON(state, strict, *i->second.value, out, context);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
18
third_party/nix/src/libexpr/value-to-xml.cc
vendored
18
third_party/nix/src/libexpr/value-to-xml.cc
vendored
|
@ -31,11 +31,11 @@ static void showAttrs(EvalState& state, bool strict, bool location,
|
|||
StringSet names;
|
||||
|
||||
for (auto& i : attrs) {
|
||||
names.insert(i.name);
|
||||
names.insert(i.second.name);
|
||||
}
|
||||
|
||||
for (auto& i : names) {
|
||||
Attr& a(*attrs.find(state.symbols.Create(i)));
|
||||
auto& [_, a] = *attrs.find(state.symbols.Create(i));
|
||||
|
||||
XMLAttrs xmlAttrs;
|
||||
xmlAttrs["name"] = i;
|
||||
|
@ -43,7 +43,7 @@ static void showAttrs(EvalState& state, bool strict, bool location,
|
|||
posToXML(xmlAttrs, *a.pos);
|
||||
}
|
||||
|
||||
XMLOpenElement _(doc, "attr", xmlAttrs);
|
||||
XMLOpenElement elem(doc, "attr", xmlAttrs);
|
||||
printValueAsXML(state, strict, location, *a.value, doc, context, drvsSeen);
|
||||
}
|
||||
}
|
||||
|
@ -93,20 +93,20 @@ static void printValueAsXML(EvalState& state, bool strict, bool location,
|
|||
a = v.attrs->find(state.sDrvPath);
|
||||
if (a != v.attrs->end()) {
|
||||
if (strict) {
|
||||
state.forceValue(*a->value);
|
||||
state.forceValue(*a->second.value);
|
||||
}
|
||||
if (a->value->type == tString) {
|
||||
xmlAttrs["drvPath"] = drvPath = a->value->string.s;
|
||||
if (a->second.value->type == tString) {
|
||||
xmlAttrs["drvPath"] = drvPath = a->second.value->string.s;
|
||||
}
|
||||
}
|
||||
|
||||
a = v.attrs->find(state.sOutPath);
|
||||
if (a != v.attrs->end()) {
|
||||
if (strict) {
|
||||
state.forceValue(*a->value);
|
||||
state.forceValue(*a->second.value);
|
||||
}
|
||||
if (a->value->type == tString) {
|
||||
xmlAttrs["outPath"] = a->value->string.s;
|
||||
if (a->second.value->type == tString) {
|
||||
xmlAttrs["outPath"] = a->second.value->string.s;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
5
third_party/nix/src/nix-env/nix-env.cc
vendored
5
third_party/nix/src/nix-env/nix-env.cc
vendored
|
@ -1209,13 +1209,12 @@ static void opQuery(Globals& globals, Strings opFlags, Strings opArgs) {
|
|||
attrs2["type"] = "strings";
|
||||
XMLOpenElement m(xml, "meta", attrs2);
|
||||
Bindings& attrs = *v->attrs;
|
||||
for (auto& i : attrs) {
|
||||
Attr& a(*attrs.find(i.name));
|
||||
for (auto& [name, a] : attrs) {
|
||||
if (a.value->type != tString) {
|
||||
continue;
|
||||
}
|
||||
XMLAttrs attrs3;
|
||||
attrs3["type"] = i.name;
|
||||
attrs3["type"] = name;
|
||||
attrs3["value"] = a.value->string.s;
|
||||
xml.writeEmptyElement("string", attrs3);
|
||||
}
|
||||
|
|
4
third_party/nix/src/nix-env/user-env.cc
vendored
4
third_party/nix/src/nix-env/user-env.cc
vendored
|
@ -129,11 +129,11 @@ bool createUserEnv(EvalState& state, DrvInfos& elems, const Path& profile,
|
|||
DLOG(INFO) << "evaluating user environment builder";
|
||||
state.forceValue(topLevel);
|
||||
PathSet context;
|
||||
Attr& aDrvPath(*topLevel.attrs->find(state.sDrvPath));
|
||||
Attr& aDrvPath(topLevel.attrs->find(state.sDrvPath)->second);
|
||||
Path topLevelDrv =
|
||||
state.coerceToPath(aDrvPath.pos != nullptr ? *(aDrvPath.pos) : noPos,
|
||||
*(aDrvPath.value), context);
|
||||
Attr& aOutPath(*topLevel.attrs->find(state.sOutPath));
|
||||
Attr& aOutPath(topLevel.attrs->find(state.sOutPath)->second);
|
||||
Path topLevelOut =
|
||||
state.coerceToPath(aOutPath.pos != nullptr ? *(aOutPath.pos) : noPos,
|
||||
*(aOutPath.value), context);
|
||||
|
|
|
@ -43,13 +43,13 @@ string resolveMirrorUri(EvalState& state, string uri) {
|
|||
if (mirrorList == vMirrors.attrs->end()) {
|
||||
throw Error(format("unknown mirror name '%1%'") % mirrorName);
|
||||
}
|
||||
state.forceList(*mirrorList->value);
|
||||
state.forceList(*mirrorList->second.value);
|
||||
|
||||
if (mirrorList->value->listSize() < 1) {
|
||||
if (mirrorList->second.value->listSize() < 1) {
|
||||
throw Error(format("mirror URI '%1%' did not expand to anything") % uri);
|
||||
}
|
||||
|
||||
string mirror = state.forceString(*mirrorList->value->listElems()[0]);
|
||||
string mirror = state.forceString(*mirrorList->second.value->listElems()[0]);
|
||||
return mirror + (hasSuffix(mirror, "/") ? "" : "/") + string(s, p + 1);
|
||||
}
|
||||
|
||||
|
@ -130,25 +130,25 @@ static int _main(int argc, char** argv) {
|
|||
if (attr == v.attrs->end()) {
|
||||
throw Error("attribute set does not contain a 'urls' attribute");
|
||||
}
|
||||
state->forceList(*attr->value);
|
||||
if (attr->value->listSize() < 1) {
|
||||
state->forceList(*attr->second.value);
|
||||
if (attr->second.value->listSize() < 1) {
|
||||
throw Error("'urls' list is empty");
|
||||
}
|
||||
uri = state->forceString(*attr->value->listElems()[0]);
|
||||
uri = state->forceString(*attr->second.value->listElems()[0]);
|
||||
|
||||
/* Extract the hash mode. */
|
||||
attr = v.attrs->find(state->symbols.Create("outputHashMode"));
|
||||
if (attr == v.attrs->end()) {
|
||||
LOG(WARNING) << "this does not look like a fetchurl call";
|
||||
} else {
|
||||
unpack = state->forceString(*attr->value) == "recursive";
|
||||
unpack = state->forceString(*attr->second.value) == "recursive";
|
||||
}
|
||||
|
||||
/* Extract the name. */
|
||||
if (name.empty()) {
|
||||
attr = v.attrs->find(state->symbols.Create("name"));
|
||||
if (attr != v.attrs->end()) {
|
||||
name = state->forceString(*attr->value);
|
||||
name = state->forceString(*attr->second.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
13
third_party/nix/src/nix/repl.cc
vendored
13
third_party/nix/src/nix/repl.cc
vendored
|
@ -385,7 +385,7 @@ StringSet NixRepl::completePrefix(const string& prefix) {
|
|||
state.forceAttrs(v);
|
||||
|
||||
for (auto& i : *v.attrs) {
|
||||
string name = i.name;
|
||||
string name = i.second.name;
|
||||
if (string(name, 0, cur2.size()) != cur2) {
|
||||
continue;
|
||||
}
|
||||
|
@ -627,7 +627,7 @@ void NixRepl::reloadFiles() {
|
|||
void NixRepl::addAttrsToScope(Value& attrs) {
|
||||
state.forceAttrs(attrs);
|
||||
for (auto& i : *attrs.attrs) {
|
||||
addVarToScope(i.name, *i.value);
|
||||
addVarToScope(i.second.name, *i.second.value);
|
||||
}
|
||||
std::cout << format("Added %1% variables.") % attrs.attrs->size()
|
||||
<< std::endl;
|
||||
|
@ -718,9 +718,10 @@ std::ostream& NixRepl::printValue(std::ostream& str, Value& v,
|
|||
str << "«derivation ";
|
||||
Bindings::iterator i = v.attrs->find(state.sDrvPath);
|
||||
PathSet context;
|
||||
Path drvPath = i != v.attrs->end()
|
||||
? state.coerceToPath(*i->pos, *i->value, context)
|
||||
: "???";
|
||||
Path drvPath =
|
||||
i != v.attrs->end()
|
||||
? state.coerceToPath(*i->second.pos, *i->second.value, context)
|
||||
: "???";
|
||||
str << drvPath << "»";
|
||||
}
|
||||
|
||||
|
@ -730,7 +731,7 @@ std::ostream& NixRepl::printValue(std::ostream& str, Value& v,
|
|||
typedef std::map<string, Value*> Sorted;
|
||||
Sorted sorted;
|
||||
for (auto& i : *v.attrs) {
|
||||
sorted[i.name] = i.value;
|
||||
sorted[i.second.name] = i.second.value;
|
||||
}
|
||||
|
||||
for (auto& i : sorted) {
|
||||
|
|
16
third_party/nix/src/nix/search.cc
vendored
16
third_party/nix/src/nix/search.cc
vendored
|
@ -175,7 +175,8 @@ struct CmdSearch : SourceExprCommand, MixJSON {
|
|||
if (!toplevel) {
|
||||
auto attrs = v->attrs;
|
||||
Bindings::iterator j = attrs->find(sRecurse);
|
||||
if (j == attrs->end() || !state->forceBool(*j->value, *j->pos)) {
|
||||
if (j == attrs->end() ||
|
||||
!state->forceBool(*j->second.value, *j->second.pos)) {
|
||||
DLOG(INFO) << "skip attribute '" << attrPath << "'";
|
||||
return;
|
||||
}
|
||||
|
@ -184,18 +185,19 @@ struct CmdSearch : SourceExprCommand, MixJSON {
|
|||
bool toplevel2 = false;
|
||||
if (!fromCache) {
|
||||
Bindings::iterator j = v->attrs->find(sToplevel);
|
||||
toplevel2 =
|
||||
j != v->attrs->end() && state->forceBool(*j->value, *j->pos);
|
||||
toplevel2 = j != v->attrs->end() &&
|
||||
state->forceBool(*j->second.value, *j->second.pos);
|
||||
}
|
||||
|
||||
for (auto& i : *v->attrs) {
|
||||
auto cache2 =
|
||||
cache != nullptr
|
||||
? std::make_unique<JSONObject>(cache->object(i.name))
|
||||
? std::make_unique<JSONObject>(cache->object(i.second.name))
|
||||
: nullptr;
|
||||
doExpr(i.value,
|
||||
attrPath.empty() ? (std::string)i.name
|
||||
: attrPath + "." + (std::string)i.name,
|
||||
doExpr(i.second.value,
|
||||
attrPath.empty()
|
||||
? (std::string)i.second.name
|
||||
: attrPath + "." + (std::string)i.second.name,
|
||||
toplevel2 || fromCache, cache2 ? cache2.get() : nullptr);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue