forked from lix-project/lix
Merge pull request #6201 from edolstra/print-value
printValue(): Don't show repeated values
This commit is contained in:
commit
391f4fcabe
3 changed files with 25 additions and 24 deletions
|
@ -86,15 +86,10 @@ RootValue allocRootValue(Value * v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void printValue(std::ostream & str, std::set<const Value *> & active, const Value & v)
|
void printValue(std::ostream & str, std::set<const void *> & seen, const Value & v)
|
||||||
{
|
{
|
||||||
checkInterrupt();
|
checkInterrupt();
|
||||||
|
|
||||||
if (!active.insert(&v).second) {
|
|
||||||
str << "<CYCLE>";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (v.internalType) {
|
switch (v.internalType) {
|
||||||
case tInt:
|
case tInt:
|
||||||
str << v.integer;
|
str << v.integer;
|
||||||
|
@ -120,24 +115,32 @@ void printValue(std::ostream & str, std::set<const Value *> & active, const Valu
|
||||||
str << "null";
|
str << "null";
|
||||||
break;
|
break;
|
||||||
case tAttrs: {
|
case tAttrs: {
|
||||||
str << "{ ";
|
if (!v.attrs->empty() && !seen.insert(v.attrs).second)
|
||||||
for (auto & i : v.attrs->lexicographicOrder()) {
|
str << "<REPEAT>";
|
||||||
str << i->name << " = ";
|
else {
|
||||||
printValue(str, active, *i->value);
|
str << "{ ";
|
||||||
str << "; ";
|
for (auto & i : v.attrs->lexicographicOrder()) {
|
||||||
|
str << i->name << " = ";
|
||||||
|
printValue(str, seen, *i->value);
|
||||||
|
str << "; ";
|
||||||
|
}
|
||||||
|
str << "}";
|
||||||
}
|
}
|
||||||
str << "}";
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case tList1:
|
case tList1:
|
||||||
case tList2:
|
case tList2:
|
||||||
case tListN:
|
case tListN:
|
||||||
str << "[ ";
|
if (v.listSize() && !seen.insert(v.listElems()).second)
|
||||||
for (auto v2 : v.listItems()) {
|
str << "<REPEAT>";
|
||||||
printValue(str, active, *v2);
|
else {
|
||||||
str << " ";
|
str << "[ ";
|
||||||
|
for (auto v2 : v.listItems()) {
|
||||||
|
printValue(str, seen, *v2);
|
||||||
|
str << " ";
|
||||||
|
}
|
||||||
|
str << "]";
|
||||||
}
|
}
|
||||||
str << "]";
|
|
||||||
break;
|
break;
|
||||||
case tThunk:
|
case tThunk:
|
||||||
case tApp:
|
case tApp:
|
||||||
|
@ -161,15 +164,13 @@ void printValue(std::ostream & str, std::set<const Value *> & active, const Valu
|
||||||
default:
|
default:
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
active.erase(&v);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::ostream & operator << (std::ostream & str, const Value & v)
|
std::ostream & operator << (std::ostream & str, const Value & v)
|
||||||
{
|
{
|
||||||
std::set<const Value *> active;
|
std::set<const void *> seen;
|
||||||
printValue(str, active, v);
|
printValue(str, seen, v);
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -114,8 +114,8 @@ struct Value
|
||||||
private:
|
private:
|
||||||
InternalType internalType;
|
InternalType internalType;
|
||||||
|
|
||||||
friend std::string showType(const Value & v);
|
friend std::string showType(const Value & v);
|
||||||
friend void printValue(std::ostream & str, std::set<const Value *> & active, const Value & v);
|
friend void printValue(std::ostream & str, std::set<const void *> & seen, const Value & v);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
|
@ -800,7 +800,7 @@ std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int m
|
||||||
else
|
else
|
||||||
printStringValue(str, i.first.c_str());
|
printStringValue(str, i.first.c_str());
|
||||||
str << " = ";
|
str << " = ";
|
||||||
if (seen.find(i.second) != seen.end())
|
if (seen.count(i.second))
|
||||||
str << "«repeated»";
|
str << "«repeated»";
|
||||||
else
|
else
|
||||||
try {
|
try {
|
||||||
|
|
Loading…
Reference in a new issue