guile-devel
[Top][All Lists]
Advanced

[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?



reply via email to

[Prev in Thread] Current Thread [Next in Thread]