From ecff9d969acef5a08d3963d16eac83a5210de86e Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 3 Mar 2022 13:07:50 +0100 Subject: [PATCH 1/2] printValue(): Don't show repeated values Fixes #6157. --- src/libexpr/eval.cc | 25 +++++++++++++------------ src/libexpr/value.hh | 4 ++-- src/nix/repl.cc | 2 +- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 193358161..d9d36fab2 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -86,15 +86,10 @@ RootValue allocRootValue(Value * v) } -void printValue(std::ostream & str, std::set & active, const Value & v) +void printValue(std::ostream & str, std::set & seen, const Value & v) { checkInterrupt(); - if (!active.insert(&v).second) { - str << ""; - return; - } - switch (v.internalType) { case tInt: str << v.integer; @@ -120,10 +115,14 @@ void printValue(std::ostream & str, std::set & active, const Valu str << "null"; break; case tAttrs: { + seen.insert(&v); str << "{ "; for (auto & i : v.attrs->lexicographicOrder()) { str << i->name << " = "; - printValue(str, active, *i->value); + if (seen.count(i->value)) + str << ""; + else + printValue(str, seen, *i->value); str << "; "; } str << "}"; @@ -132,9 +131,13 @@ void printValue(std::ostream & str, std::set & active, const Valu case tList1: case tList2: case tListN: + seen.insert(&v); str << "[ "; for (auto v2 : v.listItems()) { - printValue(str, active, *v2); + if (seen.count(v2)) + str << ""; + else + printValue(str, seen, *v2); str << " "; } str << "]"; @@ -161,15 +164,13 @@ void printValue(std::ostream & str, std::set & active, const Valu default: abort(); } - - active.erase(&v); } std::ostream & operator << (std::ostream & str, const Value & v) { - std::set active; - printValue(str, active, v); + std::set seen; + printValue(str, seen, v); return str; } diff --git a/src/libexpr/value.hh b/src/libexpr/value.hh index 3fdff71a5..84c4d09f8 100644 --- a/src/libexpr/value.hh +++ b/src/libexpr/value.hh @@ -114,8 +114,8 @@ struct Value private: InternalType internalType; -friend std::string showType(const Value & v); -friend void printValue(std::ostream & str, std::set & active, const Value & v); + friend std::string showType(const Value & v); + friend void printValue(std::ostream & str, std::set & seen, const Value & v); public: diff --git a/src/nix/repl.cc b/src/nix/repl.cc index 5c0d44c68..3a51a13e6 100644 --- a/src/nix/repl.cc +++ b/src/nix/repl.cc @@ -800,7 +800,7 @@ std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int m else printStringValue(str, i.first.c_str()); str << " = "; - if (seen.find(i.second) != seen.end()) + if (seen.count(i.second)) str << "«repeated»"; else try { From e9c04c3351b4b3acae2d154b9aba808c3600054f Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 3 Mar 2022 13:29:14 +0100 Subject: [PATCH 2/2] Be more aggressive in hiding repeated values We now memoize on Bindings / list element vectors rather than Values, so that e.g. two Values that point to the same Bindings will be printed only once. --- src/libexpr/eval.cc | 38 +++++++++++++++++++------------------- src/libexpr/value.hh | 2 +- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index d9d36fab2..2d7309738 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -86,7 +86,7 @@ RootValue allocRootValue(Value * v) } -void printValue(std::ostream & str, std::set & seen, const Value & v) +void printValue(std::ostream & str, std::set & seen, const Value & v) { checkInterrupt(); @@ -115,32 +115,32 @@ void printValue(std::ostream & str, std::set & seen, const Value str << "null"; break; case tAttrs: { - seen.insert(&v); - str << "{ "; - for (auto & i : v.attrs->lexicographicOrder()) { - str << i->name << " = "; - if (seen.count(i->value)) - str << ""; - else + if (!v.attrs->empty() && !seen.insert(v.attrs).second) + str << ""; + else { + str << "{ "; + for (auto & i : v.attrs->lexicographicOrder()) { + str << i->name << " = "; printValue(str, seen, *i->value); - str << "; "; + str << "; "; + } + str << "}"; } - str << "}"; break; } case tList1: case tList2: case tListN: - seen.insert(&v); - str << "[ "; - for (auto v2 : v.listItems()) { - if (seen.count(v2)) - str << ""; - else + if (v.listSize() && !seen.insert(v.listElems()).second) + str << ""; + else { + str << "[ "; + for (auto v2 : v.listItems()) { printValue(str, seen, *v2); - str << " "; + str << " "; + } + str << "]"; } - str << "]"; break; case tThunk: case tApp: @@ -169,7 +169,7 @@ void printValue(std::ostream & str, std::set & seen, const Value std::ostream & operator << (std::ostream & str, const Value & v) { - std::set seen; + std::set seen; printValue(str, seen, v); return str; } diff --git a/src/libexpr/value.hh b/src/libexpr/value.hh index 84c4d09f8..d0fa93e92 100644 --- a/src/libexpr/value.hh +++ b/src/libexpr/value.hh @@ -115,7 +115,7 @@ private: InternalType internalType; friend std::string showType(const Value & v); - friend void printValue(std::ostream & str, std::set & seen, const Value & v); + friend void printValue(std::ostream & str, std::set & seen, const Value & v); public: