aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2022-03-03 14:35:16 +0100
committerGitHub <noreply@github.com>2022-03-03 14:35:16 +0100
commit391f4fcabe6c307afeb2f39dec07d43f1e6bf748 (patch)
treebc084ed79faf15a58d926318dfe1df58db7d5ae7 /src
parent609779086301a600f4282a629d586bba6b6a485c (diff)
parente9c04c3351b4b3acae2d154b9aba808c3600054f (diff)
Merge pull request #6201 from edolstra/print-value
printValue(): Don't show repeated values
Diffstat (limited to 'src')
-rw-r--r--src/libexpr/eval.cc43
-rw-r--r--src/libexpr/value.hh4
-rw-r--r--src/nix/repl.cc2
3 files changed, 25 insertions, 24 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index 193358161..2d7309738 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<const Value *> & active, const Value & v)
+void printValue(std::ostream & str, std::set<const void *> & seen, const Value & v)
{
checkInterrupt();
- if (!active.insert(&v).second) {
- str << "<CYCLE>";
- return;
- }
-
switch (v.internalType) {
case tInt:
str << v.integer;
@@ -120,24 +115,32 @@ void printValue(std::ostream & str, std::set<const Value *> & active, const Valu
str << "null";
break;
case tAttrs: {
- str << "{ ";
- for (auto & i : v.attrs->lexicographicOrder()) {
- str << i->name << " = ";
- printValue(str, active, *i->value);
- str << "; ";
+ if (!v.attrs->empty() && !seen.insert(v.attrs).second)
+ str << "<REPEAT>";
+ else {
+ str << "{ ";
+ for (auto & i : v.attrs->lexicographicOrder()) {
+ str << i->name << " = ";
+ printValue(str, seen, *i->value);
+ str << "; ";
+ }
+ str << "}";
}
- str << "}";
break;
}
case tList1:
case tList2:
case tListN:
- str << "[ ";
- for (auto v2 : v.listItems()) {
- printValue(str, active, *v2);
- str << " ";
+ if (v.listSize() && !seen.insert(v.listElems()).second)
+ str << "<REPEAT>";
+ else {
+ str << "[ ";
+ for (auto v2 : v.listItems()) {
+ printValue(str, seen, *v2);
+ str << " ";
+ }
+ str << "]";
}
- str << "]";
break;
case tThunk:
case tApp:
@@ -161,15 +164,13 @@ void printValue(std::ostream & str, std::set<const Value *> & active, const Valu
default:
abort();
}
-
- active.erase(&v);
}
std::ostream & operator << (std::ostream & str, const Value & v)
{
- std::set<const Value *> active;
- printValue(str, active, v);
+ std::set<const void *> seen;
+ printValue(str, seen, v);
return str;
}
diff --git a/src/libexpr/value.hh b/src/libexpr/value.hh
index 3fdff71a5..d0fa93e92 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<const Value *> & active, const Value & v);
+ friend std::string showType(const Value & v);
+ friend void printValue(std::ostream & str, std::set<const void *> & 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 {