180 lines
8.6 KiB
HTML
180 lines
8.6 KiB
HTML
|
<!DOCTYPE html>
|
||
|
<html>
|
||
|
<!-- Created by GNU Texinfo 7.1, https://www.gnu.org/software/texinfo/ -->
|
||
|
<head>
|
||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||
|
<!-- This manual documents Guile version 3.0.10.
|
||
|
|
||
|
Copyright (C) 1996-1997, 2000-2005, 2009-2023 Free Software Foundation,
|
||
|
Inc.
|
||
|
|
||
|
Copyright (C) 2021 Maxime Devos
|
||
|
|
||
|
Copyright (C) 2024 Tomas Volf
|
||
|
|
||
|
|
||
|
Permission is granted to copy, distribute and/or modify this document
|
||
|
under the terms of the GNU Free Documentation License, Version 1.3 or
|
||
|
any later version published by the Free Software Foundation; with no
|
||
|
Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A
|
||
|
copy of the license is included in the section entitled "GNU Free
|
||
|
Documentation License." -->
|
||
|
<title>Soft Ports (Guile Reference Manual)</title>
|
||
|
|
||
|
<meta name="description" content="Soft Ports (Guile Reference Manual)">
|
||
|
<meta name="keywords" content="Soft Ports (Guile Reference Manual)">
|
||
|
<meta name="resource-type" content="document">
|
||
|
<meta name="distribution" content="global">
|
||
|
<meta name="Generator" content=".texi2any-real">
|
||
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||
|
|
||
|
<link href="index.html" rel="start" title="Top">
|
||
|
<link href="Concept-Index.html" rel="index" title="Concept Index">
|
||
|
<link href="index.html#SEC_Contents" rel="contents" title="Table of Contents">
|
||
|
<link href="Port-Types.html" rel="up" title="Port Types">
|
||
|
<link href="Void-Ports.html" rel="next" title="Void Ports">
|
||
|
<link href="Custom-Ports.html" rel="prev" title="Custom Ports">
|
||
|
<style type="text/css">
|
||
|
<!--
|
||
|
a.copiable-link {visibility: hidden; text-decoration: none; line-height: 0em}
|
||
|
div.example {margin-left: 3.2em}
|
||
|
span:hover a.copiable-link {visibility: visible}
|
||
|
strong.def-name {font-family: monospace; font-weight: bold; font-size: larger}
|
||
|
-->
|
||
|
</style>
|
||
|
<link rel="stylesheet" type="text/css" href="https://www.gnu.org/software/gnulib/manual.css">
|
||
|
|
||
|
|
||
|
</head>
|
||
|
|
||
|
<body lang="en">
|
||
|
<div class="subsubsection-level-extent" id="Soft-Ports">
|
||
|
<div class="nav-panel">
|
||
|
<p>
|
||
|
Next: <a href="Void-Ports.html" accesskey="n" rel="next">Void Ports</a>, Previous: <a href="Custom-Ports.html" accesskey="p" rel="prev">Custom Ports</a>, Up: <a href="Port-Types.html" accesskey="u" rel="up">Types of Port</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Concept-Index.html" title="Index" rel="index">Index</a>]</p>
|
||
|
</div>
|
||
|
<hr>
|
||
|
<h4 class="subsubsection" id="Soft-Ports-1"><span>6.12.10.5 Soft Ports<a class="copiable-link" href="#Soft-Ports-1"> ¶</a></span></h4>
|
||
|
<a class="index-entry-id" id="index-Soft-port"></a>
|
||
|
<a class="index-entry-id" id="index-Port_002c-soft"></a>
|
||
|
|
||
|
<p>Soft ports are what Guile had before it had custom binary and textual
|
||
|
ports, and allow for customizable textual input and output.
|
||
|
</p>
|
||
|
<p>We recommend soft ports over R6RS custom textual ports because they are
|
||
|
easier to use while also being more expressive. R6RS custom textual
|
||
|
ports operate under the principle that a port has a mutable string
|
||
|
buffer, and this is reflected in the <code class="code">read</code> and <code class="code">write</code>
|
||
|
procedures which take a buffer, offset, and length. However in Guile as
|
||
|
all ports have a byte buffer rather than some having a string buffer,
|
||
|
the R6RS interface imposes overhead and complexity.
|
||
|
</p>
|
||
|
<p>Additionally, and unlike the R6RS interfaces, <code class="code">make-soft-port</code> from
|
||
|
the <code class="code">(ice-9 soft-ports)</code> module accepts keyword arguments, allowing
|
||
|
for its functionality to be extended over time.
|
||
|
</p>
|
||
|
<p>If you find yourself needing more power, notably the ability to seek,
|
||
|
probably you want to use low-level custom ports. See <a class="xref" href="Low_002dLevel-Custom-Ports.html">Low-Level Custom Ports</a>.
|
||
|
</p>
|
||
|
<div class="example">
|
||
|
<pre class="example-preformatted">(use-modules (ice-9 soft-ports))
|
||
|
</pre></div>
|
||
|
|
||
|
<dl class="first-deffn">
|
||
|
<dt class="deffn" id="index-make_002dsoft_002dport"><span class="category-def">Scheme Procedure: </span><span><strong class="def-name">make-soft-port</strong> <var class="def-var-arguments">[#:id] [#:read-string] [#:write-string] [#:input-waiting?] [#:close] [#:close-on-gc?]</var><a class="copiable-link" href="#index-make_002dsoft_002dport"> ¶</a></span></dt>
|
||
|
<dd><p>Return a new port. If the <var class="var">read-string</var> keyword argument is
|
||
|
present, the port will be an input port. If <var class="var">write-string</var> is
|
||
|
present, the port will be an output port. If both are supplied, the
|
||
|
port will be open for input and output.
|
||
|
</p>
|
||
|
<p>When the port’s internal buffers are empty, <var class="var">read-string</var> will be
|
||
|
called with no arguments, and should return a string, or <code class="code">#f</code> to
|
||
|
indicate end-of-stream. Similarly when a port flushes its write buffer,
|
||
|
the characters in that buffer will be passed to the <var class="var">write-string</var>
|
||
|
procedure as its single argument. <var class="var">write-string</var> returns
|
||
|
unspecified values.
|
||
|
</p>
|
||
|
<p>If supplied, <var class="var">input-waiting?</var> should return <code class="code">#t</code> if the soft
|
||
|
port has input which would be returned directly by <var class="var">read-string</var>.
|
||
|
</p>
|
||
|
<p>If supplied, <var class="var">close</var> will be called when the port is closed, with no
|
||
|
arguments. If <var class="var">close-on-gc?</var> is <code class="code">#t</code>, <var class="var">close</var> will
|
||
|
additionally be called when the port becomes unreachable, after flushing
|
||
|
any pending write buffers.
|
||
|
</p></dd></dl>
|
||
|
|
||
|
<p>With soft ports, the <code class="code">open-string-input-port</code> example from the
|
||
|
previous section is more simple:
|
||
|
</p>
|
||
|
<div class="example">
|
||
|
<pre class="example-preformatted">(define (open-string-input-port source)
|
||
|
(define already-read? #f)
|
||
|
|
||
|
(define (read-string)
|
||
|
(cond
|
||
|
(already-read? "")
|
||
|
(else
|
||
|
(set! already-read? #t)
|
||
|
source)))
|
||
|
|
||
|
(make-soft-port #:id "strport" #:read-string read-string))
|
||
|
</pre></div>
|
||
|
|
||
|
<p>Note that there was an earlier form of <code class="code">make-soft-port</code> which was
|
||
|
exposed in Guile’s default environment, and which is still there. Its
|
||
|
interface is more clumsy and its users historically expect unbuffered
|
||
|
input. This interface will be deprecated, but we document it here.
|
||
|
</p>
|
||
|
<dl class="first-deffn">
|
||
|
<dt class="deffn" id="index-deprecated_002dmake_002dsoft_002dport"><span class="category-def">Scheme Procedure: </span><span><strong class="def-name">deprecated-make-soft-port</strong> <var class="def-var-arguments">pv modes</var><a class="copiable-link" href="#index-deprecated_002dmake_002dsoft_002dport"> ¶</a></span></dt>
|
||
|
<dd><p>Return a port capable of receiving or delivering characters as
|
||
|
specified by the <var class="var">modes</var> string (see <a class="pxref" href="File-Ports.html">open-file</a>). <var class="var">pv</var> must be a vector of length 5 or 6. Its
|
||
|
components are as follows:
|
||
|
</p>
|
||
|
<ol class="enumerate" start="0">
|
||
|
<li> procedure accepting one character for output
|
||
|
</li><li> procedure accepting a string for output
|
||
|
</li><li> thunk for flushing output
|
||
|
</li><li> thunk for getting one character
|
||
|
</li><li> thunk for closing port (not by garbage collection)
|
||
|
</li><li> (if present and not <code class="code">#f</code>) thunk for computing the number of
|
||
|
characters that can be read from the port without blocking.
|
||
|
</li></ol>
|
||
|
|
||
|
<p>For an output-only port only elements 0, 1, 2, and 4 need be
|
||
|
procedures. For an input-only port only elements 3 and 4 need
|
||
|
be procedures. Thunks 2 and 4 can instead be <code class="code">#f</code> if
|
||
|
there is no useful operation for them to perform.
|
||
|
</p>
|
||
|
<p>If thunk 3 returns <code class="code">#f</code> or an <code class="code">eof-object</code>
|
||
|
(see <a data-manual="r5rs" href="../r5rs_html/Input.html#Input">eof-object?</a> in <cite class="cite">The Revised^5 Report on
|
||
|
Scheme</cite>) it indicates that the port has reached end-of-file.
|
||
|
For example:
|
||
|
</p>
|
||
|
<div class="example lisp">
|
||
|
<pre class="lisp-preformatted">(define stdout (current-output-port))
|
||
|
(define p (deprecated-make-soft-port
|
||
|
(vector
|
||
|
(lambda (c) (write c stdout))
|
||
|
(lambda (s) (display s stdout))
|
||
|
(lambda () (display "." stdout))
|
||
|
(lambda () (char-upcase (read-char)))
|
||
|
(lambda () (display "@" stdout)))
|
||
|
"rw"))
|
||
|
|
||
|
(write p p) ⇒ #<input-output: soft 8081e20>
|
||
|
</pre></div>
|
||
|
</dd></dl>
|
||
|
|
||
|
</div>
|
||
|
<hr>
|
||
|
<div class="nav-panel">
|
||
|
<p>
|
||
|
Next: <a href="Void-Ports.html">Void Ports</a>, Previous: <a href="Custom-Ports.html">Custom Ports</a>, Up: <a href="Port-Types.html">Types of Port</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Concept-Index.html" title="Index" rel="index">Index</a>]</p>
|
||
|
</div>
|
||
|
|
||
|
|
||
|
|
||
|
</body>
|
||
|
</html>
|