[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
port-with-print-state doesn't create a port? Or, when is a port not a po
From: |
Doug Evans |
Subject: |
port-with-print-state doesn't create a port? Or, when is a port not a port? :-) |
Date: |
Sat, 17 May 2014 11:10:26 -0700 |
Hi.
I've been playing with gdb objects implemented as structs and have hit
an oddity.
The problem can be succinctly represented by the following:
scheme@(guile-user)> (port? (port-with-print-state (current-output-port)))
$3 = #f
I've dug into the implementation of the functions and macros involved.
I think I understand why it's printing #f.
A port-with-print-state is a scm_tc16_port_with_ps port, not a
scm_tc7_port port.
This means that any function that accepts a "port" parameter and
wishes to call functions like scm_puts has to handle this distinction
(because scm_puts only accepts a scm_tc7_port port).
Has anyone done an audit of the C API with an eye towards making any
function that claims to take a port argument accept either kind of
port?
The current situation is a bit confusing.
E.g., in the docs for scm_set_smob_print, I see this text:
It is often best to ignore @var{pstate} and just print to @var{port}
with @code{scm_display}, @code{scm_write}, @code{scm_simple_format},
and @code{scm_puts}.
scm_display and scm_write are smart enough to handle both kinds of
ports, but scm_puts is not. I didn't check scm_simple_format.
And I don't see any docs indicating one needs to be aware of this port
vs port-with-pstate-port distinction in smob or struct printers.
Users can be pretty simplistic when reading documentation, this user
included. :-)
Words tend to take on meanings that if used in one place are expected
to apply everywhere.
IOW, a port is a port is a port.
In that vein, should port? [et.al.] return #t for a
port-with-print-state port? Dunno.
I dug around looking for various problems in the guile sources that
might be caused by this confusion. I couldn't find any and I think
it's because struct printing is the only place that uses
scm_printer_apply. Every other object printer I found takes port and
pstate as separate arguments and scm_prin1 handles splitting out
pstate from the incoming port parameter, thus all printers will only
ever see a scm_tc7_port, never a scm_tc16_port_with_ps port (and thus
all printers that call scm_puts never trip over this confusion, only
struct printers).
In the meantime, I can make struct printers be aware of the
distinction and handle being passed port-with-print-state ports.
P.S. How come scm_put[cs]_unlocked are inlined in ports.h?
- port-with-print-state doesn't create a port? Or, when is a port not a port? :-),
Doug Evans <=