Bindings: Add a method for iterating in lexicographically sorted order

This commit is contained in:
Eelco Dolstra 2017-01-25 16:06:50 +01:00
parent b1f001538e
commit 54801ed6ad
No known key found for this signature in database
GPG key ID: 8170B4726D7198DE
4 changed files with 28 additions and 28 deletions

View file

@ -75,6 +75,19 @@ public:
size_t capacity() { return capacity_; } size_t capacity() { return capacity_; }
/* Returns the attributes in lexicographically sorted order. */
std::vector<const Attr *> lexicographicOrder() const
{
std::vector<const Attr *> res;
res.reserve(size_);
for (size_t n = 0; n < size_; n++)
res.emplace_back(&attrs[n]);
std::sort(res.begin(), res.end(), [](const Attr * a, const Attr * b) {
return (string) a->name < (string) b->name;
});
return res;
}
friend class EvalState; friend class EvalState;
}; };

View file

@ -91,13 +91,9 @@ static void printValue(std::ostream & str, std::set<const Value *> & active, con
break; break;
case tAttrs: { case tAttrs: {
str << "{ "; str << "{ ";
typedef std::map<string, Value *> Sorted; for (auto & i : v.attrs->lexicographicOrder()) {
Sorted sorted; str << i->name << " = ";
for (auto & i : *v.attrs) printValue(str, active, *i->value);
sorted[i.name] = i.value;
for (auto & i : sorted) {
str << i.first << " = ";
printValue(str, active, *i.second);
str << "; "; str << "; ";
} }
str << "}"; str << "}";

View file

@ -284,25 +284,19 @@ static void getDerivations(EvalState & state, Value & vIn,
there are names clashes between derivations, the derivation there are names clashes between derivations, the derivation
bound to the attribute with the "lower" name should take bound to the attribute with the "lower" name should take
precedence). */ precedence). */
typedef std::map<string, Symbol> SortedSymbols; for (auto & i : v.attrs->lexicographicOrder()) {
SortedSymbols attrs; Activity act(*logger, lvlDebug, format("evaluating attribute %1%") % i->name);
for (auto & i : *v.attrs) string pathPrefix2 = addToPath(pathPrefix, i->name);
attrs.insert(std::pair<string, Symbol>(i.name, i.name));
for (auto & i : attrs) {
Activity act(*logger, lvlDebug, format("evaluating attribute %1%") % i.first);
string pathPrefix2 = addToPath(pathPrefix, i.first);
Value & v2(*v.attrs->find(i.second)->value);
if (combineChannels) if (combineChannels)
getDerivations(state, v2, pathPrefix2, autoArgs, drvs, done, ignoreAssertionFailures); getDerivations(state, *i->value, pathPrefix2, autoArgs, drvs, done, ignoreAssertionFailures);
else if (getDerivation(state, v2, pathPrefix2, drvs, done, ignoreAssertionFailures)) { else if (getDerivation(state, *i->value, pathPrefix2, drvs, done, ignoreAssertionFailures)) {
/* If the value of this attribute is itself a set, /* If the value of this attribute is itself a set,
should we recurse into it? => Only if it has a should we recurse into it? => Only if it has a
`recurseForDerivations = true' attribute. */ `recurseForDerivations = true' attribute. */
if (v2.type == tAttrs) { if (i->value->type == tAttrs) {
Bindings::iterator j = v2.attrs->find(state.symbols.create("recurseForDerivations")); Bindings::iterator j = i->value->attrs->find(state.symbols.create("recurseForDerivations"));
if (j != v2.attrs->end() && state.forceBool(*j->value, *j->pos)) if (j != i->value->attrs->end() && state.forceBool(*j->value, *j->pos))
getDerivations(state, v2, pathPrefix2, autoArgs, drvs, done, ignoreAssertionFailures); getDerivations(state, *i->value, pathPrefix2, autoArgs, drvs, done, ignoreAssertionFailures);
} }
} }
} }

View file

@ -998,12 +998,9 @@ static void prim_attrNames(EvalState & state, const Pos & pos, Value * * args, V
state.mkList(v, args[0]->attrs->size()); state.mkList(v, args[0]->attrs->size());
unsigned int n = 0; size_t n = 0;
for (auto & i : *args[0]->attrs) for (auto & i : args[0]->attrs->lexicographicOrder())
mkString(*(v.listElems()[n++] = state.allocValue()), i.name); mkString(*(v.listElems()[n++] = state.allocValue()), i->name);
std::sort(v.listElems(), v.listElems() + n,
[](Value * v1, Value * v2) { return strcmp(v1->string.s, v2->string.s) < 0; });
} }