summaryrefslogtreecommitdiffstats
path: root/stream.h
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2016-11-01 05:40:18 -0700
committerKaz Kylheku <kaz@kylheku.com>2016-11-01 05:40:18 -0700
commitc038597853327f81ef1fc51584500a0073a9833e (patch)
treeb57b346a131a146b39c74a8d08640f04920982f6 /stream.h
parent0c7ef7145e687f1e7709f706365fd193ab33ef27 (diff)
downloadtxr-c038597853327f81ef1fc51584500a0073a9833e.tar.gz
txr-c038597853327f81ef1fc51584500a0073a9833e.tar.bz2
txr-c038597853327f81ef1fc51584500a0073a9833e.zip
Circ print: fix recursion from print methods.
Two issues addressed here, both occurring when *print-circle* is enabled and an object has struct components which have a custom print method that re-enters the object printer. One issue is that the children of these components which occur just once print with spurious labels: like #3=, when no matching #3# occurs. The other bug is a wrong "unexpected duplicate object" exception caused by mismanagement of the child object's label hash table and its merging with the parent. * stream.h (struct stream_ctx): New member, obj_hash_prev. Makes the parent hash table known to populate_obj_hash, if there is a table, otherwise nil. * lib.c (populate_obj_hash): If there is a parent table, check each object in it. If it occurs, then bail. I.e. don't add objects to the child table which occur in the parent. This fixes both issues. Also, we do the unexpected duplicate object check right here now: if we traverse an object that already printed without a label (because it is not known to be duplicate), that means that a custom print method is inappropriately introducing new references to existing objects, contrary to the rules. (obj_hash_merge): The logic here is now simplified. All entries in the child table are simply moved to the parent. If anything already exists, that is an unexpected stuation indicating an internal problem, turned into a variant of the unexpected duplicate object message. * tests/012/circ.tl: New file, giving tests for the bugs. * tests/012/circ.expected: New file.
Diffstat (limited to 'stream.h')
-rw-r--r--stream.h1
1 files changed, 1 insertions, 0 deletions
diff --git a/stream.h b/stream.h
index 818ad9cd..0cc7810a 100644
--- a/stream.h
+++ b/stream.h
@@ -39,6 +39,7 @@ enum indent_mode {
struct strm_ctx {
val obj_hash;
+ val obj_hash_prev;
val counter;
};