aboutsummaryrefslogtreecommitdiff
path: root/src/libexpr
diff options
context:
space:
mode:
Diffstat (limited to 'src/libexpr')
-rw-r--r--src/libexpr/eval.cc25
-rw-r--r--src/libexpr/value.hh4
2 files changed, 15 insertions, 14 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<const Value *> & active, const Value & v)
+void printValue(std::ostream & str, std::set<const Value *> & seen, const Value & v)
{
checkInterrupt();
- if (!active.insert(&v).second) {
- str << "<CYCLE>";
- return;
- }
-
switch (v.internalType) {
case tInt:
str << v.integer;
@@ -120,10 +115,14 @@ void printValue(std::ostream & str, std::set<const Value *> & 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 << "<REPEAT>";
+ else
+ printValue(str, seen, *i->value);
str << "; ";
}
str << "}";
@@ -132,9 +131,13 @@ void printValue(std::ostream & str, std::set<const Value *> & 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 << "<REPEAT>";
+ else
+ printValue(str, seen, *v2);
str << " ";
}
str << "]";
@@ -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 Value *> 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<const Value *> & active, const Value & v);
+ friend std::string showType(const Value & v);
+ friend void printValue(std::ostream & str, std::set<const Value *> & seen, const Value & v);
public: