summaryrefslogtreecommitdiffstats
path: root/lib.c
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 /lib.c
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.
Diffstat (limited to 'lib.c')
-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;