printValue: Don't show lists/attribute sets twice

This commit is contained in:
Eelco Dolstra 2013-09-09 11:14:43 +02:00
parent 7e3625f924
commit e587aec123

View file

@ -45,7 +45,10 @@ struct NixRepl
void addVarToScope(const Symbol & name, Value * v); void addVarToScope(const Symbol & name, Value * v);
Expr * parseString(string s); Expr * parseString(string s);
void evalString(string s, Value & v); void evalString(string s, Value & v);
typedef set<Value *> ValuesSeen;
std::ostream & printValue(std::ostream & str, Value & v, unsigned int maxDepth); std::ostream & printValue(std::ostream & str, Value & v, unsigned int maxDepth);
std::ostream & printValue(std::ostream & str, Value & v, unsigned int maxDepth, ValuesSeen & seen);
}; };
@ -315,8 +318,15 @@ void NixRepl::evalString(string s, Value & v)
} }
// FIXME: lot of cut&paste from Nix's eval.cc.
std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int maxDepth) std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int maxDepth)
{
ValuesSeen seen;
return printValue(str, v, maxDepth, seen);
}
// FIXME: lot of cut&paste from Nix's eval.cc.
std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int maxDepth, ValuesSeen & seen)
{ {
str.flush(); str.flush();
checkInterrupt(); checkInterrupt();
@ -353,6 +363,8 @@ std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int
break; break;
case tAttrs: { case tAttrs: {
seen.insert(&v);
bool isDrv = state.isDerivation(v); bool isDrv = state.isDerivation(v);
if (isDrv) str << "(derivation "; if (isDrv) str << "(derivation ";
str << "{ "; str << "{ ";
@ -379,10 +391,12 @@ std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int
} }
foreach (Sorted::iterator, i, sorted) foreach (Sorted::iterator, i, sorted)
if (hidden.find(i->first) == hidden.end()) if (hidden.find(i->first) != hidden.end())
printValue(str << i->first << " = ", *i->second, maxDepth - 1) << "; "; str << i->first << " = «...»; ";
else if (seen.find(i->second) != seen.end())
str << i->first << " = «repeated»; ";
else else
str << i->first << " = ...; "; printValue(str << i->first << " = ", *i->second, maxDepth - 1, seen) << "; ";
} else } else
str << "... "; str << "... ";
@ -393,10 +407,16 @@ std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int
} }
case tList: case tList:
seen.insert(&v);
str << "[ "; str << "[ ";
if (maxDepth > 0) if (maxDepth > 0)
for (unsigned int n = 0; n < v.list.length; ++n) for (unsigned int n = 0; n < v.list.length; ++n) {
printValue(str, *v.list.elems[n], maxDepth - 1) << " "; if (seen.find(v.list.elems[n]) != seen.end())
str << "«repeated» ";
else
printValue(str, *v.list.elems[n], maxDepth - 1, seen) << " ";
}
else else
str << "... "; str << "... ";
str << "]"; str << "]";