mirror of
https://github.com/privatevoid-net/nix-super.git
synced 2024-11-26 07:46:21 +02:00
Handle cycles when printing a value
So this no longer crashes with a stack overflow: nix-instantiate -E --eval 'let as = { x = as; }; in as' Instead it prints: { x = { x = <CYCLE>; }; }
This commit is contained in:
parent
a54c263402
commit
022618c794
1 changed files with 23 additions and 5 deletions
|
@ -38,8 +38,14 @@ void Bindings::sort()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::ostream & operator << (std::ostream & str, const Value & v)
|
static void printValue(std::ostream & str, std::set<const Value *> & seen, const Value & v)
|
||||||
{
|
{
|
||||||
|
if (seen.find(&v) != seen.end()) {
|
||||||
|
str << "<CYCLE>";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
seen.insert(&v);
|
||||||
|
|
||||||
switch (v.type) {
|
switch (v.type) {
|
||||||
case tInt:
|
case tInt:
|
||||||
str << v.integer;
|
str << v.integer;
|
||||||
|
@ -69,15 +75,20 @@ std::ostream & operator << (std::ostream & str, const Value & v)
|
||||||
Sorted sorted;
|
Sorted sorted;
|
||||||
foreach (Bindings::iterator, i, *v.attrs)
|
foreach (Bindings::iterator, i, *v.attrs)
|
||||||
sorted[i->name] = i->value;
|
sorted[i->name] = i->value;
|
||||||
foreach (Sorted::iterator, i, sorted)
|
for (auto & i : sorted) {
|
||||||
str << i->first << " = " << *i->second << "; ";
|
str << i.first << " = ";
|
||||||
|
printValue(str, seen, *i.second);
|
||||||
|
str << "; ";
|
||||||
|
}
|
||||||
str << "}";
|
str << "}";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case tList:
|
case tList:
|
||||||
str << "[ ";
|
str << "[ ";
|
||||||
for (unsigned int n = 0; n < v.list.length; ++n)
|
for (unsigned int n = 0; n < v.list.length; ++n) {
|
||||||
str << *v.list.elems[n] << " ";
|
printValue(str, seen, *v.list.elems[n]);
|
||||||
|
str << " ";
|
||||||
|
}
|
||||||
str << "]";
|
str << "]";
|
||||||
break;
|
break;
|
||||||
case tThunk:
|
case tThunk:
|
||||||
|
@ -96,6 +107,13 @@ std::ostream & operator << (std::ostream & str, const Value & v)
|
||||||
default:
|
default:
|
||||||
throw Error("invalid value");
|
throw Error("invalid value");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::ostream & operator << (std::ostream & str, const Value & v)
|
||||||
|
{
|
||||||
|
std::set<const Value *> seen;
|
||||||
|
printValue(str, seen, v);
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue