diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2016-11-01 05:40:18 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2016-11-01 05:40:18 -0700 |
commit | c038597853327f81ef1fc51584500a0073a9833e (patch) | |
tree | b57b346a131a146b39c74a8d08640f04920982f6 /stream.h | |
parent | 0c7ef7145e687f1e7709f706365fd193ab33ef27 (diff) | |
download | txr-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.h | 1 |
1 files changed, 1 insertions, 0 deletions
@@ -39,6 +39,7 @@ enum indent_mode { struct strm_ctx { val obj_hash; + val obj_hash_prev; val counter; }; |