[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
216/376: Handle cycles when printing a value
From: |
Ludovic Courtès |
Subject: |
216/376: Handle cycles when printing a value |
Date: |
Wed, 28 Jan 2015 22:05:09 +0000 |
civodul pushed a commit to tag 1.8
in repository guix.
commit 022618c794f64ea354e7c9e166f3c8fc1654c470
Author: Eelco Dolstra <address@hidden>
Date: Mon Sep 22 14:59:37 2014 +0200
Handle cycles when printing a value
So this no longer crashes with a stack overflow:
nix-instantiate -E --eval 'let as = { x = as; }; in as'
Instead it prints:
{ x = { x = <CYCLE>; }; }
---
src/libexpr/eval.cc | 28 +++++++++++++++++++++++-----
1 files changed, 23 insertions(+), 5 deletions(-)
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index bd49cec..1dab5ce 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -38,8 +38,14 @@ void Bindings::sort()
}
-std::ostream & operator << (std::ostream & str, const Value & v)
+static void printValue(std::ostream & str, std::set<const Value *> & seen,
const Value & v)
{
+ if (seen.find(&v) != seen.end()) {
+ str << "<CYCLE>";
+ return;
+ }
+ seen.insert(&v);
+
switch (v.type) {
case tInt:
str << v.integer;
@@ -69,15 +75,20 @@ std::ostream & operator << (std::ostream & str, const Value
& v)
Sorted sorted;
foreach (Bindings::iterator, i, *v.attrs)
sorted[i->name] = i->value;
- foreach (Sorted::iterator, i, sorted)
- str << i->first << " = " << *i->second << "; ";
+ for (auto & i : sorted) {
+ str << i.first << " = ";
+ printValue(str, seen, *i.second);
+ str << "; ";
+ }
str << "}";
break;
}
case tList:
str << "[ ";
- for (unsigned int n = 0; n < v.list.length; ++n)
- str << *v.list.elems[n] << " ";
+ for (unsigned int n = 0; n < v.list.length; ++n) {
+ printValue(str, seen, *v.list.elems[n]);
+ str << " ";
+ }
str << "]";
break;
case tThunk:
@@ -96,6 +107,13 @@ std::ostream & operator << (std::ostream & str, const Value
& v)
default:
throw Error("invalid value");
}
+}
+
+
+std::ostream & operator << (std::ostream & str, const Value & v)
+{
+ std::set<const Value *> seen;
+ printValue(str, seen, v);
return str;
}
- 207/376: Remove debug statement, (continued)
- 207/376: Remove debug statement, Ludovic Courtès, 2015/01/28
- 204/376: Install some pkgconfig files, Ludovic Courtès, 2015/01/28
- 206/376: Store.so: Add dependency on libnixutil, Ludovic Courtès, 2015/01/28
- 200/376: Add some instrumentation for debugging GC leaks, Ludovic Courtès, 2015/01/28
- 210/376: Inline Bindings::find(), Ludovic Courtès, 2015/01/28
- 202/376: On Linux, disable address space randomization, Ludovic Courtès, 2015/01/28
- 205/376: Update spec file, Ludovic Courtès, 2015/01/28
- 201/376: Add Make flag to disable optimization, Ludovic Courtès, 2015/01/28
- 213/376: configure: Force regeneration of Makefile.config, Ludovic Courtès, 2015/01/28
- 212/376: attrNames: Don't allocate duplicates of the symbols, Ludovic Courtès, 2015/01/28
- 216/376: Handle cycles when printing a value,
Ludovic Courtès <=
- 211/376: Fix off-by-one, Ludovic Courtès, 2015/01/28
- 215/376: Add ‘seq’ primop, Ludovic Courtès, 2015/01/28
- 209/376: Store Attrs inside Bindings, Ludovic Courtès, 2015/01/28
- 208/376: Remove bogus comment, Ludovic Courtès, 2015/01/28
- 219/376: Add ‘deepSeq’ primop, Ludovic Courtès, 2015/01/28
- 225/376: Pass through --set from nix-install-package command line to nix-env, Ludovic Courtès, 2015/01/28
- 214/376: Add a function ‘valueSize’, Ludovic Courtès, 2015/01/28
- 145/376: Use proper quotes everywhere, Ludovic Courtès, 2015/01/28
- 226/376: Add --force-name support for --set in nix-env, to support nix-install-package --set, Ludovic Courtès, 2015/01/28
- 220/376: Don't evaluate inside a "throw", Ludovic Courtès, 2015/01/28