summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2016-10-21 05:47:35 -0700
committerKaz Kylheku <kaz@kylheku.com>2016-10-21 05:47:35 -0700
commite933786bcdc0be5b01a64a70b3997013220443c0 (patch)
treec7eac4ab82e07fa973cab3f85447b2d90816833d
parent6d8df2a98bae323078951e4d4268a30b4743e31e (diff)
downloadtxr-e933786bcdc0be5b01a64a70b3997013220443c0.tar.gz
txr-e933786bcdc0be5b01a64a70b3997013220443c0.tar.bz2
txr-e933786bcdc0be5b01a64a70b3997013220443c0.zip
Fix circular printing across print methods.
* lib.c (obj_print): When invoked recursively in circular printing mode, collect the nodes of the new object into a separate hash table. Then merge these entries into to the previous hash table. If the newly visited object visits objects we have already seen, suppress those entries.
-rw-r--r--lib.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/lib.c b/lib.c
index f81b791a..0028f543 100644
--- a/lib.c
+++ b/lib.c
@@ -9436,7 +9436,17 @@ val obj_print(val obj, val out, val pretty)
uw_simple_catch_begin;
if (ctx) {
+ val cell, iter;
+ val prev_hash = ctx->obj_hash;
+ ctx->obj_hash = make_hash(nil, nil, nil);
populate_obj_hash(obj, ctx);
+ for (iter = hash_begin(ctx->obj_hash); (cell = hash_next(iter));) {
+ val new_p;
+ val pcell = gethash_c(prev_hash, car(cell), mkcloc(new_p));
+ if (new_p)
+ rplacd(pcell, cdr(cell));
+ }
+ ctx->obj_hash = prev_hash;
} else {
if (cdr(lookup_var(nil, print_circle_s))) {
ctx = &ctx_struct;